2 Copyright (C) 2002, 2004, 2005, 2006, 2008, 2009
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
22 #include <rtld-global-offsets.h>
23 #include <shlib-compat.h>
24 #include <kernel-features.h>
27 #include <asm/ptrace.h>
28 #include "ucontext_i.h"
29 #include <asm/errno.h>
34 .tc _rtld_global_ro[TC],_rtld_global_ro
36 .tc _dl_hwcap[TC],_dl_hwcap
40 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
41 ENTRY(__novec_setcontext)
43 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
47 std r0,FRAME_LR_SAVE(r1)
48 cfi_offset (lr, FRAME_LR_SAVE)
50 cfi_adjust_cfa_offset (128)
54 * If this ucontext refers to the point where we were interrupted
55 * by a signal, we have to use the rt_sigreturn system call to
56 * return to the context so we get both LR and CTR restored.
58 * Otherwise, the context we are restoring is either just after
59 * a procedure call (getcontext/swapcontext) or at the beginning
60 * of a procedure call (makecontext), so we don't need to restore
61 * msr and ctr. We don't restore r13 since it will be used as
63 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
68 addi r4,r3,UCONTEXT_SIGMASK
70 bl JUMPTARGET(__sigprocmask)
76 /* Load _rtld-global._dl_hwcap. */
77 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
79 ld r5,0(r5) /* Load extern _dl_hwcap. */
82 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
83 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
84 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
87 /* Use the extended four-operand version of the mtfsf insn. */
92 /* Availability of DFP indicates a 64-bit FPSCR. */
93 andi. r6,r5,PPC_FEATURE_HAS_DFP
95 /* Use the extended four-operand version of the mtfsf insn. */
98 /* Continue to operate on the FPSCR as if it were 32-bits. */
103 # endif /* _ARCH_PWR6 */
104 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
105 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
106 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
107 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
108 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
109 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
110 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
111 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
112 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
113 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
114 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
115 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
116 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
117 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
118 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
119 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
120 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
121 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
122 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
123 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
124 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
125 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
126 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
127 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
128 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
129 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
130 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
131 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
132 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
133 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
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)
184 ld r0,128+FRAME_LR_SAVE(r1)
190 /* At this point we assume that the ucontext was created by a
191 rt_signal and we should use rt_sigreturn to restore the original
192 state. As of the 2.4.21 kernel the ucontext is the first thing
193 (offset 0) in the rt_signal frame and rt_sigreturn expects the
194 ucontext address in R1. Normally the rt-signal trampoline handles
195 this by popping dummy frame before the rt_signal syscall. In our
196 case the stack may not be in its original (signal handler return with
197 R1 pointing at the dummy frame) state. We do have the ucontext
198 address in R3, so simply copy R3 to R1 before the syscall. */
201 li r0,SYS_ify(rt_sigreturn)
205 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
207 std r0,FRAME_LR_SAVE(r1)
208 cfi_offset(lr,FRAME_LR_SAVE)
210 cfi_adjust_cfa_offset(128)
212 bl JUMPTARGET(__syscall_error)
215 ld r0,128+FRAME_LR_SAVE(r1)
221 PSEUDO_END(__novec_setcontext)
223 compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
231 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
235 std r0,FRAME_LR_SAVE(r1)
236 cfi_offset (lr, FRAME_LR_SAVE)
238 cfi_adjust_cfa_offset (128)
242 * If this ucontext refers to the point where we were interrupted
243 * by a signal, we have to use the rt_sigreturn system call to
244 * return to the context so we get both LR and CTR restored.
246 * Otherwise, the context we are restoring is either just after
247 * a procedure call (getcontext/swapcontext) or at the beginning
248 * of a procedure call (makecontext), so we don't need to restore
249 * msr and ctr. We don't restore r13 since it will be used as
250 * the TLS pointer. */
251 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
256 addi r4,r3,UCONTEXT_SIGMASK
258 bl JUMPTARGET(__sigprocmask)
263 ld r5,.LC__dl_hwcap@toc(r2)
264 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
266 /* Load _rtld-global._dl_hwcap. */
267 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
269 ld r5,0(r5) /* Load extern _dl_hwcap. */
271 andis. r6,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
373 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
374 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
375 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
378 /* Use the extended four-operand version of the mtfsf insn. */
383 /* Availability of DFP indicates a 64-bit FPSCR. */
384 andi. r6,r5,PPC_FEATURE_HAS_DFP
386 /* Use the extended four-operand version of the mtfsf insn. */
389 /* Continue to operate on the FPSCR as if it were 32-bits. */
394 # endif /* _ARCH_PWR6 */
395 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
396 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
397 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
398 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
399 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
400 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
401 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
402 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
403 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
404 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
405 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
406 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
407 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
408 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
409 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
410 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
411 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
412 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
413 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
414 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
415 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
416 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
417 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
418 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
419 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
420 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
421 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
422 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
423 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
424 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
426 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
427 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
429 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
430 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
431 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
433 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
434 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
435 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
436 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
437 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
438 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
439 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
441 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
442 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
443 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
444 /* Don't reload the thread ID or TLS pointer (r13). */
445 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
446 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
447 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
448 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
449 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
450 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
451 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
452 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
453 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
454 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
455 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
456 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
457 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
458 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
459 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
460 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
461 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
463 /* Now we branch to the "Next Instruction Pointer" from the saved
464 context. With the powerpc64 instruction set there is no good way to
465 do this (from user state) without clobbering either the LR or CTR.
466 The makecontext and swapcontext functions depend on the callers
467 LR being preserved so we use the CTR. */
468 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
470 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
471 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
475 ld r0,128+FRAME_LR_SAVE(r1)
481 /* At this point we assume that the ucontext was created by a
482 rt_signal and we should use rt_sigreturn to restore the original
483 state. As of the 2.4.21 kernel the ucontext is the first thing
484 (offset 0) in the rt_signal frame and rt_sigreturn expects the
485 ucontext address in R1. Normally the rt-signal trampoline handles
486 this by popping dummy frame before the rt_signal syscall. In our
487 case the stack may not be in its original (signal handler return with
488 R1 pointing at the dummy frame) state. We do have the ucontext
489 address in R3, so simply copy R3 to R1 before the syscall. */
492 li r0,SYS_ify(rt_sigreturn)
496 /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
498 std r0,FRAME_LR_SAVE(r1)
499 cfi_offset (lr, FRAME_LR_SAVE)
501 cfi_adjust_cfa_offset (128)
503 bl JUMPTARGET(__syscall_error)
506 ld r0,128+FRAME_LR_SAVE(r1)
512 PSEUDO_END(__setcontext)
514 versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)