]>
Commit | Line | Data |
---|---|---|
aebcf54c UD |
1 | /* Jump to a new context. |
2 | Copyright (C) 2002 Free Software Foundation, Inc. | |
3 | This file is part of the GNU C Library. | |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
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 | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <sysdep.h> | |
21 | ||
22 | #define __ASSEMBLY__ | |
23 | #include <asm/ptrace.h> | |
24 | #include "ucontext_i.h" | |
25 | ||
26 | ENTRY(__setcontext) | |
27 | mflr r0 | |
28 | stwu r1,-16(r1) | |
29 | stw r0,20(r1) | |
30 | stw r31,12(r1) | |
31 | mr r31,r3 | |
32 | ||
33 | /* | |
34 | * If this ucontext refers to the point where we were interrupted | |
35 | * by a signal, we have to use the rt_sigreturn system call to | |
36 | * return to the context so we get both LR and CTR restored. | |
37 | * | |
38 | * Otherwise, the context we are restoring is either just after | |
39 | * a procedure call (getcontext/swapcontext) or at the beginning | |
40 | * of a procedure call (makecontext), so we don't need to restore | |
41 | * r0, xer, ctr. We don't restore r2 since it will be used as | |
42 | * the TLS pointer. | |
43 | */ | |
44 | lwz r0,_UC_GREGS+(PT_MSR*4)(r31) | |
45 | cmpwi r0,0 | |
46 | bne L(do_sigret) | |
47 | ||
48 | /* Restore the signal mask */ | |
49 | li r5,0 | |
50 | addi r4,r3,_UC_SIGMASK | |
51 | li r3,SIG_SETMASK | |
52 | bl JUMPTARGET(sigprocmask) | |
53 | cmpwi r3,0 | |
54 | bne L(error_exit) | |
55 | ||
56 | /* Restore the floating-point registers */ | |
57 | lfd fp31,_UC_FREGS+(32*8)(r31) | |
58 | lfd fp0,_UC_FREGS+(0*8)(r31) | |
59 | mtfsf 0xff,fp31 | |
60 | lfd fp1,_UC_FREGS+(1*8)(r31) | |
61 | lfd fp2,_UC_FREGS+(2*8)(r31) | |
62 | lfd fp3,_UC_FREGS+(3*8)(r31) | |
63 | lfd fp4,_UC_FREGS+(4*8)(r31) | |
64 | lfd fp5,_UC_FREGS+(5*8)(r31) | |
65 | lfd fp6,_UC_FREGS+(6*8)(r31) | |
66 | lfd fp7,_UC_FREGS+(7*8)(r31) | |
67 | lfd fp8,_UC_FREGS+(8*8)(r31) | |
68 | lfd fp9,_UC_FREGS+(9*8)(r31) | |
69 | lfd fp10,_UC_FREGS+(10*8)(r31) | |
70 | lfd fp11,_UC_FREGS+(11*8)(r31) | |
71 | lfd fp12,_UC_FREGS+(12*8)(r31) | |
72 | lfd fp13,_UC_FREGS+(13*8)(r31) | |
73 | lfd fp14,_UC_FREGS+(14*8)(r31) | |
74 | lfd fp15,_UC_FREGS+(15*8)(r31) | |
75 | lfd fp16,_UC_FREGS+(16*8)(r31) | |
76 | lfd fp17,_UC_FREGS+(17*8)(r31) | |
77 | lfd fp18,_UC_FREGS+(18*8)(r31) | |
78 | lfd fp19,_UC_FREGS+(19*8)(r31) | |
79 | lfd fp20,_UC_FREGS+(20*8)(r31) | |
80 | lfd fp21,_UC_FREGS+(21*8)(r31) | |
81 | lfd fp22,_UC_FREGS+(22*8)(r31) | |
82 | lfd fp23,_UC_FREGS+(23*8)(r31) | |
83 | lfd fp24,_UC_FREGS+(24*8)(r31) | |
84 | lfd fp25,_UC_FREGS+(25*8)(r31) | |
85 | lfd fp26,_UC_FREGS+(26*8)(r31) | |
86 | lfd fp27,_UC_FREGS+(27*8)(r31) | |
87 | lfd fp28,_UC_FREGS+(28*8)(r31) | |
88 | lfd fp29,_UC_FREGS+(29*8)(r31) | |
89 | lfd fp30,_UC_FREGS+(30*8)(r31) | |
90 | lfd fp31,_UC_FREGS+(31*8)(r31) | |
91 | ||
92 | /* Restore LR and CCR, and set CTR to the NIP value */ | |
93 | lwz r3,_UC_GREGS+(PT_LNK*4)(r31) | |
94 | lwz r4,_UC_GREGS+(PT_NIP*4)(r31) | |
95 | lwz r5,_UC_GREGS+(PT_CCR*4)(r31) | |
96 | mtlr r3 | |
97 | mtctr r4 | |
98 | mtcr r5 | |
99 | ||
100 | /* Restore the general registers */ | |
101 | lwz r1,_UC_GREGS+(PT_R1*4)(r31) | |
102 | lwz r3,_UC_GREGS+(PT_R3*4)(r31) | |
103 | lwz r4,_UC_GREGS+(PT_R4*4)(r31) | |
104 | lwz r5,_UC_GREGS+(PT_R5*4)(r31) | |
105 | lwz r6,_UC_GREGS+(PT_R6*4)(r31) | |
106 | lwz r7,_UC_GREGS+(PT_R7*4)(r31) | |
107 | lwz r8,_UC_GREGS+(PT_R8*4)(r31) | |
108 | lwz r9,_UC_GREGS+(PT_R9*4)(r31) | |
109 | lwz r10,_UC_GREGS+(PT_R10*4)(r31) | |
110 | lwz r11,_UC_GREGS+(PT_R11*4)(r31) | |
111 | lwz r12,_UC_GREGS+(PT_R12*4)(r31) | |
112 | lwz r13,_UC_GREGS+(PT_R13*4)(r31) | |
113 | lwz r14,_UC_GREGS+(PT_R14*4)(r31) | |
114 | lwz r15,_UC_GREGS+(PT_R15*4)(r31) | |
115 | lwz r16,_UC_GREGS+(PT_R16*4)(r31) | |
116 | lwz r17,_UC_GREGS+(PT_R17*4)(r31) | |
117 | lwz r18,_UC_GREGS+(PT_R18*4)(r31) | |
118 | lwz r19,_UC_GREGS+(PT_R19*4)(r31) | |
119 | lwz r20,_UC_GREGS+(PT_R20*4)(r31) | |
120 | lwz r21,_UC_GREGS+(PT_R21*4)(r31) | |
121 | lwz r22,_UC_GREGS+(PT_R22*4)(r31) | |
122 | lwz r23,_UC_GREGS+(PT_R23*4)(r31) | |
123 | lwz r24,_UC_GREGS+(PT_R24*4)(r31) | |
124 | lwz r25,_UC_GREGS+(PT_R25*4)(r31) | |
125 | lwz r26,_UC_GREGS+(PT_R26*4)(r31) | |
126 | lwz r27,_UC_GREGS+(PT_R27*4)(r31) | |
127 | lwz r28,_UC_GREGS+(PT_R28*4)(r31) | |
128 | lwz r29,_UC_GREGS+(PT_R29*4)(r31) | |
129 | lwz r30,_UC_GREGS+(PT_R30*4)(r31) | |
130 | lwz r31,_UC_GREGS+(PT_R31*4)(r31) | |
131 | ||
132 | bctr | |
133 | ||
134 | L(error_exit): | |
135 | lwz r31,12(r1) | |
136 | lwz r0,20(r1) | |
137 | addi r1,r1,16 | |
138 | mtlr r0 | |
139 | blr | |
140 | ||
141 | L(do_sigret): | |
142 | addi r1,r3,-0xd0 | |
143 | li r0,SYS_ify(rt_sigreturn) | |
144 | sc | |
145 | /* NOTREACHED */ | |
146 | ||
147 | PSEUDO_END(__setcontext) | |
148 | ||
149 | weak_alias(__setcontext, setcontext) |