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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/StackFrame.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Disassembler.h"
17 #include "lldb/Core/FormatEntity.h"
18 #include "lldb/Core/Mangled.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObjectVariable.h"
22 #include "lldb/Core/ValueObjectConstResult.h"
23 #include "lldb/Core/ValueObjectMemory.h"
24 #include "lldb/Symbol/CompileUnit.h"
25 #include "lldb/Symbol/Function.h"
26 #include "lldb/Symbol/Symbol.h"
27 #include "lldb/Symbol/SymbolContextScope.h"
28 #include "lldb/Symbol/Type.h"
29 #include "lldb/Symbol/VariableList.h"
30 #include "lldb/Target/ABI.h"
31 #include "lldb/Target/ExecutionContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 // The first bits in the flags are reserved for the SymbolContext::Scope bits
41 // so we know if we have tried to look up information in our internal symbol
42 // context (m_sc) already.
43 #define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
44 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
45 #define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
46 #define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
47 #define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
48 
49 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa,
50                        bool cfa_is_valid, addr_t pc, uint32_t stop_id, bool stop_id_is_valid, bool is_history_frame,
51                        const SymbolContext *sc_ptr)
52     : m_thread_wp(thread_sp),
53       m_frame_index(frame_idx),
54       m_concrete_frame_index(unwind_frame_index),
55       m_reg_context_sp(),
56       m_id(pc, cfa, nullptr),
57       m_frame_code_addr(pc),
58       m_sc(),
59       m_flags(),
60       m_frame_base(),
61       m_frame_base_error(),
62       m_cfa_is_valid(cfa_is_valid),
63       m_stop_id(stop_id),
64       m_stop_id_is_valid(stop_id_is_valid),
65       m_is_history_frame(is_history_frame),
66       m_variable_list_sp(),
67       m_variable_list_value_objects(),
68       m_disassembly(),
69       m_mutex()
70 {
71     // If we don't have a CFA value, use the frame index for our StackID so that recursive
72     // functions properly aren't confused with one another on a history stack.
73     if (m_is_history_frame && !m_cfa_is_valid)
74     {
75         m_id.SetCFA(m_frame_index);
76     }
77 
78     if (sc_ptr != nullptr)
79     {
80         m_sc = *sc_ptr;
81         m_flags.Set(m_sc.GetResolvedMask());
82     }
83 }
84 
85 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
86                        const RegisterContextSP &reg_context_sp, addr_t cfa, addr_t pc, const SymbolContext *sc_ptr)
87     : m_thread_wp(thread_sp),
88       m_frame_index(frame_idx),
89       m_concrete_frame_index(unwind_frame_index),
90       m_reg_context_sp(reg_context_sp),
91       m_id(pc, cfa, nullptr),
92       m_frame_code_addr(pc),
93       m_sc(),
94       m_flags(),
95       m_frame_base(),
96       m_frame_base_error(),
97       m_cfa_is_valid(true),
98       m_stop_id(0),
99       m_stop_id_is_valid(false),
100       m_is_history_frame(false),
101       m_variable_list_sp(),
102       m_variable_list_value_objects(),
103       m_disassembly(),
104       m_mutex()
105 {
106     if (sc_ptr != nullptr)
107     {
108         m_sc = *sc_ptr;
109         m_flags.Set(m_sc.GetResolvedMask());
110     }
111 
112     if (reg_context_sp && !m_sc.target_sp)
113     {
114         m_sc.target_sp = reg_context_sp->CalculateTarget();
115         if (m_sc.target_sp)
116             m_flags.Set(eSymbolContextTarget);
117     }
118 }
119 
120 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index,
121                        const RegisterContextSP &reg_context_sp, addr_t cfa, const Address &pc_addr,
122                        const SymbolContext *sc_ptr)
123     : m_thread_wp(thread_sp),
124       m_frame_index(frame_idx),
125       m_concrete_frame_index(unwind_frame_index),
126       m_reg_context_sp(reg_context_sp),
127       m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr),
128       m_frame_code_addr(pc_addr),
129       m_sc(),
130       m_flags(),
131       m_frame_base(),
132       m_frame_base_error(),
133       m_cfa_is_valid(true),
134       m_stop_id(0),
135       m_stop_id_is_valid(false),
136       m_is_history_frame(false),
137       m_variable_list_sp(),
138       m_variable_list_value_objects(),
139       m_disassembly(),
140       m_mutex()
141 {
142     if (sc_ptr != nullptr)
143     {
144         m_sc = *sc_ptr;
145         m_flags.Set(m_sc.GetResolvedMask());
146     }
147 
148     if (!m_sc.target_sp && reg_context_sp)
149     {
150         m_sc.target_sp = reg_context_sp->CalculateTarget();
151         if (m_sc.target_sp)
152             m_flags.Set(eSymbolContextTarget);
153     }
154 
155     ModuleSP pc_module_sp(pc_addr.GetModule());
156     if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
157     {
158         if (pc_module_sp)
159         {
160             m_sc.module_sp = pc_module_sp;
161             m_flags.Set(eSymbolContextModule);
162         }
163         else
164         {
165             m_sc.module_sp.reset();
166         }
167     }
168 }
169 
170 StackFrame::~StackFrame() = default;
171 
172 StackID&
173 StackFrame::GetStackID()
174 {
175     std::lock_guard<std::recursive_mutex> guard(m_mutex);
176     // Make sure we have resolved the StackID object's symbol context scope if
177     // we already haven't looked it up.
178 
179     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
180     {
181         if (m_id.GetSymbolContextScope ())
182         {
183             // We already have a symbol context scope, we just don't have our
184             // flag bit set.
185             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
186         }
187         else
188         {
189             // Calculate the frame block and use this for the stack ID symbol
190             // context scope if we have one.
191             SymbolContextScope *scope = GetFrameBlock ();
192             if (scope == nullptr)
193             {
194                 // We don't have a block, so use the symbol
195                 if (m_flags.IsClear (eSymbolContextSymbol))
196                     GetSymbolContext (eSymbolContextSymbol);
197 
198                 // It is ok if m_sc.symbol is nullptr here
199                 scope = m_sc.symbol;
200             }
201             // Set the symbol context scope (the accessor will set the
202             // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
203             SetSymbolContextScope (scope);
204         }
205     }
206     return m_id;
207 }
208 
209 uint32_t
210 StackFrame::GetFrameIndex () const
211 {
212     ThreadSP thread_sp = GetThread();
213     if (thread_sp)
214         return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
215     else
216         return m_frame_index;
217 }
218 
219 void
220 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
221 {
222     std::lock_guard<std::recursive_mutex> guard(m_mutex);
223     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
224     m_id.SetSymbolContextScope (symbol_scope);
225 }
226 
227 const Address&
228 StackFrame::GetFrameCodeAddress()
229 {
230     std::lock_guard<std::recursive_mutex> guard(m_mutex);
231     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
232     {
233         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
234 
235         // Resolve the PC into a temporary address because if ResolveLoadAddress
236         // fails to resolve the address, it will clear the address object...
237         ThreadSP thread_sp (GetThread());
238         if (thread_sp)
239         {
240             TargetSP target_sp (thread_sp->CalculateTarget());
241             if (target_sp)
242             {
243                 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get(), eAddressClassCode))
244                 {
245                     ModuleSP module_sp (m_frame_code_addr.GetModule());
246                     if (module_sp)
247                     {
248                         m_sc.module_sp = module_sp;
249                         m_flags.Set(eSymbolContextModule);
250                     }
251                 }
252             }
253         }
254     }
255     return m_frame_code_addr;
256 }
257 
258 bool
259 StackFrame::ChangePC (addr_t pc)
260 {
261     std::lock_guard<std::recursive_mutex> guard(m_mutex);
262     // We can't change the pc value of a history stack frame - it is immutable.
263     if (m_is_history_frame)
264         return false;
265     m_frame_code_addr.SetRawAddress(pc);
266     m_sc.Clear(false);
267     m_flags.Reset(0);
268     ThreadSP thread_sp (GetThread());
269     if (thread_sp)
270         thread_sp->ClearStackFrames ();
271     return true;
272 }
273 
274 const char *
275 StackFrame::Disassemble ()
276 {
277     std::lock_guard<std::recursive_mutex> guard(m_mutex);
278     if (m_disassembly.GetSize() == 0)
279     {
280         ExecutionContext exe_ctx (shared_from_this());
281         Target *target = exe_ctx.GetTargetPtr();
282         if (target)
283         {
284             const char *plugin_name = nullptr;
285             const char *flavor = nullptr;
286             Disassembler::Disassemble (target->GetDebugger(),
287                                        target->GetArchitecture(),
288                                        plugin_name,
289                                        flavor,
290                                        exe_ctx,
291                                        0,
292                                        0,
293                                        0,
294                                        m_disassembly);
295         }
296         if (m_disassembly.GetSize() == 0)
297             return nullptr;
298     }
299     return m_disassembly.GetData();
300 }
301 
302 Block *
303 StackFrame::GetFrameBlock ()
304 {
305     if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
306         GetSymbolContext (eSymbolContextBlock);
307 
308     if (m_sc.block)
309     {
310         Block *inline_block = m_sc.block->GetContainingInlinedBlock();
311         if (inline_block)
312         {
313             // Use the block with the inlined function info
314             // as the frame block we want this frame to have only the variables
315             // for the inlined function and its non-inlined block child blocks.
316             return inline_block;
317         }
318         else
319         {
320             // This block is not contained within any inlined function blocks
321             // with so we want to use the top most function block.
322             return &m_sc.function->GetBlock (false);
323         }
324     }
325     return nullptr;
326 }
327 
328 //----------------------------------------------------------------------
329 // Get the symbol context if we already haven't done so by resolving the
330 // PC address as much as possible. This way when we pass around a
331 // StackFrame object, everyone will have as much information as
332 // possible and no one will ever have to look things up manually.
333 //----------------------------------------------------------------------
334 const SymbolContext&
335 StackFrame::GetSymbolContext (uint32_t resolve_scope)
336 {
337     std::lock_guard<std::recursive_mutex> guard(m_mutex);
338     // Copy our internal symbol context into "sc".
339     if ((m_flags.Get() & resolve_scope) != resolve_scope)
340     {
341         uint32_t resolved = 0;
342 
343         // If the target was requested add that:
344         if (!m_sc.target_sp)
345         {
346             m_sc.target_sp = CalculateTarget();
347             if (m_sc.target_sp)
348                 resolved |= eSymbolContextTarget;
349         }
350 
351         // Resolve our PC to section offset if we haven't already done so
352         // and if we don't have a module. The resolved address section will
353         // contain the module to which it belongs
354         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
355             GetFrameCodeAddress();
356 
357         // If this is not frame zero, then we need to subtract 1 from the PC
358         // value when doing address lookups since the PC will be on the
359         // instruction following the function call instruction...
360 
361         Address lookup_addr(GetFrameCodeAddress());
362         if (m_frame_index > 0 && lookup_addr.IsValid())
363         {
364             addr_t offset = lookup_addr.GetOffset();
365             if (offset > 0)
366             {
367                 lookup_addr.SetOffset(offset - 1);
368 
369             }
370             else
371             {
372                 // lookup_addr is the start of a section.  We need
373                 // do the math on the actual load address and re-compute
374                 // the section.  We're working with a 'noreturn' function
375                 // at the end of a section.
376                 ThreadSP thread_sp (GetThread());
377                 if (thread_sp)
378                 {
379                     TargetSP target_sp (thread_sp->CalculateTarget());
380                     if (target_sp)
381                     {
382                         addr_t addr_minus_one = lookup_addr.GetLoadAddress(target_sp.get()) - 1;
383                         lookup_addr.SetLoadAddress (addr_minus_one, target_sp.get());
384                     }
385                     else
386                     {
387                     lookup_addr.SetOffset(offset - 1);
388                     }
389                 }
390             }
391         }
392 
393         if (m_sc.module_sp)
394         {
395             // We have something in our stack frame symbol context, lets check
396             // if we haven't already tried to lookup one of those things. If we
397             // haven't then we will do the query.
398 
399             uint32_t actual_resolve_scope = 0;
400 
401             if (resolve_scope & eSymbolContextCompUnit)
402             {
403                 if (m_flags.IsClear (eSymbolContextCompUnit))
404                 {
405                     if (m_sc.comp_unit)
406                         resolved |= eSymbolContextCompUnit;
407                     else
408                         actual_resolve_scope |= eSymbolContextCompUnit;
409                 }
410             }
411 
412             if (resolve_scope & eSymbolContextFunction)
413             {
414                 if (m_flags.IsClear (eSymbolContextFunction))
415                 {
416                     if (m_sc.function)
417                         resolved |= eSymbolContextFunction;
418                     else
419                         actual_resolve_scope |= eSymbolContextFunction;
420                 }
421             }
422 
423             if (resolve_scope & eSymbolContextBlock)
424             {
425                 if (m_flags.IsClear (eSymbolContextBlock))
426                 {
427                     if (m_sc.block)
428                         resolved |= eSymbolContextBlock;
429                     else
430                         actual_resolve_scope |= eSymbolContextBlock;
431                 }
432             }
433 
434             if (resolve_scope & eSymbolContextSymbol)
435             {
436                 if (m_flags.IsClear (eSymbolContextSymbol))
437                 {
438                     if (m_sc.symbol)
439                         resolved |= eSymbolContextSymbol;
440                     else
441                         actual_resolve_scope |= eSymbolContextSymbol;
442                 }
443             }
444 
445             if (resolve_scope & eSymbolContextLineEntry)
446             {
447                 if (m_flags.IsClear (eSymbolContextLineEntry))
448                 {
449                     if (m_sc.line_entry.IsValid())
450                         resolved |= eSymbolContextLineEntry;
451                     else
452                         actual_resolve_scope |= eSymbolContextLineEntry;
453                 }
454             }
455 
456             if (actual_resolve_scope)
457             {
458                 // We might be resolving less information than what is already
459                 // in our current symbol context so resolve into a temporary
460                 // symbol context "sc" so we don't clear out data we have
461                 // already found in "m_sc"
462                 SymbolContext sc;
463                 // Set flags that indicate what we have tried to resolve
464                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
465                 // Only replace what we didn't already have as we may have
466                 // information for an inlined function scope that won't match
467                 // what a standard lookup by address would match
468                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == nullptr)
469                     m_sc.comp_unit = sc.comp_unit;
470                 if ((resolved & eSymbolContextFunction)  && m_sc.function == nullptr)
471                     m_sc.function = sc.function;
472                 if ((resolved & eSymbolContextBlock)     && m_sc.block == nullptr)
473                     m_sc.block = sc.block;
474                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == nullptr)
475                     m_sc.symbol = sc.symbol;
476                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
477                 {
478                     m_sc.line_entry = sc.line_entry;
479                     m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
480                 }
481             }
482         }
483         else
484         {
485             // If we don't have a module, then we can't have the compile unit,
486             // function, block, line entry or symbol, so we can safely call
487             // ResolveSymbolContextForAddress with our symbol context member m_sc.
488             if (m_sc.target_sp)
489             {
490                 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
491             }
492         }
493 
494         // Update our internal flags so we remember what we have tried to locate so
495         // we don't have to keep trying when more calls to this function are made.
496         // We might have dug up more information that was requested (for example
497         // if we were asked to only get the block, we will have gotten the
498         // compile unit, and function) so set any additional bits that we resolved
499         m_flags.Set (resolve_scope | resolved);
500     }
501 
502     // Return the symbol context with everything that was possible to resolve
503     // resolved.
504     return m_sc;
505 }
506 
507 VariableList *
508 StackFrame::GetVariableList (bool get_file_globals)
509 {
510     std::lock_guard<std::recursive_mutex> guard(m_mutex);
511     if (m_flags.IsClear(RESOLVED_VARIABLES))
512     {
513         m_flags.Set(RESOLVED_VARIABLES);
514 
515         Block *frame_block = GetFrameBlock();
516 
517         if (frame_block)
518         {
519             const bool get_child_variables = true;
520             const bool can_create = true;
521             const bool stop_if_child_block_is_inlined_function = true;
522             m_variable_list_sp.reset(new VariableList());
523             frame_block->AppendBlockVariables(can_create,
524                                               get_child_variables,
525                                               stop_if_child_block_is_inlined_function,
526                                               [this](Variable* v) { return true; },
527                                               m_variable_list_sp.get());
528         }
529     }
530 
531     if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
532         get_file_globals)
533     {
534         m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
535 
536         if (m_flags.IsClear (eSymbolContextCompUnit))
537             GetSymbolContext (eSymbolContextCompUnit);
538 
539         if (m_sc.comp_unit)
540         {
541             VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
542             if (m_variable_list_sp)
543                 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
544             else
545                 m_variable_list_sp = global_variable_list_sp;
546         }
547     }
548 
549     return m_variable_list_sp.get();
550 }
551 
552 VariableListSP
553 StackFrame::GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location)
554 {
555     std::lock_guard<std::recursive_mutex> guard(m_mutex);
556     // We can't fetch variable information for a history stack frame.
557     if (m_is_history_frame)
558         return VariableListSP();
559 
560     VariableListSP var_list_sp(new VariableList);
561     GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
562 
563     if (m_sc.block)
564     {
565         const bool can_create = true;
566         const bool get_parent_variables = true;
567         const bool stop_if_block_is_inlined_function = true;
568         m_sc.block->AppendVariables (can_create,
569                                      get_parent_variables,
570                                      stop_if_block_is_inlined_function,
571                                      [this, must_have_valid_location](Variable* v)
572                                      {
573                                          return v->IsInScope(this) && (!must_have_valid_location || v->LocationIsValidForFrame(this));
574                                      },
575                                      var_list_sp.get());
576     }
577 
578     if (m_sc.comp_unit && get_file_globals)
579     {
580         VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
581         if (global_variable_list_sp)
582             var_list_sp->AddVariables (global_variable_list_sp.get());
583     }
584 
585     return var_list_sp;
586 }
587 
588 ValueObjectSP
589 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
590                                                DynamicValueType use_dynamic,
591                                                uint32_t options,
592                                                VariableSP &var_sp,
593                                                Error &error)
594 {
595     // We can't fetch variable information for a history stack frame.
596     if (m_is_history_frame)
597         return ValueObjectSP();
598 
599     if (var_expr_cstr && var_expr_cstr[0])
600     {
601         const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
602         const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
603         const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
604         //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
605         error.Clear();
606         bool deref = false;
607         bool address_of = false;
608         ValueObjectSP valobj_sp;
609         const bool get_file_globals = true;
610         // When looking up a variable for an expression, we need only consider the
611         // variables that are in scope.
612         VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
613         VariableList *variable_list = var_list_sp.get();
614 
615         if (variable_list)
616         {
617             // If first character is a '*', then show pointer contents
618             const char *var_expr = var_expr_cstr;
619             if (var_expr[0] == '*')
620             {
621                 deref = true;
622                 var_expr++; // Skip the '*'
623             }
624             else if (var_expr[0] == '&')
625             {
626                 address_of = true;
627                 var_expr++; // Skip the '&'
628             }
629 
630             std::string var_path (var_expr);
631             size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
632             StreamString var_expr_path_strm;
633 
634             ConstString name_const_string;
635             if (separator_idx == std::string::npos)
636                 name_const_string.SetCString (var_path.c_str());
637             else
638                 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
639 
640             var_sp = variable_list->FindVariable(name_const_string, false);
641 
642             bool synthetically_added_instance_object = false;
643 
644             if (var_sp)
645             {
646                 var_path.erase (0, name_const_string.GetLength ());
647             }
648 
649             if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess))
650             {
651                 // Check for direct ivars access which helps us with implicit
652                 // access to ivars with the "this->" or "self->"
653                 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
654                 lldb::LanguageType method_language = eLanguageTypeUnknown;
655                 bool is_instance_method = false;
656                 ConstString method_object_name;
657                 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
658                 {
659                     if (is_instance_method && method_object_name)
660                     {
661                         var_sp = variable_list->FindVariable(method_object_name);
662                         if (var_sp)
663                         {
664                             separator_idx = 0;
665                             var_path.insert(0, "->");
666                             synthetically_added_instance_object = true;
667                         }
668                     }
669                 }
670             }
671 
672             if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions))
673             {
674                 // Check if any anonymous unions are there which contain a variable with the name we need
675                 for (size_t i = 0;
676                      i < variable_list->GetSize();
677                      i++)
678                 {
679                     if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i))
680                     {
681                         if (variable_sp->GetName().IsEmpty())
682                         {
683                             if (Type *var_type = variable_sp->GetType())
684                             {
685                                 if (var_type->GetForwardCompilerType().IsAnonymousType())
686                                 {
687                                     valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
688                                     if (!valobj_sp)
689                                         return valobj_sp;
690                                     valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true);
691                                     if (valobj_sp)
692                                         break;
693                                 }
694                             }
695                         }
696                     }
697                 }
698             }
699 
700             if (var_sp && !valobj_sp)
701             {
702                 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
703                 if (!valobj_sp)
704                     return valobj_sp;
705             }
706             if (valobj_sp)
707             {
708                 // We are dumping at least one child
709                 while (separator_idx != std::string::npos)
710                 {
711                     // Calculate the next separator index ahead of time
712                     ValueObjectSP child_valobj_sp;
713                     const char separator_type = var_path[0];
714                     switch (separator_type)
715                     {
716                     case '-':
717                         if (var_path.size() >= 2 && var_path[1] != '>')
718                             return ValueObjectSP();
719 
720                         if (no_fragile_ivar)
721                         {
722                             // Make sure we aren't trying to deref an objective
723                             // C ivar if this is not allowed
724                             const uint32_t pointer_type_flags = valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
725                             if ((pointer_type_flags & eTypeIsObjC) &&
726                                 (pointer_type_flags & eTypeIsPointer))
727                             {
728                                 // This was an objective C object pointer and
729                                 // it was requested we skip any fragile ivars
730                                 // so return nothing here
731                                 return ValueObjectSP();
732                             }
733                         }
734                         var_path.erase (0, 1); // Remove the '-'
735                         LLVM_FALLTHROUGH;
736                     case '.':
737                         {
738                             const bool expr_is_ptr = var_path[0] == '>';
739 
740                             var_path.erase (0, 1); // Remove the '.' or '>'
741                             separator_idx = var_path.find_first_of(".-[");
742                             ConstString child_name;
743                             if (separator_idx == std::string::npos)
744                                 child_name.SetCString (var_path.c_str());
745                             else
746                                 child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
747 
748                             if (check_ptr_vs_member)
749                             {
750                                 // We either have a pointer type and need to verify
751                                 // valobj_sp is a pointer, or we have a member of a
752                                 // class/union/struct being accessed with the . syntax
753                                 // and need to verify we don't have a pointer.
754                                 const bool actual_is_ptr = valobj_sp->IsPointerType ();
755 
756                                 if (actual_is_ptr != expr_is_ptr)
757                                 {
758                                     // Incorrect use of "." with a pointer, or "->" with
759                                     // a class/union/struct instance or reference.
760                                     valobj_sp->GetExpressionPath (var_expr_path_strm, false);
761                                     if (actual_is_ptr)
762                                         error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
763                                                                         var_expr_path_strm.GetString().c_str(),
764                                                                         child_name.GetCString(),
765                                                                         var_expr_path_strm.GetString().c_str(),
766                                                                         var_path.c_str());
767                                     else
768                                         error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
769                                                                         var_expr_path_strm.GetString().c_str(),
770                                                                         child_name.GetCString(),
771                                                                         var_expr_path_strm.GetString().c_str(),
772                                                                         var_path.c_str());
773                                     return ValueObjectSP();
774                                 }
775                             }
776                             child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
777                             if (!child_valobj_sp)
778                             {
779                                 if (!no_synth_child)
780                                 {
781                                     child_valobj_sp = valobj_sp->GetSyntheticValue();
782                                     if (child_valobj_sp)
783                                         child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
784                                 }
785 
786                                 if (no_synth_child || !child_valobj_sp)
787                                 {
788                                     // No child member with name "child_name"
789                                     if (synthetically_added_instance_object)
790                                     {
791                                         // We added a "this->" or "self->" to the beginning of the expression
792                                         // and this is the first pointer ivar access, so just return the normal
793                                         // error
794                                         error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
795                                                                        name_const_string.GetCString());
796                                     }
797                                     else
798                                     {
799                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
800                                         if (child_name)
801                                         {
802                                             error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
803                                                                             child_name.GetCString(),
804                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
805                                                                             var_expr_path_strm.GetString().c_str());
806                                         }
807                                         else
808                                         {
809                                             error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
810                                                                             var_expr_path_strm.GetString().c_str(),
811                                                                             var_expr_cstr);
812                                         }
813                                     }
814                                     return ValueObjectSP();
815                                 }
816                             }
817                             synthetically_added_instance_object = false;
818                             // Remove the child name from the path
819                             var_path.erase(0, child_name.GetLength());
820                             if (use_dynamic != eNoDynamicValues)
821                             {
822                                 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
823                                 if (dynamic_value_sp)
824                                     child_valobj_sp = dynamic_value_sp;
825                             }
826                         }
827                         break;
828 
829                     case '[':
830                         // Array member access, or treating pointer as an array
831                         if (var_path.size() > 2) // Need at least two brackets and a number
832                         {
833                             char *end = nullptr;
834                             long child_index = ::strtol (&var_path[1], &end, 0);
835                             if (end && *end == ']'
836                                 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
837                             {
838                                 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref)
839                                 {
840                                     // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
841                                     // and extract bit low out of it. reading array item low
842                                     // would be done by saying ptr[low], without a deref * sign
843                                     Error error;
844                                     ValueObjectSP temp(valobj_sp->Dereference(error));
845                                     if (error.Fail())
846                                     {
847                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
848                                         error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
849                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
850                                                                         var_expr_path_strm.GetString().c_str());
851                                         return ValueObjectSP();
852                                     }
853                                     valobj_sp = temp;
854                                     deref = false;
855                                 }
856                                 else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref)
857                                 {
858                                     // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
859                                     // (an operation that is equivalent to deref-ing arr)
860                                     // and extract bit low out of it. reading array item low
861                                     // would be done by saying arr[low], without a deref * sign
862                                     Error error;
863                                     ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
864                                     if (error.Fail())
865                                     {
866                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
867                                         error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
868                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
869                                                                         var_expr_path_strm.GetString().c_str());
870                                         return ValueObjectSP();
871                                     }
872                                     valobj_sp = temp;
873                                     deref = false;
874                                 }
875 
876                                 bool is_incomplete_array = false;
877                                 if (valobj_sp->IsPointerType ())
878                                 {
879                                     bool is_objc_pointer = true;
880 
881                                     if (valobj_sp->GetCompilerType().GetMinimumLanguage() != eLanguageTypeObjC)
882                                         is_objc_pointer = false;
883                                     else if (!valobj_sp->GetCompilerType().IsPointerType())
884                                         is_objc_pointer = false;
885 
886                                     if (no_synth_child && is_objc_pointer)
887                                     {
888                                         error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
889                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
890                                                                        var_expr_path_strm.GetString().c_str());
891 
892                                         return ValueObjectSP();
893                                     }
894                                     else if (is_objc_pointer)
895                                     {
896                                         // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
897                                         ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
898                                         if (!synthetic /* no synthetic */
899                                             || synthetic == valobj_sp) /* synthetic is the same as the original object */
900                                         {
901                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
902                                             error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
903                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
904                                                                             var_expr_path_strm.GetString().c_str());
905                                         }
906                                         else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
907                                         {
908                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
909                                             error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
910                                                                             child_index,
911                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
912                                                                             var_expr_path_strm.GetString().c_str());
913                                         }
914                                         else
915                                         {
916                                             child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
917                                             if (!child_valobj_sp)
918                                             {
919                                                 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
920                                                 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
921                                                                                 child_index,
922                                                                                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
923                                                                                 var_expr_path_strm.GetString().c_str());
924                                             }
925                                         }
926                                     }
927                                     else
928                                     {
929                                         child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
930                                         if (!child_valobj_sp)
931                                         {
932                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
933                                             error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
934                                                                             child_index,
935                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
936                                                                             var_expr_path_strm.GetString().c_str());
937                                         }
938                                     }
939                                 }
940                                 else if (valobj_sp->GetCompilerType().IsArrayType(nullptr, nullptr, &is_incomplete_array))
941                                 {
942                                     // Pass false to dynamic_value here so we can tell the difference between
943                                     // no dynamic value and no member of this type...
944                                     child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
945                                     if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
946                                         child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
947 
948                                     if (!child_valobj_sp)
949                                     {
950                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
951                                         error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
952                                                                         child_index,
953                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
954                                                                         var_expr_path_strm.GetString().c_str());
955                                     }
956                                 }
957                                 else if (valobj_sp->GetCompilerType().IsScalarType())
958                                 {
959                                     // this is a bitfield asking to display just one bit
960                                     child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
961                                     if (!child_valobj_sp)
962                                     {
963                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
964                                         error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
965                                                                         child_index, child_index,
966                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
967                                                                         var_expr_path_strm.GetString().c_str());
968                                     }
969                                 }
970                                 else
971                                 {
972                                     ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
973                                     if (no_synth_child /* synthetic is forbidden */ ||
974                                         !synthetic /* no synthetic */
975                                         || synthetic == valobj_sp) /* synthetic is the same as the original object */
976                                     {
977                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
978                                         error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
979                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
980                                                                         var_expr_path_strm.GetString().c_str());
981                                     }
982                                     else if (static_cast<uint32_t>(child_index) >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
983                                     {
984                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
985                                         error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
986                                                                         child_index,
987                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
988                                                                         var_expr_path_strm.GetString().c_str());
989                                     }
990                                     else
991                                     {
992                                         child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
993                                         if (!child_valobj_sp)
994                                         {
995                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
996                                             error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
997                                                                             child_index,
998                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
999                                                                             var_expr_path_strm.GetString().c_str());
1000                                         }
1001                                     }
1002                                 }
1003 
1004                                 if (!child_valobj_sp)
1005                                 {
1006                                     // Invalid array index...
1007                                     return ValueObjectSP();
1008                                 }
1009 
1010                                 // Erase the array member specification '[%i]' where
1011                                 // %i is the array index
1012                                 var_path.erase(0, (end - var_path.c_str()) + 1);
1013                                 separator_idx = var_path.find_first_of(".-[");
1014                                 if (use_dynamic != eNoDynamicValues)
1015                                 {
1016                                     ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
1017                                     if (dynamic_value_sp)
1018                                         child_valobj_sp = dynamic_value_sp;
1019                                 }
1020                                 // Break out early from the switch since we were
1021                                 // able to find the child member
1022                                 break;
1023                             }
1024                             else if (end && *end == '-')
1025                             {
1026                                 // this is most probably a BitField, let's take a look
1027                                 char *real_end = nullptr;
1028                                 long final_index = ::strtol (end+1, &real_end, 0);
1029                                 bool expand_bitfield = true;
1030                                 if (real_end && *real_end == ']')
1031                                 {
1032                                     // if the format given is [high-low], swap range
1033                                     if (child_index > final_index)
1034                                     {
1035                                         long temp = child_index;
1036                                         child_index = final_index;
1037                                         final_index = temp;
1038                                     }
1039 
1040                                     if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref)
1041                                     {
1042                                         // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
1043                                         // and extract bits low thru high out of it. reading array items low thru high
1044                                         // would be done by saying ptr[low-high], without a deref * sign
1045                                         Error error;
1046                                         ValueObjectSP temp(valobj_sp->Dereference(error));
1047                                         if (error.Fail())
1048                                         {
1049                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1050                                             error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
1051                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
1052                                                                             var_expr_path_strm.GetString().c_str());
1053                                             return ValueObjectSP();
1054                                         }
1055                                         valobj_sp = temp;
1056                                         deref = false;
1057                                     }
1058                                     else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref)
1059                                     {
1060                                         // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
1061                                         // (an operation that is equivalent to deref-ing arr)
1062                                         // and extract bits low thru high out of it. reading array items low thru high
1063                                         // would be done by saying arr[low-high], without a deref * sign
1064                                         Error error;
1065                                         ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
1066                                         if (error.Fail())
1067                                         {
1068                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1069                                             error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
1070                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
1071                                                                             var_expr_path_strm.GetString().c_str());
1072                                             return ValueObjectSP();
1073                                         }
1074                                         valobj_sp = temp;
1075                                         deref = false;
1076                                     }
1077                                     /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
1078                                     {
1079                                         child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
1080                                         expand_bitfield = false;
1081                                         if (!child_valobj_sp)
1082                                         {
1083                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1084                                             error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
1085                                                                             child_index, final_index,
1086                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
1087                                                                             var_expr_path_strm.GetString().c_str());
1088                                         }
1089                                     }*/
1090 
1091                                     if (expand_bitfield)
1092                                     {
1093                                         child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1094                                         if (!child_valobj_sp)
1095                                         {
1096                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1097                                             error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
1098                                                                             child_index, final_index,
1099                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
1100                                                                             var_expr_path_strm.GetString().c_str());
1101                                         }
1102                                     }
1103                                 }
1104 
1105                                 if (!child_valobj_sp)
1106                                 {
1107                                     // Invalid bitfield range...
1108                                     return ValueObjectSP();
1109                                 }
1110 
1111                                 // Erase the bitfield member specification '[%i-%i]' where
1112                                 // %i is the index
1113                                 var_path.erase(0, (real_end - var_path.c_str()) + 1);
1114                                 separator_idx = var_path.find_first_of(".-[");
1115                                 if (use_dynamic != eNoDynamicValues)
1116                                 {
1117                                     ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
1118                                     if (dynamic_value_sp)
1119                                         child_valobj_sp = dynamic_value_sp;
1120                                 }
1121                                 // Break out early from the switch since we were
1122                                 // able to find the child member
1123                                 break;
1124 
1125                             }
1126                         }
1127                         else
1128                         {
1129                             error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
1130                                                            var_expr_path_strm.GetString().c_str(),
1131                                                            var_path.c_str());
1132                         }
1133                         return ValueObjectSP();
1134 
1135                     default:
1136                         // Failure...
1137                         {
1138                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
1139                             error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
1140                                                             separator_type,
1141                                                             var_expr_path_strm.GetString().c_str(),
1142                                                             var_path.c_str());
1143 
1144                             return ValueObjectSP();
1145                         }
1146                     }
1147 
1148                     if (child_valobj_sp)
1149                         valobj_sp = child_valobj_sp;
1150 
1151                     if (var_path.empty())
1152                         break;
1153                 }
1154                 if (valobj_sp)
1155                 {
1156                     if (deref)
1157                     {
1158                         ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
1159                         valobj_sp = deref_valobj_sp;
1160                     }
1161                     else if (address_of)
1162                     {
1163                         ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
1164                         valobj_sp = address_of_valobj_sp;
1165                     }
1166                 }
1167                 return valobj_sp;
1168             }
1169             else
1170             {
1171                 error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
1172                                                name_const_string.GetCString());
1173             }
1174         }
1175     }
1176     else
1177     {
1178         error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
1179     }
1180     return ValueObjectSP();
1181 }
1182 
1183 bool
1184 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
1185 {
1186     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1187     if (!m_cfa_is_valid)
1188     {
1189         m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
1190         return false;
1191     }
1192 
1193     if (m_flags.IsClear(GOT_FRAME_BASE))
1194     {
1195         if (m_sc.function)
1196         {
1197             m_frame_base.Clear();
1198             m_frame_base_error.Clear();
1199 
1200             m_flags.Set(GOT_FRAME_BASE);
1201             ExecutionContext exe_ctx (shared_from_this());
1202             Value expr_value;
1203             addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1204             if (m_sc.function->GetFrameBaseExpression().IsLocationList())
1205                 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
1206 
1207             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx,
1208                                                                  nullptr,
1209                                                                  nullptr,
1210                                                                  nullptr,
1211                                                                  loclist_base_addr,
1212                                                                  nullptr,
1213                                                                  nullptr,
1214                                                                  expr_value,
1215                                                                  &m_frame_base_error) == false)
1216             {
1217                 // We should really have an error if evaluate returns, but in case
1218                 // we don't, lets set the error to something at least.
1219                 if (m_frame_base_error.Success())
1220                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
1221             }
1222             else
1223             {
1224                 m_frame_base = expr_value.ResolveValue(&exe_ctx);
1225             }
1226         }
1227         else
1228         {
1229             m_frame_base_error.SetErrorString ("No function in symbol context.");
1230         }
1231     }
1232 
1233     if (m_frame_base_error.Success())
1234         frame_base = m_frame_base;
1235 
1236     if (error_ptr)
1237         *error_ptr = m_frame_base_error;
1238     return m_frame_base_error.Success();
1239 }
1240 
1241 DWARFExpression *
1242 StackFrame::GetFrameBaseExpression(Error *error_ptr)
1243 {
1244     if (!m_sc.function)
1245     {
1246         if (error_ptr)
1247         {
1248             error_ptr->SetErrorString ("No function in symbol context.");
1249         }
1250         return nullptr;
1251     }
1252 
1253     return &m_sc.function->GetFrameBaseExpression();
1254 }
1255 
1256 RegisterContextSP
1257 StackFrame::GetRegisterContext ()
1258 {
1259     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1260     if (!m_reg_context_sp)
1261     {
1262         ThreadSP thread_sp (GetThread());
1263         if (thread_sp)
1264             m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
1265     }
1266     return m_reg_context_sp;
1267 }
1268 
1269 bool
1270 StackFrame::HasDebugInformation ()
1271 {
1272     GetSymbolContext (eSymbolContextLineEntry);
1273     return m_sc.line_entry.IsValid();
1274 }
1275 
1276 ValueObjectSP
1277 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1278 {
1279     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1280     ValueObjectSP valobj_sp;
1281     if (m_is_history_frame)
1282     {
1283         return valobj_sp;
1284     }
1285     VariableList *var_list = GetVariableList (true);
1286     if (var_list)
1287     {
1288         // Make sure the variable is a frame variable
1289         const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
1290         const uint32_t num_variables = var_list->GetSize();
1291         if (var_idx < num_variables)
1292         {
1293             valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
1294             if (!valobj_sp)
1295             {
1296                 if (m_variable_list_value_objects.GetSize() < num_variables)
1297                     m_variable_list_value_objects.Resize(num_variables);
1298                 valobj_sp = ValueObjectVariable::Create (this, variable_sp);
1299                 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
1300             }
1301         }
1302     }
1303     if (use_dynamic != eNoDynamicValues && valobj_sp)
1304     {
1305         ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
1306         if (dynamic_sp)
1307             return dynamic_sp;
1308     }
1309     return valobj_sp;
1310 }
1311 
1312 ValueObjectSP
1313 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
1314 {
1315     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1316     if (m_is_history_frame)
1317         return ValueObjectSP();
1318 
1319     // Check to make sure we aren't already tracking this variable?
1320     ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
1321     if (!valobj_sp)
1322     {
1323         // We aren't already tracking this global
1324         VariableList *var_list = GetVariableList (true);
1325         // If this frame has no variables, create a new list
1326         if (var_list == nullptr)
1327             m_variable_list_sp.reset (new VariableList());
1328 
1329         // Add the global/static variable to this frame
1330         m_variable_list_sp->AddVariable (variable_sp);
1331 
1332         // Now make a value object for it so we can track its changes
1333         valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
1334     }
1335     return valobj_sp;
1336 }
1337 
1338 bool
1339 StackFrame::IsInlined ()
1340 {
1341     if (m_sc.block == nullptr)
1342         GetSymbolContext (eSymbolContextBlock);
1343     if (m_sc.block)
1344         return m_sc.block->GetContainingInlinedBlock() != nullptr;
1345     return false;
1346 }
1347 
1348 lldb::LanguageType
1349 StackFrame::GetLanguage ()
1350 {
1351     CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1352     if (cu)
1353         return cu->GetLanguage();
1354     return lldb::eLanguageTypeUnknown;
1355 }
1356 
1357 lldb::LanguageType
1358 StackFrame::GuessLanguage ()
1359 {
1360     LanguageType lang_type = GetLanguage();
1361 
1362     if (lang_type == eLanguageTypeUnknown)
1363     {
1364         Function *f = GetSymbolContext(eSymbolContextFunction).function;
1365         if (f)
1366         {
1367             lang_type = f->GetMangled().GuessLanguage();
1368         }
1369     }
1370 
1371     return lang_type;
1372 }
1373 
1374 namespace
1375 {
1376     std::pair<const Instruction::Operand *, int64_t>
1377     GetBaseExplainingValue(const Instruction::Operand &operand,
1378                            RegisterContext &register_context,
1379                            lldb::addr_t value)
1380     {
1381         switch(operand.m_type)
1382         {
1383         case Instruction::Operand::Type::Dereference:
1384         case Instruction::Operand::Type::Immediate:
1385         case Instruction::Operand::Type::Invalid:
1386         case Instruction::Operand::Type::Product:
1387             // These are not currently interesting
1388             return std::make_pair(nullptr, 0);
1389         case Instruction::Operand::Type::Sum:
1390             {
1391                 const Instruction::Operand *immediate_child = nullptr;
1392                 const Instruction::Operand *variable_child = nullptr;
1393                 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate)
1394                 {
1395                     immediate_child = &operand.m_children[0];
1396                     variable_child = &operand.m_children[1];
1397                 }
1398                 else if (operand.m_children[1].m_type == Instruction::Operand::Type::Immediate)
1399                 {
1400                     immediate_child = &operand.m_children[1];
1401                     variable_child = &operand.m_children[0];
1402                 }
1403                 if (!immediate_child)
1404                 {
1405                     return std::make_pair(nullptr, 0);
1406                 }
1407                 lldb::addr_t adjusted_value = value;
1408                 if (immediate_child->m_negative)
1409                 {
1410                     adjusted_value += immediate_child->m_immediate;
1411                 }
1412                 else
1413                 {
1414                     adjusted_value -= immediate_child->m_immediate;
1415                 }
1416                 std::pair<const Instruction::Operand *, int64_t> base_and_offset = GetBaseExplainingValue(*variable_child, register_context, adjusted_value);
1417                 if (!base_and_offset.first)
1418                 {
1419                     return std::make_pair(nullptr, 0);
1420                 }
1421                 if (immediate_child->m_negative)
1422                 {
1423                     base_and_offset.second -= immediate_child->m_immediate;
1424                 }
1425                 else
1426                 {
1427                     base_and_offset.second += immediate_child->m_immediate;
1428                 }
1429                 return base_and_offset;
1430             }
1431         case Instruction::Operand::Type::Register:
1432             {
1433                 const RegisterInfo *info = register_context.GetRegisterInfoByName(operand.m_register.AsCString());
1434                 if (!info)
1435                 {
1436                     return std::make_pair(nullptr, 0);
1437                 }
1438                 RegisterValue reg_value;
1439                 if (!register_context.ReadRegister(info, reg_value))
1440                 {
1441                     return std::make_pair(nullptr, 0);
1442                 }
1443                 if (reg_value.GetAsUInt64() == value)
1444                 {
1445                     return std::make_pair(&operand, 0);
1446                 }
1447                 else
1448                 {
1449                     return std::make_pair(nullptr, 0);
1450                 }
1451             }
1452         }
1453     }
1454 
1455     std::pair<const Instruction::Operand *, int64_t>
1456     GetBaseExplainingDereference(const Instruction::Operand &operand,
1457                                  RegisterContext &register_context,
1458                                  lldb::addr_t addr)
1459     {
1460         if (operand.m_type == Instruction::Operand::Type::Dereference)
1461         {
1462             return GetBaseExplainingValue(operand.m_children[0],
1463                                           register_context,
1464                                           addr);
1465         }
1466         return std::make_pair(nullptr, 0);
1467     }
1468 };
1469 
1470 lldb::ValueObjectSP
1471 StackFrame::GuessValueForAddress(lldb::addr_t addr)
1472 {
1473     TargetSP target_sp = CalculateTarget();
1474 
1475     const ArchSpec &target_arch = target_sp->GetArchitecture();
1476 
1477     AddressRange pc_range;
1478     pc_range.GetBaseAddress() = GetFrameCodeAddress();
1479     pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1480 
1481     ExecutionContext exe_ctx (shared_from_this());
1482 
1483     const char *plugin_name = nullptr;
1484     const char *flavor = nullptr;
1485     const bool prefer_file_cache = false;
1486 
1487     DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch,
1488                                                                      plugin_name,
1489                                                                      flavor,
1490                                                                      exe_ctx,
1491                                                                      pc_range,
1492                                                                      prefer_file_cache);
1493 
1494     if (!disassembler_sp->GetInstructionList().GetSize())
1495     {
1496         return ValueObjectSP();
1497     }
1498 
1499     InstructionSP instruction_sp = disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1500 
1501     llvm::SmallVector<Instruction::Operand, 3> operands;
1502 
1503     if (!instruction_sp->ParseOperands(operands))
1504     {
1505         return ValueObjectSP();
1506     }
1507 
1508     RegisterContextSP register_context_sp = GetRegisterContext();
1509 
1510     if (!register_context_sp)
1511     {
1512         return ValueObjectSP();
1513     }
1514 
1515     for (const Instruction::Operand &operand : operands)
1516     {
1517         std::pair<const Instruction::Operand *, int64_t>
1518             base_and_offset = GetBaseExplainingDereference(operand, *register_context_sp, addr);
1519 
1520         if (!base_and_offset.first)
1521         {
1522             continue;
1523         }
1524 
1525         switch (base_and_offset.first->m_type)
1526         {
1527         case Instruction::Operand::Type::Immediate:
1528             {
1529                 lldb_private::Address addr;
1530                 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate + base_and_offset.second, addr))
1531                 {
1532                     TypeSystem *c_type_system = target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
1533                     if (!c_type_system)
1534                     {
1535                         return ValueObjectSP();
1536                     }
1537                     else
1538                     {
1539                         CompilerType void_ptr_type = c_type_system->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar).GetPointerType();
1540                         return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
1541                     }
1542                 }
1543                 else
1544                 {
1545                     return ValueObjectSP();
1546                 }
1547                 break;
1548             }
1549         case Instruction::Operand::Type::Register:
1550             {
1551                 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register, base_and_offset.second);
1552             }
1553         default:
1554             return ValueObjectSP();
1555         }
1556 
1557     }
1558 
1559     return ValueObjectSP();
1560 }
1561 
1562 namespace
1563 {
1564     ValueObjectSP
1565     GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, int64_t offset)
1566     {
1567         if (offset < 0 || offset >= parent->GetByteSize())
1568         {
1569             return ValueObjectSP();
1570         }
1571 
1572         if (parent->IsPointerOrReferenceType())
1573         {
1574             return parent;
1575         }
1576 
1577         for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci)
1578         {
1579             const bool can_create = true;
1580             ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
1581 
1582             if (!child_sp)
1583             {
1584                 return ValueObjectSP();
1585             }
1586 
1587             int64_t child_offset = child_sp->GetByteOffset();
1588             int64_t child_size = child_sp->GetByteSize();
1589 
1590             if (offset >= child_offset &&
1591                 offset < (child_offset + child_size))
1592             {
1593                 return GetValueForOffset(frame, child_sp, offset - child_offset);
1594             }
1595         }
1596 
1597         if (offset == 0)
1598         {
1599             return parent;
1600         }
1601         else
1602         {
1603             return ValueObjectSP();
1604         }
1605     }
1606 
1607     ValueObjectSP
1608     GetValueForDereferincingOffset(StackFrame &frame, ValueObjectSP &base, int64_t offset)
1609     {
1610         // base is a pointer to something
1611         // offset is the thing to add to the pointer
1612         // We return the most sensible ValueObject for the result of *(base+offset)
1613 
1614         if (!base->IsPointerOrReferenceType())
1615         {
1616             return ValueObjectSP();
1617         }
1618 
1619         Error error;
1620         ValueObjectSP pointee = base->Dereference(error);
1621 
1622         if (offset >= pointee->GetByteSize())
1623         {
1624             int64_t index = offset / pointee->GetByteSize();
1625             offset = offset % pointee->GetByteSize();
1626             const bool can_create = true;
1627             pointee = base->GetSyntheticArrayMember(index, can_create);
1628         }
1629 
1630         if (!pointee || error.Fail())
1631         {
1632             return ValueObjectSP();
1633         }
1634 
1635         return GetValueForOffset(frame, pointee, offset);
1636     }
1637 
1638     //------------------------------------------------------------------
1639     /// Attempt to reconstruct the ValueObject for the address contained in a
1640     /// given register plus an offset.
1641     ///
1642     /// @params [in] frame
1643     ///   The current stack frame.
1644     ///
1645     /// @params [in] reg
1646     ///   The register.
1647     ///
1648     /// @params [in] offset
1649     ///   The offset from the register.
1650     ///
1651     /// @param [in] disassembler
1652     ///   A disassembler containing instructions valid up to the current PC.
1653     ///
1654     /// @param [in] variables
1655     ///   The variable list from the current frame,
1656     ///
1657     /// @param [in] pc
1658     ///   The program counter for the instruction considered the 'user'.
1659     ///
1660     /// @return
1661     ///   A string describing the base for the ExpressionPath.  This could be a
1662     ///     variable, a register value, an argument, or a function return value.
1663     ///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
1664     //------------------------------------------------------------------
1665     lldb::ValueObjectSP
1666     DoGuessValueAt(StackFrame &frame, ConstString reg, int64_t offset, Disassembler &disassembler, VariableList &variables, const Address &pc)
1667     {
1668         // Example of operation for Intel:
1669         //
1670         // +14: movq   -0x8(%rbp), %rdi
1671         // +18: movq   0x8(%rdi), %rdi
1672         // +22: addl   0x4(%rdi), %eax
1673         //
1674         // f, a pointer to a struct, is known to be at -0x8(%rbp).
1675         //
1676         // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18 that assigns to rdi, and calls itself recursively for that dereference
1677         //   DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at +14 that assigns to rdi, and calls itself recursively for that derefernece
1678         //     DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the variable list.
1679         //     Returns a ValueObject for f.  (That's what was stored at rbp-8 at +14)
1680         //   Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8 at +18)
1681         // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at rdi+4 at +22)
1682 
1683         // First, check the variable list to see if anything is at the specified location.
1684         for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi)
1685         {
1686             VariableSP var_sp = variables.GetVariableAtIndex(vi);
1687             DWARFExpression &dwarf_expression = var_sp->LocationExpression();
1688 
1689             const RegisterInfo *expression_reg;
1690             int64_t expression_offset;
1691             ExecutionContext exe_ctx;
1692 
1693             if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg, expression_offset))
1694             {
1695                 if ((reg == ConstString(expression_reg->name) ||
1696                      reg == ConstString(expression_reg->alt_name)) &&
1697                     expression_offset == offset)
1698                 {
1699                     return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
1700                 }
1701             }
1702         }
1703 
1704         bool is_in_return_register = false;
1705         ABISP abi_sp = frame.CalculateProcess()->GetABI();
1706         RegisterInfo return_register_info;
1707 
1708         if (abi_sp)
1709         {
1710             const char *return_register_name;
1711             const RegisterInfo *reg_info = nullptr;
1712             if (abi_sp->GetPointerReturnRegister(return_register_name) &&
1713                 reg == ConstString(return_register_name) &&
1714                 (reg_info = frame.GetRegisterContext()->GetRegisterInfoByName(return_register_name)))
1715             {
1716                 is_in_return_register = true;
1717                 return_register_info = *reg_info;
1718             }
1719         }
1720 
1721         const uint32_t current_inst = disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1722         if (current_inst == UINT32_MAX)
1723         {
1724             return ValueObjectSP();
1725         }
1726 
1727         ValueObjectSP source_path;
1728 
1729         for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii)
1730         {
1731             // This is not an exact algorithm, and it sacrifices accuracy for generality.
1732             // Recognizing "mov" and "ld" instructions –– and which are their source and
1733             // destination operands -- is something the disassembler should do for us.
1734             InstructionSP instruction_sp = disassembler.GetInstructionList().GetInstructionAtIndex(ii);
1735 
1736             if (is_in_return_register && instruction_sp->IsCall())
1737             {
1738                 llvm::SmallVector<Instruction::Operand, 1> operands;
1739                 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1)
1740                 {
1741                     continue;
1742                 }
1743 
1744                 switch (operands[0].m_type)
1745                 {
1746                 default:
1747                     break;
1748                 case Instruction::Operand::Type::Immediate:
1749                     {
1750                         SymbolContext sc;
1751                         Address load_address;
1752                         if (!frame.CalculateTarget()->ResolveLoadAddress(operands[0].m_immediate, load_address))
1753                         {
1754                             break;
1755                         }
1756                         frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(load_address, eSymbolContextFunction, sc);
1757                         if (!sc.function)
1758                         {
1759                             break;
1760                         }
1761                         CompilerType function_type = sc.function->GetCompilerType();
1762                         if (!function_type.IsFunctionType())
1763                         {
1764                             break;
1765                         }
1766                         CompilerType return_type = function_type.GetFunctionReturnType();
1767                         RegisterValue return_value;
1768                         if (!frame.GetRegisterContext()->ReadRegister(&return_register_info, return_value))
1769                         {
1770                             break;
1771                         }
1772                         std::string name_str(sc.function->GetName().AsCString("<unknown function>"));
1773                         name_str.append("()");
1774                         Address return_value_address(return_value.GetAsUInt64());
1775                         ValueObjectSP return_value_sp = ValueObjectMemory::Create(&frame, name_str.c_str(), return_value_address, return_type);
1776                         return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1777                     }
1778                 }
1779 
1780                 continue;
1781             }
1782 
1783             llvm::SmallVector<Instruction::Operand, 2> operands;
1784             if (!instruction_sp->ParseOperands(operands) || operands.size() != 2)
1785             {
1786                 continue;
1787             }
1788 
1789             Instruction::Operand *register_operand = nullptr;
1790             Instruction::Operand *origin_operand = nullptr;
1791             if (operands[0].m_type == Instruction::Operand::Type::Register &&
1792                 operands[0].m_clobbered == true &&
1793                 operands[0].m_register == reg)
1794             {
1795                 register_operand = &operands[0];
1796                 origin_operand = &operands[1];
1797             }
1798             else if (operands[1].m_type == Instruction::Operand::Type::Register &&
1799                      operands[1].m_clobbered == true &&
1800                      operands[1].m_register == reg)
1801             {
1802                 register_operand = &operands[1];
1803                 origin_operand = &operands[0];
1804             }
1805             else
1806             {
1807                 continue;
1808             }
1809 
1810             // We have an origin operand.  Can we track its value down?
1811             switch (origin_operand->m_type)
1812             {
1813             default:
1814                 break;
1815             case Instruction::Operand::Type::Register:
1816                 source_path = DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler, variables, instruction_sp->GetAddress());
1817                 break;
1818             case Instruction::Operand::Type::Dereference:
1819                 {
1820                     const Instruction::Operand &pointer = origin_operand->m_children[0];
1821                     switch (pointer.m_type)
1822                     {
1823                     default:
1824                         break;
1825                     case Instruction::Operand::Type::Register:
1826                         source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler, variables, instruction_sp->GetAddress());
1827                         if (source_path)
1828                         {
1829                             Error err;
1830                             source_path = source_path->Dereference(err);
1831                             if (!err.Success())
1832                             {
1833                                 source_path.reset();
1834                             }
1835                         }
1836                         break;
1837                     case Instruction::Operand::Type::Sum:
1838                         {
1839                             const Instruction::Operand *origin_register = nullptr;
1840                             const Instruction::Operand *origin_offset = nullptr;
1841                             if (pointer.m_children.size() != 2)
1842                             {
1843                                 break;
1844                             }
1845                             if (pointer.m_children[0].m_type == Instruction::Operand::Type::Register &&
1846                                 pointer.m_children[1].m_type == Instruction::Operand::Type::Immediate)
1847                             {
1848                                 origin_register = &pointer.m_children[0];
1849                                 origin_offset = &pointer.m_children[1];
1850                             }
1851                             else if (pointer.m_children[1].m_type == Instruction::Operand::Type::Register &&
1852                                      pointer.m_children[0].m_type == Instruction::Operand::Type::Immediate)
1853                             {
1854                                 origin_register = &pointer.m_children[1];
1855                                 origin_offset = &pointer.m_children[0];
1856                             }
1857                             if (!origin_register)
1858                             {
1859                                 break;
1860                             }
1861                             int64_t signed_origin_offset = origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate) : origin_offset->m_immediate;
1862                             source_path = DoGuessValueAt(frame, origin_register->m_register, signed_origin_offset, disassembler, variables, instruction_sp->GetAddress());
1863                             if (!source_path)
1864                             {
1865                                 break;
1866                             }
1867                             source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1868                             break;
1869                         }
1870                     }
1871                 }
1872             }
1873 
1874             if (source_path)
1875             {
1876                 return source_path;
1877             }
1878         }
1879 
1880         return ValueObjectSP();
1881     }
1882 }
1883 
1884 lldb::ValueObjectSP
1885 StackFrame::GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
1886 {
1887     TargetSP target_sp = CalculateTarget();
1888 
1889     const ArchSpec &target_arch = target_sp->GetArchitecture();
1890 
1891     Block *frame_block = GetFrameBlock();
1892 
1893     if (!frame_block)
1894     {
1895         return ValueObjectSP();
1896     }
1897 
1898     Function *function = frame_block->CalculateSymbolContextFunction();
1899     if (!function)
1900     {
1901         return ValueObjectSP();
1902     }
1903 
1904     AddressRange pc_range = function->GetAddressRange();
1905 
1906     if (GetFrameCodeAddress().GetFileAddress() < pc_range.GetBaseAddress().GetFileAddress() ||
1907         GetFrameCodeAddress().GetFileAddress() - pc_range.GetBaseAddress().GetFileAddress() >= pc_range.GetByteSize())
1908     {
1909         return ValueObjectSP();
1910     }
1911 
1912     ExecutionContext exe_ctx (shared_from_this());
1913 
1914     const char *plugin_name = nullptr;
1915     const char *flavor = nullptr;
1916     const bool prefer_file_cache = false;
1917     DisassemblerSP disassembler_sp = Disassembler::DisassembleRange (target_arch,
1918                                                                      plugin_name,
1919                                                                      flavor,
1920                                                                      exe_ctx,
1921                                                                      pc_range,
1922                                                                      prefer_file_cache);
1923 
1924     if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize())
1925     {
1926         return ValueObjectSP();
1927     }
1928 
1929     const bool get_file_globals = false;
1930     VariableList *variables = GetVariableList(get_file_globals);
1931 
1932     if (!variables)
1933     {
1934         return ValueObjectSP();
1935     }
1936 
1937     return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables, GetFrameCodeAddress());
1938 }
1939 
1940 TargetSP
1941 StackFrame::CalculateTarget ()
1942 {
1943     TargetSP target_sp;
1944     ThreadSP thread_sp(GetThread());
1945     if (thread_sp)
1946     {
1947         ProcessSP process_sp (thread_sp->CalculateProcess());
1948         if (process_sp)
1949             target_sp = process_sp->CalculateTarget();
1950     }
1951     return target_sp;
1952 }
1953 
1954 ProcessSP
1955 StackFrame::CalculateProcess ()
1956 {
1957     ProcessSP process_sp;
1958     ThreadSP thread_sp(GetThread());
1959     if (thread_sp)
1960         process_sp = thread_sp->CalculateProcess();
1961     return process_sp;
1962 }
1963 
1964 ThreadSP
1965 StackFrame::CalculateThread ()
1966 {
1967     return GetThread();
1968 }
1969 
1970 StackFrameSP
1971 StackFrame::CalculateStackFrame ()
1972 {
1973     return shared_from_this();
1974 }
1975 
1976 void
1977 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
1978 {
1979     exe_ctx.SetContext (shared_from_this());
1980 }
1981 
1982 void
1983 StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
1984 {
1985     if (strm == nullptr)
1986         return;
1987 
1988     GetSymbolContext(eSymbolContextEverything);
1989     ExecutionContext exe_ctx (shared_from_this());
1990     StreamString s;
1991 
1992     if (frame_marker)
1993         s.PutCString(frame_marker);
1994 
1995     const FormatEntity::Entry *frame_format = nullptr;
1996     Target *target = exe_ctx.GetTargetPtr();
1997     if (target)
1998         frame_format = target->GetDebugger().GetFrameFormat();
1999     if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false))
2000     {
2001         strm->Write(s.GetData(), s.GetSize());
2002     }
2003     else
2004     {
2005         Dump (strm, true, false);
2006         strm->EOL();
2007     }
2008 }
2009 
2010 void
2011 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
2012 {
2013     if (strm == nullptr)
2014         return;
2015 
2016     if (show_frame_index)
2017         strm->Printf("frame #%u: ", m_frame_index);
2018     ExecutionContext exe_ctx (shared_from_this());
2019     Target *target = exe_ctx.GetTargetPtr();
2020     strm->Printf("0x%0*" PRIx64 " ",
2021                  target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
2022                  GetFrameCodeAddress().GetLoadAddress(target));
2023     GetSymbolContext(eSymbolContextEverything);
2024     const bool show_module = true;
2025     const bool show_inline = true;
2026     const bool show_function_arguments = true;
2027     const bool show_function_name = true;
2028     m_sc.DumpStopContext (strm,
2029                           exe_ctx.GetBestExecutionContextScope(),
2030                           GetFrameCodeAddress(),
2031                           show_fullpaths,
2032                           show_module,
2033                           show_inline,
2034                           show_function_arguments,
2035                           show_function_name);
2036 }
2037 
2038 void
2039 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
2040 {
2041     std::lock_guard<std::recursive_mutex> guard(m_mutex);
2042     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
2043     m_variable_list_sp = prev_frame.m_variable_list_sp;
2044     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
2045     if (!m_disassembly.GetString().empty())
2046         m_disassembly.GetString().swap (m_disassembly.GetString());
2047 }
2048 
2049 void
2050 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
2051 {
2052     std::lock_guard<std::recursive_mutex> guard(m_mutex);
2053     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
2054     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
2055     assert (GetThread() == curr_frame.GetThread());
2056     m_frame_index = curr_frame.m_frame_index;
2057     m_concrete_frame_index = curr_frame.m_concrete_frame_index;
2058     m_reg_context_sp = curr_frame.m_reg_context_sp;
2059     m_frame_code_addr = curr_frame.m_frame_code_addr;
2060     assert (!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
2061     assert (!m_sc.module_sp || !curr_frame.m_sc.module_sp || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
2062     assert (m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
2063     assert (m_sc.function == nullptr || curr_frame.m_sc.function == nullptr || m_sc.function == curr_frame.m_sc.function);
2064     m_sc = curr_frame.m_sc;
2065     m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
2066     m_flags.Set (m_sc.GetResolvedMask());
2067     m_frame_base.Clear();
2068     m_frame_base_error.Clear();
2069 }
2070 
2071 bool
2072 StackFrame::HasCachedData () const
2073 {
2074     if (m_variable_list_sp)
2075         return true;
2076     if (m_variable_list_value_objects.GetSize() > 0)
2077         return true;
2078     if (!m_disassembly.GetString().empty())
2079         return true;
2080     return false;
2081 }
2082 
2083 bool
2084 StackFrame::GetStatus (Stream& strm,
2085                        bool show_frame_info,
2086                        bool show_source,
2087                        const char *frame_marker)
2088 {
2089 
2090     if (show_frame_info)
2091     {
2092         strm.Indent();
2093         DumpUsingSettingsFormat (&strm, frame_marker);
2094     }
2095 
2096     if (show_source)
2097     {
2098         ExecutionContext exe_ctx (shared_from_this());
2099         bool have_source = false, have_debuginfo = false;
2100         Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
2101         Target *target = exe_ctx.GetTargetPtr();
2102         if (target)
2103         {
2104             Debugger &debugger = target->GetDebugger();
2105             const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
2106             const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
2107             disasm_display = debugger.GetStopDisassemblyDisplay ();
2108 
2109             GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
2110             if (m_sc.comp_unit && m_sc.line_entry.IsValid())
2111             {
2112                 have_debuginfo = true;
2113                 if (source_lines_before > 0 || source_lines_after > 0)
2114                 {
2115                     size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
2116                                                                                       m_sc.line_entry.line,
2117                                                                                       source_lines_before,
2118                                                                                       source_lines_after,
2119                                                                                       "->",
2120                                                                                       &strm);
2121                     if (num_lines != 0)
2122                         have_source = true;
2123                     // TODO: Give here a one time warning if source file is missing.
2124                 }
2125             }
2126             switch (disasm_display)
2127             {
2128             case Debugger::eStopDisassemblyTypeNever:
2129                 break;
2130 
2131             case Debugger::eStopDisassemblyTypeNoDebugInfo:
2132                 if (have_debuginfo)
2133                     break;
2134                 LLVM_FALLTHROUGH;
2135 
2136             case Debugger::eStopDisassemblyTypeNoSource:
2137                 if (have_source)
2138                     break;
2139                 LLVM_FALLTHROUGH;
2140 
2141             case Debugger::eStopDisassemblyTypeAlways:
2142                 if (target)
2143                 {
2144                     const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
2145                     if (disasm_lines > 0)
2146                     {
2147                         const ArchSpec &target_arch = target->GetArchitecture();
2148                         AddressRange pc_range;
2149                         pc_range.GetBaseAddress() = GetFrameCodeAddress();
2150                         pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
2151                         const char *plugin_name = nullptr;
2152                         const char *flavor = nullptr;
2153                         Disassembler::Disassemble (target->GetDebugger(),
2154                                                    target_arch,
2155                                                    plugin_name,
2156                                                    flavor,
2157                                                    exe_ctx,
2158                                                    pc_range,
2159                                                    disasm_lines,
2160                                                    0,
2161                                                    Disassembler::eOptionMarkPCAddress,
2162                                                    strm);
2163                     }
2164                 }
2165                 break;
2166             }
2167         }
2168     }
2169     return true;
2170 }
2171