]> git.saurik.com Git - apple/dyld.git/blame - src/stub_binding_helper.s
dyld-46.12.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:
29 * The caller has pushed the address of the a lazy pointer to be filled in with
30 * the value for the defined symbol and pushed the address of the the mach
31 * header this pointer comes from.
32 *
33 * sp+4 address of lazy pointer
34 * sp+0 address of mach header
35 *
d6f5f96d 36 * Some inter-image function calls pass parameters in registers EAX, ECX, EDX, or XXM0-3,
9e225d03
A
37 * Therefore those registers need to be preserved during the lazy binding.
38 *
0959b6d4
A
39 * After the symbol has been resolved and the pointer filled in this is to pop
40 * these arguments off the stack and jump to the address of the defined symbol.
41 */
d6f5f96d
A
42#define MH_PARAM_BP 4
43#define LP_PARAM_BP 8
44#define RESULT_BP 8 /* in order to trash no registers, the target is stored back on the stack then ret it done to it */
45
46#define MH_PARAM_OUT 0
47#define LP_PARAM_OUT 4
48#define EAX_SAVE 8
49#define ECX_SAVE 12
50#define EDX_SAVE 16
51#define XMMM0_SAVE 32 /* 16-byte align */
52#define XMMM1_SAVE 48
53#define XMMM2_SAVE 64
54#define XMMM3_SAVE 80
55#define STACK_SIZE 96 /* (XMMM3_SAVE+16) must be 16 byte aligned too */
56
57
58 .text
59 .align 4,0x90
a3afc008
A
60 .globl _fast_stub_binding_helper_interface
61_fast_stub_binding_helper_interface:
62 pushl $0
d6f5f96d 63 .globl _stub_binding_helper_interface
0959b6d4 64_stub_binding_helper_interface:
d6f5f96d
A
65 pushl %ebp
66 movl %esp,%ebp
67 subl $STACK_SIZE,%esp # at this point stack is 16-byte aligned because two meta-parameters where pushed
68 movl %eax,EAX_SAVE(%esp) # save registers that might be used as parameters
69 movl %ecx,ECX_SAVE(%esp)
70 movl %edx,EDX_SAVE(%esp)
a3afc008
A
71 movdqa %xmm0,XMMM0_SAVE(%esp)
72 movdqa %xmm1,XMMM1_SAVE(%esp)
73 movdqa %xmm2,XMMM2_SAVE(%esp)
74 movdqa %xmm3,XMMM3_SAVE(%esp)
d6f5f96d
A
75 movl MH_PARAM_BP(%ebp),%eax # call dyld::bindLazySymbol(mh, lazy_ptr)
76 movl %eax,MH_PARAM_OUT(%esp)
77 movl LP_PARAM_BP(%ebp),%eax
78 movl %eax,LP_PARAM_OUT(%esp)
79 call __ZN4dyld14bindLazySymbolEPK11mach_headerPm
80 movl %eax,RESULT_BP(%ebp) # store target for ret
a3afc008
A
81 movdqa XMMM0_SAVE(%esp),%xmm0 # restore registers
82 movdqa XMMM1_SAVE(%esp),%xmm1
83 movdqa XMMM2_SAVE(%esp),%xmm2
84 movdqa XMMM3_SAVE(%esp),%xmm3
d6f5f96d
A
85 movl EAX_SAVE(%esp),%eax
86 movl ECX_SAVE(%esp),%ecx
87 movl EDX_SAVE(%esp),%edx
88 addl $STACK_SIZE,%esp
89 popl %ebp
90 addl $4,%esp # remove meta-parameter, other meta-parmaeter now holds target for ret
9e225d03 91 ret
0959b6d4
A
92#endif /* __i386__ */
93
94
d6f5f96d 95
8bc9f0af
A
96#if __x86_64__
97/*
98 * This is the interface for the stub_binding_helper for x86_64:
99 * The caller has pushed the address of the a lazy pointer to be filled in with
100 * the value for the defined symbol and pushed the address of the the mach
101 * header this pointer comes from.
102 *
103 * sp+4 address of lazy pointer
104 * sp+0 address of mach header
105 *
106 * All parameters registers must be preserved.
107 *
108 * After the symbol has been resolved and the pointer filled in this is to pop
109 * these arguments off the stack and jump to the address of the defined symbol.
110 */
111#define MH_PARAM_BP 8
112#define LP_PARAM_BP 16
113
114#define RDI_SAVE 0
115#define RSI_SAVE 8
116#define RDX_SAVE 16
117#define RCX_SAVE 24
118#define R8_SAVE 32
119#define R9_SAVE 40
120#define RAX_SAVE 48
121#define XMMM0_SAVE 64 /* 16-byte align */
122#define XMMM1_SAVE 80
123#define XMMM2_SAVE 96
124#define XMMM3_SAVE 112
125#define XMMM4_SAVE 128
126#define XMMM5_SAVE 144
127#define XMMM6_SAVE 160
128#define XMMM7_SAVE 176
129#define STACK_SIZE 192 /* (XMMM7_SAVE+16) must be 16 byte aligned too */
130
131 .text
132 .align 2,0x90
133 .globl _stub_binding_helper_interface
134_stub_binding_helper_interface:
135 pushq %rbp
136 movq %rsp,%rbp
137 subq $STACK_SIZE,%rsp # at this point stack is 16-byte aligned because two meta-parameters where pushed
138 movq %rdi,RDI_SAVE(%rsp) # save registers that might be used as parameters
139 movq %rsi,RSI_SAVE(%rsp)
140 movq %rdx,RDX_SAVE(%rsp)
141 movq %rcx,RCX_SAVE(%rsp)
142 movq %r8,R8_SAVE(%rsp)
143 movq %r9,R9_SAVE(%rsp)
144 movq %rax,RAX_SAVE(%rsp)
145 movdqa %xmm0,XMMM0_SAVE(%rsp)
146 movdqa %xmm1,XMMM1_SAVE(%rsp)
147 movdqa %xmm2,XMMM2_SAVE(%rsp)
148 movdqa %xmm3,XMMM3_SAVE(%rsp)
149 movdqa %xmm4,XMMM4_SAVE(%rsp)
150 movdqa %xmm5,XMMM5_SAVE(%rsp)
151 movdqa %xmm6,XMMM6_SAVE(%rsp)
152 movdqa %xmm7,XMMM7_SAVE(%rsp)
153 movq MH_PARAM_BP(%rbp),%rdi # call dyld::bindLazySymbol(mh, lazy_ptr)
154 movq LP_PARAM_BP(%rbp),%rsi
155 call __ZN4dyld14bindLazySymbolEPK11mach_headerPm
156 movq %rax,%r11 # save target
157 movdqa XMMM0_SAVE(%rsp),%xmm0 # restore registers
158 movdqa XMMM1_SAVE(%rsp),%xmm1
159 movdqa XMMM2_SAVE(%rsp),%xmm2
160 movdqa XMMM3_SAVE(%rsp),%xmm3
161 movdqa XMMM4_SAVE(%rsp),%xmm4
162 movdqa XMMM5_SAVE(%rsp),%xmm5
163 movdqa XMMM6_SAVE(%rsp),%xmm6
164 movdqa XMMM7_SAVE(%rsp),%xmm7
165 movq RDI_SAVE(%rsp),%rdi
166 movq RSI_SAVE(%rsp),%rsi
167 movq RDX_SAVE(%rsp),%rdx
168 movq RCX_SAVE(%rsp),%rcx
169 movq R8_SAVE(%rsp),%r8
170 movq R9_SAVE(%rsp),%r9
171 movq RAX_SAVE(%rsp),%rax
172 addq $STACK_SIZE,%rsp
173 popq %rbp
174 addq $16,%rsp # remove meta-parameters
175 jmp *%r11 # jmp to target
176
177#endif
3d7c199a 178
0959b6d4
A
179#if __ppc__ || __ppc64__
180#include <architecture/ppc/mode_independent_asm.h>
181/*
182 * This is the interface for the stub_binding_helper for the ppc:
183 * The caller has placed in r11 the address of the a lazy pointer to be filled
184 * in with the value for the defined symbol and placed in r12 the address of
185 * the the mach header this pointer comes from.
186 *
187 * r11 address of lazy pointer
188 * r12 address of mach header
189 */
190#define LRSAVE MODE_CHOICE(8,16)
191#define STACK_SIZE MODE_CHOICE(144,288)
192#define R3SAVE MODE_CHOICE(56,112)
193#define R4SAVE MODE_CHOICE(60,120)
194#define R5SAVE MODE_CHOICE(64,128)
195#define R6SAVE MODE_CHOICE(68,136)
196#define R7SAVE MODE_CHOICE(72,144)
197#define R8SAVE MODE_CHOICE(76,152)
198#define R9SAVE MODE_CHOICE(80,160)
199#define R10SAVE MODE_CHOICE(84,168)
200
201
202 .text
203 .align 2
204 .globl _stub_binding_helper_interface
205_stub_binding_helper_interface:
206 mflr r0 ; get link register value
207 stg r0,LRSAVE(r1) ; save link register value in the linkage area
208 stgu r1,-STACK_SIZE(r1) ; save stack pointer and update it
209
210 stg r3,R3SAVE(r1) ; save all registers that could contain
211 stg r4,R4SAVE(r1) ; parameters to the routine that is being
212 stg r5,R5SAVE(r1) ; bound.
213 stg r6,R6SAVE(r1)
214 stg r7,R7SAVE(r1)
215 stg r8,R8SAVE(r1)
216 stg r9,R9SAVE(r1)
217 stg r10,R10SAVE(r1)
218
219 mr r3,r12 ; move address of mach header to 1st parameter
220 mr r4,r11 ; move address of lazy pointer to 2nd parameter
221 ; call dyld::bindLazySymbol(mh, lazy_symbol_pointer_address)
222 bl __ZN4dyld14bindLazySymbolEPK11mach_headerPm
223 mr r12,r3 ; move the symbol`s address into r12
224 mtctr r12 ; move the symbol`s address into count register
225
226 lg r0,STACK_SIZE+LRSAVE(r1) ; get old link register value
227
228 lg r3,R3SAVE(r1) ; restore all registers that could contain
229 lg r4,R4SAVE(r1) ; parameters to the routine that was bound.
230 lg r5,R5SAVE(r1)
231 lg r6,R6SAVE(r1)
232 lg r7,R7SAVE(r1)
233 lg r8,R8SAVE(r1)
234 lg r9,R9SAVE(r1)
235 lg r10,R10SAVE(r1)
236
237 addi r1,r1,STACK_SIZE; restore old stack pointer
238 mtlr r0 ; restore link register
239
240 bctr ; jump to the symbol`s address that was bound
241
242#endif /* __ppc__ */
243
244
245
246
247
248
249
250
251
252
253