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 86 struct user_fpsimd_struct { 87 long double vregs[32]; 88 uint32_t fpsr; 89 uint32_t fpcr; 90 }; 91 typedef struct user_fpsimd_struct fpregset_t; 92 93 #include <asm/sigcontext.h> 94 typedef struct sigcontext mcontext_t; 95 96 typedef struct ucontext { 97 unsigned long uc_flags; 98 struct ucontext *uc_link; 99 stack_t uc_stack; 100 sigset_t uc_sigmask; 101 // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64. 102 char __padding[128 - sizeof(sigset_t)]; 103 mcontext_t uc_mcontext; 104 } ucontext_t; 105 106 #elif defined(__i386__) 107 108 enum { 109 REG_GS = 0, 110 REG_FS, 111 REG_ES, 112 REG_DS, 113 REG_EDI, 114 REG_ESI, 115 REG_EBP, 116 REG_ESP, 117 REG_EBX, 118 REG_EDX, 119 REG_ECX, 120 REG_EAX, 121 REG_TRAPNO, 122 REG_ERR, 123 REG_EIP, 124 REG_CS, 125 REG_EFL, 126 REG_UESP, 127 REG_SS, 128 NGREG 129 }; 130 131 typedef int greg_t; 132 typedef greg_t gregset_t[NGREG]; 133 134 struct _libc_fpreg { 135 unsigned short significand[4]; 136 unsigned short exponent; 137 }; 138 139 struct _libc_fpstate { 140 unsigned long cw; 141 unsigned long sw; 142 unsigned long tag; 143 unsigned long ipoff; 144 unsigned long cssel; 145 unsigned long dataoff; 146 unsigned long datasel; 147 struct _libc_fpreg _st[8]; 148 unsigned long status; 149 }; 150 151 typedef struct _libc_fpstate* fpregset_t; 152 153 typedef struct { 154 gregset_t gregs; 155 fpregset_t fpregs; 156 unsigned long oldmask; 157 unsigned long cr2; 158 } mcontext_t; 159 160 typedef struct ucontext { 161 unsigned long uc_flags; 162 struct ucontext* uc_link; 163 stack_t uc_stack; 164 mcontext_t uc_mcontext; 165 sigset_t uc_sigmask; 166 // Android has a wrong (smaller) sigset_t on x86. 167 uint32_t __padding_rt_sigset; 168 struct _libc_fpstate __fpregs_mem; 169 } ucontext_t; 170 171 #elif defined(__mips__) 172 173 /* glibc doesn't have names for MIPS registers. */ 174 175 #define NGREG 32 176 #define NFPREG 32 177 178 typedef unsigned long long greg_t; 179 typedef greg_t gregset_t[NGREG]; 180 181 typedef struct fpregset { 182 union { 183 double fp_dregs[NFPREG]; 184 struct { 185 float _fp_fregs; 186 unsigned _fp_pad; 187 } fp_fregs[NFPREG]; 188 } fp_r; 189 } fpregset_t; 190 191 #ifdef __LP64__ 192 typedef struct { 193 gregset_t gregs; 194 fpregset_t fpregs; 195 greg_t mdhi; 196 greg_t hi1; 197 greg_t hi2; 198 greg_t hi3; 199 greg_t mdlo; 200 greg_t lo1; 201 greg_t lo2; 202 greg_t lo3; 203 greg_t pc; 204 uint32_t fpc_csr; 205 uint32_t used_math; 206 uint32_t dsp; 207 uint32_t reserved; 208 } mcontext_t; 209 #else 210 typedef struct { 211 unsigned regmask; 212 unsigned status; 213 greg_t pc; 214 gregset_t gregs; 215 fpregset_t fpregs; 216 unsigned fp_owned; 217 unsigned fpc_csr; 218 unsigned fpc_eir; 219 unsigned used_math; 220 unsigned dsp; 221 greg_t mdhi; 222 greg_t mdlo; 223 unsigned long hi1; 224 unsigned long lo1; 225 unsigned long hi2; 226 unsigned long lo2; 227 unsigned long hi3; 228 unsigned long lo3; 229 } mcontext_t; 230 #endif 231 232 typedef struct ucontext { 233 unsigned long uc_flags; 234 struct ucontext* uc_link; 235 stack_t uc_stack; 236 mcontext_t uc_mcontext; 237 sigset_t uc_sigmask; 238 } ucontext_t; 239 240 #elif defined(__x86_64__) 241 242 enum { 243 REG_R8 = 0, 244 REG_R9, 245 REG_R10, 246 REG_R11, 247 REG_R12, 248 REG_R13, 249 REG_R14, 250 REG_R15, 251 REG_RDI, 252 REG_RSI, 253 REG_RBP, 254 REG_RBX, 255 REG_RDX, 256 REG_RAX, 257 REG_RCX, 258 REG_RSP, 259 REG_RIP, 260 REG_EFL, 261 REG_CSGSFS, 262 REG_ERR, 263 REG_TRAPNO, 264 REG_OLDMASK, 265 REG_CR2, 266 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 sigset_t uc_sigmask; 310 struct _libc_fpstate __fpregs_mem; 311 } ucontext_t; 312 313 #endif 314 315 __END_DECLS 316 317 #endif /* _SYS_UCONTEXT_H_ */ 318