2 * Copyright (c) 1999-2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 * C runtime startup for i386 and ppc interface to the dynamic linker.
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.
28 * Kernel sets up stack frame to look like:
60 * sp-> | mh | address of where the a.out's file offset 0 is in memory
63 * Where arg[i] and env[i] point into the STRING AREA
68 // Hack to make _offset_to_dyld_all_image_infos work
69 // Without this local symbol, assembler will error out about in subtraction expression
70 // The real _dyld_all_image_infos (non-weak) _dyld_all_image_infos is defined in dyld_gdb.o
71 // and the linker with throw this one away and use the real one instead.
72 .section __DATA,__datacoal_nt,coalesced
73 .globl _dyld_all_image_infos
74 .weak_definition _dyld_all_image_infos
75 _dyld_all_image_infos: .long 0
83 __dyld_start_static_picbase:
84 .long L__dyld_start_picbase
89 # stable entry points into dyld
90 .globl _stub_binding_helper
92 jmp _stub_binding_helper_interface
96 .globl _dyld_func_lookup
98 jmp __Z18lookupDyldFunctionPKcPm
102 _offset_to_dyld_all_image_infos:
103 .long _dyld_all_image_infos - . + 0x1010
105 # space for future stable entry points
114 pushl $0 # push a zero for debugger end of frames marker
115 movl %esp,%ebp # pointer to base of kernel frame
116 andl $-16,%esp # force SSE alignment
118 # call dyldbootstrap::start(app_mh, argc, argv, slide)
119 call L__dyld_start_picbase
120 L__dyld_start_picbase:
121 popl %ebx # set %ebx to runtime value of picbase
122 movl __dyld_start_static_picbase-L__dyld_start_picbase(%ebx), %eax
123 subl %eax, %ebx # slide = L__dyld_start_picbase - [__dyld_start_static_picbase]
124 pushl %ebx # param4 = slide
126 pushl %ebx # param3 = argv
128 pushl %ebx # param2 = argc
130 pushl %ebx # param1 = mh
131 call __ZN13dyldbootstrap5startEPK12macho_headeriPPKcl
133 # clean up stack and jump to result
134 movl %ebp,%esp # restore the unaligned stack pointer
135 addl $8,%esp # remove the mh argument, and debugger end
137 movl $0,%ebp # restore ebp back to zero
138 jmp *%eax # jump to the entry point
141 .globl dyld_stub_binding_helper
142 dyld_stub_binding_helper:
145 #endif /* __i386__ */
155 # stable entry points into dyld
158 .globl _stub_binding_helper
159 _stub_binding_helper:
160 jmp _stub_binding_helper_interface
164 .globl _dyld_func_lookup
166 jmp __Z18lookupDyldFunctionPKcPm
170 _offset_to_dyld_all_image_infos:
171 .long _dyld_all_image_infos - . + 0x1010
173 # space for future stable entry points
181 pushq $0 # push a zero for debugger end of frames marker
182 movq %rsp,%rbp # pointer to base of kernel frame
183 andq $-16,%rsp # force SSE alignment
185 # call dyldbootstrap::start(app_mh, argc, argv, slide)
186 movq 8(%rbp),%rdi # param1 = mh into %rdi
187 movl 16(%rbp),%esi # param2 = argc into %esi
188 leaq 24(%rbp),%rdx # param3 = &argv[0] into %rdx
189 movq __dyld_start_static(%rip), %r8
190 leaq __dyld_start(%rip), %rcx
191 subq %r8, %rcx # param4 = slide into %rcx
192 call __ZN13dyldbootstrap5startEPK12macho_headeriPPKcl
194 # clean up stack and jump to result
195 movq %rbp,%rsp # restore the unaligned stack pointer
196 addq $16,%rsp # remove the mh argument, and debugger end frame marker
197 movq $0,%rbp # restore ebp back to zero
198 jmp *%rax # jump to the entry point
200 #endif /* __x86_64__ */
203 #if __ppc__ || __ppc64__
204 #include <architecture/ppc/mode_independent_asm.h>
208 __dyld_start_static_picbase:
209 .g_long L__dyld_start_picbase
217 .set L_argc_offset,8 ; stack is 8-byte aligned and there is a 4-byte hole between argc and argv
218 .set L_argv_offset,16
223 ; stable entry points into dyld
224 .globl _stub_binding_helper
225 _stub_binding_helper:
226 b _stub_binding_helper_interface
228 .globl _dyld_func_lookup
230 b __Z18lookupDyldFunctionPKcPm
232 _offset_to_dyld_all_image_infos:
233 .long _dyld_all_image_infos - . + 0x1010
235 # space for future stable entry points
242 mr r26,r1 ; save original stack pointer into r26
243 subi r1,r1,GPR_BYTES ; make space for linkage
244 clrrgi r1,r1,5 ; align to 32 bytes
245 addi r0,0,0 ; load 0 into r0
246 stg r0,0(r1) ; terminate initial stack frame
247 stgu r1,-SF_MINSIZE(r1); allocate minimal stack frame
249 ; call dyldbootstrap::start(app_mh, argc, argv, slide)
250 lg r3,L_mh_offset(r26) ; r3 = mach_header
251 lwz r4,L_argc_offset(r26) ; r4 = argc (int == 4 bytes)
252 addi r5,r26,L_argv_offset ; r5 = argv
253 bcl 20,31,L__dyld_start_picbase
254 L__dyld_start_picbase:
255 mflr r31 ; put address of L__dyld_start_picbase in r31
256 addis r6,r31,ha16(__dyld_start_static_picbase-L__dyld_start_picbase)
257 lg r6,lo16(__dyld_start_static_picbase-L__dyld_start_picbase)(r6)
258 subf r6,r6,r31 ; r6 = slide
259 bl __ZN13dyldbootstrap5startEPK12macho_headeriPPKcl
261 ; clean up stack and jump to result
262 mtctr r3 ; Put entry point in count register
263 mr r12,r3 ; also put in r12 for ABI convention.
264 addi r1,r26,GPR_BYTES; Restore the stack pointer and remove the
265 ; mach_header argument.
266 bctr ; jump to the program's entry point
268 .globl dyld_stub_binding_helper
269 dyld_stub_binding_helper:
277 __dyld_start_static_picbase:
278 .long L__dyld_start_picbase
282 .globl _stub_binding_helper
283 _stub_binding_helper:
284 b _stub_binding_helper_interface
287 .globl _dyld_func_lookup
289 b _branch_to_lookupDyldFunction
292 _offset_to_dyld_all_image_infos:
293 .long _dyld_all_image_infos - . + 0x1010
295 # space for future stable entry points
302 // call dyldbootstrap::start(app_mh, argc, argv, slide)
304 ldr r3, L__dyld_start_picbase_ptr
305 L__dyld_start_picbase:
306 sub r0, pc, #8 // load actual PC
307 ldr r3, [r0, r3] // load expected PC
308 sub r3, r0, r3 // r3 = slide
310 ldr r0, [sp] // r0 = mach_header
311 ldr r1, [sp, #4] // r1 = argc
312 add r2, sp, #8 // r2 = argv
314 mov r8, sp // save stack pointer
315 bic sp, sp, #7 // force 8-byte alignment
317 bl __ZN13dyldbootstrap5startEPK12macho_headeriPPKcl
319 // clean up stack and jump to result
320 add sp, r8, #4 // remove the mach_header argument.
321 bx r0 // jump to the program's entry point
324 L__dyld_start_picbase_ptr:
325 .long __dyld_start_static_picbase-L__dyld_start_picbase
330 _branch_to_lookupDyldFunction:
331 // arm has no "bx label" instruction, so need this island in case lookupDyldFunction() is in thumb
334 L2: .long _lookupDyldFunction_ptr-8-L1
338 _lookupDyldFunction_ptr:
339 .long __Z18lookupDyldFunctionPKcPm
343 .globl dyld_stub_binding_helper
344 dyld_stub_binding_helper:
351 * dyld calls this function to terminate a process.
352 * It has a label so that CrashReporter can distinguish this
353 * termination from a random crash. rdar://problem/4764143
357 .globl _dyld_fatal_error
359 #if __ppc__ || __ppc64__ || __arm__
362 #elif __x86_64__ || __i386__
366 #error unknown architecture