2 * Copyright (c) 1999-2008 Apple 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 implementation of dyld_lazy_dylib_stub_binding_helper for i386
29 * on versions before Macs OS X 10.6. On entry the address of the lazy pointer
30 * has been pushed on the stack.
32 * After the symbol has been resolved and the lazy pointer filled in, this jumps
33 * to the target address.
35 #define LP_PARAM_OUT 0
36 #define XMMM0_SAVE 16 /* 16-byte align */
44 #define STACK_SIZE 104 /* must be 8 mod 16 so that stack winds up 16-byte aliged */
45 #define LP_OLD_BP_SAVE 104
49 .globl dyld_lazy_dylib_stub_binding_helper
50 .private_extern dyld_lazy_dylib_stub_binding_helper
51 dyld_lazy_dylib_stub_binding_helper
:
52 subl $STACK_SIZE
,%esp
# makes stack 16-byte aligned
53 movl
%eax
,EAX_SAVE
(%esp
)
54 movl LP_OLD_BP_SAVE
(%esp
),%eax
# get lazy-pointer meta-parameter
55 movl
%eax
,LP_LOCAL
(%esp
)
56 movl
%ebp
,LP_OLD_BP_SAVE
(%esp
) # store epb back chain
57 movl
%esp
,%ebp
# set epb to be this frame
58 add $LP_OLD_BP_SAVE
,%ebp
59 movl
%ecx
,ECX_SAVE
(%esp
)
60 movl
%edx
,EDX_SAVE
(%esp
)
61 movdqu
%xmm0
,XMMM0_SAVE
(%esp
)
62 movdqu
%xmm1
,XMMM1_SAVE
(%esp
)
63 movdqu
%xmm2
,XMMM2_SAVE
(%esp
)
64 movdqu
%xmm3
,XMMM3_SAVE
(%esp
)
65 movl LP_LOCAL
(%esp
),%eax
66 movl
%eax
,LP_PARAM_OUT
(%esp
) # call lazy_load_dylib(lazy_ptr)
68 movdqu XMMM0_SAVE
(%esp
),%xmm0
# restore registers
69 movdqu XMMM1_SAVE
(%esp
),%xmm1
70 movdqu XMMM2_SAVE
(%esp
),%xmm2
71 movdqu XMMM3_SAVE
(%esp
),%xmm3
72 movl ECX_SAVE
(%esp
),%ecx
73 movl EDX_SAVE
(%esp
),%edx
74 movl
%eax
,%ebp
# move target address to epb
75 movl EAX_SAVE
(%esp
),%eax
# restore eax
76 addl $STACK_SIZE
,%esp
# cut back stack
77 xchg
%ebp
, (%esp
) # restore ebp and set target to top of stack
85 * This is the implementation of dyld_lazy_dylib_stub_binding_helper for x86_64
86 * on versions before Macs OS X 10.6. On entry r11 contains address of the
89 * All parameters registers must be preserved.
91 * After the symbol has been resolved and the pointer filled in this is to pop
92 * these arguments off the stack and jump to the address of the defined symbol.
101 #define XMMM0_SAVE 64 /* 16-byte align */
102 #define XMMM1_SAVE 80
103 #define XMMM2_SAVE 96
104 #define XMMM3_SAVE 112
105 #define XMMM4_SAVE 128
106 #define XMMM5_SAVE 144
107 #define XMMM6_SAVE 160
108 #define XMMM7_SAVE 176
109 #define STACK_SIZE 192 /* (XMMM7_SAVE+16) must be 16 byte aligned too */
113 .globl dyld_lazy_dylib_stub_binding_helper
114 .private_extern dyld_lazy_dylib_stub_binding_helper
115 dyld_lazy_dylib_stub_binding_helper
:
118 subq $STACK_SIZE
,%rsp
119 movq
%rdi
,RDI_SAVE
(%rsp
) # save registers that might be used as parameters
120 movq
%rsi
,RSI_SAVE
(%rsp
)
121 movq
%rdx
,RDX_SAVE
(%rsp
)
122 movq
%rcx
,RCX_SAVE
(%rsp
)
123 movq
%r8,R8_SAVE
(%rsp
)
124 movq
%r9,R9_SAVE
(%rsp
)
125 movq
%rax
,RAX_SAVE
(%rsp
)
126 movdqa
%xmm0
,XMMM0_SAVE
(%rsp
)
127 movdqa
%xmm1
,XMMM1_SAVE
(%rsp
)
128 movdqa
%xmm2
,XMMM2_SAVE
(%rsp
)
129 movdqa
%xmm3
,XMMM3_SAVE
(%rsp
)
130 movdqa
%xmm4
,XMMM4_SAVE
(%rsp
)
131 movdqa
%xmm5
,XMMM5_SAVE
(%rsp
)
132 movdqa
%xmm6
,XMMM6_SAVE
(%rsp
)
133 movdqa
%xmm7
,XMMM7_SAVE
(%rsp
)
134 movq
%r11,%rdi
# call lazy_load_dylib(lazy_ptr)
135 call _lazy_load_dylib
136 movq
%rax
,%r11 # save target
137 movdqa XMMM0_SAVE
(%rsp
),%xmm0
# restore registers
138 movdqa XMMM1_SAVE
(%rsp
),%xmm1
139 movdqa XMMM2_SAVE
(%rsp
),%xmm2
140 movdqa XMMM3_SAVE
(%rsp
),%xmm3
141 movdqa XMMM4_SAVE
(%rsp
),%xmm4
142 movdqa XMMM5_SAVE
(%rsp
),%xmm5
143 movdqa XMMM6_SAVE
(%rsp
),%xmm6
144 movdqa XMMM7_SAVE
(%rsp
),%xmm7
145 movq RDI_SAVE
(%rsp
),%rdi
146 movq RSI_SAVE
(%rsp
),%rsi
147 movq RDX_SAVE
(%rsp
),%rdx
148 movq RCX_SAVE
(%rsp
),%rcx
149 movq R8_SAVE
(%rsp
),%r8
150 movq R9_SAVE
(%rsp
),%r9
151 movq RAX_SAVE
(%rsp
),%rax
152 addq $STACK_SIZE
,%rsp
154 jmp
*%r11 # jmp to target
159 #if __ppc__ || __ppc64__
160 #include <architecture/ppc/mode_independent_asm.h>
162 * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ppc
163 * on versions before Macs OS X 10.6. On entry r11 contains address of the
164 * lazy pointer to be filled
166 * r11 address of lazy pointer
168 #define LRSAVE MODE_CHOICE(8,16)
169 #define STACK_SIZE MODE_CHOICE(144,288)
170 #define R3SAVE MODE_CHOICE(56,112)
171 #define R4SAVE MODE_CHOICE(60,120)
172 #define R5SAVE MODE_CHOICE(64,128)
173 #define R6SAVE MODE_CHOICE(68,136)
174 #define R7SAVE MODE_CHOICE(72,144)
175 #define R8SAVE MODE_CHOICE(76,152)
176 #define R9SAVE MODE_CHOICE(80,160)
177 #define R10SAVE MODE_CHOICE(84,168)
182 .globl dyld_lazy_dylib_stub_binding_helper
183 .private_extern dyld_lazy_dylib_stub_binding_helper
184 dyld_lazy_dylib_stub_binding_helper
:
185 mflr r0 ; get link register value
186 stg
r0,LRSAVE
(r1) ; save link register value in the linkage area
187 stgu
r1,-STACK_SIZE
(r1) ; save stack pointer
and update it
189 stg
r3,R3SAVE
(r1) ; save all registers that could contain
190 stg
r4,R4SAVE
(r1) ; parameters to the routine that is being
191 stg
r5,R5SAVE
(r1) ; bound.
198 mr r3,r11 ; move address of lazy pointer to
1st parameter
199 ; call lazy_load_dylib
(lazy_ptr
)
201 mr r12,r3 ; move the symbol`s address into
r12
202 mtctr r12 ; move the symbol`s address into count register
204 lg
r0,STACK_SIZE+LRSAVE
(r1) ; get old link register value
206 lg
r3,R3SAVE
(r1) ; restore all registers that could contain
207 lg
r4,R4SAVE
(r1) ; parameters to the routine that was bound.
215 addi r1,r1,STACK_SIZE; restore old stack pointer
216 mtlr r0 ; restore link register
218 bctr ; jump to the symbol`s address that was bound
224 * This is the implementation of dyld_lazy_dylib_stub_binding_helper for ARM
225 * The caller has pushed the address of the a lazy pointer to be filled in with
226 * the value for the defined symbol
228 * ip address of lazy pointer
230 * After the symbol has been resolved and the pointer filled in this is to pop
231 * these arguments off the stack and jump to the address of the defined symbol.
235 .globl dyld_lazy_dylib_stub_binding_helper
236 .private_extern dyld_lazy_dylib_stub_binding_helper
237 dyld_lazy_dylib_stub_binding_helper
:
238 stmfd sp
!, {r0,r1,r2,r3,r7,lr} // save registers
239 add r7, sp
, #16 // point FP to previous FP
241 mov
r0, ip
// move address of lazy pointer to
1st parameter
242 // call lazy_load_dylib
(lazy_ptr
)
244 mov ip
, r0 // move the symbol`s address into ip
246 ldmfd sp
!, {r0,r1,r2,r3,r7,lr} // restore registers
248 bx ip
// jump to the symbol`s address that was bound
255 // This code has
be written to allow dead code stripping
256 .subsections_via_symbols