]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
Replace FSF snail mail address with URLs.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / getcontext.S
1 /* Save current context.
2 Copyright (C) 2002, 2004, 2006 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 <http://www.gnu.org/licenses/>. */
18
19 #include <sysdep.h>
20 #include <rtld-global-offsets.h>
21 #include <shlib-compat.h>
22 #include <kernel-features.h>
23
24 #define __ASSEMBLY__
25 #include <asm/ptrace.h>
26 #include <asm/errno.h>
27 #include "ucontext_i.h"
28
29
30 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
31 ENTRY(__novec_getcontext)
32 CALL_MCOUNT 1
33 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
34 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
35 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
36 mflr r0
37 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
38 std r0,FRAME_LR_SAVE(r1)
39 cfi_offset (lr, FRAME_LR_SAVE)
40 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
41 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
42 stdu r1,-128(r1)
43 cfi_adjust_cfa_offset (128)
44 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
45 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
46 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
47 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
48 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
49 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
50 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
51 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
52 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
53 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
54 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
55 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
56 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
57 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
58 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
59 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
60 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
61 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
62 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
63 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
64 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
65 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
66 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
67 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
68 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
69 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
70 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
71 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
72 mfctr r0
73 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
74 mfxer r0
75 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
76 mfcr r0
77 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
78
79 /* Set the return value of swapcontext to "success". R3 is the only
80 register whose value is not preserved in the saved context. */
81 li r0,0
82 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
83
84 /* Zero fill fields that can't be set in user state or are unused. */
85 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
86 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
87 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
88 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
89 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
90 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
91 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
92
93 /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
94 field. Struct pt_regs and elf_gregset_t are the same thing.
95 We kept the regs field for backwards compatibility with
96 libraries built before we extended sigcontext. */
97 addi r0,r3,SIGCONTEXT_GP_REGS
98 std r0,SIGCONTEXT_PT_REGS(r3)
99
100 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
101 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
102 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
103 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
104 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
105 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
106 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
107 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
108 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
109 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
110 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
111 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
112 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
113 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
114 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
115 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
116 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
117 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
118 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
119 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
120 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
121 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
122 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
123 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
124 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
125 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
126 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
127 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
128 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
129 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
130 mffs fp0
131 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
132 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
133 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
134
135 addi r5,r3,UCONTEXT_SIGMASK
136 li r4,0
137 li r3,SIG_BLOCK
138 bl JUMPTARGET(__sigprocmask)
139 nop
140 #else
141 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
142 mflr r0
143 std r0,FRAME_LR_SAVE(r1)
144 cfi_offset (lr, FRAME_LR_SAVE)
145 stdu r1,-128(r1)
146 cfi_adjust_cfa_offset(128)
147 li r3,ENOSYS
148 bl JUMPTARGET(__syscall_error)
149 nop
150 li r3,-1
151 #endif
152
153 ld r0,128+FRAME_LR_SAVE(r1)
154 addi r1,r1,128
155 mtlr r0
156 blr
157 PSEUDO_END(__novec_getcontext)
158
159 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
160
161 #endif
162
163 .section ".toc","aw"
164 .LC__dl_hwcap:
165 #ifdef SHARED
166 .tc _rtld_global_ro[TC],_rtld_global_ro
167 #else
168 .tc _dl_hwcap[TC],_dl_hwcap
169 #endif
170 .section ".text"
171
172 .machine "altivec"
173 ENTRY(__getcontext)
174 CALL_MCOUNT 1
175 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
176 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
177 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
178 mflr r0
179 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
180 std r0,FRAME_LR_SAVE(r1)
181 cfi_offset (lr, FRAME_LR_SAVE)
182 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
183 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
184 stdu r1,-128(r1)
185 cfi_adjust_cfa_offset (128)
186 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
187 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
188 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
189 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
190 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
191 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
192 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
193 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
194 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
195 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
196 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
197 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
198 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
199 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
200 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
201 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
202 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
203 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
204 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
205 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
206 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
207 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
208 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
209 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
210 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
211 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
212 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
213 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
214 mfctr r0
215 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
216 mfxer r0
217 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
218 mfcr r0
219 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
220
221 /* Set the return value of swapcontext to "success". R3 is the only
222 register whose value is not preserved in the saved context. */
223 li r0,0
224 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
225
226 /* Zero fill fields that can't be set in user state or are unused. */
227 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
228 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
229 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
230 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
231 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
232 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
233 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
234
235 /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
236 field. Struct pt_regs and elf_gregset_t are the same thing.
237 We kept the regs field for backwards compatibility with
238 libraries built before we extended sigcontext. */
239 addi r0,r3,SIGCONTEXT_GP_REGS
240 std r0,SIGCONTEXT_PT_REGS(r3)
241
242 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
243 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
244 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
245 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
246 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
247 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
248 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
249 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
250 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
251 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
252 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
253 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
254 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
255 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
256 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
257 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
258 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
259 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
260 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
261 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
262 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
263 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
264 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
265 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
266 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
267 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
268 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
269 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
270 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
271 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
272 mffs fp0
273 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
274 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
275 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
276
277 ld r5,.LC__dl_hwcap@toc(r2)
278 # ifdef SHARED
279 /* Load _rtld-global._dl_hwcap. */
280 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
281 # else
282 ld r5,0(r5) /* Load extern _dl_hwcap. */
283 # endif
284 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
285 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
286
287 andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
288
289 clrrdi r10,r10,4
290 beq L(has_no_vec)
291 clrrdi r9,r9,4
292 mr r5,r10 /* Capture *v_regs value in r5. */
293
294 stvx v0,0,r10
295 stvx v1,0,r9
296 addi r10,r10,32
297 addi r9,r9,32
298
299 stvx v2,0,r10
300 stvx v3,0,r9
301 addi r10,r10,32
302 addi r9,r9,32
303
304 stvx v4,0,r10
305 stvx v5,0,r9
306 addi r10,r10,32
307 addi r9,r9,32
308
309 stvx v6,0,r10
310 stvx v7,0,r9
311 addi r10,r10,32
312 addi r9,r9,32
313
314 stvx v8,0,r10
315 stvx v9,0,r9
316 addi r10,r10,32
317 addi r9,r9,32
318
319 stvx v10,0,r10
320 stvx v11,0,r9
321 addi r10,r10,32
322 addi r9,r9,32
323
324 stvx v12,0,r10
325 stvx v13,0,r9
326 addi r10,r10,32
327 addi r9,r9,32
328
329 stvx v14,0,r10
330 stvx v15,0,r9
331 addi r10,r10,32
332 addi r9,r9,32
333
334 stvx v16,0,r10
335 stvx v17,0,r9
336 addi r10,r10,32
337 addi r9,r9,32
338
339 stvx v18,0,r10
340 stvx v19,0,r9
341 addi r10,r10,32
342 addi r9,r9,32
343
344 stvx v20,0,r10
345 stvx v21,0,r9
346 addi r10,r10,32
347 addi r9,r9,32
348
349 stvx v22,0,r10
350 stvx v23,0,r9
351 addi r10,r10,32
352 addi r9,r9,32
353
354 stvx v24,0,r10
355 stvx v25,0,r9
356 addi r10,r10,32
357 addi r9,r9,32
358
359 stvx v26,0,r10
360 stvx v27,0,r9
361 addi r10,r10,32
362 addi r9,r9,32
363
364 stvx v28,0,r10
365 stvx v29,0,r9
366 addi r10,r10,32
367 addi r9,r9,32
368
369 stvx v30,0,r10
370 stvx v31,0,r9
371 addi r10,r10,32
372 addi r9,r9,32
373
374 mfvscr v0
375 mfspr r0,VRSAVE
376 stvx v0,0,r10
377 stw r0,0(9)
378
379 L(has_no_vec):
380 /*
381 Store either a NULL or a quadword aligned pointer to the Vector register
382 array into *v_regs.
383 */
384 std r5,(SIGCONTEXT_V_REGS_PTR)(r3)
385
386 addi r5,r3,UCONTEXT_SIGMASK
387 li r4,0
388 li r3,SIG_BLOCK
389 bl JUMPTARGET(__sigprocmask)
390 nop
391 #else
392 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
393 mflr r0
394 std r0,FRAME_LR_SAVE(r1)
395 cfi_offset (lr, FRAME_LR_SAVE)
396 stdu r1,-128(r1)
397 cfi_adjust_cfa_offset (128)
398 li r3,ENOSYS
399 bl JUMPTARGET(__syscall_error)
400 nop
401 li r3,-1
402 #endif
403
404 ld r0,128+FRAME_LR_SAVE(r1)
405 addi r1,r1,128
406 mtlr r0
407 blr
408 PSEUDO_END(__getcontext)
409
410 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)