]> git.saurik.com Git - apple/dyld.git/blame - src/dyldStartup.s
dyld-851.27.tar.gz
[apple/dyld.git] / src / dyldStartup.s
CommitLineData
0959b6d4 1/*
832b6fce 2 * Copyright (c) 1999-2011 Apple Inc. All rights reserved.
0959b6d4
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
6cae9b63 5 *
0959b6d4
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
6cae9b63 12 *
0959b6d4
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
6cae9b63 20 *
0959b6d4
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
832b6fce 24 * C runtime startup for interface to the dynamic linker.
0959b6d4
A
25 * This is the same as the entry point in crt0.o with the addition of the
26 * address of the mach header passed as the an extra first argument.
27 *
28 * Kernel sets up stack frame to look like:
29 *
30 * | STRING AREA |
31 * +-------------+
6cae9b63 32 * | 0 |
0959b6d4
A
33* +-------------+
34 * | apple[n] |
35 * +-------------+
36 * :
37 * +-------------+
6cae9b63
A
38 * | apple[0] |
39 * +-------------+
0959b6d4
A
40 * | 0 |
41 * +-------------+
42 * | env[n] |
43 * +-------------+
44 * :
45 * :
46 * +-------------+
47 * | env[0] |
48 * +-------------+
49 * | 0 |
50 * +-------------+
51 * | arg[argc-1] |
52 * +-------------+
53 * :
54 * :
55 * +-------------+
56 * | arg[0] |
57 * +-------------+
58 * | argc |
59 * +-------------+
60 * sp-> | mh | address of where the a.out's file offset 0 is in memory
61 * +-------------+
62 *
63 * Where arg[i] and env[i] point into the STRING AREA
64 */
65
0959b6d4 66
2fd3f4e8 67#include <TargetConditionals.h>
39a8cd10
A
68
69 .globl __dyld_start
70
cf998323 71#if __i386__ && !TARGET_OS_SIMULATOR
0959b6d4
A
72 .text
73 .align 4, 0x90
74 .globl __dyld_start
75__dyld_start:
832b6fce 76 popl %edx # edx = mh of app
0959b6d4
A
77 pushl $0 # push a zero for debugger end of frames marker
78 movl %esp,%ebp # pointer to base of kernel frame
79 andl $-16,%esp # force SSE alignment
832b6fce 80 subl $32,%esp # room for locals and outgoing parameters
6cae9b63 81
0959b6d4 82 call L__dyld_start_picbase
6cae9b63 83L__dyld_start_picbase:
0959b6d4 84 popl %ebx # set %ebx to runtime value of picbase
832b6fce 85
cf998323
A
86 # call dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)
87 subl $L__dyld_start_picbase-__dyld_start, %ebx # ebx = &__dyld_start
88 subl $0x1000, %ebx # ebx = load address of dyld
832b6fce 89 movl %edx,(%esp) # param1 = app_mh
6cae9b63 90 movl 4(%ebp),%eax
832b6fce 91 movl %eax,4(%esp) # param2 = argc
6cae9b63 92 lea 8(%ebp),%eax
832b6fce 93 movl %eax,8(%esp) # param3 = argv
cf998323 94 movl %ebx,12(%esp) # param4 = dyld load address
832b6fce 95 lea 28(%esp),%eax
cf998323
A
96 movl %eax,16(%esp) # param5 = &startGlue
97 call __ZN13dyldbootstrap5startEPKN5dyld311MachOLoadedEiPPKcS3_Pm
832b6fce
A
98 movl 28(%esp),%edx
99 cmpl $0,%edx
100 jne Lnew
101
102 # clean up stack and jump to "start" in main executable
0959b6d4 103 movl %ebp,%esp # restore the unaligned stack pointer
832b6fce 104 addl $4,%esp # remove debugger end frame marker
0959b6d4 105 movl $0,%ebp # restore ebp back to zero
bac542e6 106 jmp *%eax # jump to the entry point
0959b6d4 107
6cae9b63 108 # LC_MAIN case, set up stack for call to main()
832b6fce
A
109Lnew: movl 4(%ebp),%ebx
110 movl %ebx,(%esp) # main param1 = argc
111 leal 8(%ebp),%ecx
112 movl %ecx,4(%esp) # main param2 = argv
113 leal 0x4(%ecx,%ebx,4),%ebx
114 movl %ebx,8(%esp) # main param3 = env
115Lapple: movl (%ebx),%ecx # look for NULL ending env[] array
116 add $4,%ebx
117 testl %ecx,%ecx
118 jne Lapple # once found, next pointer is "apple" parameter now in %ebx
119 movl %ebx,12(%esp) # main param4 = apple
120 pushl %edx # simulate return address into _start in libdyld
121 jmp *%eax # jump to main(argc,argv,env,apple) with return address set to _start
19894a12 122
cf998323 123#endif /* __i386__ && !TARGET_OS_SIMULATOR*/
0959b6d4 124
3d7c199a 125
39a8cd10 126
cf998323 127#if __x86_64__ && !TARGET_OS_SIMULATOR
8bc9f0af
A
128 .text
129 .align 2,0x90
130 .globl __dyld_start
131__dyld_start:
832b6fce 132 popq %rdi # param1 = mh of app
8bc9f0af
A
133 pushq $0 # push a zero for debugger end of frames marker
134 movq %rsp,%rbp # pointer to base of kernel frame
135 andq $-16,%rsp # force SSE alignment
832b6fce 136 subq $16,%rsp # room for local variables
6cae9b63 137
cf998323 138 # call dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)
832b6fce
A
139 movl 8(%rbp),%esi # param2 = argc into %esi
140 leaq 16(%rbp),%rdx # param3 = &argv[0] into %rdx
cf998323
A
141 leaq ___dso_handle(%rip),%rcx # param4 = dyldsMachHeader into %rcx
142 leaq -8(%rbp),%r8 # param5 = &glue into %r8
143 call __ZN13dyldbootstrap5startEPKN5dyld311MachOLoadedEiPPKcS3_Pm
832b6fce
A
144 movq -8(%rbp),%rdi
145 cmpq $0,%rdi
146 jne Lnew
8bc9f0af 147
832b6fce 148 # clean up stack and jump to "start" in main executable
8bc9f0af 149 movq %rbp,%rsp # restore the unaligned stack pointer
832b6fce 150 addq $8,%rsp # remove the mh argument, and debugger end frame marker
8bc9f0af
A
151 movq $0,%rbp # restore ebp back to zero
152 jmp *%rax # jump to the entry point
6cae9b63
A
153
154 # LC_MAIN case, set up stack for call to main()
832b6fce
A
155Lnew: addq $16,%rsp # remove local variables
156 pushq %rdi # simulate return address into _start in libdyld
157 movq 8(%rbp),%rdi # main param1 = argc into %rdi
158 leaq 16(%rbp),%rsi # main param2 = &argv[0] into %rsi
159 leaq 0x8(%rsi,%rdi,8),%rdx # main param3 = &env[0] into %rdx
160 movq %rdx,%rcx
161Lapple: movq (%rcx),%r8
162 add $8,%rcx
163 testq %r8,%r8 # look for NULL ending env[] array
164 jne Lapple # main param4 = apple into %rcx
165 jmp *%rax # jump to main(argc,argv,env,apple) with return address set to _start
cf998323 166#endif /* __x86_64__ && !TARGET_OS_SIMULATOR*/
3d7c199a 167
2de2b37b 168
0959b6d4 169
39a8cd10 170#if __arm__
39a8cd10
A
171 .text
172 .align 2
173__dyld_start:
412ebb8e 174 mov r8, sp // save stack pointer
832b6fce 175 sub sp, #16 // make room for outgoing parameters
df9d6cf7 176 bic sp, sp, #15 // force 16-byte alignment
412ebb8e 177
cf998323 178 // call dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)
412ebb8e
A
179 ldr r0, [r8] // r0 = mach_header
180 ldr r1, [r8, #4] // r1 = argc
181 add r2, r8, #8 // r2 = argv
cf998323
A
182 adr r3, __dyld_start
183 sub r3 ,r3, #0x1000 // r3 = dyld_mh
832b6fce 184 add r4, sp, #12
cf998323 185 str r4, [sp, #0] // [sp] = &startGlue
6cae9b63 186
cf998323 187 bl __ZN13dyldbootstrap5startEPKN5dyld311MachOLoadedEiPPKcS3_Pm
832b6fce
A
188 ldr r5, [sp, #12]
189 cmp r5, #0
190 bne Lnew
6cae9b63 191
832b6fce 192 // traditional case, clean up stack and jump to result
39a8cd10
A
193 add sp, r8, #4 // remove the mach_header argument.
194 bx r0 // jump to the program's entry point
195
832b6fce
A
196 // LC_MAIN case, set up stack for call to main()
197Lnew: mov lr, r5 // simulate return address into _start in libdyld
198 mov r5, r0 // save address of main() for later use
199 ldr r0, [r8, #4] // main param1 = argc
200 add r1, r8, #8 // main param2 = argv
6cae9b63 201 add r2, r1, r0, lsl #2
832b6fce
A
202 add r2, r2, #4 // main param3 = &env[0]
203 mov r3, r2
204Lapple: ldr r4, [r3]
205 add r3, #4
206 cmp r4, #0
207 bne Lapple // main param4 = apple
208 bx r5
412ebb8e 209
19894a12
A
210#endif /* __arm__ */
211
212
213
214
bc3b7c8c 215#if __arm64__ && !TARGET_OS_SIMULATOR
39a8cd10
A
216 .text
217 .align 2
19894a12
A
218 .globl __dyld_start
219__dyld_start:
220 mov x28, sp
221 and sp, x28, #~15 // force 16-byte alignment of stack
222 mov x0, #0
223 mov x1, #0
224 stp x1, x0, [sp, #-16]! // make aligned terminating frame
225 mov fp, sp // set up fp to point to terminating frame
226 sub sp, sp, #16 // make room for local variables
6cae9b63
A
227#if __LP64__
228 ldr x0, [x28] // get app's mh into x0
229 ldr x1, [x28, #8] // get argc into x1 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
230 add x2, x28, #16 // get argv into x2
231#else
232 ldr w0, [x28] // get app's mh into x0
233 ldr w1, [x28, #4] // get argc into x1 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
234 add w2, w28, #8 // get argv into x2
235#endif
cf998323
A
236 adrp x3,___dso_handle@page
237 add x3,x3,___dso_handle@pageoff // get dyld's mh in to x4
238 mov x4,sp // x5 has &startGlue
239
240 // call dyldbootstrap::start(app_mh, argc, argv, dyld_mh, &startGlue)
241 bl __ZN13dyldbootstrap5startEPKN5dyld311MachOLoadedEiPPKcS3_Pm
19894a12 242 mov x16,x0 // save entry point address in x16
6cae9b63 243#if __LP64__
19894a12 244 ldr x1, [sp]
6cae9b63
A
245#else
246 ldr w1, [sp]
247#endif
19894a12
A
248 cmp x1, #0
249 b.ne Lnew
250
251 // LC_UNIXTHREAD way, clean up stack and jump to result
6cae9b63
A
252#if __LP64__
253 add sp, x28, #8 // restore unaligned stack pointer without app mh
254#else
255 add sp, x28, #4 // restore unaligned stack pointer without app mh
256#endif
257#if __arm64e__
258 braaz x16 // jump to the program's entry point
259#else
260 br x16 // jump to the program's entry point
261#endif
19894a12
A
262
263 // LC_MAIN case, set up stack for call to main()
264Lnew: mov lr, x1 // simulate return address into _start in libdyld.dylib
6cae9b63
A
265#if __LP64__
266 ldr x0, [x28, #8] // main param1 = argc
267 add x1, x28, #16 // main param2 = argv
268 add x2, x1, x0, lsl #3
269 add x2, x2, #8 // main param3 = &env[0]
19894a12
A
270 mov x3, x2
271Lapple: ldr x4, [x3]
272 add x3, x3, #8
6cae9b63
A
273#else
274 ldr w0, [x28, #4] // main param1 = argc
275 add x1, x28, #8 // main param2 = argv
276 add x2, x1, x0, lsl #2
277 add x2, x2, #4 // main param3 = &env[0]
278 mov x3, x2
279Lapple: ldr w4, [x3]
280 add x3, x3, #4
281#endif
19894a12
A
282 cmp x4, #0
283 b.ne Lapple // main param4 = apple
6cae9b63
A
284#if __arm64e__
285 braaz x16
286#else
287 br x16
288#endif
19894a12 289
bc3b7c8c 290#endif // __arm64__ && !TARGET_OS_SIMULATOR
39a8cd10 291
0959b6d4 292
9f83892a
A
293// When iOS 10.0 simulator runs on 10.11, abort_with_payload() does not exist,
294// so it falls back and uses dyld_fatal_error().
cf998323 295#if TARGET_OS_SIMULATOR
bac542e6
A
296 .text
297 .align 2
298 .globl _dyld_fatal_error
299_dyld_fatal_error:
bc3b7c8c
A
300#if __arm64__ || __arm64e__
301 brk #3
302#else
bac542e6 303 int3
bc3b7c8c 304#endif
39a8cd10 305 nop
bac542e6
A
306#endif
307