dyld-45.1.tar.gz
[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
127 #if __ppc__ || __ppc64__
128 #include <architecture/ppc/mode_independent_asm.h>
129
130         .data
131         .align 2
132 __dyld_start_static_picbase: 
133         .g_long   L__dyld_start_picbase
134
135 #if __ppc__     
136         .set L_mh_offset,0
137         .set L_argc_offset,4
138         .set L_argv_offset,8
139 #else
140         .set L_mh_offset,0
141         .set L_argc_offset,8    ; stack is 8-byte aligned and there is a 4-byte hole between argc and argv
142         .set L_argv_offset,16
143 #endif
144
145         .text
146         .align 2
147 ; stable entry points into dyld
148         .globl  _stub_binding_helper
149 _stub_binding_helper:
150         b       _stub_binding_helper_interface
151         nop 
152         .globl  _dyld_func_lookup
153 _dyld_func_lookup:
154         b       __Z18lookupDyldFunctionPKcPm
155         
156         
157         
158         .text
159         .align 2
160 __dyld_start:
161         mr      r26,r1          ; save original stack pointer into r26
162         subi    r1,r1,GPR_BYTES ; make space for linkage
163         clrrgi  r1,r1,5         ; align to 32 bytes
164         addi    r0,0,0          ; load 0 into r0
165         stg     r0,0(r1)        ; terminate initial stack frame
166         stgu    r1,-SF_MINSIZE(r1); allocate minimal stack frame
167                 
168         ; call dyldbootstrap::start(app_mh, argc, argv, slide)
169         lg      r3,L_mh_offset(r26)     ; r3 = mach_header
170         lwz     r4,L_argc_offset(r26)   ; r4 = argc (int == 4 bytes)
171         addi    r5,r26,L_argv_offset    ; r5 = argv
172         bcl     20,31,L__dyld_start_picbase     
173 L__dyld_start_picbase:  
174         mflr    r31             ; put address of L__dyld_start_picbase in r31
175         addis   r6,r31,ha16(__dyld_start_static_picbase-L__dyld_start_picbase)
176         lg      r6,lo16(__dyld_start_static_picbase-L__dyld_start_picbase)(r6)
177         subf    r6,r6,r31       ; r6 = slide
178         bl      __ZN13dyldbootstrap5startEPK11mach_headeriPPKcl 
179         
180         ; clean up stack and jump to result
181         mtctr   r3              ; Put entry point in count register
182         mr      r12,r3          ;  also put in r12 for ABI convention.
183         addi    r1,r26,GPR_BYTES; Restore the stack pointer and remove the
184                                 ;  mach_header argument.
185         bctr                    ; jump to the program's entry point
186
187         .globl dyld_stub_binding_helper
188 dyld_stub_binding_helper:
189         trap
190 L_end:
191 #endif /* __ppc__ */
192
193