[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
This commit is contained in:
45
llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test
Normal file
45
llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test
Normal file
@@ -0,0 +1,45 @@
|
||||
$ cat dwarf5-addrx-0x0-last.c
|
||||
#include <stdio.h>
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
int pass_me = argc + 10;
|
||||
printf("Foo\n");
|
||||
printf("Bar\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$ clang -gdwarf-5 dwarf5-addrx-0x0-last.c -c -o dwarf5-addrx-0x0-last.o
|
||||
$ clang dwarf5-addrx-0x0-last.o -o dwarf5-addrx-0x0-last.out
|
||||
|
||||
# Sanity check: make sure main's low PC (0x0) requires an index computation
|
||||
# into the .debug_addr section.
|
||||
RUN: llvm-dwarfdump -debug-addr %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.o | FileCheck %s --check-prefix DEBUGADDR
|
||||
|
||||
DEBUGADDR: Addrs: [
|
||||
DEBUGADDR: 0x0000000000000054
|
||||
DEBUGADDR: 0x0000000000000059
|
||||
DEBUGADDR: 0x0000000000000000
|
||||
DEBUGADDR: ]
|
||||
|
||||
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
|
||||
RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
|
||||
RUN: llvm-dwarfdump --verbose -debug-info %t.dSYM | FileCheck %s --check-prefix DEBUGINFO
|
||||
RUN: llvm-dwarfdump --verbose -debug-line %t.dSYM | FileCheck %s --check-prefix DEBUGLINE
|
||||
|
||||
CHECK-NOT: error:
|
||||
|
||||
DEBUGINFO: DW_TAG_subprogram
|
||||
DEBUGINFO: DW_AT_low_pc [DW_FORM_addr] (0x0000000100003f4c)
|
||||
DEBUGINFO: DW_AT_high_pc [DW_FORM_data4] (0x00000054)
|
||||
DEBUGINFO: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000011c] = "main")
|
||||
|
||||
DEBUGLINE: 0x0000000100003f4c 4 0 {{.*}} is_stmt
|
||||
DEBUGLINE: 0x0000000100003f6c 5 17 {{.*}} is_stmt prologue_end
|
||||
DEBUGLINE: 0x0000000100003f70 5 22 {{.*}}
|
||||
DEBUGLINE: 0x0000000100003f74 5 7 {{.*}}
|
||||
DEBUGLINE: 0x0000000100003f78 6 3 {{.*}} is_stmt
|
||||
DEBUGLINE: 0x0000000100003f84 7 3 {{.*}} is_stmt
|
||||
DEBUGLINE: 0x0000000100003f94 9 3 {{.*}} is_stmt epilogue_begin
|
||||
DEBUGLINE: 0x0000000100003fa0 9 3 {{.*}} is_stmt end_sequence
|
||||
Binary file not shown.
BIN
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.out
Executable file
BIN
llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.out
Executable file
Binary file not shown.
@@ -1081,9 +1081,12 @@ std::optional<int64_t> DwarfLinkerForBinary::AddressManager<
|
||||
std::optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
|
||||
if (std::optional<uint64_t> AddrOffsetSectionBase =
|
||||
DIE.getDwarfUnit()->getAddrOffsetSectionBase()) {
|
||||
uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue();
|
||||
uint64_t EndOffset =
|
||||
StartOffset + DIE.getDwarfUnit()->getAddressByteSize();
|
||||
// Addrx is a index into the debug_addr section, not an offset, so we need
|
||||
// to multiply by byte size.
|
||||
const uint64_t ByteSize = DIE.getDwarfUnit()->getAddressByteSize();
|
||||
const uint64_t StartOffset =
|
||||
*AddrOffsetSectionBase + (AddrValue->getRawUValue() * ByteSize);
|
||||
const uint64_t EndOffset = StartOffset + ByteSize;
|
||||
return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user