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)
39 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
40 std r0,FRAME_LR_SAVE(r1)
41 cfi_offset (lr, FRAME_LR_SAVE)
42 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
43 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
45 cfi_adjust_cfa_offset (128)
46 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
47 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
48 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
49 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
50 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
51 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
52 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
53 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
54 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
55 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
56 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
57 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
58 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
59 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
60 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
61 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
62 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
63 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
64 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
65 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
66 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
67 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
68 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
69 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
70 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
71 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
72 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
73 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
75 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
77 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
79 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
81 /* Set the return value of swapcontext to "success". R3 is the only
82 register whose value is not preserved in the saved context. */
84 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
86 /* Zero fill fields that can't be set in user state or are unused. */
87 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
88 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
89 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
90 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
91 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
92 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
93 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
95 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
96 field. Struct pt_regs and elf_gregset_t are the same thing.
97 We kept the regs field for backwards compatibility with
98 libraries built before we extended sigcontext. */
99 addi r0,r3,SIGCONTEXT_GP_REGS
100 std r0,SIGCONTEXT_PT_REGS(r3)
102 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
103 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
104 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
105 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
106 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
107 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
108 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
109 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
110 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
111 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
112 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
113 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
114 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
115 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
116 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
117 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
118 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
119 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
120 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
121 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
122 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
123 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
124 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
125 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
126 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
127 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
128 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
129 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
130 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
131 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
133 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
134 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
135 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
138 addi r5,r3,UCONTEXT_SIGMASK
139 addi r4,r4,UCONTEXT_SIGMASK
141 bl JUMPTARGET(__sigprocmask)
147 * If this new ucontext refers to the point where we were interrupted
148 * by a signal, we have to use the rt_sigreturn system call to
149 * return to the context so we get both LR and CTR restored.
151 * Otherwise, the context we are restoring is either just after
152 * a procedure call (getcontext/swapcontext) or at the beginning
153 * of a procedure call (makecontext), so we don't need to restore
154 * msr and ctr. We don't restore r13 since it will be used as
155 * the TLS pointer. */
156 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
160 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
161 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
162 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
164 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
165 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
166 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
167 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
168 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
169 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
170 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
171 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
172 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
173 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
174 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
175 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
176 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
177 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
178 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
179 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
180 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
181 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
182 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
183 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
184 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
185 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
186 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
187 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
188 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
189 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
190 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
191 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
192 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
193 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
195 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
196 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
198 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
199 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
200 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
202 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
203 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
204 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
206 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
207 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
208 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
209 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
210 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
211 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
212 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
213 /* Don't reload the thread ID or TLS pointer (r13). */
214 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
215 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
216 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
217 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
218 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
219 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
220 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
221 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
222 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
223 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
224 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
225 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
226 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
227 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
228 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
229 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
230 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
232 /* Now we branch to the "Next Instruction Pointer" from the saved
233 context. With the powerpc64 instruction set there is no good way to
234 do this (from user state) without clobbering either the LR or CTR.
235 The makecontext and swapcontext functions depend on the callers
236 LR being preserved so we use the CTR. */
237 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
239 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
240 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
244 ld r0,128+FRAME_LR_SAVE(r1)
250 /* At this point we assume that the ucontext was created by a
251 rt_signal and we should use rt_sigreturn to restore the original
252 state. As of the 2.4.21 kernel the ucontext is the first thing
253 (offset 0) in the rt_signal frame and rt_sigreturn expects the
254 ucontext address in R1. Normally the rt-signal trampoline handles
255 this by popping dummy frame before the rt_signal syscall. In our
256 case the stack may not be in its original (signal handler return with
257 R1 pointing at the dummy frame) state. We do have the ucontext
258 address in R3, so simply copy R3 to R1 before the syscall. */
261 li r0,SYS_ify(rt_sigreturn)
265 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
267 std r0,FRAME_LR_SAVE(r1)
268 cfi_offset(lr,FRAME_LR_SAVE)
271 bl JUMPTARGET(__syscall_error)
274 ld r0,128+FRAME_LR_SAVE(r1)
280 PSEUDO_END(__novec_swapcontext)
282 compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
289 .tc _rtld_global_ro[TC],_rtld_global_ro
291 .tc _dl_hwcap[TC],_dl_hwcap
298 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
299 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
300 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
304 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
305 std r0,FRAME_LR_SAVE(r1)
306 cfi_offset (lr, FRAME_LR_SAVE)
307 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
308 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
310 cfi_adjust_cfa_offset(128)
311 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
312 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
313 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
314 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
315 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
316 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
317 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
318 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
319 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
320 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
321 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
322 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
323 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
324 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
325 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
326 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
327 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
328 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
329 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
330 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
331 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
332 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
333 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
334 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
335 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
336 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
337 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
338 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
340 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
342 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
344 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
346 /* Set the return value of swapcontext to "success". R3 is the only
347 register whose value is not preserved in the saved context. */
349 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
351 /* Zero fill fields that can't be set in user state or are unused. */
352 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
353 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
354 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
355 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
356 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
357 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
358 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
360 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
361 field. Struct pt_regs and elf_gregset_t are the same thing.
362 We kept the regs field for backwards compatibility with
363 libraries built before we extended sigcontext. */
364 addi r0,r3,SIGCONTEXT_GP_REGS
365 std r0,SIGCONTEXT_PT_REGS(r3)
367 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
368 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
369 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
370 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
371 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
372 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
373 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
374 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
375 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
376 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
377 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
378 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
379 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
380 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
381 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
382 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
383 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
384 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
385 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
386 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
387 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
388 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
389 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
390 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
391 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
392 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
393 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
394 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
395 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
396 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
398 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
399 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
400 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
402 ld r8,.LC__dl_hwcap@toc(r2)
404 /* Load _rtld-global._dl_hwcap. */
405 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
407 ld r8,0(r8) /* Load extern _dl_hwcap. */
409 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
410 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
412 andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
418 mr r8,r10 /* Capture *v_regs value in r5. */
507 Store either a NULL or a quadword aligned pointer to the Vector register
510 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
513 addi r5,r3,UCONTEXT_SIGMASK
514 addi r4,r4,UCONTEXT_SIGMASK
516 bl JUMPTARGET(__sigprocmask)
522 * If this new ucontext refers to the point where we were interrupted
523 * by a signal, we have to use the rt_sigreturn system call to
524 * return to the context so we get both LR and CTR restored.
526 * Otherwise, the context we are restoring is either just after
527 * a procedure call (getcontext/swapcontext) or at the beginning
528 * of a procedure call (makecontext), so we don't need to restore
529 * msr and ctr. We don't restore r13 since it will be used as
530 * the TLS pointer. */
531 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
535 ld r8,.LC__dl_hwcap@toc(r2)
536 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
538 /* Load _rtld-global._dl_hwcap. */
539 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
541 ld r8,0(r8) /* Load extern _dl_hwcap. */
543 andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
646 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
647 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
648 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
650 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
651 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
652 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
653 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
654 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
655 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
656 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
657 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
658 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
659 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
660 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
661 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
662 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
663 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
664 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
665 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
666 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
667 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
668 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
669 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
670 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
671 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
672 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
673 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
674 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
675 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
676 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
677 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
678 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
679 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
681 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
682 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
684 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
685 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
686 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
688 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
689 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
690 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
691 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
692 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
693 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
694 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
696 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
697 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
698 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
699 /* Don't reload the thread ID or TLS pointer (r13). */
700 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
701 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
702 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
703 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
704 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
705 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
706 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
707 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
708 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
709 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
710 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
711 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
712 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
713 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
714 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
715 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
716 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
718 /* Now we branch to the "Next Instruction Pointer" from the saved
719 context. With the powerpc64 instruction set there is no good way to
720 do this (from user state) without clobbering either the LR or CTR.
721 The makecontext and swapcontext functions depend on the callers
722 LR being preserved so we use the CTR. */
723 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
725 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
726 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
730 ld r0,128+FRAME_LR_SAVE(r1)
736 /* At this point we assume that the ucontext was created by a
737 rt_signal and we should use rt_sigreturn to restore the original
738 state. As of the 2.4.21 kernel the ucontext is the first thing
739 (offset 0) in the rt_signal frame and rt_sigreturn expects the
740 ucontext address in R1. Normally the rt-signal trampoline handles
741 this by popping dummy frame before the rt_signal syscall. In our
742 case the stack may not be in its original (signal handler return with
743 R1 pointing at the dummy frame) state. We do have the ucontext
744 address in R3, so simply copy R3 to R1 before the syscall. */
747 li r0,SYS_ify(rt_sigreturn)
751 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
753 std r0,FRAME_LR_SAVE(r1)
754 cfi_offset (lr, FRAME_LR_SAVE)
756 cfi_adjust_cfa_offset (128)
758 bl JUMPTARGET(__syscall_error)
761 ld r0,128+FRAME_LR_SAVE(r1)
767 PSEUDO_END(__swapcontext)
769 versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)