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"
170603aa9dSGreg Clayton #include "lldb/Core/Debugger.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h"
1930fdc8d8SChris Lattner #include "lldb/Core/Value.h"
20288bdf9cSGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
2130fdc8d8SChris Lattner #include "lldb/Symbol/Function.h"
22288bdf9cSGreg Clayton #include "lldb/Symbol/VariableList.h"
2330fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2530fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2630fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner using namespace lldb;
3030fdc8d8SChris Lattner using namespace lldb_private;
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner // The first bits in the flags are reserved for the SymbolContext::Scope bits
3330fdc8d8SChris Lattner // so we know if we have tried to look up information in our internal symbol
3430fdc8d8SChris Lattner // context (m_sc) already.
3559e8fc1cSGreg Clayton #define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
366dadd508SGreg Clayton #define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
3759e8fc1cSGreg Clayton #define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
3859e8fc1cSGreg Clayton #define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
397c0962dcSSean Callanan #define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
4030fdc8d8SChris Lattner 
411b72fcb7SGreg Clayton StackFrame::StackFrame
421b72fcb7SGreg Clayton (
431b72fcb7SGreg Clayton     lldb::user_id_t frame_idx,
4459e8fc1cSGreg Clayton     lldb::user_id_t unwind_frame_index,
451b72fcb7SGreg Clayton     Thread &thread,
461b72fcb7SGreg Clayton     lldb::addr_t cfa,
471b72fcb7SGreg Clayton     lldb::addr_t pc,
481b72fcb7SGreg Clayton     const SymbolContext *sc_ptr
491b72fcb7SGreg Clayton ) :
501b72fcb7SGreg Clayton     m_frame_index (frame_idx),
5159e8fc1cSGreg Clayton     m_unwind_frame_index (unwind_frame_index),
5230fdc8d8SChris Lattner     m_thread (thread),
5330fdc8d8SChris Lattner     m_reg_context_sp (),
546dadd508SGreg Clayton     m_id (pc, cfa, NULL),
5512fc3e0fSGreg Clayton     m_frame_code_addr (NULL, pc),
5630fdc8d8SChris Lattner     m_sc (),
5730fdc8d8SChris Lattner     m_flags (),
5830fdc8d8SChris Lattner     m_frame_base (),
5930fdc8d8SChris Lattner     m_frame_base_error (),
6030fdc8d8SChris Lattner     m_variable_list_sp (),
61288bdf9cSGreg Clayton     m_variable_list_value_objects ()
6230fdc8d8SChris Lattner {
6330fdc8d8SChris Lattner     if (sc_ptr != NULL)
641b72fcb7SGreg Clayton     {
6530fdc8d8SChris Lattner         m_sc = *sc_ptr;
661b72fcb7SGreg Clayton         m_flags.Set(m_sc.GetResolvedMask ());
671b72fcb7SGreg Clayton     }
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
701b72fcb7SGreg Clayton StackFrame::StackFrame
711b72fcb7SGreg Clayton (
721b72fcb7SGreg Clayton     lldb::user_id_t frame_idx,
7359e8fc1cSGreg Clayton     lldb::user_id_t unwind_frame_index,
741b72fcb7SGreg Clayton     Thread &thread,
751b72fcb7SGreg Clayton     const RegisterContextSP &reg_context_sp,
761b72fcb7SGreg Clayton     lldb::addr_t cfa,
771b72fcb7SGreg Clayton     lldb::addr_t pc,
781b72fcb7SGreg Clayton     const SymbolContext *sc_ptr
791b72fcb7SGreg Clayton ) :
801b72fcb7SGreg Clayton     m_frame_index (frame_idx),
8159e8fc1cSGreg Clayton     m_unwind_frame_index (unwind_frame_index),
8230fdc8d8SChris Lattner     m_thread (thread),
8330fdc8d8SChris Lattner     m_reg_context_sp (reg_context_sp),
846dadd508SGreg Clayton     m_id (pc, cfa, NULL),
8512fc3e0fSGreg Clayton     m_frame_code_addr (NULL, pc),
8630fdc8d8SChris Lattner     m_sc (),
8730fdc8d8SChris Lattner     m_flags (),
8830fdc8d8SChris Lattner     m_frame_base (),
8930fdc8d8SChris Lattner     m_frame_base_error (),
9030fdc8d8SChris Lattner     m_variable_list_sp (),
91288bdf9cSGreg Clayton     m_variable_list_value_objects ()
9230fdc8d8SChris Lattner {
9330fdc8d8SChris Lattner     if (sc_ptr != NULL)
941b72fcb7SGreg Clayton     {
9530fdc8d8SChris Lattner         m_sc = *sc_ptr;
961b72fcb7SGreg Clayton         m_flags.Set(m_sc.GetResolvedMask ());
971b72fcb7SGreg Clayton     }
981b72fcb7SGreg Clayton 
991b72fcb7SGreg Clayton     if (reg_context_sp && !m_sc.target_sp)
1001b72fcb7SGreg Clayton     {
1011b72fcb7SGreg Clayton         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
1021b72fcb7SGreg Clayton         m_flags.Set (eSymbolContextTarget);
1031b72fcb7SGreg Clayton     }
1041b72fcb7SGreg Clayton }
1051b72fcb7SGreg Clayton 
1061b72fcb7SGreg Clayton StackFrame::StackFrame
1071b72fcb7SGreg Clayton (
1081b72fcb7SGreg Clayton     lldb::user_id_t frame_idx,
10959e8fc1cSGreg Clayton     lldb::user_id_t unwind_frame_index,
1101b72fcb7SGreg Clayton     Thread &thread,
1111b72fcb7SGreg Clayton     const RegisterContextSP &reg_context_sp,
1121b72fcb7SGreg Clayton     lldb::addr_t cfa,
1131b72fcb7SGreg Clayton     const Address& pc_addr,
1141b72fcb7SGreg Clayton     const SymbolContext *sc_ptr
1151b72fcb7SGreg Clayton ) :
1161b72fcb7SGreg Clayton     m_frame_index (frame_idx),
11759e8fc1cSGreg Clayton     m_unwind_frame_index (unwind_frame_index),
1181b72fcb7SGreg Clayton     m_thread (thread),
1191b72fcb7SGreg Clayton     m_reg_context_sp (reg_context_sp),
120f5e56de0SGreg Clayton     m_id (pc_addr.GetLoadAddress (&thread.GetProcess().GetTarget()), cfa, NULL),
12112fc3e0fSGreg Clayton     m_frame_code_addr (pc_addr),
1221b72fcb7SGreg Clayton     m_sc (),
1231b72fcb7SGreg Clayton     m_flags (),
1241b72fcb7SGreg Clayton     m_frame_base (),
1251b72fcb7SGreg Clayton     m_frame_base_error (),
1261b72fcb7SGreg Clayton     m_variable_list_sp (),
127288bdf9cSGreg Clayton     m_variable_list_value_objects ()
1281b72fcb7SGreg Clayton {
1291b72fcb7SGreg Clayton     if (sc_ptr != NULL)
1301b72fcb7SGreg Clayton     {
1311b72fcb7SGreg Clayton         m_sc = *sc_ptr;
1321b72fcb7SGreg Clayton         m_flags.Set(m_sc.GetResolvedMask ());
1331b72fcb7SGreg Clayton     }
1341b72fcb7SGreg Clayton 
1351b72fcb7SGreg Clayton     if (m_sc.target_sp.get() == NULL && reg_context_sp)
1361b72fcb7SGreg Clayton     {
1371b72fcb7SGreg Clayton         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
1381b72fcb7SGreg Clayton         m_flags.Set (eSymbolContextTarget);
1391b72fcb7SGreg Clayton     }
1401b72fcb7SGreg Clayton 
141ffc1d667SGreg Clayton     Module *pc_module = pc_addr.GetModule();
142ffc1d667SGreg Clayton     if (m_sc.module_sp.get() == NULL || m_sc.module_sp.get() != pc_module)
1431b72fcb7SGreg Clayton     {
1441b72fcb7SGreg Clayton         if (pc_module)
1451b72fcb7SGreg Clayton         {
1461b72fcb7SGreg Clayton             m_sc.module_sp = pc_module->GetSP();
1471b72fcb7SGreg Clayton             m_flags.Set (eSymbolContextModule);
1481b72fcb7SGreg Clayton         }
149ffc1d667SGreg Clayton         else
150ffc1d667SGreg Clayton         {
151ffc1d667SGreg Clayton             m_sc.module_sp.reset();
152ffc1d667SGreg Clayton         }
153ffc1d667SGreg Clayton 
1541b72fcb7SGreg Clayton     }
15530fdc8d8SChris Lattner }
15630fdc8d8SChris Lattner 
15730fdc8d8SChris Lattner 
15830fdc8d8SChris Lattner //----------------------------------------------------------------------
15930fdc8d8SChris Lattner // Destructor
16030fdc8d8SChris Lattner //----------------------------------------------------------------------
16130fdc8d8SChris Lattner StackFrame::~StackFrame()
16230fdc8d8SChris Lattner {
16330fdc8d8SChris Lattner }
16430fdc8d8SChris Lattner 
16530fdc8d8SChris Lattner StackID&
16630fdc8d8SChris Lattner StackFrame::GetStackID()
16730fdc8d8SChris Lattner {
1686dadd508SGreg Clayton     // Make sure we have resolved the StackID object's symbol context scope if
1696dadd508SGreg Clayton     // we already haven't looked it up.
17059e8fc1cSGreg Clayton 
17159e8fc1cSGreg Clayton     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
17259e8fc1cSGreg Clayton     {
1732cad65a5SGreg Clayton         if (m_id.GetSymbolContextScope ())
17459e8fc1cSGreg Clayton         {
17595897c6aSGreg Clayton             // We already have a symbol context scope, we just don't have our
17695897c6aSGreg Clayton             // flag bit set.
17759e8fc1cSGreg Clayton             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
17859e8fc1cSGreg Clayton         }
17959e8fc1cSGreg Clayton         else
18059e8fc1cSGreg Clayton         {
18195897c6aSGreg Clayton             // Calculate the frame block and use this for the stack ID symbol
18295897c6aSGreg Clayton             // context scope if we have one.
18395897c6aSGreg Clayton             SymbolContextScope *scope = GetFrameBlock ();
18495897c6aSGreg Clayton             if (scope == NULL)
18559e8fc1cSGreg Clayton             {
18695897c6aSGreg Clayton                 // We don't have a block, so use the symbol
18795897c6aSGreg Clayton                 if (m_flags.IsClear (eSymbolContextSymbol))
18859e8fc1cSGreg Clayton                     GetSymbolContext (eSymbolContextSymbol);
18995897c6aSGreg Clayton 
19095897c6aSGreg Clayton                 // It is ok if m_sc.symbol is NULL here
19195897c6aSGreg Clayton                 scope = m_sc.symbol;
19259e8fc1cSGreg Clayton             }
19395897c6aSGreg Clayton             // Set the symbol context scope (the accessor will set the
19495897c6aSGreg Clayton             // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
19595897c6aSGreg Clayton             SetSymbolContextScope (scope);
19659e8fc1cSGreg Clayton         }
19759e8fc1cSGreg Clayton     }
19830fdc8d8SChris Lattner     return m_id;
19930fdc8d8SChris Lattner }
20030fdc8d8SChris Lattner 
20159e8fc1cSGreg Clayton void
20259e8fc1cSGreg Clayton StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
20359e8fc1cSGreg Clayton {
20459e8fc1cSGreg Clayton     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
20559e8fc1cSGreg Clayton     m_id.SetSymbolContextScope (symbol_scope);
20659e8fc1cSGreg Clayton }
20759e8fc1cSGreg Clayton 
20830fdc8d8SChris Lattner Address&
2099da7bd07SGreg Clayton StackFrame::GetFrameCodeAddress()
21030fdc8d8SChris Lattner {
21159e8fc1cSGreg Clayton     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
21230fdc8d8SChris Lattner     {
21359e8fc1cSGreg Clayton         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
21430fdc8d8SChris Lattner 
21530fdc8d8SChris Lattner         // Resolve the PC into a temporary address because if ResolveLoadAddress
21630fdc8d8SChris Lattner         // fails to resolve the address, it will clear the address object...
21730fdc8d8SChris Lattner         Address resolved_pc;
218f5e56de0SGreg Clayton         if (m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
21930fdc8d8SChris Lattner         {
22012fc3e0fSGreg Clayton             m_frame_code_addr = resolved_pc;
22112fc3e0fSGreg Clayton             const Section *section = m_frame_code_addr.GetSection();
22230fdc8d8SChris Lattner             if (section)
22330fdc8d8SChris Lattner             {
22430fdc8d8SChris Lattner                 Module *module = section->GetModule();
22530fdc8d8SChris Lattner                 if (module)
22630fdc8d8SChris Lattner                 {
22730fdc8d8SChris Lattner                     m_sc.module_sp = module->GetSP();
22830fdc8d8SChris Lattner                     if (m_sc.module_sp)
22930fdc8d8SChris Lattner                         m_flags.Set(eSymbolContextModule);
23030fdc8d8SChris Lattner                 }
23130fdc8d8SChris Lattner             }
23230fdc8d8SChris Lattner         }
23330fdc8d8SChris Lattner     }
23412fc3e0fSGreg Clayton     return m_frame_code_addr;
23530fdc8d8SChris Lattner }
23630fdc8d8SChris Lattner 
23730fdc8d8SChris Lattner void
23830fdc8d8SChris Lattner StackFrame::ChangePC (addr_t pc)
23930fdc8d8SChris Lattner {
24012fc3e0fSGreg Clayton     m_frame_code_addr.SetOffset(pc);
24112fc3e0fSGreg Clayton     m_frame_code_addr.SetSection(NULL);
24230fdc8d8SChris Lattner     m_sc.Clear();
24373b472d4SGreg Clayton     m_flags.Reset(0);
24430fdc8d8SChris Lattner     m_thread.ClearStackFrames ();
24530fdc8d8SChris Lattner }
24630fdc8d8SChris Lattner 
24730fdc8d8SChris Lattner const char *
24830fdc8d8SChris Lattner StackFrame::Disassemble ()
24930fdc8d8SChris Lattner {
25030fdc8d8SChris Lattner     if (m_disassembly.GetSize() == 0)
25130fdc8d8SChris Lattner     {
25230fdc8d8SChris Lattner         ExecutionContext exe_ctx;
2530603aa9dSGreg Clayton         CalculateExecutionContext(exe_ctx);
2546611103cSGreg Clayton         Target &target = m_thread.GetProcess().GetTarget();
2556611103cSGreg Clayton         Disassembler::Disassemble (target.GetDebugger(),
2566611103cSGreg Clayton                                    target.GetArchitecture(),
25730fdc8d8SChris Lattner                                    exe_ctx,
25830fdc8d8SChris Lattner                                    0,
259dda4f7b5SGreg Clayton                                    false,
26030fdc8d8SChris Lattner                                    m_disassembly);
26130fdc8d8SChris Lattner         if (m_disassembly.GetSize() == 0)
26230fdc8d8SChris Lattner             return NULL;
26330fdc8d8SChris Lattner     }
26430fdc8d8SChris Lattner     return m_disassembly.GetData();
26530fdc8d8SChris Lattner }
26630fdc8d8SChris Lattner 
26795897c6aSGreg Clayton Block *
26895897c6aSGreg Clayton StackFrame::GetFrameBlock ()
26995897c6aSGreg Clayton {
27095897c6aSGreg Clayton     if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
27195897c6aSGreg Clayton         GetSymbolContext (eSymbolContextBlock);
27295897c6aSGreg Clayton 
27395897c6aSGreg Clayton     if (m_sc.block)
27495897c6aSGreg Clayton     {
27595897c6aSGreg Clayton         Block *inline_block = m_sc.block->GetContainingInlinedBlock();
27695897c6aSGreg Clayton         if (inline_block)
27795897c6aSGreg Clayton         {
27895897c6aSGreg Clayton             // Use the block with the inlined function info
27995897c6aSGreg Clayton             // as the frame block we want this frame to have only the variables
28095897c6aSGreg Clayton             // for the inlined function and its non-inlined block child blocks.
28195897c6aSGreg Clayton             return inline_block;
28295897c6aSGreg Clayton         }
28395897c6aSGreg Clayton         else
28495897c6aSGreg Clayton         {
28595897c6aSGreg Clayton             // This block is not contained withing any inlined function blocks
28695897c6aSGreg Clayton             // with so we want to use the top most function block.
28795897c6aSGreg Clayton             return &m_sc.function->GetBlock (false);
28895897c6aSGreg Clayton         }
28995897c6aSGreg Clayton     }
29095897c6aSGreg Clayton     return NULL;
29195897c6aSGreg Clayton }
29295897c6aSGreg Clayton 
29330fdc8d8SChris Lattner //----------------------------------------------------------------------
29430fdc8d8SChris Lattner // Get the symbol context if we already haven't done so by resolving the
29530fdc8d8SChris Lattner // PC address as much as possible. This way when we pass around a
29630fdc8d8SChris Lattner // StackFrame object, everyone will have as much information as
29730fdc8d8SChris Lattner // possible and no one will ever have to look things up manually.
29830fdc8d8SChris Lattner //----------------------------------------------------------------------
29930fdc8d8SChris Lattner const SymbolContext&
30030fdc8d8SChris Lattner StackFrame::GetSymbolContext (uint32_t resolve_scope)
30130fdc8d8SChris Lattner {
30230fdc8d8SChris Lattner     // Copy our internal symbol context into "sc".
30373b472d4SGreg Clayton     if ((m_flags.Get() & resolve_scope) != resolve_scope)
30430fdc8d8SChris Lattner     {
30530fdc8d8SChris Lattner         // Resolve our PC to section offset if we haven't alreday done so
30630fdc8d8SChris Lattner         // and if we don't have a module. The resolved address section will
30730fdc8d8SChris Lattner         // contain the module to which it belongs
30859e8fc1cSGreg Clayton         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
3099da7bd07SGreg Clayton             GetFrameCodeAddress();
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner         // If this is not frame zero, then we need to subtract 1 from the PC
31230fdc8d8SChris Lattner         // value when doing address lookups since the PC will be on the
31330fdc8d8SChris Lattner         // instruction following the function call instruction...
31430fdc8d8SChris Lattner 
3159da7bd07SGreg Clayton         Address lookup_addr(GetFrameCodeAddress());
3161b72fcb7SGreg Clayton         if (m_frame_index > 0 && lookup_addr.IsValid())
31730fdc8d8SChris Lattner         {
31830fdc8d8SChris Lattner             addr_t offset = lookup_addr.GetOffset();
31930fdc8d8SChris Lattner             if (offset > 0)
32030fdc8d8SChris Lattner                 lookup_addr.SetOffset(offset - 1);
32130fdc8d8SChris Lattner         }
32230fdc8d8SChris Lattner 
3239da7bd07SGreg Clayton 
3249da7bd07SGreg Clayton         uint32_t resolved = 0;
32530fdc8d8SChris Lattner         if (m_sc.module_sp)
32630fdc8d8SChris Lattner         {
32730fdc8d8SChris Lattner             // We have something in our stack frame symbol context, lets check
32830fdc8d8SChris Lattner             // if we haven't already tried to lookup one of those things. If we
32930fdc8d8SChris Lattner             // haven't then we will do the query.
3301b72fcb7SGreg Clayton 
3311b72fcb7SGreg Clayton             uint32_t actual_resolve_scope = 0;
3321b72fcb7SGreg Clayton 
3331b72fcb7SGreg Clayton             if (resolve_scope & eSymbolContextCompUnit)
3341b72fcb7SGreg Clayton             {
3351b72fcb7SGreg Clayton                 if (m_flags.IsClear (eSymbolContextCompUnit))
3361b72fcb7SGreg Clayton                 {
3371b72fcb7SGreg Clayton                     if (m_sc.comp_unit)
3389da7bd07SGreg Clayton                         resolved |= eSymbolContextCompUnit;
3391b72fcb7SGreg Clayton                     else
3401b72fcb7SGreg Clayton                         actual_resolve_scope |= eSymbolContextCompUnit;
3411b72fcb7SGreg Clayton                 }
3421b72fcb7SGreg Clayton             }
3431b72fcb7SGreg Clayton 
3441b72fcb7SGreg Clayton             if (resolve_scope & eSymbolContextFunction)
3451b72fcb7SGreg Clayton             {
3461b72fcb7SGreg Clayton                 if (m_flags.IsClear (eSymbolContextFunction))
3471b72fcb7SGreg Clayton                 {
3481b72fcb7SGreg Clayton                     if (m_sc.function)
3499da7bd07SGreg Clayton                         resolved |= eSymbolContextFunction;
3501b72fcb7SGreg Clayton                     else
3511b72fcb7SGreg Clayton                         actual_resolve_scope |= eSymbolContextFunction;
3521b72fcb7SGreg Clayton                 }
3531b72fcb7SGreg Clayton             }
3541b72fcb7SGreg Clayton 
3551b72fcb7SGreg Clayton             if (resolve_scope & eSymbolContextBlock)
3561b72fcb7SGreg Clayton             {
3571b72fcb7SGreg Clayton                 if (m_flags.IsClear (eSymbolContextBlock))
3581b72fcb7SGreg Clayton                 {
3591b72fcb7SGreg Clayton                     if (m_sc.block)
3609da7bd07SGreg Clayton                         resolved |= eSymbolContextBlock;
3611b72fcb7SGreg Clayton                     else
3621b72fcb7SGreg Clayton                         actual_resolve_scope |= eSymbolContextBlock;
3631b72fcb7SGreg Clayton                 }
3641b72fcb7SGreg Clayton             }
3651b72fcb7SGreg Clayton 
3661b72fcb7SGreg Clayton             if (resolve_scope & eSymbolContextSymbol)
3671b72fcb7SGreg Clayton             {
3681b72fcb7SGreg Clayton                 if (m_flags.IsClear (eSymbolContextSymbol))
3691b72fcb7SGreg Clayton                 {
3701b72fcb7SGreg Clayton                     if (m_sc.symbol)
3719da7bd07SGreg Clayton                         resolved |= eSymbolContextSymbol;
3721b72fcb7SGreg Clayton                     else
3731b72fcb7SGreg Clayton                         actual_resolve_scope |= eSymbolContextSymbol;
3741b72fcb7SGreg Clayton                 }
3751b72fcb7SGreg Clayton             }
3761b72fcb7SGreg Clayton 
3771b72fcb7SGreg Clayton             if (resolve_scope & eSymbolContextLineEntry)
3781b72fcb7SGreg Clayton             {
3791b72fcb7SGreg Clayton                 if (m_flags.IsClear (eSymbolContextLineEntry))
3801b72fcb7SGreg Clayton                 {
3811b72fcb7SGreg Clayton                     if (m_sc.line_entry.IsValid())
3829da7bd07SGreg Clayton                         resolved |= eSymbolContextLineEntry;
3831b72fcb7SGreg Clayton                     else
3841b72fcb7SGreg Clayton                         actual_resolve_scope |= eSymbolContextLineEntry;
3851b72fcb7SGreg Clayton                 }
3861b72fcb7SGreg Clayton             }
3871b72fcb7SGreg Clayton 
3881b72fcb7SGreg Clayton             if (actual_resolve_scope)
38930fdc8d8SChris Lattner             {
39030fdc8d8SChris Lattner                 // We might be resolving less information than what is already
39130fdc8d8SChris Lattner                 // in our current symbol context so resolve into a temporary
39230fdc8d8SChris Lattner                 // symbol context "sc" so we don't clear out data we have
39330fdc8d8SChris Lattner                 // already found in "m_sc"
39430fdc8d8SChris Lattner                 SymbolContext sc;
39530fdc8d8SChris Lattner                 // Set flags that indicate what we have tried to resolve
3969da7bd07SGreg Clayton                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
3971b72fcb7SGreg Clayton                 // Only replace what we didn't already have as we may have
3981b72fcb7SGreg Clayton                 // information for an inlined function scope that won't match
3991b72fcb7SGreg Clayton                 // what a standard lookup by address would match
4009da7bd07SGreg Clayton                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
4019da7bd07SGreg Clayton                     m_sc.comp_unit = sc.comp_unit;
4029da7bd07SGreg Clayton                 if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
4039da7bd07SGreg Clayton                     m_sc.function = sc.function;
4049da7bd07SGreg Clayton                 if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
4059da7bd07SGreg Clayton                     m_sc.block = sc.block;
4069da7bd07SGreg Clayton                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
4079da7bd07SGreg Clayton                     m_sc.symbol = sc.symbol;
4089da7bd07SGreg Clayton                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
4099da7bd07SGreg Clayton                     m_sc.line_entry = sc.line_entry;
4109da7bd07SGreg Clayton 
41130fdc8d8SChris Lattner             }
41230fdc8d8SChris Lattner         }
41330fdc8d8SChris Lattner         else
41430fdc8d8SChris Lattner         {
41530fdc8d8SChris Lattner             // If we don't have a module, then we can't have the compile unit,
41630fdc8d8SChris Lattner             // function, block, line entry or symbol, so we can safely call
41730fdc8d8SChris Lattner             // ResolveSymbolContextForAddress with our symbol context member m_sc.
4189da7bd07SGreg Clayton             resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
41930fdc8d8SChris Lattner         }
42030fdc8d8SChris Lattner 
42130fdc8d8SChris Lattner         // If the target was requested add that:
42230fdc8d8SChris Lattner         if (m_sc.target_sp.get() == NULL)
4239da7bd07SGreg Clayton         {
42430fdc8d8SChris Lattner             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
4259da7bd07SGreg Clayton             if (m_sc.target_sp)
4269da7bd07SGreg Clayton                 resolved |= eSymbolContextTarget;
4279da7bd07SGreg Clayton         }
42830fdc8d8SChris Lattner 
42930fdc8d8SChris Lattner         // Update our internal flags so we remember what we have tried to locate so
43030fdc8d8SChris Lattner         // we don't have to keep trying when more calls to this function are made.
4319da7bd07SGreg Clayton         // We might have dug up more information that was requested (for example
4329da7bd07SGreg Clayton         // if we were asked to only get the block, we will have gotten the
4339da7bd07SGreg Clayton         // compile unit, and function) so set any additional bits that we resolved
4349da7bd07SGreg Clayton         m_flags.Set (resolve_scope | resolved);
43530fdc8d8SChris Lattner     }
43630fdc8d8SChris Lattner 
43730fdc8d8SChris Lattner     // Return the symbol context with everything that was possible to resolve
43830fdc8d8SChris Lattner     // resolved.
43930fdc8d8SChris Lattner     return m_sc;
44030fdc8d8SChris Lattner }
44130fdc8d8SChris Lattner 
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner VariableList *
444288bdf9cSGreg Clayton StackFrame::GetVariableList (bool get_file_globals)
44530fdc8d8SChris Lattner {
44630fdc8d8SChris Lattner     if (m_flags.IsClear(RESOLVED_VARIABLES))
44730fdc8d8SChris Lattner     {
44830fdc8d8SChris Lattner         m_flags.Set(RESOLVED_VARIABLES);
44930fdc8d8SChris Lattner 
45095897c6aSGreg Clayton         Block *frame_block = GetFrameBlock();
451288bdf9cSGreg Clayton 
45295897c6aSGreg Clayton         if (frame_block)
45330fdc8d8SChris Lattner         {
45495897c6aSGreg Clayton             const bool get_child_variables = true;
45595897c6aSGreg Clayton             const bool can_create = true;
45695897c6aSGreg Clayton             m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create);
45730fdc8d8SChris Lattner         }
4587c0962dcSSean Callanan     }
459288bdf9cSGreg Clayton 
4607c0962dcSSean Callanan     if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
4617c0962dcSSean Callanan         get_file_globals)
46295897c6aSGreg Clayton     {
4637c0962dcSSean Callanan         m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
4647c0962dcSSean Callanan 
46595897c6aSGreg Clayton         if (m_flags.IsClear (eSymbolContextCompUnit))
46695897c6aSGreg Clayton             GetSymbolContext (eSymbolContextCompUnit);
46795897c6aSGreg Clayton 
46895897c6aSGreg Clayton         if (m_sc.comp_unit)
469288bdf9cSGreg Clayton         {
470288bdf9cSGreg Clayton             VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
471288bdf9cSGreg Clayton             if (m_variable_list_sp)
472288bdf9cSGreg Clayton                 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
473288bdf9cSGreg Clayton             else
474288bdf9cSGreg Clayton                 m_variable_list_sp = global_variable_list_sp;
475288bdf9cSGreg Clayton         }
47630fdc8d8SChris Lattner     }
4777c0962dcSSean Callanan 
47830fdc8d8SChris Lattner     return m_variable_list_sp.get();
47930fdc8d8SChris Lattner }
48030fdc8d8SChris Lattner 
481*8b2fe6dcSGreg Clayton ValueObjectSP
482*8b2fe6dcSGreg Clayton StackFrame::GetValueForVariableExpressionPath (const char *var_expr)
483*8b2fe6dcSGreg Clayton {
484*8b2fe6dcSGreg Clayton     bool deref = false;
485*8b2fe6dcSGreg Clayton     bool address_of = false;
486*8b2fe6dcSGreg Clayton     ValueObjectSP valobj_sp;
487*8b2fe6dcSGreg Clayton     const bool get_file_globals = true;
488*8b2fe6dcSGreg Clayton     VariableList *variable_list = GetVariableList (get_file_globals);
489*8b2fe6dcSGreg Clayton 
490*8b2fe6dcSGreg Clayton     if (variable_list)
491*8b2fe6dcSGreg Clayton     {
492*8b2fe6dcSGreg Clayton         // If first character is a '*', then show pointer contents
493*8b2fe6dcSGreg Clayton         if (var_expr[0] == '*')
494*8b2fe6dcSGreg Clayton         {
495*8b2fe6dcSGreg Clayton             deref = true;
496*8b2fe6dcSGreg Clayton             var_expr++; // Skip the '*'
497*8b2fe6dcSGreg Clayton         }
498*8b2fe6dcSGreg Clayton         else if (var_expr[0] == '&')
499*8b2fe6dcSGreg Clayton         {
500*8b2fe6dcSGreg Clayton             address_of = true;
501*8b2fe6dcSGreg Clayton             var_expr++; // Skip the '&'
502*8b2fe6dcSGreg Clayton         }
503*8b2fe6dcSGreg Clayton 
504*8b2fe6dcSGreg Clayton         std::string var_path (var_expr);
505*8b2fe6dcSGreg Clayton         size_t separator_idx = var_path.find_first_of(".-[");
506*8b2fe6dcSGreg Clayton 
507*8b2fe6dcSGreg Clayton         ConstString name_const_string;
508*8b2fe6dcSGreg Clayton         if (separator_idx == std::string::npos)
509*8b2fe6dcSGreg Clayton             name_const_string.SetCString (var_path.c_str());
510*8b2fe6dcSGreg Clayton         else
511*8b2fe6dcSGreg Clayton             name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
512*8b2fe6dcSGreg Clayton 
513*8b2fe6dcSGreg Clayton         VariableSP var_sp (variable_list->FindVariable(name_const_string));
514*8b2fe6dcSGreg Clayton         if (var_sp)
515*8b2fe6dcSGreg Clayton         {
516*8b2fe6dcSGreg Clayton             valobj_sp = GetValueObjectForFrameVariable (var_sp);
517*8b2fe6dcSGreg Clayton 
518*8b2fe6dcSGreg Clayton             var_path.erase (0, name_const_string.GetLength ());
519*8b2fe6dcSGreg Clayton             // We are dumping at least one child
520*8b2fe6dcSGreg Clayton             while (separator_idx != std::string::npos)
521*8b2fe6dcSGreg Clayton             {
522*8b2fe6dcSGreg Clayton                 // Calculate the next separator index ahead of time
523*8b2fe6dcSGreg Clayton                 ValueObjectSP child_valobj_sp;
524*8b2fe6dcSGreg Clayton                 const char separator_type = var_path[0];
525*8b2fe6dcSGreg Clayton                 switch (separator_type)
526*8b2fe6dcSGreg Clayton                 {
527*8b2fe6dcSGreg Clayton 
528*8b2fe6dcSGreg Clayton                 case '-':
529*8b2fe6dcSGreg Clayton                     if (var_path.size() >= 2 && var_path[1] != '>')
530*8b2fe6dcSGreg Clayton                         return ValueObjectSP();
531*8b2fe6dcSGreg Clayton 
532*8b2fe6dcSGreg Clayton                     var_path.erase (0, 1); // Remove the '-'
533*8b2fe6dcSGreg Clayton                     // Fall through
534*8b2fe6dcSGreg Clayton                 case '.':
535*8b2fe6dcSGreg Clayton                     {
536*8b2fe6dcSGreg Clayton                         // We either have a pointer type and need to verify
537*8b2fe6dcSGreg Clayton                         // valobj_sp is a pointer, or we have a member of a
538*8b2fe6dcSGreg Clayton                         // class/union/struct being accessed with the . syntax
539*8b2fe6dcSGreg Clayton                         // and need to verify we don't have a pointer.
540*8b2fe6dcSGreg Clayton                         const bool is_ptr = var_path[0] == '>';
541*8b2fe6dcSGreg Clayton 
542*8b2fe6dcSGreg Clayton                         if (valobj_sp->IsPointerType () != is_ptr)
543*8b2fe6dcSGreg Clayton                         {
544*8b2fe6dcSGreg Clayton                             // Incorrect use of "." with a pointer, or "->" with
545*8b2fe6dcSGreg Clayton                             // a class/union/struct instance or reference.
546*8b2fe6dcSGreg Clayton                             return ValueObjectSP();
547*8b2fe6dcSGreg Clayton                         }
548*8b2fe6dcSGreg Clayton 
549*8b2fe6dcSGreg Clayton                         var_path.erase (0, 1); // Remove the '.' or '>'
550*8b2fe6dcSGreg Clayton                         separator_idx = var_path.find_first_of(".-[");
551*8b2fe6dcSGreg Clayton                         ConstString child_name;
552*8b2fe6dcSGreg Clayton                         if (separator_idx == std::string::npos)
553*8b2fe6dcSGreg Clayton                             child_name.SetCString (var_path.c_str());
554*8b2fe6dcSGreg Clayton                         else
555*8b2fe6dcSGreg Clayton                             child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
556*8b2fe6dcSGreg Clayton 
557*8b2fe6dcSGreg Clayton                         child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
558*8b2fe6dcSGreg Clayton                         if (!child_valobj_sp)
559*8b2fe6dcSGreg Clayton                         {
560*8b2fe6dcSGreg Clayton                             // No child member with name "child_name"
561*8b2fe6dcSGreg Clayton                             return ValueObjectSP();
562*8b2fe6dcSGreg Clayton                         }
563*8b2fe6dcSGreg Clayton                         // Remove the child name from the path
564*8b2fe6dcSGreg Clayton                         var_path.erase(0, child_name.GetLength());
565*8b2fe6dcSGreg Clayton                     }
566*8b2fe6dcSGreg Clayton                     break;
567*8b2fe6dcSGreg Clayton 
568*8b2fe6dcSGreg Clayton                 case '[':
569*8b2fe6dcSGreg Clayton                     // Array member access, or treating pointer as an array
570*8b2fe6dcSGreg Clayton                     if (var_path.size() > 2) // Need at least two brackets and a number
571*8b2fe6dcSGreg Clayton                     {
572*8b2fe6dcSGreg Clayton                         char *end = NULL;
573*8b2fe6dcSGreg Clayton                         int32_t child_index = ::strtol (&var_path[1], &end, 0);
574*8b2fe6dcSGreg Clayton                         if (end && *end == ']')
575*8b2fe6dcSGreg Clayton                         {
576*8b2fe6dcSGreg Clayton 
577*8b2fe6dcSGreg Clayton                             if (valobj_sp->IsPointerType ())
578*8b2fe6dcSGreg Clayton                             {
579*8b2fe6dcSGreg Clayton                                 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
580*8b2fe6dcSGreg Clayton                             }
581*8b2fe6dcSGreg Clayton                             else
582*8b2fe6dcSGreg Clayton                             {
583*8b2fe6dcSGreg Clayton                                 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
584*8b2fe6dcSGreg Clayton                             }
585*8b2fe6dcSGreg Clayton 
586*8b2fe6dcSGreg Clayton                             if (!child_valobj_sp)
587*8b2fe6dcSGreg Clayton                             {
588*8b2fe6dcSGreg Clayton                                 // Invalid array index...
589*8b2fe6dcSGreg Clayton                                 return ValueObjectSP();
590*8b2fe6dcSGreg Clayton                             }
591*8b2fe6dcSGreg Clayton 
592*8b2fe6dcSGreg Clayton                             // Erase the array member specification '[%i]' where
593*8b2fe6dcSGreg Clayton                             // %i is the array index
594*8b2fe6dcSGreg Clayton                             var_path.erase(0, (end - var_path.c_str()) + 1);
595*8b2fe6dcSGreg Clayton                             separator_idx = var_path.find_first_of(".-[");
596*8b2fe6dcSGreg Clayton 
597*8b2fe6dcSGreg Clayton                             // Break out early from the switch since we were
598*8b2fe6dcSGreg Clayton                             // able to find the child member
599*8b2fe6dcSGreg Clayton                             break;
600*8b2fe6dcSGreg Clayton                         }
601*8b2fe6dcSGreg Clayton                     }
602*8b2fe6dcSGreg Clayton                     return ValueObjectSP();
603*8b2fe6dcSGreg Clayton 
604*8b2fe6dcSGreg Clayton                 default:
605*8b2fe6dcSGreg Clayton                     // Failure...
606*8b2fe6dcSGreg Clayton                     return ValueObjectSP();
607*8b2fe6dcSGreg Clayton                 }
608*8b2fe6dcSGreg Clayton 
609*8b2fe6dcSGreg Clayton                 if (child_valobj_sp)
610*8b2fe6dcSGreg Clayton                     valobj_sp = child_valobj_sp;
611*8b2fe6dcSGreg Clayton 
612*8b2fe6dcSGreg Clayton                 if (var_path.empty())
613*8b2fe6dcSGreg Clayton                     break;
614*8b2fe6dcSGreg Clayton 
615*8b2fe6dcSGreg Clayton             }
616*8b2fe6dcSGreg Clayton             if (valobj_sp)
617*8b2fe6dcSGreg Clayton             {
618*8b2fe6dcSGreg Clayton                 if (deref)
619*8b2fe6dcSGreg Clayton                 {
620*8b2fe6dcSGreg Clayton                     ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, NULL));
621*8b2fe6dcSGreg Clayton                     valobj_sp = deref_valobj_sp;
622*8b2fe6dcSGreg Clayton                 }
623*8b2fe6dcSGreg Clayton                 else if (address_of)
624*8b2fe6dcSGreg Clayton                 {
625*8b2fe6dcSGreg Clayton                     ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf());
626*8b2fe6dcSGreg Clayton                     valobj_sp = address_of_valobj_sp;
627*8b2fe6dcSGreg Clayton                 }
628*8b2fe6dcSGreg Clayton             }
629*8b2fe6dcSGreg Clayton             return valobj_sp;
630*8b2fe6dcSGreg Clayton         }
631*8b2fe6dcSGreg Clayton     }
632*8b2fe6dcSGreg Clayton     return ValueObjectSP();
633*8b2fe6dcSGreg Clayton }
63430fdc8d8SChris Lattner 
63530fdc8d8SChris Lattner bool
63630fdc8d8SChris Lattner StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
63730fdc8d8SChris Lattner {
63830fdc8d8SChris Lattner     if (m_flags.IsClear(GOT_FRAME_BASE))
63930fdc8d8SChris Lattner     {
64030fdc8d8SChris Lattner         if (m_sc.function)
64130fdc8d8SChris Lattner         {
64230fdc8d8SChris Lattner             m_frame_base.Clear();
64330fdc8d8SChris Lattner             m_frame_base_error.Clear();
64430fdc8d8SChris Lattner 
64530fdc8d8SChris Lattner             m_flags.Set(GOT_FRAME_BASE);
64630fdc8d8SChris Lattner             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
64730fdc8d8SChris Lattner             Value expr_value;
648016a95ebSGreg Clayton             addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
649016a95ebSGreg Clayton             if (m_sc.function->GetFrameBaseExpression().IsLocationList())
650f5e56de0SGreg Clayton                 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget());
651016a95ebSGreg Clayton 
6522d107dd0SJason Molenda             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
65330fdc8d8SChris Lattner             {
65430fdc8d8SChris Lattner                 // We should really have an error if evaluate returns, but in case
65530fdc8d8SChris Lattner                 // we don't, lets set the error to something at least.
65630fdc8d8SChris Lattner                 if (m_frame_base_error.Success())
65730fdc8d8SChris Lattner                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
65830fdc8d8SChris Lattner             }
65930fdc8d8SChris Lattner             else
66030fdc8d8SChris Lattner             {
66130fdc8d8SChris Lattner                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
66230fdc8d8SChris Lattner             }
66330fdc8d8SChris Lattner         }
66430fdc8d8SChris Lattner         else
66530fdc8d8SChris Lattner         {
66630fdc8d8SChris Lattner             m_frame_base_error.SetErrorString ("No function in symbol context.");
66730fdc8d8SChris Lattner         }
66830fdc8d8SChris Lattner     }
66930fdc8d8SChris Lattner 
67030fdc8d8SChris Lattner     if (m_frame_base_error.Success())
67130fdc8d8SChris Lattner         frame_base = m_frame_base;
67230fdc8d8SChris Lattner 
67330fdc8d8SChris Lattner     if (error_ptr)
67430fdc8d8SChris Lattner         *error_ptr = m_frame_base_error;
67530fdc8d8SChris Lattner     return m_frame_base_error.Success();
67630fdc8d8SChris Lattner }
67730fdc8d8SChris Lattner 
67830fdc8d8SChris Lattner RegisterContext *
67930fdc8d8SChris Lattner StackFrame::GetRegisterContext ()
68030fdc8d8SChris Lattner {
68130fdc8d8SChris Lattner     if (m_reg_context_sp.get() == NULL)
68230fdc8d8SChris Lattner         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
68330fdc8d8SChris Lattner     return m_reg_context_sp.get();
68430fdc8d8SChris Lattner }
68530fdc8d8SChris Lattner 
68630fdc8d8SChris Lattner bool
68730fdc8d8SChris Lattner StackFrame::HasDebugInformation ()
68830fdc8d8SChris Lattner {
68930fdc8d8SChris Lattner     GetSymbolContext (eSymbolContextLineEntry);
69030fdc8d8SChris Lattner     return m_sc.line_entry.IsValid();
69130fdc8d8SChris Lattner }
69230fdc8d8SChris Lattner 
693288bdf9cSGreg Clayton 
694288bdf9cSGreg Clayton ValueObjectSP
695288bdf9cSGreg Clayton StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
69630fdc8d8SChris Lattner {
697288bdf9cSGreg Clayton     ValueObjectSP valobj_sp;
698288bdf9cSGreg Clayton     VariableList *var_list = GetVariableList (true);
699288bdf9cSGreg Clayton     if (var_list)
700288bdf9cSGreg Clayton     {
701288bdf9cSGreg Clayton         // Make sure the variable is a frame variable
702288bdf9cSGreg Clayton         const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
703288bdf9cSGreg Clayton         const uint32_t num_variables = var_list->GetSize();
704288bdf9cSGreg Clayton         if (var_idx < num_variables)
705288bdf9cSGreg Clayton         {
706288bdf9cSGreg Clayton             valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
707288bdf9cSGreg Clayton             if (valobj_sp.get() == NULL)
708288bdf9cSGreg Clayton             {
709288bdf9cSGreg Clayton                 if (m_variable_list_value_objects.GetSize() < num_variables)
710288bdf9cSGreg Clayton                     m_variable_list_value_objects.Resize(num_variables);
711288bdf9cSGreg Clayton                 valobj_sp.reset (new ValueObjectVariable (variable_sp));
712288bdf9cSGreg Clayton                 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
713288bdf9cSGreg Clayton             }
714288bdf9cSGreg Clayton         }
715288bdf9cSGreg Clayton     }
716288bdf9cSGreg Clayton     return valobj_sp;
717288bdf9cSGreg Clayton }
718288bdf9cSGreg Clayton 
719288bdf9cSGreg Clayton ValueObjectSP
720288bdf9cSGreg Clayton StackFrame::TrackGlobalVariable (const VariableSP &variable_sp)
721288bdf9cSGreg Clayton {
722288bdf9cSGreg Clayton     // Check to make sure we aren't already tracking this variable?
723288bdf9cSGreg Clayton     ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp));
724288bdf9cSGreg Clayton     if (!valobj_sp)
725288bdf9cSGreg Clayton     {
726288bdf9cSGreg Clayton         // We aren't already tracking this global
727288bdf9cSGreg Clayton         VariableList *var_list = GetVariableList (true);
728288bdf9cSGreg Clayton         // If this frame has no variables, create a new list
729288bdf9cSGreg Clayton         if (var_list == NULL)
730288bdf9cSGreg Clayton             m_variable_list_sp.reset (new VariableList());
731288bdf9cSGreg Clayton 
732288bdf9cSGreg Clayton         // Add the global/static variable to this frame
733288bdf9cSGreg Clayton         m_variable_list_sp->AddVariable (variable_sp);
734288bdf9cSGreg Clayton 
735288bdf9cSGreg Clayton         // Now make a value object for it so we can track its changes
736288bdf9cSGreg Clayton         valobj_sp = GetValueObjectForFrameVariable (variable_sp);
737288bdf9cSGreg Clayton     }
738288bdf9cSGreg Clayton     return valobj_sp;
73930fdc8d8SChris Lattner }
74030fdc8d8SChris Lattner 
7416b8379c4SJim Ingham bool
7426b8379c4SJim Ingham StackFrame::IsInlined ()
7436b8379c4SJim Ingham {
74459e8fc1cSGreg Clayton     if (m_sc.block == NULL)
74559e8fc1cSGreg Clayton         GetSymbolContext (eSymbolContextBlock);
74659e8fc1cSGreg Clayton     if (m_sc.block)
74759e8fc1cSGreg Clayton         return m_sc.block->GetContainingInlinedBlock() != NULL;
74859e8fc1cSGreg Clayton     return false;
7496b8379c4SJim Ingham }
7506b8379c4SJim Ingham 
75130fdc8d8SChris Lattner Target *
75230fdc8d8SChris Lattner StackFrame::CalculateTarget ()
75330fdc8d8SChris Lattner {
75430fdc8d8SChris Lattner     return m_thread.CalculateTarget();
75530fdc8d8SChris Lattner }
75630fdc8d8SChris Lattner 
75730fdc8d8SChris Lattner Process *
75830fdc8d8SChris Lattner StackFrame::CalculateProcess ()
75930fdc8d8SChris Lattner {
76030fdc8d8SChris Lattner     return m_thread.CalculateProcess();
76130fdc8d8SChris Lattner }
76230fdc8d8SChris Lattner 
76330fdc8d8SChris Lattner Thread *
76430fdc8d8SChris Lattner StackFrame::CalculateThread ()
76530fdc8d8SChris Lattner {
76630fdc8d8SChris Lattner     return &m_thread;
76730fdc8d8SChris Lattner }
76830fdc8d8SChris Lattner 
76930fdc8d8SChris Lattner StackFrame *
77030fdc8d8SChris Lattner StackFrame::CalculateStackFrame ()
77130fdc8d8SChris Lattner {
77230fdc8d8SChris Lattner     return this;
77330fdc8d8SChris Lattner }
77430fdc8d8SChris Lattner 
77530fdc8d8SChris Lattner 
77630fdc8d8SChris Lattner void
7770603aa9dSGreg Clayton StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
77830fdc8d8SChris Lattner {
7790603aa9dSGreg Clayton     m_thread.CalculateExecutionContext (exe_ctx);
78030fdc8d8SChris Lattner     exe_ctx.frame = this;
78130fdc8d8SChris Lattner }
78230fdc8d8SChris Lattner 
78330fdc8d8SChris Lattner void
7840603aa9dSGreg Clayton StackFrame::DumpUsingSettingsFormat (Stream *strm)
7850603aa9dSGreg Clayton {
7860603aa9dSGreg Clayton     if (strm == NULL)
7870603aa9dSGreg Clayton         return;
7880603aa9dSGreg Clayton 
7890603aa9dSGreg Clayton     GetSymbolContext(eSymbolContextEverything);
7900603aa9dSGreg Clayton     ExecutionContext exe_ctx;
7910603aa9dSGreg Clayton     CalculateExecutionContext(exe_ctx);
7920603aa9dSGreg Clayton     const char *end = NULL;
7930603aa9dSGreg Clayton     StreamString s;
7940603aa9dSGreg Clayton     const char *frame_format = m_thread.GetProcess().GetTarget().GetDebugger().GetFrameFormat();
7950603aa9dSGreg Clayton     if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end))
7960603aa9dSGreg Clayton     {
7970603aa9dSGreg Clayton         strm->Write(s.GetData(), s.GetSize());
7980603aa9dSGreg Clayton     }
7990603aa9dSGreg Clayton     else
8000603aa9dSGreg Clayton     {
8010603aa9dSGreg Clayton         Dump (strm, true, false);
8020603aa9dSGreg Clayton         strm->EOL();
8030603aa9dSGreg Clayton     }
8040603aa9dSGreg Clayton }
8050603aa9dSGreg Clayton 
8060603aa9dSGreg Clayton void
8076dadd508SGreg Clayton StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
80830fdc8d8SChris Lattner {
80930fdc8d8SChris Lattner     if (strm == NULL)
81030fdc8d8SChris Lattner         return;
81130fdc8d8SChris Lattner 
81230fdc8d8SChris Lattner     if (show_frame_index)
8131b72fcb7SGreg Clayton         strm->Printf("frame #%u: ", m_frame_index);
814f5e56de0SGreg Clayton     strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget()));
8159da7bd07SGreg Clayton     GetSymbolContext(eSymbolContextEverything);
8161b72fcb7SGreg Clayton     const bool show_module = true;
8171b72fcb7SGreg Clayton     const bool show_inline = true;
8186dadd508SGreg Clayton     m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
81930fdc8d8SChris Lattner }
82030fdc8d8SChris Lattner 
8215082c5fdSGreg Clayton void
82259e8fc1cSGreg Clayton StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
8235082c5fdSGreg Clayton {
82459e8fc1cSGreg Clayton     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
82559e8fc1cSGreg Clayton     m_variable_list_sp = prev_frame.m_variable_list_sp;
826288bdf9cSGreg Clayton     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
82768275d5eSGreg Clayton     if (!m_disassembly.GetString().empty())
82868275d5eSGreg Clayton         m_disassembly.GetString().swap (m_disassembly.GetString());
8295082c5fdSGreg Clayton }
83068275d5eSGreg Clayton 
83168275d5eSGreg Clayton 
83259e8fc1cSGreg Clayton void
83359e8fc1cSGreg Clayton StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
83459e8fc1cSGreg Clayton {
83559e8fc1cSGreg Clayton     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
8362cad65a5SGreg Clayton     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
83759e8fc1cSGreg Clayton     assert (&m_thread == &curr_frame.m_thread);
83859e8fc1cSGreg Clayton     m_frame_index = curr_frame.m_frame_index;
83959e8fc1cSGreg Clayton     m_unwind_frame_index = curr_frame.m_unwind_frame_index;
84059e8fc1cSGreg Clayton     m_reg_context_sp = curr_frame.m_reg_context_sp;
84159e8fc1cSGreg Clayton     m_frame_code_addr = curr_frame.m_frame_code_addr;
84259e8fc1cSGreg Clayton     assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
84359e8fc1cSGreg Clayton     assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
84459e8fc1cSGreg Clayton     assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
84559e8fc1cSGreg Clayton     assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
84659e8fc1cSGreg Clayton     m_sc = curr_frame.m_sc;
84759e8fc1cSGreg Clayton     m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
84859e8fc1cSGreg Clayton     m_flags.Set (m_sc.GetResolvedMask());
84959e8fc1cSGreg Clayton     m_frame_base.Clear();
85059e8fc1cSGreg Clayton     m_frame_base_error.Clear();
85159e8fc1cSGreg Clayton }
85259e8fc1cSGreg Clayton 
85359e8fc1cSGreg Clayton 
8542cad65a5SGreg Clayton bool
8552cad65a5SGreg Clayton StackFrame::HasCachedData () const
8562cad65a5SGreg Clayton {
8572cad65a5SGreg Clayton     if (m_variable_list_sp.get())
8582cad65a5SGreg Clayton         return true;
8592cad65a5SGreg Clayton     if (m_variable_list_value_objects.GetSize() > 0)
8602cad65a5SGreg Clayton         return true;
8612cad65a5SGreg Clayton     if (!m_disassembly.GetString().empty())
8622cad65a5SGreg Clayton         return true;
8632cad65a5SGreg Clayton     return false;
8642cad65a5SGreg Clayton }
865e4284b71SJim Ingham 
866e4284b71SJim Ingham lldb::StackFrameSP
867e4284b71SJim Ingham StackFrame::GetSP ()
868e4284b71SJim Ingham {
869e4284b71SJim Ingham     return m_thread.GetStackFrameSPForStackFramePtr (this);
870e4284b71SJim Ingham }