1 //===-- ThreadPlanStepThrough.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Target/ThreadPlanStepThrough.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/lldb-private-log.h" 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Target/DynamicLoader.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/RegisterContext.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 //---------------------------------------------------------------------- 27 // ThreadPlanStepThrough: If the current instruction is a trampoline, step through it 28 // If it is the beginning of the prologue of a function, step through that as well. 29 // FIXME: At present only handles DYLD trampolines. 30 //---------------------------------------------------------------------- 31 32 ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others) : 33 ThreadPlan (ThreadPlan::eKindStepThrough, "Step through trampolines and prologues", thread, eVoteNoOpinion, eVoteNoOpinion), 34 m_start_address (0), 35 m_stop_others (stop_others) 36 { 37 m_start_address = GetThread().GetRegisterContext()->GetPC(0); 38 } 39 40 ThreadPlanStepThrough::~ThreadPlanStepThrough () 41 { 42 } 43 44 void 45 ThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level) 46 { 47 if (level == lldb::eDescriptionLevelBrief) 48 s->Printf ("Step through"); 49 else 50 { 51 s->Printf ("Stepping through trampoline code from: "); 52 s->Address(m_start_address, sizeof (addr_t)); 53 } 54 } 55 56 bool 57 ThreadPlanStepThrough::ValidatePlan (Stream *error) 58 { 59 if (HappyToStopHere()) 60 return false; 61 else 62 return true; 63 } 64 65 bool 66 ThreadPlanStepThrough::PlanExplainsStop () 67 { 68 return true; 69 } 70 71 bool 72 ThreadPlanStepThrough::ShouldStop (Event *event_ptr) 73 { 74 return true; 75 } 76 77 bool 78 ThreadPlanStepThrough::StopOthers () 79 { 80 return m_stop_others; 81 } 82 83 StateType 84 ThreadPlanStepThrough::RunState () 85 { 86 return eStateStepping; 87 } 88 89 bool 90 ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan) 91 { 92 ThreadPlan::WillResume(resume_state, current_plan); 93 if (current_plan) 94 { 95 ThreadPlanSP sub_plan_sp(m_thread.GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others)); 96 if (sub_plan_sp != NULL) 97 PushPlan (sub_plan_sp); 98 } 99 return true; 100 } 101 102 bool 103 ThreadPlanStepThrough::WillStop () 104 { 105 return true; 106 } 107 108 bool 109 ThreadPlanStepThrough::MischiefManaged () 110 { 111 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); 112 113 // Stop if we're happy with the place we've landed... 114 115 if (!HappyToStopHere()) 116 { 117 // If we are still at the PC we were trying to step over. 118 return false; 119 } 120 else 121 { 122 if (log) 123 log->Printf("Completed step through step plan."); 124 ThreadPlan::MischiefManaged (); 125 return true; 126 } 127 } 128 129 bool 130 ThreadPlanStepThrough::HappyToStopHere() 131 { 132 // This should again ask the various trampolines whether we are still at a 133 // trampoline point, and if so, continue through the possibly nested trampolines. 134 135 return true; 136 } 137 138