mgorny created this revision.
mgorny added reviewers: labath, emaste, krytarowski.
Herald added a subscriber: pengfei.
mgorny requested review of this revision.
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.
https://reviews.llvm.org/D91268
Files:
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/FreeBSD/RegisterContextFreeBSDTests.cpp
Index: lldb/unittests/Process/FreeBSD/RegisterContextFreeBSDTests.cpp
===================================================================
--- lldb/unittests/Process/FreeBSD/RegisterContextFreeBSDTests.cpp
+++ lldb/unittests/Process/FreeBSD/RegisterContextFreeBSDTests.cpp
@@ -38,6 +38,8 @@
#define ASSERT_GPR_X86_64(regname) \
ASSERT_REG(regname##_x86_64, offsetof(reg, r_##regname), \
sizeof(reg::r_##regname))
+#define ASSERT_DBR_X86_64(num) \
+ ASSERT_OFF(dr##num##_x86_64, offsetof(dbreg, dr[num]), sizeof(dbreg::dr[num]))
TEST(RegisterContextFreeBSDTest, x86_64) {
ArchSpec arch{"x86_64-unknown-freebsd12.2"};
@@ -118,6 +120,16 @@
ASSERT_OFF(xmm13_x86_64, 0x170, 16);
ASSERT_OFF(xmm14_x86_64, 0x180, 16);
ASSERT_OFF(xmm15_x86_64, 0x190, 16);
+
+ base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_x86_64].byte_offset;
+ ASSERT_DBR_X86_64(0);
+ ASSERT_DBR_X86_64(1);
+ ASSERT_DBR_X86_64(2);
+ ASSERT_DBR_X86_64(3);
+ ASSERT_DBR_X86_64(4);
+ ASSERT_DBR_X86_64(5);
+ ASSERT_DBR_X86_64(6);
+ ASSERT_DBR_X86_64(7);
}
#endif
@@ -125,10 +137,14 @@
#if defined(__i386__)
#define reg32 reg
+#define dbreg32 dbreg
#endif
#define ASSERT_GPR_I386(regname) \
ASSERT_REG(regname##_i386, offsetof(reg32, r_##regname), \
sizeof(reg32::r_##regname))
+#define ASSERT_DBR_I386(num) \
+ ASSERT_OFF(dr##num##_i386, offsetof(dbreg32, dr[num]), \
+ sizeof(dbreg32::dr[num]))
TEST(RegisterContextFreeBSDTest, i386) {
ArchSpec arch{"i686-unknown-freebsd12.2"};
@@ -193,5 +209,15 @@
ASSERT_OFF(xmm5_i386, 0xF0, 16);
ASSERT_OFF(xmm6_i386, 0x100, 16);
ASSERT_OFF(xmm7_i386, 0x110, 16);
+
+ base_offset = reg_ctx.GetRegisterInfo()[lldb_dr0_i386].byte_offset;
+ ASSERT_DBR_I386(0);
+ ASSERT_DBR_I386(1);
+ ASSERT_DBR_I386(2);
+ ASSERT_DBR_I386(3);
+ ASSERT_DBR_I386(4);
+ ASSERT_DBR_I386(5);
+ ASSERT_DBR_I386(6);
+ ASSERT_DBR_I386(7);
}
#endif
Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
===================================================================
--- lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
+++ lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
@@ -40,7 +40,6 @@
uint32_t NumSupportedHardwareWatchpoints() override;
-private:
const RegisterInfo *GetDR(int num) const;
};
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
@@ -71,17 +71,17 @@
// 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
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -247,8 +247,7 @@
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 @@
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 @@
#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 @@
#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 @@
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 @@
}
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 @@
::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 @@
}
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 @@
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 @@
return GetRegisterInfoInterface().GetRegisterInfo()[regno].byte_offset;
}
+size_t NativeRegisterContextFreeBSD_x86_64::GetDBROffset() const {
+ int 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__)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits