[Lldb-commits] [lldb] 2981ece - [debugserver] Share code between Enable/DisableHardwareWatchpoint (NFC)

2020-01-18 Thread Jonas Devlieghere via lldb-commits

Author: Jonas Devlieghere
Date: 2020-01-18T11:36:56-08:00
New Revision: 2981eceec337c26befe5f5d1b1031b254240e21d

URL: 
https://github.com/llvm/llvm-project/commit/2981eceec337c26befe5f5d1b1031b254240e21d
DIFF: 
https://github.com/llvm/llvm-project/commit/2981eceec337c26befe5f5d1b1031b254240e21d.diff

LOG: [debugserver] Share code between Enable/DisableHardwareWatchpoint (NFC)

This extract the common functionality of enabling and disabling hardware
watchpoints into a single function.

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

Added: 


Modified: 
lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
lldb/tools/debugserver/source/MacOSX/MachThreadList.h

Removed: 




diff  --git a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp 
b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
index d2aae9da0c4d..a086de6ab405 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
@@ -502,65 +502,56 @@ bool MachThreadList::DisableHardwareBreakpoint(const 
DNBBreakpoint *bp) const {
   return false;
 }
 
+uint32_t MachThreadList::DoHardwareBreakpointAction(
+const DNBBreakpoint *wp, HardwareBreakpointAction action) const {
+  if (wp == NULL)
+return INVALID_NUB_HW_INDEX;
+
+  uint32_t hw_index = INVALID_NUB_HW_INDEX;
+  PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
+  const size_t num_threads = m_threads.size();
+  // On Mac OS X we have to prime the control registers for new threads.  We do
+  // this using the control register data for the first thread, for lack of a
+  // better way of choosing.
+  bool also_set_on_task = true;
+  for (uint32_t idx = 0; idx < num_threads; ++idx) {
+switch (action) {
+case HardwareBreakpointAction::EnableWatchpoint:
+  hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, 
also_set_on_task);
+  break;
+case HardwareBreakpointAction::DisableWatchpoint:
+  hw_index =
+  m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task);
+  break;
+}
+if (hw_index == INVALID_NUB_HW_INDEX) {
+  // We know that idx failed for some reason.  Let's rollback the
+  // transaction for [0, idx).
+  for (uint32_t i = 0; i < idx; ++i)
+m_threads[i]->RollbackTransForHWP();
+  return INVALID_NUB_HW_INDEX;
+}
+also_set_on_task = false;
+  }
+  // Notify each thread to commit the pending transaction.
+  for (uint32_t idx = 0; idx < num_threads; ++idx)
+m_threads[idx]->FinishTransForHWP();
+  return hw_index;
+}
+
 // DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
 // MachProcess::EnableWatchpoint()
 // -> MachThreadList::EnableHardwareWatchpoint().
 uint32_t
 MachThreadList::EnableHardwareWatchpoint(const DNBBreakpoint *wp) const {
-  uint32_t hw_index = INVALID_NUB_HW_INDEX;
-  if (wp != NULL) {
-PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
-const size_t num_threads = m_threads.size();
-// On Mac OS X we have to prime the control registers for new threads.  We
-// do this
-// using the control register data for the first thread, for lack of a
-// better way of choosing.
-bool also_set_on_task = true;
-for (uint32_t idx = 0; idx < num_threads; ++idx) {
-  if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(
-   wp, also_set_on_task)) == INVALID_NUB_HW_INDEX) {
-// We know that idx failed for some reason.  Let's rollback the
-// transaction for [0, idx).
-for (uint32_t i = 0; i < idx; ++i)
-  m_threads[i]->RollbackTransForHWP();
-return INVALID_NUB_HW_INDEX;
-  }
-  also_set_on_task = false;
-}
-// Notify each thread to commit the pending transaction.
-for (uint32_t idx = 0; idx < num_threads; ++idx)
-  m_threads[idx]->FinishTransForHWP();
-  }
-  return hw_index;
+  return DoHardwareBreakpointAction(wp,
+
HardwareBreakpointAction::EnableWatchpoint);
 }
 
 bool MachThreadList::DisableHardwareWatchpoint(const DNBBreakpoint *wp) const {
-  if (wp != NULL) {
-PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
-const size_t num_threads = m_threads.size();
-
-// On Mac OS X we have to prime the control registers for new threads.  We
-// do this
-// using the control register data for the first thread, for lack of a
-// better way of choosing.
-bool also_set_on_task = true;
-for (uint32_t idx = 0; idx < num_threads; ++idx) {
-  if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task)) {
-// We know that idx failed for some reason.  Let's rollback the
-// transaction for [0, idx).
-for (uint32_t i = 0; i < idx; ++i)
-  m_threads[i]->RollbackTransForHWP();
-return false;
-  }
-  also_set_on_task = false;
-}
-// Notify each thread to commit the pending transaction.
-

