summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
diff options
context:
space:
mode:
authorChaoren Lin <chaorenl@google.com>2015-03-19 23:28:10 +0000
committerChaoren Lin <chaorenl@google.com>2015-03-19 23:28:10 +0000
commitc16f5dca27c693f934b12c948b7d53e98ce9111d (patch)
tree7e0049694785f47b4700df8c65117bf9b06dc56e /lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
parentd83003ea59ca5592580fa2e0ef27c3cac907aa8f (diff)
downloadbcm5719-llvm-c16f5dca27c693f934b12c948b7d53e98ce9111d.tar.gz
bcm5719-llvm-c16f5dca27c693f934b12c948b7d53e98ce9111d.zip
Report watchpoint hits during single stepping.
Summary: Reorganized NativeProcessLinux::MonitorSIGTRAP to check for watchpoint hits on TRAP_TRACE. Added test for stepping over watchpoints. https://llvm.org/bugs/show_bug.cgi?id=22814 Reviewers: ovyalov, tberghammer, vharron, clayborg Subscribers: jingham, labath, lldb-commits Differential Revision: http://reviews.llvm.org/D8404 llvm-svn: 232784
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp67
1 files changed, 51 insertions, 16 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index fa6dfd64b88..06ad5f296ec 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -9,6 +9,7 @@
#include "NativeRegisterContextLinux_x86_64.h"
+#include "lldb/Core/Log.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
@@ -1046,39 +1047,61 @@ NativeRegisterContextLinux_x86_64::WriteGPR()
}
Error
-NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint8_t wp_index)
+NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
{
if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+ return Error("Watchpoint index out of range");
RegisterValue reg_value;
Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return error;
+ if (error.Fail())
+ {
+ is_hit = false;
+ return error;
+ }
uint64_t status_bits = reg_value.GetAsUInt64();
- bool is_hit = status_bits & (1 << wp_index);
-
- error.SetError (!is_hit, lldb::eErrorTypeInvalid);
+ is_hit = status_bits & (1 << wp_index);
return error;
}
Error
-NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index)
+NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(uint32_t &wp_index) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
+ {
+ bool is_hit;
+ Error 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 Error();
+}
+
+Error
+NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
{
if (wp_index >= NumSupportedHardwareWatchpoints())
return Error ("Watchpoint index out of range");
RegisterValue reg_value;
Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
+ if (error.Fail())
+ {
+ is_vacant = false;
+ return error;
+ }
uint64_t control_bits = reg_value.GetAsUInt64();
- bool is_vacant = !(control_bits & (1 << (2 * wp_index)));
-
- error.SetError (!is_vacant, lldb::eErrorTypeInvalid);
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
return error;
}
@@ -1096,8 +1119,10 @@ NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
if (size != 1 && size != 2 && size != 4 && size != 8)
return Error ("Invalid size for watchpoint");
- Error error = IsWatchpointVacant (wp_index);
+ bool is_vacant;
+ Error error = IsWatchpointVacant (wp_index, is_vacant);
if (error.Fail()) return error;
+ if (!is_vacant) return Error("Watchpoint index not vacant");
RegisterValue reg_value;
error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
@@ -1184,14 +1209,24 @@ 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)
- if (IsWatchpointVacant(wp_index).Success())
+ {
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant)
{
- if (SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index).Fail())
- continue;
- return wp_index;
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
}
+ if (error.Fail() && log)
+ {
+ log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
return LLDB_INVALID_INDEX32;
}
OpenPOWER on IntegriCloud