Replace FSF snail mail address with URLs.
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / getcontext.S
blob533d98bcc8cec7da921764b33ef5364320d18ed0
1 /* Save current context.
2    Copyright (C) 2002, 2004, 2006 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, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <rtld-global-offsets.h>
21 #include <shlib-compat.h>
22 #include <kernel-features.h>
24 #define __ASSEMBLY__
25 #include <asm/ptrace.h>
26 #include <asm/errno.h>
27 #include "ucontext_i.h"
30 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
31 ENTRY(__novec_getcontext)
32         CALL_MCOUNT 1
33 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
34   std  r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
35   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
36   mflr  r0
37   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
38   std  r0,FRAME_LR_SAVE(r1)
39   cfi_offset (lr, FRAME_LR_SAVE)
40   std  r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
41   std  r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
42   stdu  r1,-128(r1)
43   cfi_adjust_cfa_offset (128)
44   std  r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
45   std  r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
46   std  r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
47   std  r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
48   std  r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
49   std  r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
50   std  r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
51   std  r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
52   std  r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
53   std  r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
54   std  r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
55   std  r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
56   std  r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
57   std  r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
58   std  r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
59   std  r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
60   std  r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
61   std  r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
62   std  r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
63   std  r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
64   std  r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
65   std  r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
66   std  r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
67   std  r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
68   std  r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
69   std  r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
70   std  r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
71   std  r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
72   mfctr  r0
73   std  r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
74   mfxer  r0
75   std  r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
76   mfcr  r0
77   std  r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
79   /* Set the return value of swapcontext to "success".  R3 is the only
80      register whose value is not preserved in the saved context.  */
81   li   r0,0
82   std  r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
84   /* Zero fill fields that can't be set in user state or are unused.  */
85   std  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
86   std  r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
87   std  r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
88   std  r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
89   std  r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
90   std  r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
91   std  r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
93   /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
94      field.  Struct pt_regs and elf_gregset_t are the same thing.
95      We kept the regs field for backwards compatibility with
96      libraries built before we extended sigcontext.  */
97   addi r0,r3,SIGCONTEXT_GP_REGS
98   std  r0,SIGCONTEXT_PT_REGS(r3)
100   stfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
101   stfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
102   stfd  fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
103   stfd  fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
104   stfd  fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
105   stfd  fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
106   stfd  fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
107   stfd  fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
108   stfd  fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
109   stfd  fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
110   stfd  fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
111   stfd  fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
112   stfd  fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
113   stfd  fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
114   stfd  fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
115   stfd  fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
116   stfd  fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
117   stfd  fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
118   stfd  fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
119   stfd  fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
120   stfd  fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
121   stfd  fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
122   stfd  fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
123   stfd  fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
124   stfd  fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
125   stfd  fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
126   stfd  fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
127   stfd  fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
128   stfd  fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
129   stfd  fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
130   mffs  fp0
131   stfd  fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
132   stfd  fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
133   stfd  fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
135   addi  r5,r3,UCONTEXT_SIGMASK
136   li  r4,0
137   li  r3,SIG_BLOCK
138   bl  JUMPTARGET(__sigprocmask)
139   nop
140 #else
141   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
142   mflr r0
143   std  r0,FRAME_LR_SAVE(r1)
144   cfi_offset (lr, FRAME_LR_SAVE)
145   stdu r1,-128(r1)
146   cfi_adjust_cfa_offset(128)
147   li   r3,ENOSYS
148   bl   JUMPTARGET(__syscall_error)
149   nop
150   li   r3,-1
151 #endif
153   ld    r0,128+FRAME_LR_SAVE(r1)
154   addi  r1,r1,128
155   mtlr  r0
156   blr
157 PSEUDO_END(__novec_getcontext)
159 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
161 #endif
163         .section        ".toc","aw"
164 .LC__dl_hwcap:
165 #ifdef SHARED
166         .tc _rtld_global_ro[TC],_rtld_global_ro
167 #else
168         .tc _dl_hwcap[TC],_dl_hwcap
169 #endif
170         .section ".text"
172         .machine        "altivec"
173 ENTRY(__getcontext)
174         CALL_MCOUNT 1
175 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
176   std  r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
177   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
178   mflr  r0
179   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
180   std  r0,FRAME_LR_SAVE(r1)
181   cfi_offset (lr, FRAME_LR_SAVE)
182   std  r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
183   std  r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
184   stdu  r1,-128(r1)
185   cfi_adjust_cfa_offset (128)
186   std  r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
187   std  r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
188   std  r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
189   std  r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
190   std  r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
191   std  r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
192   std  r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
193   std  r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
194   std  r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
195   std  r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
196   std  r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
197   std  r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
198   std  r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
199   std  r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
200   std  r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
201   std  r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
202   std  r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
203   std  r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
204   std  r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
205   std  r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
206   std  r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
207   std  r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
208   std  r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
209   std  r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
210   std  r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
211   std  r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
212   std  r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
213   std  r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
214   mfctr  r0
215   std  r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
216   mfxer  r0
217   std  r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
218   mfcr  r0
219   std  r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
221   /* Set the return value of swapcontext to "success".  R3 is the only
222      register whose value is not preserved in the saved context.  */
223   li   r0,0
224   std  r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
226   /* Zero fill fields that can't be set in user state or are unused.  */
227   std  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
228   std  r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
229   std  r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
230   std  r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
231   std  r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
232   std  r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
233   std  r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
235   /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
236      field.  Struct pt_regs and elf_gregset_t are the same thing.
237      We kept the regs field for backwards compatibility with
238      libraries built before we extended sigcontext.  */
239   addi r0,r3,SIGCONTEXT_GP_REGS
240   std  r0,SIGCONTEXT_PT_REGS(r3)
242   stfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
243   stfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
244   stfd  fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
245   stfd  fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
246   stfd  fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
247   stfd  fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
248   stfd  fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
249   stfd  fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
250   stfd  fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
251   stfd  fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
252   stfd  fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
253   stfd  fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
254   stfd  fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
255   stfd  fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
256   stfd  fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
257   stfd  fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
258   stfd  fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
259   stfd  fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
260   stfd  fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
261   stfd  fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
262   stfd  fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
263   stfd  fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
264   stfd  fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
265   stfd  fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
266   stfd  fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
267   stfd  fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
268   stfd  fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
269   stfd  fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
270   stfd  fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
271   stfd  fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
272   mffs  fp0
273   stfd  fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
274   stfd  fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
275   stfd  fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
277   ld    r5,.LC__dl_hwcap@toc(r2)
278 # ifdef SHARED
279 /* Load _rtld-global._dl_hwcap.  */
280   ld    r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
281 # else
282   ld    r5,0(r5) /* Load extern _dl_hwcap.  */
283 # endif
284   la    r10,(SIGCONTEXT_V_RESERVE+8)(r3)
285   la    r9,(SIGCONTEXT_V_RESERVE+24)(r3)
287   andis.  r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
289   clrrdi  r10,r10,4
290   beq   L(has_no_vec)
291   clrrdi  r9,r9,4
292   mr    r5,r10  /* Capture *v_regs value in r5.  */
294   stvx  v0,0,r10
295   stvx  v1,0,r9
296   addi  r10,r10,32
297   addi  r9,r9,32
299   stvx  v2,0,r10
300   stvx  v3,0,r9
301   addi  r10,r10,32
302   addi  r9,r9,32
304   stvx  v4,0,r10
305   stvx  v5,0,r9
306   addi  r10,r10,32
307   addi  r9,r9,32
309   stvx  v6,0,r10
310   stvx  v7,0,r9
311   addi  r10,r10,32
312   addi  r9,r9,32
314   stvx  v8,0,r10
315   stvx  v9,0,r9
316   addi  r10,r10,32
317   addi  r9,r9,32
319   stvx  v10,0,r10
320   stvx  v11,0,r9
321   addi  r10,r10,32
322   addi  r9,r9,32
324   stvx  v12,0,r10
325   stvx  v13,0,r9
326   addi  r10,r10,32
327   addi  r9,r9,32
329   stvx  v14,0,r10
330   stvx  v15,0,r9
331   addi  r10,r10,32
332   addi  r9,r9,32
334   stvx  v16,0,r10
335   stvx  v17,0,r9
336   addi  r10,r10,32
337   addi  r9,r9,32
339   stvx  v18,0,r10
340   stvx  v19,0,r9
341   addi  r10,r10,32
342   addi  r9,r9,32
344   stvx  v20,0,r10
345   stvx  v21,0,r9
346   addi  r10,r10,32
347   addi  r9,r9,32
349   stvx  v22,0,r10
350   stvx  v23,0,r9
351   addi  r10,r10,32
352   addi  r9,r9,32
354   stvx  v24,0,r10
355   stvx  v25,0,r9
356   addi  r10,r10,32
357   addi  r9,r9,32
359   stvx  v26,0,r10
360   stvx  v27,0,r9
361   addi  r10,r10,32
362   addi  r9,r9,32
364   stvx  v28,0,r10
365   stvx  v29,0,r9
366   addi  r10,r10,32
367   addi  r9,r9,32
369   stvx  v30,0,r10
370   stvx  v31,0,r9
371   addi  r10,r10,32
372   addi  r9,r9,32
374   mfvscr  v0
375   mfspr r0,VRSAVE
376   stvx  v0,0,r10
377   stw   r0,0(9)
379 L(has_no_vec):
381    Store either a NULL or a quadword aligned pointer to the Vector register
382    array into *v_regs.
384   std   r5,(SIGCONTEXT_V_REGS_PTR)(r3)
386   addi  r5,r3,UCONTEXT_SIGMASK
387   li  r4,0
388   li  r3,SIG_BLOCK
389   bl  JUMPTARGET(__sigprocmask)
390   nop
391 #else
392   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
393   mflr r0
394   std  r0,FRAME_LR_SAVE(r1)
395   cfi_offset (lr, FRAME_LR_SAVE)
396   stdu r1,-128(r1)
397   cfi_adjust_cfa_offset (128)
398   li   r3,ENOSYS
399   bl   JUMPTARGET(__syscall_error)
400   nop
401   li   r3,-1
402 #endif
404   ld    r0,128+FRAME_LR_SAVE(r1)
405   addi  r1,r1,128
406   mtlr  r0
407   blr
408 PSEUDO_END(__getcontext)
410 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)