[PATCH] D153162: [dsymutil] Fix .debug_addr index calculation

Jonas Devlieghere via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 12:23:59 PDT 2023


JDevlieghere created this revision.
JDevlieghere added reviewers: aprantl, avl, rastogishubham, fdeazeve.
Herald added a subscriber: arphaman.
Herald added a project: All.
JDevlieghere requested review of this revision.
Herald added a project: LLVM.

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


https://reviews.llvm.org/D153162

Files:
  llvm/test/tools/dsymutil/ARM/dwarf5-addrx-0x0-last.test
  llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.o
  llvm/test/tools/dsymutil/Inputs/private/tmp/dwarf5/dwarf5-addrx-0x0-last.out
  llvm/tools/dsymutil/DwarfLinkerForBinary.cpp


Index: llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
===================================================================
--- llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -1081,10 +1081,16 @@
     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();
-      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<int64_t> RelocAdjustment = hasValidRelocationAt(
+              ValidDebugAddrRelocs, StartOffset, EndOffset))
+        return RelocAdjustment;
+      return std::nullopt;
     }
 
     Linker.reportWarning("no base offset for address table", SrcFileName);
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 <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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153162.532262.patch
Type: text/x-patch
Size: 3397 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230616/34ffc338/attachment.bin>


More information about the llvm-commits mailing list