1 /* Save current context and install the given one.
2 Copyright (C) 2002, 2004, 2005 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., 59 Temple Place, Suite 330, 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>
30 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
31 ENTRY(__novec_swapcontext)
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)
38 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
39 std r0,FRAME_LR_SAVE(r1)
40 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
41 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
43 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
44 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
45 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
46 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
47 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
48 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
49 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
50 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
51 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
52 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
53 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
54 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
55 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
56 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
57 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
58 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
59 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
60 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
61 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
62 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
63 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
64 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
65 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
66 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
67 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
68 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
69 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
70 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
72 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
74 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
76 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
78 /* Set the return value of swapcontext to "success". R3 is the only
79 register whose value is not preserved in the saved context. */
81 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
83 /* Zero fill fields that can't be set in user state or are unused. */
84 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
85 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
86 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
87 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
88 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
89 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
90 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
92 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
93 field. Struct pt_regs and elf_gregset_t are the same thing.
94 We kept the regs field for backwards compatibility with
95 libraries built before we extended sigcontext. */
96 addi r0,r3,SIGCONTEXT_GP_REGS
97 std r0,SIGCONTEXT_PT_REGS(r3)
99 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
100 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
101 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
102 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
103 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
104 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
105 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
106 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
107 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
108 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
109 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
110 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
111 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
112 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
113 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
114 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
115 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
116 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
117 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
118 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
119 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
120 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
121 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
122 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
123 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
124 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
125 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
126 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
127 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
128 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
130 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
131 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
132 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
135 addi r5,r3,UCONTEXT_SIGMASK
136 addi r4,r4,UCONTEXT_SIGMASK
138 bl JUMPTARGET(__sigprocmask)
144 * If this new ucontext refers to the point where we were interrupted
145 * by a signal, we have to use the rt_sigreturn system call to
146 * return to the context so we get both LR and CTR restored.
148 * Otherwise, the context we are restoring is either just after
149 * a procedure call (getcontext/swapcontext) or at the beginning
150 * of a procedure call (makecontext), so we don't need to restore
151 * msr and ctr. We don't restore r13 since it will be used as
152 * the TLS pointer. */
153 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
157 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
158 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
159 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
161 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
162 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
163 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
164 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
165 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
166 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
167 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
168 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
169 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
170 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
171 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
172 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
173 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
174 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
175 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
176 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
177 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
178 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
179 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
180 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
181 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
182 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
183 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
184 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
185 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
186 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
187 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
188 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
189 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
190 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
192 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
193 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
195 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
196 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
197 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
199 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
200 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
201 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
203 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
204 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
205 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
206 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
207 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
208 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
209 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
210 /* Don't reload the thread ID or TLS pointer (r13). */
211 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
212 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
213 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
214 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
215 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
216 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
217 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
218 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
219 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
220 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
221 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
222 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
223 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
224 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
225 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
226 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
227 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
229 /* Now we branch to the "Next Instruction Pointer" from the saved
230 context. With the powerpc64 instruction set there is no good way to
231 do this (from user state) without clobbering either the LR or CTR.
232 The makecontext and swapcontext functions depend on the callers
233 LR being preserved so we use the CTR. */
234 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
236 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
237 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
241 ld r0,128+FRAME_LR_SAVE(r1)
247 /* At this point we assume that the ucontext was created by a
248 rt_signal and we should use rt_sigreturn to restore the original
249 state. As of the 2.4.21 kernel the ucontext is the first thing
250 (offset 0) in the rt_signal frame and rt_sigreturn expects the
251 ucontext address in R1. Normally the rt-signal trampoline handles
252 this by popping dummy frame before the rt_signal syscall. In our
253 case the stack may not be in its original (signal handler return with
254 R1 pointing at the dummy frame) state. We do have the ucontext
255 address in R3, so simply copy R3 to R1 before the syscall. */
258 li r0,SYS_ify(rt_sigreturn)
262 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
264 std r0,FRAME_LR_SAVE(r1)
267 bl JUMPTARGET(__syscall_error)
270 ld r0,128+FRAME_LR_SAVE(r1)
276 PSEUDO_END(__novec_swapcontext)
278 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
285 .tc _rtld_global_ro[TC],_rtld_global_ro
287 .tc _dl_hwcap[TC],_dl_hwcap
294 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
295 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
296 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
299 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
300 std r0,FRAME_LR_SAVE(r1)
301 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
302 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
304 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
305 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
306 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
307 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
308 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
309 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
310 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
311 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
312 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
313 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
314 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
315 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
316 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
317 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
318 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
319 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
320 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
321 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
322 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
323 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
324 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
325 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
326 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
327 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
328 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
329 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
330 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
331 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
333 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
335 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
337 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
339 /* Set the return value of swapcontext to "success". R3 is the only
340 register whose value is not preserved in the saved context. */
342 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
344 /* Zero fill fields that can't be set in user state or are unused. */
345 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
346 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
347 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
348 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
349 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
350 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
351 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
353 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
354 field. Struct pt_regs and elf_gregset_t are the same thing.
355 We kept the regs field for backwards compatibility with
356 libraries built before we extended sigcontext. */
357 addi r0,r3,SIGCONTEXT_GP_REGS
358 std r0,SIGCONTEXT_PT_REGS(r3)
360 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
361 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
362 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
363 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
364 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
365 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
366 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
367 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
368 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
369 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
370 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
371 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
372 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
373 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
374 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
375 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
376 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
377 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
378 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
379 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
380 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
381 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
382 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
383 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
384 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
385 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
386 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
387 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
388 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
389 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
391 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
392 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
393 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
395 ld r8,.LC__dl_hwcap@toc(r2)
397 /* Load _rtld-global._dl_hwcap. */
398 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
400 ld r8,0(r8) /* Load extern _dl_hwcap. */
402 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
403 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
405 andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
411 mr r8,r10 /* Capture *v_regs value in r5. */
500 Store either a NULL or a quadword aligned pointer to the Vector register
503 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
506 addi r5,r3,UCONTEXT_SIGMASK
507 addi r4,r4,UCONTEXT_SIGMASK
509 bl JUMPTARGET(__sigprocmask)
515 * If this new ucontext refers to the point where we were interrupted
516 * by a signal, we have to use the rt_sigreturn system call to
517 * return to the context so we get both LR and CTR restored.
519 * Otherwise, the context we are restoring is either just after
520 * a procedure call (getcontext/swapcontext) or at the beginning
521 * of a procedure call (makecontext), so we don't need to restore
522 * msr and ctr. We don't restore r13 since it will be used as
523 * the TLS pointer. */
524 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
528 ld r8,.LC__dl_hwcap@toc(r2)
529 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
531 /* Load _rtld-global._dl_hwcap. */
532 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
534 ld r8,0(r8) /* Load extern _dl_hwcap. */
536 andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
639 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
640 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
641 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
643 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
644 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
645 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
646 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
647 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
648 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
649 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
650 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
651 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
652 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
653 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
654 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
655 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
656 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
657 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
658 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
659 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
660 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
661 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
662 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
663 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
664 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
665 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
666 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
667 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
668 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
669 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
670 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
671 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
672 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
674 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
675 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
677 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
678 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
679 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
681 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
682 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
683 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
684 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
685 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
686 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
687 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
689 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
690 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
691 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
692 /* Don't reload the thread ID or TLS pointer (r13). */
693 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
694 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
695 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
696 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
697 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
698 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
699 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
700 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
701 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
702 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
703 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
704 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
705 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
706 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
707 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
708 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
709 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
711 /* Now we branch to the "Next Instruction Pointer" from the saved
712 context. With the powerpc64 instruction set there is no good way to
713 do this (from user state) without clobbering either the LR or CTR.
714 The makecontext and swapcontext functions depend on the callers
715 LR being preserved so we use the CTR. */
716 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
718 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
719 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
723 ld r0,128+FRAME_LR_SAVE(r1)
729 /* At this point we assume that the ucontext was created by a
730 rt_signal and we should use rt_sigreturn to restore the original
731 state. As of the 2.4.21 kernel the ucontext is the first thing
732 (offset 0) in the rt_signal frame and rt_sigreturn expects the
733 ucontext address in R1. Normally the rt-signal trampoline handles
734 this by popping dummy frame before the rt_signal syscall. In our
735 case the stack may not be in its original (signal handler return with
736 R1 pointing at the dummy frame) state. We do have the ucontext
737 address in R3, so simply copy R3 to R1 before the syscall. */
740 li r0,SYS_ify(rt_sigreturn)
744 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
746 std r0,FRAME_LR_SAVE(r1)
749 bl JUMPTARGET(__syscall_error)
752 ld r0,128+FRAME_LR_SAVE(r1)
758 PSEUDO_END(__swapcontext)
760 versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)