[llvm] r312477 - [DebugInfo] - Fix for lld DWARF parsing of base address selection entries in range lists.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 4 03:30:40 PDT 2017


Author: grimar
Date: Mon Sep  4 03:30:39 2017
New Revision: 312477

URL: http://llvm.org/viewvc/llvm-project?rev=312477&view=rev
Log:
[DebugInfo] - Fix for lld DWARF parsing of base address selection entries in range lists.

It solves issue of wrong section index evaluating for ranges when
base address is used.

Based on David Blaikie's patch D36097.

Differential revision: https://reviews.llvm.org/D37214

Added:
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64   (with props)
    llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h?rev=312477&r1=312476&r2=312477&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h Mon Sep  4 03:30:39 2017
@@ -18,6 +18,7 @@
 
 namespace llvm {
 
+struct BaseAddress;
 class raw_ostream;
 
 struct DWARFAddressRange {
@@ -85,7 +86,8 @@ public:
   /// getAbsoluteRanges - Returns absolute address ranges defined by this range
   /// list. Has to be passed base address of the compile unit referencing this
   /// range list.
-  DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
+  DWARFAddressRangesVector
+  getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=312477&r1=312476&r2=312477&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Mon Sep  4 03:30:39 2017
@@ -110,6 +110,12 @@ private:
   }
 };
 
+/// Represents base address of the CU.
+struct BaseAddress {
+  uint64_t Address;
+  uint64_t SectionIndex;
+};
+
 class DWARFUnit {
   DWARFContext &Context;
   /// Section containing this DWARFUnit.
@@ -135,7 +141,7 @@ class DWARFUnit {
   uint32_t Length;
   const DWARFAbbreviationDeclarationSet *Abbrevs;
   uint8_t UnitType;
-  uint64_t BaseAddr;
+  llvm::Optional<BaseAddress> BaseAddr;
   /// The compile unit debug information entry items.
   std::vector<DWARFDebugInfoEntry> DieArray;
 
@@ -259,11 +265,9 @@ public:
     llvm_unreachable("Invalid UnitType.");
   }
 
-  uint64_t getBaseAddress() const { return BaseAddr; }
+  llvm::Optional<BaseAddress> getBaseAddress() const { return BaseAddr; }
 
-  void setBaseAddress(uint64_t base_addr) {
-    BaseAddr = base_addr;
-  }
+  void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; }
 
   DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
     extractDIEsIfNeeded(ExtractUnitDIEOnly);

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp?rev=312477&r1=312476&r2=312477&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp Mon Sep  4 03:30:39 2017
@@ -14,6 +14,8 @@ using namespace llvm;
 
 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
                                                uint64_t *SecNdx) const {
+  if (SecNdx)
+    *SecNdx = -1ULL;
   if (!Section)
     return getUnsigned(Off, Size);
   Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp?rev=312477&r1=312476&r2=312477&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp Mon Sep  4 03:30:39 2017
@@ -63,16 +63,29 @@ void DWARFDebugRangeList::dump(raw_ostre
   OS << format("%08x <End of list>\n", Offset);
 }
 
-DWARFAddressRangesVector
-DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
+    llvm::Optional<BaseAddress> BaseAddr) const {
   DWARFAddressRangesVector Res;
   for (const RangeListEntry &RLE : Entries) {
     if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
-      BaseAddress = RLE.EndAddress;
-    } else {
-      Res.push_back({BaseAddress + RLE.StartAddress,
-                     BaseAddress + RLE.EndAddress, RLE.SectionIndex});
+      BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
+      continue;
     }
+
+    DWARFAddressRange E;
+    E.LowPC = RLE.StartAddress;
+    E.HighPC = RLE.EndAddress;
+    E.SectionIndex = RLE.SectionIndex;
+    // Base address of a range list entry is determined by the closest preceding
+    // base address selection entry in the same range list. It defaults to the
+    // base address of the compilation unit if there is no such entry.
+    if (BaseAddr) {
+      E.LowPC += BaseAddr->Address;
+      E.HighPC += BaseAddr->Address;
+      if (E.SectionIndex == -1ULL)
+        E.SectionIndex = BaseAddr->SectionIndex;
+    }
+    Res.push_back(E);
   }
   return Res;
 }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=312477&r1=312476&r2=312477&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Mon Sep  4 03:30:39 2017
