184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans//===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===// 284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// 384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// The LLVM Compiler Infrastructure 484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// 584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// This file is distributed under the University of Illinois Open Source 684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// License. See LICENSE.TXT for details. 784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// 884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans//===----------------------------------------------------------------------===// 984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 1084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Target/ThreadPlanRunToAddress.h" 1184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 1284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// C Includes 1384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// C++ Includes 1484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// Other libraries and framework includes 1584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// Project includes 1684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/lldb-private-log.h" 1784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Core/Log.h" 1884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Core/Stream.h" 1984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Target/Target.h" 2084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Target/Process.h" 2184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Target/Thread.h" 2284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans#include "lldb/Target/RegisterContext.h" 2384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 2484cbbcb90af44807361198baed4e74ab77715ff7Jason Evansusing namespace lldb; 2584cbbcb90af44807361198baed4e74ab77715ff7Jason Evansusing namespace lldb_private; 2684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 2784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans//---------------------------------------------------------------------- 2884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans// ThreadPlanRunToAddress: Continue plan 2984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans//---------------------------------------------------------------------- 3084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 3184cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::ThreadPlanRunToAddress 3284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans( 3384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Thread &thread, 3484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Address &address, 3584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans bool stop_others 3684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans) : 3784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 3884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_stop_others (stop_others), 3984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_addresses (), 4084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_break_ids () 4184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 4284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get())); 4384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans SetInitialBreakpoints(); 4484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans} 4584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 4684cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::ThreadPlanRunToAddress 4784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans( 4884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Thread &thread, 4984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans lldb::addr_t address, 5084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans bool stop_others 5184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans) : 5284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 5384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_stop_others (stop_others), 5484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_addresses (), 5584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_break_ids () 5684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 5784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 5884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans SetInitialBreakpoints(); 5984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans} 6084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 6184cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::ThreadPlanRunToAddress 6284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans( 6384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Thread &thread, 6484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans const std::vector<lldb::addr_t> &addresses, 6584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans bool stop_others 6684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans) : 6784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 6884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_stop_others (stop_others), 6984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_addresses (addresses), 7084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_break_ids () 7184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 7284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans // Convert all addressses into opcode addresses to make sure we set 7384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans // breakpoints at the correct address. 7484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Target &target = thread.GetProcess()->GetTarget(); 7584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 7684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans for (pos = m_addresses.begin(); pos != end; ++pos) 7784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans *pos = target.GetOpcodeLoadAddress (*pos); 7884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 7984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans SetInitialBreakpoints(); 8084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans} 8184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 8284cbbcb90af44807361198baed4e74ab77715ff7Jason Evansvoid 8384cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::SetInitialBreakpoints () 8484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 8584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans size_t num_addresses = m_addresses.size(); 8684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_break_ids.resize(num_addresses); 8784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 8884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans for (size_t i = 0; i < num_addresses; i++) 8984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans { 9084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans Breakpoint *breakpoint; 9184cbbcb90af44807361198baed4e74ab77715ff7Jason Evans breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get(); 9284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans if (breakpoint != NULL) 9384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans { 9484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_break_ids[i] = breakpoint->GetID(); 9584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans breakpoint->SetThreadID(m_thread.GetID()); 9684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans breakpoint->SetBreakpointKind("run-to-address"); 9784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans } 9884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans } 9984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans} 10084cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 10184cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::~ThreadPlanRunToAddress () 10284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 10384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans size_t num_break_ids = m_break_ids.size(); 10484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans for (size_t i = 0; i < num_break_ids; i++) 10584cbbcb90af44807361198baed4e74ab77715ff7Jason Evans { 10684cbbcb90af44807361198baed4e74ab77715ff7Jason Evans m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 10784cbbcb90af44807361198baed4e74ab77715ff7Jason Evans } 10884cbbcb90af44807361198baed4e74ab77715ff7Jason Evans} 10984cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 11084cbbcb90af44807361198baed4e74ab77715ff7Jason Evansvoid 11184cbbcb90af44807361198baed4e74ab77715ff7Jason EvansThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 11284cbbcb90af44807361198baed4e74ab77715ff7Jason Evans{ 11384cbbcb90af44807361198baed4e74ab77715ff7Jason Evans size_t num_addresses = m_addresses.size(); 11484cbbcb90af44807361198baed4e74ab77715ff7Jason Evans 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