aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Host/common/NativeProcessProtocol.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2018-10-03 12:29:33 +0000
committerPavel Labath <pavel@labath.sk>2018-10-03 12:29:33 +0000
commitaef7908f6eb060b928f4aa820e4ba5e316ee5e00 (patch)
treed2f6ba18a4b314b91337e84f03e2da1030ef19ed /lldb/source/Host/common/NativeProcessProtocol.cpp
parentaf50a5b85fe82d8b965142ddf5bfd843efed67d0 (diff)
downloadllvm-aef7908f6eb060b928f4aa820e4ba5e316ee5e00.zip
llvm-aef7908f6eb060b928f4aa820e4ba5e316ee5e00.tar.gz
llvm-aef7908f6eb060b928f4aa820e4ba5e316ee5e00.tar.bz2
Pull FixupBreakpointPCAsNeeded into base class
Summary: This function existed (with identical code) in both NativeProcessLinux and NativeProcessNetBSD, and it is likely that it would be useful to any future implementation of NativeProcessProtocol. Therefore I move it to the base class. Reviewers: krytarowski Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D52719 llvm-svn: 343683
Diffstat (limited to 'lldb/source/Host/common/NativeProcessProtocol.cpp')
-rw-r--r--lldb/source/Host/common/NativeProcessProtocol.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp
index ef063d5..5d0eff7 100644
--- a/lldb/source/Host/common/NativeProcessProtocol.cpp
+++ b/lldb/source/Host/common/NativeProcessProtocol.cpp
@@ -432,6 +432,68 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
}
}
+void NativeProcessProtocol::FixupBreakpointPCAsNeeded(
+ NativeThreadProtocol &thread) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
+
+ Status error;
+
+ // Find out the size of a breakpoint (might depend on where we are in the
+ // code).
+ NativeRegisterContext &context = thread.GetRegisterContext();
+
+ uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
+ LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
+ if (breakpoint_size == 0)
+ return;
+
+ // First try probing for a breakpoint at a software breakpoint location: PC -
+ // breakpoint size.
+ const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
+ lldb::addr_t breakpoint_addr = initial_pc_addr;
+ // Do not allow breakpoint probe to wrap around.
+ if (breakpoint_addr >= breakpoint_size)
+ breakpoint_addr -= breakpoint_size;
+
+ // Check if we stopped because of a breakpoint.
+ NativeBreakpointSP breakpoint_sp;
+ error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
+ if (!error.Success() || !breakpoint_sp) {
+ // We didn't find one at a software probe location. Nothing to do.
+ LLDB_LOG(log,
+ "pid {0} no lldb breakpoint found at current pc with "
+ "adjustment: {1}",
+ GetID(), breakpoint_addr);
+ return;
+ }
+
+ // If the breakpoint is not a software breakpoint, nothing to do.
+ if (!breakpoint_sp->IsSoftwareBreakpoint()) {
+ LLDB_LOG(
+ log,
+ "pid {0} breakpoint found at {1:x}, not software, nothing to adjust",
+ GetID(), breakpoint_addr);
+ return;
+ }
+
+ //
+ // We have a software breakpoint and need to adjust the PC.
+ //
+
+ // Change the program counter.
+ LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
+ thread.GetID(), initial_pc_addr, breakpoint_addr);
+
+ error = context.SetPC(breakpoint_addr);
+ if (error.Fail()) {
+ // This can happen in case the process was killed between the time we read
+ // the PC and when we are updating it. There's nothing better to do than to
+ // swallow the error.
+ LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
+ thread.GetID(), error);
+ }
+}
+
Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
bool hardware) {
if (hardware)