(_start): Leave most of the initialisation for __libc_start_main().

This commit is contained in:
Ulrich Drepper 1998-04-01 09:09:05 +00:00
parent c4dc6c456e
commit e7304fce4e

View File

@ -24,19 +24,19 @@
This includes _init and _libc_init This includes _init and _libc_init
At this entry point, most registers' values are unspecified, except for: At this entry point, most registers' values are unspecified, except:
r0 Contains a function pointer to be registered with `atexit'. a1 Contains a function pointer to be registered with `atexit'.
This is how the dynamic linker arranges to have DT_FINI This is how the dynamic linker arranges to have DT_FINI
functions called for shared libraries that have been loaded functions called for shared libraries that have been loaded
before this code runs. before this code runs.
sp The stack contains the arguments and environment: sp The stack contains the arguments and environment:
0(%esp) argc 0(sp) argc
4(%esp) argv[0] 4(sp) argv[0]
... ...
(4*argc)(%esp) NULL (4*argc)(sp) NULL
(4*(argc+1))(%esp) envp[0] (4*(argc+1))(sp) envp[0]
... ...
NULL NULL
*/ */
@ -44,62 +44,29 @@
.text .text
.globl _start .globl _start
_start: _start:
/* Clear the frame pointer. The Intel ABI suggests this be done, /* Clear the frame pointer since this is the outermost frame. */
to mark the outermost frame obviously. This seems like a
sensible thing to do */
mov fp, #0 mov fp, #0
/* r0 contains the address of the shared library termination /* Pop argc off the stack and save a pointer to argv */
function, which we will register with `atexit' to be called by ldmfd sp!, {a2}
`exit'. I suspect that on some systems, and when statically mov a3, sp
linked, this will not be set by anything to any function
pointer; hopefully it will be zero so we don't try to call
random pointers. */
cmp r0,#0
blne atexit(PLT)
/* Do essential libc initialization. In statically linked /* Push the last arguments to main() onto the stack */
programs under the GNU Hurd, this is what sets up the stmfd sp!, {a1}
arguments on the stack for the code below. For dyn-link ldr a1, =_fini
programs, this has been run already, in the .init code. */ stmfd sp!, {a1}
#ifndef PIC
bl __libc_init_first
/* Extract the arguments and environment as encoded on the stack /* Set up the other arguments for main() that go in registers */
and set up the arguments for `main': argc, argv, envp. */ ldr a1, =main
ldr r0,[sp] ldr a4, =_init
add r1,sp,#4
add r2,r1,r0,lsl #2
add r2,r2,#4
/* save a copy of envp while we have it */
ldr r3,L_environ
str r2,[r3]
/* Call `_init', which is the entry point to our own `.init' /* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
section; and register with `atexit' to have `exit' call
`_fini', which is the entry point to our own `.fini' section. */
bl _init
ldr r0,L_fini
bl atexit
b L_pfini
L_fini: .word _fini /* Let the libc call main and exit with its return code. */
L_environ: .word _environ bl __libc_start_main
L_pfini:
#endif
/* rebuild the arg list for main() */
ldr r0,[sp]
add r1,sp,#4
add r2,r1,r0,lsl #2
add r2,r2,#4
/* Call the user's main function, and exit with its value. */
bl main
bl exit
/* should never get here....*/ /* should never get here....*/
bl abort bl abort
/* Define a symbol for the first piece of initialized data. */ /* Define a symbol for the first piece of initialized data. */
.data .data
.globl __data_start .globl __data_start