[Lldb-commits] [lldb] [lldb] Fix prologue size calculation for discontinuous functions (PR #131597)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Mar 19 04:51:53 PDT 2025
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/131597
>From 9874a78efa086dfc3168a514051a521964ad55f3 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 17 Mar 2025 11:12:44 +0100
Subject: [PATCH 1/2] [lldb] Fix prologue size calculation for discontinuous
functions
When searching for the end of prologue, I'm only iterating through the
address range (~basic block) which contains the function entry point.
The reason for that is that even if some other range somehow contained
the end-of-prologue marker, the fact that it's in a different range
would imply it's reachable through some form of control flow, and that's
usually not a good place to set an function entry breakpoint.
---
lldb/source/Symbol/Function.cpp | 20 ++++++++-------
.../DWARF/x86/discontinuous-function.s | 25 +++++++++++++++++--
2 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index c80f37ae68d9d..61e788da0e50b 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -662,10 +662,12 @@ uint32_t Function::GetPrologueByteSize() {
}
}
- const addr_t func_start_file_addr =
- m_range.GetBaseAddress().GetFileAddress();
- const addr_t func_end_file_addr =
- func_start_file_addr + m_range.GetByteSize();
+ AddressRange entry_range;
+ m_block.GetRangeContainingAddress(m_address, entry_range);
+ const addr_t range_start_file_addr = m_address.GetFileAddress();
+ const addr_t range_end_file_addr =
+ entry_range.GetBaseAddress().GetFileAddress() +
+ entry_range.GetByteSize();
// Now calculate the offset to pass the subsequent line 0 entries.
uint32_t first_non_zero_line = prologue_end_line_idx;
@@ -677,7 +679,7 @@ uint32_t Function::GetPrologueByteSize() {
break;
}
if (line_entry.range.GetBaseAddress().GetFileAddress() >=
- func_end_file_addr)
+ range_end_file_addr)
break;
first_non_zero_line++;
@@ -694,13 +696,13 @@ uint32_t Function::GetPrologueByteSize() {
// Verify that this prologue end file address in the function's address
// range just to be sure
- if (func_start_file_addr < prologue_end_file_addr &&
- prologue_end_file_addr < func_end_file_addr) {
- m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
+ if (range_start_file_addr < prologue_end_file_addr &&
+ prologue_end_file_addr < range_end_file_addr) {
+ m_prologue_byte_size = prologue_end_file_addr - range_start_file_addr;
}
if (prologue_end_file_addr < line_zero_end_file_addr &&
- line_zero_end_file_addr < func_end_file_addr) {
+ line_zero_end_file_addr < range_end_file_addr) {
m_prologue_byte_size +=
line_zero_end_file_addr - prologue_end_file_addr;
}
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
index 197ab9aa14910..06934c2bfe9c4 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
@@ -16,22 +16,32 @@ image lookup -v -n foo
# CHECK-LABEL: image lookup -v -n foo
# CHECK: 1 match found in {{.*}}
# CHECK: Summary: input.o`foo
-# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
+# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000f)[0x0000000000000015-0x000000000000001d)
image lookup -v --regex -n '^foo$'
# CHECK-LABEL: image lookup -v --regex -n '^foo$'
# CHECK: 1 match found in {{.*}}
# CHECK: Summary: input.o`foo
-# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
+# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000f)[0x0000000000000015-0x000000000000001d)
expr -- &foo
# CHECK-LABEL: expr -- &foo
# CHECK: (void (*)()) $0 = 0x0000000000000007
+breakpoint set --name foo --skip-prologue false
+# CHECK-LABEL: breakpoint set --name foo --skip-prologue false
+# CHECK: Breakpoint 1: where = input.o`foo at -:1, address = 0x0000000000000007
+
+breakpoint set --name foo --skip-prologue true
+# CHECK-LABEL: breakpoint set --name foo --skip-prologue true
+# CHECK: Breakpoint 2: where = input.o`foo + 1 at -:2, address = 0x0000000000000008
+
#--- input.s
.text
+ .file 0 "." "-"
foo.__part.1:
+ .loc 0 10
.cfi_startproc
callq bar
jmp foo.__part.3
@@ -41,7 +51,10 @@ foo.__part.1:
.type foo, at function
foo:
+ .loc 0 1
.cfi_startproc
+ nop
+ .loc 0 2 prologue_end
cmpl $0, %edi
je foo.__part.2
jmp foo.__part.1
@@ -51,6 +64,7 @@ foo:
bar:
.cfi_startproc
+ .loc 0 100
movl $47, %eax
retq
.cfi_endproc
@@ -58,6 +72,7 @@ bar:
.size bar, .Lbar_end-bar
foo.__part.2:
+ .loc 0 20
.cfi_startproc
callq baz
jmp foo.__part.3
@@ -66,6 +81,7 @@ foo.__part.2:
.cfi_endproc
foo.__part.3:
+ .loc 0 30
.cfi_startproc
retq
.Lfoo.__part.3_end:
@@ -87,6 +103,8 @@ foo.__part.3:
.byte 35 # DW_FORM_rnglistx
.byte 116 # DW_AT_rnglists_base
.byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
@@ -127,6 +145,7 @@ foo.__part.3:
.quad 0 # DW_AT_low_pc
.byte 1 # DW_AT_ranges
.long .Lrnglists_table_base0 # DW_AT_rnglists_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
.byte 2 # Abbrev [2] DW_TAG_subprogram
.quad bar # DW_AT_low_pc
.quad .Lbar_end # DW_AT_high_pc
@@ -183,3 +202,5 @@ foo.__part.3:
.Ldebug_list_header_end0:
.section ".note.GNU-stack","", at progbits
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
>From 2b7e15a3ee841813dc8660fcb4209a32ecf60b48 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Wed, 19 Mar 2025 12:51:35 +0100
Subject: [PATCH 2/2] add comment
---
lldb/source/Symbol/Function.cpp | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 61e788da0e50b..2c4467cc2e9c5 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -664,7 +664,10 @@ uint32_t Function::GetPrologueByteSize() {
AddressRange entry_range;
m_block.GetRangeContainingAddress(m_address, entry_range);
- const addr_t range_start_file_addr = m_address.GetFileAddress();
+
+ // Deliberately not starting at entry_range.GetBaseAddress() because the
+ // function entry point need not be the first address in the range.
+ const addr_t func_start_file_addr = m_address.GetFileAddress();
const addr_t range_end_file_addr =
entry_range.GetBaseAddress().GetFileAddress() +
entry_range.GetByteSize();
@@ -694,11 +697,11 @@ uint32_t Function::GetPrologueByteSize() {
}
}
- // Verify that this prologue end file address in the function's address
- // range just to be sure
- if (range_start_file_addr < prologue_end_file_addr &&
+ // Verify that this prologue end file address inside the function just
+ // to be sure
+ if (func_start_file_addr < prologue_end_file_addr &&
prologue_end_file_addr < range_end_file_addr) {
- m_prologue_byte_size = prologue_end_file_addr - range_start_file_addr;
+ m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
}
if (prologue_end_file_addr < line_zero_end_file_addr &&
More information about the lldb-commits
mailing list