[Lldb-commits] [lldb] 96f3ea0 - [lldb/debugserver] Implement hardware breakpoints for x86_64 and i386

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Fri Jan 24 15:07:43 PST 2020


Author: Jonas Devlieghere
Date: 2020-01-24T15:07:31-08:00
New Revision: 96f3ea0d21b48ca088355db10d4d1a2e9bc9f884

URL: https://github.com/llvm/llvm-project/commit/96f3ea0d21b48ca088355db10d4d1a2e9bc9f884
DIFF: https://github.com/llvm/llvm-project/commit/96f3ea0d21b48ca088355db10d4d1a2e9bc9f884.diff

LOG: [lldb/debugserver] Implement hardware breakpoints for x86_64 and i386

This implements hardware breakpoints for x86_64 and i386 in debugserver.
It's based on Pedro's patch sent to lldb-commits [1] although most of it
is the same as the existing hardware watchpoint implementation.

[1] http://lists.llvm.org/pipermail/lldb-commits/Week-of-Mon-20200113/060327.html

Differential revision: https://reviews.llvm.org/D72985

Added: 
    

Modified: 
    lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
    lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
    lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
    lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
    lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
    lldb/tools/debugserver/source/RNBRemote.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
index 56112b24eb52..16c63b9ced1c 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
@@ -9,26 +9,47 @@
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
-# Hardware breakpoints are supported only by platforms mentioned in oslist.
- at skipUnlessPlatform(oslist=['linux'])
 class HardwareBreakpointMultiThreadTestCase(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 
     mydir = TestBase.compute_mydir(__file__)
 
-    # LLDB supports hardware breakpoints for arm and aarch64 architectures.
+    # LLDB on linux supports hardware breakpoints for arm and aarch64
+    # architectures.
+    @skipUnlessPlatform(oslist=['linux'])
     @skipIf(archs=no_match(['arm', 'aarch64']))
-    def test_hw_break_set_delete_multi_thread(self):
+    def test_hw_break_set_delete_multi_thread_linux(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('delete')
+        self.break_multi_thread('delete', 'breakpoint')
 
-    # LLDB supports hardware breakpoints for arm and aarch64 architectures.
+    # LLDB on linux supports hardware breakpoints for arm and aarch64
+    # architectures.
+    @skipUnlessPlatform(oslist=['linux'])
     @skipIf(archs=no_match(['arm', 'aarch64']))
-    def test_hw_break_set_disable_multi_thread(self):
+    def test_hw_break_set_disable_multi_thread_linux(self):
         self.build()
         self.setTearDownCleanup()
-        self.break_multi_thread('disable')
+        self.break_multi_thread('disable', 'breakpoint')
+
+    # LLDB on darwin supports hardware breakpoints for arm, aarch64, x86_64 and
+    # i386 architectures.
+    @skipUnlessDarwin
+    @skipIfOutOfTreeDebugserver
+    def test_hw_break_set_delete_multi_thread_macos(self):
+        self.build()
+        self.setTearDownCleanup()
+        self.break_multi_thread('delete', 'EXC_BREAKPOINT')
+
+    # LLDB on darwin supports hardware breakpoints for arm, aarch64, x86_64 and
+    # i386 architectures.
+    @skipUnlessDarwin
+    @skipIfOutOfTreeDebugserver
+    def test_hw_break_set_disable_multi_thread_macos(self):
+        self.build()
+        self.setTearDownCleanup()
+        self.break_multi_thread('disable', 'EXC_BREAKPOINT')
+
 
     def setUp(self):
         # Call super's setUp().
@@ -39,7 +60,7 @@ def setUp(self):
         self.first_stop = line_number(
             self.source, 'Starting thread creation with hardware breakpoint set')
 
-    def break_multi_thread(self, removal_type):
+    def break_multi_thread(self, removal_type, stop_reason):
         """Test that lldb hardware breakpoints work for multiple threads."""
         self.runCmd("file " + self.getBuildArtifact("a.out"),
                     CURRENT_EXECUTABLE_SET)
@@ -54,8 +75,7 @@ def break_multi_thread(self, removal_type):
         # We should be stopped again due to the breakpoint.
         # The stop reason of the thread should be breakpoint.
         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-                    substrs=['stopped',
-                             'stop reason = breakpoint'])
+                    substrs=['stopped', 'stop reason = breakpoint'])
 
         # Now set a hardware breakpoint in thread function.
         self.expect("breakpoint set -b hw_break_function --hardware",
@@ -75,7 +95,7 @@ def break_multi_thread(self, removal_type):
             # The stop reason of the thread should be breakpoint.
             self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                 substrs=[
-                    'stop reason = breakpoint',
+                    'stop reason = {}'.format(stop_reason),
                     'hw_break_function'])
 
             # Continue the loop and test that we are stopped 4 times.

