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 <sys/cdefs.h>
33 
34 #include <signal.h>
35 #include <sys/user.h>
36 
37 __BEGIN_DECLS
38 
39 #if defined(__arm__)
40 
41 enum {
42   REG_R0 = 0,
43   REG_R1,
44   REG_R2,
45   REG_R3,
46   REG_R4,
47   REG_R5,
48   REG_R6,
49   REG_R7,
50   REG_R8,
51   REG_R9,
52   REG_R10,
53   REG_R11,
54   REG_R12,
55   REG_R13,
56   REG_R14,
57   REG_R15,
58 };
59 
60 #define NGREG 18 /* Like glibc. */
61 
62 typedef int greg_t;
63 typedef greg_t gregset_t[NGREG];
64 typedef struct user_fpregs fpregset_t;
65 
66 #include <asm/sigcontext.h>
67 typedef struct sigcontext mcontext_t;
68 
69 typedef struct ucontext {
70   unsigned long uc_flags;
71   struct ucontext* uc_link;
72   stack_t uc_stack;
73   mcontext_t uc_mcontext;
74   sigset_t uc_sigmask;
75   /* Android has a wrong (smaller) sigset_t on ARM. */
76   uint32_t __padding_rt_sigset;
77   /* The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM. */
78   char __padding[120];
79   unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
80 } ucontext_t;
81 
82 #elif defined(__aarch64__)
83 
84 #define NGREG 34 /* x0..x30 + sp + pc + pstate */
85 typedef unsigned long greg_t;
86 typedef greg_t gregset_t[NGREG];
87 typedef struct user_fpsimd_struct fpregset_t;
88 
89 #include <asm/sigcontext.h>
90 typedef struct sigcontext mcontext_t;
91 
92 typedef struct ucontext {
93   unsigned long uc_flags;
94   struct ucontext *uc_link;
95   stack_t uc_stack;
96   sigset_t uc_sigmask;
97   /* The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64. */
98   char __padding[128 - sizeof(sigset_t)];
99   mcontext_t uc_mcontext;
100 } ucontext_t;
101 
102 #elif defined(__i386__)
103 
104 enum {
105   REG_GS = 0,
106   REG_FS,
107   REG_ES,
108   REG_DS,
109   REG_EDI,
110   REG_ESI,
111   REG_EBP,
112   REG_ESP,
113   REG_EBX,
114   REG_EDX,
115   REG_ECX,
116   REG_EAX,
117   REG_TRAPNO,
118   REG_ERR,
119   REG_EIP,
120   REG_CS,
121   REG_EFL,
122   REG_UESP,
123   REG_SS,
124   NGREG
125 };
126 
127 typedef int greg_t;
128 typedef greg_t gregset_t[NGREG];
129 
130 struct _libc_fpreg {
131   unsigned short significand[4];
132   unsigned short exponent;
133 };
134 
135 struct _libc_fpstate {
136   unsigned long cw;
137   unsigned long sw;
138   unsigned long tag;
139   unsigned long ipoff;
140   unsigned long cssel;
141   unsigned long dataoff;
142   unsigned long datasel;
143   struct _libc_fpreg _st[8];
144   unsigned long status;
145 };
146 
147 typedef struct _libc_fpstate* fpregset_t;
148 
149 typedef struct {
150   gregset_t gregs;
151   fpregset_t fpregs;
152   unsigned long oldmask;
153   unsigned long cr2;
154 } mcontext_t;
155 
156 typedef struct ucontext {
157   unsigned long uc_flags;
158   struct ucontext* uc_link;
159   stack_t uc_stack;
160   mcontext_t uc_mcontext;
161   sigset_t uc_sigmask;
162   /* Android has a wrong (smaller) sigset_t on x86. */
163   uint32_t __padding_rt_sigset;
164   struct _libc_fpstate __fpregs_mem;
165 } ucontext_t;
166 
167 #elif defined(__mips__)
168 
169 /* glibc doesn't have names for MIPS registers. */
170 
171 #define NGREG 32
172 #define NFPREG 32
173 
174 typedef unsigned long long greg_t;
175 typedef greg_t gregset_t[NGREG];
176 
177 typedef struct fpregset {
178   union {
179     double fp_dregs[NFPREG];
180     struct {
181       float _fp_fregs;
182       unsigned _fp_pad;
183     } fp_fregs[NFPREG];
184   } fp_r;
185 } fpregset_t;
186 
187 #ifdef __LP64__
188 typedef struct {
189   gregset_t gregs;
190   fpregset_t fpregs;
191   greg_t mdhi;
192   greg_t hi1;
193   greg_t hi2;
194   greg_t hi3;
195   greg_t mdlo;
196   greg_t lo1;
197   greg_t lo2;
198   greg_t lo3;
199   greg_t pc;
200   uint32_t fpc_csr;
201   uint32_t used_math;
202   uint32_t dsp;
203   uint32_t reserved;
204 } mcontext_t;
205 #else
206 typedef struct {
207   unsigned regmask;
208   unsigned status;
209   greg_t pc;
210   gregset_t gregs;
211   fpregset_t fpregs;
212   unsigned fp_owned;
213   unsigned fpc_csr;
214   unsigned fpc_eir;
215   unsigned used_math;
216   unsigned dsp;
217   greg_t mdhi;
218   greg_t mdlo;
219   unsigned long hi1;
220   unsigned long lo1;
221   unsigned long hi2;
222   unsigned long lo2;
223   unsigned long hi3;
224   unsigned long lo3;
225 } mcontext_t;
226 #endif
227 
228 typedef struct ucontext {
229   unsigned long uc_flags;
230   struct ucontext* uc_link;
231   stack_t uc_stack;
232   mcontext_t uc_mcontext;
233   sigset_t uc_sigmask;
234 } ucontext_t;
235 
236 #elif defined(__x86_64__)
237 
238 enum {
239   REG_R8 = 0,
240   REG_R9,
241   REG_R10,
242   REG_R11,
243   REG_R12,
244   REG_R13,
245   REG_R14,
246   REG_R15,
247   REG_RDI,
248   REG_RSI,
249   REG_RBP,
250   REG_RBX,
251   REG_RDX,
252   REG_RAX,
253   REG_RCX,
254   REG_RSP,
255   REG_RIP,
256   REG_EFL,
257   REG_CSGSFS,
258   REG_ERR,
259   REG_TRAPNO,
260   REG_OLDMASK,
261   REG_CR2,
262   NGREG
263 };
264 
265 typedef long greg_t;
266 typedef greg_t gregset_t[NGREG];
267 
268 struct _libc_fpxreg {
269   unsigned short significand[4];
270   unsigned short exponent;
271   unsigned short padding[3];
272 };
273 
274 struct _libc_xmmreg {
275   uint32_t element[4];
276 };
277 
278 struct _libc_fpstate {
279   uint16_t cwd;
280   uint16_t swd;
281   uint16_t ftw;
282   uint16_t fop;
283   uint64_t rip;
284   uint64_t rdp;
285   uint32_t mxcsr;
286   uint32_t mxcr_mask;
287   struct _libc_fpxreg _st[8];
288   struct _libc_xmmreg _xmm[16];
289   uint32_t padding[24];
290 };
291 
292 typedef struct _libc_fpstate* fpregset_t;
293 
294 typedef struct {
295   gregset_t gregs;
296   fpregset_t fpregs;
297   unsigned long __reserved1[8];
298 } mcontext_t;
299 
300 typedef struct ucontext {
301   unsigned long uc_flags;
302   struct ucontext* uc_link;
303   stack_t uc_stack;
304   mcontext_t uc_mcontext;
305   sigset_t uc_sigmask;
306   struct _libc_fpstate __fpregs_mem;
307 } ucontext_t;
308 
309 #endif
310 
311 __END_DECLS
312 
313 #endif /* _SYS_UCONTEXT_H_ */
314