2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
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.
32 * sp+4 address of lazy pointer
33 * sp+0 address of mach header
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.
38 * After the symbol has been resolved and the lazy pointer filled in, this jumps
39 * to the target address.
41 #define MH_PARAM_OUT 0
42 #define LP_PARAM_OUT 4
43 #define XMMM0_SAVE 16 /* 16-byte align */
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
57 .globl _fast_stub_binding_helper_interface
58 _fast_stub_binding_helper_interface
:
60 .globl _stub_binding_helper_interface
61 .globl _misaligned_stack_error
62 _stub_binding_helper_interface
:
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
)
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
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.
106 * sp+8 address of lazy pointer
107 * sp+0 address of mach header
109 * All parameters registers must be preserved.
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.
114 #define MH_PARAM_BP 8
115 #define LP_PARAM_BP 16
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 */
136 .globl _stub_binding_helper_interface
137 _stub_binding_helper_interface
:
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
177 addq $
16,%rsp
# remove meta-parameters
178 jmp
*%r11 # jmp to target
185 * This is the interface for the 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.
190 * sp+4 address of lazy pointer
191 * sp+0 address of mach header
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.
199 .globl _stub_binding_helper_interface
200 _stub_binding_helper_interface
:
201 stmfd sp
!, {r0,r1,r2,r3,r7,lr} // save registers
202 add r7, sp
, #16 // point FP to previous FP
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
207 // call dyld
::bindLazySymbol
(mh
, lazy_symbol_pointer_address
)
208 bl __ZN4dyld14bindLazySymbolEPK11mach_headerPm
209 mov ip
, r0 // move the symbol`s address into ip
211 ldmfd sp
!, {r0,r1,r2,r3,r7,lr} // restore registers
212 add sp
, sp
, #8 // remove meta-parameters
214 bx ip
// jump to the symbol`s address that was bound