Skip to content

Commit 8119ab9

Browse files
committed
[dsymutil] Fix .debug_addr index calculation
The DW_OP_addrx operation encodes a zero-based index into the .debug_addr section. The index is relative to the DW_AT_addr_base attribute of the associated compilation unit. In order to compute the offset into the .debug_addr section and find the associated relocation, we need to add the add the add base offset and multiply the index with the address size. This patch fixes a bug in this computation, where the multiplication was omitted. This went unnoticed because for small test cases, the index for interesting addresses (such as the main subprogram) is often zero. rdar://110881668 Differential revision: https://reviews.llvm.org/D153162
1 parent 70b1c39 commit 8119ab9

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
$ cat dwarf5-addrx-0x0-last.c
2+
#include <stdio.h>
3+
4+
int main (int argc, char const *argv[])
5+
{
6+
int pass_me = argc + 10;
7+
printf("Foo\n");
8+
printf("Bar\n");
9+
10+
return 0;
11+
}
12+
13+
$ clang -gdwarf-5 dwarf5-addrx-0x0-last.c -c -o dwarf5-addrx-0x0-last.o
14+
$ clang dwarf5-addrx-0x0-last.o -o dwarf5-addrx-0x0-last.out
15+
16+
# Sanity check: make sure main's low PC (0x0) requires an index computation
17+
# into the .debug_addr section.
18+
RUN: llvm-dwarfdump -debug-addr %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.o | FileCheck %s --check-prefix DEBUGADDR
19+
20+
DEBUGADDR: Addrs: [
21+
DEBUGADDR: 0x0000000000000054
22+
DEBUGADDR: 0x0000000000000059
23+
DEBUGADDR: 0x0000000000000000
24+
DEBUGADDR: ]
25+
26+
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
27+
RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
28+
RUN: llvm-dwarfdump --verbose -debug-info %t.dSYM | FileCheck %s --check-prefix DEBUGINFO
29+
RUN: llvm-dwarfdump --verbose -debug-line %t.dSYM | FileCheck %s --check-prefix DEBUGLINE
30+
31+
CHECK-NOT: error:
32+
33+
DEBUGINFO: DW_TAG_subprogram
34+
DEBUGINFO: DW_AT_low_pc [DW_FORM_addr] (0x0000000100003f4c)
35+
DEBUGINFO: DW_AT_high_pc [DW_FORM_data4] (0x00000054)
36+
DEBUGINFO: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000011c] = "main")
37+
38+
DEBUGLINE: 0x0000000100003f4c 4 0 {{.*}} is_stmt
39+
DEBUGLINE: 0x0000000100003f6c 5 17 {{.*}} is_stmt prologue_end
40+
DEBUGLINE: 0x0000000100003f70 5 22 {{.*}}
41+
DEBUGLINE: 0x0000000100003f74 5 7 {{.*}}
42+
DEBUGLINE: 0x0000000100003f78 6 3 {{.*}} is_stmt
43+
DEBUGLINE: 0x0000000100003f84 7 3 {{.*}} is_stmt
44+
DEBUGLINE: 0x0000000100003f94 9 3 {{.*}} is_stmt epilogue_begin
45+
DEBUGLINE: 0x0000000100003fa0 9 3 {{.*}} is_stmt end_sequence
Binary file not shown.
Binary file not shown.

llvm/tools/dsymutil/DwarfLinkerForBinary.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,12 @@ std::optional<int64_t> DwarfLinkerForBinary::AddressManager<
10811081
std::optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
10821082
if (std::optional<uint64_t> AddrOffsetSectionBase =
10831083
DIE.getDwarfUnit()->getAddrOffsetSectionBase()) {
1084-
uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue();
1085-
uint64_t EndOffset =
1086-
StartOffset + DIE.getDwarfUnit()->getAddressByteSize();
1084+
// Addrx is a index into the debug_addr section, not an offset, so we need
1085+
// to multiply by byte size.
1086+
const uint64_t ByteSize = DIE.getDwarfUnit()->getAddressByteSize();
1087+
const uint64_t StartOffset =
1088+
*AddrOffsetSectionBase + (AddrValue->getRawUValue() * ByteSize);
1089+
const uint64_t EndOffset = StartOffset + ByteSize;
10871090
return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset);
10881091
}
10891092

0 commit comments

Comments
 (0)