blob: 5e614e5aa52e64d9859bad12943c9f9ed8920d21 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
23using namespace lldb;
24using 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
32ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others) :
33 ThreadPlan ("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
40ThreadPlanStepThrough::~ThreadPlanStepThrough ()
41{
42}
43
44void
45ThreadPlanStepThrough::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
56bool
57ThreadPlanStepThrough::ValidatePlan (Stream *error)
58{
59 if (HappyToStopHere())
60 return false;
61 else
62 return true;
63}
64
65bool
66ThreadPlanStepThrough::PlanExplainsStop ()
67{
68 return true;
69}
70
71bool
72ThreadPlanStepThrough::ShouldStop (Event *event_ptr)
73{
74 return true;
75}
76
77bool
78ThreadPlanStepThrough::StopOthers ()
79{
80 return m_stop_others;
81}
82
83StateType
84ThreadPlanStepThrough::RunState ()
85{
86 return eStateStepping;
87}
88
89bool
90ThreadPlanStepThrough::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
102bool
103ThreadPlanStepThrough::WillStop ()
104{
105 return true;
106}
107
108bool
109ThreadPlanStepThrough::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
129bool
130ThreadPlanStepThrough::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