@@ -160,7 +160,7 @@ void DWARFUnit::clear() {
   Length = 0;
   Abbrevs = nullptr;
   FormParams = DWARFFormParams({0, 0, DWARF32});
-  BaseAddr = 0;
+  BaseAddr.reset();
   RangeSectionBase = 0;
   AddrOffsetSectionBase = 0;
   clearDIEs(false);
@@ -242,9 +242,10 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo
   // If CU DIE was just parsed, copy several attribute values from it.
   if (!HasCUDie) {
     DWARFDie UnitDie = getUnitDIE();
-    auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}));
-    if (BaseAddr)
-      setBaseAddress(*BaseAddr);
+    Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
+    if (Optional<uint64_t> Addr = toAddress(PC))
+        setBaseAddress({*Addr, PC->getSectionIndex()});
+
     if (!isDWO) {
       assert(AddrOffsetSectionBase == 0);
       assert(RangeSectionBase == 0);

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64?rev=312477&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s?rev=312477&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s (added)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s Mon Sep  4 03:30:39 2017
@@ -0,0 +1,13 @@
+# RUN: llvm-dwarfdump %S/../Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64 \
+# RUN:  | FileCheck %s
+
+## Executable binary for test produced from object built in 
+## dwarfdump-ranges-baseaddr.s testcase.
+
+# CHECK: .debug_info contents:
+# CHECK: 0x0000000b: DW_TAG_compile_unit [1]
+# CHECK:             DW_AT_low_pc [DW_FORM_addr]       (0x0000000000400078)
+# CHECK-NEXT:        DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
+# CHECK-NEXT:    [0x0000000000400078 - 0x0000000000400079)
+# CHECK-NEXT:    [0x000000000040007b - 0x000000000040007e)
+# CHECK-NEXT:    [0x000000000040007f - 0x0000000000400080))

Added: llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s?rev=312477&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s (added)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s Mon Sep  4 03:30:39 2017
@@ -0,0 +1,82 @@
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+
+# CHECK: .debug_info contents:
+# CHECK: 0x0000000b: DW_TAG_compile_unit [1]
+# CHECK:             DW_AT_low_pc [DW_FORM_addr]       (0x0000000000000000)
+# CHECK-NEXT:        DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
+# CHECK-NEXT:    [0x0000000000000000 - 0x0000000000000001) ".text"
+# CHECK-NEXT:    [0x0000000000000003 - 0x0000000000000006) ".text"
+# CHECK-NEXT:    [0x0000000000000001 - 0x0000000000000002) ".text.foo1")
+
+.text
+.globl foo
+.type foo, at function
+foo: 
+.Lfunc_begin0:
+  nop
+.Ltmp0:
+  nop
+  nop
+.Ltmp1:
+  nop
+  nop
+  nop
+.Ltmp2:
+
+.section .text.foo1,"ax", at progbits
+.Ltmp3:
+ nop
+.Ltmp4: 
+ nop
+.Ltmp5:
+
+.section .debug_abbrev,"", at progbits
+.byte 1                       # Abbreviation Code
+.byte 17                      # DW_TAG_compile_unit
+.byte 0                       # DW_CHILDREN_no
+.byte 37                      # DW_AT_producer
+.byte 14                      # DW_FORM_strp
+.byte 19                      # DW_AT_language
+.byte 5                       # DW_FORM_data2
+.byte 3                       # DW_AT_name
+.byte 14                      # DW_FORM_strp
+.byte 16                      # DW_AT_stmt_list
+.byte 23                      # DW_FORM_sec_offset
+.byte 27                      # DW_AT_comp_dir
+.byte 14                      # DW_FORM_strp
+.byte 17                      # DW_AT_low_pc
+.byte 1                       # DW_FORM_addr
+.byte 85                      # DW_AT_ranges
+.byte 23                      # DW_FORM_sec_offset
+.byte 0                       # EOM(1)
+.byte 0                       # EOM(2)
+.byte 0                       # EOM(3)
+
+.section .debug_info,"", at progbits
+.Lcu_begin0:
+.long 38                      # Length of Unit
+.short 4                      # DWARF version number
+.long .debug_abbrev           # Offset Into Abbrev. Section
+.byte 8                       # Address Size (in bytes)
+.byte 1                       # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
+.long 0                       # DW_AT_producer
+.short 4                      # DW_AT_language
+.long 0                       # DW_AT_name
+.long 0                       # DW_AT_stmt_list
+.long 0                       # DW_AT_comp_dir
+.quad .Lfunc_begin0           # DW_AT_low_pc
+.long .Ldebug_ranges0         # DW_AT_ranges
+
+.section .debug_ranges,"", at progbits
+.Ldebug_ranges0:
+ .quad .Lfunc_begin0-.Lfunc_begin0
+ .quad .Ltmp0-.Lfunc_begin0
+ .quad .Ltmp1-.Lfunc_begin0
+ .quad .Ltmp2-.Lfunc_begin0
+ .quad 0xFFFFFFFFFFFFFFFF
+ .quad .text.foo1
+ .quad .Ltmp4-.text.foo1
+ .quad .Ltmp5-.text.foo1
+ .quad 0
+ .quad 0




More information about the llvm-commits mailing list