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
41enum {
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
62typedef int greg_t;
63typedef greg_t gregset_t[NGREG];
64typedef struct user_fpregs fpregset_t;
65
66#include <asm/sigcontext.h>
67typedef struct sigcontext mcontext_t;
68
69typedef 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 */
85typedef unsigned long greg_t;
86typedef greg_t gregset_t[NGREG];
87typedef struct user_fpsimd_struct fpregset_t;
88
89#include <asm/sigcontext.h>
90typedef struct sigcontext mcontext_t;
91
92typedef 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
104enum {
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
127typedef int greg_t;
128typedef greg_t gregset_t[NGREG];
129
130struct _libc_fpreg {
131  unsigned short significand[4];
132  unsigned short exponent;
133};
134
135struct _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
147typedef struct _libc_fpstate* fpregset_t;
148
149typedef struct {
150  gregset_t gregs;
151  fpregset_t fpregs;
152  unsigned long oldmask;
153  unsigned long cr2;
154} mcontext_t;
155
156typedef 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
174typedef unsigned long long greg_t;
175typedef greg_t gregset_t[NGREG];
176
177typedef 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__
188typedef 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
206typedef 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
228typedef 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
238enum {
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
265typedef long greg_t;
266typedef greg_t gregset_t[NGREG];
267
268struct _libc_fpxreg {
269  unsigned short significand[4];
270  unsigned short exponent;
271  unsigned short padding[3];
272};
273
274struct _libc_xmmreg {
275  uint32_t element[4];
276};
277
278struct _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
292typedef struct _libc_fpstate* fpregset_t;
293
294typedef struct {
295  gregset_t gregs;
296  fpregset_t fpregs;
297  unsigned long __reserved1[8];
298} mcontext_t;
299
300typedef 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