[Lldb-commits] [lldb] [lldb] Fix Block::GetRangeIndexContainingAddress for discontinuous functions (PR #124931)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Feb 13 00:04:08 PST 2025
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/124931
>From 7e4fa296561789ae95980ac0c1468573e80ef0cc Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Wed, 29 Jan 2025 16:15:44 +0100
Subject: [PATCH 1/3] [lldb] Fix Block::GetRangeIndexContainingAddress for
discontinuous functions
This is a followup to #122440, which changed function-relative
calculations to use the function entry point rather than the lowest
address of the function (but missed this usage). Like in #116777, the
logic is changed to use file addresses instead of section offsets (as
not all parts of the function have to be in the same section).
---
lldb/source/Symbol/Block.cpp | 51 +++++++------------
.../Python/sb_function_ranges.s | 37 +++++++++-----
2 files changed, 43 insertions(+), 45 deletions(-)
diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp
index 139fa06d08fca..bddb015333e09 100644
--- a/lldb/source/Symbol/Block.cpp
+++ b/lldb/source/Symbol/Block.cpp
@@ -243,25 +243,15 @@ bool Block::GetRangeContainingAddress(const Address &addr,
AddressRange &range) {
Function *function = CalculateSymbolContextFunction();
if (function) {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetModule() == func_range.GetBaseAddress().GetModule()) {
- const addr_t file_addr = addr.GetFileAddress();
- const addr_t func_file_addr =
- func_range.GetBaseAddress().GetFileAddress();
- if (file_addr >= func_file_addr &&
- file_addr < func_file_addr + func_range.GetByteSize()) {
- addr_t offset = file_addr - func_file_addr;
-
- const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
-
- if (range_ptr) {
- range.GetBaseAddress() =
- Address(func_file_addr + range_ptr->GetRangeBase(),
- addr.GetModule()->GetSectionList());
- range.SetByteSize(range_ptr->GetByteSize());
- return true;
- }
- }
+ if (uint32_t idx = GetRangeIndexContainingAddress(addr);
+ idx != UINT32_MAX) {
+ const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
+ assert(range_ptr);
+
+ range.GetBaseAddress() = function->GetAddress();
+ range.GetBaseAddress().Slide(range_ptr->GetRangeBase());
+ range.SetByteSize(range_ptr->GetByteSize());
+ return true;
}
}
range.Clear();
@@ -278,19 +268,16 @@ bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
Function *function = CalculateSymbolContextFunction();
- if (function) {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
- const addr_t addr_offset = addr.GetOffset();
- const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
- if (addr_offset >= func_offset &&
- addr_offset < func_offset + func_range.GetByteSize()) {
- addr_t offset = addr_offset - func_offset;
- return m_ranges.FindEntryIndexThatContains(offset);
- }
- }
- }
- return UINT32_MAX;
+ if (!function)
+ return UINT32_MAX;
+
+ const Address &func_addr = function->GetAddress();
+ if (addr.GetModule() != func_addr.GetModule())
+ return UINT32_MAX;
+
+ const addr_t file_addr = addr.GetFileAddress();
+ const addr_t func_file_addr = func_addr.GetFileAddress();
+ return m_ranges.FindEntryIndexThatContains(file_addr - func_file_addr);
}
bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
diff --git a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
index 2e2bc52cd3ff9..4d42c50467da0 100644
--- a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
+++ b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
@@ -6,15 +6,22 @@
# CHECK: Found 1 function(s).
# CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]
-# CHECK-NEXT: input.o[0x0]: cmpl $0x0, %edi
-# CHECK-NEXT: input.o[0x3]: je 0x14
-# CHECK-NEXT: input.o[0x5]: jmp 0x7
-# CHECK-NEXT: input.o[0x7]: callq 0xe
-# CHECK-NEXT: input.o[0xc]: jmp 0x1b
+# CHECK-NEXT: input.o[0x0]: callq 0xe
+# CHECK-NEXT: input.o[0x5]: jmp 0x1b
+# CHECK-NEXT: input.o[0x7]: cmpl $0x0, %edi
+# CHECK-NEXT: input.o[0xa]: je 0x14
+# CHECK-NEXT: input.o[0xc]: jmp 0x0
# CHECK-EMPTY:
# CHECK-NEXT: input.o[0x14]: callq 0x19
# CHECK-NEXT: input.o[0x19]: jmp 0x1b
# CHECK-NEXT: input.o[0x1b]: retq
+# CHECK-NEXT: offset 0x00 => index 0
+# CHECK-NEXT: offset 0x0c => index 0
+# CHECK-NEXT: offset 0x0e => index ffffffff
+# CHECK-NEXT: offset 0x13 => index ffffffff
+# CHECK-NEXT: offset 0x14 => index 1
+# CHECK-NEXT: offset 0x1b => index 1
+# CHECK-NEXT: offset 0x1c => index ffffffff
#--- script.py
@@ -28,6 +35,10 @@ def __lldb_init_module(debugger, internal_dict):
fn = ctx.function
print(f"{fn.name}: {fn.GetRanges()}")
print(fn.GetInstructions(target))
+ text = fn.addr.section
+ for offset in [0x00, 0x0c, 0x0e, 0x13, 0x14, 0x1b, 0x1c]:
+ idx = fn.block.GetRangeIndexForBlockAddress(lldb.SBAddress(text, offset))
+ print(f"offset 0x{offset:02x} => index {idx:x}")
#--- input.s
# An example of a function which has been split into two parts. Roughly
@@ -40,6 +51,14 @@ def __lldb_init_module(debugger, internal_dict):
.text
.type foo, at function
+foo.__part.1:
+ .cfi_startproc
+ callq bar
+ jmp foo.__part.3
+.Lfoo.__part.1_end:
+ .size foo.__part.1, .Lfoo.__part.1_end-foo.__part.1
+ .cfi_endproc
+
foo:
.cfi_startproc
cmpl $0, %edi
@@ -49,14 +68,6 @@ foo:
.Lfoo_end:
.size foo, .Lfoo_end-foo
-foo.__part.1:
- .cfi_startproc
- callq bar
- jmp foo.__part.3
-.Lfoo.__part.1_end:
- .size foo.__part.1, .Lfoo.__part.1_end-foo.__part.1
- .cfi_endproc
-
bar:
.cfi_startproc
movl $47, %eax
>From 94ec2e937a71fd57f961ce7320f8d5dd70f41fde Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Tue, 4 Feb 2025 17:39:31 +0100
Subject: [PATCH 2/3] fix sliding
---
lldb/source/Symbol/Block.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp
index bddb015333e09..6ecc988d7a5a9 100644
--- a/lldb/source/Symbol/Block.cpp
+++ b/lldb/source/Symbol/Block.cpp
@@ -248,8 +248,10 @@ bool Block::GetRangeContainingAddress(const Address &addr,
const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
assert(range_ptr);
- range.GetBaseAddress() = function->GetAddress();
- range.GetBaseAddress().Slide(range_ptr->GetRangeBase());
+ Address func_addr = function->GetAddress();
+ range.GetBaseAddress() =
+ Address(func_addr.GetFileAddress() + range_ptr->GetRangeBase(),
+ func_addr.GetModule()->GetSectionList());
range.SetByteSize(range_ptr->GetByteSize());
return true;
}
>From 362f8f468eafe5ea55ccfbd6a0636a685a7234e0 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 13 Feb 2025 09:03:59 +0100
Subject: [PATCH 3/3] Add comment
---
lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
index 4d42c50467da0..1b15561c54283 100644
--- a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
+++ b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
@@ -15,6 +15,8 @@
# CHECK-NEXT: input.o[0x14]: callq 0x19
# CHECK-NEXT: input.o[0x19]: jmp 0x1b
# CHECK-NEXT: input.o[0x1b]: retq
+## Testing the GetRangeIndexForBlockAddress API. "ffffffff" indicates that
+## the address does not belong to any range.
# CHECK-NEXT: offset 0x00 => index 0
# CHECK-NEXT: offset 0x0c => index 0
# CHECK-NEXT: offset 0x0e => index ffffffff
More information about the lldb-commits
mailing list