Index: lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -159,12 +159,14 @@ m_posix_thread = nullptr; RegisterInfoInterface *reg_interface = nullptr; + RegisterInfoAndSetInterface *regset_interface = nullptr; + const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture(); assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD); switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(target_arch); + regset_interface = new RegisterInfoPOSIX_arm64(target_arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(target_arch); @@ -193,7 +195,8 @@ switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: { RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = - new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface); + new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, + regset_interface); m_posix_thread = reg_ctx; m_reg_context_sp.reset(reg_ctx); break; Index: lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h =================================================================== --- lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h +++ lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h @@ -18,7 +18,7 @@ public: RegisterContextPOSIXProcessMonitor_arm64( lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); + lldb_private::RegisterInfoAndSetInterface *register_info); protected: bool ReadGPR(); Index: lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -23,8 +23,8 @@ RegisterContextPOSIXProcessMonitor_arm64:: RegisterContextPOSIXProcessMonitor_arm64( lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) {} + lldb_private::RegisterInfoAndSetInterface *regset_info) + : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, regset_info) {} ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() { lldb::ProcessSP base = CalculateProcess(); Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h =================================================================== --- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h +++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h @@ -55,7 +55,7 @@ virtual void *GetGPRBuffer() = 0; - virtual size_t GetGPRSize() { + virtual size_t GetGPRSize() const { return GetRegisterInfoInterface().GetGPRSize(); } Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h =================================================================== --- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -12,7 +12,7 @@ #define lldb_NativeRegisterContextLinux_arm64_h #include "Plugins/Process/Linux/NativeRegisterContextLinux.h" -#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" namespace lldb_private { namespace process_linux { @@ -95,47 +95,15 @@ size_t GetFPRSize() override { return sizeof(m_fpr); } private: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_fpr_v; - uint32_t last_fpr_v; - - uint32_t gpr_flags; - }; - - // based on RegisterContextDarwin_arm64.h - struct VReg { - uint8_t bytes[16]; - }; - - // based on RegisterContextDarwin_arm64.h - struct FPU { - VReg v[32]; - uint32_t fpsr; - uint32_t fpcr; - }; - - struct GPR { - uint64_t x[31]; - uint64_t sp; - uint64_t pc; - uint64_t pstate; - }; - bool m_gpr_is_valid; bool m_fpu_is_valid; - GPR m_gpr_arm64; // 64-bit general purpose registers. - RegInfo m_reg_info; - FPU m_fpr; // floating-point registers including extended register sets. + std::shared_ptr m_regset_interface_up; + + RegisterInfoPOSIX_arm64::GPR m_gpr_arm64; // 64-bit general purpose registers. + RegisterInfoPOSIX_arm64::FPU + m_fpr; // floating-point registers including extended register sets. // Debug register info for hardware breakpoints and watchpoints management. struct DREG { lldb::addr_t address; // Breakpoint/watchpoint address value. Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -21,7 +21,6 @@ #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" // System includes - They have to be included after framework includes because // they define some macros which collide with variable names in other modules @@ -37,76 +36,6 @@ using namespace lldb_private; using namespace lldb_private::process_linux; -// ARM64 general purpose registers. -static const uint32_t g_gpr_regnums_arm64[] = { - gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, - gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, - gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, - gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, - gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, - gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, - gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, - gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, - gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, - gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, - gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, - gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, - gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, - gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, - gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, - gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - - 1) == k_num_gpr_registers_arm64, - "g_gpr_regnums_arm64 has wrong number of register infos"); - -// ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = { - fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, - fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, - fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, - fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, - fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, - fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, - fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, - fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, - fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, - fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, - fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, - fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, - fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, - fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, - fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, - fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, - - fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, - fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, - fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, - fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, - fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, - fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, - fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, - fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, - fpu_fpsr_arm64, fpu_fpcr_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - - 1) == k_num_fpr_registers_arm64, - "g_fpu_regnums_arm64 has wrong number of register infos"); - -namespace { -// Number of register sets provided by this context. -enum { k_num_register_sets = 2 }; -} - -// Register sets for ARM64. -static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, - g_gpr_regnums_arm64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, - g_fpu_regnums_arm64}}; - std::unique_ptr NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { @@ -126,23 +55,6 @@ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextLinux(native_thread, new RegisterInfoPOSIX_arm64(target_arch)) { - switch (target_arch.GetMachine()) { - case llvm::Triple::aarch64: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - llvm_unreachable("Unhandled target architecture."); - break; - } - ::memset(&m_fpr, 0, sizeof(m_fpr)); ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64)); ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); @@ -155,24 +67,24 @@ m_gpr_is_valid = false; m_fpu_is_valid = false; + + m_regset_interface_up = std::static_pointer_cast( + m_register_info_interface_up); } uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const { - return k_num_register_sets; + return m_regset_interface_up->GetRegisterSetCount(); } const RegisterSet * NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const { - if (set_index < k_num_register_sets) - return &g_reg_sets_arm64[set_index]; - - return nullptr; + return m_regset_interface_up->GetRegisterSet(set_index); } uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const { uint32_t count = 0; - for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) - count += g_reg_sets_arm64[set_index].num_registers; + for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index) + count += GetRegisterSet(set_index)->num_registers; return count; } @@ -344,11 +256,17 @@ } bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const { - return reg <= m_reg_info.last_gpr; // GPR's come first. + if (m_regset_interface_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterSetPOSIX_ARM64GPR) + return true; + return false; } bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + if (m_regset_interface_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterSetPOSIX_ARM64FPR) + return true; + return false; } uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() { @@ -900,8 +818,7 @@ uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset( const RegisterInfo *reg_info) const { - return reg_info->byte_offset - - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; + return reg_info->byte_offset - GetGPRSize(); } #endif // defined (__arm64__) || defined (__aarch64__) Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -33,8 +33,7 @@ const RegisterInfoInterface &GetRegisterInfoInterface() const; -private: - std::unique_ptr m_register_info_interface_up; + std::shared_ptr m_register_info_interface_up; }; } #endif Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H #include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_arm64.h" #include "lldb-arm64-register-enums.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" @@ -20,7 +21,7 @@ public: RegisterContextPOSIX_arm64( lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); + lldb_private::RegisterInfoAndSetInterface *register_info); ~RegisterContextPOSIX_arm64() override; @@ -45,53 +46,24 @@ const char *GetRegisterName(unsigned reg); protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_fpr_v; - uint32_t last_fpr_v; - - uint32_t gpr_flags; - }; - - // based on RegisterContextDarwin_arm64.h - struct VReg { - uint8_t bytes[16]; - }; - - // based on RegisterContextDarwin_arm64.h - struct FPU { - VReg v[32]; - uint32_t fpsr; - uint32_t fpcr; - }; - uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit // general // purpose // registers. - RegInfo m_reg_info; - struct RegisterContextPOSIX_arm64::FPU + + struct RegisterInfoPOSIX_arm64::FPU m_fpr; // floating-point registers including extended register sets. - std::unique_ptr + 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); + size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); } + virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -25,106 +25,26 @@ using namespace lldb; using namespace lldb_private; -// ARM64 general purpose registers. -const uint32_t g_gpr_regnums_arm64[] = { - gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, - gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, - gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, - gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, - gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, - gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, - gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, - gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, - gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, - gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, - gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, - gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, - gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, - gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, - gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, - gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - - 1) == k_num_gpr_registers_arm64, - "g_gpr_regnums_arm64 has wrong number of register infos"); - -// ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = { - fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, - fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, - fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, - fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, - fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, - fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, - fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, - fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, - fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, - fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, - fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, - fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, - fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, - fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, - fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, - fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, - - fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, - fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, - fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, - fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, - fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, - fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, - fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, - fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, - fpu_fpsr_arm64, fpu_fpcr_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - - 1) == k_num_fpr_registers_arm64, - "g_fpu_regnums_arm64 has wrong number of register infos"); - -// Number of register sets provided by this context. -enum { k_num_register_sets = 2 }; - -// Register sets for ARM64. -static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, - g_gpr_regnums_arm64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, - g_fpu_regnums_arm64}}; - bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) { - return reg <= m_reg_info.last_gpr; // GPR's come first. + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterSetPOSIX_ARM64GPR) + return true; + return false; } bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterSetPOSIX_ARM64FPR) + return true; + return false; } RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) + lldb_private::RegisterInfoAndSetInterface *register_info) : lldb_private::RegisterContext(thread, concrete_frame_idx) { m_register_info_up.reset(register_info); - switch (register_info->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } - ::memset(&m_fpr, 0, sizeof m_fpr); } @@ -135,19 +55,15 @@ void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_offset; + return m_register_info_up->GetRegisterOffset(reg); } unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_size; + return m_register_info_up->GetRegisterSize(reg); } size_t RegisterContextPOSIX_arm64::GetRegisterCount() { - size_t num_registers = - m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; - return num_registers; + return m_register_info_up->GetRegisterCount(); } size_t RegisterContextPOSIX_arm64::GetGPRSize() { @@ -164,42 +80,23 @@ const lldb_private::RegisterInfo * RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) { - if (reg < m_reg_info.num_registers) + if (reg < GetRegisterCount()) return &GetRegisterInfo()[reg]; else return nullptr; } size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() { - size_t sets = 0; - for (size_t set = 0; set < k_num_register_sets; ++set) { - if (IsRegisterSetAvailable(set)) - ++sets; - } - - return sets; -} - -bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) { - return set_index < k_num_register_sets; + return m_register_info_up->GetRegisterSetCount(); } const lldb_private::RegisterSet * RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) { - if (IsRegisterSetAvailable(set)) { - switch (m_register_info_up->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - return &g_reg_sets_arm64[set]; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } - } - return nullptr; + return m_register_info_up->GetRegisterSet(set); } const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register offset."); - return GetRegisterInfo()[reg].name; + if (reg < GetRegisterCount()) + return GetRegisterInfo()[reg].name; + return nullptr; } Index: lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h =================================================================== --- /dev/null +++ lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h @@ -0,0 +1,41 @@ +//===-- RegisterInfoAndSetInterface.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_UTILITY_REGISTERINFOANDSETINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H + +#include "RegisterInfoInterface.h" + +#include "lldb/Utility/ArchSpec.h" +#include "lldb/lldb-private-types.h" +#include + +namespace lldb_private { + +class RegisterInfoAndSetInterface : public RegisterInfoInterface { +public: + RegisterInfoAndSetInterface(const lldb_private::ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + virtual ~RegisterInfoAndSetInterface() {} + + virtual size_t GetFPRSize() const = 0; + + virtual const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const = 0; + + virtual size_t GetRegisterSetCount() const = 0; + + virtual size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const = 0; + + virtual uint32_t GetRegisterOffset(uint32_t reg_index) const = 0; + + virtual uint32_t GetRegisterSize(uint32_t reg_index) const = 0; +}; +} // namespace lldb_private + +#endif Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -9,12 +9,25 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H -#include "RegisterInfoInterface.h" +#include "RegisterInfoAndSetInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" -class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface { +enum { RegisterSetPOSIX_ARM64GPR = 0, RegisterSetPOSIX_ARM64FPR }; + +class RegisterInfoPOSIX_arm64 + : public lldb_private::RegisterInfoAndSetInterface { public: + struct RegInfo { + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + }; + // based on RegisterContextDarwin_arm64.h struct GPR { uint64_t x[29]; // x0-x28 @@ -57,11 +70,25 @@ size_t GetGPRSize() const override; + size_t GetFPRSize() const override; + const lldb_private::RegisterInfo *GetRegisterInfo() const override; uint32_t GetRegisterCount() const override; + uint32_t GetRegisterOffset(uint32_t reg_index) const override; + + uint32_t GetRegisterSize(uint32_t reg_index) const override; + + const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const override; + + size_t GetRegisterSetCount() const override; + + size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; + private: + RegInfo m_reg_info; const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; }; Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -65,6 +65,58 @@ } } +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, + k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, + k_num_register_sets = 2 +}; +// clang-format off +// ARM64 general purpose registers. +static const uint32_t g_gpr_regnums_arm64[] = { + gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, gpr_x7, + gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, gpr_x14, gpr_x15, + gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, gpr_x21, gpr_x22, gpr_x23, + gpr_x24, gpr_x25, gpr_x26, gpr_x27, gpr_x28, gpr_fp, gpr_lr, gpr_sp, + gpr_pc, gpr_cpsr, gpr_w0, gpr_w1, gpr_w2, gpr_w3, gpr_w4, gpr_w5, + gpr_w6, gpr_w7, gpr_w8, gpr_w9, gpr_w10, gpr_w11, gpr_w12, gpr_w13, + gpr_w14, gpr_w15, gpr_w16, gpr_w17, gpr_w18, gpr_w19, gpr_w20, gpr_w21, + gpr_w22, gpr_w23, gpr_w24, gpr_w25, gpr_w26, gpr_w27, gpr_w28, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_arm64 has wrong number of register infos"); + +// ARM64 floating point registers. +static const uint32_t g_fpu_regnums_arm64[] = { + fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, fpu_v7, + fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, fpu_v14, fpu_v15, + fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, fpu_v21, fpu_v22, fpu_v23, + fpu_v24, fpu_v25, fpu_v26, fpu_v27, fpu_v28, fpu_v29, fpu_v30, fpu_v31, + fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, + fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15, + fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23, + fpu_s24, fpu_s25, fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31, + fpu_d0, fpu_d1, fpu_d2, fpu_d3, fpu_d4, fpu_d5, fpu_d6, fpu_d7, + fpu_d8, fpu_d9, fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15, + fpu_d16, fpu_d17, fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23, + fpu_d24, fpu_d25, fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31, + fpu_fpsr, fpu_fpcr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - + 1) == k_num_fpr_registers, + "g_fpu_regnums_arm64 has wrong number of register infos"); +// clang-format on +// Register sets for ARM64. +static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers, + g_gpr_regnums_arm64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers, + g_fpu_regnums_arm64}}; + static uint32_t GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { @@ -80,19 +132,70 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( const lldb_private::ArchSpec &target_arch) - : lldb_private::RegisterInfoInterface(target_arch), + : lldb_private::RegisterInfoAndSetInterface(target_arch), m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)) {} + m_register_info_count(GetRegisterInfoCount(target_arch)) { + + switch (target_arch.GetMachine()) { + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + m_reg_info.num_registers = k_num_gpr_registers + k_num_fpr_registers; + m_reg_info.num_gpr_registers = k_num_gpr_registers; + m_reg_info.num_fpr_registers = k_num_fpr_registers; + m_reg_info.last_gpr = gpr_w28; + m_reg_info.first_fpr = fpu_v0; + m_reg_info.last_fpr = fpu_fpcr; + break; + default: + assert(false && "Unhandled target architecture."); + break; + } +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterOffset(uint32_t reg_index) const { + assert(reg_index < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg_index].byte_offset; +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterSize(uint32_t reg_index) const { + assert(reg_index < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg_index].byte_size; +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { + return m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; +} size_t RegisterInfoPOSIX_arm64::GetGPRSize() const { return sizeof(struct RegisterInfoPOSIX_arm64::GPR); } +size_t RegisterInfoPOSIX_arm64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_arm64::FPU); +} + const lldb_private::RegisterInfo * RegisterInfoPOSIX_arm64::GetRegisterInfo() const { return m_register_info_p; } -uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { - return m_register_info_count; +size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + if (reg_index <= m_reg_info.last_gpr) + return RegisterSetPOSIX_ARM64GPR; + else if (reg_index <= m_reg_info.last_fpr) + return RegisterSetPOSIX_ARM64FPR; + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { + if (set_index < k_num_register_sets) + return &g_reg_sets_arm64[set_index]; + + return nullptr; } Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -18,7 +18,7 @@ public: RegisterContextCorePOSIX_arm64( lldb_private::Thread &thread, - lldb_private::RegisterInfoInterface *register_info, + lldb_private::RegisterInfoAndSetInterface *register_info, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef notes); Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -17,7 +17,7 @@ using namespace lldb_private; RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( - Thread &thread, RegisterInfoInterface *register_info, + Thread &thread, RegisterInfoAndSetInterface *register_info, const DataExtractor &gpregset, llvm::ArrayRef notes) : RegisterContextPOSIX_arm64(thread, 0, register_info) { m_gpr_buffer = std::make_shared(gpregset.GetDataStart(), @@ -61,7 +61,7 @@ return false; offset -= GetGPRSize(); - if (IsFPR(reg) && offset + reg_info->byte_size <= sizeof(FPU)) { + if (IsFPR(reg) && offset + reg_info->byte_size <= GetFPUSize()) { Status error; value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, reg_info->byte_size, lldb::eByteOrderLittle, error); Index: lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp =================================================================== --- lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -77,12 +77,13 @@ ProcessElfCore *process = static_cast(GetProcess().get()); ArchSpec arch = process->GetArchitecture(); RegisterInfoInterface *reg_interface = nullptr; + RegisterInfoAndSetInterface *regset_interface = nullptr; switch (arch.GetTriple().getOS()) { case llvm::Triple::FreeBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); + regset_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(arch); @@ -111,7 +112,7 @@ case llvm::Triple::NetBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); + regset_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::x86_64: reg_interface = new RegisterContextNetBSD_x86_64(arch); @@ -128,7 +129,7 @@ reg_interface = new RegisterInfoPOSIX_arm(arch); break; case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); + regset_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::mipsel: case llvm::Triple::mips: @@ -159,7 +160,7 @@ case llvm::Triple::OpenBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); + regset_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(arch); @@ -189,7 +190,7 @@ switch (arch.GetMachine()) { case llvm::Triple::aarch64: m_thread_reg_ctx_sp = std::make_shared( - *this, reg_interface, m_gpregset_data, m_notes); + *this, regset_interface, m_gpregset_data, m_notes); break; case llvm::Triple::arm: m_thread_reg_ctx_sp = std::make_shared(