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() {
73 if (sc_ptr !=
nullptr) {
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) {
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),
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) {
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) {
304 uint32_t resolved = 0;
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,
476 bool must_have_valid_location) {
477 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
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 ||
501 if (global_variable_list_sp)
502 var_list_sp->AddVariables(global_variable_list_sp.get());
511 llvm::StringRef original_var_expr = var_expr;
516 if (var_expr.empty()) {
517 error.SetErrorStringWithFormat(
"invalid variable path '%s'",
518 var_expr.str().c_str());
522 const bool check_ptr_vs_member =
524 const bool no_fragile_ivar =
526 const bool no_synth_child =
532 bool address_of =
false;
534 const bool get_file_globals =
true;
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);
613 if (var_sp && !valobj_sp) {
619 error.SetErrorStringWithFormat(
"no variable named '%s' found in this frame",
625 while (!var_expr.empty()) {
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] !=
'>')
636 if (no_fragile_ivar) {
639 const uint32_t pointer_type_flags =
640 valobj_sp->GetCompilerType().GetTypeInfo(
nullptr);
641 if ((pointer_type_flags & eTypeIsObjC) &&
642 (pointer_type_flags & eTypeIsPointer)) {
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);
662 valobj_sp = valobj_sp->Dereference(deref_error);
664 error.SetErrorStringWithFormatv(
665 "Failed to dereference sythetic value: {0}", deref_error);
670 error.SetErrorString(
"Failed to dereference sythetic value");
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());
708 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
709 if (!child_valobj_sp) {
710 if (!no_synth_child) {
711 child_valobj_sp = valobj_sp->GetSyntheticValue();
714 child_valobj_sp->GetChildMemberWithName(child_name);
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());
745 synthetically_added_instance_object =
false;
747 var_expr = var_expr.drop_front(child_name.
GetLength());
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());
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\"",
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());
791 if (index_expr.empty()) {
794 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
801 valobj_sp->GetExpressionPath(var_expr_path_strm);
802 error.SetErrorStringWithFormat(
803 "could not dereference \"(%s) %s\"",
804 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
810 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
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>"),
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>"),
848 }
else if (is_objc_pointer) {
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);
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);
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>"),
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);
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) {
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());
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());
986 if (child_index > final_index) {
987 long temp = child_index;
988 child_index = final_index;
992 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
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());
1009 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
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());
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) {
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());
1066 if (child_valobj_sp)
1067 valobj_sp = child_valobj_sp;
1072 valobj_sp = deref_valobj_sp;
1073 }
else if (address_of) {
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);
1163 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1171 const uint32_t num_variables = var_list->
GetSize();
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;
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;
1324 *target_sp, pc_range, force_live_memory);
1326 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1331 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1333 llvm::SmallVector<Instruction::Operand, 3> operands;
1335 if (!instruction_sp->ParseOperands(operands)) {
1341 if (!register_context_sp) {
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: {0}");
1366 auto ts = *c_type_system_or_err;
1381 base_and_offset.second);
1394 if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
1398 if (parent->IsPointerOrReferenceType()) {
1402 for (
int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) {
1409 int64_t child_offset = child_sp->GetByteOffset();
1410 int64_t child_size = child_sp->GetByteSize().value_or(0);
1412 if (offset >= child_offset && offset < (child_offset + child_size)) {
1413 return GetValueForOffset(frame, child_sp, offset - child_offset);
1431 if (!base->IsPointerOrReferenceType()) {
1442 if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
1443 int64_t index = offset / pointee->GetByteSize().value_or(1);
1444 offset = offset % pointee->GetByteSize().value_or(1);
1445 const bool can_create =
true;
1446 pointee = base->GetSyntheticArrayMember(index, can_create);
1449 if (!pointee ||
error.Fail()) {
1453 return GetValueForOffset(frame, pointee, offset);
1508 using namespace OperandMatchers;
1525 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1529 const uint32_t current_inst =
1535 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1543 if (instruction_sp->IsCall()) {
1549 const char *return_register_name;
1550 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1556 return_register_name);
1557 if (!return_register_info) {
1573 llvm::SmallVector<Instruction::Operand, 1> operands;
1574 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1578 switch (operands[0].m_type) {
1585 operands[0].m_immediate, load_address)) {
1589 load_address, eSymbolContextFunction, sc);
1603 std::string name_str(
1605 name_str.append(
"()");
1608 &frame, name_str, return_value_address, return_type);
1609 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1616 llvm::SmallVector<Instruction::Operand, 2> operands;
1617 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1626 if (clobbered_reg_matcher(operands[0])) {
1627 origin_operand = &operands[1];
1629 else if (clobbered_reg_matcher(operands[1])) {
1630 origin_operand = &operands[0];
1639 int64_t origin_offset = 0;
1641 if (
FetchRegOp(origin_register)(*origin_operand)) {
1642 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1643 variables, instruction_sp->GetAddress());
1646 FetchRegOp(origin_register))(*origin_operand) ||
1651 FetchImmOp(origin_offset)))(*origin_operand)) {
1653 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1654 variables, instruction_sp->GetAddress());
1659 GetValueForDereferincingOffset(frame, source_path, offset);
1675 const ArchSpec &target_arch = target_sp->GetArchitecture();
1698 const char *plugin_name =
nullptr;
1699 const char *flavor =
nullptr;
1700 const bool force_live_memory =
true;
1703 *target_sp, pc_range, force_live_memory);
1705 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1709 const bool get_file_globals =
false;
1716 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1729 if (!target_sp && !process_sp)
1737 const bool can_create =
true;
1738 const bool get_parent_variables =
true;
1739 const bool stop_if_block_is_inlined_function =
true;
1742 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1743 [
this](
Variable *v) { return v->IsInScope(this); },
1759 ProcessSP process_sp(thread_sp->CalculateProcess());
1761 target_sp = process_sp->CalculateTarget();
1770 process_sp = thread_sp->CalculateProcess();
1783 const char *frame_marker) {
1784 if (strm ==
nullptr)
1804 nullptr,
nullptr,
false,
false)) {
1807 Dump(strm,
true,
false);
1813 bool show_fullpaths) {
1814 if (strm ==
nullptr)
1817 if (show_frame_index)
1821 strm->
Printf(
"0x%0*" PRIx64
" ",
1826 const bool show_module =
true;
1827 const bool show_inline =
true;
1828 const bool show_function_arguments =
true;
1829 const bool show_function_name =
true;
1832 show_inline, show_function_arguments,
1833 show_function_name);
1837 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1849 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1885 bool show_unique,
const char *frame_marker) {
1886 if (show_frame_info) {
1893 bool have_source =
false, have_debuginfo =
false;
1899 const uint32_t source_lines_before =
1901 const uint32_t source_lines_after =
1907 have_debuginfo =
true;
1908 if (source_lines_before > 0 || source_lines_after > 0) {
1918 source_lines_before, source_lines_after,
"->", &strm);
1927 "Note: this address is compiler-generated code in function "
1928 "%s that has no source code associated with it.",
1931 strm.
Printf(
"Note: this address is compiler-generated code that "
1932 "has no source code associated with it.");
1937 switch (disasm_display) {
1954 if (disasm_lines > 0) {
1956 const char *plugin_name =
nullptr;
1957 const char *flavor =
nullptr;
1958 const bool mixed_source_and_assembly =
false;
1960 target->
GetDebugger(), target_arch, plugin_name, flavor,
1963 mixed_source_and_assembly, 0,
1979 .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
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(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.
lldb::LanguageType GuessLanguage()
lldb::ProcessSP CalculateProcess() override
lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
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::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 SetCFA(lldb::addr_t cfa)
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, Module *module=nullptr)
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.
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
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ 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
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
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)
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.
Every register is described in detail including its name, alternate name (optional),...