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 <pa...@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,@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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits