1 //===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Target/StackFrame.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Disassembler.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectVariable.h"
21 #include "lldb/Symbol/Function.h"
22 #include "lldb/Symbol/VariableList.h"
23 #include "lldb/Target/ExecutionContext.h"
24 #include "lldb/Target/Process.h"
25 #include "lldb/Target/RegisterContext.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 // The first bits in the flags are reserved for the SymbolContext::Scope bits
33 // so we know if we have tried to look up information in our internal symbol
34 // context (m_sc) already.
35 #define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
36 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
37 #define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
38 #define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
39 #define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
40 
41 StackFrame::StackFrame
42 (
43     lldb::user_id_t frame_idx,
44     lldb::user_id_t unwind_frame_index,
45     Thread &thread,
46     lldb::addr_t cfa,
47     lldb::addr_t pc,
48     const SymbolContext *sc_ptr
49 ) :
50     m_frame_index (frame_idx),
51     m_unwind_frame_index (unwind_frame_index),
52     m_thread (thread),
53     m_reg_context_sp (),
54     m_id (pc, cfa, NULL),
55     m_frame_code_addr (NULL, pc),
56     m_sc (),
57     m_flags (),
58     m_frame_base (),
59     m_frame_base_error (),
60     m_variable_list_sp (),
61     m_variable_list_value_objects ()
62 {
63     if (sc_ptr != NULL)
64     {
65         m_sc = *sc_ptr;
66         m_flags.Set(m_sc.GetResolvedMask ());
67     }
68 }
69 
70 StackFrame::StackFrame
71 (
72     lldb::user_id_t frame_idx,
73     lldb::user_id_t unwind_frame_index,
74     Thread &thread,
75     const RegisterContextSP &reg_context_sp,
76     lldb::addr_t cfa,
77     lldb::addr_t pc,
78     const SymbolContext *sc_ptr
79 ) :
80     m_frame_index (frame_idx),
81     m_unwind_frame_index (unwind_frame_index),
82     m_thread (thread),
83     m_reg_context_sp (reg_context_sp),
84     m_id (pc, cfa, NULL),
85     m_frame_code_addr (NULL, pc),
86     m_sc (),
87     m_flags (),
88     m_frame_base (),
89     m_frame_base_error (),
90     m_variable_list_sp (),
91     m_variable_list_value_objects ()
92 {
93     if (sc_ptr != NULL)
94     {
95         m_sc = *sc_ptr;
96         m_flags.Set(m_sc.GetResolvedMask ());
97     }
98 
99     if (reg_context_sp && !m_sc.target_sp)
100     {
101         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
102         m_flags.Set (eSymbolContextTarget);
103     }
104 }
105 
106 StackFrame::StackFrame
107 (
108     lldb::user_id_t frame_idx,
109     lldb::user_id_t unwind_frame_index,
110     Thread &thread,
111     const RegisterContextSP &reg_context_sp,
112     lldb::addr_t cfa,
113     const Address& pc_addr,
114     const SymbolContext *sc_ptr
115 ) :
116     m_frame_index (frame_idx),
117     m_unwind_frame_index (unwind_frame_index),
118     m_thread (thread),
119     m_reg_context_sp (reg_context_sp),
120     m_id (pc_addr.GetLoadAddress (&thread.GetProcess().GetTarget()), cfa, NULL),
121     m_frame_code_addr (pc_addr),
122     m_sc (),
123     m_flags (),
124     m_frame_base (),
125     m_frame_base_error (),
126     m_variable_list_sp (),
127     m_variable_list_value_objects ()
128 {
129     if (sc_ptr != NULL)
130     {
131         m_sc = *sc_ptr;
132         m_flags.Set(m_sc.GetResolvedMask ());
133     }
134 
135     if (m_sc.target_sp.get() == NULL && reg_context_sp)
136     {
137         m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP();
138         m_flags.Set (eSymbolContextTarget);
139     }
140 
141     Module *pc_module = pc_addr.GetModule();
142     if (m_sc.module_sp.get() == NULL || m_sc.module_sp.get() != pc_module)
143     {
144         if (pc_module)
145         {
146             m_sc.module_sp = pc_module->GetSP();
147             m_flags.Set (eSymbolContextModule);
148         }
149         else
150         {
151             m_sc.module_sp.reset();
152         }
153 
154     }
155 }
156 
157 
158 //----------------------------------------------------------------------
159 // Destructor
160 //----------------------------------------------------------------------
161 StackFrame::~StackFrame()
162 {
163 }
164 
165 StackID&
166 StackFrame::GetStackID()
167 {
168     // Make sure we have resolved the StackID object's symbol context scope if
169     // we already haven't looked it up.
170 
171     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
172     {
173         if (m_id.GetSymbolContextScope ())
174         {
175             // We already have a symbol context scope, we just don't have our
176             // flag bit set.
177             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
178         }
179         else
180         {
181             // Calculate the frame block and use this for the stack ID symbol
182             // context scope if we have one.
183             SymbolContextScope *scope = GetFrameBlock ();
184             if (scope == NULL)
185             {
186                 // We don't have a block, so use the symbol
187                 if (m_flags.IsClear (eSymbolContextSymbol))
188                     GetSymbolContext (eSymbolContextSymbol);
189 
190                 // It is ok if m_sc.symbol is NULL here
191                 scope = m_sc.symbol;
192             }
193             // Set the symbol context scope (the accessor will set the
194             // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
195             SetSymbolContextScope (scope);
196         }
197     }
198     return m_id;
199 }
200 
201 void
202 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
203 {
204     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
205     m_id.SetSymbolContextScope (symbol_scope);
206 }
207 
208 Address&
209 StackFrame::GetFrameCodeAddress()
210 {
211     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
212     {
213         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
214 
215         // Resolve the PC into a temporary address because if ResolveLoadAddress
216         // fails to resolve the address, it will clear the address object...
217         Address resolved_pc;
218         if (m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc))
219         {
220             m_frame_code_addr = resolved_pc;
221             const Section *section = m_frame_code_addr.GetSection();
222             if (section)
223             {
224                 Module *module = section->GetModule();
225                 if (module)
226                 {
227                     m_sc.module_sp = module->GetSP();
228                     if (m_sc.module_sp)
229                         m_flags.Set(eSymbolContextModule);
230                 }
231             }
232         }
233     }
234     return m_frame_code_addr;
235 }
236 
237 void
238 StackFrame::ChangePC (addr_t pc)
239 {
240     m_frame_code_addr.SetOffset(pc);
241     m_frame_code_addr.SetSection(NULL);
242     m_sc.Clear();
243     m_flags.Reset(0);
244     m_thread.ClearStackFrames ();
245 }
246 
247 const char *
248 StackFrame::Disassemble ()
249 {
250     if (m_disassembly.GetSize() == 0)
251     {
252         ExecutionContext exe_ctx;
253         CalculateExecutionContext(exe_ctx);
254         Target &target = m_thread.GetProcess().GetTarget();
255         Disassembler::Disassemble (target.GetDebugger(),
256                                    target.GetArchitecture(),
257                                    exe_ctx,
258                                    0,
259                                    false,
260                                    m_disassembly);
261         if (m_disassembly.GetSize() == 0)
262             return NULL;
263     }
264     return m_disassembly.GetData();
265 }
266 
267 Block *
268 StackFrame::GetFrameBlock ()
269 {
270     if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
271         GetSymbolContext (eSymbolContextBlock);
272 
273     if (m_sc.block)
274     {
275         Block *inline_block = m_sc.block->GetContainingInlinedBlock();
276         if (inline_block)
277         {
278             // Use the block with the inlined function info
279             // as the frame block we want this frame to have only the variables
280             // for the inlined function and its non-inlined block child blocks.
281             return inline_block;
282         }
283         else
284         {
285             // This block is not contained withing any inlined function blocks
286             // with so we want to use the top most function block.
287             return &m_sc.function->GetBlock (false);
288         }
289     }
290     return NULL;
291 }
292 
293 //----------------------------------------------------------------------
294 // Get the symbol context if we already haven't done so by resolving the
295 // PC address as much as possible. This way when we pass around a
296 // StackFrame object, everyone will have as much information as
297 // possible and no one will ever have to look things up manually.
298 //----------------------------------------------------------------------
299 const SymbolContext&
300 StackFrame::GetSymbolContext (uint32_t resolve_scope)
301 {
302     // Copy our internal symbol context into "sc".
303     if ((m_flags.Get() & resolve_scope) != resolve_scope)
304     {
305         // Resolve our PC to section offset if we haven't alreday done so
306         // and if we don't have a module. The resolved address section will
307         // contain the module to which it belongs
308         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
309             GetFrameCodeAddress();
310 
311         // If this is not frame zero, then we need to subtract 1 from the PC
312         // value when doing address lookups since the PC will be on the
313         // instruction following the function call instruction...
314 
315         Address lookup_addr(GetFrameCodeAddress());
316         if (m_frame_index > 0 && lookup_addr.IsValid())
317         {
318             addr_t offset = lookup_addr.GetOffset();
319             if (offset > 0)
320                 lookup_addr.SetOffset(offset - 1);
321         }
322 
323 
324         uint32_t resolved = 0;
325         if (m_sc.module_sp)
326         {
327             // We have something in our stack frame symbol context, lets check
328             // if we haven't already tried to lookup one of those things. If we
329             // haven't then we will do the query.
330 
331             uint32_t actual_resolve_scope = 0;
332 
333             if (resolve_scope & eSymbolContextCompUnit)
334             {
335                 if (m_flags.IsClear (eSymbolContextCompUnit))
336                 {
337                     if (m_sc.comp_unit)
338                         resolved |= eSymbolContextCompUnit;
339                     else
340                         actual_resolve_scope |= eSymbolContextCompUnit;
341                 }
342             }
343 
344             if (resolve_scope & eSymbolContextFunction)
345             {
346                 if (m_flags.IsClear (eSymbolContextFunction))
347                 {
348                     if (m_sc.function)
349                         resolved |= eSymbolContextFunction;
350                     else
351                         actual_resolve_scope |= eSymbolContextFunction;
352                 }
353             }
354 
355             if (resolve_scope & eSymbolContextBlock)
356             {
357                 if (m_flags.IsClear (eSymbolContextBlock))
358                 {
359                     if (m_sc.block)
360                         resolved |= eSymbolContextBlock;
361                     else
362                         actual_resolve_scope |= eSymbolContextBlock;
363                 }
364             }
365 
366             if (resolve_scope & eSymbolContextSymbol)
367             {
368                 if (m_flags.IsClear (eSymbolContextSymbol))
369                 {
370                     if (m_sc.symbol)
371                         resolved |= eSymbolContextSymbol;
372                     else
373                         actual_resolve_scope |= eSymbolContextSymbol;
374                 }
375             }
376 
377             if (resolve_scope & eSymbolContextLineEntry)
378             {
379                 if (m_flags.IsClear (eSymbolContextLineEntry))
380                 {
381                     if (m_sc.line_entry.IsValid())
382                         resolved |= eSymbolContextLineEntry;
383                     else
384                         actual_resolve_scope |= eSymbolContextLineEntry;
385                 }
386             }
387 
388             if (actual_resolve_scope)
389             {
390                 // We might be resolving less information than what is already
391                 // in our current symbol context so resolve into a temporary
392                 // symbol context "sc" so we don't clear out data we have
393                 // already found in "m_sc"
394                 SymbolContext sc;
395                 // Set flags that indicate what we have tried to resolve
396                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
397                 // Only replace what we didn't already have as we may have
398                 // information for an inlined function scope that won't match
399                 // what a standard lookup by address would match
400                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
401                     m_sc.comp_unit = sc.comp_unit;
402                 if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
403                     m_sc.function = sc.function;
404                 if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
405                     m_sc.block = sc.block;
406                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
407                     m_sc.symbol = sc.symbol;
408                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
409                     m_sc.line_entry = sc.line_entry;
410 
411             }
412         }
413         else
414         {
415             // If we don't have a module, then we can't have the compile unit,
416             // function, block, line entry or symbol, so we can safely call
417             // ResolveSymbolContextForAddress with our symbol context member m_sc.
418             resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
419         }
420 
421         // If the target was requested add that:
422         if (m_sc.target_sp.get() == NULL)
423         {
424             m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
425             if (m_sc.target_sp)
426                 resolved |= eSymbolContextTarget;
427         }
428 
429         // Update our internal flags so we remember what we have tried to locate so
430         // we don't have to keep trying when more calls to this function are made.
431         // We might have dug up more information that was requested (for example
432         // if we were asked to only get the block, we will have gotten the
433         // compile unit, and function) so set any additional bits that we resolved
434         m_flags.Set (resolve_scope | resolved);
435     }
436 
437     // Return the symbol context with everything that was possible to resolve
438     // resolved.
439     return m_sc;
440 }
441 
442 
443 VariableList *
444 StackFrame::GetVariableList (bool get_file_globals)
445 {
446     if (m_flags.IsClear(RESOLVED_VARIABLES))
447     {
448         m_flags.Set(RESOLVED_VARIABLES);
449 
450         Block *frame_block = GetFrameBlock();
451 
452         if (frame_block)
453         {
454             const bool get_child_variables = true;
455             const bool can_create = true;
456             m_variable_list_sp = frame_block->GetVariableList (get_child_variables, can_create);
457         }
458     }
459 
460     if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
461         get_file_globals)
462     {
463         m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
464 
465         if (m_flags.IsClear (eSymbolContextCompUnit))
466             GetSymbolContext (eSymbolContextCompUnit);
467 
468         if (m_sc.comp_unit)
469         {
470             VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
471             if (m_variable_list_sp)
472                 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
473             else
474                 m_variable_list_sp = global_variable_list_sp;
475         }
476     }
477 
478     return m_variable_list_sp.get();
479 }
480 
481 ValueObjectSP
482 StackFrame::GetValueForVariableExpressionPath (const char *var_expr)
483 {
484     bool deref = false;
485     bool address_of = false;
486     ValueObjectSP valobj_sp;
487     const bool get_file_globals = true;
488     VariableList *variable_list = GetVariableList (get_file_globals);
489 
490     if (variable_list)
491     {
492         // If first character is a '*', then show pointer contents
493         if (var_expr[0] == '*')
494         {
495             deref = true;
496             var_expr++; // Skip the '*'
497         }
498         else if (var_expr[0] == '&')
499         {
500             address_of = true;
501             var_expr++; // Skip the '&'
502         }
503 
504         std::string var_path (var_expr);
505         size_t separator_idx = var_path.find_first_of(".-[");
506 
507         ConstString name_const_string;
508         if (separator_idx == std::string::npos)
509             name_const_string.SetCString (var_path.c_str());
510         else
511             name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
512 
513         VariableSP var_sp (variable_list->FindVariable(name_const_string));
514         if (var_sp)
515         {
516             valobj_sp = GetValueObjectForFrameVariable (var_sp);
517 
518             var_path.erase (0, name_const_string.GetLength ());
519             // We are dumping at least one child
520             while (separator_idx != std::string::npos)
521             {
522                 // Calculate the next separator index ahead of time
523                 ValueObjectSP child_valobj_sp;
524                 const char separator_type = var_path[0];
525                 switch (separator_type)
526                 {
527 
528                 case '-':
529                     if (var_path.size() >= 2 && var_path[1] != '>')
530                         return ValueObjectSP();
531 
532                     var_path.erase (0, 1); // Remove the '-'
533                     // Fall through
534                 case '.':
535                     {
536                         // We either have a pointer type and need to verify
537                         // valobj_sp is a pointer, or we have a member of a
538                         // class/union/struct being accessed with the . syntax
539                         // and need to verify we don't have a pointer.
540                         const bool is_ptr = var_path[0] == '>';
541 
542                         if (valobj_sp->IsPointerType () != is_ptr)
543                         {
544                             // Incorrect use of "." with a pointer, or "->" with
545                             // a class/union/struct instance or reference.
546                             return ValueObjectSP();
547                         }
548 
549                         var_path.erase (0, 1); // Remove the '.' or '>'
550                         separator_idx = var_path.find_first_of(".-[");
551                         ConstString child_name;
552                         if (separator_idx == std::string::npos)
553                             child_name.SetCString (var_path.c_str());
554                         else
555                             child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
556 
557                         child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
558                         if (!child_valobj_sp)
559                         {
560                             // No child member with name "child_name"
561                             return ValueObjectSP();
562                         }
563                         // Remove the child name from the path
564                         var_path.erase(0, child_name.GetLength());
565                     }
566                     break;
567 
568                 case '[':
569                     // Array member access, or treating pointer as an array
570                     if (var_path.size() > 2) // Need at least two brackets and a number
571                     {
572                         char *end = NULL;
573                         int32_t child_index = ::strtol (&var_path[1], &end, 0);
574                         if (end && *end == ']')
575                         {
576 
577                             if (valobj_sp->IsPointerType ())
578                             {
579                                 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
580                             }
581                             else
582                             {
583                                 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
584                             }
585 
586                             if (!child_valobj_sp)
587                             {
588                                 // Invalid array index...
589                                 return ValueObjectSP();
590                             }
591 
592                             // Erase the array member specification '[%i]' where
593                             // %i is the array index
594                             var_path.erase(0, (end - var_path.c_str()) + 1);
595                             separator_idx = var_path.find_first_of(".-[");
596 
597                             // Break out early from the switch since we were
598                             // able to find the child member
599                             break;
600                         }
601                     }
602                     return ValueObjectSP();
603 
604                 default:
605                     // Failure...
606                     return ValueObjectSP();
607                 }
608 
609                 if (child_valobj_sp)
610                     valobj_sp = child_valobj_sp;
611 
612                 if (var_path.empty())
613                     break;
614 
615             }
616             if (valobj_sp)
617             {
618                 if (deref)
619                 {
620                     ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, NULL));
621                     valobj_sp = deref_valobj_sp;
622                 }
623                 else if (address_of)
624                 {
625                     ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf());
626                     valobj_sp = address_of_valobj_sp;
627                 }
628             }
629             return valobj_sp;
630         }
631     }
632     return ValueObjectSP();
633 }
634 
635 bool
636 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
637 {
638     if (m_flags.IsClear(GOT_FRAME_BASE))
639     {
640         if (m_sc.function)
641         {
642             m_frame_base.Clear();
643             m_frame_base_error.Clear();
644 
645             m_flags.Set(GOT_FRAME_BASE);
646             ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
647             Value expr_value;
648             addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
649             if (m_sc.function->GetFrameBaseExpression().IsLocationList())
650                 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget());
651 
652             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
653             {
654                 // We should really have an error if evaluate returns, but in case
655                 // we don't, lets set the error to something at least.
656                 if (m_frame_base_error.Success())
657                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
658             }
659             else
660             {
661                 m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
662             }
663         }
664         else
665         {
666             m_frame_base_error.SetErrorString ("No function in symbol context.");
667         }
668     }
669 
670     if (m_frame_base_error.Success())
671         frame_base = m_frame_base;
672 
673     if (error_ptr)
674         *error_ptr = m_frame_base_error;
675     return m_frame_base_error.Success();
676 }
677 
678 RegisterContext *
679 StackFrame::GetRegisterContext ()
680 {
681     if (m_reg_context_sp.get() == NULL)
682         m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
683     return m_reg_context_sp.get();
684 }
685 
686 bool
687 StackFrame::HasDebugInformation ()
688 {
689     GetSymbolContext (eSymbolContextLineEntry);
690     return m_sc.line_entry.IsValid();
691 }
692 
693 
694 ValueObjectSP
695 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
696 {
697     ValueObjectSP valobj_sp;
698     VariableList *var_list = GetVariableList (true);
699     if (var_list)
700     {
701         // Make sure the variable is a frame variable
702         const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
703         const uint32_t num_variables = var_list->GetSize();
704         if (var_idx < num_variables)
705         {
706             valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
707             if (valobj_sp.get() == NULL)
708             {
709                 if (m_variable_list_value_objects.GetSize() < num_variables)
710                     m_variable_list_value_objects.Resize(num_variables);
711                 valobj_sp.reset (new ValueObjectVariable (variable_sp));
712                 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
713             }
714         }
715     }
716     return valobj_sp;
717 }
718 
719 ValueObjectSP
720 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp)
721 {
722     // Check to make sure we aren't already tracking this variable?
723     ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp));
724     if (!valobj_sp)
725     {
726         // We aren't already tracking this global
727         VariableList *var_list = GetVariableList (true);
728         // If this frame has no variables, create a new list
729         if (var_list == NULL)
730             m_variable_list_sp.reset (new VariableList());
731 
732         // Add the global/static variable to this frame
733         m_variable_list_sp->AddVariable (variable_sp);
734 
735         // Now make a value object for it so we can track its changes
736         valobj_sp = GetValueObjectForFrameVariable (variable_sp);
737     }
738     return valobj_sp;
739 }
740 
741 bool
742 StackFrame::IsInlined ()
743 {
744     if (m_sc.block == NULL)
745         GetSymbolContext (eSymbolContextBlock);
746     if (m_sc.block)
747         return m_sc.block->GetContainingInlinedBlock() != NULL;
748     return false;
749 }
750 
751 Target *
752 StackFrame::CalculateTarget ()
753 {
754     return m_thread.CalculateTarget();
755 }
756 
757 Process *
758 StackFrame::CalculateProcess ()
759 {
760     return m_thread.CalculateProcess();
761 }
762 
763 Thread *
764 StackFrame::CalculateThread ()
765 {
766     return &m_thread;
767 }
768 
769 StackFrame *
770 StackFrame::CalculateStackFrame ()
771 {
772     return this;
773 }
774 
775 
776 void
777 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
778 {
779     m_thread.CalculateExecutionContext (exe_ctx);
780     exe_ctx.frame = this;
781 }
782 
783 void
784 StackFrame::DumpUsingSettingsFormat (Stream *strm)
785 {
786     if (strm == NULL)
787         return;
788 
789     GetSymbolContext(eSymbolContextEverything);
790     ExecutionContext exe_ctx;
791     CalculateExecutionContext(exe_ctx);
792     const char *end = NULL;
793     StreamString s;
794     const char *frame_format = m_thread.GetProcess().GetTarget().GetDebugger().GetFrameFormat();
795     if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s, &end))
796     {
797         strm->Write(s.GetData(), s.GetSize());
798     }
799     else
800     {
801         Dump (strm, true, false);
802         strm->EOL();
803     }
804 }
805 
806 void
807 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
808 {
809     if (strm == NULL)
810         return;
811 
812     if (show_frame_index)
813         strm->Printf("frame #%u: ", m_frame_index);
814     strm->Printf("0x%0*llx ", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess().GetTarget()));
815     GetSymbolContext(eSymbolContextEverything);
816     const bool show_module = true;
817     const bool show_inline = true;
818     m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_fullpaths, show_module, show_inline);
819 }
820 
821 void
822 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
823 {
824     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
825     m_variable_list_sp = prev_frame.m_variable_list_sp;
826     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
827     if (!m_disassembly.GetString().empty())
828         m_disassembly.GetString().swap (m_disassembly.GetString());
829 }
830 
831 
832 void
833 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
834 {
835     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
836     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
837     assert (&m_thread == &curr_frame.m_thread);
838     m_frame_index = curr_frame.m_frame_index;
839     m_unwind_frame_index = curr_frame.m_unwind_frame_index;
840     m_reg_context_sp = curr_frame.m_reg_context_sp;
841     m_frame_code_addr = curr_frame.m_frame_code_addr;
842     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());
843     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());
844     assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
845     assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
846     m_sc = curr_frame.m_sc;
847     m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
848     m_flags.Set (m_sc.GetResolvedMask());
849     m_frame_base.Clear();
850     m_frame_base_error.Clear();
851 }
852 
853 
854 bool
855 StackFrame::HasCachedData () const
856 {
857     if (m_variable_list_sp.get())
858         return true;
859     if (m_variable_list_value_objects.GetSize() > 0)
860         return true;
861     if (!m_disassembly.GetString().empty())
862         return true;
863     return false;
864 }
865 
866 lldb::StackFrameSP
867 StackFrame::GetSP ()
868 {
869     return m_thread.GetStackFrameSPForStackFramePtr (this);
870 }