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