modified: nfig1.py
[GalaxyCodeBases.git] / c_cpp / Mac / Csu-85 / start.s
blobf139ce3f196c8806d83631822863a49791785b75
1 /*
2 * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
22 * @APPLE_LICENSE_HEADER_END@
25 #include <Availability.h>
27 #if __ppc__ && __DYNAMIC__
29 // Force stub section next to __text section to minimize chance that
30 // a bl to a stub will be out of range.
32 .text
33 .symbol_stub
34 .picsymbol_stub
35 #endif
38 * C runtime startup for ppc, ppc64, i386, x86_64
40 * Kernel sets up stack frame to look like:
42 * :
43 * | STRING AREA |
44 * +-------------+
45 * | 0 |
46 * +-------------+
47 * | exec_path | extra "apple" parameters start after NULL terminating env array
48 * +-------------+
49 * | 0 |
50 * +-------------+
51 * | env[n] |
52 * +-------------+
53 * :
54 * :
55 * +-------------+
56 * | env[0] |
57 * +-------------+
58 * | 0 |
59 * +-------------+
60 * | arg[argc-1] |
61 * +-------------+
62 * :
63 * :
64 * +-------------+
65 * | arg[0] |
66 * +-------------+
67 * | argc | argc is always 4 bytes long, even in 64-bit architectures
68 * +-------------+ <- sp
70 * Where arg[i] and env[i] point into the STRING AREA
73 .text
74 .globl start
75 .align 2
77 #if __ppc__
78 start: mr r26,r1 ; save original stack pointer into r26
79 subi r1,r1,4 ; make space for linkage
80 clrrwi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
81 li r0,0 ; load 0 into r0
82 stw r0,0(r1) ; terminate initial stack frame
83 stwu r1,-64(r1) ; allocate minimal stack frame
84 lwz r3,0(r26) ; get argc into r3
85 addi r4,r26,4 ; get argv into r4
86 addi r27,r3,1 ; calculate argc + 1 into r27
87 slwi r27,r27,2 ; calculate (argc + 1) * sizeof(char *) into r27
88 add r5,r4,r27 ; get address of env[0] into r5
89 #if OLD_LIBSYSTEM_SUPPORT
90 bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
91 trap ; should never return
92 #else
93 mr r6,r5
94 Lapple: lwz r0,0(r6) ; look for NULL ending env[] array
95 addi r6,r6,4
96 cmpwi r0,0
97 bne Lapple ; once found, next pointer is "apple" parameter now in r6
98 bl _main
99 b _exit ; pass result from main() to exit()
100 #endif
101 #endif // __ppc__
104 #if __ppc64__
105 start: mr r26,r1 ; save original stack pointer into r26
106 subi r1,r1,8 ; make space for linkage
107 clrrdi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
108 li r0,0 ; load 0 into r0
109 std r0,0(r1) ; terminate initial stack frame
110 stdu r1,-128(r1) ; allocate minimal stack frame
111 lwz r3,0(r26) ; get argc into r3
112 addi r4,r26,8 ; get argv into r4
113 addi r27,r3,1 ; calculate argc + 1 into r27
114 sldi r27,r27,3 ; calculate (argc + 1) * sizeof(char *) into r27
115 add r5,r4,r27 ; get address of env[0] into r5
116 #if OLD_LIBSYSTEM_SUPPORT
117 bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
118 trap ; should never return
119 #else
120 mr r6,r5
121 Lapple: ld r0,0(r6) ; look for NULL ending env[] array
122 addi r6,r6,8
123 cmpdi r0,0
124 bne Lapple ; once found, next pointer is "apple" parameter now in r6
125 bl _main
126 b _exit ; pass result from main() to exit()
127 #endif
128 #endif // __ppc64__
131 #if __i386__
132 start: pushl $0 # push a zero for debugger end of frames marker
133 movl %esp,%ebp # pointer to base of kernel frame
134 andl $-16,%esp # force SSE alignment
135 subl $16,%esp # room for new argc, argv, & envp, SSE aligned
136 movl 4(%ebp),%ebx # pickup argc in %ebx
137 movl %ebx,0(%esp) # argc to reserved stack word
138 lea 8(%ebp),%ecx # addr of arg[0], argv, into %ecx
139 movl %ecx,4(%esp) # argv to reserved stack word
140 addl $1,%ebx # argc + 1 for zero word
141 sall $2,%ebx # * sizeof(char *)
142 addl %ecx,%ebx # addr of env[0], envp, into %ebx
143 movl %ebx,8(%esp) # envp to reserved stack word
144 #if OLD_LIBSYSTEM_SUPPORT
145 call __start # call _start(argc, argv, envp)
146 hlt # should never return
147 #else
148 Lapple: movl (%ebx),%eax # look for NULL ending env[] array
149 add $4,%ebx
150 testl %eax,%eax
151 jne Lapple # once found, next pointer is "apple" parameter now in %ebx
152 movl %ebx,12(%esp) # apple to reserved stack word
153 call _main
154 movl %eax, 0(%esp) # pass result from main() to exit()
155 call _exit # need to use call to keep stack aligned
157 #endif
158 #endif // __i386__
162 #if __x86_64__
163 start: pushq $0 # push a zero for debugger end of frames marker
164 movq %rsp,%rbp # pointer to base of kernel frame
165 andq $-16,%rsp # force SSE alignment
166 movq 8(%rbp),%rdi # put argc in %rdi
167 leaq 16(%rbp),%rsi # addr of arg[0], argv, into %rsi
168 movl %edi,%edx # copy argc into %rdx
169 addl $1,%edx # argc + 1 for zero word
170 sall $3,%edx # * sizeof(char *)
171 addq %rsi,%rdx # addr of env[0], envp, into %rdx
172 #if OLD_LIBSYSTEM_SUPPORT
173 call __start # call _start(argc, argv, envp)
174 hlt # should never return
175 #else
176 movq %rdx,%rcx
177 jmp Lapple2
178 Lapple: add $8,%rcx
179 Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array
180 jne Lapple
181 add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx
182 call _main
183 movl %eax,%edi # pass result from main() to exit()
184 call _exit # need to use call to keep stack aligned
186 #endif
187 #endif // __x86_64__
189 #ifdef __arm__
190 start:
191 ldr r0, [sp] // get argc into r0
192 add r1, sp, #4 // get argv into r1
193 add r4, r0, #1 // calculate argc + 1 into r4
194 add r2, r1, r4, lsl #2 // get address of env[0] into r2
195 bic sp, sp, #7 // force eight-byte alignment
196 #if OLD_LIBSYSTEM_SUPPORT
197 bl __start
198 .long 0xe1200070 // should never return
199 #else
200 mov r3, r2
201 Lapple:
202 ldr r4, [r3], #4 // look for NULL ending env[] array
203 cmp r4, #0
204 bne Lapple
205 // "apple" param now in r3
206 #if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__)
207 bl _main
208 b _exit
209 #else
210 // use -mlong-branch style call sites so that main executable can be >32MB
211 ldr ip, L4
212 L2: add ip, pc, ip
213 ldr ip, [ip, #0]
214 #if __ARM_ARCH_4T__
215 mov lr, pc // blx not supported, so simulate it in two steps
216 bx ip
217 #else
218 blx ip // call main()
219 #endif
221 ldr ip, L5
222 L3: add ip, pc, ip
223 ldr ip, [ip, #0]
224 bx ip // jmp exit()
226 L4: .long L_main$non_lazy_ptr-(L2+8)
227 L5: .long L_exit$non_lazy_ptr-(L3+8)
229 .non_lazy_symbol_pointer
230 L_main$non_lazy_ptr:
231 .indirect_symbol _main
232 .long 0
233 L_exit$non_lazy_ptr:
234 .indirect_symbol _exit
235 .long 0
236 #endif
239 #endif
240 #endif /* __arm__ */
243 #if __arm64__
245 start:
246 mov x5, sp
247 ldr x0, [x5] ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
248 add x1, x5, #8 ; get argv into x1
249 add x4, x0, #1 ; argc + 1
250 add x2, x1, x4, lsl #3 ; &env[0] = (argc+1)*8
251 and sp, x5, #~15 ; force 16-byte alignment of stack
252 mov x3, x2
253 L1: ldr x4, [x3], #8
254 cmp x4, #0 ; look for NULL ending env[] array
255 b.ne L1
256 bl _main ; main(x0=argc, x1=argv, x2=envp, x3=apple)
257 b _exit
259 #endif /* __arm64__ */
262 // This code has be written to allow dead code stripping
263 .subsections_via_symbols