summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
commit061da546b983eb767bad15e67af1174fb0bcf31c (patch)
tree83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz
wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp')
-rw-r--r--gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp
new file mode 100644
index 00000000000..32ea2e67527
--- /dev/null
+++ b/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp
@@ -0,0 +1,203 @@
+//===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// ThreadPlanRunToAddress: Continue plan
+
+ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
+ bool stop_others)
+ : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
+ eVoteNoOpinion, eVoteNoOpinion),
+ m_stop_others(stop_others), m_addresses(), m_break_ids() {
+ m_addresses.push_back(
+ address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get()));
+ SetInitialBreakpoints();
+}
+
+ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread,
+ lldb::addr_t address,
+ bool stop_others)
+ : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
+ eVoteNoOpinion, eVoteNoOpinion),
+ m_stop_others(stop_others), m_addresses(), m_break_ids() {
+ m_addresses.push_back(
+ m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
+ SetInitialBreakpoints();
+}
+
+ThreadPlanRunToAddress::ThreadPlanRunToAddress(
+ Thread &thread, const std::vector<lldb::addr_t> &addresses,
+ bool stop_others)
+ : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
+ eVoteNoOpinion, eVoteNoOpinion),
+ m_stop_others(stop_others), m_addresses(addresses), m_break_ids() {
+ // Convert all addresses into opcode addresses to make sure we set
+ // breakpoints at the correct address.
+ Target &target = thread.GetProcess()->GetTarget();
+ std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
+ for (pos = m_addresses.begin(); pos != end; ++pos)
+ *pos = target.GetOpcodeLoadAddress(*pos);
+
+ SetInitialBreakpoints();
+}
+
+void ThreadPlanRunToAddress::SetInitialBreakpoints() {
+ size_t num_addresses = m_addresses.size();
+ m_break_ids.resize(num_addresses);
+
+ for (size_t i = 0; i < num_addresses; i++) {
+ Breakpoint *breakpoint;
+ breakpoint = m_thread.CalculateTarget()
+ ->CreateBreakpoint(m_addresses[i], true, false)
+ .get();
+ if (breakpoint != nullptr) {
+ if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations())
+ m_could_not_resolve_hw_bp = true;
+ m_break_ids[i] = breakpoint->GetID();
+ breakpoint->SetThreadID(m_thread.GetID());
+ breakpoint->SetBreakpointKind("run-to-address");
+ }
+ }
+}
+
+ThreadPlanRunToAddress::~ThreadPlanRunToAddress() {
+ size_t num_break_ids = m_break_ids.size();
+ for (size_t i = 0; i < num_break_ids; i++) {
+ m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
+ }
+ m_could_not_resolve_hw_bp = false;
+}
+
+void ThreadPlanRunToAddress::GetDescription(Stream *s,
+ lldb::DescriptionLevel level) {
+ size_t num_addresses = m_addresses.size();
+
+ if (level == lldb::eDescriptionLevelBrief) {
+ if (num_addresses == 0) {
+ s->Printf("run to address with no addresses given.");
+ return;
+ } else if (num_addresses == 1)
+ s->Printf("run to address: ");
+ else
+ s->Printf("run to addresses: ");
+
+ for (size_t i = 0; i < num_addresses; i++) {
+ DumpAddress(s->AsRawOstream(), m_addresses[i], sizeof(addr_t));
+ s->Printf(" ");
+ }
+ } else {
+ if (num_addresses == 0) {
+ s->Printf("run to address with no addresses given.");
+ return;
+ } else if (num_addresses == 1)
+ s->Printf("Run to address: ");
+ else {
+ s->Printf("Run to addresses: ");
+ }
+
+ for (size_t i = 0; i < num_addresses; i++) {
+ if (num_addresses > 1) {
+ s->Printf("\n");
+ s->Indent();
+ }
+
+ DumpAddress(s->AsRawOstream(), m_addresses[i], sizeof(addr_t));
+ s->Printf(" using breakpoint: %d - ", m_break_ids[i]);
+ Breakpoint *breakpoint =
+ m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get();
+ if (breakpoint)
+ breakpoint->Dump(s);
+ else
+ s->Printf("but the breakpoint has been deleted.");
+ }
+ }
+}
+
+bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
+ if (m_could_not_resolve_hw_bp) {
+ if (error)
+ error->Printf("Could not set hardware breakpoint(s)");
+ return false;
+ }
+
+ // If we couldn't set the breakpoint for some reason, then this won't work.
+ bool all_bps_good = true;
+ size_t num_break_ids = m_break_ids.size();
+ for (size_t i = 0; i < num_break_ids; i++) {
+ if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) {
+ all_bps_good = false;
+ if (error) {
+ error->Printf("Could not set breakpoint for address: ");
+ DumpAddress(error->AsRawOstream(), m_addresses[i], sizeof(addr_t));
+ error->Printf("\n");
+ }
+ }
+ }
+ return all_bps_good;
+}
+
+bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) {
+ return AtOurAddress();
+}
+
+bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) {
+ return AtOurAddress();
+}
+
+bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
+
+void ThreadPlanRunToAddress::SetStopOthers(bool new_value) {
+ m_stop_others = new_value;
+}
+
+StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; }
+
+bool ThreadPlanRunToAddress::WillStop() { return true; }
+
+bool ThreadPlanRunToAddress::MischiefManaged() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ if (AtOurAddress()) {
+ // Remove the breakpoint
+ size_t num_break_ids = m_break_ids.size();
+
+ for (size_t i = 0; i < num_break_ids; i++) {
+ if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) {
+ m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
+ m_break_ids[i] = LLDB_INVALID_BREAK_ID;
+ }
+ }
+ LLDB_LOGF(log, "Completed run to address plan.");
+ ThreadPlan::MischiefManaged();
+ return true;
+ } else
+ return false;
+}
+
+bool ThreadPlanRunToAddress::AtOurAddress() {
+ lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
+ bool found_it = false;
+ size_t num_addresses = m_addresses.size();
+ for (size_t i = 0; i < num_addresses; i++) {
+ if (m_addresses[i] == current_address) {
+ found_it = true;
+ break;
+ }
+ }
+ return found_it;
+}