47#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem) << 1)
48#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
49#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
50#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
51#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
56 bool behaves_like_zeroth_frame,
58 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
59 m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
60 m_id(
pc, cfa, nullptr), m_frame_code_addr(
pc), m_sc(), m_flags(),
61 m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
62 m_stack_frame_kind(kind),
63 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
64 m_variable_list_sp(), m_variable_list_value_objects(),
65 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
69 if (IsHistorical() && !m_cfa_is_valid) {
70 m_id.SetCFA(m_frame_index);
73 if (sc_ptr !=
nullptr) {
75 m_flags.Set(m_sc.GetResolvedMask());
81 const RegisterContextSP ®_context_sp,
addr_t cfa,
82 addr_t pc,
bool behaves_like_zeroth_frame,
84 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
85 m_concrete_frame_index(unwind_frame_index),
86 m_reg_context_sp(reg_context_sp), m_id(
pc, cfa, nullptr),
87 m_frame_code_addr(
pc), m_sc(), m_flags(), m_frame_base(),
88 m_frame_base_error(), m_cfa_is_valid(true),
90 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
91 m_variable_list_sp(), m_variable_list_value_objects(),
92 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
93 if (sc_ptr !=
nullptr) {
95 m_flags.Set(m_sc.GetResolvedMask());
98 if (reg_context_sp && !m_sc.target_sp) {
99 m_sc.
target_sp = reg_context_sp->CalculateTarget();
101 m_flags.Set(eSymbolContextTarget);
107 const RegisterContextSP ®_context_sp,
addr_t cfa,
108 const Address &pc_addr,
bool behaves_like_zeroth_frame,
110 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
111 m_concrete_frame_index(unwind_frame_index),
112 m_reg_context_sp(reg_context_sp),
113 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
115 m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
116 m_frame_base_error(), m_cfa_is_valid(true),
117 m_stack_frame_kind(
StackFrame::Kind::Regular),
118 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
119 m_variable_list_sp(), m_variable_list_value_objects(),
120 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
121 if (sc_ptr !=
nullptr) {
123 m_flags.Set(m_sc.GetResolvedMask());
126 if (!m_sc.target_sp && reg_context_sp) {
127 m_sc.
target_sp = reg_context_sp->CalculateTarget();
129 m_flags.Set(eSymbolContextTarget);
132 ModuleSP pc_module_sp(pc_addr.
GetModule());
133 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
135 m_sc.module_sp = pc_module_sp;
136 m_flags.Set(eSymbolContextModule);
138 m_sc.module_sp.reset();
146 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
159 if (scope ==
nullptr) {
178 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
185 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
191 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
200 TargetSP target_sp(thread_sp->CalculateTarget());
202 const bool allow_section_end =
true;
248 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
257 thread_sp->ClearStackFrames();
262 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
301 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
303 if ((
m_flags.
Get() & resolve_scope) != resolve_scope) {
310 resolved |= eSymbolContextTarget;
329 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
331 if (resolve_scope & eSymbolContextCompUnit) {
334 resolved |= eSymbolContextCompUnit;
336 actual_resolve_scope |= eSymbolContextCompUnit;
340 if (resolve_scope & eSymbolContextFunction) {
343 resolved |= eSymbolContextFunction;
345 actual_resolve_scope |= eSymbolContextFunction;
349 if (resolve_scope & eSymbolContextBlock) {
352 resolved |= eSymbolContextBlock;
354 actual_resolve_scope |= eSymbolContextBlock;
358 if (resolve_scope & eSymbolContextSymbol) {
361 resolved |= eSymbolContextSymbol;
363 actual_resolve_scope |= eSymbolContextSymbol;
367 if (resolve_scope & eSymbolContextLineEntry) {
370 resolved |= eSymbolContextLineEntry;
372 actual_resolve_scope |= eSymbolContextLineEntry;
376 if (actual_resolve_scope) {
383 lookup_addr, actual_resolve_scope, sc);
387 if ((resolved & eSymbolContextCompUnit) &&
m_sc.
comp_unit ==
nullptr)
389 if ((resolved & eSymbolContextFunction) &&
m_sc.
function ==
nullptr)
391 if ((resolved & eSymbolContextBlock) &&
m_sc.
block ==
nullptr)
393 if ((resolved & eSymbolContextSymbol) &&
m_sc.
symbol ==
nullptr)
395 if ((resolved & eSymbolContextLineEntry) &&
406 resolved |=
m_sc.
target_sp->GetImages().ResolveSymbolContextForAddress(
407 lookup_addr, resolve_scope,
m_sc);
426 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
434 const bool get_child_variables =
true;
435 const bool can_create =
true;
436 const bool stop_if_child_block_is_inlined_function =
true;
438 stop_if_child_block_is_inlined_function,
451 VariableListSP global_variable_list_sp(
476 bool must_have_valid_location) {
477 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
480 return VariableListSP();
486 const bool can_create =
true;
487 const bool get_parent_variables =
true;
488 const bool stop_if_block_is_inlined_function =
true;
490 can_create, get_parent_variables, stop_if_block_is_inlined_function,
491 [
this, must_have_valid_location](
Variable *v) {
492 return v->
IsInScope(
this) && (!must_have_valid_location ||
499 VariableListSP global_variable_list_sp(
501 if (global_variable_list_sp)
502 var_list_sp->AddVariables(global_variable_list_sp.get());
511 llvm::StringRef original_var_expr = var_expr;
514 return ValueObjectSP();
516 if (var_expr.empty()) {
517 error.SetErrorStringWithFormat(
"invalid variable path '%s'",
518 var_expr.str().c_str());
519 return ValueObjectSP();
522 const bool check_ptr_vs_member =
524 const bool no_fragile_ivar =
526 const bool no_synth_child =
532 bool address_of =
false;
533 ValueObjectSP valobj_sp;
534 const bool get_file_globals =
true;
541 return ValueObjectSP();
544 std::string var_expr_storage;
545 if (var_expr[0] ==
'*') {
547 var_expr = var_expr.drop_front();
548 }
else if (var_expr[0] ==
'&') {
550 var_expr = var_expr.drop_front();
553 size_t separator_idx = var_expr.find_first_of(
".-[=+~|&^%#@!/?,<>{}");
556 ConstString name_const_string(var_expr.substr(0, separator_idx));
558 var_sp = variable_list->
FindVariable(name_const_string,
false);
560 bool synthetically_added_instance_object =
false;
563 var_expr = var_expr.drop_front(name_const_string.
GetLength());
571 if (!instance_var_name.empty()) {
575 if (
Type *var_type = var_sp->GetType())
576 if (
auto compiler_type = var_type->GetForwardCompilerType())
577 if (!compiler_type.IsPointerType())
578 var_expr_storage =
".";
580 if (var_expr_storage.empty())
581 var_expr_storage =
"->";
582 var_expr_storage += var_expr;
583 var_expr = var_expr_storage;
584 synthetically_added_instance_object =
true;
592 for (
const VariableSP &variable_sp : *variable_list) {
595 if (!variable_sp->GetName().IsEmpty())
598 Type *var_type = variable_sp->GetType();
607 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string,
true);
613 if (var_sp && !valobj_sp) {
619 error.SetErrorStringWithFormat(
"no variable named '%s' found in this frame",
621 return ValueObjectSP();
625 while (!var_expr.empty()) {
627 ValueObjectSP child_valobj_sp;
628 const char separator_type = var_expr[0];
629 bool expr_is_ptr =
false;
630 switch (separator_type) {
633 if (var_expr.size() >= 2 && var_expr[1] !=
'>')
634 return ValueObjectSP();
636 if (no_fragile_ivar) {
640 valobj_sp->GetCompilerType().GetTypeInfo(
nullptr);
641 if ((pointer_type_flags & eTypeIsObjC) &&
642 (pointer_type_flags & eTypeIsPointer)) {
645 return ValueObjectSP();
651 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
653 if (valobj_sp->GetCompilerType().IsReferenceType()) {
654 valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error);
656 error.SetErrorStringWithFormatv(
657 "Failed to dereference reference type: %s", deref_error);
658 return ValueObjectSP();
662 valobj_sp = valobj_sp->Dereference(deref_error);
664 error.SetErrorStringWithFormatv(
665 "Failed to dereference sythetic value: {0}", deref_error);
666 return ValueObjectSP();
670 error.SetErrorString(
"Failed to dereference sythetic value");
671 return ValueObjectSP();
676 var_expr = var_expr.drop_front();
679 var_expr = var_expr.drop_front();
680 separator_idx = var_expr.find_first_of(
".-[");
681 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(
".-[")));
683 if (check_ptr_vs_member) {
687 const bool actual_is_ptr = valobj_sp->IsPointerType();
689 if (actual_is_ptr != expr_is_ptr) {
692 valobj_sp->GetExpressionPath(var_expr_path_strm);
694 error.SetErrorStringWithFormat(
695 "\"%s\" is a pointer and . was used to attempt to access "
696 "\"%s\". Did you mean \"%s->%s\"?",
698 var_expr_path_strm.
GetData(), var_expr.str().c_str());
700 error.SetErrorStringWithFormat(
701 "\"%s\" is not a pointer and -> was used to attempt to "
702 "access \"%s\". Did you mean \"%s.%s\"?",
704 var_expr_path_strm.
GetData(), var_expr.str().c_str());
705 return ValueObjectSP();
708 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name,
true);
709 if (!child_valobj_sp) {
710 if (!no_synth_child) {
711 child_valobj_sp = valobj_sp->GetSyntheticValue();
714 child_valobj_sp->GetChildMemberWithName(child_name,
true);
717 if (no_synth_child || !child_valobj_sp) {
719 if (synthetically_added_instance_object) {
723 error.SetErrorStringWithFormat(
724 "no variable or instance variable named '%s' found in "
728 valobj_sp->GetExpressionPath(var_expr_path_strm);
730 error.SetErrorStringWithFormat(
731 "\"%s\" is not a member of \"(%s) %s\"",
733 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
736 error.SetErrorStringWithFormat(
737 "incomplete expression path after \"%s\" in \"%s\"",
739 original_var_expr.str().c_str());
742 return ValueObjectSP();
745 synthetically_added_instance_object =
false;
747 var_expr = var_expr.drop_front(child_name.
GetLength());
749 ValueObjectSP dynamic_value_sp(
750 child_valobj_sp->GetDynamicValue(use_dynamic));
751 if (dynamic_value_sp)
752 child_valobj_sp = dynamic_value_sp;
759 if (var_expr.size() <= 2) {
760 error.SetErrorStringWithFormat(
761 "invalid square bracket encountered after \"%s\" in \"%s\"",
762 var_expr_path_strm.
GetData(), var_expr.str().c_str());
763 return ValueObjectSP();
767 var_expr = var_expr.drop_front();
768 long child_index = 0;
771 size_t end_pos = var_expr.find_first_of(
']');
772 if (end_pos == llvm::StringRef::npos) {
773 error.SetErrorStringWithFormat(
774 "missing closing square bracket in expression \"%s\"",
776 return ValueObjectSP();
778 llvm::StringRef index_expr = var_expr.take_front(end_pos);
779 llvm::StringRef original_index_expr = index_expr;
781 var_expr = var_expr.drop_front(end_pos + 1);
783 if (index_expr.consumeInteger(0, child_index)) {
786 error.SetErrorStringWithFormat(
"invalid index expression \"%s\"",
787 index_expr.str().c_str());
788 return ValueObjectSP();
791 if (index_expr.empty()) {
794 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
799 ValueObjectSP temp(valobj_sp->Dereference(
error));
801 valobj_sp->GetExpressionPath(var_expr_path_strm);
802 error.SetErrorStringWithFormat(
803 "could not dereference \"(%s) %s\"",
804 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
806 return ValueObjectSP();
810 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
817 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0,
true));
819 valobj_sp->GetExpressionPath(var_expr_path_strm);
820 error.SetErrorStringWithFormat(
821 "could not get item 0 for \"(%s) %s\"",
822 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
824 return ValueObjectSP();
830 bool is_incomplete_array =
false;
831 if (valobj_sp->IsPointerType()) {
832 bool is_objc_pointer =
true;
834 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
836 is_objc_pointer =
false;
837 else if (!valobj_sp->GetCompilerType().IsPointerType())
838 is_objc_pointer =
false;
840 if (no_synth_child && is_objc_pointer) {
841 error.SetErrorStringWithFormat(
842 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
844 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
847 return ValueObjectSP();
848 }
else if (is_objc_pointer) {
851 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
853 || synthetic == valobj_sp)
856 valobj_sp->GetExpressionPath(var_expr_path_strm);
857 error.SetErrorStringWithFormat(
858 "\"(%s) %s\" is not an array type",
859 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
862 static_cast<uint32_t>(child_index) >=
864 ->GetNumChildren() ) {
865 valobj_sp->GetExpressionPath(var_expr_path_strm);
866 error.SetErrorStringWithFormat(
867 "array index %ld is not valid for \"(%s) %s\"", child_index,
868 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
871 child_valobj_sp = synthetic->GetChildAtIndex(child_index,
true);
872 if (!child_valobj_sp) {
873 valobj_sp->GetExpressionPath(var_expr_path_strm);
874 error.SetErrorStringWithFormat(
875 "array index %ld is not valid for \"(%s) %s\"", child_index,
876 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
882 valobj_sp->GetSyntheticArrayMember(child_index,
true);
883 if (!child_valobj_sp) {
884 valobj_sp->GetExpressionPath(var_expr_path_strm);
885 error.SetErrorStringWithFormat(
886 "failed to use pointer as array for index %ld for "
889 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
893 }
else if (valobj_sp->GetCompilerType().IsArrayType(
894 nullptr,
nullptr, &is_incomplete_array)) {
897 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index,
true);
898 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
900 valobj_sp->GetSyntheticArrayMember(child_index,
true);
902 if (!child_valobj_sp) {
903 valobj_sp->GetExpressionPath(var_expr_path_strm);
904 error.SetErrorStringWithFormat(
905 "array index %ld is not valid for \"(%s) %s\"", child_index,
906 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
909 }
else if (valobj_sp->GetCompilerType().IsScalarType()) {
911 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
912 child_index, child_index,
true);
913 if (!child_valobj_sp) {
914 valobj_sp->GetExpressionPath(var_expr_path_strm);
915 error.SetErrorStringWithFormat(
916 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
917 child_index, child_index,
918 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
922 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
923 if (no_synth_child ||
925 || synthetic == valobj_sp)
928 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 error.SetErrorStringWithFormat(
930 "\"(%s) %s\" is not an array type",
931 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
934 static_cast<uint32_t>(child_index) >=
936 ->GetNumChildren() ) {
937 valobj_sp->GetExpressionPath(var_expr_path_strm);
938 error.SetErrorStringWithFormat(
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,
true);
944 if (!child_valobj_sp) {
945 valobj_sp->GetExpressionPath(var_expr_path_strm);
946 error.SetErrorStringWithFormat(
947 "array index %ld is not valid for \"(%s) %s\"", child_index,
948 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
954 if (!child_valobj_sp) {
956 return ValueObjectSP();
960 ValueObjectSP dynamic_value_sp(
961 child_valobj_sp->GetDynamicValue(use_dynamic));
962 if (dynamic_value_sp)
963 child_valobj_sp = dynamic_value_sp;
971 if (index_expr.front() !=
'-') {
972 error.SetErrorStringWithFormat(
"invalid range expression \"'%s'\"",
973 original_index_expr.str().c_str());
974 return ValueObjectSP();
977 index_expr = index_expr.drop_front();
978 long final_index = 0;
979 if (index_expr.getAsInteger(0, final_index)) {
980 error.SetErrorStringWithFormat(
"invalid range expression \"'%s'\"",
981 original_index_expr.str().c_str());
982 return ValueObjectSP();
986 if (child_index > final_index) {
987 long temp = child_index;
988 child_index = final_index;
992 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
998 ValueObjectSP temp(valobj_sp->Dereference(
error));
1000 valobj_sp->GetExpressionPath(var_expr_path_strm);
1001 error.SetErrorStringWithFormat(
1002 "could not dereference \"(%s) %s\"",
1003 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1004 var_expr_path_strm.
GetData());
1005 return ValueObjectSP();
1009 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1015 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0,
true));
1017 valobj_sp->GetExpressionPath(var_expr_path_strm);
1018 error.SetErrorStringWithFormat(
1019 "could not get item 0 for \"(%s) %s\"",
1020 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1021 var_expr_path_strm.
GetData());
1022 return ValueObjectSP();
1029 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index,
true);
1030 if (!child_valobj_sp) {
1031 valobj_sp->GetExpressionPath(var_expr_path_strm);
1032 error.SetErrorStringWithFormat(
1033 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1034 final_index, valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1035 var_expr_path_strm.
GetData());
1038 if (!child_valobj_sp) {
1040 return ValueObjectSP();
1044 ValueObjectSP dynamic_value_sp(
1045 child_valobj_sp->GetDynamicValue(use_dynamic));
1046 if (dynamic_value_sp)
1047 child_valobj_sp = dynamic_value_sp;
1056 valobj_sp->GetExpressionPath(var_expr_path_strm);
1057 error.SetErrorStringWithFormat(
1058 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1059 separator_type, var_expr_path_strm.
GetData(),
1060 var_expr.str().c_str());
1062 return ValueObjectSP();
1066 if (child_valobj_sp)
1067 valobj_sp = child_valobj_sp;
1071 ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(
error));
1072 valobj_sp = deref_valobj_sp;
1073 }
else if (address_of) {
1074 ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(
error));
1075 valobj_sp = address_of_valobj_sp;
1082 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1085 "No frame base available for this historical stack frame.");
1104 &exe_ctx,
nullptr, loclist_base_addr,
nullptr,
nullptr,
1110 "Evaluation of the frame base expression failed.");
1139 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1156 ValueObjectSP valobj_sp;
1163 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1172 if (var_idx < num_variables) {
1185 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1220 | eSymbolContextSymbol);
1234std::pair<const Instruction::Operand *, int64_t>
1237 switch (operand.
m_type) {
1243 return std::make_pair(
nullptr, 0);
1255 if (!immediate_child) {
1256 return std::make_pair(
nullptr, 0);
1264 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1265 GetBaseExplainingValue(*variable_child, register_context,
1267 if (!base_and_offset.first) {
1268 return std::make_pair(
nullptr, 0);
1271 base_and_offset.second -= immediate_child->
m_immediate;
1273 base_and_offset.second += immediate_child->
m_immediate;
1275 return base_and_offset;
1278 const RegisterInfo *info =
1281 return std::make_pair(
nullptr, 0);
1285 return std::make_pair(
nullptr, 0);
1288 return std::make_pair(&operand, 0);
1290 return std::make_pair(
nullptr, 0);
1294 return std::make_pair(
nullptr, 0);
1297std::pair<const Instruction::Operand *, int64_t>
1302 return GetBaseExplainingValue(operand.
m_children[0], register_context,
1305 return std::make_pair(
nullptr, 0);
1312 const ArchSpec &target_arch = target_sp->GetArchitecture();
1318 const char *plugin_name =
nullptr;
1319 const char *flavor =
nullptr;
1320 const bool force_live_memory =
true;
1322 DisassemblerSP disassembler_sp =
1324 *target_sp, pc_range, force_live_memory);
1326 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1327 return ValueObjectSP();
1330 InstructionSP instruction_sp =
1331 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1333 llvm::SmallVector<Instruction::Operand, 3> operands;
1335 if (!instruction_sp->ParseOperands(operands)) {
1336 return ValueObjectSP();
1341 if (!register_context_sp) {
1342 return ValueObjectSP();
1346 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1347 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1349 if (!base_and_offset.first) {
1353 switch (base_and_offset.first->m_type) {
1356 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1357 base_and_offset.second,
1359 auto c_type_system_or_err =
1361 if (
auto err = c_type_system_or_err.takeError()) {
1363 "Unable to guess value for given address");
1364 return ValueObjectSP();
1366 auto ts = *c_type_system_or_err;
1375 return ValueObjectSP();
1381 base_and_offset.second);
1384 return ValueObjectSP();
1388 return ValueObjectSP();
1392ValueObjectSP GetValueForOffset(
StackFrame &frame, ValueObjectSP &parent,
1394 if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
1395 return ValueObjectSP();
1398 if (parent->IsPointerOrReferenceType()) {
1402 for (
int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) {
1403 const bool can_create =
true;
1404 ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
1407 return ValueObjectSP();
1410 int64_t child_offset = child_sp->GetByteOffset();
1411 int64_t child_size = child_sp->GetByteSize().value_or(0);
1413 if (offset >= child_offset && offset < (child_offset + child_size)) {
1414 return GetValueForOffset(frame, child_sp, offset - child_offset);
1421 return ValueObjectSP();
1425ValueObjectSP GetValueForDereferincingOffset(
StackFrame &frame,
1426 ValueObjectSP &base,
1432 if (!base->IsPointerOrReferenceType()) {
1433 return ValueObjectSP();
1437 ValueObjectSP pointee = base->Dereference(
error);
1440 return ValueObjectSP();
1443 if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
1444 int64_t index = offset / pointee->GetByteSize().value_or(1);
1445 offset = offset % pointee->GetByteSize().value_or(1);
1446 const bool can_create =
true;
1447 pointee = base->GetSyntheticArrayMember(index, can_create);
1450 if (!pointee ||
error.Fail()) {
1451 return ValueObjectSP();
1454 return GetValueForOffset(frame, pointee, offset);
1509 using namespace OperandMatchers;
1511 const RegisterInfo *reg_info =
1514 return ValueObjectSP();
1525 for (VariableSP var_sp : variables) {
1526 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1533 return ValueObjectSP();
1541 InstructionSP instruction_sp =
1544 if (instruction_sp->IsCall()) {
1550 const char *return_register_name;
1551 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1555 const RegisterInfo *return_register_info =
1557 return_register_name);
1558 if (!return_register_info) {
1574 llvm::SmallVector<Instruction::Operand, 1> operands;
1575 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1579 switch (operands[0].m_type) {
1586 operands[0].m_immediate, load_address)) {
1590 load_address, eSymbolContextFunction, sc);
1604 std::string name_str(
1606 name_str.append(
"()");
1609 &frame, name_str, return_value_address, return_type);
1610 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1617 llvm::SmallVector<Instruction::Operand, 2> operands;
1618 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1627 if (clobbered_reg_matcher(operands[0])) {
1628 origin_operand = &operands[1];
1630 else if (clobbered_reg_matcher(operands[1])) {
1631 origin_operand = &operands[0];
1638 ValueObjectSP source_path;
1640 int64_t origin_offset = 0;
1642 if (
FetchRegOp(origin_register)(*origin_operand)) {
1643 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1644 variables, instruction_sp->GetAddress());
1647 FetchRegOp(origin_register))(*origin_operand) ||
1652 FetchImmOp(origin_offset)))(*origin_operand)) {
1654 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1655 variables, instruction_sp->GetAddress());
1660 GetValueForDereferincingOffset(frame, source_path, offset);
1668 return ValueObjectSP();
1676 const ArchSpec &target_arch = target_sp->GetArchitecture();
1681 return ValueObjectSP();
1686 return ValueObjectSP();
1696 return ValueObjectSP();
1699 const char *plugin_name =
nullptr;
1700 const char *flavor =
nullptr;
1701 const bool force_live_memory =
true;
1702 DisassemblerSP disassembler_sp =
1704 *target_sp, pc_range, force_live_memory);
1706 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1707 return ValueObjectSP();
1710 const bool get_file_globals =
false;
1714 return ValueObjectSP();
1717 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1722 ValueObjectSP value_sp;
1730 if (!target_sp && !process_sp)
1738 const bool can_create =
true;
1739 const bool get_parent_variables =
true;
1740 const bool stop_if_block_is_inlined_function =
true;
1743 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1744 [
this](
Variable *v) { return v->IsInScope(this); },
1760 ProcessSP process_sp(thread_sp->CalculateProcess());
1762 target_sp = process_sp->CalculateTarget();
1768 ProcessSP process_sp;
1771 process_sp = thread_sp->CalculateProcess();
1784 const char *frame_marker) {
1785 if (strm ==
nullptr)
1805 nullptr,
nullptr,
false,
false)) {
1808 Dump(strm,
true,
false);
1814 bool show_fullpaths) {
1815 if (strm ==
nullptr)
1818 if (show_frame_index)
1822 strm->
Printf(
"0x%0*" PRIx64
" ",
1827 const bool show_module =
true;
1828 const bool show_inline =
true;
1829 const bool show_function_arguments =
true;
1830 const bool show_function_name =
true;
1833 show_inline, show_function_arguments,
1834 show_function_name);
1838 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1850 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1886 bool show_unique,
const char *frame_marker) {
1887 if (show_frame_info) {
1894 bool have_source =
false, have_debuginfo =
false;
1900 const uint32_t source_lines_before =
1902 const uint32_t source_lines_after =
1908 have_debuginfo =
true;
1909 if (source_lines_before > 0 || source_lines_after > 0) {
1919 source_lines_before, source_lines_after,
"->", &strm);
1928 "Note: this address is compiler-generated code in function "
1929 "%s that has no source code associated with it.",
1932 strm.
Printf(
"Note: this address is compiler-generated code that "
1933 "has no source code associated with it.");
1938 switch (disasm_display) {
1955 if (disasm_lines > 0) {
1957 const char *plugin_name =
nullptr;
1958 const char *flavor =
nullptr;
1959 const bool mixed_source_and_assembly =
false;
1961 target->
GetDebugger(), target_arch, plugin_name, flavor,
1964 mixed_source_and_assembly, 0,
1980 .GetFrameRecognizerManager()
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.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
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)
void SetRawAddress(lldb::addr_t addr)
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
lldb::addr_t GetFileAddress() const
Get the file address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
bool IsValid() const
Check if the object state is valid.
bool IsSectionOffset() const
Check if an address is section offset.
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
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.
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::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile 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.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
bool IsEmpty() const
Test for empty string.
size_t GetLength() const
Get the length in bytes of string value.
const char * GetCString() const
Get the string value as a C string.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool IsAlwaysValidSingleExpr() const
bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const
A class to manage flag bits.
uint64_t GetDisassemblyLineCount() const
StopDisassemblyType GetStopDisassemblyDisplay() const
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoDebugInfo
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
uint64_t GetStopSourceLineCount(bool before) const
const FormatEntity::Entry * GetFrameFormat() const
const FormatEntity::Entry * GetFrameFormatUnique() const
InstructionList & GetInstructionList()
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, Target &target, const AddressRange &disasm_range, bool force_live_memory=false)
static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, 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)
"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.
bool IsClear(ValueType bit) const
Test a single flag bit to see if it is clear (zero).
ValueType Get() const
Get accessor for all flags.
ValueType Clear(ValueType mask=~static_cast< ValueType >(0))
Clear one or more flags.
void Reset(ValueType flags)
Set accessor for all flags.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
A class that describes a function.
const AddressRange & GetAddressRange()
CompilerType GetCompilerType()
DWARFExpressionList & GetFrameBaseExpression()
Get accessor for the frame base location.
ConstString GetName() const
const Mangled & GetMangled() const
void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no)
Find the file and line number of the source location of the start of the function.
Block & GetBlock(bool can_create)
Get accessor for the block list.
uint32_t GetIndexOfInstructionAtAddress(const Address &addr)
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
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(const FileSpec &file, 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)
This base class provides an interface to stack frames.
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
lldb::VariableListSP m_variable_list_sp
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
lldb::ThreadSP GetThread() const
Address m_frame_code_addr
@ eExpressionPathOptionsNoFragileObjcIvar
@ eExpressionPathOptionCheckPtrVsMember
@ eExpressionPathOptionsInspectAnonymousUnions
@ eExpressionPathOptionsAllowDirectIVarAccess
@ eExpressionPathOptionsNoSyntheticChildren
VariableList * GetVariableList(bool get_file_globals, Status *error_ptr)
Retrieve the list of variables that are in scope at this StackFrame's pc.
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
void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const char *frame_marker=nullptr)
Print a description for this frame using the frame-format formatter settings.
bool IsInlined()
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
lldb::LanguageType GetLanguage()
Query this frame to determine what the default language should be when parsing expressions given the ...
lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
lldb::RegisterContextSP m_reg_context_sp
lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
lldb::RecognizedStackFrameSP m_recognized_frame_sp
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.
@ Artificial
An artificial stack frame (e.g.
uint32_t m_concrete_frame_index
bool m_behaves_like_zeroth_frame
lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr)
Attempt to econstruct the ValueObject for a given raw address touched by the current instruction.
bool ChangePC(lldb::addr_t pc)
Change the pc value for a given thread.
lldb::ThreadSP CalculateThread() override
lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
bool HasCachedData() const
StreamString m_disassembly
lldb::StackFrameSP CalculateStackFrame() override
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Status m_frame_base_error
bool IsHistorical() const
Query whether this frame is part of a historical backtrace.
const char * Disassemble()
Return the disassembly for the instructions of this StackFrame's function as a single C string.
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.
void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths)
Print a description for this frame using a default format.
uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, bool show_unique=false, const char *frame_marker=nullptr)
Print a description of this stack frame and/or the source context/assembly for this stack frame.
Block * GetFrameBlock()
Get the current lexical scope block for this StackFrame, if possible.
bool GetFrameBaseValue(Scalar &value, Status *error_ptr)
Return the Canonical Frame Address (DWARF term) for this frame.
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 behaves_like_zeroth_frame, const SymbolContext *sc_ptr)
Construct a StackFrame object without supplying a RegisterContextSP.
lldb::LanguageType GuessLanguage()
lldb::ProcessSP CalculateProcess() override
lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
lldb::ValueObjectSP FindVariable(ConstString name)
Attempt to reconstruct the ValueObject for a variable with a given name from within the current Stack...
const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
lldb::TargetSP CalculateTarget() override
void SetPC(lldb::addr_t pc)
SymbolContextScope * GetSymbolContextScope() const
lldb::addr_t GetPC() const
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
void Clear()
Clear the object state.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
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.
"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.
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, bool show_function_name) const
Dump the stop context in this object to a Stream.
Function * function
The Function for a given query.
llvm::StringRef GetInstanceVariableName()
Determines the name of the instance variable for the this decl context.
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
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.
uint32_t GetResolvedMask() const
void Clear(bool clear_target)
Clear the object's state.
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.
SourceManager & GetSourceManager()
const ArchSpec & GetArchitecture() const
CompilerType GetForwardCompilerType()
void SetValueObjectAtIndex(size_t idx, const lldb::ValueObjectSP &valobj_sp)
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
void Swap(ValueObjectList &value_object_list)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
Scalar & ResolveValue(ExecutionContext *exe_ctx)
lldb::VariableSP FindVariable(ConstString name, bool include_static_members=true)
uint32_t FindIndexForVariable(Variable *variable)
bool IsInScope(StackFrame *frame)
bool LocationIsValidForFrame(StackFrame *frame)
#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.
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
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)
uint16_t column
The column number of the source line, or zero if there is no column information.
bool IsValid() const
Check if a line entry object is valid.
FileSpec file
The source file, possibly mapped by the target.source-map setting.
uint32_t line
The source line number, or zero if there is no line number information.
void ApplyFileMappings(lldb::TargetSP target_sp)
Apply file mappings from target.source-map to the LineEntry's file.