2 Copyright (C) 2002-2015 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>
24 #include <asm/ptrace.h>
25 #include "ucontext_i.h"
26 #include <asm/errno.h>
31 .tc _rtld_global_ro[TC],_rtld_global_ro
33 .tc _dl_hwcap[TC],_dl_hwcap
37 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
38 ENTRY(__novec_setcontext)
43 std r0,FRAME_LR_SAVE(r1)
44 cfi_offset (lr, FRAME_LR_SAVE)
46 cfi_adjust_cfa_offset (128)
50 * If this ucontext refers to the point where we were interrupted
51 * by a signal, we have to use the rt_sigreturn system call to
52 * return to the context so we get both LR and CTR restored.
54 * Otherwise, the context we are restoring is either just after
55 * a procedure call (getcontext/swapcontext) or at the beginning
56 * of a procedure call (makecontext), so we don't need to restore
57 * msr and ctr. We don't restore r13 since it will be used as
59 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
64 addi r4,r3,UCONTEXT_SIGMASK
66 bl JUMPTARGET(__sigprocmask)
72 /* Load _rtld-global._dl_hwcap. */
73 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
75 ld r5,0(r5) /* Load extern _dl_hwcap. */
78 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
79 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
80 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
83 /* Use the extended four-operand version of the mtfsf insn. */
88 /* Availability of DFP indicates a 64-bit FPSCR. */
89 andi. r6,r5,PPC_FEATURE_HAS_DFP
91 /* Use the extended four-operand version of the mtfsf insn. */
94 /* Continue to operate on the FPSCR as if it were 32-bits. */
99 # endif /* _ARCH_PWR6 */
100 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
101 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
102 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
103 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
104 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
105 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
106 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
107 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
108 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
109 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
110 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
111 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
112 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
113 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
114 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
115 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
116 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
117 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
118 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
119 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
120 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
121 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
122 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
123 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
124 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
125 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
126 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
127 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
128 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
129 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
131 /* End FDE now, because the unwind info would be wrong while
132 we're reloading registers to switch to the new context. */
135 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
136 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
138 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
139 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
140 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
142 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
143 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
144 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
146 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
147 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
148 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
149 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
150 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
151 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
152 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
153 /* Don't reload the thread ID or TLS pointer (r13). */
154 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
155 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
156 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
157 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
158 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
159 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
160 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
161 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
162 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
163 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
164 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
165 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
166 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
167 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
168 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
169 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
170 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
172 /* Now we branch to the "Next Instruction Pointer" from the saved
173 context. With the powerpc64 instruction set there is no good way to
174 do this (from user state) without clobbering either the LR or CTR.
175 The makecontext and swapcontext functions depend on the callers
176 LR being preserved so we use the CTR. */
177 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
179 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
180 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
183 /* Re-establish FDE for the rest of the actual setcontext routine. */
185 cfi_offset (lr, FRAME_LR_SAVE)
186 cfi_adjust_cfa_offset (128)
189 ld r0,128+FRAME_LR_SAVE(r1)
195 /* At this point we assume that the ucontext was created by a
196 rt_signal and we should use rt_sigreturn to restore the original
197 state. As of the 2.4.21 kernel the ucontext is the first thing
198 (offset 0) in the rt_signal frame and rt_sigreturn expects the
199 ucontext address in R1. Normally the rt-signal trampoline handles
200 this by popping dummy frame before the rt_signal syscall. In our
201 case the stack may not be in its original (signal handler return with
202 R1 pointing at the dummy frame) state. We do have the ucontext
203 address in R3, so simply copy R3 to R1 before the syscall. */
206 li r0,SYS_ify(rt_sigreturn)
210 PSEUDO_END(__novec_setcontext)
212 compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
223 std r0,FRAME_LR_SAVE(r1)
224 cfi_offset (lr, FRAME_LR_SAVE)
226 cfi_adjust_cfa_offset (128)
230 * If this ucontext refers to the point where we were interrupted
231 * by a signal, we have to use the rt_sigreturn system call to
232 * return to the context so we get both LR and CTR restored.
234 * Otherwise, the context we are restoring is either just after
235 * a procedure call (getcontext/swapcontext) or at the beginning
236 * of a procedure call (makecontext), so we don't need to restore
237 * msr and ctr. We don't restore r13 since it will be used as
238 * the TLS pointer. */
239 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
244 addi r4,r3,UCONTEXT_SIGMASK
246 bl JUMPTARGET(__sigprocmask)
251 ld r5,.LC__dl_hwcap@toc(r2)
252 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
254 /* Load _rtld-global._dl_hwcap. */
255 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
257 ld r5,0(r5) /* Load extern _dl_hwcap. */
259 andis. r6,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
361 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
362 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
363 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
366 /* Use the extended four-operand version of the mtfsf insn. */
371 /* Availability of DFP indicates a 64-bit FPSCR. */
372 andi. r6,r5,PPC_FEATURE_HAS_DFP
374 /* Use the extended four-operand version of the mtfsf insn. */
377 /* Continue to operate on the FPSCR as if it were 32-bits. */
382 # endif /* _ARCH_PWR6 */
383 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
384 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
385 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
386 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
387 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
388 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
389 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
390 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
391 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
392 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
393 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
394 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
395 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
396 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
397 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
398 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
399 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
400 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
401 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
402 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
403 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
404 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
405 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
406 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
407 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
408 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
409 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
410 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
411 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
412 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
414 /* End FDE now, because the unwind info would be wrong while
415 we're reloading registers to switch to the new context. */
418 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
419 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
421 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
422 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
423 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
425 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
426 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
427 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
428 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
429 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
430 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
431 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
433 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
434 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
435 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
436 /* Don't reload the thread ID or TLS pointer (r13). */
437 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
438 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
439 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
440 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
441 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
442 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
443 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
444 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
445 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
446 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
447 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
448 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
449 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
450 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
451 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
452 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
453 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
455 /* Now we branch to the "Next Instruction Pointer" from the saved
456 context. With the powerpc64 instruction set there is no good way to
457 do this (from user state) without clobbering either the LR or CTR.
458 The makecontext and swapcontext functions depend on the callers
459 LR being preserved so we use the CTR. */
460 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
462 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
463 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
466 /* Re-establish FDE for the rest of the actual setcontext routine. */
468 cfi_offset (lr, FRAME_LR_SAVE)
469 cfi_adjust_cfa_offset (128)
472 ld r0,128+FRAME_LR_SAVE(r1)
478 /* At this point we assume that the ucontext was created by a
479 rt_signal and we should use rt_sigreturn to restore the original
480 state. As of the 2.4.21 kernel the ucontext is the first thing
481 (offset 0) in the rt_signal frame and rt_sigreturn expects the
482 ucontext address in R1. Normally the rt-signal trampoline handles
483 this by popping dummy frame before the rt_signal syscall. In our
484 case the stack may not be in its original (signal handler return with
485 R1 pointing at the dummy frame) state. We do have the ucontext
486 address in R3, so simply copy R3 to R1 before the syscall. */
489 li r0,SYS_ify(rt_sigreturn)
493 PSEUDO_END(__setcontext)
495 versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)