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