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 #include "lldb/Target/ThreadPlanRunToAddress.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 1730fdc8d8SChris Lattner #include "lldb/Core/Log.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 1930fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2030fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2130fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2230fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2330fdc8d8SChris Lattner 2430fdc8d8SChris Lattner using namespace lldb; 2530fdc8d8SChris Lattner using namespace lldb_private; 2630fdc8d8SChris Lattner 2730fdc8d8SChris Lattner //---------------------------------------------------------------------- 2830fdc8d8SChris Lattner // ThreadPlanRunToAddress: Continue plan 2930fdc8d8SChris Lattner //---------------------------------------------------------------------- 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress 3230fdc8d8SChris Lattner ( 3330fdc8d8SChris Lattner Thread &thread, 3430fdc8d8SChris Lattner Address &address, 3530fdc8d8SChris Lattner bool stop_others 3630fdc8d8SChris Lattner ) : 3708b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 3830fdc8d8SChris Lattner m_stop_others (stop_others), 3908b87e0dSJim Ingham m_addresses (), 4008b87e0dSJim Ingham m_break_ids () 4130fdc8d8SChris Lattner { 42*f3ef3d2aSGreg Clayton m_addresses.push_back (address.GetOpcodeLoadAddress (&m_thread.GetProcess().GetTarget())); 4308b87e0dSJim Ingham SetInitialBreakpoints(); 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner 4630fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress 4730fdc8d8SChris Lattner ( 4830fdc8d8SChris Lattner Thread &thread, 4930fdc8d8SChris Lattner lldb::addr_t address, 5030fdc8d8SChris Lattner bool stop_others 5130fdc8d8SChris Lattner ) : 5208b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 5330fdc8d8SChris Lattner m_stop_others (stop_others), 5408b87e0dSJim Ingham m_addresses (), 5508b87e0dSJim Ingham m_break_ids () 5630fdc8d8SChris Lattner { 57*f3ef3d2aSGreg Clayton m_addresses.push_back(m_thread.GetProcess().GetTarget().GetOpcodeLoadAddress(address)); 5808b87e0dSJim Ingham SetInitialBreakpoints(); 5908b87e0dSJim Ingham } 6008b87e0dSJim Ingham 6108b87e0dSJim Ingham ThreadPlanRunToAddress::ThreadPlanRunToAddress 6208b87e0dSJim Ingham ( 6308b87e0dSJim Ingham Thread &thread, 64*f3ef3d2aSGreg Clayton const std::vector<lldb::addr_t> &addresses, 6508b87e0dSJim Ingham bool stop_others 6608b87e0dSJim Ingham ) : 6708b87e0dSJim Ingham ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 6808b87e0dSJim Ingham m_stop_others (stop_others), 6908b87e0dSJim Ingham m_addresses (addresses), 7008b87e0dSJim Ingham m_break_ids () 7108b87e0dSJim Ingham { 72*f3ef3d2aSGreg Clayton // Convert all addressses into opcode addresses to make sure we set 73*f3ef3d2aSGreg Clayton // breakpoints at the correct address. 74*f3ef3d2aSGreg Clayton Target &target = thread.GetProcess().GetTarget(); 75*f3ef3d2aSGreg Clayton std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 76*f3ef3d2aSGreg Clayton for (pos = m_addresses.begin(); pos != end; ++pos) 77*f3ef3d2aSGreg Clayton *pos = target.GetOpcodeLoadAddress (*pos); 78*f3ef3d2aSGreg Clayton 7908b87e0dSJim Ingham SetInitialBreakpoints(); 8030fdc8d8SChris Lattner } 8130fdc8d8SChris Lattner 8230fdc8d8SChris Lattner void 8308b87e0dSJim Ingham ThreadPlanRunToAddress::SetInitialBreakpoints () 8408b87e0dSJim Ingham { 8508b87e0dSJim Ingham size_t num_addresses = m_addresses.size(); 8608b87e0dSJim Ingham m_break_ids.resize(num_addresses); 8708b87e0dSJim Ingham 8808b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 8930fdc8d8SChris Lattner { 9030fdc8d8SChris Lattner Breakpoint *breakpoint; 9108b87e0dSJim Ingham breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_addresses[i], true).get(); 9230fdc8d8SChris Lattner if (breakpoint != NULL) 9330fdc8d8SChris Lattner { 9408b87e0dSJim Ingham m_break_ids[i] = breakpoint->GetID(); 9530fdc8d8SChris Lattner breakpoint->SetThreadID(m_thread.GetID()); 9630fdc8d8SChris Lattner } 9730fdc8d8SChris Lattner } 9808b87e0dSJim Ingham } 9930fdc8d8SChris Lattner 10030fdc8d8SChris Lattner ThreadPlanRunToAddress::~ThreadPlanRunToAddress () 10130fdc8d8SChris Lattner { 10208b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 10308b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 10430fdc8d8SChris Lattner { 10508b87e0dSJim Ingham m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]); 10630fdc8d8SChris Lattner } 10730fdc8d8SChris Lattner } 10830fdc8d8SChris Lattner 10930fdc8d8SChris Lattner void 11030fdc8d8SChris Lattner ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 11130fdc8d8SChris Lattner { 11208b87e0dSJim Ingham size_t num_addresses = m_addresses.size(); 11308b87e0dSJim Ingham 11430fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 11530fdc8d8SChris Lattner { 11608b87e0dSJim Ingham if (num_addresses == 0) 11708b87e0dSJim Ingham { 11808b87e0dSJim Ingham s->Printf ("run to address with no addresses given."); 11908b87e0dSJim Ingham return; 12008b87e0dSJim Ingham } 12108b87e0dSJim Ingham else if (num_addresses == 1) 12230fdc8d8SChris Lattner s->Printf ("run to address: "); 12308b87e0dSJim Ingham else 12408b87e0dSJim Ingham s->Printf ("run to addresses: "); 12508b87e0dSJim Ingham 12608b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 12708b87e0dSJim Ingham { 12808b87e0dSJim Ingham s->Address (m_addresses[i], sizeof (addr_t)); 12908b87e0dSJim Ingham s->Printf(" "); 13008b87e0dSJim Ingham } 13130fdc8d8SChris Lattner } 13230fdc8d8SChris Lattner else 13330fdc8d8SChris Lattner { 13408b87e0dSJim Ingham if (num_addresses == 0) 13508b87e0dSJim Ingham { 13608b87e0dSJim Ingham s->Printf ("run to address with no addresses given."); 13708b87e0dSJim Ingham return; 13808b87e0dSJim Ingham } 13908b87e0dSJim Ingham else if (num_addresses == 1) 14030fdc8d8SChris Lattner s->Printf ("Run to address: "); 14108b87e0dSJim Ingham else 14208b87e0dSJim Ingham { 14308b87e0dSJim Ingham s->Printf ("Run to addresses: "); 14408b87e0dSJim Ingham } 14508b87e0dSJim Ingham 14608b87e0dSJim Ingham for (size_t i = 0; i < num_addresses; i++) 14708b87e0dSJim Ingham { 14808b87e0dSJim Ingham if (num_addresses > 1) 14908b87e0dSJim Ingham { 15008b87e0dSJim Ingham s->Printf("\n"); 15108b87e0dSJim Ingham s->Indent(); 15208b87e0dSJim Ingham } 15308b87e0dSJim Ingham 15408b87e0dSJim Ingham s->Address(m_addresses[i], sizeof (addr_t)); 15508b87e0dSJim Ingham s->Printf (" using breakpoint: %d - ", m_break_ids[i]); 15608b87e0dSJim Ingham Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_ids[i]).get(); 15730fdc8d8SChris Lattner if (breakpoint) 15830fdc8d8SChris Lattner breakpoint->Dump (s); 15930fdc8d8SChris Lattner else 16030fdc8d8SChris Lattner s->Printf ("but the breakpoint has been deleted."); 16130fdc8d8SChris Lattner } 16230fdc8d8SChris Lattner } 16308b87e0dSJim Ingham } 16430fdc8d8SChris Lattner 16530fdc8d8SChris Lattner bool 16630fdc8d8SChris Lattner ThreadPlanRunToAddress::ValidatePlan (Stream *error) 16730fdc8d8SChris Lattner { 16830fdc8d8SChris Lattner // If we couldn't set the breakpoint for some reason, then this won't 16930fdc8d8SChris Lattner // work. 17008b87e0dSJim Ingham bool all_bps_good = true; 17108b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 17208b87e0dSJim Ingham 17308b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 17408b87e0dSJim Ingham { 17508b87e0dSJim Ingham if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) 17608b87e0dSJim Ingham { 17708b87e0dSJim Ingham all_bps_good = false; 178f48169bbSJim Ingham if (error) 179f48169bbSJim Ingham { 18008b87e0dSJim Ingham error->Printf ("Could not set breakpoint for address: "); 18108b87e0dSJim Ingham error->Address (m_addresses[i], sizeof (addr_t)); 18208b87e0dSJim Ingham error->Printf ("\n"); 18308b87e0dSJim Ingham } 18408b87e0dSJim Ingham } 185f48169bbSJim Ingham } 18608b87e0dSJim Ingham return all_bps_good; 18730fdc8d8SChris Lattner } 18830fdc8d8SChris Lattner 18930fdc8d8SChris Lattner bool 19030fdc8d8SChris Lattner ThreadPlanRunToAddress::PlanExplainsStop () 19130fdc8d8SChris Lattner { 19230fdc8d8SChris Lattner return AtOurAddress(); 19330fdc8d8SChris Lattner } 19430fdc8d8SChris Lattner 19530fdc8d8SChris Lattner bool 19630fdc8d8SChris Lattner ThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 19730fdc8d8SChris Lattner { 19830fdc8d8SChris Lattner return false; 19930fdc8d8SChris Lattner } 20030fdc8d8SChris Lattner 20130fdc8d8SChris Lattner bool 20230fdc8d8SChris Lattner ThreadPlanRunToAddress::StopOthers () 20330fdc8d8SChris Lattner { 20430fdc8d8SChris Lattner return m_stop_others; 20530fdc8d8SChris Lattner } 20630fdc8d8SChris Lattner 20730fdc8d8SChris Lattner void 20830fdc8d8SChris Lattner ThreadPlanRunToAddress::SetStopOthers (bool new_value) 20930fdc8d8SChris Lattner { 21030fdc8d8SChris Lattner m_stop_others = new_value; 21130fdc8d8SChris Lattner } 21230fdc8d8SChris Lattner 21330fdc8d8SChris Lattner StateType 21406e827ccSJim Ingham ThreadPlanRunToAddress::GetPlanRunState () 21530fdc8d8SChris Lattner { 21630fdc8d8SChris Lattner return eStateRunning; 21730fdc8d8SChris Lattner } 21830fdc8d8SChris Lattner 21930fdc8d8SChris Lattner bool 22030fdc8d8SChris Lattner ThreadPlanRunToAddress::WillStop () 22130fdc8d8SChris Lattner { 22230fdc8d8SChris Lattner return true; 22330fdc8d8SChris Lattner } 22430fdc8d8SChris Lattner 22530fdc8d8SChris Lattner bool 22630fdc8d8SChris Lattner ThreadPlanRunToAddress::MischiefManaged () 22730fdc8d8SChris Lattner { 2282d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 22930fdc8d8SChris Lattner 23030fdc8d8SChris Lattner if (AtOurAddress()) 23130fdc8d8SChris Lattner { 23230fdc8d8SChris Lattner // Remove the breakpoint 23308b87e0dSJim Ingham size_t num_break_ids = m_break_ids.size(); 23430fdc8d8SChris Lattner 23508b87e0dSJim Ingham for (size_t i = 0; i < num_break_ids; i++) 23608b87e0dSJim Ingham { 23708b87e0dSJim Ingham if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) 23808b87e0dSJim Ingham { 23908b87e0dSJim Ingham m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]); 24008b87e0dSJim Ingham m_break_ids[i] = LLDB_INVALID_BREAK_ID; 24108b87e0dSJim Ingham } 24208b87e0dSJim Ingham } 24330fdc8d8SChris Lattner if (log) 24430fdc8d8SChris Lattner log->Printf("Completed run to address plan."); 24530fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 24630fdc8d8SChris Lattner return true; 24730fdc8d8SChris Lattner } 24830fdc8d8SChris Lattner else 24930fdc8d8SChris Lattner return false; 25030fdc8d8SChris Lattner } 25130fdc8d8SChris Lattner 25230fdc8d8SChris Lattner bool 25330fdc8d8SChris Lattner ThreadPlanRunToAddress::AtOurAddress () 25430fdc8d8SChris Lattner { 25530fdc8d8SChris Lattner lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 25608b87e0dSJim Ingham bool found_it = false; 2574bf570d6SJim Ingham size_t num_addresses = m_addresses.size(); 2584bf570d6SJim Ingham for (size_t i = 0; i < num_addresses; i++) 25908b87e0dSJim Ingham { 26008b87e0dSJim Ingham if (m_addresses[i] == current_address) 26108b87e0dSJim Ingham { 26208b87e0dSJim Ingham found_it = true; 26308b87e0dSJim Ingham break; 26408b87e0dSJim Ingham } 26508b87e0dSJim Ingham } 26608b87e0dSJim Ingham return found_it; 26730fdc8d8SChris Lattner } 268