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