1 /* Save current context.
2 Copyright (C) 2002, 2004 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #include <rtld-global-offsets.h>
22 #include <shlib-compat.h>
25 #include <asm/ptrace.h>
26 #include "ucontext_i.h"
29 stw r3,_FRAME_PARM_SAVE1(r1)
30 addi r3,r3,_UC_REG_SPACE+12
32 stw r0,_UC_GREGS+(PT_R0*4)(r3)
34 stw r1,_UC_GREGS+(PT_R1*4)(r3)
36 stw r0,_UC_GREGS+(PT_LNK*4)(r3)
37 stw r0,_UC_GREGS+(PT_NIP*4)(r3)
38 stw r0,_FRAME_LR_SAVE+16(r1)
39 stw r2,_UC_GREGS+(PT_R2*4)(r3)
40 stw r4,_UC_GREGS+(PT_R4*4)(r3)
41 stw r5,_UC_GREGS+(PT_R5*4)(r3)
42 stw r6,_UC_GREGS+(PT_R6*4)(r3)
43 stw r7,_UC_GREGS+(PT_R7*4)(r3)
44 stw r8,_UC_GREGS+(PT_R8*4)(r3)
45 stw r9,_UC_GREGS+(PT_R9*4)(r3)
46 stw r10,_UC_GREGS+(PT_R10*4)(r3)
47 stw r11,_UC_GREGS+(PT_R11*4)(r3)
48 stw r12,_UC_GREGS+(PT_R12*4)(r3)
49 stw r13,_UC_GREGS+(PT_R13*4)(r3)
50 stw r14,_UC_GREGS+(PT_R14*4)(r3)
51 stw r15,_UC_GREGS+(PT_R15*4)(r3)
52 stw r16,_UC_GREGS+(PT_R16*4)(r3)
53 stw r17,_UC_GREGS+(PT_R17*4)(r3)
54 stw r18,_UC_GREGS+(PT_R18*4)(r3)
55 stw r19,_UC_GREGS+(PT_R19*4)(r3)
56 stw r20,_UC_GREGS+(PT_R20*4)(r3)
57 stw r21,_UC_GREGS+(PT_R21*4)(r3)
58 stw r22,_UC_GREGS+(PT_R22*4)(r3)
59 stw r23,_UC_GREGS+(PT_R23*4)(r3)
60 stw r24,_UC_GREGS+(PT_R24*4)(r3)
61 stw r25,_UC_GREGS+(PT_R25*4)(r3)
62 stw r26,_UC_GREGS+(PT_R26*4)(r3)
63 stw r27,_UC_GREGS+(PT_R27*4)(r3)
64 stw r28,_UC_GREGS+(PT_R28*4)(r3)
65 stw r29,_UC_GREGS+(PT_R29*4)(r3)
66 stw r30,_UC_GREGS+(PT_R30*4)(r3)
67 stw r31,_UC_GREGS+(PT_R31*4)(r3)
69 stw r0,_UC_GREGS+(PT_CTR*4)(r3)
71 stw r0,_UC_GREGS+(PT_XER*4)(r3)
73 stw r0,_UC_GREGS+(PT_CCR*4)(r3)
75 /* Set the return value of getcontext to "success". R3 is the only
76 register whose value is not preserved in the saved context. */
78 stw r0,_UC_GREGS+(PT_R3*4)(r3)
80 /* Zero fill fields that can't be set in user state. */
81 stw r0,_UC_GREGS+(PT_MSR*4)(r3)
82 stw r0,_UC_GREGS+(PT_MQ*4)(r3)
84 /* Save the floating-point registers */
85 stfd fp0,_UC_FREGS+(0*8)(r3)
86 stfd fp1,_UC_FREGS+(1*8)(r3)
87 stfd fp2,_UC_FREGS+(2*8)(r3)
88 stfd fp3,_UC_FREGS+(3*8)(r3)
89 stfd fp4,_UC_FREGS+(4*8)(r3)
90 stfd fp5,_UC_FREGS+(5*8)(r3)
91 stfd fp6,_UC_FREGS+(6*8)(r3)
92 stfd fp7,_UC_FREGS+(7*8)(r3)
93 stfd fp8,_UC_FREGS+(8*8)(r3)
94 stfd fp9,_UC_FREGS+(9*8)(r3)
95 stfd fp10,_UC_FREGS+(10*8)(r3)
96 stfd fp11,_UC_FREGS+(11*8)(r3)
97 stfd fp12,_UC_FREGS+(12*8)(r3)
98 stfd fp13,_UC_FREGS+(13*8)(r3)
99 stfd fp14,_UC_FREGS+(14*8)(r3)
100 stfd fp15,_UC_FREGS+(15*8)(r3)
101 stfd fp16,_UC_FREGS+(16*8)(r3)
102 stfd fp17,_UC_FREGS+(17*8)(r3)
103 stfd fp18,_UC_FREGS+(18*8)(r3)
104 stfd fp19,_UC_FREGS+(19*8)(r3)
105 stfd fp20,_UC_FREGS+(20*8)(r3)
106 stfd fp21,_UC_FREGS+(21*8)(r3)
107 stfd fp22,_UC_FREGS+(22*8)(r3)
108 stfd fp23,_UC_FREGS+(23*8)(r3)
109 stfd fp24,_UC_FREGS+(24*8)(r3)
110 stfd fp25,_UC_FREGS+(25*8)(r3)
111 stfd fp26,_UC_FREGS+(26*8)(r3)
112 stfd fp27,_UC_FREGS+(27*8)(r3)
113 stfd fp28,_UC_FREGS+(28*8)(r3)
114 stfd fp29,_UC_FREGS+(29*8)(r3)
116 stfd fp30,_UC_FREGS+(30*8)(r3)
117 stfd fp31,_UC_FREGS+(31*8)(r3)
118 stfd fp0,_UC_FREGS+(32*8)(r3)
122 bl _GLOBAL_OFFSET_TABLE_@local-4
125 lwz r7,_rtld_global@got(r7)
127 lwz r7,RTLD_GLOBAL_DL_HWCAP_OFFSET(r7)
129 lwz r7,_dl_hwcap@got(r7)
135 lwz r7,_dl_hwcap@l(r7)
137 andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
140 la r10,(_UC_VREGS)(r3)
141 la r9,(_UC_VREGS+16)(r3)
235 /* Restore ucontext (parm1) from stack. */
236 lwz r12,_FRAME_PARM_SAVE1+16(r1)
238 stw r3,_UC_REGS_PTR(r12)
239 addi r5,r12,_UC_SIGMASK
241 bl JUMPTARGET(sigprocmask)
243 lwz r0,_FRAME_LR_SAVE+16(r1)
247 PSEUDO_END(__getcontext)
249 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
251 #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
253 ENTRY(__novec_getcontext)
255 * Since we are not attempting to save the altivec registers,
256 * there is no need to get the register storage space
257 * aligned on a 16-byte boundary.
259 addi r3,r3,_UC_REG_SPACE
260 stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
261 stw r0,_UC_GREGS+(PT_R0*4)(r3)
262 stw r1,_UC_GREGS+(PT_R1*4)(r3)
266 stw r0,_UC_GREGS+(PT_LNK*4)(r3)
267 stw r0,_UC_GREGS+(PT_NIP*4)(r3)
268 stw r2,_UC_GREGS+(PT_R2*4)(r3)
269 stw r4,_UC_GREGS+(PT_R4*4)(r3)
270 stw r5,_UC_GREGS+(PT_R5*4)(r3)
271 stw r6,_UC_GREGS+(PT_R6*4)(r3)
272 stw r7,_UC_GREGS+(PT_R7*4)(r3)
273 stw r8,_UC_GREGS+(PT_R8*4)(r3)
274 stw r9,_UC_GREGS+(PT_R9*4)(r3)
275 stw r10,_UC_GREGS+(PT_R10*4)(r3)
276 stw r11,_UC_GREGS+(PT_R11*4)(r3)
277 stw r12,_UC_GREGS+(PT_R12*4)(r3)
278 stw r13,_UC_GREGS+(PT_R13*4)(r3)
279 stw r14,_UC_GREGS+(PT_R14*4)(r3)
280 stw r15,_UC_GREGS+(PT_R15*4)(r3)
281 stw r16,_UC_GREGS+(PT_R16*4)(r3)
282 stw r17,_UC_GREGS+(PT_R17*4)(r3)
283 stw r18,_UC_GREGS+(PT_R18*4)(r3)
284 stw r19,_UC_GREGS+(PT_R19*4)(r3)
285 stw r20,_UC_GREGS+(PT_R20*4)(r3)
286 stw r21,_UC_GREGS+(PT_R21*4)(r3)
287 stw r22,_UC_GREGS+(PT_R22*4)(r3)
288 stw r23,_UC_GREGS+(PT_R23*4)(r3)
289 stw r24,_UC_GREGS+(PT_R24*4)(r3)
290 stw r25,_UC_GREGS+(PT_R25*4)(r3)
291 stw r26,_UC_GREGS+(PT_R26*4)(r3)
292 stw r27,_UC_GREGS+(PT_R27*4)(r3)
293 stw r28,_UC_GREGS+(PT_R28*4)(r3)
294 stw r29,_UC_GREGS+(PT_R29*4)(r3)
295 stw r30,_UC_GREGS+(PT_R30*4)(r3)
296 stw r31,_UC_GREGS+(PT_R31*4)(r3)
298 stw r0,_UC_GREGS+(PT_CTR*4)(r3)
300 stw r0,_UC_GREGS+(PT_XER*4)(r3)
302 stw r0,_UC_GREGS+(PT_CCR*4)(r3)
304 /* Set the return value of getcontext to "success". R3 is the only
305 register whose value is not preserved in the saved context. */
307 stw r0,_UC_GREGS+(PT_R3*4)(r3)
309 /* Zero fill fields that can't be set in user state. */
310 stw r0,_UC_GREGS+(PT_MSR*4)(r3)
311 stw r0,_UC_GREGS+(PT_MQ*4)(r3)
313 /* Save the floating-point registers */
314 stfd fp0,_UC_FREGS+(0*8)(r3)
315 stfd fp1,_UC_FREGS+(1*8)(r3)
316 stfd fp2,_UC_FREGS+(2*8)(r3)
317 stfd fp3,_UC_FREGS+(3*8)(r3)
318 stfd fp4,_UC_FREGS+(4*8)(r3)
319 stfd fp5,_UC_FREGS+(5*8)(r3)
320 stfd fp6,_UC_FREGS+(6*8)(r3)
321 stfd fp7,_UC_FREGS+(7*8)(r3)
322 stfd fp8,_UC_FREGS+(8*8)(r3)
323 stfd fp9,_UC_FREGS+(9*8)(r3)
324 stfd fp10,_UC_FREGS+(10*8)(r3)
325 stfd fp11,_UC_FREGS+(11*8)(r3)
326 stfd fp12,_UC_FREGS+(12*8)(r3)
327 stfd fp13,_UC_FREGS+(13*8)(r3)
328 stfd fp14,_UC_FREGS+(14*8)(r3)
329 stfd fp15,_UC_FREGS+(15*8)(r3)
330 stfd fp16,_UC_FREGS+(16*8)(r3)
331 stfd fp17,_UC_FREGS+(17*8)(r3)
332 stfd fp18,_UC_FREGS+(18*8)(r3)
333 stfd fp19,_UC_FREGS+(19*8)(r3)
334 stfd fp20,_UC_FREGS+(20*8)(r3)
335 stfd fp21,_UC_FREGS+(21*8)(r3)
336 stfd fp22,_UC_FREGS+(22*8)(r3)
337 stfd fp23,_UC_FREGS+(23*8)(r3)
338 stfd fp24,_UC_FREGS+(24*8)(r3)
339 stfd fp25,_UC_FREGS+(25*8)(r3)
340 stfd fp26,_UC_FREGS+(26*8)(r3)
341 stfd fp27,_UC_FREGS+(27*8)(r3)
342 stfd fp28,_UC_FREGS+(28*8)(r3)
343 stfd fp29,_UC_FREGS+(29*8)(r3)
345 stfd fp30,_UC_FREGS+(30*8)(r3)
346 stfd fp31,_UC_FREGS+(31*8)(r3)
347 stfd fp0,_UC_FREGS+(32*8)(r3)
349 addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE
352 bl JUMPTARGET(sigprocmask)
358 PSEUDO_END(__novec_getcontext)
360 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
364 #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
367 #include <bits/errno.h>
369 ENTRY (__getcontext_stub)
371 b JUMPTARGET(__syscall_error)
372 END (__getcontext_stub)
374 compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)