[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