summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-10-01 05:30:25 +0000
committerEric Andersen <andersen@codepoet.org>2002-10-01 05:30:25 +0000
commitb58a631942341b6ccb62ab400e862f404e22dbbf (patch)
tree0c6e622729b6c98417a15c0b7c10279c17ca0038 /libc/sysdeps/linux
parent351c1d9029844a97d2771da883fc2b432d5e1bd4 (diff)
This commit contains a patch from Stefan Allius <allius@atecom.com> to change
how uClibc handles _init and _fini, allowing shared lib constructors and destructors to initialize things in the correct sequence. Stefan ported the SH architecture. I then ported x86, arm, and mips. x86 and arm are working fine, but I don't think I quite got things correct for mips.
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/arm/crt0.S28
-rw-r--r--libc/sysdeps/linux/i386/crt0.S27
-rw-r--r--libc/sysdeps/linux/mips/crt0.S17
-rw-r--r--libc/sysdeps/linux/sh/crt0.S49
4 files changed, 72 insertions, 49 deletions
diff --git a/libc/sysdeps/linux/arm/crt0.S b/libc/sysdeps/linux/arm/crt0.S
index 442c9e84b..dc0ec87d8 100644
--- a/libc/sysdeps/linux/arm/crt0.S
+++ b/libc/sysdeps/linux/arm/crt0.S
@@ -50,20 +50,10 @@ ARM register quick reference:
.text
.global _start
- .global __uClibc_main
-
.type _start,%function
- .type __uClibc_main,%function
.text
_start:
-#if 0 /* some old code the I feel should not be here - davidm */
- @ adjust the data segment base pointer
- ldr r3,=__data_start
- sub sl,sl,r3
- mov BASEREG,sl
-#endif
-
/* clear the frame pointer */
mov fp, #0
@@ -78,10 +68,11 @@ _start:
we find there (hopefully the environment) in r2 */
add r2, r1, r0, lsl #2
add r2, r2, #4
+
#else
/*
- * uClinux stacks look a little different to MMU stacks
- * for no good reason
+ * uClinux stacks look a little different from normal
+ * MMU-full Linux stacks (for no good reason)
*/
/* pull argc, argv and envp off the stack */
ldr r0,[sp, #0]
@@ -89,8 +80,19 @@ _start:
ldr r2,[sp, #8]
#endif
+ /* 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() */
+ stmfd sp!, {r0}
+ ldr a1, =_fini
+ stmfd sp!, {r0}
+
/* Ok, now run uClibc's main() -- shouldn't return */
- bl __uClibc_main
+ bl __uClibc_start_main
+
+ /* Crash if somehow `exit' returns anyways. */
+ bl abort
/* Stick in a dummy reference to main(), so that if an application
* is linking when the main() function is in a static library (.a)
diff --git a/libc/sysdeps/linux/i386/crt0.S b/libc/sysdeps/linux/i386/crt0.S
index 3623fe821..97f1fde63 100644
--- a/libc/sysdeps/linux/i386/crt0.S
+++ b/libc/sysdeps/linux/i386/crt0.S
@@ -33,11 +33,11 @@ Cambridge, MA 02139, USA. */
.text
.align 4
-.globl _start
- .type _start,@function
+ .globl _start
+ .type _start,@function
_start:
- /* First locate the start of the environment variables */
+ /* locate the start of the environment variables */
popl %ecx /* Store argc into %ecx */
movl %esp,%ebx /* Store argv into ebx */
movl %esp,%eax /* Store argv into eax as well*/
@@ -52,7 +52,6 @@ _start:
%eax = env ; argv + (argc * 4) + 4
*/
-
/* Set up an invalid (NULL return address, NULL frame pointer)
callers stack frame so anybody unrolling the stack knows where
to stop */
@@ -62,20 +61,18 @@ _start:
pushl %ebp /* callers %ebp (frame pointer) */
movl %esp,%ebp /* mark callers stack frame as invalid */
- /* Now set the environment, argc, and argv where the app can get to them */
- pushl %eax /* Environment pointer */
- pushl %ebx /* Argument pointer */
- pushl %ecx /* And the argument count */
+ /* Push .init and .fini arguments to __uClibc_start_main() on the stack */
+ pushl $_fini
+ pushl $_init
-#if 0
- /* Make sure we are not using iBCS2 personality. (i.e. force linux). */
- movl $136,%eax
- sub %ebx,%ebx
- int $0x80
-#endif
+ /* Push envp, argc, and argc arguments to __uClibc_start_main() on the stack */
+ pushl %eax /* Environment pointer */
+ pushl %ebx /* Argument pointer */
+ pushl %ecx /* And the argument count */
/* Ok, now run uClibc's main() -- shouldn't return */
- call __uClibc_main
+ call __uClibc_start_main
+
/* Crash if somehow `exit' returns anyways. */
hlt
diff --git a/libc/sysdeps/linux/mips/crt0.S b/libc/sysdeps/linux/mips/crt0.S
index 6770ab0b1..7ff3b253f 100644
--- a/libc/sysdeps/linux/mips/crt0.S
+++ b/libc/sysdeps/linux/mips/crt0.S
@@ -30,9 +30,22 @@ __start:
addu a2, a0, 1 /* load envp */
sll a2, a2, 2
add a2, a2, a1
+
+ /* Store the address of _init in a3 as an argument to __uClibc_start_main() */
+ la a3, _init
+
+ /* Push _fini onto the stack as the final argument to __uClibc_start_main()
+ I don't think I am doing this properly but it at least compiles...
+ */
+ la t0, _fini
+ sw t0,16(sp)
+
/* Ok, now run uClibc's main() -- shouldn't return */
- jal __uClibc_main
- hlt: b hlt /* Crash if somehow it does return. */
+ jal __uClibc_start_main
+
+ /* Crash if somehow `exit' returns anyways. */
+hlt:
+ b hlt
/* Stick in a dummy reference to main(), so that if an application
* is linking when the main() function is in a static library (.a)
diff --git a/libc/sysdeps/linux/sh/crt0.S b/libc/sysdeps/linux/sh/crt0.S
index 10915d545..e74ae86c4 100644
--- a/libc/sysdeps/linux/sh/crt0.S
+++ b/libc/sysdeps/linux/sh/crt0.S
@@ -26,13 +26,6 @@
At this entry point, most registers' values are unspecified, except:
- r4 Contains a function pointer to be registered with `atexit'.
- This is how the dynamic linker arranges to have DT_FINI
- functions called for shared libraries that have been loaded
- before this code runs.
- WARNING: At that stage only static linker is supported. For
- uCLinux we won't bother with r4.
-
sp The stack contains the arguments and environment:
0(sp) argc
4(sp) argv[0]
@@ -42,18 +35,26 @@
...
NULL
*/
+ .file "crt0.S"
.text
.globl _start
.type _start,@function
.size _start,_start_end - _start
_start:
- /* Clear the frame pointer since this is the outermost frame. (in delay slot) */
+ /* Clear the frame pointer since this is the outermost frame. */
mov #0, r14
/* Pop argc off the stack and save a pointer to argv */
mov.l @r15+,r4
mov r15, r5
+ /* Push the finip argument to __uClibc_start_main() onto the stack */
+ mov.l L_fini,r6
+ mov.l r6,@-r15
+
+ /* Setup the value for the initp argument */
+ mov.l L_init, r7
+
/*
* Setup the value for the environment pointer:
* r6 = (argc + 1) * 4
@@ -62,27 +63,39 @@ _start:
mov r4,r6
add #1,r6
shll2 r6
- add r5,r6
- /* call main */
+ /* jump to __uClibc_start_main (argc, argv, envp, app_init, app_fini) */
mov.l L_main, r0
jsr @r0
- nop /* delay slot */
-
+ add r5, r6 /* delay slot */
/* We should not get here. */
mov.l L_abort, r0
- jsr @r0
- nop /* delay slot */
+ jmp @r0
+ nop
_start_end:
.align 2
+ .weak _init
+ .type _init,@function
+_init:
+ rts
+ nop
+
+.Lfe1:
+ .size _init,.Lfe1-_init
+ .weak _fini
+ .set _fini,_init
L_main:
- .long __uClibc_main
+ .long __uClibc_start_main /* in libuClibc.*.so */
-L_abort:
- .long abort
+L_init:
+ .long _init
+L_fini:
+ .long _fini
+L_abort:
+ .long abort
/* Stick in a dummy reference to main(), so that if an application
* is linking when the main() function is in a static library (.a)
@@ -90,5 +103,3 @@ L_abort:
L_dummy_main_reference:
.long main
- .data
-