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