mgorny updated this revision to Diff 299704.
mgorny marked an inline comment as done.
mgorny added a comment.

Deleted unnecessary constructor and switched public/virtual order. More changes 
coming.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89874/new/

https://reviews.llvm.org/D89874

Files:
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
  lldb/source/Plugins/Process/Utility/CMakeLists.txt
  lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.cpp
  lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.h

Index: lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.h
@@ -0,0 +1,53 @@
+//===-- WatchpointMixin_x86.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifndef lldb_WatchpointMixin_x86_h
+#define lldb_WatchpointMixin_x86_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+namespace lldb_private {
+
+class WatchpointMixin_x86 : public virtual NativeRegisterContextRegisterInfo {
+public:
+  Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+  Status GetWatchpointHitIndex(uint32_t &wp_index,
+                               lldb::addr_t trap_addr) override;
+
+  Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+  bool ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+  // TODO: do we need to call it explicitly like on netbsd?
+  Status ClearWatchpointHit(uint32_t wp_index);
+
+  Status ClearAllHardwareWatchpoints() override;
+
+  Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+                                        uint32_t watch_flags,
+                                        uint32_t wp_index);
+
+  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+                                 uint32_t watch_flags) override;
+
+  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+  uint32_t NumSupportedHardwareWatchpoints() override;
+
+private:
+  int GetDR(int num) const;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_WatchpointMixin_x86_h
+
+#endif // defined(__i386__) || defined(__x86_64__)
Index: lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/Utility/WatchpointMixin_x86.cpp
@@ -0,0 +1,261 @@
+//===-- WatchpointMixin_x86.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "WatchpointMixin_x86.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+
+int WatchpointMixin_x86::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.");
+  }
+}
+
+Status WatchpointMixin_x86::IsWatchpointHit(uint32_t wp_index,
+                                                           bool &is_hit) {
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return Status("Watchpoint index out of range");
+
+  RegisterValue reg_value;
+  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6));
+  Status error = ReadRegister(reg_info, reg_value);
+  if (error.Fail()) {
+    is_hit = false;
+    return error;
+  }
+
+  uint64_t status_bits = reg_value.GetAsUInt64();
+
+  is_hit = status_bits & (1 << wp_index);
+
+  return error;
+}
+
+Status WatchpointMixin_x86::GetWatchpointHitIndex(
+    uint32_t &wp_index, lldb::addr_t trap_addr) {
+  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+  for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+    bool is_hit;
+    Status error = IsWatchpointHit(wp_index, is_hit);
+    if (error.Fail()) {
+      wp_index = LLDB_INVALID_INDEX32;
+      return error;
+    } else if (is_hit) {
+      return error;
+    }
+  }
+  wp_index = LLDB_INVALID_INDEX32;
+  return Status();
+}
+
+Status WatchpointMixin_x86::IsWatchpointVacant(uint32_t wp_index,
+                                                              bool &is_vacant) {
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return Status("Watchpoint index out of range");
+
+  RegisterValue reg_value;
+  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7));
+  Status error = ReadRegister(reg_info, reg_value);
+  if (error.Fail()) {
+    is_vacant = false;
+    return error;
+  }
+
+  uint64_t control_bits = reg_value.GetAsUInt64();
+
+  is_vacant = !(control_bits & (1 << (2 * wp_index + 1)));
+
+  return error;
+}
+
+Status WatchpointMixin_x86::SetHardwareWatchpointWithIndex(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return Status("Watchpoint index out of range");
+
+  // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+  // waitchpoints instead.
+  // TODO: Add logic to detect when a write happens and ignore that watchpoint
+  // hit.
+  if (watch_flags == 0x2)
+    watch_flags = 0x3;
+
+  if (watch_flags != 0x1 && watch_flags != 0x3)
+    return Status("Invalid read/write bits for watchpoint");
+
+  if (size != 1 && size != 2 && size != 4 && size != 8)
+    return Status("Invalid size for watchpoint");
+
+  bool is_vacant;
+  Status error = IsWatchpointVacant(wp_index, is_vacant);
+  if (error.Fail())
+    return error;
+  if (!is_vacant)
+    return Status("Watchpoint index not vacant");
+
+  const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
+  RegisterValue dr7_value;
+  error = ReadRegister(reg_info_dr7, dr7_value);
+  if (error.Fail())
+    return error;
+
+  // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
+  uint64_t enable_bit = 1 << (2 * wp_index + 1);
+
+  // set bits 16-17, 20-21, 24-25, or 28-29
+  // with 0b01 for write, and 0b11 for read/write
+  uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
+
+  // set bits 18-19, 22-23, 26-27, or 30-31
+  // with 0b00, 0b01, 0b10, or 0b11
+  // for 1, 2, 8 (if supported), or 4 bytes, respectively
+  uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+
+  uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+
+  uint64_t control_bits = dr7_value.GetAsUInt64() & ~bit_mask;
+
+  control_bits |= enable_bit | rw_bits | size_bits;
+
+  const RegisterInfo *const reg_info_drN =
+      GetRegisterInfoAtIndex(GetDR(wp_index));
+  RegisterValue drN_value;
+  error = ReadRegister(reg_info_drN, drN_value);
+  if (error.Fail())
+    return error;
+
+  // clear dr6 if address or bits changed (i.e. we're not reenabling the same
+  // watchpoint)
+  if (drN_value.GetAsUInt64() != addr ||
+      (dr7_value.GetAsUInt64() & bit_mask) != (rw_bits | size_bits)) {
+    ClearWatchpointHit(wp_index);
+
+    error = WriteRegister(reg_info_drN, RegisterValue(addr));
+    if (error.Fail())
+      return error;
+  }
+
+  error = WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+  if (error.Fail())
+    return error;
+
+  error.Clear();
+  return error;
+}
+
+bool WatchpointMixin_x86::ClearHardwareWatchpoint(
+    uint32_t wp_index) {
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return false;
+
+  // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5
+  // or 6-7 of the debug control register (DR7)
+  const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
+  RegisterValue reg_value;
+  Status error = ReadRegister(reg_info_dr7, reg_value);
+  if (error.Fail())
+    return false;
+  uint64_t bit_mask = 0x3 << (2 * wp_index);
+  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+
+  return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
+}
+
+Status WatchpointMixin_x86::ClearWatchpointHit(uint32_t wp_index) {
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return Status("Watchpoint index out of range");
+
+  // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of
+  // the debug status register (DR6)
+  const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
+  RegisterValue reg_value;
+  Status error = ReadRegister(reg_info_dr6, reg_value);
+  if (error.Fail())
+    return error;
+
+  uint64_t bit_mask = 1 << wp_index;
+  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+  return WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+}
+
+Status WatchpointMixin_x86::ClearAllHardwareWatchpoints() {
+  RegisterValue reg_value;
+
+  // clear bits {0-4} of the debug status register (DR6)
+  const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
+  Status error = ReadRegister(reg_info_dr6, reg_value);
+  if (error.Fail())
+    return error;
+  uint64_t bit_mask = 0xF;
+  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+  error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+  if (error.Fail())
+    return error;
+
+  // clear bits {0-7,16-31} of the debug control register (DR7)
+  const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
+  error = ReadRegister(reg_info_dr7, reg_value);
+  if (error.Fail())
+    return error;
+  bit_mask = 0xFF | (0xFFFF << 16);
+  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+  return WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+}
+
+uint32_t WatchpointMixin_x86::SetHardwareWatchpoint(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+  for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+    bool is_vacant;
+    Status error = IsWatchpointVacant(wp_index, is_vacant);
+    if (is_vacant) {
+      error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+      if (error.Success())
+        return wp_index;
+    }
+    if (error.Fail() && log) {
+      LLDB_LOGF(log, "WatchpointMixin_x86::%s Error: %s",
+                __FUNCTION__, error.AsCString());
+    }
+  }
+  return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+WatchpointMixin_x86::GetWatchpointAddress(uint32_t wp_index) {
+  if (wp_index >= NumSupportedHardwareWatchpoints())
+    return LLDB_INVALID_ADDRESS;
+  RegisterValue reg_value;
+  const RegisterInfo *const reg_info_drN =
+      GetRegisterInfoAtIndex(GetDR(wp_index));
+  if (ReadRegister(reg_info_drN, reg_value).Fail())
+    return LLDB_INVALID_ADDRESS;
+  return reg_value.GetAsUInt64();
+}
+
+uint32_t WatchpointMixin_x86::NumSupportedHardwareWatchpoints() {
+  // Available debug address registers: dr0, dr1, dr2, dr3
+  return 4;
+}
+
+#endif // defined(__i386__) || defined(__x86_64__)
Index: lldb/source/Plugins/Process/Utility/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -49,6 +49,7 @@
   RegisterInfoPOSIX_ppc64le.cpp
   StopInfoMachException.cpp
   ThreadMemory.cpp
