summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/sh/dl-startup.h14
-rw-r--r--libc/sysdeps/linux/sh/crt1.S10
2 files changed, 20 insertions, 4 deletions
diff --git a/ldso/ldso/sh/dl-startup.h b/ldso/ldso/sh/dl-startup.h
index 3e59093fa..05e282bd8 100644
--- a/ldso/ldso/sh/dl-startup.h
+++ b/ldso/ldso/sh/dl-startup.h
@@ -12,10 +12,20 @@ __asm__(
" bsrf r0\n"
" add #4, r4\n"
".jmp_loc:\n"
- " jmp @r0\n"
- " mov #0, r4 !call _start with arg == 0\n"
+ " mov r0, r8 ! Save the user entry point address in r8\n"
+ " mov.l .L_got, r12 ! Load the GOT on r12\n"
+ " mova .L_got, r0\n"
+ " add r0, r12\n"
+ " mov.l .L_dl_fini, r0\n"
+ " mov.l @(r0,r12), r4 ! Pass the finalizer in r4\n"
+ " jmp @r8\n"
+ " nop\n"
".L_dl_start:\n"
" .long _dl_start-.jmp_loc\n"
+ ".L_dl_fini:\n"
+ " .long _dl_fini@GOT\n"
+ ".L_got:\n"
+ " .long _GLOBAL_OFFSET_TABLE_\n"
" .size _start,.-_start\n"
" .previous\n"
);
diff --git a/libc/sysdeps/linux/sh/crt1.S b/libc/sysdeps/linux/sh/crt1.S
index fc0ce355d..1c3c54447 100644
--- a/libc/sysdeps/linux/sh/crt1.S
+++ b/libc/sysdeps/linux/sh/crt1.S
@@ -24,6 +24,11 @@
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.
+
sp The stack contains the arguments and environment:
0(sp) argc
4(sp) argv[0]
@@ -48,7 +53,8 @@ _start:
mov.l @r15+,r5
mov r15, r6
- /* Push the fini func onto the stack */
+ /* Push the stack_end, rtld_fini and fini func onto the stack */
+ mov.l r6,@-r15
mov.l r4,@-r15
mov.l L_fini,r0
mov.l r0,@-r15
@@ -57,7 +63,7 @@ _start:
mov.l L_main,r4
mov.l L_init,r7
- /* __uClibc_main (main, argc, argv, init, fini) */
+ /* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
/* Let the libc call main and exit with its return code. */
mov.l L_uClibc_main,r1