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