dyld-733.8.tar.gz
[apple/dyld.git] / src / stub_binding_helper.s
1 /*
2  * Copyright (c) 1999-2006 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  
25
26 #ifdef __i386__
27 /*
28  * This is the interface for the stub_binding_helper for i386:
29  * The caller has pushed the address of the a lazy pointer to be filled in 
30  * and pushed the address of the the mach header this pointer comes from.
31  *
32  * sp+4 address of lazy pointer
33  * sp+0 address of mach header
34  *
35  * Some inter-image function calls pass parameters in registers EAX, ECX, EDX, or XXM0-3,
36  * Therefore those registers need to be preserved during the lazy binding.
37  * 
38  * After the symbol has been resolved and the lazy pointer filled in, this jumps
39  * to the target address.
40  */
41 #define MH_PARAM_OUT                    0
42 #define LP_PARAM_OUT                    4
43 #define XMMM0_SAVE                      16      /* 16-byte align */
44 #define XMMM1_SAVE                      32
45 #define XMMM2_SAVE                      48
46 #define XMMM3_SAVE                      64
47 #define EAX_SAVE                        84
48 #define ECX_SAVE                        88
49 #define EDX_SAVE                        92
50 #define LP_LOCAL                        96
51 #define MH_LOCAL                        100
52 #define STACK_SIZE                      100     /* must be 4 mod 16 so that stack winds up 16-byte aliged  */
53 #define LP_OLD_BP_SAVE                  104
54
55     .text
56     .align 4,0x90
57         .globl _stub_binding_helper_i386_old
58 _stub_binding_helper_i386_old:
59         pushl           $0
60     .globl _stub_binding_helper
61     .globl _misaligned_stack_error
62 _stub_binding_helper:
63         subl            $STACK_SIZE,%esp            # makes stack 16-byte aligned
64         movl            %eax,EAX_SAVE(%esp)     
65         movl            LP_OLD_BP_SAVE(%esp),%eax   # get lazy-pointer meta-parameter
66         movl            %eax,LP_LOCAL(%esp)     
67         movl            %ebp,LP_OLD_BP_SAVE(%esp)   # store epb back chain
68         movl            %esp,%ebp                   # set epb to be this frame
69         add             $LP_OLD_BP_SAVE,%ebp
70         movl            %ecx,ECX_SAVE(%esp)
71         movl            %edx,EDX_SAVE(%esp)
72         .align 0,0x90
73 _misaligned_stack_error:
74         movdqa          %xmm0,XMMM0_SAVE(%esp)
75         movdqa          %xmm1,XMMM1_SAVE(%esp)
76         movdqa          %xmm2,XMMM2_SAVE(%esp)
77         movdqa          %xmm3,XMMM3_SAVE(%esp)
78 _stub_binding_helper_interface2:
79         movl            MH_LOCAL(%esp),%eax     # call dyld::bindLazySymbol(mh, lazy_ptr)
80         movl            %eax,MH_PARAM_OUT(%esp)
81         movl            LP_LOCAL(%esp),%eax
82         movl            %eax,LP_PARAM_OUT(%esp)
83         call            __ZN4dyld14bindLazySymbolEPK11mach_headerPm
84         movdqa          XMMM0_SAVE(%esp),%xmm0  # restore registers
85         movdqa          XMMM1_SAVE(%esp),%xmm1
86         movdqa          XMMM2_SAVE(%esp),%xmm2
87         movdqa          XMMM3_SAVE(%esp),%xmm3
88         movl            ECX_SAVE(%esp),%ecx
89         movl            EDX_SAVE(%esp),%edx
90         movl            %eax,%ebp               # move target address to epb
91         movl            EAX_SAVE(%esp),%eax     # restore eaz
92         addl            $STACK_SIZE+4,%esp      # cut back stack
93         xchg            %ebp, (%esp)            # restore ebp and set target to top of stack
94         ret                                     # jump to target
95     
96 #endif /* __i386__ */
97
98
99 #if __x86_64__
100 /*
101  * This is the interface for the stub_binding_helper for x86_64:
102  * The caller has pushed the address of the a lazy pointer to be filled in with
103  * the value for the defined symbol and pushed the address of the the mach
104  * header this pointer comes from.
105  *
106  * sp+8 address of lazy pointer
107  * sp+0 address of mach header
108  *
109  * All parameters registers must be preserved.
110  * 
111  * After the symbol has been resolved and the pointer filled in this is to pop
112  * these arguments off the stack and jump to the address of the defined symbol.
113  */
114 #define MH_PARAM_BP                     8
115 #define LP_PARAM_BP                     16
116
117 #define RDI_SAVE                        0
118 #define RSI_SAVE                        8
119 #define RDX_SAVE                        16
120 #define RCX_SAVE                        24
121 #define R8_SAVE                         32
122 #define R9_SAVE                         40
123 #define RAX_SAVE                        48
124 #define XMMM0_SAVE                      64    /* 16-byte align */
125 #define XMMM1_SAVE                      80
126 #define XMMM2_SAVE                      96
127 #define XMMM3_SAVE                      112
128 #define XMMM4_SAVE                      128
129 #define XMMM5_SAVE                      144
130 #define XMMM6_SAVE                      160
131 #define XMMM7_SAVE                      176
132 #define STACK_SIZE                      192 /*  (XMMM7_SAVE+16) must be 16 byte aligned too */
133     
134     .text
135     .align 2,0x90
136     .globl _stub_binding_helper
137 _stub_binding_helper:
138         pushq           %rbp
139         movq            %rsp,%rbp
140         subq            $STACK_SIZE,%rsp        # at this point stack is 16-byte aligned because two meta-parameters where pushed
141         movq            %rdi,RDI_SAVE(%rsp)     # save registers that might be used as parameters
142         movq            %rsi,RSI_SAVE(%rsp)
143         movq            %rdx,RDX_SAVE(%rsp)
144         movq            %rcx,RCX_SAVE(%rsp)
145         movq            %r8,R8_SAVE(%rsp)
146         movq            %r9,R9_SAVE(%rsp)
147         movq            %rax,RAX_SAVE(%rsp)
148         movdqa          %xmm0,XMMM0_SAVE(%rsp)
149         movdqa          %xmm1,XMMM1_SAVE(%rsp)
150         movdqa          %xmm2,XMMM2_SAVE(%rsp)
151         movdqa          %xmm3,XMMM3_SAVE(%rsp)
152         movdqa          %xmm4,XMMM4_SAVE(%rsp)
153         movdqa          %xmm5,XMMM5_SAVE(%rsp)
154         movdqa          %xmm6,XMMM6_SAVE(%rsp)
155         movdqa          %xmm7,XMMM7_SAVE(%rsp)
156         movq            MH_PARAM_BP(%rbp),%rdi  # call dyld::bindLazySymbol(mh, lazy_ptr)
157         movq            LP_PARAM_BP(%rbp),%rsi
158         call            __ZN4dyld14bindLazySymbolEPK11mach_headerPm
159         movq            %rax,%r11               # save target
160         movdqa          XMMM0_SAVE(%rsp),%xmm0  # restore registers
161         movdqa          XMMM1_SAVE(%rsp),%xmm1
162         movdqa          XMMM2_SAVE(%rsp),%xmm2
163         movdqa          XMMM3_SAVE(%rsp),%xmm3
164         movdqa          XMMM4_SAVE(%rsp),%xmm4
165         movdqa          XMMM5_SAVE(%rsp),%xmm5
166         movdqa          XMMM6_SAVE(%rsp),%xmm6
167         movdqa          XMMM7_SAVE(%rsp),%xmm7
168         movq            RDI_SAVE(%rsp),%rdi
169         movq            RSI_SAVE(%rsp),%rsi
170         movq            RDX_SAVE(%rsp),%rdx
171         movq            RCX_SAVE(%rsp),%rcx
172         movq            R8_SAVE(%rsp),%r8
173         movq            R9_SAVE(%rsp),%r9
174         movq            RAX_SAVE(%rsp),%rax
175         addq            $STACK_SIZE,%rsp
176         popq            %rbp
177         addq            $16,%rsp                # remove meta-parameters
178         jmp             *%r11                   # jmp to target
179
180 #endif
181
182
183 #if __arm__ && !__ARM_ARCH_7K__
184 /*
185  * This is the interface for the old stub_binding_helper for ARM:
186  * The caller has pushed the address of the a lazy pointer to be filled in with
187  * the value for the defined symbol and pushed the address of the the mach
188  * header this pointer comes from.
189  *
190  * sp+4        address of lazy pointer
191  * sp+0        address of mach header
192  * 
193  * After the symbol has been resolved and the pointer filled in this is to pop
194  * these arguments off the stack and jump to the address of the defined symbol.
195  */
196   
197         .text
198         .align 2
199         .globl  _stub_binding_helper
200 _stub_binding_helper:
201         stmfd   sp!, {r0,r1,r2,r3,r7,lr}        // save registers
202         add     r7, sp, #16                     // point FP to previous FP
203
204         ldr     r0, [sp, #24]                   // move address of mach header to 1st parameter
205         ldr     r1, [sp, #28]                   // move address of lazy pointer to 2nd parameter
206
207         // call dyld::bindLazySymbol(mh, lazy_symbol_pointer_address)
208         bl      __ZN4dyld14bindLazySymbolEPK11mach_headerPm
209         mov     ip, r0                          // move the symbol`s address into ip
210
211         ldmfd   sp!, {r0,r1,r2,r3,r7,lr}        // restore registers
212         add     sp, sp, #8                      // remove meta-parameters
213
214         bx      ip                              // jump to the symbol`s address that was bound
215
216 #endif /* __arm__ */
217
218
219
220
221
222
223
224
225
226