]> git.saurik.com Git - apple/dyld.git/blob - src/dyldStartup.s
2afa8d43e651a3592caa378e7a6a45006f97e3a2
[apple/dyld.git] / src / dyldStartup.s
1 /*
2 * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
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.
27 *
28 * Kernel sets up stack frame to look like:
29 *
30 * | STRING AREA |
31 * +-------------+
32 * | 0 |
33 * +-------------+
34 * | apple[n] |
35 * +-------------+
36 * :
37 * +-------------+
38 * | apple[0] |
39 * +-------------+
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
66 .globl __dyld_start
67
68
69 #ifdef __i386__
70 .data
71 __dyld_start_static_picbase:
72 .long L__dyld_start_picbase
73
74
75 .text
76 .align 2
77 # stable entry points into dyld
78 .globl _stub_binding_helper
79 _stub_binding_helper:
80 jmp _stub_binding_helper_interface
81 nop
82 nop
83 nop
84 .globl _dyld_func_lookup
85 _dyld_func_lookup:
86 jmp __Z18lookupDyldFunctionPKcPm
87
88 .text
89 .align 4, 0x90
90 .globl __dyld_start
91 __dyld_start:
92 pushl $0 # push a zero for debugger end of frames marker
93 movl %esp,%ebp # pointer to base of kernel frame
94 andl $-16,%esp # force SSE alignment
95
96 # call dyldbootstrap::start(app_mh, argc, argv, slide)
97 call L__dyld_start_picbase
98 L__dyld_start_picbase:
99 popl %ebx # set %ebx to runtime value of picbase
100 movl __dyld_start_static_picbase-L__dyld_start_picbase(%ebx), %eax
101 subl %eax, %ebx # slide = L__dyld_start_picbase - [__dyld_start_static_picbase]
102 pushl %ebx # param4 = slide
103 lea 12(%ebp),%ebx
104 pushl %ebx # param3 = argv
105 movl 8(%ebp),%ebx
106 pushl %ebx # param2 = argc
107 movl 4(%ebp),%ebx
108 pushl %ebx # param1 = mh
109 call __ZN13dyldbootstrap5startEPK11mach_headeriPPKcl
110
111 # clean up stack and jump to result
112 movl %ebp,%esp # restore the unaligned stack pointer
113 addl $8,%esp # remove the mh argument, and debugger end
114 # frame marker
115 movl $0,%ebp # restore ebp back to zero
116 jmp %eax # jump to the entry point
117
118
119 .globl dyld_stub_binding_helper
120 dyld_stub_binding_helper:
121 hlt
122 L_end:
123 #endif /* __i386__ */
124
125
126 #if __x86_64__
127 .data
128 .align 3
129 __dyld_start_static:
130 .quad __dyld_start
131
132 # stable entry points into dyld
133 .text
134 .align 2
135 .globl _stub_binding_helper
136 _stub_binding_helper:
137 jmp _stub_binding_helper_interface
138 nop
139 nop
140 nop
141 .globl _dyld_func_lookup
142 _dyld_func_lookup:
143 jmp __Z18lookupDyldFunctionPKcPm
144
145 .text
146 .align 2,0x90
147 .globl __dyld_start
148 __dyld_start:
149 pushq $0 # push a zero for debugger end of frames marker
150 movq %rsp,%rbp # pointer to base of kernel frame
151 andq $-16,%rsp # force SSE alignment
152
153 # call dyldbootstrap::start(app_mh, argc, argv, slide)
154 movq 8(%rbp),%rdi # param1 = mh into %rdi
155 movl 16(%rbp),%esi # param2 = argc into %esi
156 leaq 24(%rbp),%rdx # param3 = &argv[0] into %rdx
157 movq __dyld_start_static(%rip), %r8
158 leaq __dyld_start(%rip), %rcx
159 subq %r8, %rcx # param4 = slide into %rcx
160 call __ZN13dyldbootstrap5startEPK11mach_headeriPPKcl
161
162 # clean up stack and jump to result
163 movq %rbp,%rsp # restore the unaligned stack pointer
164 addq $16,%rsp # remove the mh argument, and debugger end frame marker
165 movq $0,%rbp # restore ebp back to zero
166 jmp *%rax # jump to the entry point
167 #endif /* __x86_64__ */
168
169
170 #if __ppc__ || __ppc64__
171 #include <architecture/ppc/mode_independent_asm.h>
172
173 .data
174 .align 2
175 __dyld_start_static_picbase:
176 .g_long L__dyld_start_picbase
177
178 #if __ppc__
179 .set L_mh_offset,0
180 .set L_argc_offset,4
181 .set L_argv_offset,8
182 #else
183 .set L_mh_offset,0
184 .set L_argc_offset,8 ; stack is 8-byte aligned and there is a 4-byte hole between argc and argv
185 .set L_argv_offset,16
186 #endif
187
188 .text
189 .align 2
190 ; stable entry points into dyld
191 .globl _stub_binding_helper
192 _stub_binding_helper:
193 b _stub_binding_helper_interface
194 nop
195 .globl _dyld_func_lookup
196 _dyld_func_lookup:
197 b __Z18lookupDyldFunctionPKcPm
198
199
200
201 .text
202 .align 2
203 __dyld_start:
204 mr r26,r1 ; save original stack pointer into r26
205 subi r1,r1,GPR_BYTES ; make space for linkage
206 clrrgi r1,r1,5 ; align to 32 bytes
207 addi r0,0,0 ; load 0 into r0
208 stg r0,0(r1) ; terminate initial stack frame
209 stgu r1,-SF_MINSIZE(r1); allocate minimal stack frame
210
211 ; call dyldbootstrap::start(app_mh, argc, argv, slide)
212 lg r3,L_mh_offset(r26) ; r3 = mach_header
213 lwz r4,L_argc_offset(r26) ; r4 = argc (int == 4 bytes)
214 addi r5,r26,L_argv_offset ; r5 = argv
215 bcl 20,31,L__dyld_start_picbase
216 L__dyld_start_picbase:
217 mflr r31 ; put address of L__dyld_start_picbase in r31
218 addis r6,r31,ha16(__dyld_start_static_picbase-L__dyld_start_picbase)
219 lg r6,lo16(__dyld_start_static_picbase-L__dyld_start_picbase)(r6)
220 subf r6,r6,r31 ; r6 = slide
221 bl __ZN13dyldbootstrap5startEPK11mach_headeriPPKcl
222
223 ; clean up stack and jump to result
224 mtctr r3 ; Put entry point in count register
225 mr r12,r3 ; also put in r12 for ABI convention.
226 addi r1,r26,GPR_BYTES; Restore the stack pointer and remove the
227 ; mach_header argument.
228 bctr ; jump to the program's entry point
229
230 .globl dyld_stub_binding_helper
231 dyld_stub_binding_helper:
232 trap
233 L_end:
234 #endif /* __ppc__ */
235
236