1 ! This file derived from the equivalent in newlib
7 ! - both 32bit pointer and 64bit pointer environments (at compile time)
8 ! - an imposed stack bias (of 2047) (at run time)
9 ! - medium/low and medium/anywhere code models (at run time)
11 ! Initial stack setup:
13 ! bottom of stack (higher memory address)
15 ! text of environment strings
16 ! text of argument strings
17 ! envp[envc] = 0 (4/8 bytes)
20 ! argv[argc] = 0 (4/8 bytes)
24 ! register save area (64 bits by 16 registers = 128 bytes)
29 ! It is the responsibility of the o/s to set this up.
30 ! We handle both a 0 and 2047 value for the stack bias.
32 ! Medium/Anywhere code model support:
34 ! In this model %g4 points to the start of the data segment.
35 ! The text segment can go anywhere, but %g4 points to the *data* segment.
36 ! It is up to the compiler/linker to get this right.
38 ! Since this model is statically linked the start of the data segment
39 ! is known at link time. Eg:
41 ! sethi %hh(data_start), %g1
42 ! sethi %lm(data_start), %g4
43 ! or %g1, %hm(data_start), %g1
44 ! or %g4, %lo(data_start), %g4
48 ! FIXME: For now we just assume 0.
50 ! FIXME: if %g1 contains a non-zero value, atexit() should be invoked
57 .type _start, @function
61 ! We use %g4 even if the code model is Medium/Low (simplifies the code).
63 clr %g4 ! Medium/Anywhere base reg
65 ! If there is a stack bias in effect, account for it in %g5. Then always
66 ! add %g5 to stack references below. This way the code can be used with
67 ! or without an imposed bias.
76 ! On entry, the kernel leaves room for one register frame, but
77 ! the C API wants more free space. Thus, we need to drop the stack
78 ! pointer additionally.
80 #if TARGET_PTR_SIZE == 32
81 sub %sp, 32, %sp ! make room for incoming arguments
82 #else /* TARGET_PTR_SIZE == 64 */
83 sub %sp, 64, %sp ! make room for incoming arguments
86 ! Set up pointers to the ELF data structure (argc, argv, ...)
87 ! Pass as the first argument to __libc_init
88 #if TARGET_PTR_SIZE == 32
90 #else /* TARGET_PTR_SIZE == 64 */
95 mov %g1, %o1 ! This is the "atexit" pointer;
96 ! pass as the second argument to __libc_init
98 ! If __libc_init returns, something is hosed. Try an illegal insn.
99 ! If that does not work, the o/s is hosed more than we are.