1 //===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Target/ThreadPlanRunToAddress.h" 11 #include "lldb/Target/Process.h" 12 #include "lldb/Target/RegisterContext.h" 13 #include "lldb/Target/Target.h" 14 #include "lldb/Target/Thread.h" 15 #include "lldb/Utility/Log.h" 16 #include "lldb/Utility/Stream.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 //---------------------------------------------------------------------- 22 // ThreadPlanRunToAddress: Continue plan 23 //---------------------------------------------------------------------- 24 25 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address, 26 bool stop_others) 27 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread, 28 eVoteNoOpinion, eVoteNoOpinion), 29 m_stop_others(stop_others), m_addresses(), m_break_ids() { 30 m_addresses.push_back( 31 address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get())); 32 SetInitialBreakpoints(); 33 } 34 35 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, 36 lldb::addr_t address, 37 bool stop_others) 38 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread, 39 eVoteNoOpinion, eVoteNoOpinion), 40 m_stop_others(stop_others), m_addresses(), m_break_ids() { 41 m_addresses.push_back( 42 m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 43 SetInitialBreakpoints(); 44 } 45 46 ThreadPlanRunToAddress::ThreadPlanRunToAddress( 47 Thread &thread, const std::vector<lldb::addr_t> &addresses, 48 bool stop_others) 49 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread, 50 eVoteNoOpinion, eVoteNoOpinion), 51 m_stop_others(stop_others), m_addresses(addresses), m_break_ids() { 52 // Convert all addresses into opcode addresses to make sure we set 53 // breakpoints at the correct address. 54 Target &target = thread.GetProcess()->GetTarget(); 55 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 56 for (pos = m_addresses.begin(); pos != end; ++pos) 57 *pos = target.GetOpcodeLoadAddress(*pos); 58 59 SetInitialBreakpoints(); 60 } 61 62 void ThreadPlanRunToAddress::SetInitialBreakpoints() { 63 size_t num_addresses = m_addresses.size(); 64 m_break_ids.resize(num_addresses); 65 66 for (size_t i = 0; i < num_addresses; i++) { 67 Breakpoint *breakpoint; 68 breakpoint = m_thread.CalculateTarget() 69 ->CreateBreakpoint(m_addresses[i], true, false) 70 .get(); 71 if (breakpoint != nullptr) { 72 if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations()) 73 m_could_not_resolve_hw_bp = true; 74 m_break_ids[i] = breakpoint->GetID(); 75 breakpoint->SetThreadID(m_thread.GetID()); 76 breakpoint->SetBreakpointKind("run-to-address"); 77 } 78 } 79 } 80 81 ThreadPlanRunToAddress::~ThreadPlanRunToAddress() { 82 size_t num_break_ids = m_break_ids.size(); 83 for (size_t i = 0; i < num_break_ids; i++) { 84 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); 85 } 86 m_could_not_resolve_hw_bp = false; 87 } 88 89 void ThreadPlanRunToAddress::GetDescription(Stream *s, 90 lldb::DescriptionLevel level) { 91 size_t num_addresses = m_addresses.size(); 92 93 if (level == lldb::eDescriptionLevelBrief) { 94 if (num_addresses == 0) { 95 s->Printf("run to address with no addresses given."); 96 return; 97 } else if (num_addresses == 1) 98 s->Printf("run to address: "); 99 else 100 s->Printf("run to addresses: "); 101 102 for (size_t i = 0; i < num_addresses; i++) { 103 s->Address(m_addresses[i], sizeof(addr_t)); 104 s->Printf(" "); 105 } 106 } else { 107 if (num_addresses == 0) { 108 s->Printf("run to address with no addresses given."); 109 return; 110 } else if (num_addresses == 1) 111 s->Printf("Run to address: "); 112 else { 113 s->Printf("Run to addresses: "); 114 } 115 116 for (size_t i = 0; i < num_addresses; i++) { 117 if (num_addresses > 1) { 118 s->Printf("\n"); 119 s->Indent(); 120 } 121 122 s->Address(m_addresses[i], sizeof(addr_t)); 123 s->Printf(" using breakpoint: %d - ", m_break_ids[i]); 124 Breakpoint *breakpoint = 125 m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get(); 126 if (breakpoint) 127 breakpoint->Dump(s); 128 else 129 s->Printf("but the breakpoint has been deleted."); 130 } 131 } 132 } 133 134 bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) { 135 if (m_could_not_resolve_hw_bp) { 136 if (error) 137 error->Printf("Could not set hardware breakpoint(s)"); 138 return false; 139 } 140 141 // If we couldn't set the breakpoint for some reason, then this won't work. 142 bool all_bps_good = true; 143 size_t num_break_ids = m_break_ids.size(); 144 for (size_t i = 0; i < num_break_ids; i++) { 145 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) { 146 all_bps_good = false; 147 if (error) { 148 error->Printf("Could not set breakpoint for address: "); 149 error->Address(m_addresses[i], sizeof(addr_t)); 150 error->Printf("\n"); 151 } 152 } 153 } 154 return all_bps_good; 155 } 156 157 bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) { 158 return AtOurAddress(); 159 } 160 161 bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) { 162 return AtOurAddress(); 163 } 164 165 bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; } 166 167 void ThreadPlanRunToAddress::SetStopOthers(bool new_value) { 168 m_stop_others = new_value; 169 } 170 171 StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; } 172 173 bool ThreadPlanRunToAddress::WillStop() { return true; } 174 175 bool ThreadPlanRunToAddress::MischiefManaged() { 176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 177 178 if (AtOurAddress()) { 179 // Remove the breakpoint 180 size_t num_break_ids = m_break_ids.size(); 181 182 for (size_t i = 0; i < num_break_ids; i++) { 183 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) { 184 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); 185 m_break_ids[i] = LLDB_INVALID_BREAK_ID; 186 } 187 } 188 if (log) 189 log->Printf("Completed run to address plan."); 190 ThreadPlan::MischiefManaged(); 191 return true; 192 } else 193 return false; 194 } 195 196 bool ThreadPlanRunToAddress::AtOurAddress() { 197 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 198 bool found_it = false; 199 size_t num_addresses = m_addresses.size(); 200 for (size_t i = 0; i < num_addresses; i++) { 201 if (m_addresses[i] == current_address) { 202 found_it = true; 203 break; 204 } 205 } 206 return found_it; 207 } 208