1*30fdc8d8SChris Lattner //===-- StackFrame.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 #include "lldb/Target/StackFrame.h"
11*30fdc8d8SChris Lattner 
12*30fdc8d8SChris Lattner // C Includes
13*30fdc8d8SChris Lattner // C++ Includes
14*30fdc8d8SChris Lattner // Other libraries and framework includes
15*30fdc8d8SChris Lattner // Project includes
16*30fdc8d8SChris Lattner #include "lldb/Core/Module.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h"
18*30fdc8d8SChris Lattner #include "lldb/Core/Value.h"
19*30fdc8d8SChris Lattner #include "lldb/Symbol/Function.h"
20*30fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
21*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
23*30fdc8d8SChris Lattner #include "lldb/Target/Target.h"
24*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
25*30fdc8d8SChris Lattner 
26*30fdc8d8SChris Lattner using namespace lldb;
27*30fdc8d8SChris Lattner using namespace lldb_private;
28*30fdc8d8SChris Lattner 
29*30fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits
30*30fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol
31*30fdc8d8SChris Lattner // context (m_sc) already.
32*30fdc8d8SChris Lattner #define RESOLVED_PC_SO_ADDR (uint32_t(eSymbolContextEverything + 1))
33*30fdc8d8SChris Lattner #define RESOLVED_FRAME_ID   (RESOLVED_PC_SO_ADDR << 1)
34*30fdc8d8SChris Lattner #define GOT_FRAME_BASE      (RESOLVED_FRAME_ID << 1)
35*30fdc8d8SChris Lattner #define FRAME_IS_OBSOLETE   (GOT_FRAME_BASE << 1)
36*30fdc8d8SChris Lattner #define RESOLVED_VARIABLES  (FRAME_IS_OBSOLETE << 1)
37*30fdc8d8SChris Lattner 
38*30fdc8d8SChris Lattner StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) :
39*30fdc8d8SChris Lattner     UserID (frame_idx),
40*30fdc8d8SChris Lattner     m_thread (thread),
41*30fdc8d8SChris Lattner     m_reg_context_sp(),
42*30fdc8d8SChris Lattner     m_id(cfa),
43*30fdc8d8SChris Lattner     m_pc(NULL, pc),
44*30fdc8d8SChris Lattner     m_sc(),
45*30fdc8d8SChris Lattner     m_flags(),
46*30fdc8d8SChris Lattner     m_frame_base(),
47*30fdc8d8SChris Lattner     m_frame_base_error(),
48*30fdc8d8SChris Lattner     m_variable_list_sp (),
49*30fdc8d8SChris Lattner     m_value_object_list ()
50*30fdc8d8SChris Lattner {
51*30fdc8d8SChris Lattner     if (sc_ptr != NULL)
52*30fdc8d8SChris Lattner         m_sc = *sc_ptr;
53*30fdc8d8SChris Lattner }
54*30fdc8d8SChris Lattner 
55*30fdc8d8SChris Lattner StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, RegisterContextSP &reg_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) :
56*30fdc8d8SChris Lattner     UserID (frame_idx),
57*30fdc8d8SChris Lattner     m_thread (thread),
58*30fdc8d8SChris Lattner     m_reg_context_sp(reg_context_sp),
59*30fdc8d8SChris Lattner     m_id(cfa),
60*30fdc8d8SChris Lattner     m_pc(NULL, pc),
61*30fdc8d8SChris Lattner     m_sc(),
62*30fdc8d8SChris Lattner     m_flags(),
63*30fdc8d8SChris Lattner     m_frame_base(),
64*30fdc8d8SChris Lattner     m_frame_base_error(),
65*30fdc8d8SChris Lattner     m_variable_list_sp (),
66*30fdc8d8SChris Lattner     m_value_object_list ()
67*30fdc8d8SChris Lattner {
68*30fdc8d8SChris Lattner     if (sc_ptr != NULL)
69*30fdc8d8SChris Lattner         m_sc = *sc_ptr;
70*30fdc8d8SChris Lattner }
71*30fdc8d8SChris Lattner 
72*30fdc8d8SChris Lattner 
73*30fdc8d8SChris Lattner //----------------------------------------------------------------------
74*30fdc8d8SChris Lattner // Destructor
75*30fdc8d8SChris Lattner //----------------------------------------------------------------------
76*30fdc8d8SChris Lattner StackFrame::~StackFrame()
77*30fdc8d8SChris Lattner {
78*30fdc8d8SChris Lattner }
79*30fdc8d8SChris Lattner 
80*30fdc8d8SChris Lattner StackID&
81*30fdc8d8SChris Lattner StackFrame::GetStackID()
82*30fdc8d8SChris Lattner {
83*30fdc8d8SChris Lattner     // Make sure we have resolved our stack ID's address range before we give
84*30fdc8d8SChris Lattner     // it out to any external clients
85*30fdc8d8SChris Lattner     if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
86*30fdc8d8SChris Lattner     {
87*30fdc8d8SChris Lattner         m_flags.Set (RESOLVED_FRAME_ID);
88*30fdc8d8SChris Lattner 
89*30fdc8d8SChris Lattner         // Resolve our PC to section offset if we haven't alreday done so
90*30fdc8d8SChris Lattner         // and if we don't have a module. The resolved address section will
91*30fdc8d8SChris Lattner         // contain the module to which it belongs.
92*30fdc8d8SChris Lattner         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
93*30fdc8d8SChris Lattner             GetPC();
94*30fdc8d8SChris Lattner 
95*30fdc8d8SChris Lattner         const uint32_t resolve_scope = eSymbolContextModule |
96*30fdc8d8SChris Lattner                                        eSymbolContextCompUnit |
97*30fdc8d8SChris Lattner                                        eSymbolContextFunction;
98*30fdc8d8SChris Lattner 
99*30fdc8d8SChris Lattner         if (m_sc.module_sp)
100*30fdc8d8SChris Lattner         {
101*30fdc8d8SChris Lattner             if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
102*30fdc8d8SChris Lattner             {
103*30fdc8d8SChris Lattner                 assert (m_sc.function);
104*30fdc8d8SChris Lattner                 m_id.SetStartAddress(m_sc.function->GetAddressRange().GetBaseAddress());
105*30fdc8d8SChris Lattner             }
106*30fdc8d8SChris Lattner             else if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
107*30fdc8d8SChris Lattner             {
108*30fdc8d8SChris Lattner                 assert (m_sc.symbol);
109*30fdc8d8SChris Lattner                 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
110*30fdc8d8SChris Lattner                 if (symbol_range_ptr)
111*30fdc8d8SChris Lattner                     m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
112*30fdc8d8SChris Lattner             }
113*30fdc8d8SChris Lattner         }
114*30fdc8d8SChris Lattner //      else if (m_sc.target != NULL)
115*30fdc8d8SChris Lattner //      {
116*30fdc8d8SChris Lattner //          if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
117*30fdc8d8SChris Lattner //          {
118*30fdc8d8SChris Lattner //              assert (m_sc.function);
119*30fdc8d8SChris Lattner //              m_id.GetAddressRange() = m_sc.function->GetAddressRange();
120*30fdc8d8SChris Lattner //          }
121*30fdc8d8SChris Lattner //          else if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
122*30fdc8d8SChris Lattner //          {
123*30fdc8d8SChris Lattner //              assert (m_sc.symbol);
124*30fdc8d8SChris Lattner //              AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRange();
125*30fdc8d8SChris Lattner //              if (symbol_range_ptr)
126*30fdc8d8SChris Lattner //                  m_id.GetAddressRange() = *symbol_range_ptr;
127*30fdc8d8SChris Lattner //          }
128*30fdc8d8SChris Lattner //      }
129*30fdc8d8SChris Lattner     }
130*30fdc8d8SChris Lattner     return m_id;
131*30fdc8d8SChris Lattner }
132*30fdc8d8SChris Lattner 
133*30fdc8d8SChris Lattner Address&
134*30fdc8d8SChris Lattner StackFrame::GetPC()
135*30fdc8d8SChris Lattner {
136*30fdc8d8SChris Lattner     if (m_flags.IsClear(RESOLVED_PC_SO_ADDR) && !m_pc.IsSectionOffset())
137*30fdc8d8SChris Lattner     {
138*30fdc8d8SChris Lattner         m_flags.Set (RESOLVED_PC_SO_ADDR);
139*30fdc8d8SChris Lattner 
140*30fdc8d8SChris Lattner         // Resolve the PC into a temporary address because if ResolveLoadAddress
141*30fdc8d8SChris Lattner         // fails to resolve the address, it will clear the address object...
142*30fdc8d8SChris Lattner         Address resolved_pc;
143*30fdc8d8SChris Lattner         if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
144*30fdc8d8SChris Lattner         {
145*30fdc8d8SChris Lattner             m_pc = resolved_pc;
146*30fdc8d8SChris Lattner             const Section *section = m_pc.GetSection();
147*30fdc8d8SChris Lattner             if (section)
148*30fdc8d8SChris Lattner             {
149*30fdc8d8SChris Lattner                 Module *module = section->GetModule();
150*30fdc8d8SChris Lattner                 if (module)
151*30fdc8d8SChris Lattner                 {
152*30fdc8d8SChris Lattner                     m_sc.module_sp = module->GetSP();
153*30fdc8d8SChris Lattner                     if (m_sc.module_sp)
154*30fdc8d8SChris Lattner                         m_flags.Set(eSymbolContextModule);
155*30fdc8d8SChris Lattner                 }
156*30fdc8d8SChris Lattner             }
157*30fdc8d8SChris Lattner         }
158*30fdc8d8SChris Lattner     }
159*30fdc8d8SChris Lattner     return m_pc;
160*30fdc8d8SChris Lattner }
161*30fdc8d8SChris Lattner 
162*30fdc8d8SChris Lattner void
163*30fdc8d8SChris Lattner StackFrame::ChangePC (addr_t pc)
164*30fdc8d8SChris Lattner {
165*30fdc8d8SChris Lattner     m_pc.SetOffset(pc);
166*30fdc8d8SChris Lattner     m_pc.SetSection(NULL);
167*30fdc8d8SChris Lattner     m_sc.Clear();
168*30fdc8d8SChris Lattner     m_flags.SetAllFlagBits(0);
169*30fdc8d8SChris Lattner     m_thread.ClearStackFrames ();
170*30fdc8d8SChris Lattner }
171*30fdc8d8SChris Lattner 
172*30fdc8d8SChris Lattner const char *
173*30fdc8d8SChris Lattner StackFrame::Disassemble ()
174*30fdc8d8SChris Lattner {
175*30fdc8d8SChris Lattner     if (m_disassembly.GetSize() == 0)
176*30fdc8d8SChris Lattner     {
177*30fdc8d8SChris Lattner         ExecutionContext exe_ctx;
178*30fdc8d8SChris Lattner         Calculate(exe_ctx);
179*30fdc8d8SChris Lattner         Disassembler::Disassemble (m_thread.GetProcess().GetTarget().GetArchitecture(),
180*30fdc8d8SChris Lattner                                    exe_ctx,
181*30fdc8d8SChris Lattner                                    0,
182*30fdc8d8SChris Lattner                                    m_disassembly);
183*30fdc8d8SChris Lattner         if (m_disassembly.GetSize() == 0)
184*30fdc8d8SChris Lattner             return NULL;
185*30fdc8d8SChris Lattner     }
186*30fdc8d8SChris Lattner     return m_disassembly.GetData();
187*30fdc8d8SChris Lattner }
188*30fdc8d8SChris Lattner 
189*30fdc8d8SChris Lattner //----------------------------------------------------------------------
190*30fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the
191*30fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a
192*30fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as
193*30fdc8d8SChris Lattner // possible and no one will ever have to look things up manually.
194*30fdc8d8SChris Lattner //----------------------------------------------------------------------
195*30fdc8d8SChris Lattner const SymbolContext&
196*30fdc8d8SChris Lattner StackFrame::GetSymbolContext (uint32_t resolve_scope)
197*30fdc8d8SChris Lattner {
198*30fdc8d8SChris Lattner     // Copy our internal symbol context into "sc".
199*30fdc8d8SChris Lattner 
200*30fdc8d8SChris Lattner     if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
201*30fdc8d8SChris Lattner     {
202*30fdc8d8SChris Lattner         // Resolve our PC to section offset if we haven't alreday done so
203*30fdc8d8SChris Lattner         // and if we don't have a module. The resolved address section will
204*30fdc8d8SChris Lattner         // contain the module to which it belongs
205*30fdc8d8SChris Lattner         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
206*30fdc8d8SChris Lattner             GetPC();
207*30fdc8d8SChris Lattner 
208*30fdc8d8SChris Lattner         // If this is not frame zero, then we need to subtract 1 from the PC
209*30fdc8d8SChris Lattner         // value when doing address lookups since the PC will be on the
210*30fdc8d8SChris Lattner         // instruction following the function call instruction...
211*30fdc8d8SChris Lattner 
212*30fdc8d8SChris Lattner         Address lookup_addr(GetPC());
213*30fdc8d8SChris Lattner         if (GetID() > 0 && lookup_addr.IsValid())
214*30fdc8d8SChris Lattner         {
215*30fdc8d8SChris Lattner             addr_t offset = lookup_addr.GetOffset();
216*30fdc8d8SChris Lattner             if (offset > 0)
217*30fdc8d8SChris Lattner                 lookup_addr.SetOffset(offset - 1);
218*30fdc8d8SChris Lattner         }
219*30fdc8d8SChris Lattner 
220*30fdc8d8SChris Lattner         if (m_sc.module_sp)
221*30fdc8d8SChris Lattner         {
222*30fdc8d8SChris Lattner             // We have something in our stack frame symbol context, lets check
223*30fdc8d8SChris Lattner             // if we haven't already tried to lookup one of those things. If we
224*30fdc8d8SChris Lattner             // haven't then we will do the query.
225*30fdc8d8SChris Lattner             if ((m_sc.comp_unit == NULL     && (resolve_scope & eSymbolContextCompUnit ) && m_flags.IsClear(eSymbolContextCompUnit   )) ||
226*30fdc8d8SChris Lattner                 (m_sc.function  == NULL     && (resolve_scope & eSymbolContextFunction ) && m_flags.IsClear(eSymbolContextFunction   )) ||
227*30fdc8d8SChris Lattner                 (m_sc.block     == NULL     && (resolve_scope & eSymbolContextBlock    ) && m_flags.IsClear(eSymbolContextBlock      )) ||
228*30fdc8d8SChris Lattner                 (m_sc.symbol    == NULL     && (resolve_scope & eSymbolContextSymbol   ) && m_flags.IsClear(eSymbolContextSymbol     )) ||
229*30fdc8d8SChris Lattner                 (!m_sc.line_entry.IsValid() && (resolve_scope & eSymbolContextLineEntry) && m_flags.IsClear(eSymbolContextLineEntry  )))
230*30fdc8d8SChris Lattner             {
231*30fdc8d8SChris Lattner                 // We might be resolving less information than what is already
232*30fdc8d8SChris Lattner                 // in our current symbol context so resolve into a temporary
233*30fdc8d8SChris Lattner                 // symbol context "sc" so we don't clear out data we have
234*30fdc8d8SChris Lattner                 // already found in "m_sc"
235*30fdc8d8SChris Lattner                 SymbolContext sc;
236*30fdc8d8SChris Lattner                 // Set flags that indicate what we have tried to resolve
237*30fdc8d8SChris Lattner                 const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, resolve_scope, sc);
238*30fdc8d8SChris Lattner                 if (resolved & eSymbolContextCompUnit)  m_sc.comp_unit  = sc.comp_unit;
239*30fdc8d8SChris Lattner                 if (resolved & eSymbolContextFunction)  m_sc.function   = sc.function;
240*30fdc8d8SChris Lattner                 if (resolved & eSymbolContextBlock)     m_sc.block      = sc.block;
241*30fdc8d8SChris Lattner                 if (resolved & eSymbolContextSymbol)    m_sc.symbol     = sc.symbol;
242*30fdc8d8SChris Lattner                 if (resolved & eSymbolContextLineEntry) m_sc.line_entry = sc.line_entry;
243*30fdc8d8SChris Lattner             }
244*30fdc8d8SChris Lattner         }
245*30fdc8d8SChris Lattner         else
246*30fdc8d8SChris Lattner         {
247*30fdc8d8SChris Lattner             // If we don't have a module, then we can't have the compile unit,
248*30fdc8d8SChris Lattner             // function, block, line entry or symbol, so we can safely call
249*30fdc8d8SChris Lattner             // ResolveSymbolContextForAddress with our symbol context member m_sc.
250*30fdc8d8SChris Lattner             m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
251*30fdc8d8SChris Lattner         }
252*30fdc8d8SChris Lattner 
253*30fdc8d8SChris Lattner         // If the target was requested add that:
254*30fdc8d8SChris Lattner         if (m_sc.target_sp.get() == NULL)
255*30fdc8d8SChris Lattner             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
256*30fdc8d8SChris Lattner 
257*30fdc8d8SChris Lattner         // Update our internal flags so we remember what we have tried to locate so
258*30fdc8d8SChris Lattner         // we don't have to keep trying when more calls to this function are made.
259*30fdc8d8SChris Lattner         m_flags.Set(resolve_scope);
260*30fdc8d8SChris Lattner     }
261*30fdc8d8SChris Lattner 
262*30fdc8d8SChris Lattner     // Return the symbol context with everything that was possible to resolve
263*30fdc8d8SChris Lattner     // resolved.
264*30fdc8d8SChris Lattner     return m_sc;
265*30fdc8d8SChris Lattner }
266*30fdc8d8SChris Lattner 
267*30fdc8d8SChris Lattner 
268*30fdc8d8SChris Lattner VariableList *
269*30fdc8d8SChris Lattner StackFrame::GetVariableList ()
270*30fdc8d8SChris Lattner {
271*30fdc8d8SChris Lattner     if (m_flags.IsClear(RESOLVED_VARIABLES))
272*30fdc8d8SChris Lattner     {
273*30fdc8d8SChris Lattner         m_flags.Set(RESOLVED_VARIABLES);
274*30fdc8d8SChris Lattner 
275*30fdc8d8SChris Lattner         GetSymbolContext(eSymbolContextFunction);
276*30fdc8d8SChris Lattner         if (m_sc.function)
277*30fdc8d8SChris Lattner         {
278*30fdc8d8SChris Lattner             bool get_child_variables = true;
279*30fdc8d8SChris Lattner             bool can_create = true;
280*30fdc8d8SChris Lattner             m_variable_list_sp = m_sc.function->GetBlocks(can_create).GetVariableList (Block::RootID, get_child_variables, can_create);
281*30fdc8d8SChris Lattner         }
282*30fdc8d8SChris Lattner     }
283*30fdc8d8SChris Lattner     return m_variable_list_sp.get();
284*30fdc8d8SChris Lattner }
285*30fdc8d8SChris Lattner 
286*30fdc8d8SChris Lattner 
287*30fdc8d8SChris Lattner bool
288*30fdc8d8SChris Lattner StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
289*30fdc8d8SChris Lattner {
290*30fdc8d8SChris Lattner     if (m_flags.IsClear(GOT_FRAME_BASE))
291*30fdc8d8SChris Lattner     {
292*30fdc8d8SChris Lattner         if (m_sc.function)
293*30fdc8d8SChris Lattner         {
294*30fdc8d8SChris Lattner             m_frame_base.Clear();
295*30fdc8d8SChris Lattner             m_frame_base_error.Clear();
296*30fdc8d8SChris Lattner 
297*30fdc8d8SChris Lattner             m_flags.Set(GOT_FRAME_BASE);
298*30fdc8d8SChris Lattner             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
299*30fdc8d8SChris Lattner             Value expr_value;
300*30fdc8d8SChris Lattner             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
301*30fdc8d8SChris Lattner             {
302*30fdc8d8SChris Lattner                 // We should really have an error if evaluate returns, but in case
303*30fdc8d8SChris Lattner                 // we don't, lets set the error to something at least.
304*30fdc8d8SChris Lattner                 if (m_frame_base_error.Success())
305*30fdc8d8SChris Lattner                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
306*30fdc8d8SChris Lattner             }
307*30fdc8d8SChris Lattner             else
308*30fdc8d8SChris Lattner             {
309*30fdc8d8SChris Lattner                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
310*30fdc8d8SChris Lattner             }
311*30fdc8d8SChris Lattner         }
312*30fdc8d8SChris Lattner         else
313*30fdc8d8SChris Lattner         {
314*30fdc8d8SChris Lattner             m_frame_base_error.SetErrorString ("No function in symbol context.");
315*30fdc8d8SChris Lattner         }
316*30fdc8d8SChris Lattner     }
317*30fdc8d8SChris Lattner 
318*30fdc8d8SChris Lattner     if (m_frame_base_error.Success())
319*30fdc8d8SChris Lattner         frame_base = m_frame_base;
320*30fdc8d8SChris Lattner 
321*30fdc8d8SChris Lattner     if (error_ptr)
322*30fdc8d8SChris Lattner         *error_ptr = m_frame_base_error;
323*30fdc8d8SChris Lattner     return m_frame_base_error.Success();
324*30fdc8d8SChris Lattner }
325*30fdc8d8SChris Lattner 
326*30fdc8d8SChris Lattner RegisterContext *
327*30fdc8d8SChris Lattner StackFrame::GetRegisterContext ()
328*30fdc8d8SChris Lattner {
329*30fdc8d8SChris Lattner     if (m_reg_context_sp.get() == NULL)
330*30fdc8d8SChris Lattner         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
331*30fdc8d8SChris Lattner     return m_reg_context_sp.get();
332*30fdc8d8SChris Lattner }
333*30fdc8d8SChris Lattner 
334*30fdc8d8SChris Lattner bool
335*30fdc8d8SChris Lattner StackFrame::HasDebugInformation ()
336*30fdc8d8SChris Lattner {
337*30fdc8d8SChris Lattner     GetSymbolContext(eSymbolContextLineEntry);
338*30fdc8d8SChris Lattner     return m_sc.line_entry.IsValid();
339*30fdc8d8SChris Lattner }
340*30fdc8d8SChris Lattner 
341*30fdc8d8SChris Lattner ValueObjectList &
342*30fdc8d8SChris Lattner StackFrame::GetValueObjectList()
343*30fdc8d8SChris Lattner {
344*30fdc8d8SChris Lattner     return m_value_object_list;
345*30fdc8d8SChris Lattner }
346*30fdc8d8SChris Lattner 
347*30fdc8d8SChris Lattner 
348*30fdc8d8SChris Lattner Target *
349*30fdc8d8SChris Lattner StackFrame::CalculateTarget ()
350*30fdc8d8SChris Lattner {
351*30fdc8d8SChris Lattner     return m_thread.CalculateTarget();
352*30fdc8d8SChris Lattner }
353*30fdc8d8SChris Lattner 
354*30fdc8d8SChris Lattner Process *
355*30fdc8d8SChris Lattner StackFrame::CalculateProcess ()
356*30fdc8d8SChris Lattner {
357*30fdc8d8SChris Lattner     return m_thread.CalculateProcess();
358*30fdc8d8SChris Lattner }
359*30fdc8d8SChris Lattner 
360*30fdc8d8SChris Lattner Thread *
361*30fdc8d8SChris Lattner StackFrame::CalculateThread ()
362*30fdc8d8SChris Lattner {
363*30fdc8d8SChris Lattner     return &m_thread;
364*30fdc8d8SChris Lattner }
365*30fdc8d8SChris Lattner 
366*30fdc8d8SChris Lattner StackFrame *
367*30fdc8d8SChris Lattner StackFrame::CalculateStackFrame ()
368*30fdc8d8SChris Lattner {
369*30fdc8d8SChris Lattner     return this;
370*30fdc8d8SChris Lattner }
371*30fdc8d8SChris Lattner 
372*30fdc8d8SChris Lattner 
373*30fdc8d8SChris Lattner void
374*30fdc8d8SChris Lattner StackFrame::Calculate (ExecutionContext &exe_ctx)
375*30fdc8d8SChris Lattner {
376*30fdc8d8SChris Lattner     m_thread.Calculate (exe_ctx);
377*30fdc8d8SChris Lattner     exe_ctx.frame = this;
378*30fdc8d8SChris Lattner }
379*30fdc8d8SChris Lattner 
380*30fdc8d8SChris Lattner void
381*30fdc8d8SChris Lattner StackFrame::Dump (Stream *strm, bool show_frame_index)
382*30fdc8d8SChris Lattner {
383*30fdc8d8SChris Lattner     if (strm == NULL)
384*30fdc8d8SChris Lattner         return;
385*30fdc8d8SChris Lattner 
386*30fdc8d8SChris Lattner     if (show_frame_index)
387*30fdc8d8SChris Lattner         strm->Printf("frame #%u: ", GetID());
388*30fdc8d8SChris Lattner     strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC());
389*30fdc8d8SChris Lattner     SymbolContext sc (GetSymbolContext(eSymbolContextEverything));
390*30fdc8d8SChris Lattner     strm->PutCString(", where = ");
391*30fdc8d8SChris Lattner     sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC());
392*30fdc8d8SChris Lattner }
393*30fdc8d8SChris Lattner 
394