summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-12-12 05:02:43 +0000
committerEric Andersen <andersen@codepoet.org>2004-12-12 05:02:43 +0000
commita80a5b718fa8ad8cc096522f117224e77bd1e1df (patch)
treebd3279c9baaef09f0ae0b18775af5904cec0c613 /libc/sysdeps/linux
parent537a1b30e6247f276b013cc07c5b4e46b5a23eca (diff)
Patch from Paul Brook:
The Arm crt0.S contains non-PIC code for locating _init and _fini sections. This caused problems on my uclinux system when static constructors were enabled. The attached patch implements a PIC version of this code. Paul
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/arm/crt0.S17
1 files changed, 17 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/arm/crt0.S b/libc/sysdeps/linux/arm/crt0.S
index 455d35d2d..f58885d17 100644
--- a/libc/sysdeps/linux/arm/crt0.S
+++ b/libc/sysdeps/linux/arm/crt0.S
@@ -93,11 +93,22 @@ _start:
#endif
#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__
+#ifdef __PIC__
+ /* Store the address of _init in r3 as an argument to main() */
+ adr r5, .L_init
+ ldr r3, .L_init
+ add r3, r3, r5
+
+ /* Push _fini onto the stack as the final argument to main() */
+ ldr r4, .L_init + 4
+ add r4, r4, r5
+#else
/* Store the address of _init in r3 as an argument to main() */
ldr r3, =_init
/* Push _fini onto the stack as the final argument to main() */
ldr r4, =_fini
+#endif
stmfd sp!, {r4}
/* Ok, now run uClibc's main() -- shouldn't return */
@@ -109,6 +120,12 @@ _start:
/* Crash if somehow `exit' returns anyways. */
bl abort
+#if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__ && defined __PIC__
+.L_init:
+ .word _init - .L_init
+ .word _fini - .L_init
+#endif
+
/* We need this stuff to make gdb behave itself, otherwise
gdb will chokes with SIGILL when trying to debug apps.
*/