[llvm-dwarfutil][DWARFv5] fix reading of DW_FORM_addrx attribute.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Mon, 5 Sep 2022 14:33:22 +0000 (17:33 +0300)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Fri, 23 Sep 2022 06:35:54 +0000 (09:35 +0300)
llvm::dwarfutil::ObjFileAddressMap::relocateIndexedAddr() does not
read address value. The relocateIndexedAddr() should not relocate
the address as the linked binary has already resolved relocations.
But it should read the value. This patch adds the reading value
of the address.

Differential Revision: https://reviews.llvm.org/D133324

llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test [new file with mode: 0644]
llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp

diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addrx.test
new file mode 100644 (file)
index 0000000..20964f9
--- /dev/null
@@ -0,0 +1,120 @@
+## Test that DWARF5 DW_FORM_addrx is correctly recognized
+## and converted into the DW_FORM_addr
+
+# RUN: yaml2obj %s -o %t.o
+
+# RUN: llvm-dwarfutil %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_compile_unit
+#DWARF-CHECK:   DW_AT_name [DW_FORM_strp]  {{.*}}     "CU1"
+#DWARF-CHECK:   DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001130)
+#DWARF-CHECK:   DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000030)
+#DWARF-CHECK:   DW_AT_addr_base [DW_FORM_sec_offset]   (0x00000008)
+#DWARF-CHECK:   DW_TAG_subprogram
+#DWARF-CHECK:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo1"
+#DWARF-CHECK:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001130)
+#DWARF-CHECK:     DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
+#DWARF-CHECK:   DW_TAG_subprogram
+#DWARF-CHECK:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo2"
+#DWARF-CHECK:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001140)
+#DWARF-CHECK:     DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
+#DWARF-CHECK:   DW_TAG_subprogram
+#DWARF-CHECK:     DW_AT_name  [DW_FORM_strp] {{.*}}   "foo3"
+#DWARF-CHECK:     DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001150)
+#DWARF-CHECK:     DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
+
+--- !ELF
+FileHeader:
+  Class:    ELFCLASS64
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1130
+    Size:            0x30
+DWARF:
+  debug_abbrev:
+    - Table:
+      - Tag:      DW_TAG_compile_unit
+        Children: DW_CHILDREN_yes
+        Attributes:
+          - Attribute: DW_AT_producer
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_language
+            Form:      DW_FORM_data2
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_low_pc
+            Form:      DW_FORM_addrx
+          - Attribute: DW_AT_high_pc
+            Form:      DW_FORM_data8
+          - Attribute: DW_AT_addr_base
+            Form:      DW_FORM_sec_offset
+      - Tag:      DW_TAG_subprogram
+        Children: DW_CHILDREN_yes
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_low_pc
+            Form:      DW_FORM_addrx
+          - Attribute: DW_AT_high_pc
+            Form:      DW_FORM_data8
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+      - Tag:      DW_TAG_base_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+  debug_info:
+    - Version: 5
+      UnitType:   DW_UT_compile
+      Entries:
+        - AbbrCode: 1
+          Values:
+            - CStr: by_hand
+            - Value:  0x04
+            - CStr: CU1
+            - Value:  0x0
+            - Value:  0x30
+            - Value:  0x8
+        - AbbrCode: 2
+          Values:
+            - CStr: foo1
+            - Value: 0x0
+            - Value: 0x10
+            - Value: 0x64
+        - AbbrCode: 0
+        - AbbrCode: 2
+          Values:
+            - CStr: foo2
+            - Value: 0x01
+            - Value: 0x10
+            - Value: 0x64
+        - AbbrCode: 0
+        - AbbrCode: 2
+          Values:
+            - CStr: foo3
+            - Value: 0x02
+            - Value: 0x10
+            - Value: 0x64
+        - AbbrCode: 0
+        - AbbrCode: 3
+          Values:
+            - CStr: int
+        - AbbrCode: 0
+  debug_addr:
+    - Version: 5
+      AddressSize: 0x08
+      Entries:
+        - Address: 0x1130
+        - Address: 0x1140
+        - Address: 0x1150
+...
index df17b01..5b1ded8 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
 #include <memory>
 #include <vector>
 
@@ -40,7 +41,7 @@ class ObjFileAddressMap : public AddressesMap {
 public:
   ObjFileAddressMap(DWARFContext &Context, const Options &Options,
                     object::ObjectFile &ObjFile)
-      : Opts(Options) {
+      : Opts(Options), Context(Context) {
     // Remember addresses of existing text sections.
     for (const object::SectionRef &Sect : ObjFile.sections()) {
       if (!Sect.isText())
@@ -137,9 +138,28 @@ public:
 
   void clear() override { DWARFAddressRanges.clear(); }
 
-  llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t, uint64_t) override {
-    // should not be called.
-    return object::createError("no relocations in linked binary");
+  llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
+                                               uint64_t EndOffset) override {
+    // No relocations in linked binary. Return just address value.
+
+    const char *AddrPtr =
+        Context.getDWARFObj().getAddrSection().Data.data() + StartOffset;
+    support::endianness Endianess =
+        Context.getDWARFObj().isLittleEndian() ? support::little : support::big;
+
+    assert(EndOffset > StartOffset);
+    switch (EndOffset - StartOffset) {
+    case 1:
+      return *AddrPtr;
+    case 2:
+      return support::endian::read16(AddrPtr, Endianess);
+    case 4:
+      return support::endian::read32(AddrPtr, Endianess);
+    case 8:
+      return support::endian::read64(AddrPtr, Endianess);
+    }
+
+    llvm_unreachable("relocateIndexedAddr unhandled case!");
   }
 
 protected:
@@ -209,6 +229,7 @@ private:
   RangesTy DWARFAddressRanges;
   AddressRanges TextAddressRanges;
   const Options &Opts;
+  DWARFContext &Context;
 };
 
 static bool knownByDWARFUtil(StringRef SecName) {