130fdc8d8SChris Lattner //===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Core/Module.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Value.h"
1930fdc8d8SChris Lattner #include "lldb/Symbol/Function.h"
2030fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2230fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2530fdc8d8SChris Lattner 
2630fdc8d8SChris Lattner using namespace lldb;
2730fdc8d8SChris Lattner using namespace lldb_private;
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits
3030fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol
3130fdc8d8SChris Lattner // context (m_sc) already.
3230fdc8d8SChris Lattner #define RESOLVED_PC_SO_ADDR (uint32_t(eSymbolContextEverything + 1))
3330fdc8d8SChris Lattner #define RESOLVED_FRAME_ID   (RESOLVED_PC_SO_ADDR << 1)
3430fdc8d8SChris Lattner #define GOT_FRAME_BASE      (RESOLVED_FRAME_ID << 1)
3530fdc8d8SChris Lattner #define FRAME_IS_OBSOLETE   (GOT_FRAME_BASE << 1)
3630fdc8d8SChris Lattner #define RESOLVED_VARIABLES  (FRAME_IS_OBSOLETE << 1)
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) :
3930fdc8d8SChris Lattner     UserID (frame_idx),
4030fdc8d8SChris Lattner     m_thread (thread),
4130fdc8d8SChris Lattner     m_reg_context_sp(),
4230fdc8d8SChris Lattner     m_id(cfa),
4330fdc8d8SChris Lattner     m_pc(NULL, pc),
4430fdc8d8SChris Lattner     m_sc(),
4530fdc8d8SChris Lattner     m_flags(),
4630fdc8d8SChris Lattner     m_frame_base(),
4730fdc8d8SChris Lattner     m_frame_base_error(),
4830fdc8d8SChris Lattner     m_variable_list_sp (),
4930fdc8d8SChris Lattner     m_value_object_list ()
5030fdc8d8SChris Lattner {
5130fdc8d8SChris Lattner     if (sc_ptr != NULL)
5230fdc8d8SChris Lattner         m_sc = *sc_ptr;
5330fdc8d8SChris Lattner }
5430fdc8d8SChris Lattner 
5530fdc8d8SChris 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) :
5630fdc8d8SChris Lattner     UserID (frame_idx),
5730fdc8d8SChris Lattner     m_thread (thread),
5830fdc8d8SChris Lattner     m_reg_context_sp(reg_context_sp),
5930fdc8d8SChris Lattner     m_id(cfa),
6030fdc8d8SChris Lattner     m_pc(NULL, pc),
6130fdc8d8SChris Lattner     m_sc(),
6230fdc8d8SChris Lattner     m_flags(),
6330fdc8d8SChris Lattner     m_frame_base(),
6430fdc8d8SChris Lattner     m_frame_base_error(),
6530fdc8d8SChris Lattner     m_variable_list_sp (),
6630fdc8d8SChris Lattner     m_value_object_list ()
6730fdc8d8SChris Lattner {
6830fdc8d8SChris Lattner     if (sc_ptr != NULL)
6930fdc8d8SChris Lattner         m_sc = *sc_ptr;
7030fdc8d8SChris Lattner }
7130fdc8d8SChris Lattner 
7230fdc8d8SChris Lattner 
7330fdc8d8SChris Lattner //----------------------------------------------------------------------
7430fdc8d8SChris Lattner // Destructor
7530fdc8d8SChris Lattner //----------------------------------------------------------------------
7630fdc8d8SChris Lattner StackFrame::~StackFrame()
7730fdc8d8SChris Lattner {
7830fdc8d8SChris Lattner }
7930fdc8d8SChris Lattner 
8030fdc8d8SChris Lattner StackID&
8130fdc8d8SChris Lattner StackFrame::GetStackID()
8230fdc8d8SChris Lattner {
8330fdc8d8SChris Lattner     // Make sure we have resolved our stack ID's address range before we give
8430fdc8d8SChris Lattner     // it out to any external clients
8530fdc8d8SChris Lattner     if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
8630fdc8d8SChris Lattner     {
8730fdc8d8SChris Lattner         m_flags.Set (RESOLVED_FRAME_ID);
8830fdc8d8SChris Lattner 
8930fdc8d8SChris Lattner         // Resolve our PC to section offset if we haven't alreday done so
9030fdc8d8SChris Lattner         // and if we don't have a module. The resolved address section will
9130fdc8d8SChris Lattner         // contain the module to which it belongs.
9230fdc8d8SChris Lattner         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
9330fdc8d8SChris Lattner             GetPC();
9430fdc8d8SChris Lattner 
9530fdc8d8SChris Lattner         const uint32_t resolve_scope = eSymbolContextModule |
9630fdc8d8SChris Lattner                                        eSymbolContextCompUnit |
9730fdc8d8SChris Lattner                                        eSymbolContextFunction;
9830fdc8d8SChris Lattner 
9930fdc8d8SChris Lattner         if (m_sc.module_sp)
10030fdc8d8SChris Lattner         {
10130fdc8d8SChris Lattner             if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
10230fdc8d8SChris Lattner             {
10330fdc8d8SChris Lattner                 assert (m_sc.function);
10430fdc8d8SChris Lattner                 m_id.SetStartAddress(m_sc.function->GetAddressRange().GetBaseAddress());
10530fdc8d8SChris Lattner             }
10630fdc8d8SChris Lattner             else if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
10730fdc8d8SChris Lattner             {
10830fdc8d8SChris Lattner                 assert (m_sc.symbol);
10930fdc8d8SChris Lattner                 AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
11030fdc8d8SChris Lattner                 if (symbol_range_ptr)
11130fdc8d8SChris Lattner                     m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
11230fdc8d8SChris Lattner             }
11330fdc8d8SChris Lattner         }
11430fdc8d8SChris Lattner //      else if (m_sc.target != NULL)
11530fdc8d8SChris Lattner //      {
11630fdc8d8SChris Lattner //          if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
11730fdc8d8SChris Lattner //          {
11830fdc8d8SChris Lattner //              assert (m_sc.function);
11930fdc8d8SChris Lattner //              m_id.GetAddressRange() = m_sc.function->GetAddressRange();
12030fdc8d8SChris Lattner //          }
12130fdc8d8SChris Lattner //          else if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
12230fdc8d8SChris Lattner //          {
12330fdc8d8SChris Lattner //              assert (m_sc.symbol);
12430fdc8d8SChris Lattner //              AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRange();
12530fdc8d8SChris Lattner //              if (symbol_range_ptr)
12630fdc8d8SChris Lattner //                  m_id.GetAddressRange() = *symbol_range_ptr;
12730fdc8d8SChris Lattner //          }
12830fdc8d8SChris Lattner //      }
12930fdc8d8SChris Lattner     }
13030fdc8d8SChris Lattner     return m_id;
13130fdc8d8SChris Lattner }
13230fdc8d8SChris Lattner 
13330fdc8d8SChris Lattner Address&
13430fdc8d8SChris Lattner StackFrame::GetPC()
13530fdc8d8SChris Lattner {
13630fdc8d8SChris Lattner     if (m_flags.IsClear(RESOLVED_PC_SO_ADDR) && !m_pc.IsSectionOffset())
13730fdc8d8SChris Lattner     {
13830fdc8d8SChris Lattner         m_flags.Set (RESOLVED_PC_SO_ADDR);
13930fdc8d8SChris Lattner 
14030fdc8d8SChris Lattner         // Resolve the PC into a temporary address because if ResolveLoadAddress
14130fdc8d8SChris Lattner         // fails to resolve the address, it will clear the address object...
14230fdc8d8SChris Lattner         Address resolved_pc;
14330fdc8d8SChris Lattner         if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
14430fdc8d8SChris Lattner         {
14530fdc8d8SChris Lattner             m_pc = resolved_pc;
14630fdc8d8SChris Lattner             const Section *section = m_pc.GetSection();
14730fdc8d8SChris Lattner             if (section)
14830fdc8d8SChris Lattner             {
14930fdc8d8SChris Lattner                 Module *module = section->GetModule();
15030fdc8d8SChris Lattner                 if (module)
15130fdc8d8SChris Lattner                 {
15230fdc8d8SChris Lattner                     m_sc.module_sp = module->GetSP();
15330fdc8d8SChris Lattner                     if (m_sc.module_sp)
15430fdc8d8SChris Lattner                         m_flags.Set(eSymbolContextModule);
15530fdc8d8SChris Lattner                 }
15630fdc8d8SChris Lattner             }
15730fdc8d8SChris Lattner         }
15830fdc8d8SChris Lattner     }
15930fdc8d8SChris Lattner     return m_pc;
16030fdc8d8SChris Lattner }
16130fdc8d8SChris Lattner 
16230fdc8d8SChris Lattner void
16330fdc8d8SChris Lattner StackFrame::ChangePC (addr_t pc)
16430fdc8d8SChris Lattner {
16530fdc8d8SChris Lattner     m_pc.SetOffset(pc);
16630fdc8d8SChris Lattner     m_pc.SetSection(NULL);
16730fdc8d8SChris Lattner     m_sc.Clear();
16830fdc8d8SChris Lattner     m_flags.SetAllFlagBits(0);
16930fdc8d8SChris Lattner     m_thread.ClearStackFrames ();
17030fdc8d8SChris Lattner }
17130fdc8d8SChris Lattner 
17230fdc8d8SChris Lattner const char *
17330fdc8d8SChris Lattner StackFrame::Disassemble ()
17430fdc8d8SChris Lattner {
17530fdc8d8SChris Lattner     if (m_disassembly.GetSize() == 0)
17630fdc8d8SChris Lattner     {
17730fdc8d8SChris Lattner         ExecutionContext exe_ctx;
17830fdc8d8SChris Lattner         Calculate(exe_ctx);
1796611103cSGreg Clayton         Target &target = m_thread.GetProcess().GetTarget();
1806611103cSGreg Clayton         Disassembler::Disassemble (target.GetDebugger(),
1816611103cSGreg Clayton                                    target.GetArchitecture(),
18230fdc8d8SChris Lattner                                    exe_ctx,
18330fdc8d8SChris Lattner                                    0,
184*dda4f7b5SGreg Clayton                                    false,
18530fdc8d8SChris Lattner                                    m_disassembly);
18630fdc8d8SChris Lattner         if (m_disassembly.GetSize() == 0)
18730fdc8d8SChris Lattner             return NULL;
18830fdc8d8SChris Lattner     }
18930fdc8d8SChris Lattner     return m_disassembly.GetData();
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner 
19230fdc8d8SChris Lattner //----------------------------------------------------------------------
19330fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the
19430fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a
19530fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as
19630fdc8d8SChris Lattner // possible and no one will ever have to look things up manually.
19730fdc8d8SChris Lattner //----------------------------------------------------------------------
19830fdc8d8SChris Lattner const SymbolContext&
19930fdc8d8SChris Lattner StackFrame::GetSymbolContext (uint32_t resolve_scope)
20030fdc8d8SChris Lattner {
20130fdc8d8SChris Lattner     // Copy our internal symbol context into "sc".
20230fdc8d8SChris Lattner 
20330fdc8d8SChris Lattner     if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
20430fdc8d8SChris Lattner     {
20530fdc8d8SChris Lattner         // Resolve our PC to section offset if we haven't alreday done so
20630fdc8d8SChris Lattner         // and if we don't have a module. The resolved address section will
20730fdc8d8SChris Lattner         // contain the module to which it belongs
20830fdc8d8SChris Lattner         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
20930fdc8d8SChris Lattner             GetPC();
21030fdc8d8SChris Lattner 
21130fdc8d8SChris Lattner         // If this is not frame zero, then we need to subtract 1 from the PC
21230fdc8d8SChris Lattner         // value when doing address lookups since the PC will be on the
21330fdc8d8SChris Lattner         // instruction following the function call instruction...
21430fdc8d8SChris Lattner 
21530fdc8d8SChris Lattner         Address lookup_addr(GetPC());
21630fdc8d8SChris Lattner         if (GetID() > 0 && lookup_addr.IsValid())
21730fdc8d8SChris Lattner         {
21830fdc8d8SChris Lattner             addr_t offset = lookup_addr.GetOffset();
21930fdc8d8SChris Lattner             if (offset > 0)
22030fdc8d8SChris Lattner                 lookup_addr.SetOffset(offset - 1);
22130fdc8d8SChris Lattner         }
22230fdc8d8SChris Lattner 
22330fdc8d8SChris Lattner         if (m_sc.module_sp)
22430fdc8d8SChris Lattner         {
22530fdc8d8SChris Lattner             // We have something in our stack frame symbol context, lets check
22630fdc8d8SChris Lattner             // if we haven't already tried to lookup one of those things. If we
22730fdc8d8SChris Lattner             // haven't then we will do the query.
22830fdc8d8SChris Lattner             if ((m_sc.comp_unit == NULL     && (resolve_scope & eSymbolContextCompUnit ) && m_flags.IsClear(eSymbolContextCompUnit   )) ||
22930fdc8d8SChris Lattner                 (m_sc.function  == NULL     && (resolve_scope & eSymbolContextFunction ) && m_flags.IsClear(eSymbolContextFunction   )) ||
23030fdc8d8SChris Lattner                 (m_sc.block     == NULL     && (resolve_scope & eSymbolContextBlock    ) && m_flags.IsClear(eSymbolContextBlock      )) ||
23130fdc8d8SChris Lattner                 (m_sc.symbol    == NULL     && (resolve_scope & eSymbolContextSymbol   ) && m_flags.IsClear(eSymbolContextSymbol     )) ||
23230fdc8d8SChris Lattner                 (!m_sc.line_entry.IsValid() && (resolve_scope & eSymbolContextLineEntry) && m_flags.IsClear(eSymbolContextLineEntry  )))
23330fdc8d8SChris Lattner             {
23430fdc8d8SChris Lattner                 // We might be resolving less information than what is already
23530fdc8d8SChris Lattner                 // in our current symbol context so resolve into a temporary
23630fdc8d8SChris Lattner                 // symbol context "sc" so we don't clear out data we have
23730fdc8d8SChris Lattner                 // already found in "m_sc"
23830fdc8d8SChris Lattner                 SymbolContext sc;
23930fdc8d8SChris Lattner                 // Set flags that indicate what we have tried to resolve
24030fdc8d8SChris Lattner                 const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, resolve_scope, sc);
24130fdc8d8SChris Lattner                 if (resolved & eSymbolContextCompUnit)  m_sc.comp_unit  = sc.comp_unit;
24230fdc8d8SChris Lattner                 if (resolved & eSymbolContextFunction)  m_sc.function   = sc.function;
24330fdc8d8SChris Lattner                 if (resolved & eSymbolContextBlock)     m_sc.block      = sc.block;
24430fdc8d8SChris Lattner                 if (resolved & eSymbolContextSymbol)    m_sc.symbol     = sc.symbol;
24530fdc8d8SChris Lattner                 if (resolved & eSymbolContextLineEntry) m_sc.line_entry = sc.line_entry;
24630fdc8d8SChris Lattner             }
24730fdc8d8SChris Lattner         }
24830fdc8d8SChris Lattner         else
24930fdc8d8SChris Lattner         {
25030fdc8d8SChris Lattner             // If we don't have a module, then we can't have the compile unit,
25130fdc8d8SChris Lattner             // function, block, line entry or symbol, so we can safely call
25230fdc8d8SChris Lattner             // ResolveSymbolContextForAddress with our symbol context member m_sc.
25330fdc8d8SChris Lattner             m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
25430fdc8d8SChris Lattner         }
25530fdc8d8SChris Lattner 
25630fdc8d8SChris Lattner         // If the target was requested add that:
25730fdc8d8SChris Lattner         if (m_sc.target_sp.get() == NULL)
25830fdc8d8SChris Lattner             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
25930fdc8d8SChris Lattner 
26030fdc8d8SChris Lattner         // Update our internal flags so we remember what we have tried to locate so
26130fdc8d8SChris Lattner         // we don't have to keep trying when more calls to this function are made.
26230fdc8d8SChris Lattner         m_flags.Set(resolve_scope);
26330fdc8d8SChris Lattner     }
26430fdc8d8SChris Lattner 
26530fdc8d8SChris Lattner     // Return the symbol context with everything that was possible to resolve
26630fdc8d8SChris Lattner     // resolved.
26730fdc8d8SChris Lattner     return m_sc;
26830fdc8d8SChris Lattner }
26930fdc8d8SChris Lattner 
27030fdc8d8SChris Lattner 
27130fdc8d8SChris Lattner VariableList *
27230fdc8d8SChris Lattner StackFrame::GetVariableList ()
27330fdc8d8SChris Lattner {
27430fdc8d8SChris Lattner     if (m_flags.IsClear(RESOLVED_VARIABLES))
27530fdc8d8SChris Lattner     {
27630fdc8d8SChris Lattner         m_flags.Set(RESOLVED_VARIABLES);
27730fdc8d8SChris Lattner 
27830fdc8d8SChris Lattner         GetSymbolContext(eSymbolContextFunction);
27930fdc8d8SChris Lattner         if (m_sc.function)
28030fdc8d8SChris Lattner         {
28130fdc8d8SChris Lattner             bool get_child_variables = true;
28230fdc8d8SChris Lattner             bool can_create = true;
28330fdc8d8SChris Lattner             m_variable_list_sp = m_sc.function->GetBlocks(can_create).GetVariableList (Block::RootID, get_child_variables, can_create);
28430fdc8d8SChris Lattner         }
28530fdc8d8SChris Lattner     }
28630fdc8d8SChris Lattner     return m_variable_list_sp.get();
28730fdc8d8SChris Lattner }
28830fdc8d8SChris Lattner 
28930fdc8d8SChris Lattner 
29030fdc8d8SChris Lattner bool
29130fdc8d8SChris Lattner StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
29230fdc8d8SChris Lattner {
29330fdc8d8SChris Lattner     if (m_flags.IsClear(GOT_FRAME_BASE))
29430fdc8d8SChris Lattner     {
29530fdc8d8SChris Lattner         if (m_sc.function)
29630fdc8d8SChris Lattner         {
29730fdc8d8SChris Lattner             m_frame_base.Clear();
29830fdc8d8SChris Lattner             m_frame_base_error.Clear();
29930fdc8d8SChris Lattner 
30030fdc8d8SChris Lattner             m_flags.Set(GOT_FRAME_BASE);
30130fdc8d8SChris Lattner             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
30230fdc8d8SChris Lattner             Value expr_value;
30330fdc8d8SChris Lattner             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
30430fdc8d8SChris Lattner             {
30530fdc8d8SChris Lattner                 // We should really have an error if evaluate returns, but in case
30630fdc8d8SChris Lattner                 // we don't, lets set the error to something at least.
30730fdc8d8SChris Lattner                 if (m_frame_base_error.Success())
30830fdc8d8SChris Lattner                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
30930fdc8d8SChris Lattner             }
31030fdc8d8SChris Lattner             else
31130fdc8d8SChris Lattner             {
31230fdc8d8SChris Lattner                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
31330fdc8d8SChris Lattner             }
31430fdc8d8SChris Lattner         }
31530fdc8d8SChris Lattner         else
31630fdc8d8SChris Lattner         {
31730fdc8d8SChris Lattner             m_frame_base_error.SetErrorString ("No function in symbol context.");
31830fdc8d8SChris Lattner         }
31930fdc8d8SChris Lattner     }
32030fdc8d8SChris Lattner 
32130fdc8d8SChris Lattner     if (m_frame_base_error.Success())
32230fdc8d8SChris Lattner         frame_base = m_frame_base;
32330fdc8d8SChris Lattner 
32430fdc8d8SChris Lattner     if (error_ptr)
32530fdc8d8SChris Lattner         *error_ptr = m_frame_base_error;
32630fdc8d8SChris Lattner     return m_frame_base_error.Success();
32730fdc8d8SChris Lattner }
32830fdc8d8SChris Lattner 
32930fdc8d8SChris Lattner RegisterContext *
33030fdc8d8SChris Lattner StackFrame::GetRegisterContext ()
33130fdc8d8SChris Lattner {
33230fdc8d8SChris Lattner     if (m_reg_context_sp.get() == NULL)
33330fdc8d8SChris Lattner         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
33430fdc8d8SChris Lattner     return m_reg_context_sp.get();
33530fdc8d8SChris Lattner }
33630fdc8d8SChris Lattner 
33730fdc8d8SChris Lattner bool
33830fdc8d8SChris Lattner StackFrame::HasDebugInformation ()
33930fdc8d8SChris Lattner {
34030fdc8d8SChris Lattner     GetSymbolContext(eSymbolContextLineEntry);
34130fdc8d8SChris Lattner     return m_sc.line_entry.IsValid();
34230fdc8d8SChris Lattner }
34330fdc8d8SChris Lattner 
34430fdc8d8SChris Lattner ValueObjectList &
34530fdc8d8SChris Lattner StackFrame::GetValueObjectList()
34630fdc8d8SChris Lattner {
34730fdc8d8SChris Lattner     return m_value_object_list;
34830fdc8d8SChris Lattner }
34930fdc8d8SChris Lattner 
35030fdc8d8SChris Lattner 
35130fdc8d8SChris Lattner Target *
35230fdc8d8SChris Lattner StackFrame::CalculateTarget ()
35330fdc8d8SChris Lattner {
35430fdc8d8SChris Lattner     return m_thread.CalculateTarget();
35530fdc8d8SChris Lattner }
35630fdc8d8SChris Lattner 
35730fdc8d8SChris Lattner Process *
35830fdc8d8SChris Lattner StackFrame::CalculateProcess ()
35930fdc8d8SChris Lattner {
36030fdc8d8SChris Lattner     return m_thread.CalculateProcess();
36130fdc8d8SChris Lattner }
36230fdc8d8SChris Lattner 
36330fdc8d8SChris Lattner Thread *
36430fdc8d8SChris Lattner StackFrame::CalculateThread ()
36530fdc8d8SChris Lattner {
36630fdc8d8SChris Lattner     return &m_thread;
36730fdc8d8SChris Lattner }
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner StackFrame *
37030fdc8d8SChris Lattner StackFrame::CalculateStackFrame ()
37130fdc8d8SChris Lattner {
37230fdc8d8SChris Lattner     return this;
37330fdc8d8SChris Lattner }
37430fdc8d8SChris Lattner 
37530fdc8d8SChris Lattner 
37630fdc8d8SChris Lattner void
37730fdc8d8SChris Lattner StackFrame::Calculate (ExecutionContext &exe_ctx)
37830fdc8d8SChris Lattner {
37930fdc8d8SChris Lattner     m_thread.Calculate (exe_ctx);
38030fdc8d8SChris Lattner     exe_ctx.frame = this;
38130fdc8d8SChris Lattner }
38230fdc8d8SChris Lattner 
38330fdc8d8SChris Lattner void
38430fdc8d8SChris Lattner StackFrame::Dump (Stream *strm, bool show_frame_index)
38530fdc8d8SChris Lattner {
38630fdc8d8SChris Lattner     if (strm == NULL)
38730fdc8d8SChris Lattner         return;
38830fdc8d8SChris Lattner 
38930fdc8d8SChris Lattner     if (show_frame_index)
39030fdc8d8SChris Lattner         strm->Printf("frame #%u: ", GetID());
39130fdc8d8SChris Lattner     strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC());
39230fdc8d8SChris Lattner     SymbolContext sc (GetSymbolContext(eSymbolContextEverything));
39330fdc8d8SChris Lattner     strm->PutCString(", where = ");
39430fdc8d8SChris Lattner     sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC());
39530fdc8d8SChris Lattner }
39630fdc8d8SChris Lattner 
397