diff options
Diffstat (limited to 'lldb/tools/debugserver')
5 files changed, 236 insertions, 6 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index f8b93d4ea0c..0acdb823cb2 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -625,6 +625,117 @@ DNBArchImplI386::NotifyException(MachException::Data& exc) return false; } +#ifndef DR_FIRSTADDR +#define DR_FIRSTADDR 0 +#endif + +#ifndef DR_LASTADDR +#define DR_LASTADDR 3 +#endif + +#ifndef DR_STATUS +#define DR_STATUS 6 +#endif + +#ifndef DR_CONTROL +#define DR_CONTROL 7 +#endif + +uint32_t +DNBArchImplI386::NumSupportedHardwareWatchpoints() +{ + return DR_LASTADDR - DR_FIRSTADDR + 1; +} + +uint32_t +DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) +{ + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); + + const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); + + // Can't watch zero bytes + if (size == 0) + return INVALID_NUB_HW_INDEX; + + // We must watch for either read or write + if (read == false && write == false) + return INVALID_NUB_HW_INDEX; + + // + // FIXME: Add implmentation. + // + + // Read the debug state + kern_return_t kret = GetDBGState(false); + + if (kret == KERN_SUCCESS) + { + // 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_watchpoints; ++i) + { + uint64_t dr_val = 0; + switch (i) { + case 0: + dr_val = debug_state.__dr0; break; + case 1: + dr_val = debug_state.__dr1; break; + case 2: + dr_val = debug_state.__dr2; break; + case 3: + dr_val = debug_state.__dr3; break; + default: + break; + } + if (dr_val != 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_watchpoints) + { + kret = SetDBGState(); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImpI386::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); + + if (kret == KERN_SUCCESS) + return i; + } + else + { + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImpl386::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); + } + } + return INVALID_NUB_HW_INDEX; +} + +bool +DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) +{ + kern_return_t kret = GetDBGState(false); + + const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); + if (kret == KERN_SUCCESS) + { + if (hw_index < num_hw_points) + { + // + // FIXEME: Add implementation. + // + + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::DisableHardwareWatchpoint( %u )", + hw_index); + + kret = SetDBGState(); + + if (kret == KERN_SUCCESS) + return true; + } + } + return false; +} // Set the single step bit in the processor status register. kern_return_t diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index fd8049ad32d..83a41530da9 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -51,6 +51,10 @@ public: virtual bool ThreadDidStop(); virtual bool NotifyException(MachException::Data& exc); + virtual uint32_t NumSupportedHardwareWatchpoints(); + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); + virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); + protected: kern_return_t EnableHardwareSingleStep (bool enable); 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 b5a40a8def3..ce46b19d411 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -554,6 +554,117 @@ DNBArchImplX86_64::NotifyException(MachException::Data& exc) return false; } +#ifndef DR_FIRSTADDR +#define DR_FIRSTADDR 0 +#endif + +#ifndef DR_LASTADDR +#define DR_LASTADDR 3 +#endif + +#ifndef DR_STATUS +#define DR_STATUS 6 +#endif + +#ifndef DR_CONTROL +#define DR_CONTROL 7 +#endif + +uint32_t +DNBArchImplX86_64::NumSupportedHardwareWatchpoints() +{ + return DR_LASTADDR - DR_FIRSTADDR + 1; +} + +uint32_t +DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) +{ + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); + + const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); + + // Can't watch zero bytes + if (size == 0) + return INVALID_NUB_HW_INDEX; + + // We must watch for either read or write + if (read == false && write == false) + return INVALID_NUB_HW_INDEX; + + // + // FIXME: Add implmentation. + // + + // Read the debug state + kern_return_t kret = GetDBGState(false); + + if (kret == KERN_SUCCESS) + { + // 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_watchpoints; ++i) + { + uint64_t dr_val = 0; + switch (i) { + case 0: + dr_val = debug_state.__dr0; break; + case 1: + dr_val = debug_state.__dr1; break; + case 2: + dr_val = debug_state.__dr2; break; + case 3: + dr_val = debug_state.__dr3; break; + default: + break; + } + if (dr_val != 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_watchpoints) + { + kret = SetDBGState(); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); + + if (kret == KERN_SUCCESS) + return i; + } + else + { + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); + } + } + return INVALID_NUB_HW_INDEX; +} + +bool +DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) +{ + kern_return_t kret = GetDBGState(false); + + const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); + if (kret == KERN_SUCCESS) + { + if (hw_index < num_hw_points) + { + // + // FIXEME: Add implementation. + // + + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::DisableHardwareWatchpoint( %u )", + hw_index); + + kret = SetDBGState(); + + if (kret == KERN_SUCCESS) + return true; + } + } + return false; +} // Set the single step bit in the processor status register. kern_return_t 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 f4e323f5023..e02ac63060d 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -50,6 +50,10 @@ public: virtual bool ThreadDidStop(); virtual bool NotifyException(MachException::Data& exc); + virtual uint32_t NumSupportedHardwareWatchpoints(); + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); + virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); + protected: kern_return_t EnableHardwareSingleStep (bool enable); diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 2b32688bd24..c95eb45be92 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -147,12 +147,12 @@ RNBRemote::CreatePacketTable () // 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_write_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z2", "Insert write watchpoint")); -// t.push_back (Packet (remove_write_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z2", "Remove write watchpoint")); -// t.push_back (Packet (insert_read_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z3", "Insert read watchpoint")); -// t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z3", "Remove read watchpoint")); -// t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z4", "Insert access watchpoint")); -// t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z4", "Remove access watchpoint")); + 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, "z2", "Remove write watchpoint")); + t.push_back (Packet (insert_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z3", "Insert read watchpoint")); + t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z3", "Remove read watchpoint")); + t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z4", "Insert access watchpoint")); + t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z4", "Remove access watchpoint")); t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID")); t.push_back (Packet (query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id")); // t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region")); |

