#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H
+// The purpose of this file is to glue the mismatching headers (Android NDK vs
+// glibc) and therefore avoid doing otherwise awkward #ifdefs in the code.
+// The following quirks are currently handled by this file:
+// - MIPS: Keep using forked definitions of user.h structs. The definition in
+// the NDK is completely different.
+// Internal bug b/18097715
+// - i386: Use the Android NDK but alias user_fxsr_struct > user_fpxregs_struct.
+// - Other platforms: Just use the Android NDK unchanged.
+
+#ifdef __mips__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
-// These types are used with ptrace(), more specifically with
-// PTRACE_GETREGS, PTRACE_GETFPREGS and PTRACE_GETVFPREGS respectively.
-//
-// They are also defined, sometimes with different names, in <asm/user.h>
-//
-
-#if defined(__arm__)
-
-#define _ARM_USER_H 1 // Prevent <asm/user.h> conflicts
-
-// Note: on ARM, GLibc uses user_regs instead of user_regs_struct.
-struct user_regs {
- // Note: Entries 0-15 match r0..r15
- // Entry 16 is used to store the CPSR register.
- // Entry 17 is used to store the "orig_r0" value.
- unsigned long int uregs[18];
-};
-
-// Same here: user_fpregs instead of user_fpregs_struct.
-struct user_fpregs {
- struct fp_reg {
- unsigned int sign1:1;
- unsigned int unused:15;
- unsigned int sign2:1;
- unsigned int exponent:14;
- unsigned int j:1;
- unsigned int mantissa1:31;
- unsigned int mantissa0:32;
- } fpregs[8];
- unsigned int fpsr:32;
- unsigned int fpcr:32;
- unsigned char ftype[8];
- unsigned int init_flag;
-};
-
-// GLibc doesn't define this one in <sys/user.h> though.
-struct user_vfpregs {
- unsigned long long fpregs[32];
- unsigned long fpscr;
-};
-
-#elif defined(__i386__)
-
-#define _I386_USER_H 1 // Prevent <asm/user.h> conflicts
-
-// GLibc-compatible definitions
-struct user_regs_struct {
- long ebx, ecx, edx, esi, edi, ebp, eax;
- long xds, xes, xfs, xgs, orig_eax;
- long eip, xcs, eflags, esp, xss;
-};
-
-struct user_fpregs_struct {
- long cwd, swd, twd, fip, fcs, foo, fos;
- long st_space[20];
-};
-
-struct user_fpxregs_struct {
- unsigned short cwd, swd, twd, fop;
- long fip, fcs, foo, fos, mxcsr, reserved;
- long st_space[32];
- long xmm_space[32];
- long padding[56];
-};
-
-struct user {
- struct user_regs_struct regs;
- int u_fpvalid;
- struct user_fpregs_struct i387;
- unsigned long u_tsize;
- unsigned long u_dsize;
- unsigned long u_ssize;
- unsigned long start_code;
- unsigned long start_stack;
- long signal;
- int reserved;
- struct user_regs_struct* u_ar0;
- struct user_fpregs_struct* u_fpstate;
- unsigned long magic;
- char u_comm [32];
- int u_debugreg [8];
-};
-
-
-#elif defined(__mips__)
-
-#define _ASM_USER_H 1 // Prevent <asm/user.h> conflicts
+#define EF_REG0 6
+#define EF_REG1 7
+#define EF_REG2 8
+#define EF_REG3 9
+#define EF_REG4 10
+#define EF_REG5 11
+#define EF_REG6 12
+#define EF_REG7 13
+#define EF_REG8 14
+#define EF_REG9 15
+#define EF_REG10 16
+#define EF_REG11 17
+#define EF_REG12 18
+#define EF_REG13 19
+#define EF_REG14 20
+#define EF_REG15 21
+#define EF_REG16 22
+#define EF_REG17 23
+#define EF_REG18 24
+#define EF_REG19 25
+#define EF_REG20 26
+#define EF_REG21 27
+#define EF_REG22 28
+#define EF_REG23 29
+#define EF_REG24 30
+#define EF_REG25 31
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_REG26 32
+#define EF_REG27 33
+#define EF_REG28 34
+#define EF_REG29 35
+#define EF_REG30 36
+#define EF_REG31 37
+
+/*
+ * Saved special registers
+ */
+#define EF_LO 38
+#define EF_HI 39
+#define EF_CP0_EPC 40
+#define EF_CP0_BADVADDR 41
+#define EF_CP0_STATUS 42
+#define EF_CP0_CAUSE 43
struct user_regs_struct {
unsigned long long regs[32];
unsigned int fir;
};
-#else
-# error "Unsupported Android CPU ABI"
-#endif
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#else // __mips__
+
+#include_next <sys/user.h>
+#ifdef __i386__
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+typedef struct user_fxsr_struct user_fpxregs_struct;
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+#endif // __i386__
+
+#endif // __mips__
#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_SYS_USER_H