diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h @@ -51,6 +51,8 @@ std::optional GetMmapData() override; + const RegisterInfo *GetDR(int num) const override; + protected: void *GetGPRBuffer() override { return &m_gpr_x86_64; } @@ -104,7 +106,7 @@ YMM m_ymm_set; MPX m_mpx_set; RegInfo m_reg_info; - uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64]; + uint64_t m_gpr_x86_64[x86_64_with_base::k_num_gpr_registers]; uint32_t m_fctrl_offset_in_userarea; // Private member methods. diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -100,96 +100,97 @@ // x86 64-bit general purpose registers. static const uint32_t g_gpr_regnums_x86_64[] = { - lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, - lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64, - lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64, - lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64, - lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64, - lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64, - lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64, - lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64, - lldb_r8d_x86_64, // Low 32 bits or r8 - lldb_r9d_x86_64, // Low 32 bits or r9 - lldb_r10d_x86_64, // Low 32 bits or r10 - lldb_r11d_x86_64, // Low 32 bits or r11 - lldb_r12d_x86_64, // Low 32 bits or r12 - lldb_r13d_x86_64, // Low 32 bits or r13 - lldb_r14d_x86_64, // Low 32 bits or r14 - lldb_r15d_x86_64, // Low 32 bits or r15 - lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64, - lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64, - lldb_r8w_x86_64, // Low 16 bits or r8 - lldb_r9w_x86_64, // Low 16 bits or r9 - lldb_r10w_x86_64, // Low 16 bits or r10 - lldb_r11w_x86_64, // Low 16 bits or r11 - lldb_r12w_x86_64, // Low 16 bits or r12 - lldb_r13w_x86_64, // Low 16 bits or r13 - lldb_r14w_x86_64, // Low 16 bits or r14 - lldb_r15w_x86_64, // Low 16 bits or r15 - lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64, - lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64, - lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64, - lldb_r8l_x86_64, // Low 8 bits or r8 - lldb_r9l_x86_64, // Low 8 bits or r9 - lldb_r10l_x86_64, // Low 8 bits or r10 - lldb_r11l_x86_64, // Low 8 bits or r11 - lldb_r12l_x86_64, // Low 8 bits or r12 - lldb_r13l_x86_64, // Low 8 bits or r13 - lldb_r14l_x86_64, // Low 8 bits or r14 - lldb_r15l_x86_64, // Low 8 bits or r15 + x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_rdx, + x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_rsp, + x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r11, + x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r15, + x86_64_with_base::lldb_rip, x86_64_with_base::lldb_rflags, x86_64_with_base::lldb_cs, x86_64_with_base::lldb_fs, + x86_64_with_base::lldb_gs, x86_64_with_base::lldb_ss, x86_64_with_base::lldb_fs_base, x86_64_with_base::lldb_gs_base, + x86_64_with_base::lldb_ds, x86_64_with_base::lldb_es, + x86_64_with_base::lldb_eax, x86_64_with_base::lldb_ebx, x86_64_with_base::lldb_ecx, x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_edi, x86_64_with_base::lldb_esi, x86_64_with_base::lldb_ebp, x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_r8d, // Low 32 bits or r8 + x86_64_with_base::lldb_r9d, // Low 32 bits or r9 + x86_64_with_base::lldb_r10d, // Low 32 bits or r10 + x86_64_with_base::lldb_r11d, // Low 32 bits or r11 + x86_64_with_base::lldb_r12d, // Low 32 bits or r12 + x86_64_with_base::lldb_r13d, // Low 32 bits or r13 + x86_64_with_base::lldb_r14d, // Low 32 bits or r14 + x86_64_with_base::lldb_r15d, // Low 32 bits or r15 + x86_64_with_base::lldb_ax, x86_64_with_base::lldb_bx, x86_64_with_base::lldb_cx, x86_64_with_base::lldb_dx, + x86_64_with_base::lldb_di, x86_64_with_base::lldb_si, x86_64_with_base::lldb_bp, x86_64_with_base::lldb_sp, + x86_64_with_base::lldb_r8w, // Low 16 bits or r8 + x86_64_with_base::lldb_r9w, // Low 16 bits or r9 + x86_64_with_base::lldb_r10w, // Low 16 bits or r10 + x86_64_with_base::lldb_r11w, // Low 16 bits or r11 + x86_64_with_base::lldb_r12w, // Low 16 bits or r12 + x86_64_with_base::lldb_r13w, // Low 16 bits or r13 + x86_64_with_base::lldb_r14w, // Low 16 bits or r14 + x86_64_with_base::lldb_r15w, // Low 16 bits or r15 + x86_64_with_base::lldb_ah, x86_64_with_base::lldb_bh, x86_64_with_base::lldb_ch, x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_al, x86_64_with_base::lldb_bl, x86_64_with_base::lldb_cl, x86_64_with_base::lldb_dl, + x86_64_with_base::lldb_dil, x86_64_with_base::lldb_sil, x86_64_with_base::lldb_bpl, x86_64_with_base::lldb_spl, + x86_64_with_base::lldb_r8l, // Low 8 bits or r8 + x86_64_with_base::lldb_r9l, // Low 8 bits or r9 + x86_64_with_base::lldb_r10l, // Low 8 bits or r10 + x86_64_with_base::lldb_r11l, // Low 8 bits or r11 + x86_64_with_base::lldb_r12l, // Low 8 bits or r12 + x86_64_with_base::lldb_r13l, // Low 8 bits or r13 + x86_64_with_base::lldb_r14l, // Low 8 bits or r14 + x86_64_with_base::lldb_r15l, // Low 8 bits or r15 LLDB_INVALID_REGNUM // register sets need to end with this flag }; static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == - k_num_gpr_registers_x86_64, + x86_64_with_base::k_num_gpr_registers, "g_gpr_regnums_x86_64 has wrong number of register infos"); // x86 64-bit floating point registers. static const uint32_t g_fpu_regnums_x86_64[] = { - lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, - lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, - lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64, - lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, - lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64, - lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, - lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64, - lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64, - lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64, - lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64, - lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64, - lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64, - lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64, - lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64, - lldb_xmm14_x86_64, lldb_xmm15_x86_64, + x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat, x86_64_with_base::lldb_ftag, + x86_64_with_base::lldb_fop, x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg, x86_64_with_base::lldb_fooff, + x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask, + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1, x86_64_with_base::lldb_st2, + x86_64_with_base::lldb_st3, x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5, + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm0, + x86_64_with_base::lldb_mm1, x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3, + x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5, x86_64_with_base::lldb_mm6, + x86_64_with_base::lldb_mm7, x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1, + x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3, x86_64_with_base::lldb_xmm4, + x86_64_with_base::lldb_xmm5, x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7, + x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9, x86_64_with_base::lldb_xmm10, + x86_64_with_base::lldb_xmm11, x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13, + x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15, LLDB_INVALID_REGNUM // register sets need to end with this flag }; static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 1 == - k_num_fpr_registers_x86_64, + x86_64_with_base::k_num_fpr_registers, "g_fpu_regnums_x86_64 has wrong number of register infos"); // x86 64-bit AVX registers. static const uint32_t g_avx_regnums_x86_64[] = { - lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64, - lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64, - lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64, - lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64, + x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1, x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3, + x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5, x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7, + x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9, x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11, + x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13, x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15, LLDB_INVALID_REGNUM // register sets need to end with this flag }; static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == - k_num_avx_registers_x86_64, + x86_64_with_base::k_num_avx_registers, "g_avx_regnums_x86_64 has wrong number of register infos"); // x86 64-bit MPX registers. static const uint32_t g_mpx_regnums_x86_64[] = { - lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, - lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64, + x86_64_with_base::lldb_bnd0, x86_64_with_base::lldb_bnd1, x86_64_with_base::lldb_bnd2, + x86_64_with_base::lldb_bnd3, x86_64_with_base::lldb_bndcfgu, x86_64_with_base::lldb_bndstatus, LLDB_INVALID_REGNUM // register sets need to end with this flag }; static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) - 1 == - k_num_mpx_registers_x86_64, + x86_64_with_base::k_num_mpx_registers, "g_mpx_regnums_x86_64 has wrong number of register infos"); // Number of register sets provided by this context. @@ -208,13 +209,13 @@ // Register sets for x86 64-bit. static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, + {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers, g_gpr_regnums_x86_64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, + {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers, g_fpu_regnums_x86_64}, - {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, + {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers, g_avx_regnums_x86_64}, - { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64, + { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers, g_mpx_regnums_x86_64}}; #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR)) @@ -330,29 +331,29 @@ m_reg_info.gpr_flags = lldb_eflags_i386; break; case llvm::Triple::x86_64: - m_reg_info.num_registers = k_num_registers_x86_64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64; - m_reg_info.num_avx_registers = k_num_avx_registers_x86_64; - m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64; - m_reg_info.last_gpr = k_last_gpr_x86_64; - m_reg_info.first_fpr = k_first_fpr_x86_64; - m_reg_info.last_fpr = k_last_fpr_x86_64; - m_reg_info.first_st = lldb_st0_x86_64; - m_reg_info.last_st = lldb_st7_x86_64; - m_reg_info.first_mm = lldb_mm0_x86_64; - m_reg_info.last_mm = lldb_mm7_x86_64; - m_reg_info.first_xmm = lldb_xmm0_x86_64; - m_reg_info.last_xmm = lldb_xmm15_x86_64; - m_reg_info.first_ymm = lldb_ymm0_x86_64; - m_reg_info.last_ymm = lldb_ymm15_x86_64; - m_reg_info.first_mpxr = lldb_bnd0_x86_64; - m_reg_info.last_mpxr = lldb_bnd3_x86_64; - m_reg_info.first_mpxc = lldb_bndcfgu_x86_64; - m_reg_info.last_mpxc = lldb_bndstatus_x86_64; - m_reg_info.first_dr = lldb_dr0_x86_64; - m_reg_info.last_dr = lldb_dr7_x86_64; - m_reg_info.gpr_flags = lldb_rflags_x86_64; + m_reg_info.num_registers = x86_64_with_base::k_num_registers; + m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers; + m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers; + m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers; + m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers; + m_reg_info.last_gpr = x86_64_with_base::k_last_gpr; + m_reg_info.first_fpr = x86_64_with_base::k_first_fpr; + m_reg_info.last_fpr = x86_64_with_base::k_last_fpr; + m_reg_info.first_st = x86_64_with_base::lldb_st0; + m_reg_info.last_st = x86_64_with_base::lldb_st7; + m_reg_info.first_mm = x86_64_with_base::lldb_mm0; + m_reg_info.last_mm = x86_64_with_base::lldb_mm7; + m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0; + m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15; + m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0; + m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15; + m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0; + m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3; + m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu; + m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus; + m_reg_info.first_dr = x86_64_with_base::lldb_dr0; + m_reg_info.last_dr = x86_64_with_base::lldb_dr7; + m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags; break; default: assert(false && "Unhandled target architecture."); @@ -1048,9 +1049,9 @@ case llvm::Triple::x86_64: { static const uint8_t Syscall[] = {0x0f, 0x05}; static const uint32_t Args[] = { - lldb_rax_x86_64, lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rdx_x86_64, - lldb_r10_x86_64, lldb_r8_x86_64, lldb_r9_x86_64}; - return SyscallData{Syscall, Args, lldb_rax_x86_64}; + x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx, + x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9}; + return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax}; } default: llvm_unreachable("Unhandled architecture!"); @@ -1069,4 +1070,16 @@ } } +const RegisterInfo *NativeRegisterContextLinux_x86_64::GetDR(int num) const { + assert(num >= 0 && num <= 7); + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfoAtIndex(lldb_dr0_i386 + num); + case llvm::Triple::x86_64: + return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num); + default: + llvm_unreachable("Unhandled target architecture."); + } +} + #endif // defined(__i386__) || defined(__x86_64__) diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -47,6 +47,7 @@ RegisterContextThreadMemory.cpp RegisterContextWindows_i386.cpp RegisterContextWindows_x86_64.cpp + RegisterInfos_x86_64_with_base_shared.cpp RegisterInfoPOSIX_arm.cpp RegisterInfoPOSIX_arm64.cpp RegisterInfoPOSIX_loongarch64.cpp diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h --- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h +++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h @@ -46,7 +46,7 @@ uint32_t NumSupportedHardwareWatchpoints() override; - const RegisterInfo *GetDR(int num) const; + virtual const RegisterInfo *GetDR(int num) const; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp --- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -75,10 +75,10 @@ (LLVM_EXTENSION offsetof(UserArea, dbg) + \ LLVM_EXTENSION offsetof(DBG, dr[reg_index])) -// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 +// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64_with_base // structure. #define DECLARE_REGISTER_INFOS_X86_64_STRUCT -#include "RegisterInfos_x86_64.h" +#include "RegisterInfos_x86_64_with_base.h" #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT static std::vector &GetPrivateRegisterInfoVector() { @@ -103,7 +103,7 @@ // Include RegisterInfos_x86_64 to update the g_register_infos structure // with x86_64 offsets. #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS -#include "RegisterInfos_x86_64.h" +#include "RegisterInfos_x86_64_with_base.h" #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS } @@ -115,7 +115,7 @@ case llvm::Triple::x86: return GetRegisterInfo_i386(target_arch); case llvm::Triple::x86_64: - return g_register_infos_x86_64; + return g_register_infos_x86_64_with_base; default: assert(false && "Unhandled target architecture."); return nullptr; @@ -130,8 +130,8 @@ return static_cast(GetPrivateRegisterInfoVector().size()); } case llvm::Triple::x86_64: - return static_cast(sizeof(g_register_infos_x86_64) / - sizeof(g_register_infos_x86_64[0])); + return static_cast(sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])); default: assert(false && "Unhandled target architecture."); return 0; @@ -143,7 +143,7 @@ case llvm::Triple::x86: return static_cast(k_num_user_registers_i386); case llvm::Triple::x86_64: - return static_cast(k_num_user_registers_x86_64); + return static_cast(x86_64_with_base::k_num_user_registers); default: assert(false && "Unhandled target architecture."); return 0; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -11,6 +11,7 @@ #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" +#include "RegisterInfos_x86_64_with_base_shared.h" #include "lldb-x86-register-enums.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" @@ -149,34 +150,6 @@ static uint32_t g_invalidate_st7_64[]; protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - uint32_t num_avx_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_st; - uint32_t last_st; - uint32_t first_mm; - uint32_t last_mm; - uint32_t first_xmm; - uint32_t last_xmm; - uint32_t first_ymm; - uint32_t last_ymm; - - uint32_t first_dr; - uint32_t gpr_flags; - }; - - uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit - // general - // purpose - // registers. - RegInfo m_reg_info; FPRType m_fpr_type; // determines the type of data stored by union FPR, if any. lldb_private::FPR m_fpr; // floating-point registers including extended @@ -206,6 +179,7 @@ virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; + virtual lldb_private::RegInfo &GetRegInfo(); }; #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -374,15 +374,15 @@ g_avx_regnums_x86_64}}; bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) { - return reg <= m_reg_info.last_gpr; // GPR's come first. + return reg <= GetRegInfo().last_gpr; // GPR's come first. } bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + return (GetRegInfo().first_fpr <= reg && reg <= GetRegInfo().last_fpr); } bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) { - return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm); + return (GetRegInfo().first_ymm <= reg && reg <= GetRegInfo().last_ymm); } bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) { @@ -399,50 +399,6 @@ : RegisterContext(thread, concrete_frame_idx) { m_register_info_up.reset(register_info); - switch (register_info->GetTargetArchitecture().GetMachine()) { - case llvm::Triple::x86: - m_reg_info.num_registers = k_num_registers_i386; - m_reg_info.num_gpr_registers = k_num_gpr_registers_i386; - m_reg_info.num_fpr_registers = k_num_fpr_registers_i386; - m_reg_info.num_avx_registers = k_num_avx_registers_i386; - m_reg_info.last_gpr = k_last_gpr_i386; - m_reg_info.first_fpr = k_first_fpr_i386; - m_reg_info.last_fpr = k_last_fpr_i386; - m_reg_info.first_st = lldb_st0_i386; - m_reg_info.last_st = lldb_st7_i386; - m_reg_info.first_mm = lldb_mm0_i386; - m_reg_info.last_mm = lldb_mm7_i386; - m_reg_info.first_xmm = lldb_xmm0_i386; - m_reg_info.last_xmm = lldb_xmm7_i386; - m_reg_info.first_ymm = lldb_ymm0_i386; - m_reg_info.last_ymm = lldb_ymm7_i386; - m_reg_info.first_dr = lldb_dr0_i386; - m_reg_info.gpr_flags = lldb_eflags_i386; - break; - case llvm::Triple::x86_64: - m_reg_info.num_registers = k_num_registers_x86_64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64; - m_reg_info.num_avx_registers = k_num_avx_registers_x86_64; - m_reg_info.last_gpr = k_last_gpr_x86_64; - m_reg_info.first_fpr = k_first_fpr_x86_64; - m_reg_info.last_fpr = k_last_fpr_x86_64; - m_reg_info.first_st = lldb_st0_x86_64; - m_reg_info.last_st = lldb_st7_x86_64; - m_reg_info.first_mm = lldb_mm0_x86_64; - m_reg_info.last_mm = lldb_mm7_x86_64; - m_reg_info.first_xmm = lldb_xmm0_x86_64; - m_reg_info.last_xmm = lldb_xmm15_x86_64; - m_reg_info.first_ymm = lldb_ymm0_x86_64; - m_reg_info.last_ymm = lldb_ymm15_x86_64; - m_reg_info.first_dr = lldb_dr0_x86_64; - m_reg_info.gpr_flags = lldb_rflags_x86_64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } - ::memset(&m_fpr, 0, sizeof(FPR)); ::memset(&m_ymm_set, 0, sizeof(YMM)); @@ -466,20 +422,26 @@ void RegisterContextPOSIX_x86::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); + assert(reg < GetRegInfo().num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_offset; } +RegInfo &RegisterContextPOSIX_x86::GetRegInfo() { + return GetRegInfoShared( + m_register_info_up->GetTargetArchitecture().GetMachine(), + /*with_base=*/false); +} + unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); + assert(reg < GetRegInfo().num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_size; } size_t RegisterContextPOSIX_x86::GetRegisterCount() { size_t num_registers = - m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; + GetRegInfo().num_gpr_registers + GetRegInfo().num_fpr_registers; if (GetFPRType() == eXSAVE) - return num_registers + m_reg_info.num_avx_registers; + return num_registers + GetRegInfo().num_avx_registers; return num_registers; } @@ -488,7 +450,7 @@ } size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() { - return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset; + return GetRegisterInfo()[GetRegInfo().first_fpr].byte_offset; } const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() { @@ -500,7 +462,7 @@ const RegisterInfo * RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) { - if (reg < m_reg_info.num_registers) + if (reg < GetRegInfo().num_registers) return &GetRegisterInfo()[reg]; else return nullptr; @@ -532,7 +494,7 @@ } const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register offset."); + assert(reg < GetRegInfo().num_registers && "Invalid register offset."); return GetRegisterInfo()[reg].name; } @@ -543,10 +505,9 @@ return false; if (byte_order == eByteOrderLittle) { - uint32_t reg_no = reg - m_reg_info.first_ymm; - YMMToXState(m_ymm_set.ymm[reg_no], - m_fpr.fxsave.xmm[reg_no].bytes, - m_fpr.xsave.ymmh[reg_no].bytes); + uint32_t reg_no = reg - GetRegInfo().first_ymm; + YMMToXState(m_ymm_set.ymm[reg_no], m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); return true; } @@ -560,10 +521,9 @@ return false; if (byte_order == eByteOrderLittle) { - uint32_t reg_no = reg - m_reg_info.first_ymm; - m_ymm_set.ymm[reg_no] = XStateToYMM( - m_fpr.fxsave.xmm[reg_no].bytes, - m_fpr.xsave.ymmh[reg_no].bytes); + uint32_t reg_no = reg - GetRegInfo().first_ymm; + m_ymm_set.ymm[reg_no] = XStateToYMM(m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); return true; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h --- a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -201,6 +201,9 @@ dwarf_ds_x86_64, dwarf_fs_x86_64, dwarf_gs_x86_64, + // Base registers + dwarf_fs_base_x86_64 = 58, + dwarf_gs_base_x86_64 = 59, // Floating point control registers dwarf_mxcsr_x86_64 = 64, // Media Control and Status dwarf_fctrl_x86_64, // x87 control word diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h @@ -0,0 +1,480 @@ +//===-- RegisterInfos_x86_64_with_base.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterInfos_x86_64_with_base_shared.h" + +// This file is meant to be textually included. Do not #include modular +// headers here. + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, fxsave) + \ + LLVM_EXTENSION offsetof(FXSAVE, regname)) + +// Computes the offset of the YMM register assembled from register halves. +// Based on DNBArchImplX86_64.cpp from debugserver +#define YMM_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) + +// Guarantees BNDR/BNDC offsets do not overlap with YMM offsets. +#define GDB_REMOTE_OFFSET 128 + +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]) + GDB_REMOTE_OFFSET) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]) + GDB_REMOTE_OFFSET) + +#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +// Number of bytes needed to represent a FPR. +#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) + +// Number of bytes needed to represent the i'th FP register. +#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) + +// Number of bytes needed to represent an XMM register. +#define XMM_SIZE sizeof(XMMReg) + +// Number of bytes needed to represent a YMM register. +#define YMM_SIZE sizeof(YMMReg) + +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + +#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0]) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \ + nullptr, nullptr, \ + } + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR_WITH_BASE(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##name}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FP_ST(reg, i) \ + { \ + #reg #i, nullptr, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_st##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FP_MM(reg, i, streg) \ + { \ + #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ + eEncodingUint, eFormatHex, \ + {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_mm##i}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##streg##_64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##streg##_64, \ + nullptr, \ + } + +#define DEFINE_XMM(reg, i) \ + { \ + #reg #i, nullptr, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_YMM(reg, i) \ + { \ + #reg #i, nullptr, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, nullptr, BNDR_SIZE, LLVM_EXTENSION BNDR_OFFSET(i), \ + eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, nullptr, BNDC_SIZE, LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##name}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_DR(reg, i) \ + { \ + #reg #i, nullptr, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ + { \ + #reg32, nullptr, 4, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg32}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ + { \ + #reg16, nullptr, 2, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg16}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr \ + } + +#define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##name}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +// clang-format off +static RegisterInfo g_register_infos_x86_64_with_base[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs_base, nullptr, dwarf_fs_base_x86_64, dwarf_fs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs_base, nullptr, dwarf_gs_base_x86_64, dwarf_gs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx), + DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx), + DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi), + DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp), + DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9), + DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11), + DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13), + DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15), + DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx), + DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx), + DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi), + DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp), + DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9), + DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11), + DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13), + DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15), + DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx), + DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx), + DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx), + DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx), + DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi), + DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp), + DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9), + DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11), + DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13), + DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15), + +// i387 Floating point registers. EH_frame DWARF Generic Process Plugin reg64 +// ====================================== =============== ================== =================== ==================== ===== + DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR_32(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip), + DEFINE_FPR_32(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip), + DEFINE_FPR(fip, ptr.x86_64.fip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR_32(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp), + DEFINE_FPR_32(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp), + DEFINE_FPR(fdp, ptr.x86_64.fdp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + // FP registers. + DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), + DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), + DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), + + DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1), + DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3), + DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5), + DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7), + + // XMM registers + DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), + DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), + DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8), + DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11), + DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14), + DEFINE_XMM(xmm, 15), + + // Copy of YMM registers assembled from xmm and ymmh + DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), + DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), + DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8), + DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11), + DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), + DEFINE_YMM(ymm, 15), + + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + + // Debug registers for lldb internal use + DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), + DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; + +// clang-format on + +static_assert( + (sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])) == + x86_64_with_base::k_num_registers, + "g_register_infos_x86_64_with_base has wrong number of register infos"); + +#undef FPR_SIZE +#undef FP_SIZE +#undef XMM_SIZE +#undef YMM_SIZE +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FP +#undef DEFINE_XMM +#undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC +#undef DEFINE_DR +#undef DEFINE_GPR_PSEUDO_32 +#undef DEFINE_GPR_PSEUDO_16 +#undef DEFINE_GPR_PSEUDO_8H +#undef DEFINE_GPR_PSEUDO_8L + +#endif // DECLARE_REGISTER_INFOS_X86_64_STRUCT + +#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#define UPDATE_GPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_GPR_INFO_8H(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ + } while (false); + +#define UPDATE_FPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_FP_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ + } while (false); + +#define UPDATE_XMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ + } while (false); + +#define UPDATE_YMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \ + } while (false); + +#define UPDATE_DR_INFO(reg_index) \ + do { \ + g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \ + DR_OFFSET(reg_index); \ + } while (false); + +// Update the register offsets +UPDATE_GPR_INFO(eax, rax); +UPDATE_GPR_INFO(ebx, rbx); +UPDATE_GPR_INFO(ecx, rcx); +UPDATE_GPR_INFO(edx, rdx); +UPDATE_GPR_INFO(edi, rdi); +UPDATE_GPR_INFO(esi, rsi); +UPDATE_GPR_INFO(ebp, rbp); +UPDATE_GPR_INFO(esp, rsp); +UPDATE_GPR_INFO(eip, rip); +UPDATE_GPR_INFO(eflags, rflags); +UPDATE_GPR_INFO(cs, cs); +UPDATE_GPR_INFO(fs, fs); +UPDATE_GPR_INFO(gs, gs); +UPDATE_GPR_INFO(ss, ss); +UPDATE_GPR_INFO(ds, ds); +UPDATE_GPR_INFO(es, es); + +UPDATE_GPR_INFO(ax, rax); +UPDATE_GPR_INFO(bx, rbx); +UPDATE_GPR_INFO(cx, rcx); +UPDATE_GPR_INFO(dx, rdx); +UPDATE_GPR_INFO(di, rdi); +UPDATE_GPR_INFO(si, rsi); +UPDATE_GPR_INFO(bp, rbp); +UPDATE_GPR_INFO(sp, rsp); +UPDATE_GPR_INFO_8H(ah, rax); +UPDATE_GPR_INFO_8H(bh, rbx); +UPDATE_GPR_INFO_8H(ch, rcx); +UPDATE_GPR_INFO_8H(dh, rdx); +UPDATE_GPR_INFO(al, rax); +UPDATE_GPR_INFO(bl, rbx); +UPDATE_GPR_INFO(cl, rcx); +UPDATE_GPR_INFO(dl, rdx); + +UPDATE_FPR_INFO(fctrl, fctrl); +UPDATE_FPR_INFO(fstat, fstat); +UPDATE_FPR_INFO(ftag, ftag); +UPDATE_FPR_INFO(fop, fop); +UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg); +UPDATE_FPR_INFO(fioff, ptr.i386_.fioff); +UPDATE_FPR_INFO(fooff, ptr.i386_.fooff); +UPDATE_FPR_INFO(foseg, ptr.i386_.foseg); +UPDATE_FPR_INFO(mxcsr, mxcsr); +UPDATE_FPR_INFO(mxcsrmask, mxcsrmask); + +UPDATE_FP_INFO(st, 0); +UPDATE_FP_INFO(st, 1); +UPDATE_FP_INFO(st, 2); +UPDATE_FP_INFO(st, 3); +UPDATE_FP_INFO(st, 4); +UPDATE_FP_INFO(st, 5); +UPDATE_FP_INFO(st, 6); +UPDATE_FP_INFO(st, 7); +UPDATE_FP_INFO(mm, 0); +UPDATE_FP_INFO(mm, 1); +UPDATE_FP_INFO(mm, 2); +UPDATE_FP_INFO(mm, 3); +UPDATE_FP_INFO(mm, 4); +UPDATE_FP_INFO(mm, 5); +UPDATE_FP_INFO(mm, 6); +UPDATE_FP_INFO(mm, 7); + +UPDATE_XMM_INFO(xmm, 0); +UPDATE_XMM_INFO(xmm, 1); +UPDATE_XMM_INFO(xmm, 2); +UPDATE_XMM_INFO(xmm, 3); +UPDATE_XMM_INFO(xmm, 4); +UPDATE_XMM_INFO(xmm, 5); +UPDATE_XMM_INFO(xmm, 6); +UPDATE_XMM_INFO(xmm, 7); + +UPDATE_YMM_INFO(ymm, 0); +UPDATE_YMM_INFO(ymm, 1); +UPDATE_YMM_INFO(ymm, 2); +UPDATE_YMM_INFO(ymm, 3); +UPDATE_YMM_INFO(ymm, 4); +UPDATE_YMM_INFO(ymm, 5); +UPDATE_YMM_INFO(ymm, 6); +UPDATE_YMM_INFO(ymm, 7); + +UPDATE_DR_INFO(0); +UPDATE_DR_INFO(1); +UPDATE_DR_INFO(2); +UPDATE_DR_INFO(3); +UPDATE_DR_INFO(4); +UPDATE_DR_INFO(5); +UPDATE_DR_INFO(6); +UPDATE_DR_INFO(7); + +#undef UPDATE_GPR_INFO +#undef UPDATE_GPR_INFO_8H +#undef UPDATE_FPR_INFO +#undef UPDATE_FP_INFO +#undef UPDATE_XMM_INFO +#undef UPDATE_YMM_INFO +#undef UPDATE_DR_INFO + +#endif // UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef YMM_OFFSET diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h copy from lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h copy to lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_x86.h ------------------------------*- C++ -*-===// +//===-- RegisterInfos_x86_64_with_base_shared.h -----------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,54 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" +#include -#include "RegisterContext_x86.h" -#include "RegisterInfoInterface.h" -#include "lldb-x86-register-enums.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Utility/Log.h" +#ifndef lldb_RegisterInfos_x86_64_with_base_shared_h +#define lldb_RegisterInfos_x86_64_with_base_shared_h -class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext { -public: - RegisterContextPOSIX_x86(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); +#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" - ~RegisterContextPOSIX_x86() override; - - void Invalidate(); - - void InvalidateAllRegisters() override; - - size_t GetRegisterCount() override; - - virtual size_t GetGPRSize(); - - virtual size_t GetFXSAVEOffset(); - - virtual unsigned GetRegisterSize(unsigned reg); - - virtual unsigned GetRegisterOffset(unsigned reg); - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; - - size_t GetRegisterSetCount() override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; - - const char *GetRegisterName(unsigned reg); - - // Note: prefer kernel definitions over user-land - enum FPRType { - eNotValid = 0, - eFSAVE, // TODO - eFXSAVE, - eSOFT, // TODO - eXSAVE - }; +namespace lldb_private { +struct RegisterInfos_x86_64_with_base_shared { static uint32_t g_contained_eax[]; static uint32_t g_contained_ebx[]; static uint32_t g_contained_ecx[]; @@ -147,65 +110,33 @@ static uint32_t g_invalidate_st5_64[]; static uint32_t g_invalidate_st6_64[]; static uint32_t g_invalidate_st7_64[]; +}; -protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - uint32_t num_avx_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_st; - uint32_t last_st; - uint32_t first_mm; - uint32_t last_mm; - uint32_t first_xmm; - uint32_t last_xmm; - uint32_t first_ymm; - uint32_t last_ymm; - - uint32_t first_dr; - uint32_t gpr_flags; - }; - - uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit - // general - // purpose - // registers. - RegInfo m_reg_info; - FPRType - m_fpr_type; // determines the type of data stored by union FPR, if any. - lldb_private::FPR m_fpr; // floating-point registers including extended - // register sets. - lldb_private::YMM m_ymm_set; // copy of ymmh and xmm register halves. - std::unique_ptr - m_register_info_up; // Register Info Interface (FreeBSD or Linux) - - // Determines if an extended register set is supported on the processor - // running the inferior process. - virtual bool IsRegisterSetAvailable(size_t set_index); - - virtual const lldb_private::RegisterInfo *GetRegisterInfo(); - - bool IsGPR(unsigned reg); - - bool IsFPR(unsigned reg); - - bool IsAVX(unsigned reg); - - bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order); - bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order); - bool IsFPR(unsigned reg, FPRType fpr_type); - FPRType GetFPRType(); - - virtual bool ReadGPR() = 0; - virtual bool ReadFPR() = 0; - virtual bool WriteGPR() = 0; - virtual bool WriteFPR() = 0; +struct RegInfo { + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + uint32_t num_avx_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + + uint32_t first_st; + uint32_t last_st; + uint32_t first_mm; + uint32_t last_mm; + uint32_t first_xmm; + uint32_t last_xmm; + uint32_t first_ymm; + uint32_t last_ymm; + + uint32_t first_dr; + uint32_t gpr_flags; }; -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base); + +} // namespace lldb_private + +#endif // ifndef lldb_RegisterInfos_x86_64_with_base_shared_h diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp @@ -0,0 +1,321 @@ +//===-- RegisterInfos_x86_64_with_base_shared.cpp--------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterInfos_x86_64_with_base_shared.h" + +#include "lldb/lldb-defines.h" +#include + +using namespace lldb; + +namespace lldb_private { + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_eax[] = { + lldb_eax_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebx[] = { + lldb_ebx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ecx[] = { + lldb_ecx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edx[] = { + lldb_edx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edi[] = { + lldb_edi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esi[] = { + lldb_esi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebp[] = { + lldb_ebp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esp[] = { + lldb_esp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_eax[] = { + lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebx[] = { + lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ecx[] = { + lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edx[] = { + lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edi[] = { + lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esi[] = { + lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebp[] = { + lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esp[] = { + lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rax[] = { + x86_64_with_base::lldb_rax, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbx[] = { + x86_64_with_base::lldb_rbx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rcx[] = { + x86_64_with_base::lldb_rcx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdx[] = { + x86_64_with_base::lldb_rdx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdi[] = { + x86_64_with_base::lldb_rdi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsi[] = { + x86_64_with_base::lldb_rsi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbp[] = { + x86_64_with_base::lldb_rbp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsp[] = { + x86_64_with_base::lldb_rsp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r8[] = { + x86_64_with_base::lldb_r8, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r9[] = { + x86_64_with_base::lldb_r9, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r10[] = { + x86_64_with_base::lldb_r10, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r11[] = { + x86_64_with_base::lldb_r11, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r12[] = { + x86_64_with_base::lldb_r12, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r13[] = { + x86_64_with_base::lldb_r13, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r14[] = { + x86_64_with_base::lldb_r14, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r15[] = { + x86_64_with_base::lldb_r15, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rax[] = { + x86_64_with_base::lldb_rax, x86_64_with_base::lldb_eax, + x86_64_with_base::lldb_ax, x86_64_with_base::lldb_ah, + x86_64_with_base::lldb_al, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbx[] = { + x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_ebx, + x86_64_with_base::lldb_bx, x86_64_with_base::lldb_bh, + x86_64_with_base::lldb_bl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rcx[] = { + x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_ecx, + x86_64_with_base::lldb_cx, x86_64_with_base::lldb_ch, + x86_64_with_base::lldb_cl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdx[] = { + x86_64_with_base::lldb_rdx, x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_dx, x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_dl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdi[] = { + x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_edi, + x86_64_with_base::lldb_di, x86_64_with_base::lldb_dil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsi[] = { + x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_esi, + x86_64_with_base::lldb_si, x86_64_with_base::lldb_sil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbp[] = { + x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_ebp, + x86_64_with_base::lldb_bp, x86_64_with_base::lldb_bpl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsp[] = { + x86_64_with_base::lldb_rsp, x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_sp, x86_64_with_base::lldb_spl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r8[] = { + x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r8d, + x86_64_with_base::lldb_r8w, x86_64_with_base::lldb_r8l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r9[] = { + x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r9d, + x86_64_with_base::lldb_r9w, x86_64_with_base::lldb_r9l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r10[] = { + x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r10d, + x86_64_with_base::lldb_r10w, x86_64_with_base::lldb_r10l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r11[] = { + x86_64_with_base::lldb_r11, x86_64_with_base::lldb_r11d, + x86_64_with_base::lldb_r11w, x86_64_with_base::lldb_r11l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r12[] = { + x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r12d, + x86_64_with_base::lldb_r12w, x86_64_with_base::lldb_r12l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r13[] = { + x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r13d, + x86_64_with_base::lldb_r13w, x86_64_with_base::lldb_r13l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r14[] = { + x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r14d, + x86_64_with_base::lldb_r14w, x86_64_with_base::lldb_r14l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r15[] = { + x86_64_with_base::lldb_r15, x86_64_with_base::lldb_r15d, + x86_64_with_base::lldb_r15w, x86_64_with_base::lldb_r15l, + LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fip[] = { + x86_64_with_base::lldb_fip, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fdp[] = { + x86_64_with_base::lldb_fdp, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fip[] = { + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fiseg, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fdp[] = { + x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_fooff, + x86_64_with_base::lldb_foseg, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_32[] = { + lldb_st0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_32[] = { + lldb_st1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_32[] = { + lldb_st2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_32[] = { + lldb_st3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_32[] = { + lldb_st4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_32[] = { + lldb_st5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_32[] = { + lldb_st6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_32[] = { + lldb_st7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_32[] = { + lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_32[] = { + lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_32[] = { + lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_32[] = { + lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_32[] = { + lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_32[] = { + lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_32[] = { + lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_32[] = { + lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_64[] = { + x86_64_with_base::lldb_st0, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_64[] = { + x86_64_with_base::lldb_st1, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_64[] = { + x86_64_with_base::lldb_st2, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_64[] = { + x86_64_with_base::lldb_st3, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_64[] = { + x86_64_with_base::lldb_st4, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_64[] = { + x86_64_with_base::lldb_st5, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_64[] = { + x86_64_with_base::lldb_st6, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_64[] = { + x86_64_with_base::lldb_st7, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_64[] = { + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_mm0, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_64[] = { + x86_64_with_base::lldb_st1, x86_64_with_base::lldb_mm1, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_64[] = { + x86_64_with_base::lldb_st2, x86_64_with_base::lldb_mm2, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_64[] = { + x86_64_with_base::lldb_st3, x86_64_with_base::lldb_mm3, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_64[] = { + x86_64_with_base::lldb_st4, x86_64_with_base::lldb_mm4, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_64[] = { + x86_64_with_base::lldb_st5, x86_64_with_base::lldb_mm5, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_64[] = { + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_mm6, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_64[] = { + x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm7, + LLDB_INVALID_REGNUM}; + +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base) { + static std::once_flag once_flag_x86, once_flag_x86_64, + once_flag_x86_64_with_base; + static RegInfo reg_info_x86, reg_info_x86_64, reg_info_x86_64_with_base; + + switch (arch_type) { + case llvm::Triple::x86: + std::call_once(once_flag_x86, []() { + reg_info_x86.num_registers = k_num_registers_i386; + reg_info_x86.num_gpr_registers = k_num_gpr_registers_i386; + reg_info_x86.num_fpr_registers = k_num_fpr_registers_i386; + reg_info_x86.num_avx_registers = k_num_avx_registers_i386; + reg_info_x86.last_gpr = k_last_gpr_i386; + reg_info_x86.first_fpr = k_first_fpr_i386; + reg_info_x86.last_fpr = k_last_fpr_i386; + reg_info_x86.first_st = lldb_st0_i386; + reg_info_x86.last_st = lldb_st7_i386; + reg_info_x86.first_mm = lldb_mm0_i386; + reg_info_x86.last_mm = lldb_mm7_i386; + reg_info_x86.first_xmm = lldb_xmm0_i386; + reg_info_x86.last_xmm = lldb_xmm7_i386; + reg_info_x86.first_ymm = lldb_ymm0_i386; + reg_info_x86.last_ymm = lldb_ymm7_i386; + reg_info_x86.first_dr = lldb_dr0_i386; + reg_info_x86.gpr_flags = lldb_eflags_i386; + }); + + return reg_info_x86; + case llvm::Triple::x86_64: + if (with_base) { + std::call_once(once_flag_x86_64_with_base, []() { + reg_info_x86_64_with_base.num_registers = + x86_64_with_base::k_num_registers; + reg_info_x86_64_with_base.num_gpr_registers = + x86_64_with_base::k_num_gpr_registers; + reg_info_x86_64_with_base.num_fpr_registers = + x86_64_with_base::k_num_fpr_registers; + reg_info_x86_64_with_base.num_avx_registers = + x86_64_with_base::k_num_avx_registers; + reg_info_x86_64_with_base.last_gpr = x86_64_with_base::k_last_gpr; + reg_info_x86_64_with_base.first_fpr = x86_64_with_base::k_first_fpr; + reg_info_x86_64_with_base.last_fpr = x86_64_with_base::k_last_fpr; + reg_info_x86_64_with_base.first_st = x86_64_with_base::lldb_st0; + reg_info_x86_64_with_base.last_st = x86_64_with_base::lldb_st7; + reg_info_x86_64_with_base.first_mm = x86_64_with_base::lldb_mm0; + reg_info_x86_64_with_base.last_mm = x86_64_with_base::lldb_mm7; + reg_info_x86_64_with_base.first_xmm = x86_64_with_base::lldb_xmm0; + reg_info_x86_64_with_base.last_xmm = x86_64_with_base::lldb_xmm15; + reg_info_x86_64_with_base.first_ymm = x86_64_with_base::lldb_ymm0; + reg_info_x86_64_with_base.last_ymm = x86_64_with_base::lldb_ymm15; + reg_info_x86_64_with_base.first_dr = x86_64_with_base::lldb_dr0; + reg_info_x86_64_with_base.gpr_flags = x86_64_with_base::lldb_rflags; + }); + + return reg_info_x86_64_with_base; + } else { + std::call_once(once_flag_x86_64, []() { + reg_info_x86_64.num_registers = k_num_registers_x86_64; + reg_info_x86_64.num_gpr_registers = k_num_gpr_registers_x86_64; + reg_info_x86_64.num_fpr_registers = k_num_fpr_registers_x86_64; + reg_info_x86_64.num_avx_registers = k_num_avx_registers_x86_64; + reg_info_x86_64.last_gpr = k_last_gpr_x86_64; + reg_info_x86_64.first_fpr = k_first_fpr_x86_64; + reg_info_x86_64.last_fpr = k_last_fpr_x86_64; + reg_info_x86_64.first_st = lldb_st0_x86_64; + reg_info_x86_64.last_st = lldb_st7_x86_64; + reg_info_x86_64.first_mm = lldb_mm0_x86_64; + reg_info_x86_64.last_mm = lldb_mm7_x86_64; + reg_info_x86_64.first_xmm = lldb_xmm0_x86_64; + reg_info_x86_64.last_xmm = lldb_xmm15_x86_64; + reg_info_x86_64.first_ymm = lldb_ymm0_x86_64; + reg_info_x86_64.last_ymm = lldb_ymm15_x86_64; + reg_info_x86_64.first_dr = lldb_dr0_x86_64; + reg_info_x86_64.gpr_flags = lldb_rflags_x86_64; + }); + return reg_info_x86_64; + } + default: + assert(false && "Unhandled target architecture."); + break; + } +} + +} // namespace lldb_private diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h --- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -321,6 +321,197 @@ k_num_mpx_registers_x86_64, k_num_dbr_registers_x86_64 = k_last_dbr_x86_64 - k_first_dbr_x86_64 + 1, }; + +// For platform that supports fs_base/gs_base registers. +namespace x86_64_with_base { +enum { + k_first_gpr, + lldb_rax = k_first_gpr, + lldb_rbx, + lldb_rcx, + lldb_rdx, + lldb_rdi, + lldb_rsi, + lldb_rbp, + lldb_rsp, + lldb_r8, + lldb_r9, + lldb_r10, + lldb_r11, + lldb_r12, + lldb_r13, + lldb_r14, + lldb_r15, + lldb_rip, + lldb_rflags, + lldb_cs, + lldb_fs, + lldb_gs, + lldb_ss, + lldb_fs_base, + lldb_gs_base, + lldb_ds, + lldb_es, + + k_first_alias, + lldb_eax = k_first_alias, + lldb_ebx, + lldb_ecx, + lldb_edx, + lldb_edi, + lldb_esi, + lldb_ebp, + lldb_esp, + lldb_r8d, // Low 32 bits of r8 + lldb_r9d, // Low 32 bits of r9 + lldb_r10d, // Low 32 bits of r10 + lldb_r11d, // Low 32 bits of r11 + lldb_r12d, // Low 32 bits of r12 + lldb_r13d, // Low 32 bits of r13 + lldb_r14d, // Low 32 bits of r14 + lldb_r15d, // Low 32 bits of r15 + lldb_ax, + lldb_bx, + lldb_cx, + lldb_dx, + lldb_di, + lldb_si, + lldb_bp, + lldb_sp, + lldb_r8w, // Low 16 bits of r8 + lldb_r9w, // Low 16 bits of r9 + lldb_r10w, // Low 16 bits of r10 + lldb_r11w, // Low 16 bits of r11 + lldb_r12w, // Low 16 bits of r12 + lldb_r13w, // Low 16 bits of r13 + lldb_r14w, // Low 16 bits of r14 + lldb_r15w, // Low 16 bits of r15 + lldb_ah, + lldb_bh, + lldb_ch, + lldb_dh, + lldb_al, + lldb_bl, + lldb_cl, + lldb_dl, + lldb_dil, + lldb_sil, + lldb_bpl, + lldb_spl, + lldb_r8l, // Low 8 bits of r8 + lldb_r9l, // Low 8 bits of r9 + lldb_r10l, // Low 8 bits of r10 + lldb_r11l, // Low 8 bits of r11 + lldb_r12l, // Low 8 bits of r12 + lldb_r13l, // Low 8 bits of r13 + lldb_r14l, // Low 8 bits of r14 + lldb_r15l, // Low 8 bits of r15 + k_last_alias = lldb_r15l, + + k_last_gpr = k_last_alias, + + k_first_fpr, + lldb_fctrl = k_first_fpr, + lldb_fstat, + lldb_ftag, + lldb_fop, + lldb_fiseg, + lldb_fioff, + lldb_fip, + lldb_foseg, + lldb_fooff, + lldb_fdp, + lldb_mxcsr, + lldb_mxcsrmask, + lldb_st0, + lldb_st1, + lldb_st2, + lldb_st3, + lldb_st4, + lldb_st5, + lldb_st6, + lldb_st7, + lldb_mm0, + lldb_mm1, + lldb_mm2, + lldb_mm3, + lldb_mm4, + lldb_mm5, + lldb_mm6, + lldb_mm7, + lldb_xmm0, + lldb_xmm1, + lldb_xmm2, + lldb_xmm3, + lldb_xmm4, + lldb_xmm5, + lldb_xmm6, + lldb_xmm7, + lldb_xmm8, + lldb_xmm9, + lldb_xmm10, + lldb_xmm11, + lldb_xmm12, + lldb_xmm13, + lldb_xmm14, + lldb_xmm15, + k_last_fpr = lldb_xmm15, + + k_first_avx, + lldb_ymm0 = k_first_avx, + lldb_ymm1, + lldb_ymm2, + lldb_ymm3, + lldb_ymm4, + lldb_ymm5, + lldb_ymm6, + lldb_ymm7, + lldb_ymm8, + lldb_ymm9, + lldb_ymm10, + lldb_ymm11, + lldb_ymm12, + lldb_ymm13, + lldb_ymm14, + lldb_ymm15, + k_last_avx = lldb_ymm15, + + k_first_mpxr, + lldb_bnd0 = k_first_mpxr, + lldb_bnd1, + lldb_bnd2, + lldb_bnd3, + k_last_mpxr = lldb_bnd3, + + k_first_mpxc, + lldb_bndcfgu = k_first_mpxc, + lldb_bndstatus, + k_last_mpxc = lldb_bndstatus, + + k_first_dbr, + lldb_dr0 = k_first_dbr, + lldb_dr1, + lldb_dr2, + lldb_dr3, + lldb_dr4, + lldb_dr5, + lldb_dr6, + lldb_dr7, + k_last_dbr = lldb_dr7, + + k_num_registers, + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, + k_num_fpr_registers = k_last_fpr - k_first_fpr + 1, + k_num_avx_registers = k_last_avx - k_first_avx + 1, + k_num_mpx_registers = k_last_mpxc - k_first_mpxr + 1, + k_num_user_registers = k_num_gpr_registers + + k_num_fpr_registers + + k_num_avx_registers + + k_num_mpx_registers, + k_num_dbr_registers = k_last_dbr - k_first_dbr + 1, +}; +} // namespace x86_64_with_base + } #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt --- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN ProcessElfCore.cpp ThreadElfCore.cpp + RegisterContextLinuxCore_x86_64.cpp RegisterContextPOSIXCore_arm.cpp RegisterContextPOSIXCore_arm64.cpp RegisterContextPOSIXCore_mips64.cpp diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h @@ -0,0 +1,28 @@ +//===-- RegisterContextLinuxCore_x86_64.h -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H + +#include "Plugins/Process/elf-core/RegisterUtilities.h" +#include "RegisterContextPOSIXCore_x86_64.h" + +class RegisterContextLinuxCore_x86_64 : public RegisterContextCorePOSIX_x86_64 { +public: + RegisterContextLinuxCore_x86_64( + lldb_private::Thread &thread, + lldb_private::RegisterInfoInterface *register_info, + const lldb_private::DataExtractor &gpregset, + llvm::ArrayRef notes); + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + lldb_private::RegInfo &GetRegInfo() override; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp @@ -0,0 +1,237 @@ +//===-- RegisterContextLinuxCore_x86_64.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextLinuxCore_x86_64.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" + +using namespace lldb_private; + +const uint32_t g_gpr_regnums_i386[] = { + lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, + lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, + lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, + lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, + lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, + lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, + lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, + lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM, // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - + 1 == + k_num_gpr_registers_i386, + "g_gpr_regnums_i386 has wrong number of register infos"); + +const uint32_t g_lldb_regnums_i386[] = { + lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, + lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, + lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, + lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, + lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, + lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, + lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, + lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, + lldb_xmm6_i386, lldb_xmm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - + 1 == + k_num_fpr_registers_i386, + "g_lldb_regnums_i386 has wrong number of register infos"); + +const uint32_t g_avx_regnums_i386[] = { + lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, + lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - + 1 == + k_num_avx_registers_i386, + " g_avx_regnums_i386 has wrong number of register infos"); + +static const uint32_t g_gpr_regnums_x86_64[] = { + x86_64_with_base::lldb_rax, + x86_64_with_base::lldb_rbx, + x86_64_with_base::lldb_rcx, + x86_64_with_base::lldb_rdx, + x86_64_with_base::lldb_rdi, + x86_64_with_base::lldb_rsi, + x86_64_with_base::lldb_rbp, + x86_64_with_base::lldb_rsp, + x86_64_with_base::lldb_r8, + x86_64_with_base::lldb_r9, + x86_64_with_base::lldb_r10, + x86_64_with_base::lldb_r11, + x86_64_with_base::lldb_r12, + x86_64_with_base::lldb_r13, + x86_64_with_base::lldb_r14, + x86_64_with_base::lldb_r15, + x86_64_with_base::lldb_rip, + x86_64_with_base::lldb_rflags, + x86_64_with_base::lldb_cs, + x86_64_with_base::lldb_fs, + x86_64_with_base::lldb_gs, + x86_64_with_base::lldb_ss, + x86_64_with_base::lldb_fs_base, + x86_64_with_base::lldb_gs_base, + x86_64_with_base::lldb_ds, + x86_64_with_base::lldb_es, + x86_64_with_base::lldb_eax, + x86_64_with_base::lldb_ebx, + x86_64_with_base::lldb_ecx, + x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_edi, + x86_64_with_base::lldb_esi, + x86_64_with_base::lldb_ebp, + x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_r8d, // Low 32 bits or r8 + x86_64_with_base::lldb_r9d, // Low 32 bits or r9 + x86_64_with_base::lldb_r10d, // Low 32 bits or r10 + x86_64_with_base::lldb_r11d, // Low 32 bits or r11 + x86_64_with_base::lldb_r12d, // Low 32 bits or r12 + x86_64_with_base::lldb_r13d, // Low 32 bits or r13 + x86_64_with_base::lldb_r14d, // Low 32 bits or r14 + x86_64_with_base::lldb_r15d, // Low 32 bits or r15 + x86_64_with_base::lldb_ax, + x86_64_with_base::lldb_bx, + x86_64_with_base::lldb_cx, + x86_64_with_base::lldb_dx, + x86_64_with_base::lldb_di, + x86_64_with_base::lldb_si, + x86_64_with_base::lldb_bp, + x86_64_with_base::lldb_sp, + x86_64_with_base::lldb_r8w, // Low 16 bits or r8 + x86_64_with_base::lldb_r9w, // Low 16 bits or r9 + x86_64_with_base::lldb_r10w, // Low 16 bits or r10 + x86_64_with_base::lldb_r11w, // Low 16 bits or r11 + x86_64_with_base::lldb_r12w, // Low 16 bits or r12 + x86_64_with_base::lldb_r13w, // Low 16 bits or r13 + x86_64_with_base::lldb_r14w, // Low 16 bits or r14 + x86_64_with_base::lldb_r15w, // Low 16 bits or r15 + x86_64_with_base::lldb_ah, + x86_64_with_base::lldb_bh, + x86_64_with_base::lldb_ch, + x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_al, + x86_64_with_base::lldb_bl, + x86_64_with_base::lldb_cl, + x86_64_with_base::lldb_dl, + x86_64_with_base::lldb_dil, + x86_64_with_base::lldb_sil, + x86_64_with_base::lldb_bpl, + x86_64_with_base::lldb_spl, + x86_64_with_base::lldb_r8l, // Low 8 bits or r8 + x86_64_with_base::lldb_r9l, // Low 8 bits or r9 + x86_64_with_base::lldb_r10l, // Low 8 bits or r10 + x86_64_with_base::lldb_r11l, // Low 8 bits or r11 + x86_64_with_base::lldb_r12l, // Low 8 bits or r12 + x86_64_with_base::lldb_r13l, // Low 8 bits or r13 + x86_64_with_base::lldb_r14l, // Low 8 bits or r14 + x86_64_with_base::lldb_r15l, // Low 8 bits or r15 + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - + 1 == + x86_64_with_base::k_num_gpr_registers, + "g_gpr_regnums_x86_64 has wrong number of register infos"); + +static const uint32_t g_lldb_regnums_x86_64[] = { + x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat, + x86_64_with_base::lldb_ftag, x86_64_with_base::lldb_fop, + x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg, + x86_64_with_base::lldb_fooff, x86_64_with_base::lldb_fdp, + x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask, + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1, + x86_64_with_base::lldb_st2, x86_64_with_base::lldb_st3, + x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5, + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7, + x86_64_with_base::lldb_mm0, x86_64_with_base::lldb_mm1, + x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3, + x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5, + x86_64_with_base::lldb_mm6, x86_64_with_base::lldb_mm7, + x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1, + x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3, + x86_64_with_base::lldb_xmm4, x86_64_with_base::lldb_xmm5, + x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7, + x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9, + x86_64_with_base::lldb_xmm10, x86_64_with_base::lldb_xmm11, + x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13, + x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert( + (sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 == + x86_64_with_base::k_num_fpr_registers, + "g_lldb_regnums_x86_64 has wrong number of register infos"); + +static const uint32_t g_avx_regnums_x86_64[] = { + x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1, + x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3, + x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5, + x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7, + x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9, + x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11, + x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13, + x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - + 1 == + x86_64_with_base::k_num_avx_registers, + "g_avx_regnums_x86_64 has wrong number of register infos"); + +static const RegisterSet g_reg_sets_i386[] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, + g_gpr_regnums_i386}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, + g_lldb_regnums_i386}, + {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, + g_avx_regnums_i386}}; + +static const RegisterSet g_reg_sets_x86_64[] = { + {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers, + g_gpr_regnums_x86_64}, + {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers, + g_lldb_regnums_x86_64}, + {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers, + g_avx_regnums_x86_64}}; + +RegisterContextLinuxCore_x86_64::RegisterContextLinuxCore_x86_64( + Thread &thread, RegisterInfoInterface *register_info, + const DataExtractor &gpregset, llvm::ArrayRef notes) + : RegisterContextCorePOSIX_x86_64(thread, register_info, gpregset, notes) {} + +const RegisterSet *RegisterContextLinuxCore_x86_64::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) { + switch (m_register_info_up->GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return &g_reg_sets_i386[set]; + case llvm::Triple::x86_64: + return &g_reg_sets_x86_64[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + } + return nullptr; +} + +RegInfo &RegisterContextLinuxCore_x86_64::GetRegInfo() { + return GetRegInfoShared( + m_register_info_up->GetTargetArchitecture().GetMachine(), + /*with_base=*/true); +} diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -29,6 +29,7 @@ #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" #include "ProcessElfCore.h" +#include "RegisterContextLinuxCore_x86_64.h" #include "RegisterContextPOSIXCore_arm.h" #include "RegisterContextPOSIXCore_arm64.h" #include "RegisterContextPOSIXCore_mips64.h" @@ -71,6 +72,7 @@ if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); + bool is_linux = false; if (concrete_frame_idx == 0) { if (m_thread_reg_ctx_sp) return m_thread_reg_ctx_sp; @@ -123,6 +125,7 @@ } case llvm::Triple::Linux: { + is_linux = true; switch (arch.GetMachine()) { case llvm::Triple::aarch64: break; @@ -206,8 +209,13 @@ break; case llvm::Triple::x86: case llvm::Triple::x86_64: - m_thread_reg_ctx_sp = std::make_shared( - *this, reg_interface, m_gpregset_data, m_notes); + if (is_linux) { + m_thread_reg_ctx_sp = std::make_shared( + *this, reg_interface, m_gpregset_data, m_notes); + } else { + m_thread_reg_ctx_sp = std::make_shared( + *this, reg_interface, m_gpregset_data, m_notes); + } break; default: break; diff --git a/lldb/test/API/commands/register/register/register_command/TestRegisters.py b/lldb/test/API/commands/register/register/register_command/TestRegisters.py --- a/lldb/test/API/commands/register/register/register_command/TestRegisters.py +++ b/lldb/test/API/commands/register/register/register_command/TestRegisters.py @@ -606,3 +606,44 @@ # This has an alternative name according to the ABI. self.expect("register info x30", substrs=["Name: lr (x30)"]) + + @skipUnlessPlatform(["linux"]) + @skipIf(archs=no_match(["x86_64"])) + def test_fs_gs_base(self): + """Tests fs_base register can be read and equals to pthread_self() return value.""" + self.build() + target = self.createTestTarget() + # Launch the process and stop. + self.expect("run", PROCESS_STOPPED, substrs=["stopped"]) + + process = target.GetProcess() + + thread = process.GetThreadAtIndex(0) + self.assertTrue(thread.IsValid(), "current thread is valid") + + current_frame = thread.GetFrameAtIndex(0) + self.assertTrue(current_frame.IsValid(), "current frame is valid") + + reg_fs_base = current_frame.FindRegister("fs_base") + self.assertTrue(reg_fs_base.IsValid(), "fs_base is not available") + reg_gs_base = current_frame.FindRegister("gs_base") + self.assertTrue(reg_gs_base.IsValid(), "gs_base is not available") + self.assertEqual( + reg_gs_base.GetValueAsSigned(-1), 0, f"gs_base should be zero" + ) + + # Evaluate pthread_self() and compare against fs_base register read. + pthread_self_code = "(uint64_t)pthread_self()" + pthread_self_val = current_frame.EvaluateExpression(pthread_self_code) + self.assertTrue( + pthread_self_val.IsValid(), f"{pthread_self_code} evaluation has failed" + ) + self.assertNotEqual( + reg_fs_base.GetValueAsSigned(-1), -1, f"fs_base returned -1 which is wrong" + ) + + self.assertEqual( + reg_fs_base.GetValueAsUnsigned(0), + pthread_self_val.GetValueAsUnsigned(0), + "fs_base does not equal to pthread_self() value.", + ) diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -623,6 +623,38 @@ self.expect("register read --all") + @skipUnlessPlatform(["linux"]) + @skipIf(archs=no_match(["x86_64"])) + def test_fs_gs_base(self): + """Tests fs_base/gs_base registers can be read from linux coredump.""" + target = self.dbg.CreateTarget(None) + process = target.LoadCore("linux-x86_64.core") + self.assertTrue(process, PROCESS_IS_VALID) + + error = lldb.SBError() + bytesread = process.ReadMemory(0x400FF0, 20, error) + + thread = process.GetThreadAtIndex(0) + self.assertTrue(thread.IsValid(), "current thread is valid") + + current_frame = thread.GetFrameAtIndex(0) + self.assertTrue(current_frame.IsValid(), "current frame is valid") + + reg_fs_base = current_frame.FindRegister("fs_base") + reg_gs_base = current_frame.FindRegister("gs_base") + self.assertTrue(reg_fs_base.IsValid(), "fs_base is not available") + self.assertTrue(reg_gs_base.IsValid(), "gs_base is not available") + # The fs_base/gs_base registers in linux-x86_64.core are both zero. + # Use "eu-readelf -n linux-x86_64.core" to verify. + self.assertEqual( + reg_fs_base.GetValueAsSigned(-1), 0, f"fs_base read is different from expected" + ) + self.assertEqual( + reg_gs_base.GetValueAsSigned(-1), 0, f"gs_base read is different from expected" + ) + self.dbg.DeleteTarget(target) + + def check_memory_regions(self, process, region_count): region_list = process.GetMemoryRegions() self.assertEqual(region_list.GetSize(), region_count)