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 ®_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, 184dda4f7b5SGreg 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; 283*0b76a2c2SGreg Clayton m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (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