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