[Lldb-commits] [lldb] 6adb558 - [lldb] [Process/FreeBSDRemote] Access debug registers via offsets
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Mon Nov 16 04:03:15 PST 2020
Author: Michał Górny
Date: 2020-11-16T13:03:01+01:00
New Revision: 6adb55877c4bae6c75ab0d2c0374fab6787bff2d
URL: https://github.com/llvm/llvm-project/commit/6adb55877c4bae6c75ab0d2c0374fab6787bff2d
DIFF: https://github.com/llvm/llvm-project/commit/6adb55877c4bae6c75ab0d2c0374fab6787bff2d.diff
LOG: [lldb] [Process/FreeBSDRemote] Access debug registers via offsets
Use offset-based method to access x86 debug registers. This also
involves adding a test for the correctness of these offsets, and making
GetDR() method of NativeRegisterContextWatchpoint_x86 public to avoid
duplicate code.
Differential Revision: https://reviews.llvm.org/D91268
Added:
Modified:
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
index 02dd24b52934..c29308b1219e 100644
--- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -247,8 +247,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
: NativeRegisterContextRegisterInfo(
- native_thread, CreateRegisterInfoInterface(target_arch)),
- m_dbr() {
+ native_thread, CreateRegisterInfoInterface(target_arch)) {
assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
}
@@ -296,15 +295,6 @@ static constexpr int RegNumX86ToX86_64(int regnum) {
return lldb_bndcfgu_x86_64;
case lldb_bndstatus_i386:
return lldb_bndstatus_x86_64;
- case lldb_dr0_i386:
- case lldb_dr1_i386:
- case lldb_dr2_i386:
- case lldb_dr3_i386:
- case lldb_dr4_i386:
- case lldb_dr5_i386:
- case lldb_dr6_i386:
- case lldb_dr7_i386:
- return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
default:
llvm_unreachable("Unhandled i386 register.");
}
@@ -363,7 +353,7 @@ Status NativeRegisterContextFreeBSD_x86_64::ReadRegisterSet(uint32_t set) {
#endif
case DBRegSet:
return NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS, m_thread.GetID(),
- &m_dbr);
+ m_dbr.data());
case XSaveRegSet: {
struct ptrace_xstate_info info;
Status ret = NativeProcessFreeBSD::PtraceWrapper(
@@ -404,7 +394,7 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegisterSet(uint32_t set) {
#endif
case DBRegSet:
return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(),
- &m_dbr);
+ m_dbr.data());
case XSaveRegSet:
// ReadRegisterSet() must always be called before WriteRegisterSet().
assert(m_xsave.size() > 0);
@@ -457,8 +447,11 @@ NativeRegisterContextFreeBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
reg_value.SetBytes(m_fpr.data() + reg_info->byte_offset - GetFPROffset(),
reg_info->byte_size, endian::InlHostByteOrder());
return error;
- case XSaveRegSet:
case DBRegSet:
+ reg_value.SetBytes(m_dbr.data() + reg_info->byte_offset - GetDBROffset(),
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+ case XSaveRegSet:
// legacy logic
break;
}
@@ -507,16 +500,6 @@ NativeRegisterContextFreeBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
}
break;
}
- case lldb_dr0_x86_64:
- case lldb_dr1_x86_64:
- case lldb_dr2_x86_64:
- case lldb_dr3_x86_64:
- case lldb_dr4_x86_64:
- case lldb_dr5_x86_64:
- case lldb_dr6_x86_64:
- case lldb_dr7_x86_64:
- reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
- break;
default:
llvm_unreachable("Reading unknown/unsupported register");
}
@@ -567,8 +550,11 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegister(
::memcpy(m_fpr.data() + reg_info->byte_offset - GetFPROffset(),
reg_value.GetBytes(), reg_value.GetByteSize());
return WriteRegisterSet(set);
- case XSaveRegSet:
case DBRegSet:
+ ::memcpy(m_dbr.data() + reg_info->byte_offset - GetDBROffset(),
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ return WriteRegisterSet(set);
+ case XSaveRegSet:
// legacy logic
break;
}
@@ -616,16 +602,6 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteRegister(
}
break;
}
- case lldb_dr0_x86_64:
- case lldb_dr1_x86_64:
- case lldb_dr2_x86_64:
- case lldb_dr3_x86_64:
- case lldb_dr4_x86_64:
- case lldb_dr5_x86_64:
- case lldb_dr6_x86_64:
- case lldb_dr7_x86_64:
- m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
- break;
default:
llvm_unreachable("Reading unknown/unsupported register");
}
@@ -686,25 +662,15 @@ Status NativeRegisterContextFreeBSD_x86_64::WriteAllRegisterValues(
return error;
}
-int NativeRegisterContextFreeBSD_x86_64::GetDR(int num) const {
- assert(num >= 0 && num <= 7);
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::x86:
- return lldb_dr0_i386 + num;
- case llvm::Triple::x86_64:
- return lldb_dr0_x86_64 + num;
- default:
- llvm_unreachable("Unhandled target architecture.");
- }
-}
-
llvm::Error NativeRegisterContextFreeBSD_x86_64::CopyHardwareWatchpointsFrom(
NativeRegisterContextFreeBSD &source) {
auto &r_source = static_cast<NativeRegisterContextFreeBSD_x86_64 &>(source);
- Status res = r_source.ReadRegisterSet(DBRegSet);
+ // NB: This implicitly reads the whole dbreg set.
+ RegisterValue dr7;
+ Status res = r_source.ReadRegister(GetDR(7), dr7);
if (!res.Fail()) {
// copy dbregs only if any watchpoints were set
- if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
+ if ((dr7.GetAsUInt64() & 0xFF) == 0)
return llvm::Error::success();
m_dbr = r_source.m_dbr;
@@ -729,4 +695,20 @@ size_t NativeRegisterContextFreeBSD_x86_64::GetFPROffset() const {
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;
+ break;
+ case llvm::Triple::x86_64:
+ regno = lldb_dr0_x86_64;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ return GetRegisterInfoInterface().GetRegisterInfo()[regno].byte_offset;
+}
+
#endif // defined(__x86_64__)
diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
index 24a698eec0fe..17853860f457 100644
--- a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
@@ -71,17 +71,17 @@ class NativeRegisterContextFreeBSD_x86_64
// Private member variables.
std::array<uint8_t, sizeof(struct reg)> m_gpr;
std::array<uint8_t, 512> m_fpr; // FXSAVE
- struct dbreg m_dbr;
+ std::array<uint8_t, sizeof(struct dbreg)> m_dbr;
std::vector<uint8_t> m_xsave;
std::array<uint32_t, MaxXSaveSet + 1> m_xsave_offsets;
llvm::Optional<enum RegSetKind> GetSetForNativeRegNum(int reg_num) const;
- int GetDR(int num) const;
Status ReadRegisterSet(uint32_t set);
Status WriteRegisterSet(uint32_t set);
size_t GetFPROffset() const;
+ size_t GetDBROffset() const;
};
} // namespace process_freebsd
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
index 3085712f3cc3..cfb8900a4fd2 100644
--- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
@@ -40,7 +40,6 @@ class NativeRegisterContextWatchpoint_x86
uint32_t NumSupportedHardwareWatchpoints() override;
-private:
const RegisterInfo *GetDR(int num) const;
};
diff --git a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
index ba4348e7de4a..6aaf0e58984a 100644
--- a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -39,6 +39,8 @@ std::pair<size_t, size_t> GetRegParams(RegisterInfoInterface &ctx,
EXPECT_THAT( \
GetRegParams(reg_ctx, lldb_##regname##_x86_64), \
::testing::Pair(offsetof(reg, r_##regname), sizeof(reg::r_##regname)))
+#define EXPECT_DBR_X86_64(num) \
+ EXPECT_OFF(dr##num##_x86_64, offsetof(dbreg, dr[num]), sizeof(dbreg::dr[num]))
TEST(RegisterContextFreeBSDTest, x86_64) {
ArchSpec arch{"x86_64-unknown-freebsd"};
@@ -119,6 +121,16 @@ TEST(RegisterContextFreeBSDTest, x86_64) {
EXPECT_OFF(xmm13_x86_64, 0x170, 16);
EXPECT_OFF(xmm14_x86_64, 0x180, 16);
EXPECT_OFF(xmm15_x86_64, 0x190, 16);
+
+ base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_x86_64].byte_offset;
+ EXPECT_DBR_X86_64(0);
+ EXPECT_DBR_X86_64(1);
+ EXPECT_DBR_X86_64(2);
+ EXPECT_DBR_X86_64(3);
+ EXPECT_DBR_X86_64(4);
+ EXPECT_DBR_X86_64(5);
+ EXPECT_DBR_X86_64(6);
+ EXPECT_DBR_X86_64(7);
}
#endif // defined(__x86_64__)
@@ -129,6 +141,9 @@ TEST(RegisterContextFreeBSDTest, x86_64) {
EXPECT_THAT(GetRegParams(reg_ctx, lldb_##regname##_i386), \
::testing::Pair(offsetof(native_i386_regs, r_##regname), \
sizeof(native_i386_regs::r_##regname)))
+#define EXPECT_DBR_I386(num) \
+ EXPECT_OFF(dr##num##_i386, offsetof(native_i386_dbregs, dr[num]), \
+ sizeof(native_i386_dbregs::dr[num]))
TEST(RegisterContextFreeBSDTest, i386) {
ArchSpec arch{"i686-unknown-freebsd"};
@@ -136,8 +151,10 @@ TEST(RegisterContextFreeBSDTest, i386) {
#if defined(__i386__)
using native_i386_regs = ::reg;
+ using native_i386_dbregs = ::dbreg;
#else
using native_i386_regs = ::reg32;
+ using native_i386_dbregs = ::dbreg32;
#endif
EXPECT_GPR_I386(fs);
@@ -199,6 +216,16 @@ TEST(RegisterContextFreeBSDTest, i386) {
EXPECT_OFF(xmm5_i386, 0xF0, 16);
EXPECT_OFF(xmm6_i386, 0x100, 16);
EXPECT_OFF(xmm7_i386, 0x110, 16);
+
+ base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_i386].byte_offset;
+ EXPECT_DBR_I386(0);
+ EXPECT_DBR_I386(1);
+ EXPECT_DBR_I386(2);
+ EXPECT_DBR_I386(3);
+ EXPECT_DBR_I386(4);
+ EXPECT_DBR_I386(5);
+ EXPECT_DBR_I386(6);
+ EXPECT_DBR_I386(7);
}
#endif // defined(__i386__) || defined(__x86_64__)
More information about the lldb-commits
mailing list