1 | /* PLT trampolines. Sparc 32-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 | * %g2: callers PC, which is PLT0 + 4, and we store the |
26 | * link map at PLT0 + 12, therefore we add 8 to get |
27 | * the address of the link map |
28 | */ |
29 | .globl _dl_runtime_resolve |
30 | .type _dl_runtime_resolve, @function |
31 | _dl_runtime_resolve: |
32 | cfi_startproc |
33 | |
34 | save %sp, -104, %sp |
35 | cfi_def_cfa_register(%fp) |
36 | cfi_window_save |
37 | cfi_register (%o7, %i7) |
38 | |
39 | ld [%g2 + 8], %o0 |
40 | srl %g1, 10, %o1 |
41 | call _dl_fixup |
42 | sub %o1, 4*12, %o1 |
43 | jmp %o0 |
44 | restore |
45 | |
46 | cfi_endproc |
47 | |
48 | .size _dl_runtime_resolve, .-_dl_runtime_resolve |
49 | |
50 | #ifdef SHARED |
51 | /* For the profiling cases we pass in our stack frame |
52 | * as the base of the La_sparc32_regs, so it looks |
53 | * like: |
54 | * %l0 %sp + (0 * 8) |
55 | * %l1 %sp + (0 * 8) + 4 |
56 | * ... |
57 | * %l6 %sp + (3 * 8) |
58 | * %l7 %sp + (3 * 8) + 4 |
59 | * %i0 %sp + (4 * 8) |
60 | * %i1 %sp + (4 * 8) + 4 |
61 | * ... |
62 | * %i6 %sp + (7 * 8) |
63 | * %i7 %sp + (7 * 8) + 4 |
64 | * struct_ret_ptr %sp + (8 * 8) |
65 | * framesize %sp + (9 * 8) |
66 | */ |
67 | |
68 | .globl _dl_profile_save_regs |
69 | .type _dl_profile_save_regs, @function |
70 | _dl_profile_save_regs: |
71 | cfi_startproc |
72 | |
73 | std %l0, [%sp + ( 0 * 8)] |
74 | std %l2, [%sp + ( 1 * 8)] |
75 | std %l4, [%sp + ( 2 * 8)] |
76 | std %l6, [%sp + ( 3 * 8)] |
77 | std %i0, [%sp + ( 4 * 8)] |
78 | std %i2, [%sp + ( 5 * 8)] |
79 | std %i4, [%sp + ( 6 * 8)] |
80 | std %i6, [%sp + ( 7 * 8)] |
81 | ld [%fp + (8 * 8)], %l4 |
82 | retl |
83 | st %l4, [%sp + (8 * 8)] |
84 | |
85 | cfi_endproc |
86 | |
87 | .size _dl_profile_save_regs, .-_dl_profile_save_regs |
88 | |
89 | /* If we are going to call pltexit, then we must replicate |
90 | * the caller's stack frame. |
91 | * %o0: PLT resolved function address |
92 | */ |
93 | .globl _dl_profile_invoke |
94 | .type _dl_profile_invoke, @function |
95 | _dl_profile_invoke: |
96 | cfi_startproc |
97 | |
98 | add %l0, 7, %l0 |
99 | andn %l0, 7, %l0 |
100 | add %l0, 2 * 8, %g1 |
101 | |
102 | sub %sp, %g1, %sp |
103 | srl %l0, 3, %l7 |
104 | mov %o0, %l1 |
105 | mov %i0, %o0 |
106 | mov %i1, %o1 |
107 | mov %i2, %o2 |
108 | mov %i3, %o3 |
109 | mov %i4, %o4 |
110 | mov %i5, %o5 |
111 | cmp %l0, 0 |
112 | mov %fp, %l2 |
113 | be 2f |
114 | add %sp, (11 * 8), %l3 |
115 | 1: ldd [%l2], %g2 |
116 | add %l2, 0x8, %l2 |
117 | subcc %l7, 1, %l7 |
118 | std %g2, [%l3] |
119 | bne 1b |
120 | add %l3, 0x8, %l3 |
121 | |
122 | 2: jmpl %l1, %o7 |
123 | nop |
124 | |
125 | std %o0, [%sp + ( 9 * 8)] |
126 | std %f0, [%sp + (10 * 8)] |
127 | |
128 | mov %l5, %o0 |
129 | mov %l6, %o1 |
130 | add %sp, (11 * 8), %o2 |
131 | call _dl_audit_pltexit |
132 | add %sp, ( 9 * 8), %o3 |
133 | |
134 | ldd [%sp + ( 9 * 8)], %i0 |
135 | ldd [%sp + (10 * 8)], %f0 |
136 | |
137 | jmpl %i7 + 8, %g0 |
138 | restore |
139 | |
140 | cfi_endproc |
141 | |
142 | .size _dl_profile_invoke, .-_dl_profile_invoke |
143 | |
144 | /* %g1: PLT offset loaded by PLT entry |
145 | * %g2: callers PC, which is PLT0 + 4, and we store the |
146 | * link map at PLT0 + 12, therefore we add 8 to get |
147 | * the address of the link map |
148 | */ |
149 | .align 32 |
150 | .globl _dl_runtime_profile |
151 | .type _dl_runtime_profile, @function |
152 | _dl_runtime_profile: |
153 | cfi_startproc |
154 | |
155 | save %sp, -104, %sp |
156 | cfi_def_cfa_register(%fp) |
157 | cfi_window_save |
158 | cfi_register(%o7, %i7) |
159 | |
160 | ld [%g2 + 8], %o0 |
161 | srl %g1, 10, %o1 |
162 | mov %i7, %o2 |
163 | sub %o1, 4*12, %o1 |
164 | |
165 | mov %o0, %l5 |
166 | mov %o1, %l6 |
167 | |
168 | call _dl_profile_save_regs |
169 | nop |
170 | |
171 | mov %sp, %o3 |
172 | call _dl_profile_fixup |
173 | add %sp, (9 * 8), %o4 |
174 | |
175 | ld [%sp + (9 * 8)], %l0 |
176 | cmp %l0, 0 |
177 | bl 1f |
178 | nop |
179 | |
180 | call _dl_profile_invoke |
181 | nop |
182 | |
183 | 1: jmp %o0 |
184 | restore |
185 | |
186 | cfi_endproc |
187 | |
188 | .size _dl_runtime_profile, .-_dl_runtime_profile |
189 | #endif |
190 | |