Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h =================================================================== --- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -39,12 +39,6 @@ const RegisterSet *GetRegisterSet(uint32_t set_index) const override; - Status ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) override; - - Status WriteRegister(const RegisterInfo *reg_info, - const RegisterValue ®_value) override; - Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; @@ -76,6 +70,19 @@ Status CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD &source) override; +protected: + uint32_t GetRegisterSetForRegNum(uint32_t reg_index) const override; + + Status ReadRegisterSet(uint32_t set) override; + Status WriteRegisterSet(uint32_t set) override; + + Status GetRegisterFromCache(const RegisterInfo *reg_info, + RegisterValue ®_value, + uint32_t set) override; + Status SetRegisterInCache(const RegisterInfo *reg_info, + const RegisterValue ®_value, + uint32_t set) override; + private: // Private member types. enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet }; @@ -92,11 +99,7 @@ struct xstate m_xstate; #endif - int GetSetForNativeRegNum(int reg_num) const; int GetDR(int num) const; - - Status ReadRegisterSet(uint32_t set); - Status WriteRegisterSet(uint32_t set); }; } // namespace process_netbsd Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -263,7 +263,7 @@ uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const { uint32_t sets = 0; for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { - if (GetSetForNativeRegNum(set_index) != -1) + if (GetRegisterSetForRegNum(set_index) != LLDB_INVALID_REGNUM) ++sets; } @@ -395,8 +395,8 @@ } } -int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( - int reg_num) const { +uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetForRegNum( + uint32_t reg_num) const { switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86: if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386) @@ -406,9 +406,9 @@ if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386) return XStateRegSet; // AVX if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386) - return -1; // MPXR + return LLDB_INVALID_REGSET; // MPXR if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386) - return -1; // MPXC + return LLDB_INVALID_REGSET; // MPXC if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386) return DBRegSet; // DBR break; @@ -420,9 +420,9 @@ if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64) return XStateRegSet; // AVX if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64) - return -1; // MPXR + return LLDB_INVALID_REGSET; // MPXR if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64) - return -1; // MPXC + return LLDB_INVALID_REGSET; // MPXC if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64) return DBRegSet; // DBR break; @@ -484,33 +484,14 @@ } Status -NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) { - Status error; +NativeRegisterContextNetBSD_x86_64::GetRegisterFromCache( + const RegisterInfo *reg_info, RegisterValue ®_value, uint32_t set) { - if (!reg_info) { - error.SetErrorString("reg_info NULL"); - return error; - } + assert(reg_info); + assert(set != LLDB_INVALID_REGSET); + Status error; uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; - if (reg == LLDB_INVALID_REGNUM) { - // This is likely an internal register for lldb use only and should not be - // directly queried. - error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " - "register, cannot read directly", - reg_info->name); - return error; - } - - int set = GetSetForNativeRegNum(reg); - if (set == -1) { - // This is likely an internal register for lldb use only and should not be - // directly queried. - error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", - reg_info->name); - return error; - } switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86_64: @@ -522,10 +503,6 @@ llvm_unreachable("Unhandled target architecture."); } - error = ReadRegisterSet(set); - if (error.Fail()) - return error; - switch (reg) { #if defined(__x86_64__) case lldb_rax_x86_64: @@ -771,34 +748,16 @@ return error; } -Status NativeRegisterContextNetBSD_x86_64::WriteRegister( - const RegisterInfo *reg_info, const RegisterValue ®_value) { - - Status error; +Status NativeRegisterContextNetBSD_x86_64::SetRegisterInCache( + const RegisterInfo *reg_info, + const RegisterValue ®_value, + uint32_t set) { - if (!reg_info) { - error.SetErrorString("reg_info NULL"); - return error; - } + assert(reg_info); + assert(set != LLDB_INVALID_REGSET); + Status error; uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; - if (reg == LLDB_INVALID_REGNUM) { - // This is likely an internal register for lldb use only and should not be - // directly queried. - error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " - "register, cannot read directly", - reg_info->name); - return error; - } - - int set = GetSetForNativeRegNum(reg); - if (set == -1) { - // This is likely an internal register for lldb use only and should not be - // directly queried. - error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", - reg_info->name); - return error; - } switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86_64: @@ -810,10 +769,6 @@ llvm_unreachable("Unhandled target architecture."); } - error = ReadRegisterSet(set); - if (error.Fail()) - return error; - switch (reg) { #if defined(__x86_64__) case lldb_rax_x86_64: @@ -1057,7 +1012,7 @@ llvm_unreachable("Reading unknown/unsupported register"); } - return WriteRegisterSet(set); + return Status(); } Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -9,11 +9,21 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H +#include +#include #include #include "RegisterInfoInterface.h" #include "lldb/Host/common/NativeRegisterContext.h" +enum class RegSetCacheStatus { + Empty, + Read, + Written, +}; + +#define LLDB_INVALID_REGSET UINT32_MAX + namespace lldb_private { class NativeRegisterContextRegisterInfo : public NativeRegisterContext { public: @@ -33,8 +43,50 @@ const RegisterInfoInterface &GetRegisterInfoInterface() const; + Status ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + Status WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + Status FlushRegisterSets(); + protected: std::unique_ptr m_register_info_interface_up; + + // APIs used to implement cached register access, they need to be defined + // only if ReadRegister() and WriteRegister() are not overriden + + virtual uint32_t GetRegisterSetForRegNum(uint32_t reg_index) const { + return LLDB_INVALID_REGSET; + } + + virtual Status ReadRegisterSet(uint32_t set) { + return Status("not implemented"); + } + + virtual Status WriteRegisterSet(uint32_t set) { + return Status("not implemented"); + } + + virtual Status GetRegisterFromCache(const RegisterInfo *reg_info, + RegisterValue ®_value, uint32_t set) { + return Status("not implemented"); + } + + virtual Status SetRegisterInCache(const RegisterInfo *reg_info, + const RegisterValue ®_value, + uint32_t set) { + return Status("not implemented"); + } + + virtual Status FlushRegisterSet(uint32_t set); + + // --------------------------------------------------------------------------- + +private: + std::map m_regset_cache_status; }; -} + +} // namespace lldb_private #endif Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp +++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -40,3 +40,98 @@ NativeRegisterContextRegisterInfo::GetRegisterInfoInterface() const { return *m_register_info_interface_up; } + +Status +NativeRegisterContextRegisterInfo::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + + if (!reg_info) { + error.SetErrorString("reg_info NULL"); + return error; + } + + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " + "register, cannot read directly", + reg_info->name); + return error; + } + + uint32_t set = GetRegisterSetForRegNum(reg); + if (set == LLDB_INVALID_REGSET) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + error = ReadRegisterSet(set); + if (error.Fail()) + return error; + + return GetRegisterFromCache(reg_info, reg_value, set); +} + +Status NativeRegisterContextRegisterInfo::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue ®_value) { + + Status error; + + if (!reg_info) { + error.SetErrorString("reg_info NULL"); + return error; + } + + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " + "register, cannot read directly", + reg_info->name); + return error; + } + + uint32_t set = GetRegisterSetForRegNum(reg); + if (set == LLDB_INVALID_REGSET) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + error = ReadRegisterSet(set); + if (error.Fail()) + return error; + + error = SetRegisterInCache(reg_info, reg_value, set); + if (error.Fail()) + return error; + + return WriteRegisterSet(set); +} + +Status NativeRegisterContextRegisterInfo::FlushRegisterSets() { + Status error; + + for (auto kv : m_regset_cache_status) { + if (kv.second == RegSetCacheStatus::Empty) + continue; + error = FlushRegisterSet(kv.first); + if (error.Fail()) + break; + } + + return error; +} + +Status NativeRegisterContextRegisterInfo::FlushRegisterSet(uint32_t set) { + m_regset_cache_status[set] = RegSetCacheStatus::Empty; + return Status(); +}