]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / setcontext.S
1 /* Switch to context.
2 Copyright (C) 2002-2014 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 #include <kernel-features.h>
23
24 #define __ASSEMBLY__
25 #include <asm/ptrace.h>
26 #include "ucontext_i.h"
27 #include <asm/errno.h>
28
29 .section ".toc","aw"
30 .LC__dl_hwcap:
31 #ifdef SHARED
32 .tc _rtld_global_ro[TC],_rtld_global_ro
33 #else
34 .tc _dl_hwcap[TC],_dl_hwcap
35 #endif
36 .section ".text"
37
38 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
39 ENTRY(__novec_setcontext)
40 CALL_MCOUNT 1
41 mflr r0
42 std r31,-8(1)
43 cfi_offset(r31,-8)
44 std r0,FRAME_LR_SAVE(r1)
45 cfi_offset (lr, FRAME_LR_SAVE)
46 stdu r1,-128(r1)
47 cfi_adjust_cfa_offset (128)
48 mr r31,r3
49
50 /*
51 * If this ucontext refers to the point where we were interrupted
52 * by a signal, we have to use the rt_sigreturn system call to
53 * return to the context so we get both LR and CTR restored.
54 *
55 * Otherwise, the context we are restoring is either just after
56 * a procedure call (getcontext/swapcontext) or at the beginning
57 * of a procedure call (makecontext), so we don't need to restore
58 * msr and ctr. We don't restore r13 since it will be used as
59 * the TLS pointer. */
60 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
61 cmpdi r0,0
62 bne L(nv_do_sigret)
63
64 li r5,0
65 addi r4,r3,UCONTEXT_SIGMASK
66 li r3,SIG_SETMASK
67 bl JUMPTARGET(__sigprocmask)
68 nop
69 cmpdi r3,0
70 bne L(nv_error_exit)
71
72 # ifdef SHARED
73 /* Load _rtld-global._dl_hwcap. */
74 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
75 # else
76 ld r5,0(r5) /* Load extern _dl_hwcap. */
77 # endif
78
79 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
80 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
81 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
82
83 # ifdef _ARCH_PWR6
84 /* Use the extended four-operand version of the mtfsf insn. */
85 mtfsf 0xff,fp0,1,0
86 # else
87 .machine push
88 .machine "power6"
89 /* Availability of DFP indicates a 64-bit FPSCR. */
90 andi. r6,r5,PPC_FEATURE_HAS_DFP
91 beq 5f
92 /* Use the extended four-operand version of the mtfsf insn. */
93 mtfsf 0xff,fp0,1,0
94 b 6f
95 /* Continue to operate on the FPSCR as if it were 32-bits. */
96 5:
97 mtfsf 0xff,fp0
98 6:
99 .machine pop
100 # endif /* _ARCH_PWR6 */
101 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
102 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
103 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
104 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
105 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
106 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
107 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
108 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
109 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
110 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
111 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
112 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
113 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
114 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
115 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
116 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
117 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
118 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
119 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
120 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
121 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
122 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
123 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
124 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
125 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
126 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
127 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
128 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
129 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
130 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
131
132 /* End FDE now, because the unwind info would be wrong while
133 we're reloading registers to switch to the new context. */
134 cfi_endproc
135
136 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
137 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
138 mtlr r0
139 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
140 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
141 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
142 mtxer r0
143 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
144 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
145 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
146 mtcr r0
147 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
148 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
149 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
150 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
151 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
152 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
153 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
154 /* Don't reload the thread ID or TLS pointer (r13). */
155 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
156 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
157 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
158 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
159 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
160 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
161 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
162 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
163 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
164 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
165 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
166 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
167 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
168 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
169 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
170 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
171 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
172
173 /* Now we branch to the "Next Instruction Pointer" from the saved
174 context. With the powerpc64 instruction set there is no good way to
175 do this (from user state) without clobbering either the LR or CTR.
176 The makecontext and swapcontext functions depend on the callers
177 LR being preserved so we use the CTR. */
178 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
179 mtctr r0
180 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
181 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
182 bctr
183
184 /* Re-establish FDE for the rest of the actual setcontext routine. */
185 cfi_startproc
186 cfi_offset (lr, FRAME_LR_SAVE)
187 cfi_adjust_cfa_offset (128)
188
189 L(nv_error_exit):
190 ld r0,128+FRAME_LR_SAVE(r1)
191 addi r1,r1,128
192 mtlr r0
193 ld r31,-8(r1)
194 blr
195
196 /* At this point we assume that the ucontext was created by a
197 rt_signal and we should use rt_sigreturn to restore the original
198 state. As of the 2.4.21 kernel the ucontext is the first thing
199 (offset 0) in the rt_signal frame and rt_sigreturn expects the
200 ucontext address in R1. Normally the rt-signal trampoline handles
201 this by popping dummy frame before the rt_signal syscall. In our
202 case the stack may not be in its original (signal handler return with
203 R1 pointing at the dummy frame) state. We do have the ucontext
204 address in R3, so simply copy R3 to R1 before the syscall. */
205 L(nv_do_sigret):
206 mr r1,r3,
207 li r0,SYS_ify(rt_sigreturn)
208 sc
209 /* No return. */
210
211 PSEUDO_END(__novec_setcontext)
212
213 compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
214
215 #endif
216
217 .section ".text"
218 .machine "altivec"
219 ENTRY(__setcontext)
220 CALL_MCOUNT 1
221 mflr r0
222 std r31,-8(1)
223 cfi_offset(r31,-8)
224 std r0,FRAME_LR_SAVE(r1)
225 cfi_offset (lr, FRAME_LR_SAVE)
226 stdu r1,-128(r1)
227 cfi_adjust_cfa_offset (128)
228 mr r31,r3
229
230 /*
231 * If this ucontext refers to the point where we were interrupted
232 * by a signal, we have to use the rt_sigreturn system call to
233 * return to the context so we get both LR and CTR restored.
234 *
235 * Otherwise, the context we are restoring is either just after
236 * a procedure call (getcontext/swapcontext) or at the beginning
237 * of a procedure call (makecontext), so we don't need to restore
238 * msr and ctr. We don't restore r13 since it will be used as
239 * the TLS pointer. */
240 ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
241 cmpdi r0,0
242 bne L(do_sigret)
243
244 li r5,0
245 addi r4,r3,UCONTEXT_SIGMASK
246 li r3,SIG_SETMASK
247 bl JUMPTARGET(__sigprocmask)
248 nop
249 cmpdi r3,0
250 bne L(error_exit)
251
252 ld r5,.LC__dl_hwcap@toc(r2)
253 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
254 # ifdef SHARED
255 /* Load _rtld-global._dl_hwcap. */
256 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
257 # else
258 ld r5,0(r5) /* Load extern _dl_hwcap. */
259 # endif
260 andis. r6,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
261 beq L(has_no_vec)
262
263 cmpdi r10,0
264 beq L(has_no_vec)
265 lwz r0,(33*16)(r10)
266
267 li r9,(16*32)
268 mtspr VRSAVE,r0
269 cmpwi r0,0
270 beq L(has_no_vec)
271
272 lvx v19,r9,r10
273 la r9,(16)(r10)
274
275 lvx v0,0,r10
276 lvx v1,0,r9
277 addi r10,r10,32
278 addi r9,r9,32
279
280 mtvscr v19
281 lvx v2,0,r10
282 lvx v3,0,r9
283 addi r10,r10,32
284 addi r9,r9,32
285
286 lvx v4,0,r10
287 lvx v5,0,r9
288 addi r10,r10,32
289 addi r9,r9,32
290
291 lvx v6,0,r10
292 lvx v7,0,r9
293 addi r10,r10,32
294 addi r9,r9,32
295
296 lvx v8,0,r10
297 lvx v9,0,r9
298 addi r10,r10,32
299 addi r9,r9,32
300
301 lvx v10,0,r10
302 lvx v11,0,r9
303 addi r10,r10,32
304 addi r9,r9,32
305
306 lvx v12,0,r10
307 lvx v13,0,r9
308 addi r10,r10,32
309 addi r9,r9,32
310
311 lvx v14,0,r10
312 lvx v15,0,r9
313 addi r10,r10,32
314 addi r9,r9,32
315
316 lvx v16,0,r10
317 lvx v17,0,r9
318 addi r10,r10,32
319 addi r9,r9,32
320
321 lvx v18,0,r10
322 lvx v19,0,r9
323 addi r10,r10,32
324 addi r9,r9,32
325
326 lvx v20,0,r10
327 lvx v21,0,r9
328 addi r10,r10,32
329 addi r9,r9,32
330
331 lvx v22,0,r10
332 lvx v23,0,r9
333 addi r10,r10,32
334 addi r9,r9,32
335
336 lvx v24,0,r10
337 lvx v25,0,r9
338 addi r10,r10,32
339 addi r9,r9,32
340
341 lvx v26,0,r10
342 lvx v27,0,r9
343 addi r10,r10,32
344 addi r9,r9,32
345
346 lvx v28,0,r10
347 lvx v29,0,r9
348 addi r10,r10,32
349 addi r9,r9,32
350
351 lvx v30,0,r10
352 lvx v31,0,r9
353 addi r10,r10,32
354 addi r9,r9,32
355
356 lvx v10,0,r10
357 lvx v11,0,r9
358 addi r10,r10,32
359 addi r9,r9,32
360
361 L(has_no_vec):
362 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
363 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
364 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
365
366 # ifdef _ARCH_PWR6
367 /* Use the extended four-operand version of the mtfsf insn. */
368 mtfsf 0xff,fp0,1,0
369 # else
370 .machine push
371 .machine "power6"
372 /* Availability of DFP indicates a 64-bit FPSCR. */
373 andi. r6,r5,PPC_FEATURE_HAS_DFP
374 beq 7f
375 /* Use the extended four-operand version of the mtfsf insn. */
376 mtfsf 0xff,fp0,1,0
377 b 8f
378 /* Continue to operate on the FPSCR as if it were 32-bits. */
379 7:
380 mtfsf 0xff,fp0
381 8:
382 .machine pop
383 # endif /* _ARCH_PWR6 */
384 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
385 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
386 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
387 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
388 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
389 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
390 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
391 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
392 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
393 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
394 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
395 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
396 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
397 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
398 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
399 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
400 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
401 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
402 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
403 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
404 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
405 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
406 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
407 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
408 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
409 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
410 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
411 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
412 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
413 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
414
415 /* End FDE now, because the unwind info would be wrong while
416 we're reloading registers to switch to the new context. */
417 cfi_endproc
418
419 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
420 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
421 mtlr r0
422 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
423 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
424 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
425 mtxer r0
426 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
427 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
428 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
429 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
430 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
431 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
432 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
433 mtcr r0
434 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
435 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
436 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
437 /* Don't reload the thread ID or TLS pointer (r13). */
438 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
439 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
440 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
441 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
442 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
443 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
444 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
445 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
446 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
447 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
448 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
449 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
450 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
451 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
452 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
453 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
454 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
455
456 /* Now we branch to the "Next Instruction Pointer" from the saved
457 context. With the powerpc64 instruction set there is no good way to
458 do this (from user state) without clobbering either the LR or CTR.
459 The makecontext and swapcontext functions depend on the callers
460 LR being preserved so we use the CTR. */
461 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
462 mtctr r0
463 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
464 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
465 bctr
466
467 /* Re-establish FDE for the rest of the actual setcontext routine. */
468 cfi_startproc
469 cfi_offset (lr, FRAME_LR_SAVE)
470 cfi_adjust_cfa_offset (128)
471
472 L(error_exit):
473 ld r0,128+FRAME_LR_SAVE(r1)
474 addi r1,r1,128
475 mtlr r0
476 ld r31,-8(r1)
477 blr
478
479 /* At this point we assume that the ucontext was created by a
480 rt_signal and we should use rt_sigreturn to restore the original
481 state. As of the 2.4.21 kernel the ucontext is the first thing
482 (offset 0) in the rt_signal frame and rt_sigreturn expects the
483 ucontext address in R1. Normally the rt-signal trampoline handles
484 this by popping dummy frame before the rt_signal syscall. In our
485 case the stack may not be in its original (signal handler return with
486 R1 pointing at the dummy frame) state. We do have the ucontext
487 address in R3, so simply copy R3 to R1 before the syscall. */
488 L(do_sigret):
489 mr r1,r3,
490 li r0,SYS_ify(rt_sigreturn)
491 sc
492 /* No return. */
493
494 PSEUDO_END(__setcontext)
495
496 versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)