]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / setcontext.S
1 /* Switch to context.
2 Copyright (C) 2002-2015 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, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <sysdep.h>
20 #include <rtld-global-offsets.h>
21 #include <shlib-compat.h>
22
23 #define __ASSEMBLY__
24 #include <asm/ptrace.h>
25 #include "ucontext_i.h"
26 #include <asm/errno.h>
27
28 .section ".toc","aw"
29 .LC__dl_hwcap:
30 #ifdef SHARED
31 .tc _rtld_global_ro[TC],_rtld_global_ro
32 #else
33 .tc _dl_hwcap[TC],_dl_hwcap
34 #endif
35 .section ".text"
36
37 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
38 ENTRY(__novec_setcontext)
39 CALL_MCOUNT 1
40 mflr r0
41 std r31,-8(1)
42 cfi_offset(r31,-8)
43 std r0,FRAME_LR_SAVE(r1)
44 cfi_offset (lr, FRAME_LR_SAVE)
45 stdu r1,-128(r1)
46 cfi_adjust_cfa_offset (128)
47 mr r31,r3
48
49 /*
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.
53 *
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
58 * the TLS pointer. */
59 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
60 cmpdi r0,0
61 bne L(nv_do_sigret)
62
63 li r5,0
64 addi r4,r3,UCONTEXT_SIGMASK
65 li r3,SIG_SETMASK
66 bl JUMPTARGET(__sigprocmask)
67 nop
68 cmpdi r3,0
69 bne L(nv_error_exit)
70
71 # ifdef SHARED
72 /* Load _rtld-global._dl_hwcap. */
73 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
74 # else
75 ld r5,0(r5) /* Load extern _dl_hwcap. */
76 # endif
77
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)
81
82 # ifdef _ARCH_PWR6
83 /* Use the extended four-operand version of the mtfsf insn. */
84 mtfsf 0xff,fp0,1,0
85 # else
86 .machine push
87 .machine "power6"
88 /* Availability of DFP indicates a 64-bit FPSCR. */
89 andi. r6,r5,PPC_FEATURE_HAS_DFP
90 beq 5f
91 /* Use the extended four-operand version of the mtfsf insn. */
92 mtfsf 0xff,fp0,1,0
93 b 6f
94 /* Continue to operate on the FPSCR as if it were 32-bits. */
95 5:
96 mtfsf 0xff,fp0
97 6:
98 .machine pop
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)
130
131 /* End FDE now, because the unwind info would be wrong while
132 we're reloading registers to switch to the new context. */
133 cfi_endproc
134
135 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
136 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
137 mtlr r0
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)
141 mtxer r0
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)
145 mtcr r0
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)
171
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)
178 mtctr r0
179 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
180 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
181 bctr
182
183 /* Re-establish FDE for the rest of the actual setcontext routine. */
184 cfi_startproc
185 cfi_offset (lr, FRAME_LR_SAVE)
186 cfi_adjust_cfa_offset (128)
187
188 L(nv_error_exit):
189 ld r0,128+FRAME_LR_SAVE(r1)
190 addi r1,r1,128
191 mtlr r0
192 ld r31,-8(r1)
193 blr
194
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. */
204 L(nv_do_sigret):
205 mr r1,r3,
206 li r0,SYS_ify(rt_sigreturn)
207 sc
208 /* No return. */
209
210 PSEUDO_END(__novec_setcontext)
211
212 compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
213
214 #endif
215
216 .section ".text"
217 .machine "altivec"
218 ENTRY(__setcontext)
219 CALL_MCOUNT 1
220 mflr r0
221 std r31,-8(1)
222 cfi_offset(r31,-8)
223 std r0,FRAME_LR_SAVE(r1)
224 cfi_offset (lr, FRAME_LR_SAVE)
225 stdu r1,-128(r1)
226 cfi_adjust_cfa_offset (128)
227 mr r31,r3
228
229 /*
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.
233 *
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)
240 cmpdi r0,0
241 bne L(do_sigret)
242
243 li r5,0
244 addi r4,r3,UCONTEXT_SIGMASK
245 li r3,SIG_SETMASK
246 bl JUMPTARGET(__sigprocmask)
247 nop
248 cmpdi r3,0
249 bne L(error_exit)
250
251 ld r5,.LC__dl_hwcap@toc(r2)
252 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
253 # ifdef SHARED
254 /* Load _rtld-global._dl_hwcap. */
255 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
256 # else
257 ld r5,0(r5) /* Load extern _dl_hwcap. */
258 # endif
259 andis. r6,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
260 beq L(has_no_vec)
261
262 cmpdi r10,0
263 beq L(has_no_vec)
264 lwz r0,(33*16)(r10)
265
266 li r9,(16*32)
267 mtspr VRSAVE,r0
268 cmpwi r0,0
269 beq L(has_no_vec)
270
271 lvx v19,r9,r10
272 la r9,(16)(r10)
273
274 lvx v0,0,r10
275 lvx v1,0,r9
276 addi r10,r10,32
277 addi r9,r9,32
278
279 mtvscr v19
280 lvx v2,0,r10
281 lvx v3,0,r9
282 addi r10,r10,32
283 addi r9,r9,32
284
285 lvx v4,0,r10
286 lvx v5,0,r9
287 addi r10,r10,32
288 addi r9,r9,32
289
290 lvx v6,0,r10
291 lvx v7,0,r9
292 addi r10,r10,32
293 addi r9,r9,32
294
295 lvx v8,0,r10
296 lvx v9,0,r9
297 addi r10,r10,32
298 addi r9,r9,32
299
300 lvx v10,0,r10
301 lvx v11,0,r9
302 addi r10,r10,32
303 addi r9,r9,32
304
305 lvx v12,0,r10
306 lvx v13,0,r9
307 addi r10,r10,32
308 addi r9,r9,32
309
310 lvx v14,0,r10
311 lvx v15,0,r9
312 addi r10,r10,32
313 addi r9,r9,32
314
315 lvx v16,0,r10
316 lvx v17,0,r9
317 addi r10,r10,32
318 addi r9,r9,32
319
320 lvx v18,0,r10
321 lvx v19,0,r9
322 addi r10,r10,32
323 addi r9,r9,32
324
325 lvx v20,0,r10
326 lvx v21,0,r9
327 addi r10,r10,32
328 addi r9,r9,32
329
330 lvx v22,0,r10
331 lvx v23,0,r9
332 addi r10,r10,32
333 addi r9,r9,32
334
335 lvx v24,0,r10
336 lvx v25,0,r9
337 addi r10,r10,32
338 addi r9,r9,32
339
340 lvx v26,0,r10
341 lvx v27,0,r9
342 addi r10,r10,32
343 addi r9,r9,32
344
345 lvx v28,0,r10
346 lvx v29,0,r9
347 addi r10,r10,32
348 addi r9,r9,32
349
350 lvx v30,0,r10
351 lvx v31,0,r9
352 addi r10,r10,32
353 addi r9,r9,32
354
355 lvx v10,0,r10
356 lvx v11,0,r9
357 addi r10,r10,32
358 addi r9,r9,32
359
360 L(has_no_vec):
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)
364
365 # ifdef _ARCH_PWR6
366 /* Use the extended four-operand version of the mtfsf insn. */
367 mtfsf 0xff,fp0,1,0
368 # else
369 .machine push
370 .machine "power6"
371 /* Availability of DFP indicates a 64-bit FPSCR. */
372 andi. r6,r5,PPC_FEATURE_HAS_DFP
373 beq 7f
374 /* Use the extended four-operand version of the mtfsf insn. */
375 mtfsf 0xff,fp0,1,0
376 b 8f
377 /* Continue to operate on the FPSCR as if it were 32-bits. */
378 7:
379 mtfsf 0xff,fp0
380 8:
381 .machine pop
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)
413
414 /* End FDE now, because the unwind info would be wrong while
415 we're reloading registers to switch to the new context. */
416 cfi_endproc
417
418 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
419 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
420 mtlr r0
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)
424 mtxer r0
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)
432 mtcr r0
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)
454
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)
461 mtctr r0
462 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
463 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
464 bctr
465
466 /* Re-establish FDE for the rest of the actual setcontext routine. */
467 cfi_startproc
468 cfi_offset (lr, FRAME_LR_SAVE)
469 cfi_adjust_cfa_offset (128)
470
471 L(error_exit):
472 ld r0,128+FRAME_LR_SAVE(r1)
473 addi r1,r1,128
474 mtlr r0
475 ld r31,-8(r1)
476 blr
477
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. */
487 L(do_sigret):
488 mr r1,r3,
489 li r0,SYS_ify(rt_sigreturn)
490 sc
491 /* No return. */
492
493 PSEUDO_END(__setcontext)
494
495 versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)