1254721Semaste//===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Target/ThreadPlanRunToAddress.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/lldb-private-log.h" 17254721Semaste#include "lldb/Core/Log.h" 18254721Semaste#include "lldb/Core/Stream.h" 19254721Semaste#include "lldb/Target/Target.h" 20254721Semaste#include "lldb/Target/Process.h" 21254721Semaste#include "lldb/Target/Thread.h" 22254721Semaste#include "lldb/Target/RegisterContext.h" 23254721Semaste 24254721Semasteusing namespace lldb; 25254721Semasteusing namespace lldb_private; 26254721Semaste 27254721Semaste//---------------------------------------------------------------------- 28254721Semaste// ThreadPlanRunToAddress: Continue plan 29254721Semaste//---------------------------------------------------------------------- 30254721Semaste 31254721SemasteThreadPlanRunToAddress::ThreadPlanRunToAddress 32254721Semaste( 33254721Semaste Thread &thread, 34254721Semaste Address &address, 35254721Semaste bool stop_others 36254721Semaste) : 37254721Semaste ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 38254721Semaste m_stop_others (stop_others), 39254721Semaste m_addresses (), 40254721Semaste m_break_ids () 41254721Semaste{ 42254721Semaste m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get())); 43254721Semaste SetInitialBreakpoints(); 44254721Semaste} 45254721Semaste 46254721SemasteThreadPlanRunToAddress::ThreadPlanRunToAddress 47254721Semaste( 48254721Semaste Thread &thread, 49254721Semaste lldb::addr_t address, 50254721Semaste bool stop_others 51254721Semaste) : 52254721Semaste ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 53254721Semaste m_stop_others (stop_others), 54254721Semaste m_addresses (), 55254721Semaste m_break_ids () 56254721Semaste{ 57254721Semaste m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 58254721Semaste SetInitialBreakpoints(); 59254721Semaste} 60254721Semaste 61254721SemasteThreadPlanRunToAddress::ThreadPlanRunToAddress 62254721Semaste( 63254721Semaste Thread &thread, 64254721Semaste const std::vector<lldb::addr_t> &addresses, 65254721Semaste bool stop_others 66254721Semaste) : 67254721Semaste ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 68254721Semaste m_stop_others (stop_others), 69254721Semaste m_addresses (addresses), 70254721Semaste m_break_ids () 71254721Semaste{ 72254721Semaste // Convert all addressses into opcode addresses to make sure we set 73254721Semaste // breakpoints at the correct address. 74254721Semaste Target &target = thread.GetProcess()->GetTarget(); 75254721Semaste std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 76254721Semaste for (pos = m_addresses.begin(); pos != end; ++pos) 77254721Semaste *pos = target.GetOpcodeLoadAddress (*pos); 78254721Semaste 79254721Semaste SetInitialBreakpoints(); 80254721Semaste} 81254721Semaste 82254721Semastevoid 83254721SemasteThreadPlanRunToAddress::SetInitialBreakpoints () 84254721Semaste{ 85254721Semaste size_t num_addresses = m_addresses.size(); 86254721Semaste m_break_ids.resize(num_addresses); 87254721Semaste 88254721Semaste for (size_t i = 0; i < num_addresses; i++) 89254721Semaste { 90254721Semaste Breakpoint *breakpoint; 91263363Semaste breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get(); 92254721Semaste if (breakpoint != NULL) 93254721Semaste { 94254721Semaste m_break_ids[i] = breakpoint->GetID(); 95254721Semaste breakpoint->SetThreadID(m_thread.GetID()); 96254721Semaste breakpoint->SetBreakpointKind("run-to-address"); 97254721Semaste } 98254721Semaste } 99254721Semaste} 100254721Semaste 101254721SemasteThreadPlanRunToAddress::~ThreadPlanRunToAddress () 102254721Semaste{ 103254721Semaste size_t num_break_ids = m_break_ids.size(); 104254721Semaste for (size_t i = 0; i < num_break_ids; i++) 105254721Semaste { 106254721Semaste m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 107254721Semaste } 108254721Semaste} 109254721Semaste 110254721Semastevoid 111254721SemasteThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 112254721Semaste{ 113254721Semaste size_t num_addresses = m_addresses.size(); 114254721Semaste 115254721Semaste if (level == lldb::eDescriptionLevelBrief) 116254721Semaste { 117254721Semaste if (num_addresses == 0) 118254721Semaste { 119254721Semaste s->Printf ("run to address with no addresses given."); 120254721Semaste return; 121254721Semaste } 122254721Semaste else if (num_addresses == 1) 123254721Semaste s->Printf ("run to address: "); 124254721Semaste else 125254721Semaste s->Printf ("run to addresses: "); 126254721Semaste 127254721Semaste for (size_t i = 0; i < num_addresses; i++) 128254721Semaste { 129254721Semaste s->Address (m_addresses[i], sizeof (addr_t)); 130254721Semaste s->Printf(" "); 131254721Semaste } 132254721Semaste } 133254721Semaste else 134254721Semaste { 135254721Semaste if (num_addresses == 0) 136254721Semaste { 137254721Semaste s->Printf ("run to address with no addresses given."); 138254721Semaste return; 139254721Semaste } 140254721Semaste else if (num_addresses == 1) 141254721Semaste s->Printf ("Run to address: "); 142254721Semaste else 143254721Semaste { 144254721Semaste s->Printf ("Run to addresses: "); 145254721Semaste } 146254721Semaste 147254721Semaste for (size_t i = 0; i < num_addresses; i++) 148254721Semaste { 149254721Semaste if (num_addresses > 1) 150254721Semaste { 151254721Semaste s->Printf("\n"); 152254721Semaste s->Indent(); 153254721Semaste } 154254721Semaste 155254721Semaste s->Address(m_addresses[i], sizeof (addr_t)); 156254721Semaste s->Printf (" using breakpoint: %d - ", m_break_ids[i]); 157254721Semaste Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get(); 158254721Semaste if (breakpoint) 159254721Semaste breakpoint->Dump (s); 160254721Semaste else 161254721Semaste s->Printf ("but the breakpoint has been deleted."); 162254721Semaste } 163254721Semaste } 164254721Semaste} 165254721Semaste 166254721Semastebool 167254721SemasteThreadPlanRunToAddress::ValidatePlan (Stream *error) 168254721Semaste{ 169254721Semaste // If we couldn't set the breakpoint for some reason, then this won't 170254721Semaste // work. 171254721Semaste bool all_bps_good = true; 172254721Semaste size_t num_break_ids = m_break_ids.size(); 173254721Semaste 174254721Semaste for (size_t i = 0; i < num_break_ids; i++) 175254721Semaste { 176254721Semaste if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) 177254721Semaste { 178254721Semaste all_bps_good = false; 179254721Semaste if (error) 180254721Semaste { 181254721Semaste error->Printf ("Could not set breakpoint for address: "); 182254721Semaste error->Address (m_addresses[i], sizeof (addr_t)); 183254721Semaste error->Printf ("\n"); 184254721Semaste } 185254721Semaste } 186254721Semaste } 187254721Semaste return all_bps_good; 188254721Semaste} 189254721Semaste 190254721Semastebool 191254721SemasteThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr) 192254721Semaste{ 193254721Semaste return AtOurAddress(); 194254721Semaste} 195254721Semaste 196254721Semastebool 197254721SemasteThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 198254721Semaste{ 199254721Semaste return false; 200254721Semaste} 201254721Semaste 202254721Semastebool 203254721SemasteThreadPlanRunToAddress::StopOthers () 204254721Semaste{ 205254721Semaste return m_stop_others; 206254721Semaste} 207254721Semaste 208254721Semastevoid 209254721SemasteThreadPlanRunToAddress::SetStopOthers (bool new_value) 210254721Semaste{ 211254721Semaste m_stop_others = new_value; 212254721Semaste} 213254721Semaste 214254721SemasteStateType 215254721SemasteThreadPlanRunToAddress::GetPlanRunState () 216254721Semaste{ 217254721Semaste return eStateRunning; 218254721Semaste} 219254721Semaste 220254721Semastebool 221254721SemasteThreadPlanRunToAddress::WillStop () 222254721Semaste{ 223254721Semaste return true; 224254721Semaste} 225254721Semaste 226254721Semastebool 227254721SemasteThreadPlanRunToAddress::MischiefManaged () 228254721Semaste{ 229254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 230254721Semaste 231254721Semaste if (AtOurAddress()) 232254721Semaste { 233254721Semaste // Remove the breakpoint 234254721Semaste size_t num_break_ids = m_break_ids.size(); 235254721Semaste 236254721Semaste for (size_t i = 0; i < num_break_ids; i++) 237254721Semaste { 238254721Semaste if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) 239254721Semaste { 240254721Semaste m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 241254721Semaste m_break_ids[i] = LLDB_INVALID_BREAK_ID; 242254721Semaste } 243254721Semaste } 244254721Semaste if (log) 245254721Semaste log->Printf("Completed run to address plan."); 246254721Semaste ThreadPlan::MischiefManaged (); 247254721Semaste return true; 248254721Semaste } 249254721Semaste else 250254721Semaste return false; 251254721Semaste} 252254721Semaste 253254721Semastebool 254254721SemasteThreadPlanRunToAddress::AtOurAddress () 255254721Semaste{ 256254721Semaste lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 257254721Semaste bool found_it = false; 258254721Semaste size_t num_addresses = m_addresses.size(); 259254721Semaste for (size_t i = 0; i < num_addresses; i++) 260254721Semaste { 261254721Semaste if (m_addresses[i] == current_address) 262254721Semaste { 263254721Semaste found_it = true; 264254721Semaste break; 265254721Semaste } 266254721Semaste } 267254721Semaste return found_it; 268254721Semaste} 269