[llvm] r333004 - [DWARFv5] Put the DWO ID in its place.

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Tue May 22 10:27:32 PDT 2018


Author: probinson
Date: Tue May 22 10:27:31 2018
New Revision: 333004

URL: http://llvm.org/viewvc/llvm-project?rev=333004&view=rev
Log:
[DWARFv5] Put the DWO ID in its place.

In DWARF v5, the DWO ID is in the (split/skeleton) CU header, not an
attribute on the CU DIE.

This changes the size of those headers, so use the parsed size whenever
we have one, for simplicitly.

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

Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/test/CodeGen/X86/dwarf-headers.ll
    llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h Tue May 22 10:27:31 2018
@@ -34,9 +34,6 @@ public:
       : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
                   UnitSection) {}
 
-  uint32_t getHeaderSize() const override {
-    return DWARFUnit::getHeaderSize() + 12;
-  }
   uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
   uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }
 

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=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Tue May 22 10:27:31 2018
@@ -59,9 +59,15 @@ class DWARFUnitHeader {
   uint64_t TypeHash = 0;
   uint32_t TypeOffset = 0;
 
+  // For v5 split or skeleton compile units only.
+  Optional<uint64_t> DWOId;
+
   // Unit type as parsed, or derived from the section kind.
   uint8_t UnitType = 0;
 
+  // Size as parsed. uint8_t for compactness.
+  uint8_t Size = 0;
+
 public:
   /// Parse a unit header from \p debug_info starting at \p offset_ptr.
   bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
@@ -78,6 +84,11 @@ public:
   }
   uint32_t getLength() const { return Length; }
   uint64_t getAbbrOffset() const { return AbbrOffset; }
+  Optional<uint64_t> getDWOId() const { return DWOId; }
+  void setDWOId(uint64_t Id) {
+    assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
+    DWOId = Id;
+  }
   const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
   uint64_t getTypeHash() const { return TypeHash; }
   uint32_t getTypeOffset() const { return TypeOffset; }
@@ -85,6 +96,7 @@ public:
   bool isTypeUnit() const {
     return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
   }
+  uint8_t getSize() const { return Size; }
   // FIXME: Support DWARF64.
   uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
 };
@@ -289,8 +301,8 @@ class DWARFUnit {
 protected:
   const DWARFUnitHeader &getHeader() const { return Header; }
 
-  /// Size in bytes of the unit header.
-  virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
+  /// Size in bytes of the parsed unit header.
+  uint32_t getHeaderSize() const { return Header.getSize(); }
 
   /// Find the unit's contribution to the string offsets table and determine its
   /// length and form. The given offset is expected to be derived from the unit
@@ -430,7 +442,8 @@ public:
   }
 
   const char *getCompilationDir();
-  Optional<uint64_t> getDWOId();
+  Optional<uint64_t> getDWOId() const { return getHeader().getDWOId(); }
+  void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
 
   /// Return a vector of address ranges resulting from a (possibly encoded)
   /// range list starting at a given offset in the appropriate ranges section.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue May 22 10:27:31 2018
@@ -855,6 +855,8 @@ void DwarfCompileUnit::emitHeader(bool U
                                 : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
                                                       : dwarf::DW_UT_compile;
   DwarfUnit::emitCommonHeader(UseOffsets, UT);
+  if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
+    Asm->emitInt64(getDWOId());
 }
 
 bool DwarfCompileUnit::hasDwarfPubSections() const {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue May 22 10:27:31 2018
@@ -83,6 +83,9 @@ class DwarfCompileUnit final : public Dw
   DenseMap<const MDNode *, DIE *> AbstractSPDies;
   DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
 
+  /// DWO ID for correlating skeleton and split units.
+  uint64_t DWOId = 0;
+
   /// Construct a DIE for the given DbgVariable without initializing the
   /// DbgVariable's DIE reference.
   DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
@@ -219,6 +222,13 @@ public:
   /// Set the skeleton unit associated with this unit.
   void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
 
+  unsigned getHeaderSize() const override {
+    // DWARF v5 added the DWO ID to the header for split/skeleton units.
+    unsigned DWOIdSize =
+        DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t)
+                                                          : 0;
+    return DwarfUnit::getHeaderSize() + DWOIdSize;
+  }
   unsigned getLength() {
     return sizeof(uint32_t) + // Length field
         getHeaderSize() + getUnitDie().getSize();
@@ -290,6 +300,9 @@ public:
   void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }
   const MCSymbol *getBaseAddress() const { return BaseAddress; }
 
