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