1 /* Save current context and install the given one.
2 Copyright (C) 2002, 2004 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)
32 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
33 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
34 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
37 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
38 std r0,FRAME_LR_SAVE(r1)
39 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
40 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
42 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
43 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
44 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
45 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
46 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
47 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
48 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
49 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
50 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
51 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
52 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
53 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
54 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
55 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
56 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
57 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
58 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
59 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
60 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
61 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
62 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
63 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
64 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
65 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
66 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
67 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
68 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
69 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
71 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
73 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
75 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
77 /* Set the return value of swapcontext to "success". R3 is the only
78 register whose value is not preserved in the saved context. */
80 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
82 /* Zero fill fields that can't be set in user state or are unused. */
83 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
84 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
85 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
86 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
87 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
88 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
89 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
91 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
92 field. Struct pt_regs and elf_gregset_t are the same thing.
93 We kept the regs field for backwards compatibility with
94 libraries built before we extended sigcontext. */
95 addi r0,r3,SIGCONTEXT_GP_REGS
96 std r0,SIGCONTEXT_PT_REGS(r3)
98 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
99 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
100 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
101 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
102 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
103 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
104 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
105 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
106 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
107 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
108 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
109 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
110 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
111 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
112 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
113 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
114 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
115 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
116 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
117 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
118 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
119 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
120 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
121 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
122 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
123 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
124 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
125 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
126 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
127 stfd fp29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
129 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
130 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
131 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
134 addi r5,r3,UCONTEXT_SIGMASK
135 addi r4,r4,UCONTEXT_SIGMASK
137 bl JUMPTARGET(sigprocmask)
143 * If this new ucontext refers to the point where we were interrupted
144 * by a signal, we have to use the rt_sigreturn system call to
145 * return to the context so we get both LR and CTR restored.
147 * Otherwise, the context we are restoring is either just after
148 * a procedure call (getcontext/swapcontext) or at the beginning
149 * of a procedure call (makecontext), so we don't need to restore
150 * msr and ctr. We don't restore r13 since it will be used as
151 * the TLS pointer. */
152 lwz r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
156 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
157 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
158 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
160 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
161 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
162 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
163 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
164 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
165 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
166 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
167 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
168 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
169 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
170 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
171 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
172 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
173 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
174 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
175 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
176 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
177 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
178 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
179 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
180 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
181 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
182 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
183 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
184 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
185 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
186 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
187 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
188 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
189 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
191 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
192 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
194 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
195 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
196 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
198 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
199 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
200 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
202 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
203 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
204 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
205 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
206 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
207 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
208 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
209 /* Don't reload the thread ID or TLS pointer (r13). */
210 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
211 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
212 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
213 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
214 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
215 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
216 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
217 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
218 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
219 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
220 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
221 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
222 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
223 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
224 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
225 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
226 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
228 /* Now we branch to the "Next Instruction Pointer" from the saved
229 context. With the powerpc64 instruction set there is no good way to
230 do this (from user state) without clobbering either the LR or CTR.
231 The makecontext and swapcontext functions depend on the callers
232 LR being preserved so we use the CTR. */
233 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
235 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
236 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
240 ld r0,128+FRAME_LR_SAVE(r1)
246 /* At this point we assume that the ucontext was created by a
247 rt_signal and we should use rt_sigreturn to restore the original
248 state. As of the 2.4.21 kernel the ucontext is the first thing
249 (offset 0) in the rt_signal frame and rt_sigreturn expects the
250 ucontext address in R1. Normally the rt-signal trampoline handles
251 this by popping dummy frame before the rt_signal syscall. In our
252 case the stack may not be in its original (signal handler return with
253 R1 pointing at the dummy frame) state. We do have the ucontext
254 address in R3, so simply copy R3 to R1 before the syscall. */
257 li r0,SYS_ify(rt_sigreturn)
261 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
263 std r0,FRAME_LR_SAVE(r1)
266 bl JUMPTARGET(__syscall_error)
269 ld r0,128+FRAME_LR_SAVE(r1)
275 PSEUDO_END(__novec_swapcontext)
277 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
284 .tc _rtld_global_ro[TC],_rtld_global_ro
286 .tc _dl_hwcap[TC],_dl_hwcap
291 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
292 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
293 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
296 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
297 std r0,FRAME_LR_SAVE(r1)
298 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
299 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
301 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
302 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
303 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
304 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
305 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
306 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
307 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
308 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
309 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
310 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
311 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
312 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
313 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
314 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
315 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
316 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
317 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
318 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
319 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
320 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
321 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
322 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
323 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
324 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
325 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
326 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
327 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
328 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
330 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
332 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
334 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
336 /* Set the return value of swapcontext to "success". R3 is the only
337 register whose value is not preserved in the saved context. */
339 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
341 /* Zero fill fields that can't be set in user state or are unused. */
342 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
343 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
344 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
345 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
346 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
347 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
348 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
350 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
351 field. Struct pt_regs and elf_gregset_t are the same thing.
352 We kept the regs field for backwards compatibility with
353 libraries built before we extended sigcontext. */
354 addi r0,r3,SIGCONTEXT_GP_REGS
355 std r0,SIGCONTEXT_PT_REGS(r3)
357 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
358 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
359 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
360 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
361 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
362 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
363 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
364 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
365 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
366 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
367 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
368 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
369 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
370 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
371 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
372 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
373 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
374 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
375 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
376 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
377 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
378 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
379 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
380 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
381 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
382 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
383 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
384 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
385 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
386 stfd fp29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
388 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
389 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
390 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
392 ld r8,.LC__dl_hwcap@toc(r2)
395 /* Load _rtld-global._dl_hwcap. */
396 ld r8,RTLD_GLOBAL_DL_HWCAP_OFFSET(r8)
398 ld r8,0(r8) /* Load extern _dl_hwcap. */
400 andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
403 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
404 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
500 Store either a NULL or a quadword aligned pointer to the Vector register
503 std r10,(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 lwz 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_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)
685 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
686 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
687 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
688 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)