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