54#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem) << 1)
55#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
56#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
57#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
58#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
63 bool artificial,
bool behaves_like_zeroth_frame,
67 m_id(
pc, cfa, nullptr, thread_sp->GetProcess().get()),
81 if (sc_ptr !=
nullptr) {
90 addr_t pc,
bool behaves_like_zeroth_frame,
95 m_id(
pc, cfa, nullptr, thread_sp->GetProcess().get()),
102 if (sc_ptr !=
nullptr) {
107 if (reg_context_sp && !
m_sc.target_sp) {
108 m_sc.target_sp = reg_context_sp->CalculateTarget();
110 m_flags.Set(eSymbolContextTarget);
117 const Address &pc_addr,
bool behaves_like_zeroth_frame,
123 nullptr, thread_sp->GetProcess().get()),
130 if (sc_ptr !=
nullptr) {
135 if (!
m_sc.target_sp && reg_context_sp) {
136 m_sc.target_sp = reg_context_sp->CalculateTarget();
138 m_flags.Set(eSymbolContextTarget);
142 if (!
m_sc.module_sp ||
m_sc.module_sp != pc_module_sp) {
144 m_sc.module_sp = pc_module_sp;
145 m_flags.Set(eSymbolContextModule);
147 m_sc.module_sp.reset();
155 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
160 if (
m_id.GetSymbolContextScope()) {
168 if (scope ==
nullptr) {
170 if (
m_flags.IsClear(eSymbolContextSymbol))
187 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
194 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
196 m_id.SetSymbolContextScope(symbol_scope);
200 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
209 TargetSP target_sp(thread_sp->CalculateTarget());
211 const bool allow_section_end =
true;
217 m_sc.module_sp = module_sp;
218 m_flags.Set(eSymbolContextModule);
240 lookup_addr.
Slide(-1);
257 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
266 thread_sp->ClearStackFrames();
271 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
286 if (
m_sc.block ==
nullptr &&
m_flags.IsClear(eSymbolContextBlock))
290 Block *inline_block =
m_sc.block->GetContainingInlinedBlock();
299 return &
m_sc.function->GetBlock(
false);
308 if (!frame_block || !addr_block)
326 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
328 if ((
m_flags.Get() & resolve_scope) != resolve_scope) {
329 uint32_t resolved = 0;
332 if (!
m_sc.target_sp) {
335 resolved |= eSymbolContextTarget;
352 m_flags.Set(resolve_scope | resolved);
356 if (
m_sc.module_sp) {
361 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
363 if (resolve_scope & eSymbolContextCompUnit) {
364 if (
m_flags.IsClear(eSymbolContextCompUnit)) {
366 resolved |= eSymbolContextCompUnit;
368 actual_resolve_scope |= eSymbolContextCompUnit;
372 if (resolve_scope & eSymbolContextFunction) {
373 if (
m_flags.IsClear(eSymbolContextFunction)) {
375 resolved |= eSymbolContextFunction;
377 actual_resolve_scope |= eSymbolContextFunction;
381 if (resolve_scope & eSymbolContextBlock) {
382 if (
m_flags.IsClear(eSymbolContextBlock)) {
384 resolved |= eSymbolContextBlock;
386 actual_resolve_scope |= eSymbolContextBlock;
390 if (resolve_scope & eSymbolContextSymbol) {
391 if (
m_flags.IsClear(eSymbolContextSymbol)) {
393 resolved |= eSymbolContextSymbol;
395 actual_resolve_scope |= eSymbolContextSymbol;
399 if (resolve_scope & eSymbolContextLineEntry) {
400 if (
m_flags.IsClear(eSymbolContextLineEntry)) {
401 if (
m_sc.line_entry.IsValid())
402 resolved |= eSymbolContextLineEntry;
404 actual_resolve_scope |= eSymbolContextLineEntry;
408 if (actual_resolve_scope) {
414 resolved |=
m_sc.module_sp->ResolveSymbolContextForAddress(
415 lookup_addr, actual_resolve_scope, sc);
419 if ((resolved & eSymbolContextCompUnit) &&
m_sc.comp_unit ==
nullptr)
421 if ((resolved & eSymbolContextFunction) &&
m_sc.function ==
nullptr)
423 if ((resolved & eSymbolContextBlock) &&
m_sc.block ==
nullptr)
425 if ((resolved & eSymbolContextSymbol) &&
m_sc.symbol ==
nullptr)
427 if ((resolved & eSymbolContextLineEntry) &&
428 !
m_sc.line_entry.IsValid()) {
430 m_sc.line_entry.ApplyFileMappings(
m_sc.target_sp);
437 if (
m_sc.target_sp) {
438 resolved |=
m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
439 lookup_addr, resolve_scope,
m_sc);
448 m_flags.Set(resolve_scope | resolved);
457 bool include_synthetic_vars,
460 (void)include_synthetic_vars;
462 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
470 const bool get_child_variables =
true;
471 const bool can_create =
true;
472 const bool stop_if_child_block_is_inlined_function =
true;
474 can_create, get_child_variables,
475 stop_if_child_block_is_inlined_function,
483 if (
m_flags.IsClear(eSymbolContextCompUnit))
486 if (
m_sc.comp_unit) {
488 m_sc.comp_unit->GetVariableList(
true));
500 if (
m_sc.module_sp) {
512 bool include_synthetic_vars,
513 bool must_have_valid_location) {
515 (void)include_synthetic_vars;
517 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
526 const bool can_create =
true;
527 const bool get_parent_variables =
true;
528 const bool stop_if_block_is_inlined_function =
true;
529 m_sc.block->AppendVariables(
530 can_create, get_parent_variables, stop_if_block_is_inlined_function,
531 [
this, must_have_valid_location](
Variable *v) {
532 return v->
IsInScope(
this) && (!must_have_valid_location ||
538 if (
m_sc.comp_unit && get_file_globals) {
540 m_sc.comp_unit->GetVariableList(
true));
541 if (global_variable_list_sp)
542 var_list_sp->AddVariables(global_variable_list_sp.get());
556 var_sp,
error, mode);
578 exe_ctx, var_expr, std::move(*lex_or_err), use_dynamic, mode);
579 if (!tree_or_error) {
587 auto valobj_or_error = interpreter.
EvaluateTree(*tree_or_error);
588 if (!valobj_or_error) {
593 var_sp = (*valobj_or_error)->GetVariable();
594 return *valobj_or_error;
600 llvm::StringRef original_var_expr = var_expr;
605 if (var_expr.empty()) {
611 const bool check_ptr_vs_member =
613 const bool no_synth_child =
617 bool address_of =
false;
619 const bool get_file_globals =
true;
629 std::string var_expr_storage;
630 if (var_expr[0] ==
'*') {
632 var_expr = var_expr.drop_front();
633 }
else if (var_expr[0] ==
'&') {
635 var_expr = var_expr.drop_front();
638 size_t separator_idx = var_expr.find_first_of(
".-[=+~|&^%#@!/?,<>{}");
641 ConstString name_const_string(var_expr.substr(0, separator_idx));
643 var_sp = variable_list->
FindVariable(name_const_string,
false);
645 bool synthetically_added_instance_object =
false;
648 var_expr = var_expr.drop_front(name_const_string.
GetLength());
655 llvm::StringRef instance_name =
m_sc.GetInstanceName();
656 if (!instance_name.empty()) {
660 if (
Type *var_type = var_sp->GetType())
661 if (
auto compiler_type = var_type->GetForwardCompilerType())
662 if (!compiler_type.IsPointerType())
663 var_expr_storage =
".";
665 if (var_expr_storage.empty())
666 var_expr_storage =
"->";
667 var_expr_storage += var_expr;
668 var_expr = var_expr_storage;
669 synthetically_added_instance_object =
true;
677 for (
const VariableSP &variable_sp : *variable_list) {
680 if (!variable_sp->GetName().IsEmpty())
683 Type *var_type = variable_sp->GetType();
692 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
698 if (var_sp && !valobj_sp) {
705 "no variable named '{0}' found in this frame", name_const_string);
710 while (!var_expr.empty()) {
713 const char separator_type = var_expr[0];
714 bool expr_is_ptr =
false;
715 switch (separator_type) {
721 if (var_expr.size() < 2 || var_expr[1] !=
'>')
726 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
729 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
730 synth_deref_sp && deref_error.
Success()) {
731 valobj_sp = std::move(synth_deref_sp);
733 if (!valobj_sp || deref_error.
Fail()) {
735 "Failed to dereference synthetic value: {0}", deref_error);
748 var_expr = var_expr.drop_front();
751 var_expr = var_expr.drop_front();
752 separator_idx = var_expr.find_first_of(
".-[");
753 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(
".-[")));
755 if (check_ptr_vs_member) {
759 const bool actual_is_ptr = valobj_sp->IsPointerType();
761 if (actual_is_ptr != expr_is_ptr) {
764 valobj_sp->GetExpressionPath(var_expr_path_strm);
767 "\"%s\" is a pointer and . was used to attempt to access "
768 "\"%s\". Did you mean \"%s->%s\"?",
770 var_expr_path_strm.
GetData(), var_expr.str().c_str());
773 "\"%s\" is not a pointer and -> was used to attempt to "
774 "access \"%s\". Did you mean \"%s.%s\"?",
776 var_expr_path_strm.
GetData(), var_expr.str().c_str());
780 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
781 if (!child_valobj_sp) {
782 if (!no_synth_child) {
783 child_valobj_sp = valobj_sp->GetSyntheticValue();
786 child_valobj_sp->GetChildMemberWithName(child_name);
789 if (no_synth_child || !child_valobj_sp) {
791 if (synthetically_added_instance_object) {
796 "no variable or instance variable named '%s' found in "
800 valobj_sp->GetExpressionPath(var_expr_path_strm);
803 "\"%s\" is not a member of \"(%s) %s\"",
805 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
809 "incomplete expression path after \"%s\" in \"%s\"",
811 original_var_expr.str().c_str());
817 synthetically_added_instance_object =
false;
819 var_expr = var_expr.drop_front(child_name.
GetLength());
822 child_valobj_sp->GetDynamicValue(use_dynamic));
823 if (dynamic_value_sp)
824 child_valobj_sp = dynamic_value_sp;
831 if (var_expr.size() <= 2) {
833 "invalid square bracket encountered after \"%s\" in \"%s\"",
834 var_expr_path_strm.
GetData(), var_expr.str().c_str());
839 var_expr = var_expr.drop_front();
840 long child_index = 0;
843 size_t end_pos = var_expr.find_first_of(
']');
844 if (end_pos == llvm::StringRef::npos) {
846 "missing closing square bracket in expression \"%s\"",
850 llvm::StringRef index_expr = var_expr.take_front(end_pos);
851 llvm::StringRef original_index_expr = index_expr;
853 var_expr = var_expr.drop_front(end_pos + 1);
855 if (index_expr.consumeInteger(0, child_index)) {
859 "invalid index expression \"%s\"", index_expr.str().c_str());
863 if (index_expr.empty()) {
866 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
872 if (!temp || deref_error.
Fail()) {
873 valobj_sp->GetExpressionPath(var_expr_path_strm);
875 "could not dereference \"(%s) %s\"",
876 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
882 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
890 valobj_sp->GetExpressionPath(var_expr_path_strm);
892 "could not get item 0 for \"(%s) %s\"",
893 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
901 bool is_incomplete_array =
false;
902 if (valobj_sp->IsPointerType()) {
903 bool is_objc_pointer =
true;
905 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
907 is_objc_pointer =
false;
908 else if (!valobj_sp->GetCompilerType().IsPointerType())
909 is_objc_pointer =
false;
911 if (no_synth_child && is_objc_pointer) {
913 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
915 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
919 }
else if (is_objc_pointer) {
924 || synthetic == valobj_sp)
927 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 "\"(%s) %s\" is not an array type",
930 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
932 }
else if (
static_cast<uint32_t
>(child_index) >=
934 ->GetNumChildrenIgnoringErrors()
937 valobj_sp->GetExpressionPath(var_expr_path_strm);
939 "array index %ld is not valid for \"(%s) %s\"", child_index,
940 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
943 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
944 if (!child_valobj_sp) {
945 valobj_sp->GetExpressionPath(var_expr_path_strm);
947 "array index %ld is not valid for \"(%s) %s\"", child_index,
948 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
954 valobj_sp->GetSyntheticArrayMember(child_index,
true);
955 if (!child_valobj_sp) {
956 valobj_sp->GetExpressionPath(var_expr_path_strm);
958 "failed to use pointer as array for index %ld for "
961 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
965 }
else if (valobj_sp->GetCompilerType().IsArrayType(
966 nullptr,
nullptr, &is_incomplete_array)) {
969 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
970 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
972 valobj_sp->GetSyntheticArrayMember(child_index,
true);
974 if (!child_valobj_sp) {
975 valobj_sp->GetExpressionPath(var_expr_path_strm);
977 "array index %ld is not valid for \"(%s) %s\"", child_index,
978 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
981 }
else if (valobj_sp->GetCompilerType().IsScalarType()) {
983 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
984 child_index, child_index,
true);
985 if (!child_valobj_sp) {
986 valobj_sp->GetExpressionPath(var_expr_path_strm);
988 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
989 child_index, child_index,
990 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
995 if (no_synth_child ||
997 || synthetic == valobj_sp)
1000 valobj_sp->GetExpressionPath(var_expr_path_strm);
1002 "\"(%s) %s\" is not an array type",
1003 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1004 var_expr_path_strm.
GetData());
1005 }
else if (
static_cast<uint32_t
>(child_index) >=
1006 synthetic->GetNumChildrenIgnoringErrors()
1008 valobj_sp->GetExpressionPath(var_expr_path_strm);
1010 "array index %ld is not valid for \"(%s) %s\"", child_index,
1011 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1012 var_expr_path_strm.
GetData());
1014 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
1015 if (!child_valobj_sp) {
1016 valobj_sp->GetExpressionPath(var_expr_path_strm);
1018 "array index %ld is not valid for \"(%s) %s\"", child_index,
1019 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1020 var_expr_path_strm.
GetData());
1025 if (!child_valobj_sp) {
1032 child_valobj_sp->GetDynamicValue(use_dynamic));
1033 if (dynamic_value_sp)
1034 child_valobj_sp = dynamic_value_sp;
1042 if (index_expr.front() !=
'-') {
1044 "invalid range expression \"'%s'\"",
1045 original_index_expr.str().c_str());
1049 index_expr = index_expr.drop_front();
1050 long final_index = 0;
1051 if (index_expr.getAsInteger(0, final_index)) {
1053 "invalid range expression \"'%s'\"",
1054 original_index_expr.str().c_str());
1059 if (child_index > final_index) {
1060 long temp = child_index;
1061 child_index = final_index;
1065 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1072 if (!temp || deref_error.
Fail()) {
1073 valobj_sp->GetExpressionPath(var_expr_path_strm);
1075 "could not dereference \"(%s) %s\"",
1076 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1077 var_expr_path_strm.
GetData());
1082 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1089 valobj_sp->GetExpressionPath(var_expr_path_strm);
1091 "could not get item 0 for \"(%s) %s\"",
1092 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1093 var_expr_path_strm.
GetData());
1101 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index,
true);
1102 if (!child_valobj_sp) {
1103 valobj_sp->GetExpressionPath(var_expr_path_strm);
1105 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1106 final_index, valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1107 var_expr_path_strm.
GetData());
1110 if (!child_valobj_sp) {
1117 child_valobj_sp->GetDynamicValue(use_dynamic));
1118 if (dynamic_value_sp)
1119 child_valobj_sp = dynamic_value_sp;
1128 valobj_sp->GetExpressionPath(var_expr_path_strm);
1130 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1131 separator_type, var_expr_path_strm.
GetData(),
1132 var_expr.str().c_str());
1138 if (child_valobj_sp)
1139 valobj_sp = child_valobj_sp;
1144 if (!deref_valobj_sp && !no_synth_child) {
1145 if (
ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1147 deref_valobj_sp = synth_obj_sp->Dereference(
error);
1150 valobj_sp = deref_valobj_sp;
1151 }
else if (address_of) {
1153 valobj_sp = address_of_valobj_sp;
1160 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1163 "No frame base available for this historical stack frame.");
1168 if (
m_sc.function) {
1175 if (!
m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1179 llvm::Expected<Value> expr_value =
1180 m_sc.function->GetFrameBaseExpression().Evaluate(
1181 &exe_ctx,
nullptr, loclist_base_addr,
nullptr,
nullptr);
1196 return llvm::Error::success();
1200 if (!
m_sc.function) {
1207 return &
m_sc.function->GetFrameBaseExpression();
1211 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1222 return m_sc.line_entry.IsValid();
1235 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1240 true,
true,
nullptr);
1243 const uint32_t var_idx =
1245 const uint32_t num_variables = var_list->
GetSize();
1246 if (var_idx < num_variables) {
1260 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1268 if (
m_sc.block ==
nullptr)
1271 return m_sc.block->GetContainingInlinedBlock() !=
nullptr;
1287 return recognized_frame_sp->ShouldHide();
1296 if (
auto runtime_sp =
1298 return runtime_sp->GetLanguageSpecificData(
1304 const char *name =
nullptr;
1306 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1309 if (inlined_block) {
1317 if (name ==
nullptr) {
1322 if (name ==
nullptr) {
1331 const char *name =
nullptr;
1333 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1336 if (inlined_block) {
1344 if (name ==
nullptr) {
1349 if (name ==
nullptr) {
1379std::pair<const Instruction::Operand *, int64_t>
1382 switch (operand.
m_type) {
1388 return std::make_pair(
nullptr, 0);
1400 if (!immediate_child) {
1401 return std::make_pair(
nullptr, 0);
1409 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1410 GetBaseExplainingValue(*variable_child, register_context,
1412 if (!base_and_offset.first) {
1413 return std::make_pair(
nullptr, 0);
1416 base_and_offset.second -= immediate_child->
m_immediate;
1418 base_and_offset.second += immediate_child->
m_immediate;
1420 return base_and_offset;
1426 return std::make_pair(
nullptr, 0);
1430 return std::make_pair(
nullptr, 0);
1433 return std::make_pair(&operand, 0);
1435 return std::make_pair(
nullptr, 0);
1439 return std::make_pair(
nullptr, 0);
1442std::pair<const Instruction::Operand *, int64_t>
1447 return GetBaseExplainingValue(operand.
m_children[0], register_context,
1450 return std::make_pair(
nullptr, 0);
1457 const ArchSpec &target_arch = target_sp->GetArchitecture();
1463 const char *plugin_name =
nullptr;
1464 const char *flavor =
nullptr;
1465 const char *cpu =
nullptr;
1466 const char *features =
nullptr;
1467 const bool force_live_memory =
true;
1470 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1473 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1478 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1480 llvm::SmallVector<Instruction::Operand, 3> operands;
1482 if (!instruction_sp->ParseOperands(operands)) {
1488 if (!register_context_sp) {
1493 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1494 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1496 if (!base_and_offset.first) {
1500 switch (base_and_offset.first->m_type) {
1503 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1504 base_and_offset.second,
1506 auto c_type_system_or_err =
1508 if (
auto err = c_type_system_or_err.takeError()) {
1510 "Unable to guess value for given address: {0}");
1513 auto ts = *c_type_system_or_err;
1528 base_and_offset.second);
1543 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1547 if (parent->IsPointerOrReferenceType()) {
1551 for (
int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1559 int64_t child_offset = child_sp->GetByteOffset();
1560 int64_t child_size =
1561 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1563 if (offset >= child_offset && offset < (child_offset + child_size)) {
1564 return GetValueForOffset(frame, child_sp, offset - child_offset);
1582 if (!base->IsPointerOrReferenceType()) {
1595 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1597 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1598 int64_t index = offset / size;
1599 offset = offset % size;
1600 const bool can_create =
true;
1601 pointee = base->GetSyntheticArrayMember(index, can_create);
1604 if (!pointee ||
error.Fail()) {
1608 return GetValueForOffset(frame, pointee, offset);
1680 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1684 const uint32_t current_inst =
1690 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1698 if (instruction_sp->IsCall()) {
1704 const char *return_register_name;
1705 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1711 return_register_name);
1712 if (!return_register_info) {
1728 llvm::SmallVector<Instruction::Operand, 1> operands;
1729 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1733 switch (operands[0].m_type) {
1738 if (!
pc.GetModule())
1740 Address address(operands[0].m_immediate,
1741 pc.GetModule()->GetSectionList());
1742 if (!address.IsValid())
1745 address, eSymbolContextFunction, sc);
1759 std::string name_str(
1761 name_str.append(
"()");
1764 &frame, name_str, return_value_address, return_type);
1765 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1772 llvm::SmallVector<Instruction::Operand, 2> operands;
1773 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1782 if (clobbered_reg_matcher(operands[0])) {
1783 origin_operand = &operands[1];
1784 }
else if (clobbered_reg_matcher(operands[1])) {
1785 origin_operand = &operands[0];
1792 std::string origin_register;
1793 int64_t origin_offset = 0;
1795 if (
FetchRegOp(origin_register)(*origin_operand)) {
1796 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1797 variables, instruction_sp->GetAddress());
1800 FetchRegOp(origin_register))(*origin_operand) ||
1805 FetchImmOp(origin_offset)))(*origin_operand)) {
1807 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1808 variables, instruction_sp->GetAddress());
1812 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1829 const ArchSpec &target_arch = target_sp->GetArchitecture();
1848 const char *plugin_name =
nullptr;
1849 const char *flavor =
nullptr;
1850 const char *cpu =
nullptr;
1851 const char *features =
nullptr;
1852 const bool force_live_memory =
true;
1854 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1857 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1861 const bool get_file_globals =
false;
1865 const bool include_synthetic_vars =
false;
1873 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1886 if (!target_sp && !process_sp)
1894 const bool can_create =
true;
1895 const bool get_parent_variables =
true;
1896 const bool stop_if_block_is_inlined_function =
true;
1899 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1900 [
this](
Variable *v) { return v->IsInScope(this); },
1916 ProcessSP process_sp(thread_sp->CalculateProcess());
1918 target_sp = process_sp->CalculateTarget();
1927 process_sp = thread_sp->CalculateProcess();
1941 llvm::StringRef frame_marker) {
1956 const llvm::StringRef frame_marker) {
1957 if (strm ==
nullptr)
1968 frame_format = &format_entry;
1971 frame_format = &format_entry;
1975 Dump(strm,
true,
false);
1981 bool show_fullpaths) {
1982 if (strm ==
nullptr)
1985 if (show_frame_index)
1989 strm->
Printf(
"0x%0*" PRIx64
" ",
1994 const bool show_module =
true;
1995 const bool show_inline =
true;
1996 const bool show_function_arguments =
true;
1997 const bool show_function_name =
true;
2000 show_inline, show_function_arguments,
2001 show_function_name);
2005 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
2017 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
2056 const llvm::StringRef frame_marker) {
2057 if (show_frame_info) {
2064 bool have_source =
false, have_debuginfo =
false;
2069 const uint32_t source_lines_before =
2071 const uint32_t source_lines_after =
2076 if (
m_sc.comp_unit ||
m_sc.line_entry.IsValid()) {
2077 have_debuginfo =
true;
2078 if (source_lines_before > 0 || source_lines_after > 0) {
2080 uint32_t start_line =
m_sc.line_entry.line;
2081 if (!start_line &&
m_sc.function) {
2082 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2087 source_file_sp, start_line,
m_sc.line_entry.column,
2088 source_lines_before, source_lines_after,
"->", &strm,
2093 if (!
m_sc.line_entry.line)
2094 strm <<
"note: This address is not associated with a specific line "
2095 "of code. This may be due to compiler optimizations.\n";
2098 switch (disasm_display) {
2115 if (disasm_lines > 0) {
2117 const char *plugin_name =
nullptr;
2118 const char *flavor =
nullptr;
2119 const bool mixed_source_and_assembly =
false;
2121 target->
GetDebugger(), target_arch, plugin_name, flavor,
2125 mixed_source_and_assembly, 0,
2137 auto process =
GetThread()->GetProcess();
2141 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2142 auto new_generation = manager.GetGeneration();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
#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.
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
bool SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, AddressClass addr_class=AddressClass::eInvalid, bool allow_section_end=false)
bool Slide(int64_t offset)
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
bool IsValid() const
Check if the object state is valid.
Block * CalculateSymbolContextBlock() const
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
uint32_t GetMaximumOpcodeByteSize() const
A class that describes a single lexical block.
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Function * CalculateSymbolContextFunction() override
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.
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.
A class that describes a compilation unit.
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.
bool IsAnonymousType() const
bool IsFunctionType() const
CompilerType GetFunctionReturnType() const
A uniqued constant string class.
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.
uint64_t GetDisassemblyLineCount() const
FormatEntity::Entry GetFrameFormatUnique() const
uint64_t GetStopSourceLineCount(bool before) const
FormatEntity::Entry GetFrameFormat() const
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
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.
CompilerType GetCompilerType()
bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, AddressRange &range)
ConstString GetName() const
const Mangled & GetMangled() const
AddressRanges GetAddressRanges()
ConstString GetDisplayName() const
A class that describes information for an inlined function.
ConstString GetDisplayName() const
ConstString GetName() const
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_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.
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
lldb::VariableListSP m_variable_list_sp
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
lldb::ThreadSP GetThread() const
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...
@ eExpressionPathOptionCheckPtrVsMember
@ eExpressionPathOptionsInspectAnonymousUnions
@ eExpressionPathOptionsAllowDirectIVarAccess
@ eExpressionPathOptionsNoSyntheticChildren
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.
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
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.
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
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
static char ID
LLVM RTTI support.
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.
@ Regular
A regular stack frame with access to registers and local variables.
@ Synthetic
An synthetic stack frame (e.g.
uint32_t m_concrete_frame_index
bool m_behaves_like_zeroth_frame
Whether this frame behaves like the zeroth frame, in the sense that its pc value might not immediatel...
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:
bool HasCachedData() const
StreamString m_disassembly
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.
Status m_frame_base_error
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
virtual lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
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
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
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.
Status GetFrameVariableError(StackFrame &frame)
Get an error that describes why variables might be missing for a given symbol context.
ConstString GetName() const
ConstString GetDisplayName() const
const char * GetDisassemblyFeatures() const
const char * GetDisassemblyCPU() const
bool GetUseDIL(ExecutionContext *exe_ctx) const
SourceManager & GetSourceManager()
Debugger & GetDebugger() const
const ArchSpec & GetArchitecture() const
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, 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)
bool LocationIsValidForFrame(StackFrame *frame)
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.
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.
llvm::Expected< lldb::ValueObjectSP > EvaluateTree(const ASTNodeUP &tree)
Evaluate an ASTNode tree.
#define LLDB_INVALID_ADDRESS
std::function< bool(const Instruction::Operand &)> FetchRegOp(std::string ®)
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.
NonNullSharedPtr< lldb_private::SupportFile > SupportFileNSP
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
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