1 /* Save current context and install the given one.
2 Copyright (C) 2002-2014 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, see
17 <http://www.gnu.org/licenses/>. */
20 #include <rtld-global-offsets.h>
21 #include <shlib-compat.h>
22 #include <kernel-features.h>
25 #include <asm/ptrace.h>
26 #include "ucontext_i.h"
27 #include <asm/errno.h>
32 .tc _rtld_global_ro[TC],_rtld_global_ro
34 .tc _dl_hwcap[TC],_dl_hwcap
37 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
39 ENTRY(__novec_swapcontext)
41 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
42 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
46 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
47 std r0,FRAME_LR_SAVE(r1)
48 cfi_offset (lr, FRAME_LR_SAVE)
49 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
50 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
52 cfi_adjust_cfa_offset (128)
53 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
54 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
55 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
56 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
57 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
58 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
59 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
60 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
61 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
62 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
63 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
64 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
65 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
66 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
67 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
68 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
69 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
70 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
71 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
72 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
73 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
74 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
75 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
76 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
77 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
78 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
79 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
80 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
82 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
84 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
86 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
88 /* Set the return value of swapcontext to "success". R3 is the only
89 register whose value is not preserved in the saved context. */
91 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
93 /* Zero fill fields that can't be set in user state or are unused. */
94 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
95 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
96 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
97 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
98 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
99 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
100 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
102 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
103 field. Struct pt_regs and elf_gregset_t are the same thing.
104 We kept the regs field for backwards compatibility with
105 libraries built before we extended sigcontext. */
106 addi r0,r3,SIGCONTEXT_GP_REGS
107 std r0,SIGCONTEXT_PT_REGS(r3)
109 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
110 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
111 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
112 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
113 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
114 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
115 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
116 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
117 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
118 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
119 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
120 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
121 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
122 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
123 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
124 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
125 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
126 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
127 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
128 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
129 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
130 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
131 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
132 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
133 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
134 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
135 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
136 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
137 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
138 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
140 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
141 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
142 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
145 addi r5,r3,UCONTEXT_SIGMASK
146 addi r4,r4,UCONTEXT_SIGMASK
148 bl JUMPTARGET(__sigprocmask)
154 * If this new ucontext refers to the point where we were interrupted
155 * by a signal, we have to use the rt_sigreturn system call to
156 * return to the context so we get both LR and CTR restored.
158 * Otherwise, the context we are restoring is either just after
159 * a procedure call (getcontext/swapcontext) or at the beginning
160 * of a procedure call (makecontext), so we don't need to restore
161 * msr and ctr. We don't restore r13 since it will be used as
162 * the TLS pointer. */
163 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
168 /* Load _rtld-global._dl_hwcap. */
169 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
171 ld r8,0(r8) /* Load extern _dl_hwcap. */
174 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
175 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
176 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
178 /* 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. */
194 #endif /* _ARCH_PWR6 */
195 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
196 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
197 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
198 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
199 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
200 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
201 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
202 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
203 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
204 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
205 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
206 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
207 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
208 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
209 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
210 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
211 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
212 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
213 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
214 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
215 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
216 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
217 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
218 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
219 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
220 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
221 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
222 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
223 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
224 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
226 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
227 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
229 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
230 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
231 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
233 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
234 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
235 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
237 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
238 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
239 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
240 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
241 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
242 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
243 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
244 /* Don't reload the thread ID or TLS pointer (r13). */
245 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
246 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
247 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
248 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
249 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
250 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
251 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
252 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
253 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
254 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
255 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
256 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
257 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
258 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
259 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
260 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
261 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
263 /* Now we branch to the "Next Instruction Pointer" from the saved
264 context. With the powerpc64 instruction set there is no good way to
265 do this (from user state) without clobbering either the LR or CTR.
266 The makecontext and swapcontext functions depend on the callers
267 LR being preserved so we use the CTR. */
268 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
270 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
271 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
275 ld r0,128+FRAME_LR_SAVE(r1)
281 /* At this point we assume that the ucontext was created by a
282 rt_signal and we should use rt_sigreturn to restore the original
283 state. As of the 2.4.21 kernel the ucontext is the first thing
284 (offset 0) in the rt_signal frame and rt_sigreturn expects the
285 ucontext address in R1. Normally the rt-signal trampoline handles
286 this by popping dummy frame before the rt_signal syscall. In our
287 case the stack may not be in its original (signal handler return with
288 R1 pointing at the dummy frame) state. We do have the ucontext
289 address in R3, so simply copy R3 to R1 before the syscall. */
292 li r0,SYS_ify(rt_sigreturn)
296 PSEUDO_END(__novec_swapcontext)
298 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
306 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
307 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
311 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
312 std r0,FRAME_LR_SAVE(r1)
313 cfi_offset (lr, FRAME_LR_SAVE)
314 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
315 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
317 cfi_adjust_cfa_offset(128)
318 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
319 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
320 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
321 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
322 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
323 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
324 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
325 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
326 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
327 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
328 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
329 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
330 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
331 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
332 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
333 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
334 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
335 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
336 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
337 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
338 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
339 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
340 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
341 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
342 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
343 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
344 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
345 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
347 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
349 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
351 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
353 /* Set the return value of swapcontext to "success". R3 is the only
354 register whose value is not preserved in the saved context. */
356 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
358 /* Zero fill fields that can't be set in user state or are unused. */
359 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
360 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
361 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
362 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
363 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
364 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
365 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
367 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
368 field. Struct pt_regs and elf_gregset_t are the same thing.
369 We kept the regs field for backwards compatibility with
370 libraries built before we extended sigcontext. */
371 addi r0,r3,SIGCONTEXT_GP_REGS
372 std r0,SIGCONTEXT_PT_REGS(r3)
374 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
375 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
376 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
377 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
378 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
379 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
380 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
381 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
382 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
383 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
384 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
385 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
386 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
387 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
388 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
389 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
390 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
391 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
392 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
393 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
394 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
395 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
396 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
397 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
398 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
399 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
400 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
401 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
402 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
403 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
405 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
406 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
407 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
409 ld r8,.LC__dl_hwcap@toc(r2)
411 /* Load _rtld-global._dl_hwcap. */
412 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
414 ld r8,0(r8) /* Load extern _dl_hwcap. */
416 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
417 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
419 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
425 mr r8,r10 /* Capture *v_regs value in r5. */
514 Store either a NULL or a quadword aligned pointer to the Vector register
517 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
520 addi r5,r3,UCONTEXT_SIGMASK
521 addi r4,r4,UCONTEXT_SIGMASK
523 bl JUMPTARGET(__sigprocmask)
529 * If this new ucontext refers to the point where we were interrupted
530 * by a signal, we have to use the rt_sigreturn system call to
531 * return to the context so we get both LR and CTR restored.
533 * Otherwise, the context we are restoring is either just after
534 * a procedure call (getcontext/swapcontext) or at the beginning
535 * of a procedure call (makecontext), so we don't need to restore
536 * msr and ctr. We don't restore r13 since it will be used as
537 * the TLS pointer. */
538 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
542 ld r8,.LC__dl_hwcap@toc(r2)
543 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
545 /* Load _rtld-global._dl_hwcap. */
546 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
548 ld r8,0(r8) /* Load extern _dl_hwcap. */
550 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
653 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
654 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
655 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
657 /* Use the extended four-operand version of the mtfsf insn. */
662 /* Availability of DFP indicates a 64-bit FPSCR. */
663 andi. r6,r8,PPC_FEATURE_HAS_DFP
665 /* Use the extended four-operand version of the mtfsf insn. */
668 /* Continue to operate on the FPSCR as if it were 32-bits. */
673 #endif /* _ARCH_PWR6 */
674 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
675 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
676 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
677 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
678 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
679 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
680 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
681 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
682 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
683 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
684 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
685 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
686 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
687 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
688 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
689 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
690 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
691 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
692 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
693 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
694 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
695 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
696 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
697 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
698 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
699 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
700 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
701 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
702 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
703 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
705 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
706 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
708 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
709 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
710 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
712 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
713 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
714 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
715 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
716 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
717 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
718 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
720 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
721 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
722 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
723 /* Don't reload the thread ID or TLS pointer (r13). */
724 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
725 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
726 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
727 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
728 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
729 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
730 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
731 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
732 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
733 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
734 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
735 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
736 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
737 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
738 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
739 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
740 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
742 /* Now we branch to the "Next Instruction Pointer" from the saved
743 context. With the powerpc64 instruction set there is no good way to
744 do this (from user state) without clobbering either the LR or CTR.
745 The makecontext and swapcontext functions depend on the callers
746 LR being preserved so we use the CTR. */
747 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
749 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
750 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
754 ld r0,128+FRAME_LR_SAVE(r1)
760 /* At this point we assume that the ucontext was created by a
761 rt_signal and we should use rt_sigreturn to restore the original
762 state. As of the 2.4.21 kernel the ucontext is the first thing
763 (offset 0) in the rt_signal frame and rt_sigreturn expects the
764 ucontext address in R1. Normally the rt-signal trampoline handles
765 this by popping dummy frame before the rt_signal syscall. In our
766 case the stack may not be in its original (signal handler return with
767 R1 pointing at the dummy frame) state. We do have the ucontext
768 address in R3, so simply copy R3 to R1 before the syscall. */
771 li r0,SYS_ify(rt_sigreturn)
775 PSEUDO_END(__swapcontext)
777 versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)