diff options
Diffstat (limited to 'libc/sysdeps/linux')
| -rw-r--r-- | libc/sysdeps/linux/arm/crt1.S | 50 | 
1 files changed, 23 insertions, 27 deletions
| diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S index 3bea01e73..69357a913 100644 --- a/libc/sysdeps/linux/arm/crt1.S +++ b/libc/sysdeps/linux/arm/crt1.S @@ -59,23 +59,29 @@ ARM register quick reference:  .text  _start: +	/* Save a copy of rtld_fini before r0 gets nuked */ +	mov     r5, r0 +  	/* clear the frame pointer */  	mov     fp, #0 + +	/* Load register r0 with main */  #ifdef __PIC__ -	/* Store the address of main in r0 */ -	adr r5, .L_main +	adr r8, .L_main  	ldr r0, .L_main -	add r0, r0, r5 +	add r0, r0, r8 +	ldr r4, .L_init + 4 +	add r4, r4, r8  #else -	/* Store the address of main in r0 */  	ldr r0, =main  #endif +  #ifdef __ARCH_HAS_MMU__ -	/* Load register r1 (argc) from the stack to its final resting place */ +	/* Load register r1 from the stack to its final resting place */  	ldr     r1, [sp], #4  	/* Copy argv pointer into r2 -- which its final resting place */ @@ -85,45 +91,36 @@ _start:  	 * uClinux stacks look a little different from normal  	 * MMU-full Linux stacks (for no good reason)  	 */ -	/* pull argc, argv and envp off the stack */ +	/* pull argc and argv off the stack */  	ldr r1,[sp, #0]  	ldr r2,[sp, #4]  #endif +	/* Store _init and _fini to r3 and r4 */  #ifdef __PIC__ -	/* Store the address of _init in r3 */ -	adr r5, .L_init +	adr r8, .L_init  	ldr r3, .L_init -	add r3, r3, r5 +	add r3, r3, r8 -	/* Push _fini onto the stack as an argument to main() */  	ldr r4, .L_init + 4 -	add r4, r4, r5 -	stmfd sp!, {r4} - -	/* Push rtld_fini onto the stack as an argument to main() */ -	ldr r4, .L_init + 8 -	add r4, r4, r5 -	stmfd sp!, {r4} +	add r4, r4, r8  #else -	/* Store the address of _init in r3 as an argument to main() */  	ldr r3, =_init - -	/* Push _fini onto the stack as an argument to main() */  	ldr r4, =_fini -	stmfd sp!, {r4} - -	/* Push rtld_fini onto the stack as an argument to main() */ -	ldr r4, =rtld_fini -	stmfd sp!, {r4}  #endif +	/* Store _fini(r4), rtld_fini(r5), and stack_end(r2) on the stack */ +	str r2, [sp, #-4]! +	str r5, [sp, #-4]! +	str r4, [sp, #-4]! + +  	/* We need to call __uClibc_main which should not return.  	   __uClibc_main (int (*main) (int, char **, char **), int argc,  			      char **argv, void (*init) (void), void (*fini) (void),  			      void (*rtld_fini) (void), void *stack_end)  	*/ -	bl	__uClibc_main +	bl __uClibc_main  	/* Crash if somehow `exit' returns anyways.  */  	bl abort @@ -132,7 +129,6 @@ _start:  .L_init:  	.word _init  	.word _fini -	.word rtld_fini  .L_main:  	.word main  #endif | 
