Skip to content

Commit fdeb2ff

Browse files
authored
[lldb] Fix prologue size calculation for discontinuous functions (#131597)
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.
1 parent ff3341c commit fdeb2ff

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

lldb/source/Symbol/Function.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -662,10 +662,15 @@ uint32_t Function::GetPrologueByteSize() {
662662
}
663663
}
664664

665-
const addr_t func_start_file_addr =
666-
m_range.GetBaseAddress().GetFileAddress();
667-
const addr_t func_end_file_addr =
668-
func_start_file_addr + m_range.GetByteSize();
665+
AddressRange entry_range;
666+
m_block.GetRangeContainingAddress(m_address, entry_range);
667+
668+
// Deliberately not starting at entry_range.GetBaseAddress() because the
669+
// function entry point need not be the first address in the range.
670+
const addr_t func_start_file_addr = m_address.GetFileAddress();
671+
const addr_t range_end_file_addr =
672+
entry_range.GetBaseAddress().GetFileAddress() +
673+
entry_range.GetByteSize();
669674

670675
// Now calculate the offset to pass the subsequent line 0 entries.
671676
uint32_t first_non_zero_line = prologue_end_line_idx;
@@ -677,7 +682,7 @@ uint32_t Function::GetPrologueByteSize() {
677682
break;
678683
}
679684
if (line_entry.range.GetBaseAddress().GetFileAddress() >=
680-
func_end_file_addr)
685+
range_end_file_addr)
681686
break;
682687

683688
first_non_zero_line++;
@@ -692,15 +697,15 @@ uint32_t Function::GetPrologueByteSize() {
692697
}
693698
}
694699

695-
// Verify that this prologue end file address in the function's address
696-
// range just to be sure
700+
// Verify that this prologue end file address inside the function just
701+
// to be sure
697702
if (func_start_file_addr < prologue_end_file_addr &&
698-
prologue_end_file_addr < func_end_file_addr) {
703+
prologue_end_file_addr < range_end_file_addr) {
699704
m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
700705
}
701706

702707
if (prologue_end_file_addr < line_zero_end_file_addr &&
703-
line_zero_end_file_addr < func_end_file_addr) {
708+
line_zero_end_file_addr < range_end_file_addr) {
704709
m_prologue_byte_size +=
705710
line_zero_end_file_addr - prologue_end_file_addr;
706711
}

lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,32 @@ image lookup -v -n foo
1616
# CHECK-LABEL: image lookup -v -n foo
1717
# CHECK: 1 match found in {{.*}}
1818
# CHECK: Summary: input.o`foo
19-
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
19+
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000f)[0x0000000000000015-0x000000000000001d)
2020

2121
image lookup -v --regex -n '^foo$'
2222
# CHECK-LABEL: image lookup -v --regex -n '^foo$'
2323
# CHECK: 1 match found in {{.*}}
2424
# CHECK: Summary: input.o`foo
25-
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
25+
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000f)[0x0000000000000015-0x000000000000001d)
2626

2727
expr -- &foo
2828
# CHECK-LABEL: expr -- &foo
2929
# CHECK: (void (*)()) $0 = 0x0000000000000007
3030

31+
breakpoint set --name foo --skip-prologue false
32+
# CHECK-LABEL: breakpoint set --name foo --skip-prologue false
33+
# CHECK: Breakpoint 1: where = input.o`foo at -:1, address = 0x0000000000000007
34+
35+
breakpoint set --name foo --skip-prologue true
36+
# CHECK-LABEL: breakpoint set --name foo --skip-prologue true
37+
# CHECK: Breakpoint 2: where = input.o`foo + 1 at -:2, address = 0x0000000000000008
38+
3139
#--- input.s
3240
.text
3341

42+
.file 0 "." "-"
3443
foo.__part.1:
44+
.loc 0 10
3545
.cfi_startproc
3646
callq bar
3747
jmp foo.__part.3
@@ -41,7 +51,10 @@ foo.__part.1:
4151

4252
.type foo,@function
4353
foo:
54+
.loc 0 1
4455
.cfi_startproc
56+
nop
57+
.loc 0 2 prologue_end
4558
cmpl $0, %edi
4659
je foo.__part.2
4760
jmp foo.__part.1
@@ -51,13 +64,15 @@ foo:
5164

5265
bar:
5366
.cfi_startproc
67+
.loc 0 100
5468
movl $47, %eax
5569
retq
5670
.cfi_endproc
5771
.Lbar_end:
5872
.size bar, .Lbar_end-bar
5973

6074
foo.__part.2:
75+
.loc 0 20
6176
.cfi_startproc
6277
callq baz
6378
jmp foo.__part.3
@@ -66,6 +81,7 @@ foo.__part.2:
6681
.cfi_endproc
6782

6883
foo.__part.3:
84+
.loc 0 30
6985
.cfi_startproc
7086
retq
7187
.Lfoo.__part.3_end:
@@ -87,6 +103,8 @@ foo.__part.3:
87103
.byte 35 # DW_FORM_rnglistx
88104
.byte 116 # DW_AT_rnglists_base
89105
.byte 23 # DW_FORM_sec_offset
106+
.byte 16 # DW_AT_stmt_list
107+
.byte 23 # DW_FORM_sec_offset
90108
.byte 0 # EOM(1)
91109
.byte 0 # EOM(2)
92110
.byte 2 # Abbreviation Code
@@ -127,6 +145,7 @@ foo.__part.3:
127145
.quad 0 # DW_AT_low_pc
128146
.byte 1 # DW_AT_ranges
129147
.long .Lrnglists_table_base0 # DW_AT_rnglists_base
148+
.long .Lline_table_start0 # DW_AT_stmt_list
130149
.byte 2 # Abbrev [2] DW_TAG_subprogram
131150
.quad bar # DW_AT_low_pc
132151
.quad .Lbar_end # DW_AT_high_pc
@@ -183,3 +202,5 @@ foo.__part.3:
183202
.Ldebug_list_header_end0:
184203

185204
.section ".note.GNU-stack","",@progbits
205+
.section .debug_line,"",@progbits
206+
.Lline_table_start0:

0 commit comments

Comments
 (0)