1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef _SYS_UCONTEXT_H_
30 #define _SYS_UCONTEXT_H_
31 
32 #include <signal.h>
33 #include <sys/user.h>
34 
35 __BEGIN_DECLS
36 
37 #if defined(__arm__)
38 
39 enum {
40   REG_R0 = 0,
41   REG_R1,
42   REG_R2,
43   REG_R3,
44   REG_R4,
45   REG_R5,
46   REG_R6,
47   REG_R7,
48   REG_R8,
49   REG_R9,
50   REG_R10,
51   REG_R11,
52   REG_R12,
53   REG_R13,
54   REG_R14,
55   REG_R15,
56 };
57 
58 #define NGREG 18 /* Like glibc. */
59 
60 typedef int greg_t;
61 typedef greg_t gregset_t[NGREG];
62 typedef struct user_fpregs fpregset_t;
63 
64 #include <asm/sigcontext.h>
65 typedef struct sigcontext mcontext_t;
66 
67 typedef struct ucontext {
68   unsigned long uc_flags;
69   struct ucontext* uc_link;
70   stack_t uc_stack;
71   mcontext_t uc_mcontext;
72   sigset_t uc_sigmask;
73   // Android has a wrong (smaller) sigset_t on ARM.
74   uint32_t __padding_rt_sigset;
75   // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM.
76   char __padding[120];
77   unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
78 } ucontext_t;
79 
80 #elif defined(__aarch64__)
81 
82 #define NGREG 34 /* x0..x30 + sp + pc + pstate */
83 typedef unsigned long greg_t;
84 typedef greg_t gregset_t[NGREG];
85 typedef struct user_fpsimd_struct fpregset_t;
86 
87 #include <asm/sigcontext.h>
88 typedef struct sigcontext mcontext_t;
89 
90 typedef struct ucontext {
91   unsigned long uc_flags;
92   struct ucontext *uc_link;
93   stack_t uc_stack;
94   sigset_t uc_sigmask;
95   // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64.
96   char __padding[128 - sizeof(sigset_t)];
97   mcontext_t uc_mcontext;
98 } ucontext_t;
99 
100 #elif defined(__i386__)
101 
102 enum {
103   REG_GS = 0,
104   REG_FS,
105   REG_ES,
106   REG_DS,
107   REG_EDI,
108   REG_ESI,
109   REG_EBP,
110   REG_ESP,
111   REG_EBX,
112   REG_EDX,
113   REG_ECX,
114   REG_EAX,
115   REG_TRAPNO,
116   REG_ERR,
117   REG_EIP,
118   REG_CS,
119   REG_EFL,
120   REG_UESP,
121   REG_SS,
122   NGREG
123 };
124 
125 typedef int greg_t;
126 typedef greg_t gregset_t[NGREG];
127 
128 struct _libc_fpreg {
129   unsigned short significand[4];
130   unsigned short exponent;
131 };
132 
133 struct _libc_fpstate {
134   unsigned long cw;
135   unsigned long sw;
136   unsigned long tag;
137   unsigned long ipoff;
138   unsigned long cssel;
139   unsigned long dataoff;
140   unsigned long datasel;
141   struct _libc_fpreg _st[8];
142   unsigned long status;
143 };
144 
145 typedef struct _libc_fpstate* fpregset_t;
146 
147 typedef struct {
148   gregset_t gregs;
149   fpregset_t fpregs;
150   unsigned long oldmask;
151   unsigned long cr2;
152 } mcontext_t;
153 
154 typedef struct ucontext {
155   unsigned long uc_flags;
156   struct ucontext* uc_link;
157   stack_t uc_stack;
158   mcontext_t uc_mcontext;
159   sigset_t uc_sigmask;
160   // Android has a wrong (smaller) sigset_t on x86.
161   uint32_t __padding_rt_sigset;
162   struct _libc_fpstate __fpregs_mem;
163 } ucontext_t;
164 
165 #elif defined(__mips__)
166 
167 /* glibc doesn't have names for MIPS registers. */
168 
169 #define NGREG 32
170 #define NFPREG 32
171 
172 typedef unsigned long long greg_t;
173 typedef greg_t gregset_t[NGREG];
174 
175 typedef struct fpregset {
176   union {
177     double fp_dregs[NFPREG];
178     struct {
179       float _fp_fregs;
180       unsigned _fp_pad;
181     } fp_fregs[NFPREG];
182   } fp_r;
183 } fpregset_t;
184 
185 #ifdef __LP64__
186 typedef struct {
187   gregset_t gregs;
188   fpregset_t fpregs;
189   greg_t mdhi;
190   greg_t hi1;
191   greg_t hi2;
192   greg_t hi3;
193   greg_t mdlo;
194   greg_t lo1;
195   greg_t lo2;
196   greg_t lo3;
197   greg_t pc;
198   uint32_t fpc_csr;
199   uint32_t used_math;
200   uint32_t dsp;
201   uint32_t reserved;
202 } mcontext_t;
203 #else
204 typedef struct {
205   unsigned regmask;
206   unsigned status;
207   greg_t pc;
208   gregset_t gregs;
209   fpregset_t fpregs;
210   unsigned fp_owned;
211   unsigned fpc_csr;
212   unsigned fpc_eir;
213   unsigned used_math;
214   unsigned dsp;
215   greg_t mdhi;
216   greg_t mdlo;
217   unsigned long hi1;
218   unsigned long lo1;
219   unsigned long hi2;
220   unsigned long lo2;
221   unsigned long hi3;
222   unsigned long lo3;
223 } mcontext_t;
224 #endif
225 
226 typedef struct ucontext {
227   unsigned long uc_flags;
228   struct ucontext* uc_link;
229   stack_t uc_stack;
230   mcontext_t uc_mcontext;
231   sigset_t uc_sigmask;
232 } ucontext_t;
233 
234 #elif defined(__x86_64__)
235 
236 enum {
237   REG_R8 = 0,
238   REG_R9,
239   REG_R10,
240   REG_R11,
241   REG_R12,
242   REG_R13,
243   REG_R14,
244   REG_R15,
245   REG_RDI,
246   REG_RSI,
247   REG_RBP,
248   REG_RBX,
249   REG_RDX,
250   REG_RAX,
251   REG_RCX,
252   REG_RSP,
253   REG_RIP,
254   REG_EFL,
255   REG_CSGSFS,
256   REG_ERR,
257   REG_TRAPNO,
258   REG_OLDMASK,
259   REG_CR2,
260   NGREG
261 };
262 
263 typedef long greg_t;
264 typedef greg_t gregset_t[NGREG];
265 
266 struct _libc_fpxreg {
267   unsigned short significand[4];
268   unsigned short exponent;
269   unsigned short padding[3];
270 };
271 
272 struct _libc_xmmreg {
273   uint32_t element[4];
274 };
275 
276 struct _libc_fpstate {
277   uint16_t cwd;
278   uint16_t swd;
279   uint16_t ftw;
280   uint16_t fop;
281   uint64_t rip;
282   uint64_t rdp;
283   uint32_t mxcsr;
284   uint32_t mxcr_mask;
285   struct _libc_fpxreg _st[8];
286   struct _libc_xmmreg _xmm[16];
287   uint32_t padding[24];
288 };
289 
290 typedef struct _libc_fpstate* fpregset_t;
291 
292 typedef struct {
293   gregset_t gregs;
294   fpregset_t fpregs;
295   unsigned long __reserved1[8];
296 } mcontext_t;
297 
298 typedef struct ucontext {
299   unsigned long uc_flags;
300   struct ucontext* uc_link;
301   stack_t uc_stack;
302   mcontext_t uc_mcontext;
303   sigset_t uc_sigmask;
304   struct _libc_fpstate __fpregs_mem;
305 } ucontext_t;
306 
307 #endif
308 
309 __END_DECLS
310 
311 #endif /* _SYS_UCONTEXT_H_ */
312