https://github.com/labath created https://github.com/llvm/llvm-project/pull/134662
These are needed for functions whose entry point is not their lowest address. >From 10a1029d776bf5dcae5fe69a72883916de7c4b5f Mon Sep 17 00:00:00 2001 From: Pavel Labath <pa...@labath.sk> Date: Fri, 4 Apr 2025 11:37:34 +0200 Subject: [PATCH] [lldb] Support negative function offsets in UnwindPlans These are needed for functions whose entry point is not their lowest address. --- lldb/include/lldb/Symbol/UnwindPlan.h | 10 +++++----- .../UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp | 5 +++-- lldb/source/Symbol/DWARFCallFrameInfo.cpp | 2 +- lldb/source/Symbol/UnwindPlan.cpp | 6 +++--- lldb/unittests/Symbol/UnwindPlanTest.cpp | 5 +++++ 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index 6640a23a3e868..410289851a879 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -356,11 +356,11 @@ class UnwindPlan { void RemoveRegisterInfo(uint32_t reg_num); - lldb::addr_t GetOffset() const { return m_offset; } + int64_t GetOffset() const { return m_offset; } - void SetOffset(lldb::addr_t offset) { m_offset = offset; } + void SetOffset(int64_t offset) { m_offset = offset; } - void SlideOffset(lldb::addr_t offset) { m_offset += offset; } + void SlideOffset(int64_t offset) { m_offset += offset; } const FAValue &GetCFAValue() const { return m_cfa_value; } FAValue &GetCFAValue() { return m_cfa_value; } @@ -420,7 +420,7 @@ class UnwindPlan { protected: typedef std::map<uint32_t, AbstractRegisterLocation> collection; - lldb::addr_t m_offset = 0; // Offset into the function for this row + int64_t m_offset = 0; // Offset into the function for this row FAValue m_cfa_value; FAValue m_afa_value; @@ -472,7 +472,7 @@ class UnwindPlan { // practice, the UnwindPlan for a function with no known start address will be // the architectural default UnwindPlan which will only have one row. const UnwindPlan::Row * - GetRowForFunctionOffset(std::optional<int> offset) const; + GetRowForFunctionOffset(std::optional<int64_t> offset) const; lldb::RegisterKind GetRegisterKind() const { return m_register_kind; } diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp index 3eaa2f33fce3e..aaff278ca31e2 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp +++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp @@ -1390,11 +1390,12 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite( // If we already have one row for this instruction, we can continue. while (row_id < unwind_plan.GetRowCount() && - unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) { + unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= + static_cast<int64_t>(offset)) { row_id++; } const UnwindPlan::Row *original_row = unwind_plan.GetRowAtIndex(row_id - 1); - if (original_row->GetOffset() == offset) { + if (original_row->GetOffset() == static_cast<int64_t>(offset)) { row = *original_row; continue; } diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp index 957818e8d077f..dca3f665b0b80 100644 --- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -765,7 +765,7 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset, __FUNCTION__, dwarf_offset, startaddr.GetFileAddress()); break; } - lldb::addr_t offset = row.GetOffset(); + int64_t offset = row.GetOffset(); row = std::move(stack.back()); stack.pop_back(); row.SetOffset(offset); diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index cfa8eefaa55bb..33aba0a859d5c 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -398,10 +398,10 @@ void UnwindPlan::AppendRow(Row row) { } struct RowLess { - bool operator()(addr_t a, const UnwindPlan::RowSP &b) const { + bool operator()(int64_t a, const UnwindPlan::RowSP &b) const { return a < b->GetOffset(); } - bool operator()(const UnwindPlan::RowSP &a, addr_t b) const { + bool operator()(const UnwindPlan::RowSP &a, int64_t b) const { return a->GetOffset() < b; } }; @@ -418,7 +418,7 @@ void UnwindPlan::InsertRow(Row row, bool replace_existing) { } const UnwindPlan::Row * -UnwindPlan::GetRowForFunctionOffset(std::optional<int> offset) const { +UnwindPlan::GetRowForFunctionOffset(std::optional<int64_t> offset) const { auto it = offset ? llvm::upper_bound(m_row_list, *offset, RowLess()) : m_row_list.end(); if (it == m_row_list.begin()) diff --git a/lldb/unittests/Symbol/UnwindPlanTest.cpp b/lldb/unittests/Symbol/UnwindPlanTest.cpp index fa8bb153e9247..08aa5b2dd84bb 100644 --- a/lldb/unittests/Symbol/UnwindPlanTest.cpp +++ b/lldb/unittests/Symbol/UnwindPlanTest.cpp @@ -24,6 +24,7 @@ static UnwindPlan::Row make_simple_row(addr_t offset, uint64_t cfa_value) { TEST(UnwindPlan, InsertRow) { UnwindPlan::Row row1 = make_simple_row(0, 42); UnwindPlan::Row row2 = make_simple_row(0, 47); + UnwindPlan::Row row3 = make_simple_row(-1, 4242); UnwindPlan plan(eRegisterKindGeneric); plan.InsertRow(row1); @@ -34,6 +35,10 @@ TEST(UnwindPlan, InsertRow) { plan.InsertRow(row2, /*replace_existing=*/true); EXPECT_THAT(plan.GetRowForFunctionOffset(0), testing::Pointee(row2)); + + EXPECT_THAT(plan.GetRowForFunctionOffset(-1), nullptr); + plan.InsertRow(row3); + EXPECT_THAT(plan.GetRowForFunctionOffset(-1), testing::Pointee(row3)); } TEST(UnwindPlan, GetRowForFunctionOffset) { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits