diff options
author | Pavel Labath <pavel@labath.sk> | 2018-10-03 12:29:33 +0000 |
---|---|---|
committer | Pavel Labath <pavel@labath.sk> | 2018-10-03 12:29:33 +0000 |
commit | aef7908f6eb060b928f4aa820e4ba5e316ee5e00 (patch) | |
tree | d2f6ba18a4b314b91337e84f03e2da1030ef19ed /lldb/source/Host/common/NativeProcessProtocol.cpp | |
parent | af50a5b85fe82d8b965142ddf5bfd843efed67d0 (diff) | |
download | llvm-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.cpp | 62 |
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) |