aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/Utility/RegisterContext_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/Utility/RegisterContext_x86.h')
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h487
1 files changed, 487 insertions, 0 deletions
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
new file mode 100644
index 000000000000..6b3f6fb43e33
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -0,0 +1,487 @@
+//===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContext_x86_H_
+#define liblldb_RegisterContext_x86_H_
+
+//---------------------------------------------------------------------------
+// i386 gcc, dwarf, gdb enums
+//---------------------------------------------------------------------------
+
+// Register numbers seen in eh_frame (eRegisterKindGCC)
+//
+// From Jason Molenda: "gcc registers" is the register numbering used in the eh_frame
+// CFI. The only registers that are described in eh_frame CFI are those that are
+// preserved across function calls aka callee-saved aka non-volatile. And none
+// of the floating point registers on x86 are preserved across function calls.
+//
+// The only reason there is a "gcc register" and a "dwarf register" is because of a
+// mistake years and years ago with i386 where they got esp and ebp
+// backwards when they emitted the eh_frame instructions. Once there were
+// binaries In The Wild using the reversed numbering, we had to stick with it
+// forever.
+enum
+{
+ // 2nd parameter in DwarfRegNum() is regnum for exception handling on x86-32.
+ // See http://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register
+ gcc_eax_i386 = 0,
+ gcc_ecx_i386,
+ gcc_edx_i386,
+ gcc_ebx_i386,
+
+ // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus dwarf's reg numbering).
+ // To be specific:
+ // i386+darwin eh_frame: 4 is ebp, 5 is esp
+ // i386+everyone else eh_frame: 4 is esp, 5 is ebp
+ // i386 dwarf: 4 is esp, 5 is ebp
+ // lldb will get the darwin-specific eh_frame reg numberings from debugserver instead of here so we
+ // only encode the 4 == esp, 5 == ebp numbers in this generic header.
+ gcc_esp_i386,
+ gcc_ebp_i386,
+ gcc_esi_i386,
+ gcc_edi_i386,
+ gcc_eip_i386,
+ gcc_eflags_i386,
+ gcc_st0_i386 = 12,
+ gcc_st1_i386,
+ gcc_st2_i386,
+ gcc_st3_i386,
+ gcc_st4_i386,
+ gcc_st5_i386,
+ gcc_st6_i386,
+ gcc_st7_i386,
+ gcc_xmm0_i386 = 21,
+ gcc_xmm1_i386,
+ gcc_xmm2_i386,
+ gcc_xmm3_i386,
+ gcc_xmm4_i386,
+ gcc_xmm5_i386,
+ gcc_xmm6_i386,
+ gcc_xmm7_i386,
+ gcc_mm0_i386 = 29,
+ gcc_mm1_i386,
+ gcc_mm2_i386,
+ gcc_mm3_i386,
+ gcc_mm4_i386,
+ gcc_mm5_i386,
+ gcc_mm6_i386,
+ gcc_mm7_i386,
+};
+
+// DWARF register numbers (eRegisterKindDWARF)
+// Intel's x86 or IA-32
+enum
+{
+ // General Purpose Registers.
+ dwarf_eax_i386 = 0,
+ dwarf_ecx_i386,
+ dwarf_edx_i386,
+ dwarf_ebx_i386,
+ dwarf_esp_i386,
+ dwarf_ebp_i386,
+ dwarf_esi_i386,
+ dwarf_edi_i386,
+ dwarf_eip_i386,
+ dwarf_eflags_i386,
+ // Floating Point Registers
+ dwarf_st0_i386 = 11,
+ dwarf_st1_i386,
+ dwarf_st2_i386,
+ dwarf_st3_i386,
+ dwarf_st4_i386,
+ dwarf_st5_i386,
+ dwarf_st6_i386,
+ dwarf_st7_i386,
+ // SSE Registers
+ dwarf_xmm0_i386 = 21,
+ dwarf_xmm1_i386,
+ dwarf_xmm2_i386,
+ dwarf_xmm3_i386,
+ dwarf_xmm4_i386,
+ dwarf_xmm5_i386,
+ dwarf_xmm6_i386,
+ dwarf_xmm7_i386,
+ // MMX Registers
+ dwarf_mm0_i386 = 29,
+ dwarf_mm1_i386,
+ dwarf_mm2_i386,
+ dwarf_mm3_i386,
+ dwarf_mm4_i386,
+ dwarf_mm5_i386,
+ dwarf_mm6_i386,
+ dwarf_mm7_i386,
+ dwarf_fctrl_i386 = 37, // x87 control word
+ dwarf_fstat_i386 = 38, // x87 status word
+ dwarf_mxcsr_i386 = 39,
+ dwarf_es_i386 = 40,
+ dwarf_cs_i386 = 41,
+ dwarf_ss_i386 = 42,
+ dwarf_ds_i386 = 43,
+ dwarf_fs_i386 = 44,
+ dwarf_gs_i386 = 45
+
+ // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
+ // then differentiate based on size of the register.
+};
+
+// Register numbers GDB uses (eRegisterKindGDB)
+//
+// From Jason Molenda: The "gdb numbers" are what you would see in the stabs debug format.
+enum
+{
+ gdb_eax_i386,
+ gdb_ecx_i386,
+ gdb_edx_i386,
+ gdb_ebx_i386,
+ gdb_esp_i386,
+ gdb_ebp_i386,
+ gdb_esi_i386,
+ gdb_edi_i386,
+ gdb_eip_i386,
+ gdb_eflags_i386,
+ gdb_cs_i386,
+ gdb_ss_i386,
+ gdb_ds_i386,
+ gdb_es_i386,
+ gdb_fs_i386,
+ gdb_gs_i386,
+ gdb_st0_i386 = 16,
+ gdb_st1_i386,
+ gdb_st2_i386,
+ gdb_st3_i386,
+ gdb_st4_i386,
+ gdb_st5_i386,
+ gdb_st6_i386,
+ gdb_st7_i386,
+ gdb_fctrl_i386, // FPU Control Word
+ gdb_fstat_i386, // FPU Status Word
+ gdb_ftag_i386, // FPU Tag Word
+ gdb_fiseg_i386, // FPU IP Selector
+ gdb_fioff_i386, // FPU IP Offset
+ gdb_foseg_i386, // FPU Operand Pointer Selector
+ gdb_fooff_i386, // FPU Operand Pointer Offset
+ gdb_fop_i386, // Last Instruction Opcode
+ gdb_xmm0_i386 = 32,
+ gdb_xmm1_i386,
+ gdb_xmm2_i386,
+ gdb_xmm3_i386,
+ gdb_xmm4_i386,
+ gdb_xmm5_i386,
+ gdb_xmm6_i386,
+ gdb_xmm7_i386,
+ gdb_mxcsr_i386 = 40,
+ gdb_ymm0h_i386,
+ gdb_ymm1h_i386,
+ gdb_ymm2h_i386,
+ gdb_ymm3h_i386,
+ gdb_ymm4h_i386,
+ gdb_ymm5h_i386,
+ gdb_ymm6h_i386,
+ gdb_ymm7h_i386,
+ gdb_mm0_i386,
+ gdb_mm1_i386,
+ gdb_mm2_i386,
+ gdb_mm3_i386,
+ gdb_mm4_i386,
+ gdb_mm5_i386,
+ gdb_mm6_i386,
+ gdb_mm7_i386,
+};
+
+//---------------------------------------------------------------------------
+// AMD x86_64, AMD64, Intel EM64T, or Intel 64 gcc, dwarf, gdb enums
+//---------------------------------------------------------------------------
+
+// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF)
+// This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
+// http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
+enum
+{
+ // GP Registers
+ gcc_dwarf_rax_x86_64 = 0,
+ gcc_dwarf_rdx_x86_64,
+ gcc_dwarf_rcx_x86_64,
+ gcc_dwarf_rbx_x86_64,
+ gcc_dwarf_rsi_x86_64,
+ gcc_dwarf_rdi_x86_64,
+ gcc_dwarf_rbp_x86_64,
+ gcc_dwarf_rsp_x86_64,
+ // Extended GP Registers
+ gcc_dwarf_r8_x86_64 = 8,
+ gcc_dwarf_r9_x86_64,
+ gcc_dwarf_r10_x86_64,
+ gcc_dwarf_r11_x86_64,
+ gcc_dwarf_r12_x86_64,
+ gcc_dwarf_r13_x86_64,
+ gcc_dwarf_r14_x86_64,
+ gcc_dwarf_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ gcc_dwarf_rip_x86_64 = 16,
+ // SSE Vector Registers
+ gcc_dwarf_xmm0_x86_64 = 17,
+ gcc_dwarf_xmm1_x86_64,
+ gcc_dwarf_xmm2_x86_64,
+ gcc_dwarf_xmm3_x86_64,
+ gcc_dwarf_xmm4_x86_64,
+ gcc_dwarf_xmm5_x86_64,
+ gcc_dwarf_xmm6_x86_64,
+ gcc_dwarf_xmm7_x86_64,
+ gcc_dwarf_xmm8_x86_64,
+ gcc_dwarf_xmm9_x86_64,
+ gcc_dwarf_xmm10_x86_64,
+ gcc_dwarf_xmm11_x86_64,
+ gcc_dwarf_xmm12_x86_64,
+ gcc_dwarf_xmm13_x86_64,
+ gcc_dwarf_xmm14_x86_64,
+ gcc_dwarf_xmm15_x86_64,
+ // Floating Point Registers
+ gcc_dwarf_st0_x86_64 = 33,
+ gcc_dwarf_st1_x86_64,
+ gcc_dwarf_st2_x86_64,
+ gcc_dwarf_st3_x86_64,
+ gcc_dwarf_st4_x86_64,
+ gcc_dwarf_st5_x86_64,
+ gcc_dwarf_st6_x86_64,
+ gcc_dwarf_st7_x86_64,
+ // MMX Registers
+ gcc_dwarf_mm0_x86_64 = 41,
+ gcc_dwarf_mm1_x86_64,
+ gcc_dwarf_mm2_x86_64,
+ gcc_dwarf_mm3_x86_64,
+ gcc_dwarf_mm4_x86_64,
+ gcc_dwarf_mm5_x86_64,
+ gcc_dwarf_mm6_x86_64,
+ gcc_dwarf_mm7_x86_64,
+ // Control and Status Flags Register
+ gcc_dwarf_rflags_x86_64 = 49,
+ // selector registers
+ gcc_dwarf_es_x86_64 = 50,
+ gcc_dwarf_cs_x86_64,
+ gcc_dwarf_ss_x86_64,
+ gcc_dwarf_ds_x86_64,
+ gcc_dwarf_fs_x86_64,
+ gcc_dwarf_gs_x86_64,
+ // Floating point control registers
+ gcc_dwarf_mxcsr_x86_64 = 64, // Media Control and Status
+ gcc_dwarf_fctrl_x86_64, // x87 control word
+ gcc_dwarf_fstat_x86_64, // x87 status word
+ // Upper Vector Registers
+ gcc_dwarf_ymm0h_x86_64 = 67,
+ gcc_dwarf_ymm1h_x86_64,
+ gcc_dwarf_ymm2h_x86_64,
+ gcc_dwarf_ymm3h_x86_64,
+ gcc_dwarf_ymm4h_x86_64,
+ gcc_dwarf_ymm5h_x86_64,
+ gcc_dwarf_ymm6h_x86_64,
+ gcc_dwarf_ymm7h_x86_64,
+ gcc_dwarf_ymm8h_x86_64,
+ gcc_dwarf_ymm9h_x86_64,
+ gcc_dwarf_ymm10h_x86_64,
+ gcc_dwarf_ymm11h_x86_64,
+ gcc_dwarf_ymm12h_x86_64,
+ gcc_dwarf_ymm13h_x86_64,
+ gcc_dwarf_ymm14h_x86_64,
+ gcc_dwarf_ymm15h_x86_64,
+ // AVX2 Vector Mask Registers
+ // gcc_dwarf_k0_x86_64 = 118,
+ // gcc_dwarf_k1_x86_64,
+ // gcc_dwarf_k2_x86_64,
+ // gcc_dwarf_k3_x86_64,
+ // gcc_dwarf_k4_x86_64,
+ // gcc_dwarf_k5_x86_64,
+ // gcc_dwarf_k6_x86_64,
+ // gcc_dwarf_k7_x86_64,
+};
+
+// GDB Register numbers (eRegisterKindGDB)
+enum
+{
+ // GP Registers
+ gdb_rax_x86_64 = 0,
+ gdb_rbx_x86_64,
+ gdb_rcx_x86_64,
+ gdb_rdx_x86_64,
+ gdb_rsi_x86_64,
+ gdb_rdi_x86_64,
+ gdb_rbp_x86_64,
+ gdb_rsp_x86_64,
+ // Extended GP Registers
+ gdb_r8_x86_64,
+ gdb_r9_x86_64,
+ gdb_r10_x86_64,
+ gdb_r11_x86_64,
+ gdb_r12_x86_64,
+ gdb_r13_x86_64,
+ gdb_r14_x86_64,
+ gdb_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ gdb_rip_x86_64,
+ // Control and Status Flags Register
+ gdb_rflags_x86_64,
+ gdb_cs_x86_64,
+ gdb_ss_x86_64,
+ gdb_ds_x86_64,
+ gdb_es_x86_64,
+ gdb_fs_x86_64,
+ gdb_gs_x86_64,
+ // Floating Point Registers
+ gdb_st0_x86_64,
+ gdb_st1_x86_64,
+ gdb_st2_x86_64,
+ gdb_st3_x86_64,
+ gdb_st4_x86_64,
+ gdb_st5_x86_64,
+ gdb_st6_x86_64,
+ gdb_st7_x86_64,
+ gdb_fctrl_x86_64,
+ gdb_fstat_x86_64,
+ gdb_ftag_x86_64,
+ gdb_fiseg_x86_64,
+ gdb_fioff_x86_64,
+ gdb_foseg_x86_64,
+ gdb_fooff_x86_64,
+ gdb_fop_x86_64,
+ // SSE Vector Registers
+ gdb_xmm0_x86_64 = 40,
+ gdb_xmm1_x86_64,
+ gdb_xmm2_x86_64,
+ gdb_xmm3_x86_64,
+ gdb_xmm4_x86_64,
+ gdb_xmm5_x86_64,
+ gdb_xmm6_x86_64,
+ gdb_xmm7_x86_64,
+ gdb_xmm8_x86_64,
+ gdb_xmm9_x86_64,
+ gdb_xmm10_x86_64,
+ gdb_xmm11_x86_64,
+ gdb_xmm12_x86_64,
+ gdb_xmm13_x86_64,
+ gdb_xmm14_x86_64,
+ gdb_xmm15_x86_64,
+ // Floating point control registers
+ gdb_mxcsr_x86_64 = 56,
+ gdb_ymm0h_x86_64,
+ gdb_ymm1h_x86_64,
+ gdb_ymm2h_x86_64,
+ gdb_ymm3h_x86_64,
+ gdb_ymm4h_x86_64,
+ gdb_ymm5h_x86_64,
+ gdb_ymm6h_x86_64,
+ gdb_ymm7h_x86_64,
+ gdb_ymm8h_x86_64,
+ gdb_ymm9h_x86_64,
+ gdb_ymm10h_x86_64,
+ gdb_ymm11h_x86_64,
+ gdb_ymm12h_x86_64,
+ gdb_ymm13h_x86_64,
+ gdb_ymm14h_x86_64,
+ gdb_ymm15h_x86_64
+};
+
+//---------------------------------------------------------------------------
+// Generic floating-point registers
+//---------------------------------------------------------------------------
+
+struct MMSReg
+{
+ uint8_t bytes[10];
+ uint8_t pad[6];
+};
+
+struct XMMReg
+{
+ uint8_t bytes[16]; // 128-bits for each XMM register
+};
+
+// i387_fxsave_struct
+struct FXSAVE
+{
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint16_t ftag; // FPU Tag Word (ftw)
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union
+ {
+ struct
+ {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct
+ {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_;// Added _ in the end to avoid error with gcc defining i386 in some cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
+ uint32_t padding[24];
+};
+
+//---------------------------------------------------------------------------
+// Extended floating-point registers
+//---------------------------------------------------------------------------
+
+struct YMMHReg
+{
+ uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+};
+
+struct YMMReg
+{
+ uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+};
+
+struct YMM
+{
+ YMMReg ymm[16]; // assembled from ymmh and xmm registers
+};
+
+struct XSAVE_HDR
+{
+ uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states supported by the processor
+ uint64_t reserved1[2];
+ uint64_t reserved2[5];
+} __attribute__((packed));
+
+// x86 extensions to FXSAVE (i.e. for AVX processors)
+struct XSAVE
+{
+ FXSAVE i387; // floating point registers typical in i387_fxsave_struct
+ XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the following extensions are usable
+ YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
+ // Slot any extensions to the register file here
+} __attribute__((packed, aligned (64)));
+
+// Floating-point registers
+struct FPR
+{
+ // Thread state for the floating-point unit of the processor read by ptrace.
+ union XSTATE
+ {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
+ } xstate;
+};
+
+//---------------------------------------------------------------------------
+// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
+//---------------------------------------------------------------------------
+
+struct IOVEC
+{
+ void *iov_base; // pointer to XSAVE
+ size_t iov_len; // sizeof(XSAVE)
+};
+
+#endif