From patchwork Sun Aug 21 04:32:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: linted X-Patchwork-Id: 1668483 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=uclibc-ng.org (client-ip=2a00:1828:2000:679::23; helo=helium.openadk.org; envelope-from=devel-bounces@uclibc-ng.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=pKDSKU79; dkim-atps=neutral X-Greylist: delayed 582 seconds by postgrey-1.36 at legolas; Sun, 21 Aug 2022 14:44:12 AEST Received: from helium.openadk.org (helium.openadk.org [IPv6:2a00:1828:2000:679::23]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4M9NDs00X7z1ygG for ; Sun, 21 Aug 2022 14:44:12 +1000 (AEST) Received: from helium.openadk.org (localhost [IPv6:::1]) by helium.openadk.org (Postfix) with ESMTP id D81AE31E051A; Sun, 21 Aug 2022 06:34:16 +0200 (CEST) Authentication-Results: helium.openadk.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=pKDSKU79; dkim-atps=neutral Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by helium.openadk.org (Postfix) with ESMTPS id 496D431E03AF for ; Sun, 21 Aug 2022 06:32:57 +0200 (CEST) Received: by mail-pj1-f47.google.com with SMTP id pm17so8012528pjb.3 for ; Sat, 20 Aug 2022 21:32:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=to:subject:message-id:date:from:mime-version:from:to:cc; bh=9WT46oRvUZss8Wr9RA0jPM1GBx9buzk9Phwh9INdIBo=; b=pKDSKU79HpA46fANHW7FpOGFDsioDqK1MBrRAkw3m41U8xo1AioDRciSLJjnAYRqfw EBeSsdB0r2e7nb/zdFTlms8Vv+RX0BadhCuDLoDyl1VSEGZda2zw+Mg+OEQsll/f9Mar bLZB7uhLrS+wwS/DlAl9lcPFoqWB56sTE3a0mseb/N8wfXbwCedR4OSJCabd5BVwvsB/ rCQu0/ewhe7+YEWJasn+7J1+UuT88gGHxhs/Dhopp5WHnSDythid+D7YnYkOuRfZizQx AQlkwDXsSVojIS6wmTA7sbOExNeYf4LjEvs3uqFnSass9syiWmWnYzt15XZVIyNVgEMy cPrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc; bh=9WT46oRvUZss8Wr9RA0jPM1GBx9buzk9Phwh9INdIBo=; b=HIMK9OR6i70nBor0RL9OjKFjZF18OJu25Y4bvnMO3tLqMWPeXcHmwF+QdNbvD/bxqW BsLcw4I8AtZqg5nIDJmrMVAzvhLFR3azJnumPZSriqgdGQ8cPdHWbHszWKdoEQ70gd9V ANDZcLAaABn+Hl3uOuq0VFZdW7xEByP15FT8gYqn2dU6+JJ5v60BlzvZd1dW6N+g3qr9 JStXxgaKMIa4RvDyxyqg07isOhvgEpsIaTEvTXu5/r7M+5WzE7cAd/yFl2XjyC3Du7iG Zfj2FIf//Lb94AMPVrGdn7Op+UcFiUEJy/zvrKKw2vGM8y6/UwjDejcv/NCj1w/D1KwN gD/w== X-Gm-Message-State: ACgBeo3tsIi7c2ye+4pd708MtoxvXm2syp59Ul6PZn3f+poSs+2A8/vB O2li4Pu5RAnpXKSU/cgqvTTvLNCJNl6ly4E7ZPdZkrXdUko= X-Google-Smtp-Source: AA6agR6zGI2FYXJ3K/8DnBMf8JRZGUXFlyXiyHCFo1aOc0UNuYLebN+CrTBAtuhVqmlpdSiHWoFAb6tkOis7jQXt9b8= X-Received: by 2002:a17:90b:1b4a:b0:1f5:5578:6398 with SMTP id nv10-20020a17090b1b4a00b001f555786398mr16383691pjb.122.1661056374826; Sat, 20 Aug 2022 21:32:54 -0700 (PDT) MIME-Version: 1.0 From: linted Date: Sun, 21 Aug 2022 00:32:39 -0400 Message-ID: To: devel@uclibc-ng.org Message-ID-Hash: MWOERMGLTRJRGADOJDBUXKFTKYV5F3EN X-Message-ID-Hash: MWOERMGLTRJRGADOJDBUXKFTKYV5F3EN X-MailFrom: linted90@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.3 Precedence: list Subject: [uclibc-ng-devel] [Patch] Static PIE support for mips List-Id: uClibc-ng Development Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Hello, I have completed a patch to get static pie support working for the mips architecture. Unfortunately a lot of the optimizations I made for previous architectures needed to be rewritten in order to support the way that mips works. There is a substantial rewrite of reloc_static_pie, however the code is nearly a copy paste from dl-startup.c and has been tested with all the currently supported architectures to ensure that it still works. In order to compile with gcc, a patch for mips static pie is required. I'm actively working on submitting said patch, but I do not have a link for it yet. In the meantime, compilation using the following flags passed to gcc should suffice. mips-linux-gcc -static-pie -Bstatic -pie --no-dynamic-linker -z text input.c -o output ---- From a6fa331c7ea16b5146c0d3ba3b2d6d723f09a9b4 Mon Sep 17 00:00:00 2001 From: linted Date: Sat, 20 Aug 2022 16:41:38 -0400 Subject: [PATCH] Added support for creation of Static Position-Independent Executables (PIE) on mips Updated config to allow compilation of rcrt1.o for mips and modified it's crt1.S to perform relocates in __start. The mips architecture performs relocations differently then most other architectures. reloc_static_pie was rewritten, taking code from dl-startup.c, in order to perform the additional relocations. Modifications were made to mips' dl-startup.h to allow for the use of contained macros without including _start definition. Signed-off-by: linted --- extra/Configs/Config.in | 2 +- ldso/ldso/mips/dl-startup.h | 3 +- libc/misc/internals/Makefile.in | 2 +- libc/misc/internals/reloc_static_pie.c | 91 ++++++++++++++++++++++---- libc/sysdeps/linux/mips/crt1.S | 22 +++++++ 5 files changed, 103 insertions(+), 17 deletions(-) diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index e0905e956..43c04fd0a 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -324,7 +324,7 @@ config DOPIC config STATIC_PIE bool "Add support for Static Position Independent Executables (PIE)" default n - depends on DOPIC && !UCLIBC_FORMAT_FDPIC_ELF && (TARGET_arm || TARGET_i386 || TARGET_x86_64 || TARGET_aarch64) + depends on DOPIC && !UCLIBC_FORMAT_FDPIC_ELF && (TARGET_arm || TARGET_i386 || TARGET_x86_64 || TARGET_aarch64 || TARGET_mips) config ARCH_HAS_NO_SHARED bool diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h index 8026f1702..c2168d774 100644 --- a/ldso/ldso/mips/dl-startup.h +++ b/ldso/ldso/mips/dl-startup.h @@ -7,6 +7,7 @@ #include +#ifndef L_rcrt1 __asm__("" " .text\n" " .globl _start\n" @@ -114,6 +115,7 @@ __asm__("" "\n\n" ".previous\n" ); +#endif /* * Get a pointer to the argv array. On many platforms this can be just @@ -191,6 +193,5 @@ do { \ case R_MIPS_NONE: \ break; \ default: \ - SEND_STDERR("Aiieeee!"); \ _dl_exit(1); \ } diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in index 69af8b76e..908b18321 100644 --- a/libc/misc/internals/Makefile.in +++ b/libc/misc/internals/Makefile.in @@ -17,7 +17,7 @@ MISC_INTERNALS_SRC := $(patsubst %.c,$(MISC_INTERNALS_DIR)/%.c,$(CSRC-y)) MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC-y)) CFLAGS-__uClibc_main.c := $(SSP_DISABLE_FLAGS) -CFLAGS-reloc_static_pie.c := $(SSP_DISABLE_FLAGS) +CFLAGS-reloc_static_pie.c := $(SSP_DISABLE_FLAGS) -DL_rcrt1 libc-y += $(MISC_INTERNALS_OBJ) ifneq ($(UCLIBC_FORMAT_SHARED_FLAT),y) diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c index 578202d23..cd9190d60 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -20,28 +20,91 @@ #include #include +#include +#ifdef __mips__ +#include +#endif + ElfW(Addr) _dl_load_base = NULL; void reloc_static_pie (ElfW(Addr) load_addr); void -reloc_static_pie (ElfW(Addr) load_addr) +reloc_static_pie(ElfW(Addr) load_addr) { - ElfW(Word) relative_count = 0; - ElfW(Addr) rel_addr = 0; - ElfW(Dyn) * dyn_addr = NULL; - unsigned long dynamic_info[DYNAMIC_SIZE] = {0}; + int indx; + ElfW(Addr) got; + ElfW(Dyn) *dpnt; + struct elf_resolve tpnt_tmp; + struct elf_resolve *tpnt = &tpnt_tmp; + + DL_BOOT_COMPUTE_GOT(got); + DL_BOOT_COMPUTE_DYN(dpnt, got, (DL_LOADADDR_TYPE)load_addr); + + _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); + tpnt->loadaddr = load_addr; + tpnt->dynamic_addr = dpnt; + + __dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL, load_addr); + +#if defined(PERFORM_BOOTSTRAP_GOT) + /* some arches (like MIPS) we have to tweak the GOT before relocations */ + PERFORM_BOOTSTRAP_GOT(tpnt); +#endif + + +#if defined(ELF_MACHINE_PLTREL_OVERLAP) +# define INDX_MAX 1 +#else +# define INDX_MAX 2 +#endif + + for (indx = 0; indx < INDX_MAX; indx++) { + unsigned long rel_addr, rel_size; + ElfW(Word) relative_count = tpnt->dynamic_info[DT_RELCONT_IDX]; + + rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : + tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]); + rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : + tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]); + + if (!rel_addr) + continue; - /* Read our own dynamic section and fill in the info array. */ - dyn_addr = ((void *) load_addr + elf_machine_dynamic ()); + if((0 == indx) && relative_count) { + rel_size -= relative_count * sizeof(ELF_RELOC); + elf_machine_relative(load_addr, rel_addr, relative_count); + rel_addr += relative_count * sizeof(ELF_RELOC); + } - /* Use the underlying function to avoid TLS access before initialization */ - __dl_parse_dynamic_info(dyn_addr, dynamic_info, NULL, load_addr); +#ifdef ARCH_NEEDS_BOOTSTRAP_RELOCS + { + ELF_RELOC *rpnt; + unsigned int i; + ElfW(Sym) *sym; + unsigned long symbol_addr; + int symtab_index; + unsigned long *reloc_addr; - /* Perform relocations */ - relative_count = dynamic_info[DT_RELCONT_IDX]; - rel_addr = dynamic_info[DT_RELOC_TABLE_ADDR]; - elf_machine_relative(load_addr, rel_addr, relative_count); + /* Now parse the relocation information */ + rpnt = (ELF_RELOC *) rel_addr; + for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { + reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset); + symtab_index = ELF_R_SYM(rpnt->r_info); + symbol_addr = 0; + sym = NULL; + if (symtab_index) { + ElfW(Sym) *symtab; + symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; + sym = &symtab[symtab_index]; + symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value); + } + /* Use this machine-specific macro to perform the actual relocation. */ + PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); + } + } +#endif + } _dl_load_base = load_addr; -} +} \ No newline at end of file diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S index 083615515..a7f72a90f 100644 --- a/libc/sysdeps/linux/mips/crt1.S +++ b/libc/sysdeps/linux/mips/crt1.S @@ -77,6 +77,10 @@ #ifndef __UCLIBC_CTOR_DTOR__ .weak _init .weak _fini +#endif +#ifdef L_rcrt1 + .type reloc_static_pie,@function + .weak reloc_static_pie #endif .type main,@function .type __uClibc_main,@function @@ -90,6 +94,24 @@ __start: PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */ move $31, $0 #endif +#ifdef L_rcrt1 + PTR_LA $4, _DYNAMIC /* Place _DYNAMIC into the GOT */ + REG_S $4, -0x7ff0($28) + jal L0 /* Get the current $pc address */ +L0: + INT_SUB $25, $31, $25 /* Calculate load addr */ + move $4, $25 /* store load addr in param 1 */ + and $29, -2 * SZREG /* Ensure stack is aligned */ + addi $29, $29, (-2 * SZREG) /* Allocate 2 register spaces on stack */ + REG_S $2, SZREG($29) /* Store atexit in case it exists */ + PTR_LA $5, reloc_static_pie /* function calls before relocation + don't work unless we set $t9 manually */ + INT_ADDU $25, $25, $5 /* store reloc_static_pie in $t9 */ + bal reloc_static_pie /* call, and pray the compiler adds a nop + in delay slot */ + REG_L $2, SZREG($29) /* cleanup stack */ + addi $29, $29, (2 * SZREG) +#endif PTR_LA $4, main /* main */ PTR_L $5, 0($29) /* argc */