[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