Index: llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test @@ -0,0 +1,45 @@ +$ cat dwarf5-addrx-0x0-last.c +#include + +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 Index: llvm/tools/dsymutil/DwarfLinkerForBinary.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -1081,10 +1081,16 @@ std::optional AddrValue = DIE.find(dwarf::DW_AT_low_pc); if (std::optional AddrOffsetSectionBase = DIE.getDwarfUnit()->getAddrOffsetSectionBase()) { - uint64_t StartOffset = *AddrOffsetSectionBase + AddrValue->getRawUValue(); - uint64_t EndOffset = - StartOffset + DIE.getDwarfUnit()->getAddressByteSize(); - return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset); + // 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; + if (std::optional RelocAdjustment = hasValidRelocationAt( + ValidDebugAddrRelocs, StartOffset, EndOffset)) + return RelocAdjustment; + return std::nullopt; } Linker.reportWarning("no base offset for address table", SrcFileName);