130fdc8d8SChris Lattner //===-- ThreadPlanStepInstruction.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 1130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 1230fdc8d8SChris Lattner 1330fdc8d8SChris Lattner // C Includes 1430fdc8d8SChris Lattner // C++ Includes 1530fdc8d8SChris Lattner // Other libraries and framework includes 1630fdc8d8SChris Lattner // Project includes 1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Log.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 2030fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2230fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2430fdc8d8SChris Lattner 2530fdc8d8SChris Lattner using namespace lldb; 2630fdc8d8SChris Lattner using namespace lldb_private; 2730fdc8d8SChris Lattner 2830fdc8d8SChris Lattner //---------------------------------------------------------------------- 2930fdc8d8SChris Lattner // ThreadPlanStepInstruction: Step over the current instruction 3030fdc8d8SChris Lattner //---------------------------------------------------------------------- 3130fdc8d8SChris Lattner 3230fdc8d8SChris Lattner ThreadPlanStepInstruction::ThreadPlanStepInstruction 3330fdc8d8SChris Lattner ( 3430fdc8d8SChris Lattner Thread &thread, 3530fdc8d8SChris Lattner bool step_over, 3630fdc8d8SChris Lattner bool stop_other_threads, 3730fdc8d8SChris Lattner Vote stop_vote, 3830fdc8d8SChris Lattner Vote run_vote 3930fdc8d8SChris Lattner ) : 40b01e742aSJim Ingham ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote), 4130fdc8d8SChris Lattner m_instruction_addr (0), 42*1ee0d4f7SBenjamin Kramer m_stop_other_threads (stop_other_threads), 4330fdc8d8SChris Lattner m_step_over (step_over), 44*1ee0d4f7SBenjamin Kramer m_stack_depth (0) 45*1ee0d4f7SBenjamin Kramer { 4630fdc8d8SChris Lattner m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 4730fdc8d8SChris Lattner m_stack_depth = m_thread.GetStackFrameCount(); 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 5130fdc8d8SChris Lattner { 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner void 5530fdc8d8SChris Lattner ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 5630fdc8d8SChris Lattner { 5730fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner if (m_step_over) 6030fdc8d8SChris Lattner s->Printf ("instruction step over"); 6130fdc8d8SChris Lattner else 6230fdc8d8SChris Lattner s->Printf ("instruction step into"); 6330fdc8d8SChris Lattner } 6430fdc8d8SChris Lattner else 6530fdc8d8SChris Lattner { 6630fdc8d8SChris Lattner s->Printf ("Stepping one instruction past "); 6730fdc8d8SChris Lattner s->Address(m_instruction_addr, sizeof (addr_t)); 6830fdc8d8SChris Lattner if (m_step_over) 6930fdc8d8SChris Lattner s->Printf(" stepping over calls"); 7030fdc8d8SChris Lattner else 7130fdc8d8SChris Lattner s->Printf(" stepping into calls"); 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner } 7430fdc8d8SChris Lattner 7530fdc8d8SChris Lattner bool 7630fdc8d8SChris Lattner ThreadPlanStepInstruction::ValidatePlan (Stream *error) 7730fdc8d8SChris Lattner { 7830fdc8d8SChris Lattner // Since we read the instruction we're stepping over from the thread, 7930fdc8d8SChris Lattner // this plan will always work. 8030fdc8d8SChris Lattner return true; 8130fdc8d8SChris Lattner } 8230fdc8d8SChris Lattner 8330fdc8d8SChris Lattner bool 8430fdc8d8SChris Lattner ThreadPlanStepInstruction::PlanExplainsStop () 8530fdc8d8SChris Lattner { 8630fdc8d8SChris Lattner Thread::StopInfo info; 8730fdc8d8SChris Lattner if (m_thread.GetStopInfo (&info)) 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner StopReason reason = info.GetStopReason(); 9030fdc8d8SChris Lattner if (reason == eStopReasonTrace || reason ==eStopReasonNone) 9130fdc8d8SChris Lattner return true; 9230fdc8d8SChris Lattner else 9330fdc8d8SChris Lattner return false; 9430fdc8d8SChris Lattner } 9530fdc8d8SChris Lattner return false; 9630fdc8d8SChris Lattner } 9730fdc8d8SChris Lattner 9830fdc8d8SChris Lattner bool 9930fdc8d8SChris Lattner ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 10030fdc8d8SChris Lattner { 10130fdc8d8SChris Lattner if (m_step_over) 10230fdc8d8SChris Lattner { 10330fdc8d8SChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 10430fdc8d8SChris Lattner if (m_thread.GetStackFrameCount() <= m_stack_depth) 10530fdc8d8SChris Lattner { 10630fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 10730fdc8d8SChris Lattner { 10830fdc8d8SChris Lattner SetPlanComplete(); 10930fdc8d8SChris Lattner return true; 11030fdc8d8SChris Lattner } 11130fdc8d8SChris Lattner else 11230fdc8d8SChris Lattner return false; 11330fdc8d8SChris Lattner } 11430fdc8d8SChris Lattner else 11530fdc8d8SChris Lattner { 11630fdc8d8SChris Lattner // We've stepped in, step back out again: 11730fdc8d8SChris Lattner StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 11830fdc8d8SChris Lattner if (return_frame) 11930fdc8d8SChris Lattner { 12030fdc8d8SChris Lattner if (log) 12130fdc8d8SChris Lattner { 12230fdc8d8SChris Lattner StreamString s; 12330fdc8d8SChris Lattner s.PutCString ("Stepped in to: "); 12430fdc8d8SChris Lattner addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess()); 12530fdc8d8SChris Lattner s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize()); 12630fdc8d8SChris Lattner s.PutCString (" stepping out to: "); 12730fdc8d8SChris Lattner addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); 12830fdc8d8SChris Lattner s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); 12930fdc8d8SChris Lattner log->Printf("%s.", s.GetData()); 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion); 13230fdc8d8SChris Lattner return false; 13330fdc8d8SChris Lattner } 13430fdc8d8SChris Lattner else 13530fdc8d8SChris Lattner { 13630fdc8d8SChris Lattner if (log) 13730fdc8d8SChris Lattner log->Printf("Could not find previous frame, stopping."); 13830fdc8d8SChris Lattner SetPlanComplete(); 13930fdc8d8SChris Lattner return true; 14030fdc8d8SChris Lattner } 14130fdc8d8SChris Lattner 14230fdc8d8SChris Lattner } 14330fdc8d8SChris Lattner 14430fdc8d8SChris Lattner } 14530fdc8d8SChris Lattner else 14630fdc8d8SChris Lattner { 14730fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 14830fdc8d8SChris Lattner { 14930fdc8d8SChris Lattner SetPlanComplete(); 15030fdc8d8SChris Lattner return true; 15130fdc8d8SChris Lattner } 15230fdc8d8SChris Lattner else 15330fdc8d8SChris Lattner return false; 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner } 15630fdc8d8SChris Lattner 15730fdc8d8SChris Lattner bool 15830fdc8d8SChris Lattner ThreadPlanStepInstruction::StopOthers () 15930fdc8d8SChris Lattner { 16030fdc8d8SChris Lattner return m_stop_other_threads; 16130fdc8d8SChris Lattner } 16230fdc8d8SChris Lattner 16330fdc8d8SChris Lattner StateType 16430fdc8d8SChris Lattner ThreadPlanStepInstruction::RunState () 16530fdc8d8SChris Lattner { 16630fdc8d8SChris Lattner return eStateStepping; 16730fdc8d8SChris Lattner } 16830fdc8d8SChris Lattner 16930fdc8d8SChris Lattner bool 17030fdc8d8SChris Lattner ThreadPlanStepInstruction::WillStop () 17130fdc8d8SChris Lattner { 17230fdc8d8SChris Lattner return true; 17330fdc8d8SChris Lattner } 17430fdc8d8SChris Lattner 17530fdc8d8SChris Lattner bool 17630fdc8d8SChris Lattner ThreadPlanStepInstruction::MischiefManaged () 17730fdc8d8SChris Lattner { 17830fdc8d8SChris Lattner if (IsPlanComplete()) 17930fdc8d8SChris Lattner { 18030fdc8d8SChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 18130fdc8d8SChris Lattner if (log) 18230fdc8d8SChris Lattner log->Printf("Completed single instruction step plan."); 18330fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 18430fdc8d8SChris Lattner return true; 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner else 18730fdc8d8SChris Lattner { 18830fdc8d8SChris Lattner return false; 18930fdc8d8SChris Lattner } 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner 192