[Lldb-commits] [PATCH] D72971: [debugserver] Share code between Enable/DisableHardwareWatchpoint (NFC)

2020-01-18 Thread Jonas Devlieghere via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2981eceec337: [debugserver] Share code between 
Enable/DisableHardwareWatchpoint (NFC) (authored by JDevlieghere).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72971

Files:
  lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
  lldb/tools/debugserver/source/MacOSX/MachThreadList.h

Index: lldb/tools/debugserver/source/MacOSX/MachThreadList.h
===
--- lldb/tools/debugserver/source/MacOSX/MachThreadList.h
+++ lldb/tools/debugserver/source/MacOSX/MachThreadList.h
@@ -83,6 +83,14 @@
   typedef collection::iterator iterator;
   typedef collection::const_iterator const_iterator;
 
+  enum class HardwareBreakpointAction {
+EnableWatchpoint,
+DisableWatchpoint,
+  };
+
+  uint32_t DoHardwareBreakpointAction(const DNBBreakpoint *wp,
+  HardwareBreakpointAction action) const;
+
   uint32_t UpdateThreadList(MachProcess *process, bool update,
 collection *num_threads = NULL);
   //  const_iterator  FindThreadByID (thread_t tid) const;
Index: lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
===
--- lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
@@ -502,65 +502,56 @@
   return false;
 }
 
