Skip to content

Commit 7e4fa29

Browse files
committed
[lldb] Fix Block::GetRangeIndexContainingAddress for discontinuous functions
This is a followup to llvm#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 llvm#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).
1 parent b968fd9 commit 7e4fa29

File tree

2 files changed

+43
-45
lines changed

2 files changed

+43
-45
lines changed

lldb/source/Symbol/Block.cpp

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,15 @@ bool Block::GetRangeContainingAddress(const Address &addr,
243243
AddressRange &range) {
244244
Function *function = CalculateSymbolContextFunction();
245245
if (function) {
246-
const AddressRange &func_range = function->GetAddressRange();
247-
if (addr.GetModule() == func_range.GetBaseAddress().GetModule()) {
248-
const addr_t file_addr = addr.GetFileAddress();
249-
const addr_t func_file_addr =
250-
func_range.GetBaseAddress().GetFileAddress();
251-
if (file_addr >= func_file_addr &&
252-
file_addr < func_file_addr + func_range.GetByteSize()) {
253-
addr_t offset = file_addr - func_file_addr;
254-
255-
const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
256-
257-
if (range_ptr) {
258-
range.GetBaseAddress() =
259-
Address(func_file_addr + range_ptr->GetRangeBase(),
260-
addr.GetModule()->GetSectionList());
261-
range.SetByteSize(range_ptr->GetByteSize());
262-
return true;
263-
}
264-
}
246+
if (uint32_t idx = GetRangeIndexContainingAddress(addr);
247+
idx != UINT32_MAX) {
248+
const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
249+
assert(range_ptr);
250+
251+
range.GetBaseAddress() = function->GetAddress();
252+
range.GetBaseAddress().Slide(range_ptr->GetRangeBase());
253+
range.SetByteSize(range_ptr->GetByteSize());
254+
return true;
265255
}
266256
}
267257
range.Clear();
@@ -278,19 +268,16 @@ bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
278268

279269
uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
280270
Function *function = CalculateSymbolContextFunction();
281-
if (function) {
282-
const AddressRange &func_range = function->GetAddressRange();
283-
if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
284-
const addr_t addr_offset = addr.GetOffset();
285-
const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
286-
if (addr_offset >= func_offset &&
287-
addr_offset < func_offset + func_range.GetByteSize()) {
288-
addr_t offset = addr_offset - func_offset;
289-
return m_ranges.FindEntryIndexThatContains(offset);
290-
}
291-
}
292-
}
293-
return UINT32_MAX;
271+
if (!function)
272+
return UINT32_MAX;
273+
274+
const Address &func_addr = function->GetAddress();
275+
if (addr.GetModule() != func_addr.GetModule())
276+
return UINT32_MAX;
277+
278+
const addr_t file_addr = addr.GetFileAddress();
279+
const addr_t func_file_addr = func_addr.GetFileAddress();
280+
return m_ranges.FindEntryIndexThatContains(file_addr - func_file_addr);
294281
}
295282

296283
bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {

lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,22 @@
66

77
# CHECK: Found 1 function(s).
88
# CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]
9-
# CHECK-NEXT: input.o[0x0]: cmpl $0x0, %edi
10-
# CHECK-NEXT: input.o[0x3]: je 0x14
11-
# CHECK-NEXT: input.o[0x5]: jmp 0x7
12-
# CHECK-NEXT: input.o[0x7]: callq 0xe
13-
# CHECK-NEXT: input.o[0xc]: jmp 0x1b
9+
# CHECK-NEXT: input.o[0x0]: callq 0xe
10+
# CHECK-NEXT: input.o[0x5]: jmp 0x1b
11+
# CHECK-NEXT: input.o[0x7]: cmpl $0x0, %edi
12+
# CHECK-NEXT: input.o[0xa]: je 0x14
13+
# CHECK-NEXT: input.o[0xc]: jmp 0x0
1414
# CHECK-EMPTY:
1515
# CHECK-NEXT: input.o[0x14]: callq 0x19
1616
# CHECK-NEXT: input.o[0x19]: jmp 0x1b
1717
# CHECK-NEXT: input.o[0x1b]: retq
18+
# CHECK-NEXT: offset 0x00 => index 0
19+
# CHECK-NEXT: offset 0x0c => index 0
20+
# CHECK-NEXT: offset 0x0e => index ffffffff
21+
# CHECK-NEXT: offset 0x13 => index ffffffff
22+
# CHECK-NEXT: offset 0x14 => index 1
23+
# CHECK-NEXT: offset 0x1b => index 1
24+
# CHECK-NEXT: offset 0x1c => index ffffffff
1825

1926

2027
#--- script.py
@@ -28,6 +35,10 @@ def __lldb_init_module(debugger, internal_dict):
2835
fn = ctx.function
2936
print(f"{fn.name}: {fn.GetRanges()}")
3037
print(fn.GetInstructions(target))
38+
text = fn.addr.section
39+
for offset in [0x00, 0x0c, 0x0e, 0x13, 0x14, 0x1b, 0x1c]:
40+
idx = fn.block.GetRangeIndexForBlockAddress(lldb.SBAddress(text, offset))
41+
print(f"offset 0x{offset:02x} => index {idx:x}")
3142

3243
#--- input.s
3344
# An example of a function which has been split into two parts. Roughly
@@ -40,6 +51,14 @@ def __lldb_init_module(debugger, internal_dict):
4051
.text
4152

4253
.type foo,@function
54+
foo.__part.1:
55+
.cfi_startproc
56+
callq bar
57+
jmp foo.__part.3
58+
.Lfoo.__part.1_end:
59+
.size foo.__part.1, .Lfoo.__part.1_end-foo.__part.1
60+
.cfi_endproc
61+
4362
foo:
4463
.cfi_startproc
4564
cmpl $0, %edi
@@ -49,14 +68,6 @@ foo:
4968
.Lfoo_end:
5069
.size foo, .Lfoo_end-foo
5170

52-
foo.__part.1:
53-
.cfi_startproc
54-
callq bar
55-
jmp foo.__part.3
56-
.Lfoo.__part.1_end:
57-
.size foo.__part.1, .Lfoo.__part.1_end-foo.__part.1
58-
.cfi_endproc
59-
6071
bar:
6172
.cfi_startproc
6273
movl $47, %eax

0 commit comments

Comments
 (0)