Skip to content

[lldb] Fix prologue size calculation for discontinuous functions #131597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions lldb/source/Symbol/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to do it this way rather than:

const addr_t range_start_file_addr = entry_range.GetBaseAddress().GetFileAddress();
const addr_t range_end_file_addr = range_start_file_addr + entry_range.GetByteSize();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because in the most general case, the entry point may not be at the start of any particular range (either because of a perverse compiler or because the linker placed two of the ranges next to each other and we have merged them into one).

I'm going to add a comment about that.


// Now calculate the offset to pass the subsequent line 0 entries.
uint32_t first_non_zero_line = prologue_end_line_idx;
Expand All @@ -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++;
Expand All @@ -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;
}
Expand Down
25 changes: 23 additions & 2 deletions lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -41,7 +51,10 @@ foo.__part.1:

.type foo,@function
foo:
.loc 0 1
.cfi_startproc
nop
.loc 0 2 prologue_end
cmpl $0, %edi
je foo.__part.2
jmp foo.__part.1
Expand All @@ -51,13 +64,15 @@ foo:

bar:
.cfi_startproc
.loc 0 100
movl $47, %eax
retq
.cfi_endproc
.Lbar_end:
.size bar, .Lbar_end-bar

foo.__part.2:
.loc 0 20
.cfi_startproc
callq baz
jmp foo.__part.3
Expand All @@ -66,6 +81,7 @@ foo.__part.2:
.cfi_endproc

foo.__part.3:
.loc 0 30
.cfi_startproc
retq
.Lfoo.__part.3_end:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -183,3 +202,5 @@ foo.__part.3:
.Ldebug_list_header_end0:

.section ".note.GNU-stack","",@progbits
.section .debug_line,"",@progbits
.Lline_table_start0: