[Lldb-commits] [lldb] [lldb] Fix Block::GetRangeIndexContainingAddress for discontinuous functions (PR #124931)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Jan 29 07:21:24 PST 2025


https://github.com/labath created https://github.com/llvm/llvm-project/pull/124931

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).

>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] [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 139fa06d08fca5..bddb015333e09c 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 2e2bc52cd3ff99..4d42c50467da06 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



More information about the lldb-commits mailing list