modified: nfig1.py
[GalaxyCodeBases.git] / c_cpp / Mac / Csu-85 / lazy_dylib_helper.s
blobe24afcd5bc004426022f6cc5cc6c12f479dc635d
1 /*
2 * Copyright (c) 1999-2008 Apple Inc. All rights reserved.
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.
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@
26 #if __i386__
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 */
37 #define XMMM1_SAVE 32
38 #define XMMM2_SAVE 48
39 #define XMMM3_SAVE 64
40 #define EAX_SAVE 84
41 #define ECX_SAVE 88
42 #define EDX_SAVE 92
43 #define LP_LOCAL 96
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
47 .text
48 .align 4,0x90
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)
67 call _lazy_load_dylib
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
78 ret # jump to target
80 #endif /* __i386__ */
83 #if __x86_64__
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
87 * lazy pointer.
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.
94 #define RDI_SAVE 0
95 #define RSI_SAVE 8
96 #define RDX_SAVE 16
97 #define RCX_SAVE 24
98 #define R8_SAVE 32
99 #define R9_SAVE 40
100 #define RAX_SAVE 48
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 */
111 .text
112 .align 2,0x90
113 .globl dyld_lazy_dylib_stub_binding_helper
114 .private_extern dyld_lazy_dylib_stub_binding_helper
115 dyld_lazy_dylib_stub_binding_helper:
116 pushq %rbp
117 movq %rsp,%rbp
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
153 popq %rbp
154 jmp *%r11 # jmp to target
156 #endif
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)
180 .text
181 .align 2
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.
192 stg r6,R6SAVE(r1)
193 stg r7,R7SAVE(r1)
194 stg r8,R8SAVE(r1)
195 stg r9,R9SAVE(r1)
196 stg r10,R10SAVE(r1)
198 mr r3,r11 ; move address of lazy pointer to 1st parameter
199 ; call lazy_load_dylib(lazy_ptr)
200 bl _lazy_load_dylib
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.
208 lg r5,R5SAVE(r1)
209 lg r6,R6SAVE(r1)
210 lg r7,R7SAVE(r1)
211 lg r8,R8SAVE(r1)
212 lg r9,R9SAVE(r1)
213 lg r10,R10SAVE(r1)
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
220 #endif /* __ppc__ */
222 #if __arm__
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.
233 .text
234 .align 2
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)
243 bl _lazy_load_dylib
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
250 #endif /* __arm__ */
255 // This code has be written to allow dead code stripping
256 .subsections_via_symbols