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