1 /* Save current context and install the given one.
2 Copyright (C) 2002, 2004, 2005, 2006, 2008, 2009
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
22 #include <rtld-global-offsets.h>
23 #include <shlib-compat.h>
24 #include <kernel-features.h>
27 #include <asm/ptrace.h>
28 #include "ucontext_i.h"
29 #include <asm/errno.h>
34 .tc _rtld_global_ro[TC],_rtld_global_ro
36 .tc _dl_hwcap[TC],_dl_hwcap
39 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
41 ENTRY(__novec_swapcontext)
43 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
44 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
45 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
49 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
50 std r0,FRAME_LR_SAVE(r1)
51 cfi_offset (lr, FRAME_LR_SAVE)
52 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
53 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
55 cfi_adjust_cfa_offset (128)
56 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
57 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
58 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
59 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
60 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
61 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
62 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
63 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
64 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
65 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
66 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
67 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
68 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
69 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
70 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
71 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
72 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
73 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
74 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
75 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
76 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
77 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
78 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
79 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
80 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
81 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
82 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
83 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
85 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
87 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
89 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
91 /* Set the return value of swapcontext to "success". R3 is the only
92 register whose value is not preserved in the saved context. */
94 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
96 /* Zero fill fields that can't be set in user state or are unused. */
97 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
98 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
99 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
100 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
101 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
102 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
103 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
105 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
106 field. Struct pt_regs and elf_gregset_t are the same thing.
107 We kept the regs field for backwards compatibility with
108 libraries built before we extended sigcontext. */
109 addi r0,r3,SIGCONTEXT_GP_REGS
110 std r0,SIGCONTEXT_PT_REGS(r3)
112 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
113 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
114 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
115 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
116 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
117 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
118 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
119 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
120 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
121 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
122 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
123 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
124 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
125 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
126 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
127 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
128 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
129 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
130 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
131 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
132 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
133 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
134 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
135 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
136 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
137 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
138 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
139 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
140 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
141 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
143 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
144 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
145 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
148 addi r5,r3,UCONTEXT_SIGMASK
149 addi r4,r4,UCONTEXT_SIGMASK
151 bl JUMPTARGET(__sigprocmask)
157 * If this new ucontext refers to the point where we were interrupted
158 * by a signal, we have to use the rt_sigreturn system call to
159 * return to the context so we get both LR and CTR restored.
161 * Otherwise, the context we are restoring is either just after
162 * a procedure call (getcontext/swapcontext) or at the beginning
163 * of a procedure call (makecontext), so we don't need to restore
164 * msr and ctr. We don't restore r13 since it will be used as
165 * the TLS pointer. */
166 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
171 /* Load _rtld-global._dl_hwcap. */
172 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
174 ld r8,0(r8) /* Load extern _dl_hwcap. */
177 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
178 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
179 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
181 /* Use the extended four-operand version of the mtfsf insn. */
186 /* Availability of DFP indicates a 64-bit FPSCR. */
187 andi. r6,r8,PPC_FEATURE_HAS_DFP
189 /* Use the extended four-operand version of the mtfsf insn. */
192 /* Continue to operate on the FPSCR as if it were 32-bits. */
197 #endif /* _ARCH_PWR6 */
198 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
199 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
200 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
201 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
202 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
203 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
204 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
205 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
206 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
207 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
208 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
209 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
210 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
211 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
212 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
213 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
214 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
215 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
216 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
217 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
218 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
219 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
220 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
221 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
222 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
223 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
224 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
225 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
226 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
227 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
229 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
230 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
232 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
233 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
234 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
236 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
237 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
238 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
240 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
241 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
242 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
243 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
244 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
245 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
246 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
247 /* Don't reload the thread ID or TLS pointer (r13). */
248 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
249 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
250 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
251 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
252 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
253 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
254 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
255 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
256 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
257 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
258 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
259 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
260 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
261 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
262 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
263 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
264 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
266 /* Now we branch to the "Next Instruction Pointer" from the saved
267 context. With the powerpc64 instruction set there is no good way to
268 do this (from user state) without clobbering either the LR or CTR.
269 The makecontext and swapcontext functions depend on the callers
270 LR being preserved so we use the CTR. */
271 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
273 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
274 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
278 ld r0,128+FRAME_LR_SAVE(r1)
284 /* At this point we assume that the ucontext was created by a
285 rt_signal and we should use rt_sigreturn to restore the original
286 state. As of the 2.4.21 kernel the ucontext is the first thing
287 (offset 0) in the rt_signal frame and rt_sigreturn expects the
288 ucontext address in R1. Normally the rt-signal trampoline handles
289 this by popping dummy frame before the rt_signal syscall. In our
290 case the stack may not be in its original (signal handler return with
291 R1 pointing at the dummy frame) state. We do have the ucontext
292 address in R3, so simply copy R3 to R1 before the syscall. */
295 li r0,SYS_ify(rt_sigreturn)
299 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
301 std r0,FRAME_LR_SAVE(r1)
302 cfi_offset(lr,FRAME_LR_SAVE)
305 bl JUMPTARGET(__syscall_error)
308 ld r0,128+FRAME_LR_SAVE(r1)
314 PSEUDO_END(__novec_swapcontext)
316 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
324 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
325 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
326 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
330 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
331 std r0,FRAME_LR_SAVE(r1)
332 cfi_offset (lr, FRAME_LR_SAVE)
333 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
334 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
336 cfi_adjust_cfa_offset(128)
337 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
338 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
339 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
340 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
341 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
342 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
343 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
344 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
345 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
346 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
347 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
348 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
349 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
350 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
351 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
352 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
353 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
354 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
355 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
356 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
357 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
358 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
359 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
360 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
361 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
362 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
363 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
364 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
366 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
368 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
370 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
372 /* Set the return value of swapcontext to "success". R3 is the only
373 register whose value is not preserved in the saved context. */
375 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
377 /* Zero fill fields that can't be set in user state or are unused. */
378 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
379 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
380 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
381 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
382 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
383 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
384 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
386 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
387 field. Struct pt_regs and elf_gregset_t are the same thing.
388 We kept the regs field for backwards compatibility with
389 libraries built before we extended sigcontext. */
390 addi r0,r3,SIGCONTEXT_GP_REGS
391 std r0,SIGCONTEXT_PT_REGS(r3)
393 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
394 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
395 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
396 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
397 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
398 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
399 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
400 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
401 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
402 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
403 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
404 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
405 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
406 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
407 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
408 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
409 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
410 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
411 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
412 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
413 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
414 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
415 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
416 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
417 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
418 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
419 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
420 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
421 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
422 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
424 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
425 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
426 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
428 ld r8,.LC__dl_hwcap@toc(r2)
430 /* Load _rtld-global._dl_hwcap. */
431 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
433 ld r8,0(r8) /* Load extern _dl_hwcap. */
435 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
436 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
438 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
444 mr r8,r10 /* Capture *v_regs value in r5. */
533 Store either a NULL or a quadword aligned pointer to the Vector register
536 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
539 addi r5,r3,UCONTEXT_SIGMASK
540 addi r4,r4,UCONTEXT_SIGMASK
542 bl JUMPTARGET(__sigprocmask)
548 * If this new ucontext refers to the point where we were interrupted
549 * by a signal, we have to use the rt_sigreturn system call to
550 * return to the context so we get both LR and CTR restored.
552 * Otherwise, the context we are restoring is either just after
553 * a procedure call (getcontext/swapcontext) or at the beginning
554 * of a procedure call (makecontext), so we don't need to restore
555 * msr and ctr. We don't restore r13 since it will be used as
556 * the TLS pointer. */
557 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
561 ld r8,.LC__dl_hwcap@toc(r2)
562 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
564 /* Load _rtld-global._dl_hwcap. */
565 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
567 ld r8,0(r8) /* Load extern _dl_hwcap. */
569 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
672 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
673 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
674 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
676 /* Use the extended four-operand version of the mtfsf insn. */
681 /* Availability of DFP indicates a 64-bit FPSCR. */
682 andi. r6,r8,PPC_FEATURE_HAS_DFP
684 /* Use the extended four-operand version of the mtfsf insn. */
687 /* Continue to operate on the FPSCR as if it were 32-bits. */
692 #endif /* _ARCH_PWR6 */
693 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
694 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
695 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
696 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
697 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
698 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
699 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
700 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
701 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
702 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
703 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
704 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
705 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
706 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
707 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
708 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
709 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
710 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
711 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
712 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
713 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
714 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
715 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
716 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
717 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
718 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
719 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
720 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
721 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
722 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
724 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
725 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
727 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
728 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
729 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
731 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
732 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
733 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
734 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
735 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
736 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
737 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
739 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
740 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
741 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
742 /* Don't reload the thread ID or TLS pointer (r13). */
743 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
744 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
745 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
746 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
747 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
748 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
749 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
750 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
751 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
752 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
753 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
754 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
755 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
756 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
757 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
758 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
759 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
761 /* Now we branch to the "Next Instruction Pointer" from the saved
762 context. With the powerpc64 instruction set there is no good way to
763 do this (from user state) without clobbering either the LR or CTR.
764 The makecontext and swapcontext functions depend on the callers
765 LR being preserved so we use the CTR. */
766 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
768 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
769 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
773 ld r0,128+FRAME_LR_SAVE(r1)
779 /* At this point we assume that the ucontext was created by a
780 rt_signal and we should use rt_sigreturn to restore the original
781 state. As of the 2.4.21 kernel the ucontext is the first thing
782 (offset 0) in the rt_signal frame and rt_sigreturn expects the
783 ucontext address in R1. Normally the rt-signal trampoline handles
784 this by popping dummy frame before the rt_signal syscall. In our
785 case the stack may not be in its original (signal handler return with
786 R1 pointing at the dummy frame) state. We do have the ucontext
787 address in R3, so simply copy R3 to R1 before the syscall. */
790 li r0,SYS_ify(rt_sigreturn)
794 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
796 std r0,FRAME_LR_SAVE(r1)
797 cfi_offset (lr, FRAME_LR_SAVE)
799 cfi_adjust_cfa_offset (128)
801 bl JUMPTARGET(__syscall_error)
804 ld r0,128+FRAME_LR_SAVE(r1)
810 PSEUDO_END(__swapcontext)
812 versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)