+uint32_t MachThreadList::DoHardwareBreakpointAction(
+const DNBBreakpoint *wp, HardwareBreakpointAction action) const {
+  if (wp == NULL)
+return INVALID_NUB_HW_INDEX;
+
+  uint32_t hw_index = INVALID_NUB_HW_INDEX;
+  PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
+  const size_t num_threads = m_threads.size();
+  // On Mac OS X we have to prime the control registers for new threads.  We do
+  // this using the control register data for the first thread, for lack of a
+  // better way of choosing.
+  bool also_set_on_task = true;
+  for (uint32_t idx = 0; idx < num_threads; ++idx) {
+switch (action) {
+case HardwareBreakpointAction::EnableWatchpoint:
+  hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task);
+  break;
+case HardwareBreakpointAction::DisableWatchpoint:
+  hw_index =
+  m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task);
+  break;
+}
+if (hw_index == INVALID_NUB_HW_INDEX) {
+  // We know that idx failed for some reason.  Let's rollback the
+  // transaction for [0, idx).
+  for (uint32_t i = 0; i < idx; ++i)
+m_threads[i]->RollbackTransForHWP();
+  return INVALID_NUB_HW_INDEX;
+}
+also_set_on_task = false;
+  }
+  // Notify each thread to commit the pending transaction.
+  for (uint32_t idx = 0; idx < num_threads; ++idx)
+m_threads[idx]->FinishTransForHWP();
+  return hw_index;
+}
+
 // DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
 // MachProcess::EnableWatchpoint()
 // -> MachThreadList::EnableHardwareWatchpoint().
 uint32_t
 MachThreadList::EnableHardwareWatchpoint(const DNBBreakpoint *wp) const {
-  uint32_t hw_index = INVALID_NUB_HW_INDEX;
-  if (wp != NULL) {
-PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
-const size_t num_threads = m_threads.size();
-// On Mac OS X we have to prime the control registers for new threads.  We
-// do this
-// using the control register data for the first thread, for lack of a
-// better way of choosing.
-bool also_set_on_task = true;
-for (uint32_t idx = 0; idx < num_threads; ++idx) {
-  if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(
-   wp, also_set_on_task)) == INVALID_NUB_HW_INDEX) {
-// We know that idx failed for some reason.  Let's rollback the
-// transaction for [0, idx).
-for (uint32_t i = 0; i < idx; ++i)
-  m_threads[i]->RollbackTransForHWP();
-return INVALID_NUB_HW_INDEX;
-  }
-  also_set_on_task = false;
-}
-// Notify each thread to commit the pending transaction.
-for (uint32_t idx = 0; idx < num_threads; ++idx)
-  m_threads[idx]->FinishTransForHWP();
-  }
-  return hw_index;
+  return DoHardwareBreakpointAction(wp,
+HardwareBreakpointAction::EnableWatchpoint);
 }
 
 bool MachThreadList::DisableHardwareWatchpoint(const DNBBreakpoint *wp) const {
-  if (wp != NULL) {
-PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
-const size_t num_threads = m_threads.size();
-
-// On Mac OS X we have to prime the control registers for new threads.  We
-// do this
-// using the control register data for the first thread, for lack of a
-// better way of choosing.
-bool also_set_on_task = true;
-for (uint32_t idx = 0; idx < num_threads; ++idx) {
-  if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task

[Lldb-commits] [PATCH] D72981: [debugserver] Unify the breakpoint/watchpoint interface (NFCI)

2020-01-18 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere created this revision.
JDevlieghere added a reviewer: jasonmolenda.
Herald added a project: LLDB.
JDevlieghere added a parent revision: D72971: [debugserver] Share code between 
Enable/DisableHardwareWatchpoint (NFC).

Unify the interface for enabling and disabling breakpoints with their 
watchpoint counterpart. This allows both to go through 
`DoHardwareBreakpointAction`.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D72981

Files:
  lldb/tools/debugserver/source/DNBArch.h
  lldb/tools/debugserver/source/MacOSX/MachThread.cpp
  lldb/tools/debugserver/source/MacOSX/MachThread.h
  lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
  lldb/tools/debugserver/source/MacOSX/MachThreadList.h

Index: lldb/tools/debugserver/source/MacOSX/MachThreadList.h
===
--- lldb/tools/debugserver/source/MacOSX/MachThreadList.h
+++ lldb/tools/debugserver/source/MacOSX/MachThreadList.h
@@ -86,9 +86,11 @@
   enum class HardwareBreakpointAction {
 EnableWatchpoint,
 DisableWatchpoint,
+EnableBreakpoint,
+DisableBreakpoint,
   };
 
-  uint32_t DoHardwareBreakpointAction(const DNBBreakpoint *wp,
+  uint32_t DoHardwareBreakpointAction(const DNBBreakpoint *bp,
   HardwareBreakpointAction action) const;
 
   uint32_t UpdateThreadList(MachProcess *process, bool update,
Index: lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
===
--- lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
@@ -483,28 +483,9 @@
   }
 }
 
-uint32_t
-MachThreadList::EnableHardwareBreakpoint(const DNBBreakpoint *bp) const {
-  if (bp != NULL) {
-const size_t num_threads = m_threads.size();
-for (uint32_t idx = 0; idx < num_threads; ++idx)
-  m_threads[idx]->EnableHardwareBreakpoint(bp);
-  }
-  return INVALID_NUB_HW_INDEX;
-}
-
-bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const {
-  if (bp != NULL) {
-const size_t num_threads = m_threads.size();
-for (uint32_t idx = 0; idx < num_threads; ++idx)
-  m_threads[idx]->DisableHardwareBreakpoint(bp);
-  }
-  return false;
-}
-
 uint32_t MachThreadList::DoHardwareBreakpointAction(
-const DNBBreakpoint *wp, HardwareBreakpointAction action) const {
-  if (wp == NULL)
+const DNBBreakpoint *bp, HardwareBreakpointAction action) const {
+  if (bp == NULL)
 return INVALID_NUB_HW_INDEX;
 
   uint32_t hw_index = INVALID_NUB_HW_INDEX;
@@ -517,11 +498,18 @@
   for (uint32_t idx = 0; idx < num_threads; ++idx) {
 switch (action) {
 case HardwareBreakpointAction::EnableWatchpoint:
-  hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task);
+  hw_index = m_threads[idx]->EnableHardwareWatchpoint(bp, also_set_on_task);
   break;
 case HardwareBreakpointAction::DisableWatchpoint:
   hw_index =
-  m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task);
+  m_threads[idx]->DisableHardwareWatchpoint(bp, also_set_on_task);
+  break;
+case HardwareBreakpointAction::EnableBreakpoint:
+  hw_index = m_threads[idx]->EnableHardwareBreakpoint(bp, also_set_on_task);
+  break;
+case HardwareBreakpointAction::DisableBreakpoint:
+  hw_index =
+  m_threads[idx]->DisableHardwareBreakpoint(bp, also_set_on_task);
   break;
 }
 if (hw_index == INVALID_NUB_HW_INDEX) {
@@ -554,6 +542,18 @@
  INVALID_NUB_HW_INDEX;
 }
 
+uint32_t
+MachThreadList::EnableHardwareBreakpoint(const DNBBreakpoint *bp) const {
+  return DoHardwareBreakpointAction(bp,
+HardwareBreakpointAction::EnableBreakpoint);
+}
+
+bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const {
+  return DoHardwareBreakpointAction(
+ bp, HardwareBreakpointAction::DisableBreakpoint) !=
+ INVALID_NUB_HW_INDEX;
+}
+
 uint32_t MachThreadList::NumSupportedHardwareWatchpoints() const {
   PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
   const size_t num_threads = m_threads.size();
Index: lldb/tools/debugserver/source/MacOSX/MachThread.h
===
--- lldb/tools/debugserver/source/MacOSX/MachThread.h
+++ lldb/tools/debugserver/source/MacOSX/MachThread.h
@@ -66,10 +66,12 @@
   uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer
 
   DNBBreakpoint *CurrentBreakpoint();
-  uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
+  uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint,
+bool also_set_on_task);
   uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
 bool also_set_on_task);
-  bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
+  bool DisableHardwareBreakpoint(const

[Lldb-commits] [lldb] f78f15a - [lldb/Test] XFAIL TestRequireHWBreakpoints when HW BPs are avialable

2020-01-18 Thread Jonas Devlieghere via lldb-commits

Author: Jonas Devlieghere
Date: 2020-01-18T13:15:44-08:00
New Revision: f78f15a60ee42781cbe9fb04b6c40ef0e2cd093c

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

LOG: [lldb/Test] XFAIL TestRequireHWBreakpoints when HW BPs are avialable

Resolves PR44055

Added: 


Modified: 

lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py

Removed: 




diff  --git 
a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py
 
b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py
index 0bf82c4a310a..74f2fbb0c1a0 100644
--- 
a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py
+++ 
b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py
@@ -13,6 +13,17 @@ class BreakpointLocationsTestCase(TestBase):
 NO_DEBUG_INFO_TESTCASE = True
 mydir = TestBase.compute_mydir(__file__)
 
+def supports_hw_breakpoints(self):
+self.build()
+self.runCmd("file " + self.getBuildArtifact("a.out"),
+CURRENT_EXECUTABLE_SET)
+self.runCmd("breakpoint set -b main --hardware")
+self.runCmd("run")
+print(self.res.GetOutput())
+if 'stopped' in self.res.GetOutput():
+return 'Hardware breakpoints are supported'
+return None
+
 def test_breakpoint(self):
 """Test regular breakpoints when hardware breakpoints are required."""
 self.build()
@@ -25,8 +36,7 @@ def test_breakpoint(self):
 self.assertTrue(breakpoint.IsHardware())
 
 @skipIfWindows
-@expectedFailureAll(archs="aarch64", oslist="linux",
-
bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44055";)
+@expectedFailure(supports_hw_breakpoints)
 def test_step_range(self):
 """Test stepping when hardware breakpoints are required."""
 self.build()
@@ -48,8 +58,7 @@ def test_step_range(self):
 in error.GetCString())
 
 @skipIfWindows
-@expectedFailureAll(archs="aarch64", oslist="linux",
-
bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44055";)
+@expectedFailure(supports_hw_breakpoints)
 def test_step_out(self):
 """Test stepping out when hardware breakpoints are required."""
 self.build()
@@ -70,8 +79,7 @@ def test_step_out(self):
 in error.GetCString())
 
 @skipIfWindows
-@expectedFailureAll(archs="aarch64", oslist="linux",
-
bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44055";)
+@expectedFailure(supports_hw_breakpoints)
 def test_step_over(self):
 """Test stepping over when hardware breakpoints are required."""
 self.build()
@@ -90,8 +98,7 @@ def test_step_over(self):
 ])
 
 @skipIfWindows
-@expectedFailureAll(archs="aarch64", oslist="linux",
-
bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44055";)
+@expectedFailure(supports_hw_breakpoints)
 def test_step_until(self):
 """Test stepping until when hardware breakpoints are required."""
 self.build()



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D72985: [lldb/debugserver] Implement hardware breakpoints for x86_64 and i386

2020-01-18 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere created this revision.
JDevlieghere added reviewers: jasonmolenda, jingham.
Herald added a subscriber: abidh.
Herald added a project: LLDB.
JDevlieghere added a parent revision: D72981: [debugserver] Unify the 
breakpoint/watchpoint interface (NFCI).

This implements hardware breakpoints for x86_64 and i386 in debugserver. It's 
based on Pedro's patch sent to lldb-commits 
(http://lists.llvm.org/pipermail/lldb-commits/Week-of-Mon-20200113/060327.html) 
although most of it is the same as the existing hardware watchpoint 
implementation.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D72985

Files:
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py
  
lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.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

Index: lldb/tools/debugserver/source/RNBRemote.cpp
===
--- lldb/tools/debugserver/source/RNBRemote.cpp
+++ lldb/tools/debugserver/source/RNBRemote.cpp
@@ -279,12 +279,10 @@
  "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,
Index: lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
===
--- lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
+++ lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
@@ -50,7 +50,13 @@
   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 @@
 
   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,
Index: lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
===
--- lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
@@ -679,6 +679,12 @@
   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 @@
   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: