Hello, This is a slight update to the v2 patch. I realized that I left some extraneous comments in crt1.S. This patch removes those comments.
-------- From f5a4f77a396631bfceea2967b6a9100b09802f6c Mon Sep 17 00:00:00 2001 From: linted linted@users.noreply.github.com 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 linted@users.noreply.github.com --- 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 | 23 +++++++ 5 files changed, 105 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 <sgidefs.h> +#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 https://www.gnu.org/licenses/. */ - +#define IS_IN_rtld // force inline function calls #include <link.h> #include <elf.h> #include <dl-elf.h>
+#include <ldso.h> +#ifdef __mips__ +#include <dl-startup.h> +#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..7c4db447c 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,25 @@ __start: #else 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) /* 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) + #endif
PTR_LA $4, main /* main */
Now works for me, great job!
On 9/2/2022 10:24 AM, linted wrote:
Hello, This is a slight update to the v2 patch. I realized that I left some extraneous comments in crt1.S. This patch removes those comments.
From f5a4f77a396631bfceea2967b6a9100b09802f6c Mon Sep 17 00:00:00 2001 From: linted linted@users.noreply.github.com 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 linted@users.noreply.github.com
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 | 23 +++++++ 5 files changed, 105 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 <sgidefs.h> +#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 https://www.gnu.org/licenses/. */
+#define IS_IN_rtld // force inline function calls #include <link.h> #include <elf.h> #include <dl-elf.h>
+#include <ldso.h> +#ifdef __mips__ +#include <dl-startup.h> +#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..7c4db447c 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,25 @@ __start: #else 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) /* 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)
#endif
PTR_LA $4, main /* main */
2.34.1
devel mailing list --devel@uclibc-ng.org To unsubscribe send an email todevel-leave@uclibc-ng.org
Hi,
applied and pushed,
best regards Waldemar
linted wrote,
Hello, This is a slight update to the v2 patch. I realized that I left some extraneous comments in crt1.S. This patch removes those comments.
From f5a4f77a396631bfceea2967b6a9100b09802f6c Mon Sep 17 00:00:00 2001 From: linted linted@users.noreply.github.com 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 linted@users.noreply.github.com
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 | 23 +++++++ 5 files changed, 105 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 <sgidefs.h> +#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 https://www.gnu.org/licenses/. */
+#define IS_IN_rtld // force inline function calls #include <link.h> #include <elf.h> #include <dl-elf.h> +#include <ldso.h> +#ifdef __mips__ +#include <dl-startup.h> +#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..7c4db447c 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,25 @@ __start: #else 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) /* 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)
#endif PTR_LA $4, main /* main */ -- 2.34.1
From f5a4f77a396631bfceea2967b6a9100b09802f6c Mon Sep 17 00:00:00 2001 From: linted linted@users.noreply.github.com 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 linted@users.noreply.github.com
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 | 23 +++++++ 5 files changed, 105 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 <sgidefs.h> +#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: \
_dl_exit(1); \ }SEND_STDERR("Aiieeee!"); \
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 https://www.gnu.org/licenses/. */
+#define IS_IN_rtld // force inline function calls #include <link.h> #include <elf.h> #include <dl-elf.h>
+#include <ldso.h> +#ifdef __mips__ +#include <dl-startup.h> +#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..7c4db447c 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,25 @@ __start: #else 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) /* 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)
#endif
PTR_LA $4, main /* main */
2.34.1
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org