+  WatchpointMixin_x86.cpp
 
   LINK_LIBS
     lldbBreakpoint
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -13,6 +13,7 @@
 
 #include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
+#include "Plugins/Process/Utility/WatchpointMixin_x86.h"
 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 #include <sys/uio.h>
 
@@ -21,7 +22,7 @@
 
 class NativeProcessLinux;
 
-class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
+class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux, public WatchpointMixin_x86 {
 public:
   NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
                                     NativeThreadProtocol &native_thread);
@@ -42,28 +43,6 @@
 
   Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
 
-  Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
-  Status GetWatchpointHitIndex(uint32_t &wp_index,
-                               lldb::addr_t trap_addr) override;
-
-  Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
-  bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
-  Status ClearAllHardwareWatchpoints() override;
-
-  Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
-                                        uint32_t watch_flags,
-                                        uint32_t wp_index);
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
-                                 uint32_t watch_flags) override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
   llvm::Optional<SyscallData> GetSyscallData() override;
 
   llvm::Optional<MmapData> GetMmapData() override;
@@ -128,7 +107,7 @@
 
   bool IsRegisterSetAvailable(uint32_t set_index) const;
 
-  bool IsGPR(uint32_t reg_index) const;
+  bool IsGPROrDR(uint32_t reg_index) const;
 
   bool IsFPR(uint32_t reg_index) const;
 
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -293,8 +293,7 @@
 
 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-    : NativeRegisterContextLinux(native_thread,
-                                 CreateRegisterInfoInterface(target_arch)),
+    : NativeRegisterContextRegisterInfo(native_thread, CreateRegisterInfoInterface(target_arch)),
       m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
       m_reg_info(), m_gpr_x86_64() {
   // Set up data about ranges of valid registers.
@@ -578,7 +577,7 @@
 
   UpdateXSTATEforWrite(reg_index);
 
-  if (IsGPR(reg_index))
+  if (IsGPROrDR(reg_index))
     return WriteRegisterRaw(reg_index, reg_value);
 
   if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
@@ -867,9 +866,9 @@
   return false;
 }
 
-bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
+bool NativeRegisterContextLinux_x86_64::IsGPROrDR(uint32_t reg_index) const {
   // GPRs come first.
-  return reg_index <= m_reg_info.last_gpr;
+  return reg_index <= m_reg_info.last_gpr || reg_index >= m_reg_info.first_dr;
 }
 
 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
@@ -1009,210 +1008,6 @@
   return true;
 }
 
-Status NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
-                                                          bool &is_hit) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return Status("Watchpoint index out of range");
-
-  RegisterValue reg_value;
-  Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
-  if (error.Fail()) {
-    is_hit = false;
-    return error;
-  }
-
-  uint64_t status_bits = reg_value.GetAsUInt64();
-
-  is_hit = status_bits & (1 << wp_index);
-
-  return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
-    uint32_t &wp_index, lldb::addr_t trap_addr) {
-  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
-  for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
-    bool is_hit;
-    Status error = IsWatchpointHit(wp_index, is_hit);
-    if (error.Fail()) {
-      wp_index = LLDB_INVALID_INDEX32;
-      return error;
-    } else if (is_hit) {
-      return error;
-    }
-  }
-  wp_index = LLDB_INVALID_INDEX32;
-  return Status();
-}
-
-Status NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
-                                                             bool &is_vacant) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return Status("Watchpoint index out of range");
-
-  RegisterValue reg_value;
-  Status error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
-  if (error.Fail()) {
-    is_vacant = false;
-    return error;
-  }
-
-  uint64_t control_bits = reg_value.GetAsUInt64();
-
-  is_vacant = !(control_bits & (1 << (2 * wp_index)));
-
-  return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
-    lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
-
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return Status("Watchpoint index out of range");
-
-  // Read only watchpoints aren't supported on x86_64. Fall back to read/write
-  // waitchpoints instead.
-  // TODO: Add logic to detect when a write happens and ignore that watchpoint
-  // hit.
-  if (watch_flags == 0x2)
-    watch_flags = 0x3;
-
-  if (watch_flags != 0x1 && watch_flags != 0x3)
-    return Status("Invalid read/write bits for watchpoint");
-
-  if (size != 1 && size != 2 && size != 4 && size != 8)
-    return Status("Invalid size for watchpoint");
-
-  bool is_vacant;
-  Status error = IsWatchpointVacant(wp_index, is_vacant);
-  if (error.Fail())
-    return error;
-  if (!is_vacant)
-    return Status("Watchpoint index not vacant");
-
-  RegisterValue reg_value;
-  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
-  if (error.Fail())
-    return error;
-
-  // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
-  uint64_t enable_bit = 1 << (2 * wp_index);
-
-  // set bits 16-17, 20-21, 24-25, or 28-29
-  // with 0b01 for write, and 0b11 for read/write
-  uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
-
-  // set bits 18-19, 22-23, 26-27, or 30-31
-  // with 0b00, 0b01, 0b10, or 0b11
-  // for 1, 2, 8 (if supported), or 4 bytes, respectively
-  uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
-
-  uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
-
-  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-
-  control_bits |= enable_bit | rw_bits | size_bits;
-
-  error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
-  if (error.Fail())
-    return error;
-
-  error =
-      WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
-  if (error.Fail())
-    return error;
-
-  error.Clear();
-  return error;
-}
-
-bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
-    uint32_t wp_index) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return false;
-
-  RegisterValue reg_value;
-
-  // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
-  // the debug status register (DR6)
-  Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
-  if (error.Fail())
-    return false;
-  uint64_t bit_mask = 1 << wp_index;
-  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
-  error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
-  if (error.Fail())
-    return false;
-
-  // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
-  // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
-  // (DR7)
-  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
-  if (error.Fail())
-    return false;
-  bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
-  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-  return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
-      .Success();
-}
-
-Status NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
-  RegisterValue reg_value;
-
-  // clear bits {0-4} of the debug status register (DR6)
-  Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
-  if (error.Fail())
-    return error;
-  uint64_t bit_mask = 0xF;
-  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
-  error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
-  if (error.Fail())
-    return error;
-
-  // clear bits {0-7,16-31} of the debug control register (DR7)
-  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
-  if (error.Fail())
-    return error;
-  bit_mask = 0xFF | (0xFFFF << 16);
-  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-  return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
-}
-
-uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
-    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
-  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
-    bool is_vacant;
-    Status error = IsWatchpointVacant(wp_index, is_vacant);
-    if (is_vacant) {
-      error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
-      if (error.Success())
-        return wp_index;
-    }
-    if (error.Fail() && log) {
-      LLDB_LOGF(log, "NativeRegisterContextLinux_x86_64::%s Error: %s",
-                __FUNCTION__, error.AsCString());
-    }
-  }
-  return LLDB_INVALID_INDEX32;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return LLDB_INVALID_ADDRESS;
-  RegisterValue reg_value;
-  if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
-    return LLDB_INVALID_ADDRESS;
-  return reg_value.GetAsUInt64();
-}
-
-uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
-  // Available debug address registers: dr0, dr1, dr2, dr3
-  return 4;
-}
-
 uint32_t
 NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
   // If register is MPX, remove extra factor from gdb offset
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -15,11 +15,8 @@
 namespace lldb_private {
 namespace process_linux {
 
-class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
+class NativeRegisterContextLinux : public virtual NativeRegisterContextRegisterInfo {
 public:
-  NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
-                             RegisterInfoInterface *reg_info_interface_p);
-
   // This function is implemented in the NativeRegisterContextLinux_* subclasses
   // to create a new instance of the host specific NativeRegisterContextLinux.
   // The implementations can't collide as only one NativeRegisterContextLinux_*
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -19,11 +19,6 @@
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
 
-NativeRegisterContextLinux::NativeRegisterContextLinux(
-    NativeThreadProtocol &native_thread,
-    RegisterInfoInterface *reg_info_interface_p)
-    : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
-
 lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
   return m_thread.GetProcess().GetByteOrder();
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to