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 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/lldb-private-log.h" 17#include "lldb/Core/Log.h" 18#include "lldb/Core/Stream.h" 19#include "lldb/Target/Target.h" 20#include "lldb/Target/Process.h" 21#include "lldb/Target/Thread.h" 22#include "lldb/Target/RegisterContext.h" 23 24using namespace lldb; 25using namespace lldb_private; 26 27//---------------------------------------------------------------------- 28// ThreadPlanRunToAddress: Continue plan 29//---------------------------------------------------------------------- 30 31ThreadPlanRunToAddress::ThreadPlanRunToAddress 32( 33 Thread &thread, 34 Address &address, 35 bool stop_others 36) : 37 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 38 m_stop_others (stop_others), 39 m_addresses (), 40 m_break_ids () 41{ 42 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get())); 43 SetInitialBreakpoints(); 44} 45 46ThreadPlanRunToAddress::ThreadPlanRunToAddress 47( 48 Thread &thread, 49 lldb::addr_t address, 50 bool stop_others 51) : 52 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 53 m_stop_others (stop_others), 54 m_addresses (), 55 m_break_ids () 56{ 57 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 58 SetInitialBreakpoints(); 59} 60 61ThreadPlanRunToAddress::ThreadPlanRunToAddress 62( 63 Thread &thread, 64 const std::vector<lldb::addr_t> &addresses, 65 bool stop_others 66) : 67 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 68 m_stop_others (stop_others), 69 m_addresses (addresses), 70 m_break_ids () 71{ 72 // Convert all addressses into opcode addresses to make sure we set 73 // breakpoints at the correct address. 74 Target &target = thread.GetProcess()->GetTarget(); 75 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 76 for (pos = m_addresses.begin(); pos != end; ++pos) 77 *pos = target.GetOpcodeLoadAddress (*pos); 78 79 SetInitialBreakpoints(); 80} 81 82void 83ThreadPlanRunToAddress::SetInitialBreakpoints () 84{ 85 size_t num_addresses = m_addresses.size(); 86 m_break_ids.resize(num_addresses); 87 88 for (size_t i = 0; i < num_addresses; i++) 89 { 90 Breakpoint *breakpoint; 91 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get(); 92 if (breakpoint != NULL) 93 { 94 m_break_ids[i] = breakpoint->GetID(); 95 breakpoint->SetThreadID(m_thread.GetID()); 96 breakpoint->SetBreakpointKind("run-to-address"); 97 } 98 } 99} 100 101ThreadPlanRunToAddress::~ThreadPlanRunToAddress () 102{ 103 size_t num_break_ids = m_break_ids.size(); 104 for (size_t i = 0; i < num_break_ids; i++) 105 { 106 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 107 } 108} 109 110void 111ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 112{ 113 size_t num_addresses = m_addresses.size(); 114 115 if (level == lldb::eDescriptionLevelBrief) 116 { 117 if (num_addresses == 0) 118 { 119 s->Printf ("run to address with no addresses given."); 120 return; 121 } 122 else if (num_addresses == 1) 123 s->Printf ("run to address: "); 124 else 125 s->Printf ("run to addresses: "); 126 127 for (size_t i = 0; i < num_addresses; i++) 128 { 129 s->Address (m_addresses[i], sizeof (addr_t)); 130 s->Printf(" "); 131 } 132 } 133 else 134 { 135 if (num_addresses == 0) 136 { 137 s->Printf ("run to address with no addresses given."); 138 return; 139 } 140 else if (num_addresses == 1) 141 s->Printf ("Run to address: "); 142 else 143 { 144 s->Printf ("Run to addresses: "); 145 } 146 147 for (size_t i = 0; i < num_addresses; i++) 148 { 149 if (num_addresses > 1) 150 { 151 s->Printf("\n"); 152 s->Indent(); 153 } 154 155 s->Address(m_addresses[i], sizeof (addr_t)); 156 s->Printf (" using breakpoint: %d - ", m_break_ids[i]); 157 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get(); 158 if (breakpoint) 159 breakpoint->Dump (s); 160 else 161 s->Printf ("but the breakpoint has been deleted."); 162 } 163 } 164} 165 166bool 167ThreadPlanRunToAddress::ValidatePlan (Stream *error) 168{ 169 // If we couldn't set the breakpoint for some reason, then this won't 170 // work. 171 bool all_bps_good = true; 172 size_t num_break_ids = m_break_ids.size(); 173 174 for (size_t i = 0; i < num_break_ids; i++) 175 { 176 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) 177 { 178 all_bps_good = false; 179 if (error) 180 { 181 error->Printf ("Could not set breakpoint for address: "); 182 error->Address (m_addresses[i], sizeof (addr_t)); 183 error->Printf ("\n"); 184 } 185 } 186 } 187 return all_bps_good; 188} 189 190bool 191ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr) 192{ 193 return AtOurAddress(); 194} 195 196bool 197ThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 198{ 199 return false; 200} 201 202bool 203ThreadPlanRunToAddress::StopOthers () 204{ 205 return m_stop_others; 206} 207 208void 209ThreadPlanRunToAddress::SetStopOthers (bool new_value) 210{ 211 m_stop_others = new_value; 212} 213 214StateType 215ThreadPlanRunToAddress::GetPlanRunState () 216{ 217 return eStateRunning; 218} 219 220bool 221ThreadPlanRunToAddress::WillStop () 222{ 223 return true; 224} 225 226bool 227ThreadPlanRunToAddress::MischiefManaged () 228{ 229 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 230 231 if (AtOurAddress()) 232 { 233 // Remove the breakpoint 234 size_t num_break_ids = m_break_ids.size(); 235 236 for (size_t i = 0; i < num_break_ids; i++) 237 { 238 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) 239 { 240 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 241 m_break_ids[i] = LLDB_INVALID_BREAK_ID; 242 } 243 } 244 if (log) 245 log->Printf("Completed run to address plan."); 246 ThreadPlan::MischiefManaged (); 247 return true; 248 } 249 else 250 return false; 251} 252 253bool 254ThreadPlanRunToAddress::AtOurAddress () 255{ 256 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 257 bool found_it = false; 258 size_t num_addresses = m_addresses.size(); 259 for (size_t i = 0; i < num_addresses; i++) 260 { 261 if (m_addresses[i] == current_address) 262 { 263 found_it = true; 264 break; 265 } 266 } 267 return found_it; 268} 269