]> git.saurik.com Git - apple/dyld.git/blame - src/stub_binding_helper.s
dyld-360.21.tar.gz
[apple/dyld.git] / src / stub_binding_helper.s
CommitLineData
0959b6d4 1/*
3d7c199a 2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
0959b6d4
A
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:
bac542e6
A
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.
0959b6d4
A
31 *
32 * sp+4 address of lazy pointer
33 * sp+0 address of mach header
34 *
d6f5f96d 35 * Some inter-image function calls pass parameters in registers EAX, ECX, EDX, or XXM0-3,
9e225d03
A
36 * Therefore those registers need to be preserved during the lazy binding.
37 *
bac542e6
A
38 * After the symbol has been resolved and the lazy pointer filled in, this jumps
39 * to the target address.
0959b6d4 40 */
bac542e6
A
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
d6f5f96d
A
54
55 .text
56 .align 4,0x90
19894a12
A
57 .globl _stub_binding_helper_i386_old
58_stub_binding_helper_i386_old:
a3afc008 59 pushl $0
19894a12 60 .globl _stub_binding_helper
bac542e6 61 .globl _misaligned_stack_error
19894a12 62_stub_binding_helper:
bac542e6
A
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
d6f5f96d
A
70 movl %ecx,ECX_SAVE(%esp)
71 movl %edx,EDX_SAVE(%esp)
bac542e6
A
72 .align 0,0x90
73_misaligned_stack_error:
a3afc008
A
74 movdqa %xmm0,XMMM0_SAVE(%esp)
75 movdqa %xmm1,XMMM1_SAVE(%esp)
76 movdqa %xmm2,XMMM2_SAVE(%esp)
77 movdqa %xmm3,XMMM3_SAVE(%esp)
bac542e6
A
78_stub_binding_helper_interface2:
79 movl MH_LOCAL(%esp),%eax # call dyld::bindLazySymbol(mh, lazy_ptr)
d6f5f96d 80 movl %eax,MH_PARAM_OUT(%esp)
bac542e6 81 movl LP_LOCAL(%esp),%eax
d6f5f96d
A
82 movl %eax,LP_PARAM_OUT(%esp)
83 call __ZN4dyld14bindLazySymbolEPK11mach_headerPm
a3afc008
A
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
d6f5f96d
A
88 movl ECX_SAVE(%esp),%ecx
89 movl EDX_SAVE(%esp),%edx
bac542e6
A
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
0959b6d4
A
96#endif /* __i386__ */
97
98
8bc9f0af
A
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 *
bac542e6 106 * sp+8 address of lazy pointer
8bc9f0af
A
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
19894a12
A
136 .globl _stub_binding_helper
137_stub_binding_helper:
8bc9f0af
A
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
3d7c199a 181
bac542e6 182
df9d6cf7 183#if __arm__ && !__ARM_ARCH_7K__
39a8cd10 184/*
df9d6cf7 185 * This is the interface for the old stub_binding_helper for ARM:
39a8cd10
A
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
19894a12
A
199 .globl _stub_binding_helper
200_stub_binding_helper:
39a8cd10
A
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__ */
0959b6d4
A
217
218
219
220
221
222
223
224
225
226