blob: c7257a762f6e03e97b682feff3b25da889591de0 [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"
Jim Inghamb66cd072010-09-28 01:25:32 +000020#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// ThreadPlanStepThrough: If the current instruction is a trampoline, step through it
29// If it is the beginning of the prologue of a function, step through that as well.
30// FIXME: At present only handles DYLD trampolines.
31//----------------------------------------------------------------------
32
33ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others) :
Jim Ingham5a47e8b2010-06-19 04:45:32 +000034 ThreadPlan (ThreadPlan::eKindStepThrough, "Step through trampolines and prologues", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner24943d22010-06-08 16:52:24 +000035 m_start_address (0),
36 m_stop_others (stop_others)
37{
38 m_start_address = GetThread().GetRegisterContext()->GetPC(0);
39}
40
41ThreadPlanStepThrough::~ThreadPlanStepThrough ()
42{
43}
44
45void
46ThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level)
47{
48 if (level == lldb::eDescriptionLevelBrief)
49 s->Printf ("Step through");
50 else
51 {
52 s->Printf ("Stepping through trampoline code from: ");
53 s->Address(m_start_address, sizeof (addr_t));
54 }
55}
56
57bool
58ThreadPlanStepThrough::ValidatePlan (Stream *error)
59{
60 if (HappyToStopHere())
61 return false;
62 else
63 return true;
64}
65
66bool
67ThreadPlanStepThrough::PlanExplainsStop ()
68{
69 return true;
70}
71
72bool
73ThreadPlanStepThrough::ShouldStop (Event *event_ptr)
74{
75 return true;
76}
77
78bool
79ThreadPlanStepThrough::StopOthers ()
80{
81 return m_stop_others;
82}
83
84StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +000085ThreadPlanStepThrough::GetPlanRunState ()
Chris Lattner24943d22010-06-08 16:52:24 +000086{
87 return eStateStepping;
88}
89
90bool
91ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan)
92{
93 ThreadPlan::WillResume(resume_state, current_plan);
94 if (current_plan)
95 {
96 ThreadPlanSP sub_plan_sp(m_thread.GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others));
Jim Inghamb66cd072010-09-28 01:25:32 +000097 // If that didn't come up with anything, try the ObjC runtime plugin:
98 if (sub_plan_sp == NULL)
99 {
100 ObjCLanguageRuntime *objc_runtime = m_thread.GetProcess().GetObjCLanguageRuntime();
101 if (objc_runtime)
102 sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (m_thread, m_stop_others);
103 }
104
Chris Lattner24943d22010-06-08 16:52:24 +0000105 if (sub_plan_sp != NULL)
106 PushPlan (sub_plan_sp);
107 }
108 return true;
109}
110
111bool
112ThreadPlanStepThrough::WillStop ()
113{
114 return true;
115}
116
117bool
118ThreadPlanStepThrough::MischiefManaged ()
119{
Greg Claytone005f2c2010-11-06 01:53:30 +0000120 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000121
122 // Stop if we're happy with the place we've landed...
123
124 if (!HappyToStopHere())
125 {
126 // If we are still at the PC we were trying to step over.
127 return false;
128 }
129 else
130 {
131 if (log)
132 log->Printf("Completed step through step plan.");
133 ThreadPlan::MischiefManaged ();
134 return true;
135 }
136}
137
138bool
139ThreadPlanStepThrough::HappyToStopHere()
140{
141 // This should again ask the various trampolines whether we are still at a
142 // trampoline point, and if so, continue through the possibly nested trampolines.
143
144 return true;
145}
146