zequanwu created this revision. zequanwu added reviewers: labath, clayborg, jasonmolenda. Herald added subscribers: atanasyan, jrtc27, kbarton, nemanjai, sdardis. Herald added a project: All. zequanwu requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
This adds stack scanning as fallback unwind plan to find a value that looks like return address. If the return address is not valid, continue scanning from next locatoin on stack when trying fallback unwind and the active row is `raSearch`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D124198 Files: lldb/include/lldb/Symbol/UnwindPlan.h lldb/include/lldb/Target/ABI.h lldb/include/lldb/Target/RegisterContextUnwind.h lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h lldb/source/Plugins/ABI/ARC/ABISysV_arc.h lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h lldb/source/Plugins/ABI/ARM/ABISysV_arm.h lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h lldb/source/Plugins/ABI/Mips/ABISysV_mips.h lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h lldb/source/Plugins/ABI/X86/ABISysV_i386.h lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp lldb/source/Symbol/UnwindPlan.cpp lldb/source/Target/RegisterContextUnwind.cpp lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test
Index: lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test =================================================================== --- lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test +++ lldb/test/Shell/SymbolFile/Breakpad/unwind-via-raSearch.test @@ -16,13 +16,13 @@ # CHECK: This UnwindPlan is valid at all instruction locations: no. # CHECK: This UnwindPlan is for a trap handler function: no. # CHECK: Address range of this UnwindPlan: [unwind-via-stack-win.exe..module_image + 4112-0x0000107d) -# CHECK: row[0]: 0: CFA=RaSearch@SP+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref +# CHECK: row[0]: 0: CFA=RaSearch@SP+0, offset=+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref image show-unwind -n nonzero_frame_size # CHECK-LABEL: image show-unwind -n nonzero_frame_size # CHECK: UNWIND PLANS for unwind-via-stack-win.exe`nonzero_frame_size # CHECK: Symbol file UnwindPlan: -# CHECK: row[0]: 0: CFA=RaSearch@SP+12 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref +# CHECK: row[0]: 0: CFA=RaSearch@SP+12, offset=+0 => esp=DW_OP_pick 0x0, DW_OP_consts +4, DW_OP_plus eip=DW_OP_pick 0x0, DW_OP_deref # Then, some invalid rules. image show-unwind -n complex_rasearch Index: lldb/source/Target/RegisterContextUnwind.cpp =================================================================== --- lldb/source/Target/RegisterContextUnwind.cpp +++ lldb/source/Target/RegisterContextUnwind.cpp @@ -285,7 +285,18 @@ cfa_status = true; } if (!cfa_status) { - UnwindLogMsg("could not read CFA value for first frame."); + UnwindLogMsg("could not read CFA value for first frame. Trying stack " + "walking unwind plan."); + if (abi) { + UnwindPlanSP stack_walk_unwind_plan = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (abi->CreateStackWalkingUnwindPlan(*stack_walk_unwind_plan)) { + m_fallback_unwind_plan_sp = stack_walk_unwind_plan; + cfa_status = TryFallbackUnwindPlan(); + } + } + } + if (!cfa_status) { m_frame_type = eNotAValidFrame; return; } @@ -384,7 +395,7 @@ // symbol/function information - just stick in some reasonable defaults and // hope we can unwind past this frame. If we're above a trap handler, // we may be at a bogus address because we jumped through a bogus function - // pointer and trapped, so don't force the arch default unwind plan in that + // pointer and trapped, so don't force the arch default unwind plan in that // case. ModuleSP pc_module_sp(m_current_pc.GetModule()); if ((!m_current_pc.IsValid() || !pc_module_sp) && @@ -660,9 +671,20 @@ } if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { - UnwindLogMsg("failed to get cfa"); - m_frame_type = eNotAValidFrame; - return; + UnwindLogMsg("failed to get cfa. Trying stack walking unwind plan."); + bool cfa_status = false; + if (abi) { + UnwindPlanSP stack_walk_unwind_plan = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (abi->CreateStackWalkingUnwindPlan(*stack_walk_unwind_plan)) { + m_fallback_unwind_plan_sp = stack_walk_unwind_plan; + cfa_status = TryFallbackUnwindPlan(); + } + } + if (!cfa_status) { + m_frame_type = eNotAValidFrame; + return; + } } ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); @@ -1287,7 +1309,7 @@ // arch default unwind plan is used as the Fast Unwind Plan, we // need to recognize this & switch over to the Full Unwind Plan // to see what unwind rule that (more knoweldgeable, probably) - // UnwindPlan has. If the full UnwindPlan says the register + // UnwindPlan has. If the full UnwindPlan says the register // location is Undefined, then it really is. if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), unwindplan_regloc) && @@ -1335,14 +1357,14 @@ m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM) { // If this is a trap handler frame, we should have access to - // the complete register context when the interrupt/async + // the complete register context when the interrupt/async // signal was received, we should fetch the actual saved $pc // value instead of the Return Address register. // If $pc is not available, fall back to the RA reg. UnwindPlan::Row::RegisterLocation scratch; if (m_frame_type == eTrapHandlerFrame && - active_row->GetRegisterInfo - (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) { + active_row->GetRegisterInfo( + pc_regnum.GetAsKind(unwindplan_registerkind), scratch)) { UnwindLogMsg("Providing pc register instead of rewriting to " "RA reg because this is a trap handler and there is " "a location for the saved pc register value."); @@ -1710,12 +1732,6 @@ if (m_full_unwind_plan_sp.get() == nullptr) return false; - if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || - m_full_unwind_plan_sp->GetSourceName() == - m_fallback_unwind_plan_sp->GetSourceName()) { - return false; - } - // If a compiler generated unwind plan failed, trying the arch default // unwindplan isn't going to do any better. if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) @@ -1771,71 +1787,86 @@ UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); - + UnwindPlan::Row::FAValue &fa = active_row->GetCFAValue(); if (active_row && - active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::FAValue::unspecified) { + fa.GetValueType() != UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; - if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { - UnwindLogMsg("failed to get cfa with fallback unwindplan"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - return false; + // If itn's not first attempt and ra search, update ra search offset before + // searching for cfa. Previous attempts may fail due to bad pc. + if (fa.IsRaSearch() && old_cfa != LLDB_INVALID_ADDRESS) { + addr_t sp; + if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp)) { + UnwindLogMsg("failed to get cfa with fallback unwindplan"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + return false; + } + Process &process = *m_thread.GetProcess(); + // It's the next stack offset location so that sp + next_search_offset == + // old_cfa + process.GetAddressByteSize(). + addr_t next_search_offset = + old_cfa - sp - fa.GetOffset() + process.GetAddressByteSize(); + fa.SetRaSearch(next_search_offset, fa.GetOffset()); } - m_cfa = new_cfa; - - ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetAFAValue(), m_afa); + if (ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), fa, + new_cfa) || + new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { - if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), - regloc) == - UnwindLLDB::RegisterSearchResult::eRegisterFound) { - const RegisterInfo *reg_info = - GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); - if (reg_info) { - RegisterValue reg_value; - if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, - reg_value)) { - new_caller_pc_value = reg_value.GetAsUInt64(); - if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi = process_sp->GetABI()) - new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value); + m_cfa = new_cfa; + + ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), + active_row->GetAFAValue(), m_afa); + + if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), + regloc) == + UnwindLLDB::RegisterSearchResult::eRegisterFound) { + const RegisterInfo *reg_info = + GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); + if (reg_info) { + RegisterValue reg_value; + if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, + reg_value)) { + new_caller_pc_value = reg_value.GetAsUInt64(); + if (ProcessSP process_sp = m_thread.GetProcess()) { + if (ABISP abi = process_sp->GetABI()) + new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value); + } } } } - } - if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { - UnwindLogMsg("failed to get a pc value for the caller frame with the " - "fallback unwind plan"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - m_cfa = old_cfa; - m_afa = old_afa; - return false; - } + if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { + UnwindLogMsg("failed to get a pc value for the caller frame with the " + "fallback unwind plan"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + m_cfa = old_cfa; + m_afa = old_afa; + return false; + } + + if (old_caller_pc_value == new_caller_pc_value && m_cfa == old_cfa && + m_afa == old_afa) { + UnwindLogMsg("fallback unwind plan got the same values for this frame " + "CFA and caller frame pc, not using"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + return false; + } + + UnwindLogMsg( + "trying to unwind from this function with the UnwindPlan '%s' " + "because UnwindPlan '%s' failed.", + m_fallback_unwind_plan_sp->GetSourceName().GetCString(), + original_full_unwind_plan_sp->GetSourceName().GetCString()); - if (old_caller_pc_value == new_caller_pc_value && - m_cfa == old_cfa && - m_afa == old_afa) { - UnwindLogMsg("fallback unwind plan got the same values for this frame " - "CFA and caller frame pc, not using"); + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); + } else { + UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); m_full_unwind_plan_sp = original_full_unwind_plan_sp; return false; } - - UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' " - "because UnwindPlan '%s' failed.", - m_fallback_unwind_plan_sp->GetSourceName().GetCString(), - original_full_unwind_plan_sp->GetSourceName().GetCString()); - - // We've copied the fallback unwind plan into the full - now clear the - // fallback. - m_fallback_unwind_plan_sp.reset(); - PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); } return true; @@ -2025,16 +2056,21 @@ } case UnwindPlan::Row::FAValue::isRaSearch: { Process &process = *m_thread.GetProcess(); - lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset()); - if (return_address_hint == LLDB_INVALID_ADDRESS) + addr_t sp; + if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp)) return false; + addr_t return_address_hint = sp + fa.GetRaSearchOffset(); + if (fa.IsFirstRaSearch()) + return_address_hint += GetParameterStackSize(); const unsigned max_iterations = 256; for (unsigned i = 0; i < max_iterations; ++i) { Status st; - lldb::addr_t candidate_addr = + addr_t candidate_addr = return_address_hint + i * process.GetAddressByteSize(); - lldb::addr_t candidate = - process.ReadPointerFromMemory(candidate_addr, st); + if (!process.GetABI()->CallFrameAddressIsValid(candidate_addr + + fa.GetOffset())) + continue; + addr_t candidate = process.ReadPointerFromMemory(candidate_addr, st); if (st.Fail()) { UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr, st.AsCString()); @@ -2044,7 +2080,7 @@ uint32_t permissions; if (process.GetLoadAddressPermissions(candidate, permissions) && permissions & lldb::ePermissionsExecutable) { - address = candidate_addr; + address = candidate_addr + fa.GetOffset(); UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address); return true; } @@ -2058,29 +2094,21 @@ return false; } -lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) { - addr_t hint; - if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint)) - return LLDB_INVALID_ADDRESS; - if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) - return LLDB_INVALID_ADDRESS; - - hint += plan_offset; - +addr_t RegisterContextUnwind::GetParameterStackSize() { if (auto next = GetNextFrame()) { if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol) - return LLDB_INVALID_ADDRESS; + return 0; if (auto expected_size = next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize( *next->m_sym_ctx.symbol)) - hint += *expected_size; + return *expected_size; else { UnwindLogMsgVerbose("Could not retrieve parameter size: %s", llvm::toString(expected_size.takeError()).c_str()); - return LLDB_INVALID_ADDRESS; + return 0; } } - return hint; + return 0; } // Retrieve a general purpose register value for THIS frame, as saved by the Index: lldb/source/Symbol/UnwindPlan.cpp =================================================================== --- lldb/source/Symbol/UnwindPlan.cpp +++ lldb/source/Symbol/UnwindPlan.cpp @@ -169,8 +169,11 @@ if (m_type == rhs.m_type) { switch (m_type) { case unspecified: + return true; case isRaSearch: - return m_value.ra_search_offset == rhs.m_value.ra_search_offset; + return m_value.ra_search.search_offset == + rhs.m_value.ra_search.search_offset && + m_value.ra_search.cfa_offset == rhs.m_value.ra_search.cfa_offset; case isRegisterPlusOffset: return m_value.reg.offset == rhs.m_value.reg.offset; @@ -209,7 +212,7 @@ s.PutCString("unspecified"); break; case isRaSearch: - s.Printf("RaSearch@SP%+d", m_value.ra_search_offset); + s.Printf("RaSearch@SP%+d, offset=%+d", GetRaSearchOffset(), GetOffset()); break; } } Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1255,7 +1255,7 @@ auto begin = scope.begin(); auto end = scope.end(); std::vector<clang::ParmVarDecl *> params; - while (begin != end && param_count > 0) { + for (uint32_t i = 0; i < param_count && begin != end;) { uint32_t record_offset = begin.offset(); CVSymbol sym = *begin++; @@ -1307,10 +1307,10 @@ m_uid_to_decl[toOpaqueUid(param_uid)] = param; params.push_back(param); - --param_count; + ++i; } - if (!params.empty()) + if (!params.empty() && params.size() == param_count) m_clang.SetFunctionParameters(&function_decl, params); } Index: lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -740,8 +740,8 @@ // clang will use T1, if it needs to realign the stack. auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second); if (symbol && symbol->GetName() == ".raSearch") { - row_sp->GetCFAValue().SetRaSearch(record->LocalSize + - record->SavedRegisterSize); + row_sp->GetCFAValue().SetRaSearch( + record->LocalSize + record->SavedRegisterSize, 0); } else { if (!postfix::ResolveSymbols(it->second, symbol_resolver)) { LLDB_LOG(log, "Resolving symbols in `{0}` failed.", Index: lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h =================================================================== --- lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h +++ lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h @@ -33,6 +33,9 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp =================================================================== --- lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp +++ lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp @@ -731,6 +731,27 @@ return return_valobj_sp; } +bool ABIWindows_x86_64::CreateStackWalkingUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindLLDB); + + uint32_t sp_reg_num = dwarf_rsp; + uint32_t pc_reg_num = dwarf_rip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetRaSearch(0, 8); + row->SetUnspecifiedRegistersAreUndefined(true); + + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("x86_64 stack-walking unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + // This defines the CFA as rsp+8 // the saved pc is at CFA-8 (i.e. rsp+0) // The saved rsp is CFA+0 Index: lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h =================================================================== --- lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h +++ lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h @@ -33,6 +33,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/X86/ABISysV_i386.h =================================================================== --- lldb/source/Plugins/ABI/X86/ABISysV_i386.h +++ lldb/source/Plugins/ABI/X86/ABISysV_i386.h @@ -36,6 +36,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h =================================================================== --- lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h +++ lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h @@ -30,6 +30,11 @@ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h =================================================================== --- lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h +++ lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h @@ -34,6 +34,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h =================================================================== --- lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h +++ lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h @@ -34,6 +34,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h =================================================================== --- lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h +++ lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h @@ -34,6 +34,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h =================================================================== --- lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h +++ lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h @@ -34,6 +34,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/Mips/ABISysV_mips.h =================================================================== --- lldb/source/Plugins/ABI/Mips/ABISysV_mips.h +++ lldb/source/Plugins/ABI/Mips/ABISysV_mips.h @@ -34,6 +34,11 @@ GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h =================================================================== --- lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h +++ lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h @@ -46,6 +46,11 @@ lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, llvm::Type &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/ARM/ABISysV_arm.h =================================================================== --- lldb/source/Plugins/ABI/ARM/ABISysV_arm.h +++ lldb/source/Plugins/ABI/ARM/ABISysV_arm.h @@ -29,6 +29,11 @@ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h =================================================================== --- lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h +++ lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h @@ -29,6 +29,11 @@ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/ARC/ABISysV_arc.h =================================================================== --- lldb/source/Plugins/ABI/ARC/ABISysV_arc.h +++ lldb/source/Plugins/ABI/ARC/ABISysV_arc.h @@ -49,6 +49,11 @@ lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, llvm::Type &type) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h +++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h @@ -30,6 +30,11 @@ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -27,6 +27,11 @@ bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override; + bool + CreateStackWalkingUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override { + return false; + } + bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; Index: lldb/include/lldb/Target/RegisterContextUnwind.h =================================================================== --- lldb/include/lldb/Target/RegisterContextUnwind.h +++ lldb/include/lldb/Target/RegisterContextUnwind.h @@ -206,7 +206,7 @@ bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset); - lldb::addr_t GetReturnAddressHint(int32_t plan_offset); + lldb::addr_t GetParameterStackSize(); lldb_private::Thread &m_thread; Index: lldb/include/lldb/Target/ABI.h =================================================================== --- lldb/include/lldb/Target/ABI.h +++ lldb/include/lldb/Target/ABI.h @@ -96,6 +96,8 @@ lldb::ProcessSP GetProcessSP() const { return m_process_wp.lock(); } public: + virtual bool CreateStackWalkingUnwindPlan(UnwindPlan &unwind_plan) = 0; + virtual bool CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) = 0; virtual bool CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) = 0; Index: lldb/include/lldb/Symbol/UnwindPlan.h =================================================================== --- lldb/include/lldb/Symbol/UnwindPlan.h +++ lldb/include/lldb/Symbol/UnwindPlan.h @@ -215,9 +215,16 @@ bool IsUnspecified() const { return m_type == unspecified; } - void SetRaSearch(int32_t offset) { + bool IsRaSearch() const { return m_type == isRaSearch; } + + void SetRaSearch(int32_t search_offset, int32_t cfa_offset) { + m_value.ra_search.search_offset = search_offset; + m_value.ra_search.cfa_offset = cfa_offset; + if (m_type == isRaSearch) { + // Not the first search. + m_value.ra_search.search_offset |= 1; + } m_type = isRaSearch; - m_value.ra_search_offset = offset; } bool IsRegisterPlusOffset() const { @@ -255,12 +262,20 @@ ValueType GetValueType() const { return m_type; } + int32_t GetRaSearchOffset() const { + return m_type == isRaSearch ? m_value.ra_search.search_offset & ~1 : 0; + } + + bool IsFirstRaSearch() const { + return m_value.ra_search.search_offset % 2 == 0; + } + int32_t GetOffset() const { switch (m_type) { case isRegisterPlusOffset: return m_value.reg.offset; case isRaSearch: - return m_value.ra_search_offset; + return m_value.ra_search.cfa_offset; default: return 0; } @@ -316,7 +331,12 @@ uint16_t length; } expr; // For m_type == isRaSearch - int32_t ra_search_offset; + struct { + // If last bit of search_offset is 0, it's the first try in this + // ra_search. + int32_t search_offset; + int32_t cfa_offset; + } ra_search; } m_value; }; // class FAValue
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits