diff options
Diffstat (limited to 'source/Plugins/Process/POSIX/RegisterContext_x86.h')
-rw-r--r-- | source/Plugins/Process/POSIX/RegisterContext_x86.h | 541 |
1 files changed, 455 insertions, 86 deletions
diff --git a/source/Plugins/Process/POSIX/RegisterContext_x86.h b/source/Plugins/Process/POSIX/RegisterContext_x86.h index 61a25c407758..df3e1e5a84bf 100644 --- a/source/Plugins/Process/POSIX/RegisterContext_x86.h +++ b/source/Plugins/Process/POSIX/RegisterContext_x86.h @@ -1,4 +1,4 @@ -//===-- RegisterContext_x86.h ---------------------------*- C++ -*-===// +//===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,101 +10,470 @@ #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, + gcc_ebp_i386, // Warning: these are switched from dwarf values + gcc_esp_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 { - gcc_eax = 0, - gcc_ecx, - gcc_edx, - gcc_ebx, - gcc_ebp, - gcc_esp, - gcc_esi, - gcc_edi, - gcc_eip, - gcc_eflags + // 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 { - dwarf_eax = 0, - dwarf_ecx, - dwarf_edx, - dwarf_ebx, - dwarf_esp, - dwarf_ebp, - dwarf_esi, - dwarf_edi, - dwarf_eip, - dwarf_eflags, - dwarf_stmm0 = 11, - dwarf_stmm1, - dwarf_stmm2, - dwarf_stmm3, - dwarf_stmm4, - dwarf_stmm5, - dwarf_stmm6, - dwarf_stmm7, - dwarf_xmm0 = 21, - dwarf_xmm1, - dwarf_xmm2, - dwarf_xmm3, - dwarf_xmm4, - dwarf_xmm5, - dwarf_xmm6, - dwarf_xmm7 + 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 { - gdb_eax = 0, - gdb_ecx = 1, - gdb_edx = 2, - gdb_ebx = 3, - gdb_esp = 4, - gdb_ebp = 5, - gdb_esi = 6, - gdb_edi = 7, - gdb_eip = 8, - gdb_eflags = 9, - gdb_cs = 10, - gdb_ss = 11, - gdb_ds = 12, - gdb_es = 13, - gdb_fs = 14, - gdb_gs = 15, - gdb_stmm0 = 16, - gdb_stmm1 = 17, - gdb_stmm2 = 18, - gdb_stmm3 = 19, - gdb_stmm4 = 20, - gdb_stmm5 = 21, - gdb_stmm6 = 22, - gdb_stmm7 = 23, - gdb_fcw = 24, - gdb_fsw = 25, - gdb_ftw = 26, - gdb_fpu_cs = 27, - gdb_ip = 28, - gdb_fpu_ds = 29, - gdb_dp = 30, - gdb_fop = 31, - gdb_xmm0 = 32, - gdb_xmm1 = 33, - gdb_xmm2 = 34, - gdb_xmm3 = 35, - gdb_xmm4 = 36, - gdb_xmm5 = 37, - gdb_xmm6 = 38, - gdb_xmm7 = 39, - gdb_mxcsr = 40, - gdb_mm0 = 41, - gdb_mm1 = 42, - gdb_mm2 = 43, - gdb_mm3 = 44, - gdb_mm4 = 45, - gdb_mm5 = 46, - gdb_mm6 = 47, - gdb_mm7 = 48 + // 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; + } 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 |