+  uint64_t getDWOId() const { return DWOId; }
+  void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
+
   bool hasDwarfPubSections() const;
 };
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue May 22 10:27:31 2018
@@ -747,11 +747,15 @@ void DwarfDebug::finalizeModuleInfo() {
       // Emit a unique identifier for this CU.
       uint64_t ID =
           DIEHash(Asm).computeCUSignature(DWOName, TheCU.getUnitDie());
-      TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
-                    dwarf::DW_FORM_data8, ID);
-      SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
-                    dwarf::DW_FORM_data8, ID);
-
+      if (getDwarfVersion() >= 5) {
+        TheCU.setDWOId(ID);
+        SkCU->setDWOId(ID);
+      } else {
+        TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
+                      dwarf::DW_FORM_data8, ID);
+        SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
+                      dwarf::DW_FORM_data8, ID);
+      }
       // We don't keep track of which addresses are used in which CU so this
       // is a bit pessimistic under LTO.
       if (!AddrPool.isEmpty()) {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp Tue May 22 10:27:31 2018
@@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream
   if (getVersion() >= 5)
     OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
   OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
-     << " addr_size = " << format("0x%02x", getAddressByteSize())
-     << " (next unit at " << format("0x%08x", getNextUnitOffset())
-     << ")\n";
+     << " addr_size = " << format("0x%02x", getAddressByteSize());
+  if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
+    OS << " DWO_id = " << format("0x%016" PRIx64, *getDWOId());
+  OS << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
 
   if (DWARFDie CUDie = getUnitDIE(false))
     CUDie.dump(OS, 0, DumpOpts);

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Tue May 22 10:27:31 2018
@@ -561,9 +561,19 @@ DWARFCompileUnit *DWARFContext::getDWOCo
   // probably only one unless this is something like LTO - though an in-process
   // built/cached lookup table could be used in that case to improve repeated
   // lookups of different CUs in the DWO.
-  for (const auto &DWOCU : dwo_compile_units())
+  for (const auto &DWOCU : dwo_compile_units()) {
+    // Might not have parsed DWO ID yet.
+    if (!DWOCU->getDWOId()) {
+      if (Optional<uint64_t> DWOId =
+          toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
+        DWOCU->setDWOId(*DWOId);
+      else
+        // No DWO ID?
+        continue;
+    }
     if (DWOCU->getDWOId() == Hash)
       return DWOCU.get();
+  }
   return nullptr;
 }
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Tue May 22 10:27:31 2018
@@ -130,15 +130,22 @@ bool DWARFUnitHeader::extract(DWARFConte
       return false;
     AbbrOffset = AbbrEntry->Offset;
   }
-  bool TypeOffsetOK = true;
   if (isTypeUnit()) {
     TypeHash = debug_info.getU64(offset_ptr);
     TypeOffset = debug_info.getU32(offset_ptr);
-    // Type offset is unit-relative; should be after the header and before
-    // the end of the current unit.
-    TypeOffsetOK = TypeOffset >= *offset_ptr - Offset &&
-                   TypeOffset < getLength() + SizeOfLength;
-  }
+  } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
+    DWOId = debug_info.getU64(offset_ptr);
+
+  // Header fields all parsed, capture the size of this unit header.
+  assert(*offset_ptr - Offset <= 255 && "unexpected header size");
+  Size = uint8_t(*offset_ptr - Offset);
+
+  // Type offset is unit-relative; should be after the header and before
+  // the end of the current unit.
+  bool TypeOffsetOK =
+      !isTypeUnit()
+          ? true
+          : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
   bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
   bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
   bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
