2 * Copyright (c) 1999-2011 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 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
85 Lmh: .long ___dso_handle
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 popl %edx # edx = mh of app
115 pushl $0 # push a zero for debugger end of frames marker
116 movl %esp,%ebp # pointer to base of kernel frame
117 andl $-16,%esp # force SSE alignment
118 subl $32,%esp # room for locals and outgoing parameters
120 call L__dyld_start_picbase
121 L__dyld_start_picbase:
122 popl %ebx # set %ebx to runtime value of picbase
124 movl Lmh-L__dyld_start_picbase(%ebx), %ecx # ecx = prefered load address
125 movl __dyld_start_static_picbase-L__dyld_start_picbase(%ebx), %eax
126 subl %eax, %ebx # ebx = slide = L__dyld_start_picbase - [__dyld_start_static_picbase]
127 addl %ebx, %ecx # ecx = actual load address
128 # call dyldbootstrap::start(app_mh, argc, argv, slide, dyld_mh, &startGlue)
129 movl %edx,(%esp) # param1 = app_mh
131 movl %eax,4(%esp) # param2 = argc
133 movl %eax,8(%esp) # param3 = argv
134 movl %ebx,12(%esp) # param4 = slide
135 movl %ecx,16(%esp) # param5 = actual load address
137 movl %eax,20(%esp) # param6 = &startGlue
138 call __ZN13dyldbootstrap5startEPK12macho_headeriPPKclS2_Pm
143 # clean up stack and jump to "start" in main executable
144 movl %ebp,%esp # restore the unaligned stack pointer
145 addl $4,%esp # remove debugger end frame marker
146 movl $0,%ebp # restore ebp back to zero
147 jmp *%eax # jump to the entry point
149 # LC_MAIN case, set up stack for call to main()
150 Lnew: movl 4(%ebp),%ebx
151 movl %ebx,(%esp) # main param1 = argc
153 movl %ecx,4(%esp) # main param2 = argv
154 leal 0x4(%ecx,%ebx,4),%ebx
155 movl %ebx,8(%esp) # main param3 = env
156 Lapple: movl (%ebx),%ecx # look for NULL ending env[] array
159 jne Lapple # once found, next pointer is "apple" parameter now in %ebx
160 movl %ebx,12(%esp) # main param4 = apple
161 pushl %edx # simulate return address into _start in libdyld
162 jmp *%eax # jump to main(argc,argv,env,apple) with return address set to _start
165 .globl dyld_stub_binding_helper
166 dyld_stub_binding_helper:
169 #endif /* __i386__ */
179 # stable entry points into dyld
182 .globl _stub_binding_helper
183 _stub_binding_helper:
184 jmp _stub_binding_helper_interface
188 .globl _dyld_func_lookup
190 jmp __Z18lookupDyldFunctionPKcPm
194 _offset_to_dyld_all_image_infos:
195 .long _dyld_all_image_infos - . + 0x1010
197 # space for future stable entry points
205 popq %rdi # param1 = mh of app
206 pushq $0 # push a zero for debugger end of frames marker
207 movq %rsp,%rbp # pointer to base of kernel frame
208 andq $-16,%rsp # force SSE alignment
209 subq $16,%rsp # room for local variables
211 # call dyldbootstrap::start(app_mh, argc, argv, slide, dyld_mh, &startGlue)
212 movl 8(%rbp),%esi # param2 = argc into %esi
213 leaq 16(%rbp),%rdx # param3 = &argv[0] into %rdx
214 movq __dyld_start_static(%rip), %r8
215 leaq __dyld_start(%rip), %rcx
216 subq %r8, %rcx # param4 = slide into %rcx
217 leaq ___dso_handle(%rip),%r8 # param5 = dyldsMachHeader
219 call __ZN13dyldbootstrap5startEPK12macho_headeriPPKclS2_Pm
224 # clean up stack and jump to "start" in main executable
225 movq %rbp,%rsp # restore the unaligned stack pointer
226 addq $8,%rsp # remove the mh argument, and debugger end frame marker
227 movq $0,%rbp # restore ebp back to zero
228 jmp *%rax # jump to the entry point
230 # LC_MAIN case, set up stack for call to main()
231 Lnew: addq $16,%rsp # remove local variables
232 pushq %rdi # simulate return address into _start in libdyld
233 movq 8(%rbp),%rdi # main param1 = argc into %rdi
234 leaq 16(%rbp),%rsi # main param2 = &argv[0] into %rsi
235 leaq 0x8(%rsi,%rdi,8),%rdx # main param3 = &env[0] into %rdx
237 Lapple: movq (%rcx),%r8
239 testq %r8,%r8 # look for NULL ending env[] array
240 jne Lapple # main param4 = apple into %rcx
241 jmp *%rax # jump to main(argc,argv,env,apple) with return address set to _start
243 #endif /* __x86_64__ */
251 __dyld_start_static_picbase:
252 .long L__dyld_start_picbase
256 .globl _stub_binding_helper
257 _stub_binding_helper:
258 b _stub_binding_helper_interface
261 .globl _dyld_func_lookup
263 b _branch_to_lookupDyldFunction
266 _offset_to_dyld_all_image_infos:
267 .long _dyld_all_image_infos - . + 0x1010
269 # space for future stable entry points
273 // Hack to make ___dso_handle work
274 // Without this local symbol, assembler will error out about in subtraction expression
275 // The real ___dso_handle (non-weak) sythesized by the linker
276 // Since this one is weak, the linker will throw this one away and use the real one instead.
279 .weak_definition ___dso_handle
280 ___dso_handle: .long 0
285 mov r8, sp // save stack pointer
286 sub sp, #16 // make room for outgoing parameters
287 bic sp, sp, #7 // force 8-byte alignment
289 // call dyldbootstrap::start(app_mh, argc, argv, slide, dyld_mh, &startGlue)
291 ldr r3, L__dyld_start_picbase_ptr
292 L__dyld_start_picbase:
293 sub r0, pc, #8 // load actual PC
294 ldr r3, [r0, r3] // load expected PC
295 sub r3, r0, r3 // r3 = slide
297 ldr r0, [r8] // r0 = mach_header
298 ldr r1, [r8, #4] // r1 = argc
299 add r2, r8, #8 // r2 = argv
303 str r4, [sp, #0] // [sp] = dyld_mh
305 str r4, [sp, #4] // [sp+4] = &startGlue
307 bl __ZN13dyldbootstrap5startEPK12macho_headeriPPKclS2_Pm
312 // traditional case, clean up stack and jump to result
313 add sp, r8, #4 // remove the mach_header argument.
314 bx r0 // jump to the program's entry point
316 // LC_MAIN case, set up stack for call to main()
317 Lnew: mov lr, r5 // simulate return address into _start in libdyld
318 mov r5, r0 // save address of main() for later use
319 ldr r0, [r8, #4] // main param1 = argc
320 add r1, r8, #8 // main param2 = argv
321 add r2, r1, r0, lsl #2
322 add r2, r2, #4 // main param3 = &env[0]
327 bne Lapple // main param4 = apple
331 L__dyld_start_picbase_ptr:
332 .long __dyld_start_static_picbase-L__dyld_start_picbase
333 Lmh: .long ___dso_handle-L3-8
337 _branch_to_lookupDyldFunction:
338 // arm has no "bx label" instruction, so need this island in case lookupDyldFunction() is in thumb
341 L2: .long _lookupDyldFunction_ptr-8-L1
345 _lookupDyldFunction_ptr:
346 .long __Z18lookupDyldFunctionPKcPm
350 .globl dyld_stub_binding_helper
351 dyld_stub_binding_helper:
358 * dyld calls this function to terminate a process.
359 * It has a label so that CrashReporter can distinguish this
360 * termination from a random crash. rdar://problem/4764143
364 .globl _dyld_fatal_error
369 #elif __x86_64__ || __i386__
373 #error unknown architecture
377 // work around for: <rdar://problem/6530727> gdb-1109: notifier in dyld does not work if it is in thumb
380 .globl _gdb_image_notifier
381 .private_extern _gdb_image_notifier