1/* PLT trampolines. Alpha version.
2 Copyright (C) 2005-2022 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 .set noat
22
23.macro savei regno, offset
24 stq $\regno, \offset($30)
25 cfi_rel_offset(\regno, \offset)
26.endm
27
28.macro savef regno, offset
29 stt $f\regno, \offset($30)
30 cfi_rel_offset(\regno+32, \offset)
31.endm
32
33 .align 4
34 .globl _dl_runtime_resolve_new
35 .ent _dl_runtime_resolve_new
36
37#undef FRAMESIZE
38#define FRAMESIZE 14*8
39
40_dl_runtime_resolve_new:
41 .frame $30, FRAMESIZE, $26, 0
42 .mask 0x4000000, 0
43
44 ldah $29, 0($27) !gpdisp!1
45 lda $30, -FRAMESIZE($30)
46 stq $26, 0*8($30)
47 stq $16, 2*8($30)
48
49 stq $17, 3*8($30)
50 lda $29, 0($29) !gpdisp!1
51 stq $18, 4*8($30)
52 mov $28, $16 /* link_map from .got.plt */
53
54 stq $19, 5*8($30)
55 mov $25, $17 /* offset of reloc entry */
56 stq $20, 6*8($30)
57 mov $26, $18 /* return address */
58
59 stq $21, 7*8($30)
60 stt $f16, 8*8($30)
61 stt $f17, 9*8($30)
62 stt $f18, 10*8($30)
63
64 stt $f19, 11*8($30)
65 stt $f20, 12*8($30)
66 stt $f21, 13*8($30)
67 .prologue 2
68
69 bsr $26, _dl_fixup !samegp
70 mov $0, $27
71
72 ldq $26, 0*8($30)
73 ldq $16, 2*8($30)
74 ldq $17, 3*8($30)
75 ldq $18, 4*8($30)
76 ldq $19, 5*8($30)
77 ldq $20, 6*8($30)
78 ldq $21, 7*8($30)
79 ldt $f16, 8*8($30)
80 ldt $f17, 9*8($30)
81 ldt $f18, 10*8($30)
82 ldt $f19, 11*8($30)
83 ldt $f20, 12*8($30)
84 ldt $f21, 13*8($30)
85 lda $30, FRAMESIZE($30)
86 jmp $31, ($27), 0
87 .end _dl_runtime_resolve_new
88
89 .globl _dl_runtime_profile_new
90 .type _dl_runtime_profile_new, @function
91
92#undef FRAMESIZE
93#define FRAMESIZE 20*8
94
95 /* We save the registers in a different order than desired by
96 .mask/.fmask, so we have to use explicit cfi directives. */
97 cfi_startproc
98
99_dl_runtime_profile_new:
100 ldah $29, 0($27) !gpdisp!2
101 lda $30, -FRAMESIZE($30)
102 savei 26, 0*8
103 stq $16, 2*8($30)
104
105 stq $17, 3*8($30)
106 lda $29, 0($29) !gpdisp!2
107 stq $18, 4*8($30)
108 lda $1, FRAMESIZE($30) /* incoming sp value */
109
110 stq $1, 1*8($30)
111 stq $19, 5*8($30)
112 stq $20, 6*8($30)
113 mov $28, $16 /* link_map from .got.plt */
114
115 stq $21, 7*8($30)
116 mov $25, $17 /* offset of reloc entry */
117 stt $f16, 8*8($30)
118 mov $26, $18 /* return address */
119
120 stt $f17, 9*8($30)
121 mov $30, $19 /* La_alpha_regs address */
122 stt $f18, 10*8($30)
123 lda $20, 14*8($30) /* framesize address */
124
125 stt $f19, 11*8($30)
126 stt $f20, 12*8($30)
127 stt $f21, 13*8($30)
128 stq $28, 16*8($30)
129 stq $25, 17*8($30)
130
131 bsr $26, _dl_profile_fixup !samegp
132 mov $0, $27
133
134 /* Discover if we're wrapping this call. */
135 ldq $18, 14*8($30)
136 bge $18, 1f
137
138 ldq $26, 0*8($30)
139 ldq $16, 2*8($30)
140 ldq $17, 3*8($30)
141 ldq $18, 4*8($30)
142 ldq $19, 5*8($30)
143 ldq $20, 6*8($30)
144 ldq $21, 7*8($30)
145 ldt $f16, 8*8($30)
146 ldt $f17, 9*8($30)
147 ldt $f18, 10*8($30)
148 ldt $f19, 11*8($30)
149 ldt $f20, 12*8($30)
150 ldt $f21, 13*8($30)
151 lda $30, FRAMESIZE($30)
152 jmp $31, ($27), 0
153
1541:
155 /* Create a frame pointer and allocate a new argument frame. */
156 savei 15, 15*8
157 mov $30, $15
158 cfi_def_cfa_register (15)
159 addq $18, 15, $18
160 bic $18, 15, $18
161 subq $30, $18, $30
162
163 /* Save the call destination around memcpy. */
164 stq $0, 14*8($30)
165
166 /* Copy the stack arguments into place. */
167 lda $16, 0($30)
168 lda $17, FRAMESIZE($15)
169 jsr $26, memcpy
170 ldgp $29, 0($26)
171
172 /* Reload the argument registers. */
173 ldq $27, 14*8($30)
174 ldq $16, 2*8($15)
175 ldq $17, 3*8($15)
176 ldq $18, 4*8($15)
177 ldq $19, 5*8($15)
178 ldq $20, 6*8($15)
179 ldq $21, 7*8($15)
180 ldt $f16, 8*8($15)
181 ldt $f17, 9*8($15)
182 ldt $f18, 10*8($15)
183 ldt $f19, 11*8($15)
184 ldt $f20, 12*8($15)
185 ldt $f21, 13*8($15)
186
187 jsr $26, ($27), 0
188 ldgp $29, 0($26)
189
190 /* Set up for call to _dl_audit_pltexit. */
191 ldq $16, 16*8($15)
192 ldq $17, 17*8($15)
193 stq $0, 16*8($15)
194 lda $18, 0($15)
195 stq $1, 17*8($15)
196 lda $19, 16*8($15)
197 stt $f0, 18*8($15)
198 stt $f1, 19*8($15)
199 bsr $26, _dl_audit_pltexit !samegp
200
201 mov $15, $30
202 cfi_def_cfa_register (30)
203 ldq $26, 0($30)
204 ldq $15, 15*8($30)
205 lda $30, FRAMESIZE($30)
206 ret
207
208 cfi_endproc
209 .size _dl_runtime_profile_new, .-_dl_runtime_profile_new
210
211 .align 4
212 .globl _dl_runtime_resolve_old
213 .ent _dl_runtime_resolve_old
214
215#undef FRAMESIZE
216#define FRAMESIZE 44*8
217
218_dl_runtime_resolve_old:
219 lda $30, -FRAMESIZE($30)
220 .frame $30, FRAMESIZE, $26
221 /* Preserve all registers that C normally doesn't. */
222 stq $26, 0*8($30)
223 stq $0, 1*8($30)
224 stq $1, 2*8($30)
225 stq $2, 3*8($30)
226 stq $3, 4*8($30)
227 stq $4, 5*8($30)
228 stq $5, 6*8($30)
229 stq $6, 7*8($30)
230 stq $7, 8*8($30)
231 stq $8, 9*8($30)
232 stq $16, 10*8($30)
233 stq $17, 11*8($30)
234 stq $18, 12*8($30)
235 stq $19, 13*8($30)
236 stq $20, 14*8($30)
237 stq $21, 15*8($30)
238 stq $22, 16*8($30)
239 stq $23, 17*8($30)
240 stq $24, 18*8($30)
241 stq $25, 19*8($30)
242 stq $29, 20*8($30)
243 stt $f0, 21*8($30)
244 stt $f1, 22*8($30)
245 stt $f10, 23*8($30)
246 stt $f11, 24*8($30)
247 stt $f12, 25*8($30)
248 stt $f13, 26*8($30)
249 stt $f14, 27*8($30)
250 stt $f15, 28*8($30)
251 stt $f16, 29*8($30)
252 stt $f17, 30*8($30)
253 stt $f18, 31*8($30)
254 stt $f19, 32*8($30)
255 stt $f20, 33*8($30)
256 stt $f21, 34*8($30)
257 stt $f22, 35*8($30)
258 stt $f23, 36*8($30)
259 stt $f24, 37*8($30)
260 stt $f25, 38*8($30)
261 stt $f26, 39*8($30)
262 stt $f27, 40*8($30)
263 stt $f28, 41*8($30)
264 stt $f29, 42*8($30)
265 stt $f30, 43*8($30)
266 .mask 0x27ff01ff, -FRAMESIZE
267 .fmask 0xfffffc03, -FRAMESIZE+21*8
268 /* Set up our GP. */
269 br $29, .+4
270 ldgp $29, 0($29)
271 .prologue 0
272 /* Set up the arguments for _dl_fixup:
273 $16 = link_map out of plt0
274 $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
275 $18 = return address
276 */
277 subq $28, $27, $17
278 ldq $16, 8($27)
279 subq $17, 20, $17
280 mov $26, $18
281 addq $17, $17, $17
282 bsr $26, _dl_fixup !samegp
283
284 /* Move the destination address into position. */
285 mov $0, $27
286 /* Restore program registers. */
287 ldq $26, 0*8($30)
288 ldq $0, 1*8($30)
289 ldq $1, 2*8($30)
290 ldq $2, 3*8($30)
291 ldq $3, 4*8($30)
292 ldq $4, 5*8($30)
293 ldq $5, 6*8($30)
294 ldq $6, 7*8($30)
295 ldq $7, 8*8($30)
296 ldq $8, 9*8($30)
297 ldq $16, 10*8($30)
298 ldq $17, 11*8($30)
299 ldq $18, 12*8($30)
300 ldq $19, 13*8($30)
301 ldq $20, 14*8($30)
302 ldq $21, 15*8($30)
303 ldq $22, 16*8($30)
304 ldq $23, 17*8($30)
305 ldq $24, 18*8($30)
306 ldq $25, 19*8($30)
307 ldq $29, 20*8($30)
308 ldt $f0, 21*8($30)
309 ldt $f1, 22*8($30)
310 ldt $f10, 23*8($30)
311 ldt $f11, 24*8($30)
312 ldt $f12, 25*8($30)
313 ldt $f13, 26*8($30)
314 ldt $f14, 27*8($30)
315 ldt $f15, 28*8($30)
316 ldt $f16, 29*8($30)
317 ldt $f17, 30*8($30)
318 ldt $f18, 31*8($30)
319 ldt $f19, 32*8($30)
320 ldt $f20, 33*8($30)
321 ldt $f21, 34*8($30)
322 ldt $f22, 35*8($30)
323 ldt $f23, 36*8($30)
324 ldt $f24, 37*8($30)
325 ldt $f25, 38*8($30)
326 ldt $f26, 39*8($30)
327 ldt $f27, 40*8($30)
328 ldt $f28, 41*8($30)
329 ldt $f29, 42*8($30)
330 ldt $f30, 43*8($30)
331 /* Flush the Icache after having modified the .plt code. */
332 imb
333 /* Clean up and turn control to the destination */
334 lda $30, FRAMESIZE($30)
335 jmp $31, ($27)
336
337 .end _dl_runtime_resolve_old
338
339 .globl _dl_runtime_profile_old
340 .usepv _dl_runtime_profile_old, no
341 .type _dl_runtime_profile_old, @function
342
343 /* We save the registers in a different order than desired by
344 .mask/.fmask, so we have to use explicit cfi directives. */
345 cfi_startproc
346
347#undef FRAMESIZE
348#define FRAMESIZE 50*8
349
350 .align 4
351_dl_runtime_profile_old:
352 lda $30, -FRAMESIZE($30)
353 cfi_adjust_cfa_offset (FRAMESIZE)
354
355 /* Preserve all argument registers. This also constructs the
356 La_alpha_regs structure. */
357 savei 26, 0*8
358 savei 16, 2*8
359 savei 17, 3*8
360 savei 18, 4*8
361 savei 19, 5*8
362 savei 20, 6*8
363 savei 21, 7*8
364 lda $16, FRAMESIZE($30)
365 savef 16, 8*8
366 savef 17, 9*8
367 savef 18, 10*8
368 savef 19, 11*8
369 savef 20, 12*8
370 savef 21, 13*8
371 stq $16, 1*8($30)
372
373 /* Preserve all registers that C normally doesn't. */
374 savei 0, 14*8
375 savei 1, 15*8
376 savei 2, 16*8
377 savei 3, 17*8
378 savei 4, 18*8
379 savei 5, 19*8
380 savei 6, 20*8
381 savei 7, 21*8
382 savei 8, 22*8
383 savei 22, 23*8
384 savei 23, 24*8
385 savei 24, 25*8
386 savei 25, 26*8
387 savei 29, 27*8
388 savef 0, 28*8
389 savef 1, 29*8
390 savef 10, 30*8
391 savef 11, 31*8
392 savef 12, 32*8
393 savef 13, 33*8
394 savef 14, 34*8
395 savef 15, 35*8
396 savef 22, 36*8
397 savef 23, 37*8
398 savef 24, 38*8
399 savef 25, 39*8
400 savef 26, 40*8
401 savef 27, 41*8
402 savef 28, 42*8
403 savef 29, 43*8
404 savef 30, 44*8
405
406 /* Set up our GP. */
407 br $29, .+4
408 ldgp $29, 0($29)
409
410 /* Set up the arguments for _dl_profile_fixup:
411 $16 = link_map out of plt0
412 $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
413 $18 = return address
414 $19 = La_alpha_regs address
415 $20 = framesize address
416 */
417 subq $28, $27, $17
418 ldq $16, 8($27)
419 subq $17, 20, $17
420 mov $26, $18
421 addq $17, $17, $17
422 lda $19, 0($30)
423 lda $20, 45*8($30)
424 stq $16, 48*8($30)
425 stq $17, 49*8($30)
426
427 bsr $26, _dl_profile_fixup !samegp
428
429 /* Discover if we're wrapping this call. */
430 ldq $18, 45*8($30)
431 bge $18, 1f
432
433 /* Move the destination address into position. */
434 mov $0, $27
435 /* Restore program registers. */
436 ldq $26, 0*8($30)
437 ldq $16, 2*8($30)
438 ldq $17, 3*8($30)
439 ldq $18, 4*8($30)
440 ldq $19, 5*8($30)
441 ldq $20, 6*8($30)
442 ldq $21, 7*8($30)
443 ldt $f16, 8*8($30)
444 ldt $f17, 9*8($30)
445 ldt $f18, 10*8($30)
446 ldt $f19, 11*8($30)
447 ldt $f20, 12*8($30)
448 ldt $f21, 13*8($30)
449 ldq $0, 14*8($30)
450 ldq $1, 15*8($30)
451 ldq $2, 16*8($30)
452 ldq $3, 17*8($30)
453 ldq $4, 18*8($30)
454 ldq $5, 19*8($30)
455 ldq $6, 20*8($30)
456 ldq $7, 21*8($30)
457 ldq $8, 22*8($30)
458 ldq $22, 23*8($30)
459 ldq $23, 24*8($30)
460 ldq $24, 25*8($30)
461 ldq $25, 26*8($30)
462 ldq $29, 27*8($30)
463 ldt $f0, 28*8($30)
464 ldt $f1, 29*8($30)
465 ldt $f10, 30*8($30)
466 ldt $f11, 31*8($30)
467 ldt $f12, 32*8($30)
468 ldt $f13, 33*8($30)
469 ldt $f14, 34*8($30)
470 ldt $f15, 35*8($30)
471 ldt $f22, 36*8($30)
472 ldt $f23, 37*8($30)
473 ldt $f24, 38*8($30)
474 ldt $f25, 39*8($30)
475 ldt $f26, 40*8($30)
476 ldt $f27, 41*8($30)
477 ldt $f28, 42*8($30)
478 ldt $f29, 43*8($30)
479 ldt $f30, 44*8($30)
480
481 /* Clean up and turn control to the destination. */
482 lda $30, FRAMESIZE($30)
483 jmp $31, ($27)
484
4851:
486 /* Create a frame pointer and allocate a new argument frame. */
487 savei 15, 45*8
488 mov $30, $15
489 cfi_def_cfa_register (15)
490 addq $18, 15, $18
491 bic $18, 15, $18
492 subq $30, $18, $30
493
494 /* Save the call destination around memcpy. */
495 stq $0, 46*8($30)
496
497 /* Copy the stack arguments into place. */
498 lda $16, 0($30)
499 lda $17, FRAMESIZE($15)
500 jsr $26, memcpy
501 ldgp $29, 0($26)
502
503 /* Reload the argument registers. */
504 ldq $27, 46*8($30)
505 ldq $16, 2*8($15)
506 ldq $17, 3*8($15)
507 ldq $18, 4*8($15)
508 ldq $19, 5*8($15)
509 ldq $20, 6*8($15)
510 ldq $21, 7*8($15)
511 ldt $f16, 8*8($15)
512 ldt $f17, 9*8($15)
513 ldt $f18, 10*8($15)
514 ldt $f19, 11*8($15)
515 ldt $f20, 12*8($15)
516 ldt $f21, 13*8($15)
517
518 jsr $26, ($27), 0
519 ldgp $29, 0($26)
520
521 /* Set up for call to _dl_audit_pltexit. */
522 ldq $16, 48*8($15)
523 ldq $17, 49*8($15)
524 stq $0, 46*8($15)
525 lda $18, 0($15)
526 stq $1, 47*8($15)
527 lda $19, 46*8($15)
528 stt $f0, 48*8($15)
529 stt $f1, 49*8($15)
530 bsr $26, _dl_audit_pltexit !samegp
531
532 mov $15, $30
533 cfi_def_cfa_register (30)
534 ldq $26, 0($30)
535 ldq $15, 45*8($30)
536 lda $30, FRAMESIZE($30)
537 ret
538
539 cfi_endproc
540 .size _dl_runtime_profile_old, .-_dl_runtime_profile_old
541

source code of glibc/sysdeps/alpha/dl-trampoline.S