@@ -197,10 +204,6 @@ const char *DWARFUnit::getCompilationDir
   return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
 }
 
-Optional<uint64_t> DWARFUnit::getDWOId() {
-  return toUnsigned(getUnitDIE().find(DW_AT_GNU_dwo_id));
-}
-
 void DWARFUnit::extractDIEsToVector(
     bool AppendCUDie, bool AppendNonCUDies,
     std::vector<DWARFDebugInfoEntry> &Dies) const {
@@ -269,6 +272,8 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo
   // If CU DIE was just parsed, copy several attribute values from it.
   if (!HasCUDie) {
     DWARFDie UnitDie = getUnitDIE();
+    if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
+      Header.setDWOId(*DWOId);
     if (!isDWO) {
       assert(AddrOffsetSectionBase == 0);
       assert(RangeSectionBase == 0);

Modified: llvm/trunk/test/CodeGen/X86/dwarf-headers.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dwarf-headers.ll?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dwarf-headers.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dwarf-headers.ll Tue May 22 10:27:31 2018
@@ -19,9 +19,10 @@
 ; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
 
 ; Looking for DWARF headers to be generated correctly.
-; There are 7 variants: v4 CU, v4 TU, v5 (normal/skeleton/split) CU,
-; v5 (normal/split) TU.  The v5 CU variants and TU variants differ
-; only in the type-unit code.
+; There are 8 variants with 5 formats: v4 CU, v4 TU, v5 normal/partial CU,
+; v5 skeleton/split CU, v5 normal/split TU.  Some v5 variants differ only
+; in the unit_type code, and the skeleton/split CU differs from normal/partial
+; by having one extra field (dwo_id).
 ; (v2 thru v4 CUs are all the same, and TUs were invented in v4,
 ; so we don't bother checking older versions.)
 
@@ -73,11 +74,13 @@
 ;
 ; O-5: .debug_info contents:
 ; O-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_skeleton abbr_offset
-; O-5: 0x0000000c: DW_TAG_compile_unit
+; O-5-SAME:        DWO_id = 0x4ed74084f749d96b
+; O-5: 0x00000014: DW_TAG_compile_unit
 ;
 ; DWO-5: .debug_info.dwo contents:
 ; DWO-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_compile abbr_offset
-; DWO-5: 0x0000000c: DW_TAG_compile_unit
+; DWO-5-SAME:        DWO_id = 0x4ed74084f749d96b
+; DWO-5: 0x00000014: DW_TAG_compile_unit
 ;
 ; FIXME: V5 wants type units in .debug_info.dwo not .debug_types.dwo.
 ; DWO-5: .debug_types.dwo contents:

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s?rev=333004&r1=333003&r2=333004&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-header.s Tue May 22 10:27:31 2018
@@ -137,6 +137,7 @@ CU_split_5_version:
         .byte 5                 # DWARF Unit Type
         .byte 8                 # Address Size (in bytes)
         .long .debug_abbrev.dwo # Offset Into Abbrev. Section
+        .quad 0x5a              # DWO ID
 # The split compile-unit DIE, with DW_AT_producer, DW_AT_name, DW_AT_stmt_list.
         .byte 1
         .long dwo_producer
@@ -145,8 +146,8 @@ CU_split_5_version:
         .byte 0 # NULL
 CU_split_5_end:
 
-# CHECK: 0x00000000: Compile Unit: length = 0x00000016 version = 0x0005 unit_type = DW_UT_split_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000001a)
-# CHECK: 0x0000000c: DW_TAG_compile_unit
+# CHECK: 0x00000000: Compile Unit: length = 0x0000001e version = 0x0005 unit_type = DW_UT_split_compile abbr_offset = 0x0000 addr_size = 0x08 DWO_id = 0x000000000000005a (next unit at 0x00000022)
+# CHECK: 0x00000014: DW_TAG_compile_unit
 # CHECK-NEXT: DW_AT_producer {{.*}} "Handmade DWO producer"
 # CHECK-NEXT: DW_AT_name {{.*}} "V5_dwo_compile_unit"
 




More information about the llvm-commits mailing list