//===-- 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, 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 { // 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; } 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