Hey Lance,
I'm having a bit of trouble recreating this bug. I do however have a couple
of possible solutions. Do you mind trying the following patch on top of my
previous one and letting me know if it solves the problem?
---
diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S
index a7f72a90f..811b15387 100644
--- a/libc/sysdeps/linux/mips/crt1.S
+++ b/libc/sysdeps/linux/mips/crt1.S
@@ -81,6 +81,7 @@
#ifdef L_rcrt1
.type reloc_static_pie,@function
.weak reloc_static_pie
+ .hidden .L0
#endif
.type main,@function
.type __uClibc_main,@function
@@ -97,8 +98,8 @@ __start:
#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:
+ 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 */
On Mon, Aug 22, 2022 at 1:37 PM Lance Fredrickson <lancethepants(a)gmail.com>
wrote:
Gave this patch a go with patched gcc for -static-pie
for mips.
It works when compiling hello.c, but when I tried c++ hello.cpp program
I get the following build error.
mipsel-linux-g++ -s -static-pie hello.cpp -o hello
/opt/tomatoware/mipsel-soft-mmc/mipsel-tomatoware-linux-uclibc/sysroot/usr/lib/rcrt1.o:
in function `L0':
(.text+0x50): relocation truncated to fit: R_MIPS_PC16 against
`reloc_static_pie'
collect2: error: ld returned 1 exit status
Also tested arm with the new reworked patch and it seems to work for c
and c++ hello world.
Lance
On 8/20/2022 10:32 PM, linted wrote:
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 <linted(a)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 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 <linted(a)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 | 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 <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..cd9190d60 100644
--- a/libc/misc/internals/reloc_static_pie.c
+++ b/libc/misc/internals/reloc_static_pie.c
@@ -20,28 +20,91 @@
#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..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 */
--
2.34.1
_______________________________________________
devel mailing list -- devel(a)uclibc-ng.org
To unsubscribe send an email to devel-leave(a)uclibc-ng.org
_______________________________________________
devel mailing list -- devel(a)uclibc-ng.org
To unsubscribe send an email to devel-leave(a)uclibc-ng.org