1*30fdc8d8SChris Lattner //===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner 11*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 12*30fdc8d8SChris Lattner 13*30fdc8d8SChris Lattner // C Includes 14*30fdc8d8SChris Lattner // C++ Includes 15*30fdc8d8SChris Lattner // Other libraries and framework includes 16*30fdc8d8SChris Lattner // Project includes 17*30fdc8d8SChris Lattner #include "lldb/lldb-private-log.h" 18*30fdc8d8SChris Lattner #include "lldb/Core/Log.h" 19*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 20*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 21*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 23*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 24*30fdc8d8SChris Lattner 25*30fdc8d8SChris Lattner using namespace lldb; 26*30fdc8d8SChris Lattner using namespace lldb_private; 27*30fdc8d8SChris Lattner 28*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 29*30fdc8d8SChris Lattner // ThreadPlanStepInstruction: Step over the current instruction 30*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 31*30fdc8d8SChris Lattner 32*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ThreadPlanStepInstruction 33*30fdc8d8SChris Lattner ( 34*30fdc8d8SChris Lattner Thread &thread, 35*30fdc8d8SChris Lattner bool step_over, 36*30fdc8d8SChris Lattner bool stop_other_threads, 37*30fdc8d8SChris Lattner Vote stop_vote, 38*30fdc8d8SChris Lattner Vote run_vote 39*30fdc8d8SChris Lattner ) : 40*30fdc8d8SChris Lattner ThreadPlan ("Step over single instruction", thread, stop_vote, run_vote), 41*30fdc8d8SChris Lattner m_instruction_addr (0), 42*30fdc8d8SChris Lattner m_step_over (step_over), 43*30fdc8d8SChris Lattner m_stack_depth(0), 44*30fdc8d8SChris Lattner m_stop_other_threads (stop_other_threads) 45*30fdc8d8SChris Lattner { 46*30fdc8d8SChris Lattner m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); 47*30fdc8d8SChris Lattner m_stack_depth = m_thread.GetStackFrameCount(); 48*30fdc8d8SChris Lattner } 49*30fdc8d8SChris Lattner 50*30fdc8d8SChris Lattner ThreadPlanStepInstruction::~ThreadPlanStepInstruction () 51*30fdc8d8SChris Lattner { 52*30fdc8d8SChris Lattner } 53*30fdc8d8SChris Lattner 54*30fdc8d8SChris Lattner void 55*30fdc8d8SChris Lattner ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level) 56*30fdc8d8SChris Lattner { 57*30fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief) 58*30fdc8d8SChris Lattner { 59*30fdc8d8SChris Lattner if (m_step_over) 60*30fdc8d8SChris Lattner s->Printf ("instruction step over"); 61*30fdc8d8SChris Lattner else 62*30fdc8d8SChris Lattner s->Printf ("instruction step into"); 63*30fdc8d8SChris Lattner } 64*30fdc8d8SChris Lattner else 65*30fdc8d8SChris Lattner { 66*30fdc8d8SChris Lattner s->Printf ("Stepping one instruction past "); 67*30fdc8d8SChris Lattner s->Address(m_instruction_addr, sizeof (addr_t)); 68*30fdc8d8SChris Lattner if (m_step_over) 69*30fdc8d8SChris Lattner s->Printf(" stepping over calls"); 70*30fdc8d8SChris Lattner else 71*30fdc8d8SChris Lattner s->Printf(" stepping into calls"); 72*30fdc8d8SChris Lattner } 73*30fdc8d8SChris Lattner } 74*30fdc8d8SChris Lattner 75*30fdc8d8SChris Lattner bool 76*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ValidatePlan (Stream *error) 77*30fdc8d8SChris Lattner { 78*30fdc8d8SChris Lattner // Since we read the instruction we're stepping over from the thread, 79*30fdc8d8SChris Lattner // this plan will always work. 80*30fdc8d8SChris Lattner return true; 81*30fdc8d8SChris Lattner } 82*30fdc8d8SChris Lattner 83*30fdc8d8SChris Lattner bool 84*30fdc8d8SChris Lattner ThreadPlanStepInstruction::PlanExplainsStop () 85*30fdc8d8SChris Lattner { 86*30fdc8d8SChris Lattner Thread::StopInfo info; 87*30fdc8d8SChris Lattner if (m_thread.GetStopInfo (&info)) 88*30fdc8d8SChris Lattner { 89*30fdc8d8SChris Lattner StopReason reason = info.GetStopReason(); 90*30fdc8d8SChris Lattner if (reason == eStopReasonTrace || reason ==eStopReasonNone) 91*30fdc8d8SChris Lattner return true; 92*30fdc8d8SChris Lattner else 93*30fdc8d8SChris Lattner return false; 94*30fdc8d8SChris Lattner } 95*30fdc8d8SChris Lattner return false; 96*30fdc8d8SChris Lattner } 97*30fdc8d8SChris Lattner 98*30fdc8d8SChris Lattner bool 99*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) 100*30fdc8d8SChris Lattner { 101*30fdc8d8SChris Lattner if (m_step_over) 102*30fdc8d8SChris Lattner { 103*30fdc8d8SChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 104*30fdc8d8SChris Lattner if (m_thread.GetStackFrameCount() <= m_stack_depth) 105*30fdc8d8SChris Lattner { 106*30fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 107*30fdc8d8SChris Lattner { 108*30fdc8d8SChris Lattner SetPlanComplete(); 109*30fdc8d8SChris Lattner return true; 110*30fdc8d8SChris Lattner } 111*30fdc8d8SChris Lattner else 112*30fdc8d8SChris Lattner return false; 113*30fdc8d8SChris Lattner } 114*30fdc8d8SChris Lattner else 115*30fdc8d8SChris Lattner { 116*30fdc8d8SChris Lattner // We've stepped in, step back out again: 117*30fdc8d8SChris Lattner StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); 118*30fdc8d8SChris Lattner if (return_frame) 119*30fdc8d8SChris Lattner { 120*30fdc8d8SChris Lattner if (log) 121*30fdc8d8SChris Lattner { 122*30fdc8d8SChris Lattner StreamString s; 123*30fdc8d8SChris Lattner s.PutCString ("Stepped in to: "); 124*30fdc8d8SChris Lattner addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess()); 125*30fdc8d8SChris Lattner s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize()); 126*30fdc8d8SChris Lattner s.PutCString (" stepping out to: "); 127*30fdc8d8SChris Lattner addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); 128*30fdc8d8SChris Lattner s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); 129*30fdc8d8SChris Lattner log->Printf("%s.", s.GetData()); 130*30fdc8d8SChris Lattner } 131*30fdc8d8SChris Lattner m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion); 132*30fdc8d8SChris Lattner return false; 133*30fdc8d8SChris Lattner } 134*30fdc8d8SChris Lattner else 135*30fdc8d8SChris Lattner { 136*30fdc8d8SChris Lattner if (log) 137*30fdc8d8SChris Lattner log->Printf("Could not find previous frame, stopping."); 138*30fdc8d8SChris Lattner SetPlanComplete(); 139*30fdc8d8SChris Lattner return true; 140*30fdc8d8SChris Lattner } 141*30fdc8d8SChris Lattner 142*30fdc8d8SChris Lattner } 143*30fdc8d8SChris Lattner 144*30fdc8d8SChris Lattner } 145*30fdc8d8SChris Lattner else 146*30fdc8d8SChris Lattner { 147*30fdc8d8SChris Lattner if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) 148*30fdc8d8SChris Lattner { 149*30fdc8d8SChris Lattner SetPlanComplete(); 150*30fdc8d8SChris Lattner return true; 151*30fdc8d8SChris Lattner } 152*30fdc8d8SChris Lattner else 153*30fdc8d8SChris Lattner return false; 154*30fdc8d8SChris Lattner } 155*30fdc8d8SChris Lattner } 156*30fdc8d8SChris Lattner 157*30fdc8d8SChris Lattner bool 158*30fdc8d8SChris Lattner ThreadPlanStepInstruction::StopOthers () 159*30fdc8d8SChris Lattner { 160*30fdc8d8SChris Lattner return m_stop_other_threads; 161*30fdc8d8SChris Lattner } 162*30fdc8d8SChris Lattner 163*30fdc8d8SChris Lattner StateType 164*30fdc8d8SChris Lattner ThreadPlanStepInstruction::RunState () 165*30fdc8d8SChris Lattner { 166*30fdc8d8SChris Lattner return eStateStepping; 167*30fdc8d8SChris Lattner } 168*30fdc8d8SChris Lattner 169*30fdc8d8SChris Lattner bool 170*30fdc8d8SChris Lattner ThreadPlanStepInstruction::WillStop () 171*30fdc8d8SChris Lattner { 172*30fdc8d8SChris Lattner return true; 173*30fdc8d8SChris Lattner } 174*30fdc8d8SChris Lattner 175*30fdc8d8SChris Lattner bool 176*30fdc8d8SChris Lattner ThreadPlanStepInstruction::MischiefManaged () 177*30fdc8d8SChris Lattner { 178*30fdc8d8SChris Lattner if (IsPlanComplete()) 179*30fdc8d8SChris Lattner { 180*30fdc8d8SChris Lattner Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 181*30fdc8d8SChris Lattner if (log) 182*30fdc8d8SChris Lattner log->Printf("Completed single instruction step plan."); 183*30fdc8d8SChris Lattner ThreadPlan::MischiefManaged (); 184*30fdc8d8SChris Lattner return true; 185*30fdc8d8SChris Lattner } 186*30fdc8d8SChris Lattner else 187*30fdc8d8SChris Lattner { 188*30fdc8d8SChris Lattner return false; 189*30fdc8d8SChris Lattner } 190*30fdc8d8SChris Lattner } 191*30fdc8d8SChris Lattner 192