1 | /* PLT trampolines. Sparc 64-bit version. |
2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <sysdep.h> |
20 | |
21 | .text |
22 | .align 32 |
23 | |
24 | /* %g1: PLT offset loaded by PLT entry |
25 | * %g4: callers PC, which is PLT0 + 24, therefore we |
26 | * add (32 + 8) to get the address of PLT2 which |
27 | * is where the magic cookie is stored |
28 | */ |
29 | .globl _dl_runtime_resolve_0 |
30 | .type _dl_runtime_resolve_0, @function |
31 | _dl_runtime_resolve_0: |
32 | cfi_startproc |
33 | |
34 | save %sp, -192, %sp |
35 | cfi_def_cfa_register(%fp) |
36 | cfi_window_save |
37 | cfi_register(%o7, %i7) |
38 | |
39 | sethi %hi(1047552), %l2 |
40 | ldx [%g4 + 32 + 8], %o0 |
41 | sub %g1, %g4, %l0 |
42 | xor %l2, -1016, %l2 |
43 | sethi %hi(5120), %l3 /* 160 * 32 */ |
44 | add %l0, %l2, %l0 |
45 | sethi %hi(32768), %l4 |
46 | udivx %l0, %l3, %l3 |
47 | sllx %l3, 2, %l1 |
48 | add %l1, %l3, %l1 |
49 | sllx %l1, 10, %l2 |
50 | sub %l4, 4, %l4 |
51 | sllx %l1, 5, %l1 |
52 | sub %l0, %l2, %l0 |
53 | udivx %l0, 24, %l0 |
54 | add %l0, %l4, %l0 |
55 | add %l1, %l0, %l1 |
56 | add %l1, %l1, %l0 |
57 | add %l0, %l1, %l0 |
58 | call _dl_fixup |
59 | sllx %l0, 3, %o1 |
60 | jmp %o0 |
61 | restore |
62 | |
63 | cfi_endproc |
64 | |
65 | .size _dl_runtime_resolve_0, .-_dl_runtime_resolve_0 |
66 | |
67 | /* %g1: PLT offset loaded by PLT entry |
68 | * %g4: callers PC, which is PLT1 + 24, therefore we |
69 | * add 8 to get the address of PLT2 which |
70 | * is where the magic cookie is stored |
71 | */ |
72 | .globl _dl_runtime_resolve_1 |
73 | .type _dl_runtime_resolve_1, @function |
74 | _dl_runtime_resolve_1: |
75 | cfi_startproc |
76 | |
77 | save %sp, -192, %sp |
78 | cfi_def_cfa_register(%fp) |
79 | cfi_window_save |
80 | cfi_register(%o7, %i7) |
81 | |
82 | srlx %g1, 12, %o1 |
83 | ldx [%g4 + 8], %o0 |
84 | add %o1, %o1, %o3 |
85 | sub %o1, 96, %o1 |
86 | call _dl_fixup |
87 | add %o1, %o3, %o1 |
88 | jmp %o0 |
89 | restore |
90 | |
91 | cfi_endproc |
92 | |
93 | .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1 |
94 | |
95 | #ifdef SHARED |
96 | /* For the profiling cases we pass in our stack frame |
97 | * as the base of the La_sparc64_regs, so it looks |
98 | * like: |
99 | * %l0 %sp |
100 | * ... |
101 | * %l7 %sp + (7 * 8) |
102 | * %i0 %sp + (8 * 8) |
103 | * ... |
104 | * %i7 %sp + (15 * 8) |
105 | * %f0 %sp + (16 * 8) |
106 | * %f16 %sp + (31 * 8) |
107 | * framesize %sp + (32 * 8) |
108 | */ |
109 | |
110 | .globl _dl_profile_save_regs |
111 | .type _dl_profile_save_regs, @function |
112 | _dl_profile_save_regs: |
113 | cfi_startproc |
114 | |
115 | stx %l0, [%sp + STACK_BIAS + ( 0 * 8)] |
116 | stx %l1, [%sp + STACK_BIAS + ( 1 * 8)] |
117 | stx %l2, [%sp + STACK_BIAS + ( 2 * 8)] |
118 | stx %l3, [%sp + STACK_BIAS + ( 3 * 8)] |
119 | stx %l4, [%sp + STACK_BIAS + ( 4 * 8)] |
120 | stx %l5, [%sp + STACK_BIAS + ( 5 * 8)] |
121 | stx %l6, [%sp + STACK_BIAS + ( 6 * 8)] |
122 | stx %l7, [%sp + STACK_BIAS + ( 7 * 8)] |
123 | stx %i0, [%sp + STACK_BIAS + ( 8 * 8)] |
124 | stx %i1, [%sp + STACK_BIAS + ( 9 * 8)] |
125 | stx %i2, [%sp + STACK_BIAS + (10 * 8)] |
126 | stx %i3, [%sp + STACK_BIAS + (11 * 8)] |
127 | stx %i4, [%sp + STACK_BIAS + (12 * 8)] |
128 | stx %i5, [%sp + STACK_BIAS + (13 * 8)] |
129 | stx %i6, [%sp + STACK_BIAS + (14 * 8)] |
130 | stx %i7, [%sp + STACK_BIAS + (15 * 8)] |
131 | std %f0, [%sp + STACK_BIAS + (16 * 8)] |
132 | std %f2, [%sp + STACK_BIAS + (17 * 8)] |
133 | std %f4, [%sp + STACK_BIAS + (18 * 8)] |
134 | std %f6, [%sp + STACK_BIAS + (19 * 8)] |
135 | std %f8, [%sp + STACK_BIAS + (20 * 8)] |
136 | std %f10, [%sp + STACK_BIAS + (21 * 8)] |
137 | std %f12, [%sp + STACK_BIAS + (22 * 8)] |
138 | std %f14, [%sp + STACK_BIAS + (23 * 8)] |
139 | std %f16, [%sp + STACK_BIAS + (24 * 8)] |
140 | std %f18, [%sp + STACK_BIAS + (25 * 8)] |
141 | std %f20, [%sp + STACK_BIAS + (26 * 8)] |
142 | std %f22, [%sp + STACK_BIAS + (27 * 8)] |
143 | std %f24, [%sp + STACK_BIAS + (28 * 8)] |
144 | std %f26, [%sp + STACK_BIAS + (29 * 8)] |
145 | std %f28, [%sp + STACK_BIAS + (30 * 8)] |
146 | retl |
147 | std %f30, [%sp + STACK_BIAS + (31 * 8)] |
148 | |
149 | cfi_endproc |
150 | |
151 | .size _dl_profile_save_regs, .-_dl_profile_save_regs |
152 | |
153 | /* If we are going to call pltexit, then we must replicate |
154 | * the caller's stack frame. |
155 | * %o0: PLT resolved function address |
156 | */ |
157 | .globl _dl_profile_invoke |
158 | .type _dl_profile_invoke, @function |
159 | _dl_profile_invoke: |
160 | cfi_startproc |
161 | |
162 | add %l0, 7, %l0 |
163 | andn %l0, 7, %l0 |
164 | add %l0, (8 * 8), %g1 |
165 | |
166 | sub %sp, %g1, %sp |
167 | srlx %l0, 3, %l7 |
168 | mov %o0, %l1 |
169 | mov %i0, %o0 |
170 | mov %i1, %o1 |
171 | mov %i2, %o2 |
172 | mov %i3, %o3 |
173 | mov %i4, %o4 |
174 | mov %i5, %o5 |
175 | add %fp, STACK_BIAS, %l2 |
176 | brz %l0, 2f |
177 | add %sp, STACK_BIAS, %l3 |
178 | 1: ldx [%l2], %l4 |
179 | add %l2, 0x8, %l2 |
180 | subcc %l7, 1, %l7 |
181 | stx %l4, [%l3] |
182 | bne,pt %xcc, 1b |
183 | add %l3, 0x8, %l3 |
184 | |
185 | 2: jmpl %l1, %o7 |
186 | nop |
187 | |
188 | stx %o0, [%sp + STACK_BIAS + (16 * 8)] |
189 | stx %o1, [%sp + STACK_BIAS + (17 * 8)] |
190 | stx %o2, [%sp + STACK_BIAS + (18 * 8)] |
191 | stx %o3, [%sp + STACK_BIAS + (19 * 8)] |
192 | std %f0, [%sp + STACK_BIAS + (20 * 8)] |
193 | std %f2, [%sp + STACK_BIAS + (21 * 8)] |
194 | std %f4, [%sp + STACK_BIAS + (22 * 8)] |
195 | std %f8, [%sp + STACK_BIAS + (23 * 8)] |
196 | |
197 | mov %l5, %o0 |
198 | mov %l6, %o1 |
199 | add %sp, STACK_BIAS + (24 * 8), %o2 |
200 | call _dl_audit_pltexit |
201 | add %sp, STACK_BIAS + (16 * 8), %o3 |
202 | |
203 | ldx [%sp + STACK_BIAS + (16 * 8)], %i0 |
204 | ldx [%sp + STACK_BIAS + (17 * 8)], %i1 |
205 | ldx [%sp + STACK_BIAS + (18 * 8)], %i2 |
206 | ldx [%sp + STACK_BIAS + (19 * 8)], %i3 |
207 | ldd [%sp + STACK_BIAS + (20 * 8)], %f0 |
208 | ldd [%sp + STACK_BIAS + (21 * 8)], %f2 |
209 | ldd [%sp + STACK_BIAS + (22 * 8)], %f4 |
210 | ldd [%sp + STACK_BIAS + (23 * 8)], %f8 |
211 | |
212 | jmpl %i7 + 8, %g0 |
213 | restore |
214 | |
215 | cfi_endproc |
216 | |
217 | .size _dl_profile_invoke, .-_dl_profile_invoke |
218 | |
219 | /* %g1: PLT offset loaded by PLT entry |
220 | * %g4: callers PC, which is PLT0 + 24, therefore we |
221 | * add (32 + 8) to get the address of PLT2 which |
222 | * is where the magic cookie is stored |
223 | */ |
224 | .align 32 |
225 | .globl _dl_runtime_profile_0 |
226 | .type _dl_runtime_profile_0, @function |
227 | _dl_runtime_profile_0: |
228 | cfi_startproc |
229 | |
230 | save %sp, -336, %sp |
231 | cfi_def_cfa_register(%fp) |
232 | cfi_window_save |
233 | cfi_register(%o7, %i7) |
234 | |
235 | sethi %hi(1047552), %l2 |
236 | ldx [%g4 + 32 + 8], %o0 |
237 | sub %g1, %g4, %l0 |
238 | xor %l2, -1016, %l2 |
239 | sethi %hi(5120), %l3 /* 160 * 32 */ |
240 | add %l0, %l2, %l0 |
241 | sethi %hi(32768), %l4 |
242 | udivx %l0, %l3, %l3 |
243 | sllx %l3, 2, %l1 |
244 | add %l1, %l3, %l1 |
245 | sllx %l1, 10, %l2 |
246 | sub %l4, 4, %l4 |
247 | sllx %l1, 5, %l1 |
248 | sub %l0, %l2, %l0 |
249 | udivx %l0, 24, %l0 |
250 | add %l0, %l4, %l0 |
251 | add %l1, %l0, %l1 |
252 | add %l1, %l1, %l0 |
253 | add %l0, %l1, %l0 |
254 | |
255 | mov %i7, %o2 |
256 | sllx %l0, 3, %o1 |
257 | |
258 | mov %o0, %l5 |
259 | mov %o1, %l6 |
260 | |
261 | call _dl_profile_save_regs |
262 | nop |
263 | |
264 | add %sp, STACK_BIAS, %o3 |
265 | call _dl_profile_fixup |
266 | add %sp, (STACK_BIAS + (32 * 8)), %o4 |
267 | |
268 | ldx [%sp + STACK_BIAS + (32 * 8)], %l0 |
269 | brlz,pt %l0, 1f |
270 | nop |
271 | |
272 | call _dl_profile_invoke |
273 | nop |
274 | |
275 | 1: jmp %o0 |
276 | restore |
277 | |
278 | cfi_endproc |
279 | |
280 | .size _dl_runtime_profile_0, .-_dl_runtime_profile_0 |
281 | |
282 | /* %g1: PLT offset loaded by PLT entry |
283 | * %g4: callers PC, which is PLT1 + 24, therefore we |
284 | * add 8 to get the address of PLT2 which |
285 | * is where the magic cookie is stored |
286 | */ |
287 | .globl _dl_runtime_profile_1 |
288 | .type _dl_runtime_profile_1, @function |
289 | _dl_runtime_profile_1: |
290 | cfi_startproc |
291 | |
292 | save %sp, -336, %sp |
293 | cfi_def_cfa_register(%fp) |
294 | cfi_window_save |
295 | cfi_register(%o7, %i7) |
296 | |
297 | srlx %g1, 12, %o1 |
298 | ldx [%g4 + 8], %o0 |
299 | add %o1, %o1, %o3 |
300 | sub %o1, 96, %o1 |
301 | mov %i7, %o2 |
302 | add %o1, %o3, %o1 |
303 | |
304 | mov %o0, %l5 |
305 | mov %o1, %l6 |
306 | |
307 | call _dl_profile_save_regs |
308 | nop |
309 | |
310 | add %sp, STACK_BIAS, %o3 |
311 | call _dl_profile_fixup |
312 | add %sp, (STACK_BIAS + (32 * 8)), %o4 |
313 | |
314 | ldx [%sp + STACK_BIAS + (32 * 8)], %l0 |
315 | brlz,pt %l0, 1f |
316 | nop |
317 | |
318 | call _dl_profile_invoke |
319 | nop |
320 | |
321 | 1: jmp %o0 |
322 | restore |
323 | |
324 | cfi_endproc |
325 | |
326 | .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1 |
327 | #endif |
328 | |