diff  --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
index 45d05d6e0bdd..90cc25650e38 100644
--- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
@@ -980,7 +980,8 @@ uint32_t DNBArchMachARM::NumSupportedHardwareWatchpoints() {
 }
 
 uint32_t DNBArchMachARM::EnableHardwareBreakpoint(nub_addr_t addr,
-                                                  nub_size_t size) {
+                                                  nub_size_t size,
+                                                  bool also_set_on_task) {
   // Make sure our address isn't bogus
   if (addr & 1)
     return INVALID_NUB_HW_INDEX;
@@ -1052,7 +1053,8 @@ uint32_t DNBArchMachARM::EnableHardwareBreakpoint(nub_addr_t addr,
   return INVALID_NUB_HW_INDEX;
 }
 
-bool DNBArchMachARM::DisableHardwareBreakpoint(uint32_t hw_index) {
+bool DNBArchMachARM::DisableHardwareBreakpoint(uint32_t hw_index,
+                                               bool also_set_on_task) {
   kern_return_t kret = GetDBGState(false);
 
   const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();

diff  --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
index 4bb899b4503d..4c27a342f9ff 100644
--- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
+++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
@@ -70,8 +70,10 @@ class DNBArchMachARM : public DNBArchProtocol {
 
   virtual uint32_t NumSupportedHardwareBreakpoints();
   virtual uint32_t NumSupportedHardwareWatchpoints();
-  virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size);
-  virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index);
+  virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size,
+                                            bool also_set_on_task);
+  virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index,
+                                         bool also_set_on_task);
 
   virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,
                                             bool read, bool write,

diff  --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
index 7d2d0c2ef1b3..27bc75110620 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
@@ -718,6 +718,11 @@ bool DNBArchImplI386::NotifyException(MachException::Data &exc) {
   return false;
 }
 
