diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h @@ -72,14 +72,14 @@ std::array m_dbr; std::vector m_xsave; std::array m_xsave_offsets; + std::array m_regset_offsets; llvm::Optional GetSetForNativeRegNum(int reg_num) const; Status ReadRegisterSet(uint32_t set); Status WriteRegisterSet(uint32_t set); - size_t GetFPROffset() const; - size_t GetDBROffset() const; + uint8_t *GetOffsetRegSetData(uint32_t set, size_t reg_offset); struct YMMSplitPtr { void *xmm; diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp --- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -262,8 +262,28 @@ NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextRegisterInfo( - native_thread, CreateRegisterInfoInterface(target_arch)) { + native_thread, CreateRegisterInfoInterface(target_arch)), + m_regset_offsets({0}) { assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize()); + std::array first_regnos; + + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + first_regnos[FPRegSet] = lldb_fctrl_i386; + first_regnos[DBRegSet] = lldb_dr0_i386; + break; + case llvm::Triple::x86_64: + first_regnos[FPRegSet] = lldb_fctrl_x86_64; + first_regnos[DBRegSet] = lldb_dr0_x86_64; + break; + default: + llvm_unreachable("Unhandled target architecture."); + } + + for (int i: {FPRegSet, DBRegSet}) + m_regset_offsets[i] = GetRegisterInfoInterface() + .GetRegisterInfo()[first_regnos[i]] + .byte_offset; } uint32_t NativeRegisterContextFreeBSD_x86_64::GetRegisterSetCount() const { @@ -429,15 +449,9 @@ switch (set) { case GPRegSet: - reg_value.SetBytes(m_gpr.data() + reg_info->byte_offset, - reg_info->byte_size, endian::InlHostByteOrder()); - break; case FPRegSet: - reg_value.SetBytes(m_fpr.data() + reg_info->byte_offset - GetFPROffset(), - reg_info->byte_size, endian::InlHostByteOrder()); - break; case DBRegSet: - reg_value.SetBytes(m_dbr.data() + reg_info->byte_offset - GetDBROffset(), + reg_value.SetBytes(GetOffsetRegSetData(set, reg_info->byte_offset), reg_info->byte_size, endian::InlHostByteOrder()); break; case YMMRegSet: { @@ -495,15 +509,9 @@ switch (set) { case GPRegSet: - ::memcpy(m_gpr.data() + reg_info->byte_offset, reg_value.GetBytes(), - reg_value.GetByteSize()); - break; case FPRegSet: - ::memcpy(m_fpr.data() + reg_info->byte_offset - GetFPROffset(), - reg_value.GetBytes(), reg_value.GetByteSize()); - break; case DBRegSet: - ::memcpy(m_dbr.data() + reg_info->byte_offset - GetDBROffset(), + ::memcpy(GetOffsetRegSetData(set, reg_info->byte_offset), reg_value.GetBytes(), reg_value.GetByteSize()); break; case YMMRegSet: { @@ -595,36 +603,25 @@ return res.ToError(); } -size_t NativeRegisterContextFreeBSD_x86_64::GetFPROffset() const { - uint32_t regno; - switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { - case llvm::Triple::x86: - regno = lldb_fctrl_i386; - break; - case llvm::Triple::x86_64: - regno = lldb_fctrl_x86_64; +uint8_t * +NativeRegisterContextFreeBSD_x86_64::GetOffsetRegSetData(uint32_t set, + size_t reg_offset) { + uint8_t *base; + switch (set) { + case GPRegSet: + base = m_gpr.data(); break; - default: - llvm_unreachable("Unhandled target architecture."); - } - - return GetRegisterInfoInterface().GetRegisterInfo()[regno].byte_offset; -} - -size_t NativeRegisterContextFreeBSD_x86_64::GetDBROffset() const { - uint32_t regno; - switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { - case llvm::Triple::x86: - regno = lldb_dr0_i386; + case FPRegSet: + base = m_fpr.data(); break; - case llvm::Triple::x86_64: - regno = lldb_dr0_x86_64; + case DBRegSet: + base = m_dbr.data(); break; - default: - llvm_unreachable("Unhandled target architecture."); + case YMMRegSet: + llvm_unreachable("GetRegSetData() is unsuitable for this regset."); } - - return GetRegisterInfoInterface().GetRegisterInfo()[regno].byte_offset; + assert(reg_offset >= m_regset_offsets[set]); + return base + (reg_offset - m_regset_offsets[set]); } llvm::Optional