From patchwork Thu Sep 1 21:25:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: linted X-Patchwork-Id: 1673226 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=jVeuuNAz; dkim-atps=neutral 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) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MJYxd0ZQnz1yhd for ; Fri, 2 Sep 2022 07:25:57 +1000 (AEST) Received: from helium.openadk.org (localhost [IPv6:::1]) by helium.openadk.org (Postfix) with ESMTP id 06A0131E0565; Thu, 1 Sep 2022 23:25:51 +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=jVeuuNAz; dkim-atps=neutral Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) by helium.openadk.org (Postfix) with ESMTPS id E123731E04C9 for ; Thu, 1 Sep 2022 23:25:46 +0200 (CEST) Received: by mail-pl1-f174.google.com with SMTP id y1so43218plb.2 for ; Thu, 01 Sep 2022 14:25:46 -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:subject :date; bh=Ro6SN5KKf6uD24ZEPe4qI5+lH/1idBpIkVYZYSg0I0g=; b=jVeuuNAzVxnBBswzODvGyfN8GFQ+Yow4T0VY6Aq5MUtTHCVA0LEKSYKefWASawpJb/ YBKqwL0WGymojlK4hOPW/mFtN/782LjFQo9UdMj8oFogXHFIM6hD3h2p+NKJyJpkV1So /VQtzYKCXYzuhWBu4KT9Ysz+h5jxnBbOXATYqmP8s+irBw1DM6xVeJlt2uK5RxFs21Vd XTdyxStKzPFVQazWOJugIvakT90wh8thWMktktZ/XbNrDtR/hkEo2MUeZQeCYyuXcTyA NNhaDptfVsle5VsU/c2QuTtZ3eELMrltJ/UC0vQtvOqKgsdm72jgHXFo3yMpbEjhV/Hq sXaw== 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:subject:date; bh=Ro6SN5KKf6uD24ZEPe4qI5+lH/1idBpIkVYZYSg0I0g=; b=0J/40xm/9v4jMTq7ac0oOxuYBjszoxRPZUdsUZOeaigmlx3jXljciNo5CQVMmHLfXG 3XoZsxs2qH+IHXKlLA417kBBp9IcplEeAxOnA78wNOov8jKSugUaP0ZautG9o2Ov6QVF oTyIlrKOtRAj8KfW8IgoV5GwWuisD64OfHl9hbQqdHFQxTpcfXn8vq+/CUOHW19JNqeV 8NILyv99pTCPaiJyDKI8NxbgZEQR++/bMNdbvBBJez3h0fI62uJkfuG0tfKORciOzK65 AY7lG/iBs4FgwxVqlsVUqmJD7v693W78rH5aUWeYidZ2n9rO+EWFUgAZOa8TLJ3gAJVU G+ug== X-Gm-Message-State: ACgBeo0/TjAv9yuqTt5PrO0RWFsdg0NHrnpgMUu1Hf6USg0rKipWZBWS Fmr76M/TSj10Vo3QtHI/NG/2E+eD39LnVPQvUqx7VYoOQFk= X-Google-Smtp-Source: AA6agR5ivtFTlukQ5z1gkST3yVY/MPaviDC+3Rz0/tRksFUg72ssGUbZKYA4VhPldYrZJzsvDMyrGflu5XbarkEKpWY= X-Received: by 2002:a17:902:f543:b0:175:4f62:7a74 with SMTP id h3-20020a170902f54300b001754f627a74mr7584797plf.28.1662067544832; Thu, 01 Sep 2022 14:25:44 -0700 (PDT) MIME-Version: 1.0 From: linted Date: Thu, 1 Sep 2022 17:25:25 -0400 Message-ID: To: devel@uclibc-ng.org Message-ID-Hash: 4LFNKKZYDZH5YAGQHHERAG4REHXYRGJW X-Message-ID-Hash: 4LFNKKZYDZH5YAGQHHERAG4REHXYRGJW 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 v2] 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, This is the second iteration of the patch for mips static pie support. This version fixes two truncation errors which were occurring. The first problem came from calling reloc_static_pie() directly from __start which caused gcc to request a R_MIPS_PC16 relocation. Unfortunately that type of relocation would not be large enough for the linker to place the PC relative address if the supplied user code was too large. By changing the call to be a register relative jump which we were already correctly calculating, the problem went away. The other bug was the improper usage of the mips assembly macros. I had chosen to use INT_* functions for the calculation to determine the load address. These macros ended up truncating the results since they can use the 32bit instructions on mips64. This was remedied by changing to PTR_* macros. ------- From 051a7536e8f3bfb96c290bda74749886ae7d1693 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 perfrom 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 | 93 +++++++++++++++++++++----- libc/sysdeps/linux/mips/crt1.S | 29 ++++++++ 5 files changed, 111 insertions(+), 18 deletions(-) From 051a7536e8f3bfb96c290bda74749886ae7d1693 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 perfrom 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 | 93 +++++++++++++++++++++----- libc/sysdeps/linux/mips/crt1.S | 29 ++++++++ 5 files changed, 111 insertions(+), 18 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..c0027de6f 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -15,33 +15,96 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ - +#define IS_IN_rtld // force inline function calls #include #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..6a4257b1f 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 + .hidden .L0 #endif .type main,@function .type __uClibc_main,@function @@ -89,6 +93,31 @@ __start: #else PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */ move $31, $0 +#endif +#ifdef L_rcrt1 +/* #if _MIPS_SIM == _MIPS_SIM_ABI32 */ + PTR_LA $4, _DYNAMIC /* Place _DYNAMIC into the GOT */ + REG_S $4, -0x7ff0($28) /* offset to GOT stolen from dl-startup */ + jal .L0 /* Get the current $pc address */ +.L0: + PTR_SUBU $4, $31, $25 /* Calculate load addr */ + move $31, $0 /* Clear ra */ + and $29, -2 * SZREG /* Ensure stack is aligned */ + PTR_ADDIU $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 */ + PTR_ADDU $25, $4, $5 /* store reloc_static_pie in $t9 */ + jalr $25 /* call reloc_static_pie */ + nop /* delay slot, just in case */ + REG_L $2, SZREG($29) /* cleanup stack */ + PTR_ADDIU $29, $29, (2 * SZREG) +#else + PTR_LA $4, _DYNAMIC /* Place _DYNAMIC into the GOT */ + REG_S $4, -0x7ff0($28) + +/* #endif */ + #endif PTR_LA $4, main /* main */ -- 2.34.1