[Lldb-commits] [lldb] [lldb] Support negative function offsets in UnwindPlans (PR #134662)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Apr 7 07:47:09 PDT 2025
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 <pavel at 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) {
More information about the lldb-commits
mailing list