40#include "llvm/Support/Error.h"
41#include "llvm/Support/FormatAdapters.h"
60 return abi_sp->CallFrameAddressIsValid(cfa);
61 return cfa != 0 && cfa != 1;
73 if (name.starts_with(
"OUTLINED_FUNCTION_"))
78#define UNWIND_LOG_IMPL(LOG_FN, log, ...) \
79 LOG_FN(log, "{0}th{1}/fr{2} {3}", \
80 llvm::indent(std::min(m_frame_number, 100U)), m_thread.GetIndexID(), \
81 m_frame_number, llvm::formatv(__VA_ARGS__))
83#define UNWIND_LOG(log, ...) UNWIND_LOG_IMPL(LLDB_LOG, log, __VA_ARGS__)
85#define UNWIND_LOG_VERBOSE(log, ...) \
86 UNWIND_LOG_IMPL(LLDB_LOG_VERBOSE, log, __VA_ARGS__)
91 uint32_t frame_number,
115 m_all_registers_available = true;
120 std::shared_ptr<const UnwindPlan> unwind_plan_sp) {
137 pc_minus_one.
Slide(-1);
138 if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
153 if (reg_ctx_sp.get() ==
nullptr) {
155 UNWIND_LOG(log,
"frame does not have a register context");
159 addr_t current_pc = reg_ctx_sp->GetPC();
175 current_pc = abi_sp->FixCodeAddress(current_pc);
177 std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
180 if (lang_runtime_plan_sp.get()) {
193 UNWIND_LOG(log,
"using architectural default unwind method");
199 UNWIND_LOG(log,
"with pc value of {0:x}, symbol name is '{1}'", current_pc,
202 UNWIND_LOG(log,
"with pc value of {0:x}, function name is '{1}'",
205 UNWIND_LOG(log,
"with pc value of {0:x}, no symbol/function name is known.",
227 pc_module_sp ? pc_module_sp->GetUnwindTable()
228 .GetFunctionStartFromObjectFileUnwindInfo(
255 if (lang_runtime_plan_sp.get()) {
258 row_register_kind = lang_runtime_plan_sp->GetRegisterKind();
266 active_row->
Dump(active_row_strm, lang_runtime_plan_sp.get(), &
m_thread,
272 "initialized async frame current pc is {0:x} cfa is {1:x} afa "
287 if (active_row && log) {
296 UNWIND_LOG(log,
"could not find an unwindplan row for this frame's pc");
305 std::shared_ptr<const UnwindPlan> call_site_unwind_plan;
306 bool cfa_status =
false;
310 pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
314 if (func_unwinders_sp.get() !=
nullptr)
315 call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
318 if (call_site_unwind_plan !=
nullptr) {
324 UNWIND_LOG(log,
"could not read CFA value for first frame.");
333 "could not read CFA or AFA values for first frame, not valid.");
342 "initialized frame current pc is {0:x} cfa is {1:x} afa is {2:x} "
343 "using {3} UnwindPlan",
355 UNWIND_LOG(log,
"non-zeroth frame tests positive for IsFrameZero -- that "
356 "shouldn't happen.");
362 UNWIND_LOG(log,
"Could not get next frame, marking this frame as invalid.");
365 if (!
m_thread.GetRegisterContext()) {
367 UNWIND_LOG(log,
"Could not get register context for this thread, marking "
368 "this frame as invalid.");
382 std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
385 if (lang_runtime_plan_sp.get()) {
400 pc = abi_sp->FixCodeAddress(
pc);
413 bool above_trap_handler =
false;
416 above_trap_handler =
true;
418 if (
pc == 0 ||
pc == 0x1) {
419 if (!above_trap_handler) {
421 UNWIND_LOG(log,
"this frame has a pc of 0x0");
426 const bool allow_section_end =
true;
437 above_trap_handler ==
false) {
438 UNWIND_LOG(log,
"using architectural default unwind method");
442 uint32_t permissions;
444 (permissions & ePermissionsExecutable) == 0) {
453 "had a pc of {0:x} which is not in executable memory but on "
454 "frame 1 -- allowing it once.",
461 UNWIND_LOG(log,
"pc is in a non-executable section of memory and this "
462 "isn't the 2nd frame in the stack walk.");
473 ->GetUnspecifiedRegistersAreUndefined())) &&
474 "Default UnwindPlan must set "
475 "UnspecifiedRegistersAreUndefined to true");
499 UNWIND_LOG(log,
"could not find a valid cfa address");
507 (permissions & ePermissionsReadable) == 0) {
510 log,
"the CFA points to a region of memory that is not readable");
514 UNWIND_LOG(log,
"could not find a row for function offset zero");
522 UNWIND_LOG(log,
"same CFA address as next frame, assuming the unwind "
523 "is looping - stopping");
537 UNWIND_LOG(log,
"could not find any symbol for this pc, or a default "
538 "unwind plan, to continue unwind.");
545 UNWIND_LOG(log,
"with pc value of {0:x}, symbol name is '{1}'",
pc,
548 UNWIND_LOG(log,
"with pc value of {0:x}, function name is '{1}'",
pc,
551 UNWIND_LOG(log,
"with pc value of {0:x}, no symbol/function name is known.",
555 bool decr_pc_and_recompute_addr_range;
559 decr_pc_and_recompute_addr_range =
true;
564 decr_pc_and_recompute_addr_range =
false;
570 decr_pc_and_recompute_addr_range =
false;
572 decr_pc_and_recompute_addr_range =
true;
578 decr_pc_and_recompute_addr_range =
false;
580 decr_pc_and_recompute_addr_range =
false;
583 decr_pc_and_recompute_addr_range =
true;
592 if (decr_pc_and_recompute_addr_range) {
594 "Backing up the pc value of {0:x} by 1 and re-doing symbol "
595 "lookup; old symbol was {1}",
612 if (decr_pc_and_recompute_addr_range &&
643 if (lang_runtime_plan_sp.get()) {
646 row_register_kind = lang_runtime_plan_sp->GetRegisterKind();
654 active_row->
Dump(active_row_strm, lang_runtime_plan_sp.get(), &
m_thread,
660 "initialized async frame current pc is {0:x} cfa is {1:x} afa "
682 if (active_row && log) {
686 UNWIND_LOG(log,
"Using fast unwind plan '{0}'",
697 if (active_row && log) {
702 UNWIND_LOG(log,
"Using full unwind plan '{0}'",
711 UNWIND_LOG(log,
"could not find unwind row for this pc");
728 UNWIND_LOG(log,
"same CFA address as next frame, assuming the unwind is "
729 "looping - stopping");
739 "initialized frame current pc is {0:x} cfa is {1:x} afa is {2:x}",
760 next_frame->GetNextFrame();
762 if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
763 if (next_next_frame_cfa ==
m_cfa) {
793std::shared_ptr<const UnwindPlan>
798 pc_module_sp->GetObjectFile() ==
nullptr)
805 pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
807 if (!func_unwinders_sp)
815 if (std::shared_ptr<const UnwindPlan> unwind_plan_sp =
816 func_unwinders_sp->GetUnwindPlanFastUnwind(
820 return unwind_plan_sp;
835std::shared_ptr<const UnwindPlan>
838 std::shared_ptr<const UnwindPlan> arch_default_unwind_plan_sp;
841 ABI *abi = process ? process->
GetABI().get() :
nullptr;
844 assert(((!arch_default_unwind_plan_sp ||
845 arch_default_unwind_plan_sp->GetRowCount() == 0 ||
846 arch_default_unwind_plan_sp->GetRowAtIndex(0)
847 ->GetUnspecifiedRegistersAreUndefined())) &&
848 "Default UnwindPlan must set "
849 "UnspecifiedRegistersAreUndefined to true");
852 log,
"unable to get architectural default UnwindPlan from ABI plugin");
874 uint32_t permissions;
877 if (current_pc_addr == 0 ||
880 (permissions & ePermissionsExecutable) == 0)) {
891 pc_module_sp->GetObjectFile() ==
nullptr) {
893 return arch_default_unwind_plan_sp;
911 "Overriding full unwind plan, using architectural default for "
914 return arch_default_unwind_plan_sp;
921 pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
931 if (!func_unwinders_sp) {
934 if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
936 return arch_default_unwind_plan_sp;
941 pc_module_sp->GetUnwindTable().GetEHFrameInfo()) {
942 if (std::unique_ptr<UnwindPlan> plan_up =
948 pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
950 auto unwind_plan_sp =
954 return unwind_plan_sp;
958 pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
959 if (object_file_unwind) {
960 if (std::unique_ptr<UnwindPlan> plan_up =
965 return arch_default_unwind_plan_sp;
977 if (
auto unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
979 return unwind_plan_sp;
982 auto unwind_plan_sp =
983 func_unwinders_sp->GetEHFrameUnwindPlan(process->
GetTarget());
986 func_unwinders_sp->GetObjectFileUnwindPlan(process->
GetTarget());
987 if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(
m_current_pc) &&
988 unwind_plan_sp->GetSourcedFromCompiler() ==
eLazyBoolYes) {
989 return unwind_plan_sp;
1007 auto unwind_plan_sp =
1008 func_unwinders_sp->GetEHFrameUnwindPlan(process->
GetTarget());
1009 if (!unwind_plan_sp)
1011 func_unwinders_sp->GetObjectFileUnwindPlan(process->
GetTarget());
1012 if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(
m_current_pc)) {
1014 "frame uses {0} for full UnwindPlan because the "
1015 "DynamicLoader suggested we prefer it",
1016 unwind_plan_sp->GetSourceName());
1017 return unwind_plan_sp;
1024 auto unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
1026 if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(
m_current_pc)) {
1027 if (unwind_plan_sp->GetSourcedFromCompiler() ==
eLazyBoolNo) {
1039 std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
1040 func_unwinders_sp->GetUnwindPlanAtCallSite(process->
GetTarget(),
1042 if (call_site_unwind_plan &&
1043 call_site_unwind_plan.get() != unwind_plan_sp.get() &&
1044 call_site_unwind_plan->GetSourceName() !=
1045 unwind_plan_sp->GetSourceName()) {
1053 "frame uses {0} for full UnwindPlan because this is the non-call "
1054 "site unwind plan and this is a zeroth frame",
1055 unwind_plan_sp->GetSourceName());
1056 return unwind_plan_sp;
1064 func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
1066 if (unwind_plan_sp) {
1068 "frame uses {0} for full UnwindPlan because we are "
1069 "at the first instruction of a function",
1070 unwind_plan_sp->GetSourceName());
1071 return unwind_plan_sp;
1076 std::shared_ptr<const UnwindPlan> unwind_plan_sp;
1080 unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
1085 "frame uses {0} for full UnwindPlan because this is the "
1086 "call-site unwind plan",
1087 unwind_plan_sp->GetSourceName());
1088 return unwind_plan_sp;
1095 unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
1098 if (unwind_plan_sp &&
1099 unwind_plan_sp->GetSourcedFromCompiler() ==
eLazyBoolNo) {
1110 std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
1111 func_unwinders_sp->GetUnwindPlanAtCallSite(process->
GetTarget(),
1113 if (call_site_unwind_plan &&
1114 call_site_unwind_plan.get() != unwind_plan_sp.get() &&
1115 call_site_unwind_plan->GetSourceName() !=
1116 unwind_plan_sp->GetSourceName()) {
1125 "frame uses {0} for full UnwindPlan because we failed "
1126 "to find a call-site unwind plan that would work",
1127 unwind_plan_sp->GetSourceName());
1128 return unwind_plan_sp;
1133 if (arch_default_unwind_plan_sp)
1135 "frame uses {0} for full UnwindPlan because we are "
1136 "falling back to the arch default plan",
1137 arch_default_unwind_plan_sp->GetSourceName());
1140 "Unable to find any UnwindPlan for full unwind of this frame.");
1142 return arch_default_unwind_plan_sp;
1150 return m_thread.GetRegisterContext()->GetRegisterCount();
1154 return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
1158 return m_thread.GetRegisterContext()->GetRegisterSetCount();
1162 return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
1167 return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
1176 bool success =
false;
1178 switch (regloc.
type) {
1183 if (!other_reg_info)
1187 m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
1193 if (!other_reg_info)
1198 m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
1200 success =
GetNextFrame()->ReadRegister(other_reg_info, value);
1208 if (!other_reg_info)
1213 m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
1215 success =
GetNextFrame()->ReadRegister(other_reg_info, value);
1219 UNWIND_LOG(log,
"read ({0})'s location", regnum);
1222 UNWIND_LOG(log,
"success {0}", success ?
"yes" :
"no");
1233 llvm_unreachable(
"FIXME debugger inferior function call unwind");
1238 success =
error.Success();
1241 llvm_unreachable(
"Unknown ConcreteRegisterLocation type.");
1252 bool success =
false;
1254 switch (regloc.
type) {
1259 m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
1266 m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
1268 success =
GetNextFrame()->WriteRegister(other_reg_info, value);
1276 llvm_unreachable(
"FIXME debugger inferior function call unwind");
1281 success =
error.Success();
1284 llvm_unreachable(
"Unknown ConcreteRegisterLocation type.");
1320 const std::vector<std::string> &trap_handler_names(
1321 platform_sp->GetTrapHandlerSymbolNames());
1322 for (
const std::string &name : trap_handler_names) {
1324 m_sym_ctx.function->GetName().GetStringRef() == name) ||
1326 m_sym_ctx.symbol->GetName().GetStringRef() == name)) {
1331 const std::vector<std::string> &user_specified_trap_handler_names =
1333 for (
const std::string &name : user_specified_trap_handler_names) {
1335 m_sym_ctx.function->GetName().GetStringRef() == name) ||
1337 m_sym_ctx.symbol->GetName().GetStringRef() == name)) {
1377std::optional<UnwindPlan::Row::AbstractRegisterLocation>
1392 "could not convert lldb regnum {0} ({1}) into {2} "
1393 "RegisterKind reg numbering scheme",
1407 unwindplan_regloc) &&
1411 "supplying caller's saved {0} ({1})'s location using FastUnwindPlan",
1413 return unwindplan_regloc;
1418 bool got_new_full_unwindplan =
false;
1421 got_new_full_unwindplan =
true;
1432 if (got_new_full_unwindplan && active_row && log) {
1437 UNWIND_LOG(log,
"Using full unwind plan '{0}'",
1445 "could not convert lldb regnum {0} ({1}) into "
1446 "eRegisterKindGeneric reg numbering scheme",
1450 "could not convert lldb regnum {0} ({1}) into {2} "
1451 "RegisterKind reg numbering scheme",
1456 "marking register {0} ({1}) as Undefined (volatile) in this "
1457 "stack frame because this row is UnspecifiedRegistersAreUndefined.",
1460 return unwindplan_regloc;
1465 if (regnum.
IsValid() && active_row &&
1467 unwindplan_regloc)) {
1470 "supplying caller's saved {0} ({1})'s location using {2} UnwindPlan",
1473 return unwindplan_regloc;
1502 if (pc_regnum.
IsValid() && pc_regnum == regnum) {
1509 return_address_regnum =
1514 return_address_regnum = arch_default_ra_regnum.
GetAsKind(kind);
1522 return_address_regnum);
1524 "requested caller's saved PC but this UnwindPlan uses a RA "
1525 "reg; getting {0} ({1}) instead",
1532 unwindplan_regloc)) {
1534 "supplying caller's saved {0} ({1})'s location using {2} "
1542 if (unwindplan_regloc.
IsSame())
1544 return unwindplan_regloc;
1552 return unwindplan_regloc;
1560 "marking register {0} ({1}) as Undefined (volatile) in this "
1561 "stack frame because this row is UnspecifiedRegistersAreUndefined.",
1564 return unwindplan_regloc;
1578 ABI *abi = process ? process->
GetABI().get() :
nullptr;
1587 "supplying caller's saved {0} ({1})'s location using ABI default",
1592 return unwindplan_regloc;
1599 std::string unwindplan_name;
1601 unwindplan_name +=
"via '";
1603 unwindplan_name +=
"'";
1609 return unwindplan_regloc;
1617 uint32_t lldb_regnum,
1626 regloc = iterator->second;
1627 UNWIND_LOG(log,
"supplying caller's saved {0} ({1})'s location, cached",
1634 std::optional<UnwindPlan::Row::AbstractRegisterLocation> abs_regloc =
1640 if (abs_regloc->IsUndefined()) {
1642 log,
"did not supply reg location for {0} ({1}) because it is volatile",
1650 if (abs_regloc->IsUnspecified()) {
1655 "save location for {0} ({1}) is unspecified, continue searching",
1660 if (abs_regloc->IsSame()) {
1667 "supplying caller's register {0} ({1}) from the live "
1668 "RegisterContext at frame 0",
1681 "register {0} ({1}) is marked as 'IsSame' - it is a pc or "
1682 "return address reg on a frame which does not have all "
1683 "registers available -- treat as if we have no information",
1692 "supplying caller's register {0} ({1}) value is unmodified in "
1698 if (abs_regloc->IsCFAPlusOffset()) {
1699 int offset = abs_regloc->GetOffset();
1704 "supplying caller's register {0} ({1}), value is CFA plus "
1705 "offset {2} [value is {3:x}]",
1711 if (abs_regloc->IsAtCFAPlusOffset()) {
1712 int offset = abs_regloc->GetOffset();
1718 "supplying caller's register {0} ({1}) from the stack, saved at "
1719 "CFA plus offset {2} [saved at {3:x}]",
1725 if (abs_regloc->IsAFAPlusOffset()) {
1729 int offset = abs_regloc->GetOffset();
1734 "supplying caller's register {0} ({1}), value is AFA plus "
1735 "offset {2} [value is {3:x}]",
1741 if (abs_regloc->IsAtAFAPlusOffset()) {
1745 int offset = abs_regloc->GetOffset();
1751 "supplying caller's register {0} ({1}) from the stack, saved at "
1752 "AFA plus offset {2} [saved at {3:x}]",
1758 if (abs_regloc->IsInOtherRegister()) {
1760 abs_regloc->GetRegisterNumber());
1763 "could not supply caller's {0} ({1}) location - was saved in "
1764 "another reg but couldn't convert that regnum",
1773 "supplying caller's register {0} ({1}), saved in register {2} ({3})",
1779 if (abs_regloc->IsDWARFExpression() || abs_regloc->IsAtDWARFExpression()) {
1780 DataExtractor dwarfdata(abs_regloc->GetDWARFExpressionBytes(),
1781 abs_regloc->GetDWARFExpressionLength(),
1789 llvm::Expected<Value> result =
1790 dwarfexpr.
Evaluate(&exe_ctx,
this, 0, &cfa_val,
nullptr);
1793 "DWARF expression failed to evaluate: {0}");
1796 val = result->GetScalar().ULongLong();
1797 if (abs_regloc->IsDWARFExpression()) {
1803 "supplying caller's register {0} ({1}) via DWARF expression "
1804 "(IsDWARFExpression)",
1808 regloc.
type = UnwindLLDB::ConcreteRegisterLocation::
1809 eRegisterSavedAtMemoryLocation;
1813 "supplying caller's register {0} ({1}) via DWARF expression "
1814 "(IsAtDWARFExpression)",
1820 "tried to use IsDWARFExpression or IsAtDWARFExpression for {0} "
1826 if (abs_regloc->IsConstant()) {
1830 UNWIND_LOG(log,
"supplying caller's register {0} ({1}) via constant value",
1835 UNWIND_LOG(log,
"no save location for {0} ({1}) in this stack frame",
1852 if (
Architecture *arch = process_sp->GetTarget().GetArchitecturePlugin())
1853 arch_override_plan_sp =
1856 if (arch_override_plan_sp) {
1862 log,
"Replacing Full Unwindplan with Architecture UnwindPlan, '{0}'",
1870 m_start_pc.GetLoadAddress(&process_sp->GetTarget()));
1934 if (
ABISP abi_sp = process_sp->GetABI())
1935 old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value);
1954 std::shared_ptr<const UnwindPlan> original_full_unwind_plan_sp =
1973 ABISP abi_sp = process_sp ? process_sp->GetABI() :
nullptr;
1977 UNWIND_LOG(log,
"failed to get cfa with fallback unwindplan");
1998 new_caller_pc_value =
1999 process_sp->FixCodeAddress(new_caller_pc_value);
2005 UNWIND_LOG(log,
"failed to get a pc value for the caller frame with the "
2006 "fallback unwind plan");
2014 if (old_caller_pc_value == new_caller_pc_value &&
2017 UNWIND_LOG(log,
"fallback unwind plan got the same values for this frame "
2018 "CFA and caller frame pc, not using");
2025 "trying to unwind from this function with the UnwindPlan '{0}' "
2026 "because UnwindPlan '{1}' failed.",
2028 original_full_unwind_plan_sp->GetSourceName());
2060 ABISP abi_sp = process_sp ? process_sp->GetABI() :
nullptr;
2065 "failed to get cfa with fallback unwindplan");
2083 "switched unconditionally to the fallback unwindplan {0}",
2091 std::shared_ptr<const UnwindPlan> unwind_plan) {
2092 if (unwind_plan->GetUnwindPlanForSignalTrap() !=
eLazyBoolYes) {
2106 UNWIND_LOG(log,
"This frame is marked as a trap handler via its UnwindPlan");
2120 "Resetting current offset and re-doing symbol lookup; old "
2153 UNWIND_LOG(log,
"CFA value via dereferencing reg");
2156 addr_t reg_to_deref_contents;
2157 if (
ReadGPRValue(regnum_to_deref, reg_to_deref_contents)) {
2163 reg_info, reg_to_deref_contents, reg_info->
byte_size, reg_value);
2164 if (
error.Success()) {
2167 "CFA value via dereferencing reg {0} ({1}): reg has val "
2168 "{2:x}, CFA value is {3:x}",
2171 reg_to_deref_contents, address);
2176 "Tried to deref reg {0} ({1}) [{2:x}] but memory read failed.",
2179 reg_to_deref_contents);
2186 UNWIND_LOG(log,
"CFA value via register plus offset");
2193 "Got an invalid CFA register value - reg {0} ({1}), value {2:x}",
2198 address = cfa_reg_contents + fa.
GetOffset();
2201 "CFA is {0:x}: Register {1} ({2}) contents are {3:x}, offset is {4}",
2211 UNWIND_LOG(log,
"CFA value via DWARF expression");
2222 llvm::Expected<Value> result =
2223 dwarfexpr.
Evaluate(&exe_ctx,
this, 0,
nullptr,
nullptr);
2225 address = result->GetScalar().ULongLong();
2226 UNWIND_LOG(log,
"CFA value set by DWARF expression is {0:x}", address);
2230 "Failed to set CFA value via DWARF expression: {0}");
2234 UNWIND_LOG(log,
"CFA value via heuristic search");
2239 const unsigned max_iterations = 256;
2240 for (
unsigned i = 0; i < max_iterations; ++i) {
2243 llvm::Expected<lldb::addr_t> candidate =
2247 "Cannot read memory at {1:x}: {0}", candidate_addr);
2251 uint32_t permissions;
2253 permissions & lldb::ePermissionsExecutable) {
2254 address = candidate_addr;
2255 UNWIND_LOG(log,
"Heuristically found CFA: {0:x}", address);
2264 UNWIND_LOG(log,
"CFA value set by constant is {0:x}", address);
2280 hint = abi_sp->FixCodeAddress(hint);
2282 hint += plan_offset;
2285 if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
2287 if (
auto expected_size =
2288 next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
2289 *next->m_sym_ctx.symbol))
2290 hint += *expected_size;
2293 "Could not retrieve parameter size: {0}");
2317 uint32_t regnum,
addr_t &value) {
2321 uint32_t lldb_regnum;
2323 lldb_regnum = regnum;
2324 }
else if (!
m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
2334 "Could not find RegisterInfo definition for lldb register number {0}",
2341 generic_regnum = regnum;
2343 m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
2351 if (
m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
2356 value = abi_sp->FixCodeAddress(value);
2363 bool pc_register =
false;
2378 value = abi_sp->FixCodeAddress(value);
2407 "passing along to the live register context for reg {0}",
2409 return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
2412 bool is_pc_regnum =
false;
2415 is_pc_regnum =
true;
2430 value = abi_sp->FixCodeAddress(reg_value);
2450 "passing along to the live register context for reg {0}",
2452 return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
2508 bool read_successfully =
ReadPC (start_pc);
2509 if (read_successfully)
2514 if (
ABISP abi_sp = process_sp->GetABI())
2515 start_pc = abi_sp->FixCodeAddress(start_pc);
2518 return read_successfully;
2530 bool above_trap_handler =
false;
2533 above_trap_handler =
true;
2544 pc = abi_sp->FixCodeAddress(
pc);
2547 above_trap_handler ==
false && (
pc == 0 ||
pc == 1));
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERRORV(log, error,...)
#define LLDB_LOG_ERROR(log, error,...)
static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx)
#define UNWIND_LOG_VERBOSE(log,...)
static bool IsClangOutlinedFunction(const SymbolContext &sym_ctx)
Identify a clang outlined function by symbol name.
static bool CallFrameAddressIsValid(ABISP abi_sp, lldb::addr_t cfa)
#define UNWIND_LOG(log,...)
A class to represent register numbers, and able to convert between different register numbering schem...
uint32_t GetAsKind(lldb::RegisterKind kind)
lldb::RegisterKind GetRegisterKind() const
uint32_t GetRegisterNumber() const
void init(lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num)
virtual lldb::UnwindPlanSP CreateDefaultUnwindPlan()=0
virtual bool GetFallbackRegisterLocation(const RegisterInfo *reg_info, UnwindPlan::Row::AbstractRegisterLocation &unwind_regloc)
virtual lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan()=0
A section + offset based address class.
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
bool Slide(int64_t offset)
bool ResolveFunctionScope(lldb_private::SymbolContext &sym_ctx)
Resolve this address to its containing function.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
bool GetUnwindPlan(Target &target, const Address &addr, UnwindPlan &unwind_plan)
virtual std::unique_ptr< UnwindPlan > GetUnwindPlan(llvm::ArrayRef< AddressRange > ranges, const Address &addr)=0
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr) const
DWARFExpression * GetMutableExpressionAtAddress(lldb::addr_t func_load_addr=LLDB_INVALID_ADDRESS, lldb::addr_t load_addr=0)
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
virtual bool AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx)
Ask if the eh_frame information for the given SymbolContext should be relied on even when it's the fi...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Target * GetTargetPtr() const
Returns a pointer to the target object.
Target & GetTargetRef() const
Returns a reference to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
ConstString GetName() const
static lldb::UnwindPlanSP GetRuntimeUnwindPlan(lldb_private::Thread &thread, lldb_private::RegisterContext *regctx, bool &behaves_like_zeroth_frame)
A language runtime may be able to provide a special UnwindPlan for the frame represented by the regis...
A plug-in interface definition class for debugging a process.
virtual bool GetLoadAddressPermissions(lldb::addr_t load_addr, uint32_t &permissions)
Attempt to get the attributes for a region of memory in the process.
lldb::ByteOrder GetByteOrder() const
llvm::Expected< lldb::addr_t > ReadPointerFromMemory(lldb::addr_t vm_addr)
uint32_t GetAddressByteSize() const
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
const lldb::ABISP & GetABI()
Target & GetTarget()
Get the target object pointer for this module.
std::optional< UnwindPlan::Row::AbstractRegisterLocation > GetAbstractRegisterLocation(uint32_t lldb_regnum, lldb::RegisterKind &kind)
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
bool CheckIfLoopingStack()
bool GetCFA(lldb::addr_t &cfa)
void InitializeZerothFrame()
lldb_private::Thread & m_thread
void PropagateTrapHandlerFlagFromUnwindPlan(std::shared_ptr< const UnwindPlan > unwind_plan)
Check if the given unwind plan indicates a signal trap handler, and update frame type and symbol cont...
lldb_private::Address m_start_pc
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
void InitializeNonZerothFrame()
bool ReadRegisterValueFromRegisterLocation(lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc, const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
const lldb_private::RegisterSet * GetRegisterSet(size_t reg_set) override
bool m_behaves_like_zeroth_frame
std::shared_ptr< RegisterContextUnwind > SharedPtr
bool ReadFrameAddress(lldb::RegisterKind register_kind, const UnwindPlan::Row::FAValue &fa, lldb::addr_t &address)
bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override
void InvalidateAllRegisters() override
lldb::UnwindPlanSP TryAdoptArchitectureUnwindPlan()
RegisterContextUnwind(lldb_private::Thread &thread, const SharedPtr &next_frame, lldb_private::SymbolContext &sym_ctx, uint32_t frame_number, lldb_private::UnwindLLDB &unwind_lldb)
std::shared_ptr< const UnwindPlan > GetFastUnwindPlanForFrame()
std::shared_ptr< const UnwindPlan > m_fast_unwind_plan_sp
std::map< uint32_t, lldb_private::UnwindLLDB::ConcreteRegisterLocation > m_registers
std::shared_ptr< const UnwindPlan > GetFullUnwindPlanForFrame()
bool ReadPC(lldb::addr_t &start_pc)
bool ForceSwitchToFallbackUnwindPlan()
Switch to the fallback unwind plan unconditionally without any safety checks that it is providing bet...
size_t GetRegisterSetCount() override
lldb_private::UnwindLLDB::RegisterSearchResult SavedLocationForRegister(uint32_t lldb_regnum, lldb_private::UnwindLLDB::ConcreteRegisterLocation ®loc)
bool IsTrapHandlerFrame() const
bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum, lldb::addr_t &value)
lldb_private::UnwindLLDB & m_parent_unwind
bool WriteRegisterValueToRegisterLocation(lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc, const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
bool m_all_registers_available
bool TryFallbackUnwindPlan()
If the unwind has to the caller frame has failed, try something else.
std::optional< int > m_current_offset
How far into the function we've executed.
lldb_private::Address m_current_pc
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override
lldb::addr_t GetReturnAddressHint(int32_t plan_offset)
std::optional< int > m_current_offset_backed_up_one
bool IsTrapHandlerSymbol(lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const
Determines if a SymbolContext is a trap handler or not.
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
bool IsUnwindPlanValidForCurrentPC(std::shared_ptr< const UnwindPlan > unwind_plan_sp)
std::shared_ptr< const UnwindPlan > m_fallback_unwind_plan_sp
lldb_private::SymbolContext & m_sym_ctx
bool BehavesLikeZerothFrame() const override
Indicates that this frame is currently executing code, that the PC value is not a return-pc but an ac...
SharedPtr GetPrevFrame() const
std::shared_ptr< const UnwindPlan > m_full_unwind_plan_sp
SharedPtr GetNextFrame() const
size_t GetRegisterCount() override
bool GetStartPC(lldb::addr_t &start_pc)
virtual Status ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue ®_value)
RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
lldb::TargetSP CalculateTarget() override
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue ®_value)
bool SetUInt(uint64_t uint, uint32_t byte_size)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
RegisterValue::Type GetType() const
llvm::StringRef GetString() const
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Symbol * symbol
The Symbol for a given query.
ConstString GetName() const
lldb::PlatformSP GetPlatform()
const ArchSpec & GetArchitecture() const
void SetInRegister(uint32_t reg_num)
int GetDWARFExpressionLength() const
const uint8_t * GetDWARFExpressionBytes() const
int32_t GetOffset() const
ValueType GetValueType() const
uint64_t GetConstant() const
uint32_t GetRegisterNumber() const
const FAValue & GetAFAValue() const
const FAValue & GetCFAValue() const
bool GetRegisterInfo(uint32_t reg_num, AbstractRegisterLocation ®ister_location) const
void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, lldb::addr_t base_addr) const
bool GetUnspecifiedRegistersAreUndefined() const
@ LoadAddress
A load address value.
void SetValueType(ValueType value_type)
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
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::Platform > PlatformSP
std::shared_ptr< lldb_private::FuncUnwinders > FuncUnwindersSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
Registers are grouped into register sets.
An UnwindPlan::Row::AbstractRegisterLocation, combined with the register context and memory for a spe...
union lldb_private::UnwindLLDB::ConcreteRegisterLocation::@112231307016025255352221255122100277032134020214 location
@ eRegisterSavedAtHostMemoryLocation
@ eRegisterIsRegisterPlusOffset
@ eRegisterSavedAtMemoryLocation
@ eRegisterInLiveRegisterContext
lldb::addr_t target_memory_location
struct lldb_private::UnwindLLDB::ConcreteRegisterLocation::@112231307016025255352221255122100277032134020214::@342316333304072166237122265045271116073153235374 reg_plus_offset