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);
311 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
313 if ((
m_flags.Get() & resolve_scope) != resolve_scope) {
314 uint32_t resolved = 0;
317 if (!
m_sc.target_sp) {
320 resolved |= eSymbolContextTarget;
337 m_flags.Set(resolve_scope | resolved);
341 if (
m_sc.module_sp) {
346 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
348 if (resolve_scope & eSymbolContextCompUnit) {
349 if (
m_flags.IsClear(eSymbolContextCompUnit)) {
351 resolved |= eSymbolContextCompUnit;
353 actual_resolve_scope |= eSymbolContextCompUnit;
357 if (resolve_scope & eSymbolContextFunction) {
358 if (
m_flags.IsClear(eSymbolContextFunction)) {
360 resolved |= eSymbolContextFunction;
362 actual_resolve_scope |= eSymbolContextFunction;
366 if (resolve_scope & eSymbolContextBlock) {
367 if (
m_flags.IsClear(eSymbolContextBlock)) {
369 resolved |= eSymbolContextBlock;
371 actual_resolve_scope |= eSymbolContextBlock;
375 if (resolve_scope & eSymbolContextSymbol) {
376 if (
m_flags.IsClear(eSymbolContextSymbol)) {
378 resolved |= eSymbolContextSymbol;
380 actual_resolve_scope |= eSymbolContextSymbol;
384 if (resolve_scope & eSymbolContextLineEntry) {
385 if (
m_flags.IsClear(eSymbolContextLineEntry)) {
386 if (
m_sc.line_entry.IsValid())
387 resolved |= eSymbolContextLineEntry;
389 actual_resolve_scope |= eSymbolContextLineEntry;
393 if (actual_resolve_scope) {
399 resolved |=
m_sc.module_sp->ResolveSymbolContextForAddress(
400 lookup_addr, actual_resolve_scope, sc);
404 if ((resolved & eSymbolContextCompUnit) &&
m_sc.comp_unit ==
nullptr)
406 if ((resolved & eSymbolContextFunction) &&
m_sc.function ==
nullptr)
408 if ((resolved & eSymbolContextBlock) &&
m_sc.block ==
nullptr)
410 if ((resolved & eSymbolContextSymbol) &&
m_sc.symbol ==
nullptr)
412 if ((resolved & eSymbolContextLineEntry) &&
413 !
m_sc.line_entry.IsValid()) {
415 m_sc.line_entry.ApplyFileMappings(
m_sc.target_sp);
422 if (
m_sc.target_sp) {
423 resolved |=
m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
424 lookup_addr, resolve_scope,
m_sc);
433 m_flags.Set(resolve_scope | resolved);
442 bool include_synthetic_vars,
445 (void)include_synthetic_vars;
447 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
455 const bool get_child_variables =
true;
456 const bool can_create =
true;
457 const bool stop_if_child_block_is_inlined_function =
true;
459 can_create, get_child_variables,
460 stop_if_child_block_is_inlined_function,
468 if (
m_flags.IsClear(eSymbolContextCompUnit))
471 if (
m_sc.comp_unit) {
473 m_sc.comp_unit->GetVariableList(
true));
485 if (
m_sc.module_sp) {
497 bool include_synthetic_vars,
498 bool must_have_valid_location) {
500 (void)include_synthetic_vars;
502 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
511 const bool can_create =
true;
512 const bool get_parent_variables =
true;
513 const bool stop_if_block_is_inlined_function =
true;
514 m_sc.block->AppendVariables(
515 can_create, get_parent_variables, stop_if_block_is_inlined_function,
516 [
this, must_have_valid_location](
Variable *v) {
517 return v->
IsInScope(
this) && (!must_have_valid_location ||
523 if (
m_sc.comp_unit && get_file_globals) {
525 m_sc.comp_unit->GetVariableList(
true));
526 if (global_variable_list_sp)
527 var_list_sp->AddVariables(global_variable_list_sp.get());
541 var_sp,
error, mode);
561 var_expr, std::move(*lex_or_err), shared_from_this(), use_dynamic, mode);
562 if (!tree_or_error) {
570 use_dynamic, options);
572 auto valobj_or_error = interpreter.
Evaluate(**tree_or_error);
573 if (!valobj_or_error) {
578 var_sp = (*valobj_or_error)->GetVariable();
579 return *valobj_or_error;
585 llvm::StringRef original_var_expr = var_expr;
590 if (var_expr.empty()) {
596 const bool check_ptr_vs_member =
598 const bool no_synth_child =
602 bool address_of =
false;
604 const bool get_file_globals =
true;
614 std::string var_expr_storage;
615 if (var_expr[0] ==
'*') {
617 var_expr = var_expr.drop_front();
618 }
else if (var_expr[0] ==
'&') {
620 var_expr = var_expr.drop_front();
623 size_t separator_idx = var_expr.find_first_of(
".-[=+~|&^%#@!/?,<>{}");
626 ConstString name_const_string(var_expr.substr(0, separator_idx));
628 var_sp = variable_list->
FindVariable(name_const_string,
false);
630 bool synthetically_added_instance_object =
false;
633 var_expr = var_expr.drop_front(name_const_string.
GetLength());
640 llvm::StringRef instance_name =
m_sc.GetInstanceName();
641 if (!instance_name.empty()) {
645 if (
Type *var_type = var_sp->GetType())
646 if (
auto compiler_type = var_type->GetForwardCompilerType())
647 if (!compiler_type.IsPointerType())
648 var_expr_storage =
".";
650 if (var_expr_storage.empty())
651 var_expr_storage =
"->";
652 var_expr_storage += var_expr;
653 var_expr = var_expr_storage;
654 synthetically_added_instance_object =
true;
662 for (
const VariableSP &variable_sp : *variable_list) {
665 if (!variable_sp->GetName().IsEmpty())
668 Type *var_type = variable_sp->GetType();
677 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
683 if (var_sp && !valobj_sp) {
690 "no variable named '{0}' found in this frame", name_const_string);
695 while (!var_expr.empty()) {
698 const char separator_type = var_expr[0];
699 bool expr_is_ptr =
false;
700 switch (separator_type) {
703 if (var_expr.size() >= 2 && var_expr[1] !=
'>')
708 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
711 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
712 synth_deref_sp && deref_error.
Success()) {
713 valobj_sp = std::move(synth_deref_sp);
715 if (!valobj_sp || deref_error.
Fail()) {
717 "Failed to dereference synthetic value: {0}", deref_error);
730 var_expr = var_expr.drop_front();
733 var_expr = var_expr.drop_front();
734 separator_idx = var_expr.find_first_of(
".-[");
735 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(
".-[")));
737 if (check_ptr_vs_member) {
741 const bool actual_is_ptr = valobj_sp->IsPointerType();
743 if (actual_is_ptr != expr_is_ptr) {
746 valobj_sp->GetExpressionPath(var_expr_path_strm);
749 "\"%s\" is a pointer and . was used to attempt to access "
750 "\"%s\". Did you mean \"%s->%s\"?",
752 var_expr_path_strm.
GetData(), var_expr.str().c_str());
755 "\"%s\" is not a pointer and -> was used to attempt to "
756 "access \"%s\". Did you mean \"%s.%s\"?",
758 var_expr_path_strm.
GetData(), var_expr.str().c_str());
762 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
763 if (!child_valobj_sp) {
764 if (!no_synth_child) {
765 child_valobj_sp = valobj_sp->GetSyntheticValue();
768 child_valobj_sp->GetChildMemberWithName(child_name);
771 if (no_synth_child || !child_valobj_sp) {
773 if (synthetically_added_instance_object) {
778 "no variable or instance variable named '%s' found in "
782 valobj_sp->GetExpressionPath(var_expr_path_strm);
785 "\"%s\" is not a member of \"(%s) %s\"",
787 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
791 "incomplete expression path after \"%s\" in \"%s\"",
793 original_var_expr.str().c_str());
799 synthetically_added_instance_object =
false;
801 var_expr = var_expr.drop_front(child_name.
GetLength());
804 child_valobj_sp->GetDynamicValue(use_dynamic));
805 if (dynamic_value_sp)
806 child_valobj_sp = dynamic_value_sp;
813 if (var_expr.size() <= 2) {
815 "invalid square bracket encountered after \"%s\" in \"%s\"",
816 var_expr_path_strm.
GetData(), var_expr.str().c_str());
821 var_expr = var_expr.drop_front();
822 long child_index = 0;
825 size_t end_pos = var_expr.find_first_of(
']');
826 if (end_pos == llvm::StringRef::npos) {
828 "missing closing square bracket in expression \"%s\"",
832 llvm::StringRef index_expr = var_expr.take_front(end_pos);
833 llvm::StringRef original_index_expr = index_expr;
835 var_expr = var_expr.drop_front(end_pos + 1);
837 if (index_expr.consumeInteger(0, child_index)) {
841 "invalid index expression \"%s\"", index_expr.str().c_str());
845 if (index_expr.empty()) {
848 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
854 if (!temp || deref_error.
Fail()) {
855 valobj_sp->GetExpressionPath(var_expr_path_strm);
857 "could not dereference \"(%s) %s\"",
858 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
864 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
872 valobj_sp->GetExpressionPath(var_expr_path_strm);
874 "could not get item 0 for \"(%s) %s\"",
875 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
883 bool is_incomplete_array =
false;
884 if (valobj_sp->IsPointerType()) {
885 bool is_objc_pointer =
true;
887 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
889 is_objc_pointer =
false;
890 else if (!valobj_sp->GetCompilerType().IsPointerType())
891 is_objc_pointer =
false;
893 if (no_synth_child && is_objc_pointer) {
895 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
897 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
901 }
else if (is_objc_pointer) {
906 || synthetic == valobj_sp)
909 valobj_sp->GetExpressionPath(var_expr_path_strm);
911 "\"(%s) %s\" is not an array type",
912 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
914 }
else if (
static_cast<uint32_t
>(child_index) >=
916 ->GetNumChildrenIgnoringErrors()
919 valobj_sp->GetExpressionPath(var_expr_path_strm);
921 "array index %ld is not valid for \"(%s) %s\"", child_index,
922 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
925 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
926 if (!child_valobj_sp) {
927 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 "array index %ld is not valid for \"(%s) %s\"", child_index,
930 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
936 valobj_sp->GetSyntheticArrayMember(child_index,
true);
937 if (!child_valobj_sp) {
938 valobj_sp->GetExpressionPath(var_expr_path_strm);
940 "failed to use pointer as array for index %ld for "
943 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
947 }
else if (valobj_sp->GetCompilerType().IsArrayType(
948 nullptr,
nullptr, &is_incomplete_array)) {
951 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
952 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
954 valobj_sp->GetSyntheticArrayMember(child_index,
true);
956 if (!child_valobj_sp) {
957 valobj_sp->GetExpressionPath(var_expr_path_strm);
959 "array index %ld is not valid for \"(%s) %s\"", child_index,
960 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
963 }
else if (valobj_sp->GetCompilerType().IsScalarType()) {
965 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
966 child_index, child_index,
true);
967 if (!child_valobj_sp) {
968 valobj_sp->GetExpressionPath(var_expr_path_strm);
970 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
971 child_index, child_index,
972 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
977 if (no_synth_child ||
979 || synthetic == valobj_sp)
982 valobj_sp->GetExpressionPath(var_expr_path_strm);
984 "\"(%s) %s\" is not an array type",
985 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
987 }
else if (
static_cast<uint32_t
>(child_index) >=
988 synthetic->GetNumChildrenIgnoringErrors()
990 valobj_sp->GetExpressionPath(var_expr_path_strm);
992 "array index %ld is not valid for \"(%s) %s\"", child_index,
993 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
996 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
997 if (!child_valobj_sp) {
998 valobj_sp->GetExpressionPath(var_expr_path_strm);
1000 "array index %ld is not valid for \"(%s) %s\"", child_index,
1001 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1002 var_expr_path_strm.
GetData());
1007 if (!child_valobj_sp) {
1014 child_valobj_sp->GetDynamicValue(use_dynamic));
1015 if (dynamic_value_sp)
1016 child_valobj_sp = dynamic_value_sp;
1024 if (index_expr.front() !=
'-') {
1026 "invalid range expression \"'%s'\"",
1027 original_index_expr.str().c_str());
1031 index_expr = index_expr.drop_front();
1032 long final_index = 0;
1033 if (index_expr.getAsInteger(0, final_index)) {
1035 "invalid range expression \"'%s'\"",
1036 original_index_expr.str().c_str());
1041 if (child_index > final_index) {
1042 long temp = child_index;
1043 child_index = final_index;
1047 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1054 if (!temp || deref_error.
Fail()) {
1055 valobj_sp->GetExpressionPath(var_expr_path_strm);
1057 "could not dereference \"(%s) %s\"",
1058 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1059 var_expr_path_strm.
GetData());
1064 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1071 valobj_sp->GetExpressionPath(var_expr_path_strm);
1073 "could not get item 0 for \"(%s) %s\"",
1074 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1075 var_expr_path_strm.
GetData());
1083 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index,
true);
1084 if (!child_valobj_sp) {
1085 valobj_sp->GetExpressionPath(var_expr_path_strm);
1087 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1088 final_index, valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1089 var_expr_path_strm.
GetData());
1092 if (!child_valobj_sp) {
1099 child_valobj_sp->GetDynamicValue(use_dynamic));
1100 if (dynamic_value_sp)
1101 child_valobj_sp = dynamic_value_sp;
1110 valobj_sp->GetExpressionPath(var_expr_path_strm);
1112 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1113 separator_type, var_expr_path_strm.
GetData(),
1114 var_expr.str().c_str());
1120 if (child_valobj_sp)
1121 valobj_sp = child_valobj_sp;
1126 if (!deref_valobj_sp && !no_synth_child) {
1127 if (
ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1129 deref_valobj_sp = synth_obj_sp->Dereference(
error);
1132 valobj_sp = deref_valobj_sp;
1133 }
else if (address_of) {
1135 valobj_sp = address_of_valobj_sp;
1142 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1145 "No frame base available for this historical stack frame.");
1150 if (
m_sc.function) {
1157 if (!
m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1161 llvm::Expected<Value> expr_value =
1162 m_sc.function->GetFrameBaseExpression().Evaluate(
1163 &exe_ctx,
nullptr, loclist_base_addr,
nullptr,
nullptr);
1178 return llvm::Error::success();
1182 if (!
m_sc.function) {
1189 return &
m_sc.function->GetFrameBaseExpression();
1193 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1204 return m_sc.line_entry.IsValid();
1217 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1222 true,
true,
nullptr);
1225 const uint32_t var_idx =
1227 const uint32_t num_variables = var_list->
GetSize();
1228 if (var_idx < num_variables) {
1242 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1250 if (
m_sc.block ==
nullptr)
1253 return m_sc.block->GetContainingInlinedBlock() !=
nullptr;
1269 return recognized_frame_sp->ShouldHide();
1278 if (
auto runtime_sp =
1280 return runtime_sp->GetLanguageSpecificData(
1286 const char *name =
nullptr;
1288 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1291 if (inlined_block) {
1299 if (name ==
nullptr) {
1304 if (name ==
nullptr) {
1313 const char *name =
nullptr;
1315 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1318 if (inlined_block) {
1326 if (name ==
nullptr) {
1331 if (name ==
nullptr) {
1361std::pair<const Instruction::Operand *, int64_t>
1364 switch (operand.
m_type) {
1370 return std::make_pair(
nullptr, 0);
1382 if (!immediate_child) {
1383 return std::make_pair(
nullptr, 0);
1391 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1392 GetBaseExplainingValue(*variable_child, register_context,
1394 if (!base_and_offset.first) {
1395 return std::make_pair(
nullptr, 0);
1398 base_and_offset.second -= immediate_child->
m_immediate;
1400 base_and_offset.second += immediate_child->
m_immediate;
1402 return base_and_offset;
1408 return std::make_pair(
nullptr, 0);
1412 return std::make_pair(
nullptr, 0);
1415 return std::make_pair(&operand, 0);
1417 return std::make_pair(
nullptr, 0);
1421 return std::make_pair(
nullptr, 0);
1424std::pair<const Instruction::Operand *, int64_t>
1429 return GetBaseExplainingValue(operand.
m_children[0], register_context,
1432 return std::make_pair(
nullptr, 0);
1439 const ArchSpec &target_arch = target_sp->GetArchitecture();
1445 const char *plugin_name =
nullptr;
1446 const char *flavor =
nullptr;
1447 const char *cpu =
nullptr;
1448 const char *features =
nullptr;
1449 const bool force_live_memory =
true;
1452 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1455 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1460 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1462 llvm::SmallVector<Instruction::Operand, 3> operands;
1464 if (!instruction_sp->ParseOperands(operands)) {
1470 if (!register_context_sp) {
1475 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1476 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1478 if (!base_and_offset.first) {
1482 switch (base_and_offset.first->m_type) {
1485 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1486 base_and_offset.second,
1488 auto c_type_system_or_err =
1490 if (
auto err = c_type_system_or_err.takeError()) {
1492 "Unable to guess value for given address: {0}");
1495 auto ts = *c_type_system_or_err;
1510 base_and_offset.second);
1525 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1529 if (parent->IsPointerOrReferenceType()) {
1533 for (
int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1541 int64_t child_offset = child_sp->GetByteOffset();
1542 int64_t child_size =
1543 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1545 if (offset >= child_offset && offset < (child_offset + child_size)) {
1546 return GetValueForOffset(frame, child_sp, offset - child_offset);
1564 if (!base->IsPointerOrReferenceType()) {
1577 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1579 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1580 int64_t index = offset / size;
1581 offset = offset % size;
1582 const bool can_create =
true;
1583 pointee = base->GetSyntheticArrayMember(index, can_create);
1586 if (!pointee ||
error.Fail()) {
1590 return GetValueForOffset(frame, pointee, offset);
1662 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1666 const uint32_t current_inst =
1672 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1680 if (instruction_sp->IsCall()) {
1686 const char *return_register_name;
1687 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1693 return_register_name);
1694 if (!return_register_info) {
1710 llvm::SmallVector<Instruction::Operand, 1> operands;
1711 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1715 switch (operands[0].m_type) {
1720 if (!
pc.GetModule())
1722 Address address(operands[0].m_immediate,
1723 pc.GetModule()->GetSectionList());
1724 if (!address.IsValid())
1727 address, eSymbolContextFunction, sc);
1741 std::string name_str(
1743 name_str.append(
"()");
1746 &frame, name_str, return_value_address, return_type);
1747 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1754 llvm::SmallVector<Instruction::Operand, 2> operands;
1755 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1764 if (clobbered_reg_matcher(operands[0])) {
1765 origin_operand = &operands[1];
1766 }
else if (clobbered_reg_matcher(operands[1])) {
1767 origin_operand = &operands[0];
1775 int64_t origin_offset = 0;
1777 if (
FetchRegOp(origin_register)(*origin_operand)) {
1778 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1779 variables, instruction_sp->GetAddress());
1782 FetchRegOp(origin_register))(*origin_operand) ||
1787 FetchImmOp(origin_offset)))(*origin_operand)) {
1789 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1790 variables, instruction_sp->GetAddress());
1794 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1810 const ArchSpec &target_arch = target_sp->GetArchitecture();
1829 const char *plugin_name =
nullptr;
1830 const char *flavor =
nullptr;
1831 const char *cpu =
nullptr;
1832 const char *features =
nullptr;
1833 const bool force_live_memory =
true;
1835 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1838 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1842 const bool get_file_globals =
false;
1846 const bool include_synthetic_vars =
false;
1854 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1867 if (!target_sp && !process_sp)
1875 const bool can_create =
true;
1876 const bool get_parent_variables =
true;
1877 const bool stop_if_block_is_inlined_function =
true;
1880 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1881 [
this](
Variable *v) { return v->IsInScope(this); },
1897 ProcessSP process_sp(thread_sp->CalculateProcess());
1899 target_sp = process_sp->CalculateTarget();
1908 process_sp = thread_sp->CalculateProcess();
1922 llvm::StringRef frame_marker) {
1937 const llvm::StringRef frame_marker) {
1938 if (strm ==
nullptr)
1949 frame_format = &format_entry;
1952 frame_format = &format_entry;
1956 Dump(strm,
true,
false);
1962 bool show_fullpaths) {
1963 if (strm ==
nullptr)
1966 if (show_frame_index)
1970 strm->
Printf(
"0x%0*" PRIx64
" ",
1975 const bool show_module =
true;
1976 const bool show_inline =
true;
1977 const bool show_function_arguments =
true;
1978 const bool show_function_name =
true;
1981 show_inline, show_function_arguments,
1982 show_function_name);
1986 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1998 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
2037 const llvm::StringRef frame_marker) {
2038 if (show_frame_info) {
2045 bool have_source =
false, have_debuginfo =
false;
2050 const uint32_t source_lines_before =
2052 const uint32_t source_lines_after =
2057 if (
m_sc.comp_unit ||
m_sc.line_entry.IsValid()) {
2058 have_debuginfo =
true;
2059 if (source_lines_before > 0 || source_lines_after > 0) {
2061 uint32_t start_line =
m_sc.line_entry.line;
2062 if (!start_line &&
m_sc.function) {
2063 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2068 source_file_sp, start_line,
m_sc.line_entry.column,
2069 source_lines_before, source_lines_after,
"->", &strm,
2074 if (!
m_sc.line_entry.line)
2075 strm <<
"note: This address is not associated with a specific line "
2076 "of code. This may be due to compiler optimizations.\n";
2079 switch (disasm_display) {
2096 if (disasm_lines > 0) {
2098 const char *plugin_name =
nullptr;
2099 const char *flavor =
nullptr;
2100 const bool mixed_source_and_assembly =
false;
2102 target->
GetDebugger(), target_arch, plugin_name, flavor,
2106 mixed_source_and_assembly, 0,
2118 auto process =
GetThread()->GetProcess();
2122 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2123 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.
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 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.
lldb::RegisterContextSP m_reg_context_sp
static char ID
LLVM RTTI support.
virtual lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
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(llvm::StringRef dil_input_expr, DILLexer lexer, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
#define LLDB_INVALID_ADDRESS
std::function< bool(const Instruction::Operand &)> MatchRegOp(const RegisterInfo &info)
std::function< bool(const Instruction::Operand &)> FetchRegOp(ConstString ®)
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 BuildSum(const Operand &lhs, const Operand &rhs)
static Operand BuildRegister(ConstString &r)
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