+uint32_t DNBArchImplI386::NumSupportedHardwareBreakpoints() {
+  // Available debug address registers: dr0, dr1, dr2, dr3.
+  return 4;
+}
+
 uint32_t DNBArchImplI386::NumSupportedHardwareWatchpoints() {
   // Available debug address registers: dr0, dr1, dr2, dr3.
   return 4;
@@ -797,6 +802,151 @@ void DNBArchImplI386::SetWatchpoint(DBG &debug_state, uint32_t hw_index,
   return;
 }
 
+void DNBArchImplI386::SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index,
+                                            nub_addr_t addr, nub_size_t size) {
+  // Set both dr7 (debug control register) and dri (debug address register).
+
+  // dr7{7-0} encodes the local/gloabl enable bits:
+  //  global enable --. .-- local enable
+  //                  | |
+  //                  v v
+  //      dr0 -> bits{1-0}
+  //      dr1 -> bits{3-2}
+  //      dr2 -> bits{5-4}
+  //      dr3 -> bits{7-6}
+  //
+  // dr7{31-16} encodes the rw/len bits:
+  //  b_x+3, b_x+2, b_x+1, b_x
+  //      where bits{x+1, x} => rw
+  //            0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io
+  //            read-or-write (unused)
+  //      and bits{x+3, x+2} => len
+  //            0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+  //
+  //      dr0 -> bits{19-16}
+  //      dr1 -> bits{23-20}
+  //      dr2 -> bits{27-24}
+  //      dr3 -> bits{31-28}
+  debug_state.__dr7 |= (1 << (2 * hw_index) | 0 << (16 + 4 * hw_index));
+  uint32_t addr_32 = addr & 0xffffffff;
+  switch (hw_index) {
+  case 0:
+    debug_state.__dr0 = addr_32;
+    break;
+  case 1:
+    debug_state.__dr1 = addr_32;
+    break;
+  case 2:
+    debug_state.__dr2 = addr_32;
+    break;
+  case 3:
+    debug_state.__dr3 = addr_32;
+    break;
+  default:
+    assert(0 &&
+           "invalid hardware register index, must be one of 0, 1, 2, or 3");
+  }
+  return;
+}
+
+uint32_t DNBArchImplI386::EnableHardwareBreakpoint(nub_addr_t addr,
+                                                   nub_size_t size,
+                                                   bool also_set_on_task) {
+  DNBLogThreadedIf(LOG_BREAKPOINTS,
+                   "DNBArchImplI386::EnableHardwareBreakpoint( addr = "
+                   "0x%8.8llx, size = %llu )",
+                   (uint64_t)addr, (uint64_t)size);
+
+  const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
+  // Read the debug state
+  kern_return_t kret = GetDBGState(false);
+
+  if (kret != KERN_SUCCESS) {
+    return INVALID_NUB_HW_INDEX;
+  }
+
+  // Check to make sure we have the needed hardware support
+  uint32_t i = 0;
+
+  DBG &debug_state = m_state.context.dbg;
+  for (i = 0; i < num_hw_breakpoints; ++i) {
+    if (IsWatchpointVacant(debug_state, i)) {
+      break;
+    }
+  }
+
+  // See if we found an available hw breakpoint slot above
+  if (i < num_hw_breakpoints) {
+    DNBLogThreadedIf(
+        LOG_BREAKPOINTS,
+        "DNBArchImplI386::EnableHardwareBreakpoint( free slot = %u )", i);
+
+    StartTransForHWP();
+
+    // Modify our local copy of the debug state, first.
+    SetHardwareBreakpoint(debug_state, i, addr, size);
+    // Now set the watch point in the inferior.
+    kret = SetDBGState(also_set_on_task);
+
+    DNBLogThreadedIf(LOG_BREAKPOINTS,
+                     "DNBArchImplI386::"
+                     "EnableHardwareBreakpoint() "
+                     "SetDBGState() => 0x%8.8x.",
+                     kret);
+
+    if (kret == KERN_SUCCESS) {
+      DNBLogThreadedIf(
+          LOG_BREAKPOINTS,
+          "DNBArchImplI386::EnableHardwareBreakpoint( enabled at slot = %u)",
+          i);
+      return i;
+    }
+    // Revert to the previous debug state voluntarily.  The transaction
+    // coordinator knows that we have failed.
+    else {
+      m_state.context.dbg = GetDBGCheckpoint();
+    }
+  } else {
+    DNBLogThreadedIf(LOG_BREAKPOINTS,
+                     "DNBArchImplI386::EnableHardwareBreakpoint(addr = "
+                     "0x%8.8llx, size = %llu) => all hardware breakpoint "
+                     "resources are being used.",
+                     (uint64_t)addr, (uint64_t)size);
+  }
+
+  return INVALID_NUB_HW_INDEX;
+}
+
+bool DNBArchImplI386::DisableHardwareBreakpoint(uint32_t hw_index,
+                                                bool also_set_on_task) {
+  kern_return_t kret = GetDBGState(false);
+
+  const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
+  if (kret == KERN_SUCCESS) {
+    DBG &debug_state = m_state.context.dbg;
+    if (hw_index < num_hw_points &&
+        !IsWatchpointVacant(debug_state, hw_index)) {
+
+      StartTransForHWP();
+
+      // Modify our local copy of the debug state, first.
+      ClearWatchpoint(debug_state, hw_index);
+      // Now disable the watch point in the inferior.
+      kret = SetDBGState(true);
+      DNBLogThreadedIf(LOG_WATCHPOINTS,
+                       "DNBArchImplI386::DisableHardwareBreakpoint( %u )",
+                       hw_index);
+
+      if (kret == KERN_SUCCESS)
+        return true;
+      else // Revert to the previous debug state voluntarily.  The transaction
+           // coordinator knows that we have failed.
+        m_state.context.dbg = GetDBGCheckpoint();
+    }
+  }
+  return false;
+}
+
 void DNBArchImplI386::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) {
   debug_state.__dr7 &= ~(3 << (2 * hw_index));
   switch (hw_index) {

diff  --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
index 12b515a29575..dfd2ef0c8541 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
@@ -51,7 +51,12 @@ class DNBArchImplI386 : public DNBArchProtocol {
   virtual bool ThreadDidStop();
   virtual bool NotifyException(MachException::Data &exc);
 
+  virtual uint32_t NumSupportedHardwareBreakpoints();
   virtual uint32_t NumSupportedHardwareWatchpoints();
+  virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size,
+                                            bool also_set_on_task);
+  virtual bool DisableHardwareBreakpoint(uint32_t hw_index,
+                                         bool also_set_on_task);
   virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,
                                             bool read, bool write,
                                             bool also_set_on_task);
@@ -210,6 +215,9 @@ class DNBArchImplI386 : public DNBArchProtocol {
 
   static uint32_t GetRegisterContextSize();
 
+  static void SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index,
+                                    nub_addr_t addr, nub_size_t size);
+
   // Helper functions for watchpoint manipulations.
   static void SetWatchpoint(DBG &debug_state, uint32_t hw_index,
                             nub_addr_t addr, nub_size_t size, bool read,

diff  --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
index 319215e8a7f4..519b6277fd06 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
@@ -679,6 +679,12 @@ uint32_t DNBArchImplX86_64::NumSupportedHardwareWatchpoints() {
   return 4;
 }
 
+uint32_t DNBArchImplX86_64::NumSupportedHardwareBreakpoints() {
+  DNBLogThreadedIf(LOG_BREAKPOINTS,
+                   "DNBArchImplX86_64::NumSupportedHardwareBreakpoints");
+  return 4;
+}
+
 static uint32_t size_and_rw_bits(nub_size_t size, bool read, bool write) {
   uint32_t rw;
   if (read) {
@@ -853,6 +859,153 @@ DNBArchImplX86_64::DBG DNBArchImplX86_64::GetDBGCheckpoint() {
   return m_2pc_dbg_checkpoint;
 }
 
+void DNBArchImplX86_64::SetHardwareBreakpoint(DBG &debug_state,
+                                              uint32_t hw_index,
+                                              nub_addr_t addr,
+                                              nub_size_t size) {
+  // Set both dr7 (debug control register) and dri (debug address register).
+
+  // dr7{7-0} encodes the local/gloabl enable bits:
+  //  global enable --. .-- local enable
+  //                  | |
+  //                  v v
+  //      dr0 -> bits{1-0}
+  //      dr1 -> bits{3-2}
+  //      dr2 -> bits{5-4}
+  //      dr3 -> bits{7-6}
+  //
+  // dr7{31-16} encodes the rw/len bits:
+  //  b_x+3, b_x+2, b_x+1, b_x
+  //      where bits{x+1, x} => rw
+  //            0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io
+  //            read-or-write (unused)
+  //      and bits{x+3, x+2} => len
+  //            0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+  //
+  //      dr0 -> bits{19-16}
+  //      dr1 -> bits{23-20}
+  //      dr2 -> bits{27-24}
+  //      dr3 -> bits{31-28}
+  debug_state.__dr7 |= (1 << (2 * hw_index) | 0 << (16 + 4 * hw_index));
+
+  switch (hw_index) {
+  case 0:
+    debug_state.__dr0 = addr;
+    break;
+  case 1:
+    debug_state.__dr1 = addr;
+    break;
+  case 2:
+    debug_state.__dr2 = addr;
+    break;
+  case 3:
+    debug_state.__dr3 = addr;
+    break;
+  default:
+    assert(0 &&
+           "invalid hardware register index, must be one of 0, 1, 2, or 3");
+  }
+  return;
+}
+
+uint32_t DNBArchImplX86_64::EnableHardwareBreakpoint(nub_addr_t addr,
+                                                     nub_size_t size,
+                                                     bool also_set_on_task) {
+  DNBLogThreadedIf(LOG_BREAKPOINTS,
+                   "DNBArchImplX86_64::EnableHardwareBreakpoint( addr = "
+                   "0x%8.8llx, size = %llu )",
+                   (uint64_t)addr, (uint64_t)size);
+
+  const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
+  // Read the debug state
+  kern_return_t kret = GetDBGState(false);
+
+  if (kret != KERN_SUCCESS) {
+    return INVALID_NUB_HW_INDEX;
+  }
+
+  // Check to make sure we have the needed hardware support
+  uint32_t i = 0;
+
+  DBG &debug_state = m_state.context.dbg;
+  for (i = 0; i < num_hw_breakpoints; ++i) {
+    if (IsWatchpointVacant(debug_state, i)) {
+      break;
+    }
+  }
+
+  // See if we found an available hw breakpoint slot above
+  if (i < num_hw_breakpoints) {
+    DNBLogThreadedIf(
+        LOG_BREAKPOINTS,
+        "DNBArchImplX86_64::EnableHardwareBreakpoint( free slot = %u )", i);
+
+    StartTransForHWP();
+
+    // Modify our local copy of the debug state, first.
+    SetHardwareBreakpoint(debug_state, i, addr, size);
+    // Now set the watch point in the inferior.
+    kret = SetDBGState(also_set_on_task);
+
+    DNBLogThreadedIf(LOG_BREAKPOINTS,
+                     "DNBArchImplX86_64::"
+                     "EnableHardwareBreakpoint() "
+                     "SetDBGState() => 0x%8.8x.",
+                     kret);
+
+    if (kret == KERN_SUCCESS) {
+      DNBLogThreadedIf(
+          LOG_BREAKPOINTS,
+          "DNBArchImplX86_64::EnableHardwareBreakpoint( enabled at slot = %u)",
+          i);
+      return i;
+    }
+    // Revert to the previous debug state voluntarily.  The transaction
+    // coordinator knows that we have failed.
+    else {
+      m_state.context.dbg = GetDBGCheckpoint();
+    }
+  } else {
+    DNBLogThreadedIf(LOG_BREAKPOINTS,
+                     "DNBArchImplX86_64::EnableHardwareBreakpoint(addr = "
+                     "0x%8.8llx, size = %llu) => all hardware breakpoint "
+                     "resources are being used.",
+                     (uint64_t)addr, (uint64_t)size);
+  }
+
+  return INVALID_NUB_HW_INDEX;
+}
+
+bool DNBArchImplX86_64::DisableHardwareBreakpoint(uint32_t hw_index,
+                                                  bool also_set_on_task) {
+  kern_return_t kret = GetDBGState(false);
+
+  const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
+  if (kret == KERN_SUCCESS) {
+    DBG &debug_state = m_state.context.dbg;
+    if (hw_index < num_hw_points &&
+        !IsWatchpointVacant(debug_state, hw_index)) {
+
+      StartTransForHWP();
+
+      // Modify our local copy of the debug state, first.
+      ClearWatchpoint(debug_state, hw_index);
+      // Now disable the watch point in the inferior.
+      kret = SetDBGState(true);
+      DNBLogThreadedIf(LOG_WATCHPOINTS,
+                       "DNBArchImplX86_64::DisableHardwareBreakpoint( %u )",
+                       hw_index);
+
+      if (kret == KERN_SUCCESS)
+        return true;
+      else // Revert to the previous debug state voluntarily.  The transaction
+           // coordinator knows that we have failed.
+        m_state.context.dbg = GetDBGCheckpoint();
+    }
+  }
+  return false;
+}
+
 uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint(nub_addr_t addr,
                                                      nub_size_t size, bool read,
                                                      bool write,

diff  --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
index 62ce37d4c049..94c3969084a8 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
@@ -50,7 +50,13 @@ class DNBArchImplX86_64 : public DNBArchProtocol {
   virtual bool ThreadDidStop();
   virtual bool NotifyException(MachException::Data &exc);
 
+  virtual uint32_t NumSupportedHardwareBreakpoints();
   virtual uint32_t NumSupportedHardwareWatchpoints();
+
+  virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size,
+                                            bool also_set_on_task);
+  virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index,
+                                         bool also_set_on_task);
   virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,
                                             bool read, bool write,
                                             bool also_set_on_task);
@@ -213,6 +219,9 @@ class DNBArchImplX86_64 : public DNBArchProtocol {
 
   static uint32_t GetRegisterContextSize();
 
+  static void SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index,
+                                    nub_addr_t addr, nub_size_t size);
+
   // Helper functions for watchpoint manipulations.
   static void SetWatchpoint(DBG &debug_state, uint32_t hw_index,
                             nub_addr_t addr, nub_size_t size, bool read,

diff  --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 64e3bc49abc8..6f2c7353b723 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -279,12 +279,10 @@ void RNBRemote::CreatePacketTable() {
                      "x", "Read data from memory"));
   t.push_back(Packet(write_data_to_memory, &RNBRemote::HandlePacket_X, NULL,
                      "X", "Write data to memory"));
-  //  t.push_back (Packet (insert_hardware_bp,
-  //  &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware
-  //  breakpoint"));
-  //  t.push_back (Packet (remove_hardware_bp,
-  //  &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware
-  //  breakpoint"));
+  t.push_back(Packet(insert_hardware_bp, &RNBRemote::HandlePacket_z, NULL, "Z1",
+                     "Insert hardware breakpoint"));
+  t.push_back(Packet(remove_hardware_bp, &RNBRemote::HandlePacket_z, NULL, "z1",
+                     "Remove hardware breakpoint"));
   t.push_back(Packet(insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL,
                      "Z2", "Insert write watchpoint"));
   t.push_back(Packet(remove_write_watch_bp, &RNBRemote::HandlePacket_z, NULL,


        


More information about the lldb-commits mailing list