1 /* Save current context and install the given one.
2 Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
21 #include <rtld-global-offsets.h>
22 #include <shlib-compat.h>
23 #include <kernel-features.h>
26 #include <asm/ptrace.h>
27 #include "ucontext_i.h"
28 #include <asm/errno.h>
33 .tc _rtld_global_ro[TC],_rtld_global_ro
35 .tc _dl_hwcap[TC],_dl_hwcap
38 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
40 ENTRY(__novec_swapcontext)
42 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
43 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
44 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
48 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
49 std r0,FRAME_LR_SAVE(r1)
50 cfi_offset (lr, FRAME_LR_SAVE)
51 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
52 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
54 cfi_adjust_cfa_offset (128)
55 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
56 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
57 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
58 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
59 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
60 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
61 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
62 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
63 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
64 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
65 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
66 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
67 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
68 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
69 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
70 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
71 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
72 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
73 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
74 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
75 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
76 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
77 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
78 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
79 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
80 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
81 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
82 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
84 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
86 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
88 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
90 /* Set the return value of swapcontext to "success". R3 is the only
91 register whose value is not preserved in the saved context. */
93 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
95 /* Zero fill fields that can't be set in user state or are unused. */
96 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
97 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
98 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
99 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
100 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
101 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
102 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
104 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
105 field. Struct pt_regs and elf_gregset_t are the same thing.
106 We kept the regs field for backwards compatibility with
107 libraries built before we extended sigcontext. */
108 addi r0,r3,SIGCONTEXT_GP_REGS
109 std r0,SIGCONTEXT_PT_REGS(r3)
111 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
112 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
113 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
114 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
115 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
116 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
117 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
118 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
119 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
120 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
121 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
122 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
123 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
124 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
125 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
126 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
127 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
128 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
129 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
130 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
131 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
132 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
133 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
134 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
135 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
136 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
137 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
138 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
139 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
140 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
142 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
143 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
144 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
147 addi r5,r3,UCONTEXT_SIGMASK
148 addi r4,r4,UCONTEXT_SIGMASK
150 bl JUMPTARGET(__sigprocmask)
156 * If this new ucontext refers to the point where we were interrupted
157 * by a signal, we have to use the rt_sigreturn system call to
158 * return to the context so we get both LR and CTR restored.
160 * Otherwise, the context we are restoring is either just after
161 * a procedure call (getcontext/swapcontext) or at the beginning
162 * of a procedure call (makecontext), so we don't need to restore
163 * msr and ctr. We don't restore r13 since it will be used as
164 * the TLS pointer. */
165 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
170 /* Load _rtld-global._dl_hwcap. */
171 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
173 ld r8,0(r8) /* Load extern _dl_hwcap. */
176 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
177 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
178 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
180 /* Use the extended four-operand version of the mtfsf insn. */
183 /* Availability of DFP indicates a 64-bit FPSCR. */
184 andi. r6,r8,PPC_FEATURE_HAS_DFP
186 /* Use the extended four-operand version of the mtfsf insn. */
189 /* Continue to operate on the FPSCR as if it were 32-bits. */
193 #endif /* _ARCH_PWR6 */
194 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
195 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
196 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
197 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
198 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
199 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
200 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
201 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
202 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
203 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
204 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
205 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
206 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
207 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
208 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
209 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
210 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
211 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
212 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
213 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
214 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
215 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
216 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
217 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
218 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
219 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
220 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
221 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
222 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
223 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
225 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
226 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
228 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
229 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
230 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
232 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
233 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
234 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
236 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
237 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
238 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
239 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
240 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
241 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
242 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
243 /* Don't reload the thread ID or TLS pointer (r13). */
244 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
245 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
246 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
247 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
248 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
249 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
250 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
251 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
252 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
253 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
254 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
255 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
256 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
257 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
258 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
259 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
260 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
262 /* Now we branch to the "Next Instruction Pointer" from the saved
263 context. With the powerpc64 instruction set there is no good way to
264 do this (from user state) without clobbering either the LR or CTR.
265 The makecontext and swapcontext functions depend on the callers
266 LR being preserved so we use the CTR. */
267 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
269 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
270 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
274 ld r0,128+FRAME_LR_SAVE(r1)
280 /* At this point we assume that the ucontext was created by a
281 rt_signal and we should use rt_sigreturn to restore the original
282 state. As of the 2.4.21 kernel the ucontext is the first thing
283 (offset 0) in the rt_signal frame and rt_sigreturn expects the
284 ucontext address in R1. Normally the rt-signal trampoline handles
285 this by popping dummy frame before the rt_signal syscall. In our
286 case the stack may not be in its original (signal handler return with
287 R1 pointing at the dummy frame) state. We do have the ucontext
288 address in R3, so simply copy R3 to R1 before the syscall. */
291 li r0,SYS_ify(rt_sigreturn)
295 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
297 std r0,FRAME_LR_SAVE(r1)
298 cfi_offset(lr,FRAME_LR_SAVE)
301 bl JUMPTARGET(__syscall_error)
304 ld r0,128+FRAME_LR_SAVE(r1)
310 PSEUDO_END(__novec_swapcontext)
312 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
320 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
321 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
322 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
326 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
327 std r0,FRAME_LR_SAVE(r1)
328 cfi_offset (lr, FRAME_LR_SAVE)
329 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
330 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
332 cfi_adjust_cfa_offset(128)
333 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
334 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
335 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
336 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
337 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
338 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
339 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
340 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
341 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
342 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
343 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
344 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
345 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
346 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
347 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
348 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
349 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
350 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
351 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
352 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
353 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
354 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
355 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
356 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
357 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
358 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
359 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
360 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
362 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
364 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
366 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
368 /* Set the return value of swapcontext to "success". R3 is the only
369 register whose value is not preserved in the saved context. */
371 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
373 /* Zero fill fields that can't be set in user state or are unused. */
374 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
375 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
376 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
377 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
378 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
379 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
380 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
382 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
383 field. Struct pt_regs and elf_gregset_t are the same thing.
384 We kept the regs field for backwards compatibility with
385 libraries built before we extended sigcontext. */
386 addi r0,r3,SIGCONTEXT_GP_REGS
387 std r0,SIGCONTEXT_PT_REGS(r3)
389 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
390 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
391 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
392 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
393 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
394 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
395 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
396 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
397 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
398 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
399 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
400 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
401 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
402 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
403 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
404 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
405 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
406 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
407 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
408 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
409 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
410 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
411 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
412 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
413 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
414 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
415 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
416 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
417 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
418 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
420 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
421 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
422 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
424 ld r8,.LC__dl_hwcap@toc(r2)
426 /* Load _rtld-global._dl_hwcap. */
427 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
429 ld r8,0(r8) /* Load extern _dl_hwcap. */
431 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
432 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
434 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
440 mr r8,r10 /* Capture *v_regs value in r5. */
529 Store either a NULL or a quadword aligned pointer to the Vector register
532 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
535 addi r5,r3,UCONTEXT_SIGMASK
536 addi r4,r4,UCONTEXT_SIGMASK
538 bl JUMPTARGET(__sigprocmask)
544 * If this new ucontext refers to the point where we were interrupted
545 * by a signal, we have to use the rt_sigreturn system call to
546 * return to the context so we get both LR and CTR restored.
548 * Otherwise, the context we are restoring is either just after
549 * a procedure call (getcontext/swapcontext) or at the beginning
550 * of a procedure call (makecontext), so we don't need to restore
551 * msr and ctr. We don't restore r13 since it will be used as
552 * the TLS pointer. */
553 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
557 ld r8,.LC__dl_hwcap@toc(r2)
558 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
560 /* Load _rtld-global._dl_hwcap. */
561 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
563 ld r8,0(r8) /* Load extern _dl_hwcap. */
565 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
668 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
669 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
670 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
672 /* Use the extended four-operand version of the mtfsf insn. */
675 /* Availability of DFP indicates a 64-bit FPSCR. */
676 andi. r6,r8,PPC_FEATURE_HAS_DFP
678 /* Use the extended four-operand version of the mtfsf insn. */
681 /* Continue to operate on the FPSCR as if it were 32-bits. */
685 #endif /* _ARCH_PWR6 */
686 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
687 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
688 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
689 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
690 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
691 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
692 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
693 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
694 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
695 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
696 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
697 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
698 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
699 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
700 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
701 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
702 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
703 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
704 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
705 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
706 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
707 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
708 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
709 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
710 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
711 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
712 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
713 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
714 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
715 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
717 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
718 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
720 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
721 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
722 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
724 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
725 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
726 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
727 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
728 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
729 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
730 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
732 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
733 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
734 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
735 /* Don't reload the thread ID or TLS pointer (r13). */
736 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
737 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
738 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
739 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
740 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
741 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
742 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
743 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
744 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
745 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
746 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
747 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
748 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
749 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
750 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
751 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
752 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
754 /* Now we branch to the "Next Instruction Pointer" from the saved
755 context. With the powerpc64 instruction set there is no good way to
756 do this (from user state) without clobbering either the LR or CTR.
757 The makecontext and swapcontext functions depend on the callers
758 LR being preserved so we use the CTR. */
759 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
761 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
762 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
766 ld r0,128+FRAME_LR_SAVE(r1)
772 /* At this point we assume that the ucontext was created by a
773 rt_signal and we should use rt_sigreturn to restore the original
774 state. As of the 2.4.21 kernel the ucontext is the first thing
775 (offset 0) in the rt_signal frame and rt_sigreturn expects the
776 ucontext address in R1. Normally the rt-signal trampoline handles
777 this by popping dummy frame before the rt_signal syscall. In our
778 case the stack may not be in its original (signal handler return with
779 R1 pointing at the dummy frame) state. We do have the ucontext
780 address in R3, so simply copy R3 to R1 before the syscall. */
783 li r0,SYS_ify(rt_sigreturn)
787 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
789 std r0,FRAME_LR_SAVE(r1)
790 cfi_offset (lr, FRAME_LR_SAVE)
792 cfi_adjust_cfa_offset (128)
794 bl JUMPTARGET(__syscall_error)
797 ld r0,128+FRAME_LR_SAVE(r1)
803 PSEUDO_END(__swapcontext)
805 versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)