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