130fdc8d8SChris Lattner //===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner // Other libraries and framework includes 1330fdc8d8SChris Lattner // Project includes 14*e65b2cf2SEugene Zelenko #include "lldb/Target/ThreadPlanRunToAddress.h" 1530fdc8d8SChris Lattner #include "lldb/Core/Log.h" 1630fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 1730fdc8d8SChris Lattner #include "lldb/Target/Target.h" 1830fdc8d8SChris Lattner #include "lldb/Target/Process.h" 1930fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2030fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner using namespace lldb; 2330fdc8d8SChris Lattner using namespace lldb_private; 2430fdc8d8SChris Lattner 2530fdc8d8SChris Lattner //---------------------------------------------------------------------- 2630fdc8d8SChris Lattner // ThreadPlanRunToAddress: Continue plan 2730fdc8d8SChris Lattner //---------------------------------------------------------------------- 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress 3030fdc8d8SChris Lattner ( 3130fdc8d8SChris Lattner Thread &thread, 3230fdc8d8SChris Lattner Address &address, 3330fdc8d8SChris Lattner bool stop_others 3430fdc8d8SChris Lattner ) : 3508b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 3630fdc8d8SChris Lattner m_stop_others (stop_others), 3708b87e0dSJim Ingham m_addresses (), 3808b87e0dSJim Ingham m_break_ids () 3930fdc8d8SChris Lattner { 401ac04c30SGreg Clayton m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get())); 4108b87e0dSJim Ingham SetInitialBreakpoints(); 4230fdc8d8SChris Lattner } 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress 4530fdc8d8SChris Lattner ( 4630fdc8d8SChris Lattner Thread &thread, 4730fdc8d8SChris Lattner lldb::addr_t address, 4830fdc8d8SChris Lattner bool stop_others 4930fdc8d8SChris Lattner ) : 5008b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 5130fdc8d8SChris Lattner m_stop_others (stop_others), 5208b87e0dSJim Ingham m_addresses (), 5308b87e0dSJim Ingham m_break_ids () 5430fdc8d8SChris Lattner { 551ac04c30SGreg Clayton m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 5608b87e0dSJim Ingham SetInitialBreakpoints(); 5708b87e0dSJim Ingham } 5808b87e0dSJim Ingham 5908b87e0dSJim Ingham ThreadPlanRunToAddress::ThreadPlanRunToAddress 6008b87e0dSJim Ingham ( 6108b87e0dSJim Ingham Thread &thread, 62f3ef3d2aSGreg Clayton const std::vector<lldb::addr_t> &addresses, 6308b87e0dSJim Ingham bool stop_others 6408b87e0dSJim Ingham ) : 6508b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 6608b87e0dSJim Ingham m_stop_others (stop_others), 6708b87e0dSJim Ingham m_addresses (addresses), 6808b87e0dSJim Ingham m_break_ids () 6908b87e0dSJim Ingham { 70d93c4a33SBruce Mitchener // Convert all addresses into opcode addresses to make sure we set 71f3ef3d2aSGreg Clayton // breakpoints at the correct address. 721ac04c30SGreg Clayton Target &target = thread.GetProcess()->GetTarget(); 73f3ef3d2aSGreg Clayton std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 74f3ef3d2aSGreg Clayton for (pos = m_addresses.begin(); pos != end; ++pos) 75f3ef3d2aSGreg Clayton *pos = target.GetOpcodeLoadAddress (*pos); 76f3ef3d2aSGreg Clayton 7708b87e0dSJim Ingham SetInitialBreakpoints(); 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner 8030fdc8d8SChris Lattner void 8108b87e0dSJim Ingham ThreadPlanRunToAddress::SetInitialBreakpoints () 8208b87e0dSJim Ingham { 8308b87e0dSJim Ingham size_t num_addresses = m_addresses.size(); 8408b87e0dSJim Ingham m_break_ids.resize(num_addresses); 8508b87e0dSJim Ingham 8608b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 8730fdc8d8SChris Lattner { 8830fdc8d8SChris Lattner Breakpoint *breakpoint; 89eb023e75SGreg Clayton breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get(); 90*e65b2cf2SEugene Zelenko if (breakpoint != nullptr) 9130fdc8d8SChris Lattner { 9208b87e0dSJim Ingham m_break_ids[i] = breakpoint->GetID(); 9330fdc8d8SChris Lattner breakpoint->SetThreadID(m_thread.GetID()); 942995077dSJim Ingham breakpoint->SetBreakpointKind("run-to-address"); 9530fdc8d8SChris Lattner } 9630fdc8d8SChris Lattner } 9708b87e0dSJim Ingham } 9830fdc8d8SChris Lattner 9930fdc8d8SChris Lattner ThreadPlanRunToAddress::~ThreadPlanRunToAddress () 10030fdc8d8SChris Lattner { 10108b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 10208b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 10330fdc8d8SChris Lattner { 1041ac04c30SGreg Clayton m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 10530fdc8d8SChris Lattner } 10630fdc8d8SChris Lattner } 10730fdc8d8SChris Lattner 10830fdc8d8SChris Lattner void 10930fdc8d8SChris Lattner ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 11030fdc8d8SChris Lattner { 11108b87e0dSJim Ingham size_t num_addresses = m_addresses.size(); 11208b87e0dSJim Ingham 11330fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 11430fdc8d8SChris Lattner { 11508b87e0dSJim Ingham if (num_addresses == 0) 11608b87e0dSJim Ingham { 11708b87e0dSJim Ingham s->Printf ("run to address with no addresses given."); 11808b87e0dSJim Ingham return; 11908b87e0dSJim Ingham } 12008b87e0dSJim Ingham else if (num_addresses == 1) 12130fdc8d8SChris Lattner s->Printf ("run to address: "); 12208b87e0dSJim Ingham else 12308b87e0dSJim Ingham s->Printf ("run to addresses: "); 12408b87e0dSJim Ingham 12508b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 12608b87e0dSJim Ingham { 12708b87e0dSJim Ingham s->Address (m_addresses[i], sizeof (addr_t)); 12808b87e0dSJim Ingham s->Printf(" "); 12908b87e0dSJim Ingham } 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner else 13230fdc8d8SChris Lattner { 13308b87e0dSJim Ingham if (num_addresses == 0) 13408b87e0dSJim Ingham { 13508b87e0dSJim Ingham s->Printf ("run to address with no addresses given."); 13608b87e0dSJim Ingham return; 13708b87e0dSJim Ingham } 13808b87e0dSJim Ingham else if (num_addresses == 1) 13930fdc8d8SChris Lattner s->Printf ("Run to address: "); 14008b87e0dSJim Ingham else 14108b87e0dSJim Ingham { 14208b87e0dSJim Ingham s->Printf ("Run to addresses: "); 14308b87e0dSJim Ingham } 14408b87e0dSJim Ingham 14508b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 14608b87e0dSJim Ingham { 14708b87e0dSJim Ingham if (num_addresses > 1) 14808b87e0dSJim Ingham { 14908b87e0dSJim Ingham s->Printf("\n"); 15008b87e0dSJim Ingham s->Indent(); 15108b87e0dSJim Ingham } 15208b87e0dSJim Ingham 15308b87e0dSJim Ingham s->Address(m_addresses[i], sizeof (addr_t)); 154f58a0487SJim Ingham s->Printf (" using breakpoint: %d - ", m_break_ids[i]); 1551ac04c30SGreg Clayton Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get(); 15630fdc8d8SChris Lattner if (breakpoint) 15730fdc8d8SChris Lattner breakpoint->Dump (s); 15830fdc8d8SChris Lattner else 15930fdc8d8SChris Lattner s->Printf ("but the breakpoint has been deleted."); 16030fdc8d8SChris Lattner } 16130fdc8d8SChris Lattner } 16208b87e0dSJim Ingham } 16330fdc8d8SChris Lattner 16430fdc8d8SChris Lattner bool 16530fdc8d8SChris Lattner ThreadPlanRunToAddress::ValidatePlan (Stream *error) 16630fdc8d8SChris Lattner { 16730fdc8d8SChris Lattner // If we couldn't set the breakpoint for some reason, then this won't 16830fdc8d8SChris Lattner // work. 16908b87e0dSJim Ingham bool all_bps_good = true; 17008b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 17108b87e0dSJim Ingham 17208b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 17308b87e0dSJim Ingham { 17408b87e0dSJim Ingham if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) 17508b87e0dSJim Ingham { 17608b87e0dSJim Ingham all_bps_good = false; 177f48169bbSJim Ingham if (error) 178f48169bbSJim Ingham { 17908b87e0dSJim Ingham error->Printf ("Could not set breakpoint for address: "); 18008b87e0dSJim Ingham error->Address (m_addresses[i], sizeof (addr_t)); 18108b87e0dSJim Ingham error->Printf ("\n"); 18208b87e0dSJim Ingham } 18308b87e0dSJim Ingham } 184f48169bbSJim Ingham } 18508b87e0dSJim Ingham return all_bps_good; 18630fdc8d8SChris Lattner } 18730fdc8d8SChris Lattner 18830fdc8d8SChris Lattner bool 189221d51cfSJim Ingham ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr) 19030fdc8d8SChris Lattner { 19130fdc8d8SChris Lattner return AtOurAddress(); 19230fdc8d8SChris Lattner } 19330fdc8d8SChris Lattner 19430fdc8d8SChris Lattner bool 19530fdc8d8SChris Lattner ThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 19630fdc8d8SChris Lattner { 1971fd2f08eSJim Ingham return AtOurAddress(); 19830fdc8d8SChris Lattner } 19930fdc8d8SChris Lattner 20030fdc8d8SChris Lattner bool 20130fdc8d8SChris Lattner ThreadPlanRunToAddress::StopOthers () 20230fdc8d8SChris Lattner { 20330fdc8d8SChris Lattner return m_stop_others; 20430fdc8d8SChris Lattner } 20530fdc8d8SChris Lattner 20630fdc8d8SChris Lattner void 20730fdc8d8SChris Lattner ThreadPlanRunToAddress::SetStopOthers (bool new_value) 20830fdc8d8SChris Lattner { 20930fdc8d8SChris Lattner m_stop_others = new_value; 21030fdc8d8SChris Lattner } 21130fdc8d8SChris Lattner 21230fdc8d8SChris Lattner StateType 21306e827ccSJim Ingham ThreadPlanRunToAddress::GetPlanRunState () 21430fdc8d8SChris Lattner { 21530fdc8d8SChris Lattner return eStateRunning; 21630fdc8d8SChris Lattner } 21730fdc8d8SChris Lattner 21830fdc8d8SChris Lattner bool 21930fdc8d8SChris Lattner ThreadPlanRunToAddress::WillStop () 22030fdc8d8SChris Lattner { 22130fdc8d8SChris Lattner return true; 22230fdc8d8SChris Lattner } 22330fdc8d8SChris Lattner 22430fdc8d8SChris Lattner bool 22530fdc8d8SChris Lattner ThreadPlanRunToAddress::MischiefManaged () 22630fdc8d8SChris Lattner { 2275160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 22830fdc8d8SChris Lattner 22930fdc8d8SChris Lattner if (AtOurAddress()) 23030fdc8d8SChris Lattner { 23130fdc8d8SChris Lattner // Remove the breakpoint 23208b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 23330fdc8d8SChris Lattner 23408b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 23508b87e0dSJim Ingham { 23608b87e0dSJim Ingham if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) 23708b87e0dSJim Ingham { 2381ac04c30SGreg Clayton m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 23908b87e0dSJim Ingham m_break_ids[i] = LLDB_INVALID_BREAK_ID; 24008b87e0dSJim Ingham } 24108b87e0dSJim Ingham } 24230fdc8d8SChris Lattner if (log) 24330fdc8d8SChris Lattner log->Printf("Completed run to address plan."); 24430fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 24530fdc8d8SChris Lattner return true; 24630fdc8d8SChris Lattner } 24730fdc8d8SChris Lattner else 24830fdc8d8SChris Lattner return false; 24930fdc8d8SChris Lattner } 25030fdc8d8SChris Lattner 25130fdc8d8SChris Lattner bool 25230fdc8d8SChris Lattner ThreadPlanRunToAddress::AtOurAddress () 25330fdc8d8SChris Lattner { 25430fdc8d8SChris Lattner lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 25508b87e0dSJim Ingham bool found_it = false; 2564bf570d6SJim Ingham size_t num_addresses = m_addresses.size(); 2574bf570d6SJim Ingham for (size_t i = 0; i < num_addresses; i++) 25808b87e0dSJim Ingham { 25908b87e0dSJim Ingham if (m_addresses[i] == current_address) 26008b87e0dSJim Ingham { 26108b87e0dSJim Ingham found_it = true; 26208b87e0dSJim Ingham break; 26308b87e0dSJim Ingham } 26408b87e0dSJim Ingham } 26508b87e0dSJim Ingham return found_it; 26630fdc8d8SChris Lattner } 267