[llvm] r336927 - [DWARF v5] Generate range list tables into the .debug_rnglists section. No support for split DWARF

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 12 11:18:21 PDT 2018


Author: wolfgangp
Date: Thu Jul 12 11:18:21 2018
New Revision: 336927

URL: http://llvm.org/viewvc/llvm-project?rev=336927&view=rev
Log:
[DWARF v5] Generate range list tables into the .debug_rnglists section. No support for split DWARF 
and no use of DW_FORM_rnglistx with the DW_AT_ranges attribute.

Reviewer: aprantl

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

Added:
    llvm/trunk/test/DebugInfo/X86/rnglists-nobase.ll
Modified:
    llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
    llvm/trunk/lib/MC/MCObjectFileInfo.cpp
    llvm/trunk/test/DebugInfo/X86/fission-ranges.ll

Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Thu Jul 12 11:18:21 2018
@@ -116,6 +116,11 @@ protected:
   /// The DWARF v5 string offset and address table sections.
   MCSection *DwarfStrOffSection;
   MCSection *DwarfAddrSection;
+  /// The DWARF v5 range list section.
+  MCSection *DwarfRnglistsSection;
+
+  /// The DWARF v5 range list section for fission.
+  MCSection *DwarfRnglistsDWOSection;
 
   // These are for Fission DWP files.
   MCSection *DwarfCUIndexSection;
@@ -256,6 +261,7 @@ public:
   MCSection *getDwarfLocSection() const { return DwarfLocSection; }
   MCSection *getDwarfARangesSection() const { return DwarfARangesSection; }
   MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
+  MCSection *getDwarfRnglistsSection() const { return DwarfRnglistsSection; }
   MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
 
   MCSection *getDwarfDebugNamesSection() const {
@@ -281,6 +287,9 @@ public:
   MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
   MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
   MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
+  MCSection *getDwarfRnglistsDWOSection() const {
+    return DwarfRnglistsDWOSection;
+  }
   MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
   MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
   MCSection *getDwarfSwiftASTSection() const { return DwarfSwiftASTSection; }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Thu Jul 12 11:18:21 2018
@@ -399,21 +399,30 @@ void DwarfCompileUnit::addScopeRangeList
                                          SmallVector<RangeSpan, 2> Range) {
   const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
 
-  // Emit offset in .debug_range as a relocatable label. emitDIE will handle
-  // emitting it appropriately.
+  // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable
+  // label. emitDIE() will handle emitting it appropriately.
   const MCSymbol *RangeSectionSym =
-      TLOF.getDwarfRangesSection()->getBeginSymbol();
+      DD->getDwarfVersion() >= 5
+          ? TLOF.getDwarfRnglistsSection()->getBeginSymbol()
+          : TLOF.getDwarfRangesSection()->getBeginSymbol();
 
   RangeSpanList List(Asm->createTempSymbol("debug_ranges"), std::move(Range));
 
   // Under fission, ranges are specified by constant offsets relative to the
   // CU's DW_AT_GNU_ranges_base.
-  if (isDwoUnit())
-    addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
-                    RangeSectionSym);
-  else
+  // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
+  // fission until we support the forms using the .debug_addr section
+  // (DW_RLE_startx_endx etc.).
+  if (isDwoUnit()) {
+    if (DD->getDwarfVersion() < 5)
+      addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
+                      RangeSectionSym);
+  } else {
     addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(),
                     RangeSectionSym);
+    if (DD->getDwarfVersion() >= 5)
+      addRnglistsBase();
+  }
 
   // Add the range list to the set of ranges to be emitted.
   (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List));

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Jul 12 11:18:21 2018
@@ -645,6 +645,12 @@ void DwarfDebug::beginModule() {
     (useSplitDwarf() ? SkeletonHolder : InfoHolder)
         .setStringOffsetsStartSym(Asm->createTempSymbol("str_offsets_base"));
 
+  // Create the symbol that designates the start of the DWARF v5 range list
+  // table. It is located past the header and before the offsets table.
+  if (getDwarfVersion() >= 5)
+    (useSplitDwarf() ? SkeletonHolder : InfoHolder)
+        .setRnglistsTableBaseSym(Asm->createTempSymbol("rnglists_table_base"));
+
   for (DICompileUnit *CUNode : M->debug_compile_units()) {
     // FIXME: Move local imported entities into a list attached to the
     // subprogram, then this search won't be needed and a
@@ -765,7 +771,7 @@ void DwarfDebug::finalizeModuleInfo() {
         SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_addr_base,
                               Sym, Sym);
       }
-      if (!SkCU->getRangeLists().empty()) {
+      if (getDwarfVersion() < 5 && !SkCU->getRangeLists().empty()) {
         const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol();
         SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
                               Sym, Sym);
@@ -1970,9 +1976,11 @@ void DwarfDebug::emitDebugARanges() {
   }
 }
 
-/// Emit a single range list.
+/// Emit a single range list. We handle both DWARF v5 and earlier.
 static void emitRangeList(AsmPrinter *Asm, DwarfCompileUnit *CU,
                           const RangeSpanList &List) {
+
+  auto DwarfVersion = CU->getDwarfVersion();
   // Emit our symbol so we can find the beginning of the range.
   Asm->OutStreamer->EmitLabel(List.getSym());
   // Gather all the ranges that apply to the same section so they can share
@@ -1992,18 +2000,24 @@ static void emitRangeList(AsmPrinter *As
     // usually consist of single regions from each of many sections
     // (-ffunction-sections, or just C++ inline functions) except under LTO
     // or optnone where there may be holes in a single CU's section
-    // contrubutions.
+    // contributions.
     auto *Base = CUBase;
     if (!Base && P.second.size() > 1 && UseDwarfRangesBaseAddressSpecifier) {
       BaseIsSet = true;
       // FIXME/use care: This may not be a useful base address if it's not
       // the lowest address/range in this object.
       Base = P.second.front()->getStart();
-      Asm->OutStreamer->EmitIntValue(-1, Size);
+      if (DwarfVersion >= 5)
+        Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_base_address, 1);
+      else
+        Asm->OutStreamer->EmitIntValue(-1, Size);
       Asm->OutStreamer->EmitSymbolValue(Base, Size);
     } else if (BaseIsSet) {
       BaseIsSet = false;
-      Asm->OutStreamer->EmitIntValue(-1, Size);
+      if (DwarfVersion >= 5)
+        Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_base_address, 1);
+      else
+        Asm->OutStreamer->EmitIntValue(-1, Size);
       Asm->OutStreamer->EmitIntValue(0, Size);
     }
 
@@ -2013,21 +2027,87 @@ static void emitRangeList(AsmPrinter *As
       assert(Begin && "Range without a begin symbol?");
       assert(End && "Range without an end symbol?");
       if (Base) {
-        Asm->EmitLabelDifference(Begin, Base, Size);
-        Asm->EmitLabelDifference(End, Base, Size);
+        if (DwarfVersion >= 5) {
+          // Emit DW_RLE_offset_pair when we have a base.
+          Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_offset_pair, 1);
+          Asm->EmitLabelDifferenceAsULEB128(Begin, Base);
+          Asm->EmitLabelDifferenceAsULEB128(End, Base);
+        } else {
+          Asm->EmitLabelDifference(Begin, Base, Size);
+          Asm->EmitLabelDifference(End, Base, Size);
+        }
+      } else if (DwarfVersion >= 5) {
+        Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_start_length, 1);
+        Asm->OutStreamer->EmitSymbolValue(Begin, Size);
+        Asm->EmitLabelDifferenceAsULEB128(End, Begin);
       } else {
         Asm->OutStreamer->EmitSymbolValue(Begin, Size);
         Asm->OutStreamer->EmitSymbolValue(End, Size);
       }
     }
   }
+  if (DwarfVersion >= 5)
+    Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_end_of_list, 1);
+  else {
+    // Terminate the list with two 0 values.
+    Asm->OutStreamer->EmitIntValue(0, Size);
+    Asm->OutStreamer->EmitIntValue(0, Size);
+  }
+}
+
+void DwarfDebug::emitDebugRnglists() {
+
+  // Don't emit a rangelist table if there are no ranges.
+  if (llvm::all_of(CUMap,
+                   [](const decltype(CUMap)::const_iterator::value_type &Pair) {
+                     DwarfCompileUnit *TheCU = Pair.second;
+                     if (auto *Skel = TheCU->getSkeleton())
+                       TheCU = Skel;
+                     return TheCU->getRangeLists().empty();
+                   }))
+    return;
+
+  assert(getDwarfVersion() >= 5 && "Dwarf version must be 5 or greater");
+  // FIXME: As long as we don't support DW_RLE_base_addrx, we cannot generate
+  // any tables in the .debug_rnglists.dwo section.
+  Asm->OutStreamer->SwitchSection(
+      Asm->getObjFileLowering().getDwarfRnglistsSection());
+  // The length is described by a starting label right after the length field
+  // and an end label.
+  MCSymbol *TableStart = Asm->createTempSymbol("debug_rnglist_table_start");
+  MCSymbol *TableEnd = Asm->createTempSymbol("debug_rnglist_table_end");
+  // Build the range table header, which starts with the length field.
+  Asm->EmitLabelDifference(TableEnd, TableStart, 4);
+  Asm->OutStreamer->EmitLabel(TableStart);
+  // Version number (DWARF v5 and later).
+  Asm->emitInt16(getDwarfVersion());
+  // Address size.
+  Asm->emitInt8(Asm->MAI->getCodePointerSize());
+  // Segment selector size.
+  Asm->emitInt8(0);
+
+  MCSymbol *RnglistTableBaseSym =
+      (useSplitDwarf() ? SkeletonHolder : InfoHolder).getRnglistsTableBaseSym();
+
+  // FIXME: Generate the offsets table and use DW_FORM_rnglistx with the
+  // DW_AT_ranges attribute. Until then set the number of offsets to 0.
+  Asm->emitInt32(0);
+  Asm->OutStreamer->EmitLabel(RnglistTableBaseSym);
+
+  // Emit the individual range lists.
+  for (const auto &I : CUMap) {
+    DwarfCompileUnit *TheCU = I.second;
+    if (auto *Skel = TheCU->getSkeleton())
+      TheCU = Skel;
+    for (const RangeSpanList &List : TheCU->getRangeLists())
+      emitRangeList(Asm, TheCU, List);
+  }
 
-  // And terminate the list with two 0 values.
-  Asm->OutStreamer->EmitIntValue(0, Size);
-  Asm->OutStreamer->EmitIntValue(0, Size);
+  Asm->OutStreamer->EmitLabel(TableEnd);
 }
 
-/// Emit address ranges into a debug ranges section.
+/// Emit address ranges into the .debug_ranges section or DWARF v5 rangelists
+/// into the .debug_rnglists section.
 void DwarfDebug::emitDebugRanges() {
   if (CUMap.empty())
     return;
@@ -2042,6 +2122,11 @@ void DwarfDebug::emitDebugRanges() {
     return;
   }
 
+  if (getDwarfVersion() >= 5) {
+    emitDebugRnglists();
+    return;
+  }
+
   // Start the dwarf ranges section.
   Asm->OutStreamer->SwitchSection(
       Asm->getObjFileLowering().getDwarfRangesSection());
@@ -2134,7 +2219,7 @@ void DwarfDebug::initSkeletonUnit(const
 
 // This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
 // DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
-// DW_AT_addr_base, DW_AT_ranges_base.
+// DW_AT_addr_base, DW_AT_ranges_base or DW_AT_rnglists_base.
 DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
 
   auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Jul 12 11:18:21 2018
@@ -405,6 +405,9 @@ class DwarfDebug : public DebugHandlerBa
   /// Emit address ranges into a debug ranges section.
   void emitDebugRanges();
 
+  /// Emit range lists into a DWARF v5 debug rnglists section.
+  void emitDebugRnglists();
+
   /// Emit macros into a debug macinfo section.
   void emitDebugMacinfo();
   void emitMacro(DIMacro &M);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h Thu Jul 12 11:18:21 2018
@@ -48,6 +48,10 @@ class DwarfFile {
   /// the string offsets table. The contribution is shared by all units.
   MCSymbol *StringOffsetsStartSym = nullptr;
 
+  /// DWARF v5: The symbol that designates the base of the range list table.
+  /// The table is shared by all units.
+  MCSymbol *RnglistsTableBaseSym = nullptr;
+
   /// The variables of a lexical scope.
   struct ScopeVars {
     /// We need to sort Args by ArgNo and check for duplicates. This could also
@@ -114,6 +118,10 @@ public:
 
   void setStringOffsetsStartSym(MCSymbol *Sym) { StringOffsetsStartSym = Sym; }
 
+  MCSymbol *getRnglistsTableBaseSym() const { return RnglistsTableBaseSym; }
+
+  void setRnglistsTableBaseSym(MCSymbol *Sym) { RnglistsTableBaseSym = Sym; }
+
   /// \returns false if the variable was merged with a previous one.
   bool addScopeVariable(LexicalScope *LS, DbgVariable *Var);
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Thu Jul 12 11:18:21 2018
@@ -1757,3 +1757,12 @@ void DwarfUnit::addStringOffsetsStart()
                   DU->getStringOffsetsStartSym(),
                   TLOF.getDwarfStrOffSection()->getBeginSymbol());
 }
+
+void DwarfUnit::addRnglistsBase() {
+  assert(DD->getDwarfVersion() >= 5 &&
+         "DW_AT_rnglists_base requires DWARF version 5 or later");
+  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+  addSectionLabel(getUnitDie(), dwarf::DW_AT_rnglists_base,
+                  DU->getRnglistsTableBaseSym(),
+                  TLOF.getDwarfRnglistsSection()->getBeginSymbol());
+}

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h Thu Jul 12 11:18:21 2018
@@ -112,6 +112,8 @@ public:
   uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
   const DICompileUnit *getCUNode() const { return CUNode; }
 
+  uint16_t getDwarfVersion() const { return DD->getDwarfVersion(); }
+
   /// Return true if this compile unit has something to write out.
   bool hasContent() const { return getUnitDie().hasChildren(); }
 
@@ -293,6 +295,9 @@ public:
   /// Add the DW_AT_str_offsets_base attribute to the unit DIE.
   void addStringOffsetsStart();
 
+  /// Add the DW_AT_rnglists_base attribute to the unit DIE.
+  void addRnglistsBase();
+
   virtual DwarfCompileUnit &getCU() = 0;
 
   void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy);

Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Thu Jul 12 11:18:21 2018
@@ -267,6 +267,9 @@ void MCObjectFileInfo::initMachOMCObject
   DwarfRangesSection =
       Ctx->getMachOSection("__DWARF", "__debug_ranges", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata(), "debug_range");
+  DwarfRnglistsSection =
+      Ctx->getMachOSection("__DWARF", "__debug_rnglists", MachO::S_ATTR_DEBUG,
+                           SectionKind::getMetadata(), "debug_range");
   DwarfMacinfoSection =
       Ctx->getMachOSection("__DWARF", "__debug_macinfo", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata(), "debug_macinfo");
@@ -578,6 +581,7 @@ void MCObjectFileInfo::initELFMCObjectFi
   DwarfStrOffSection =
       Ctx->getELFSection(".debug_str_offsets", DebugSecType, 0);
   DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
+  DwarfRnglistsSection = Ctx->getELFSection(".debug_rnglists", DebugSecType, 0);
 
   // Fission Sections
   DwarfInfoDWOSection =
@@ -595,6 +599,8 @@ void MCObjectFileInfo::initELFMCObjectFi
       Ctx->getELFSection(".debug_loc.dwo", DebugSecType, 0);
   DwarfStrOffDWOSection =
       Ctx->getELFSection(".debug_str_offsets.dwo", DebugSecType, 0);
+  DwarfRnglistsDWOSection =
+      Ctx->getELFSection(".debug_rnglists.dwo", DebugSecType, 0);
 
   // DWP Sections
   DwarfCUIndexSection =

Modified: llvm/trunk/test/DebugInfo/X86/fission-ranges.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/fission-ranges.ll?rev=336927&r1=336926&r2=336927&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/fission-ranges.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/fission-ranges.ll Thu Jul 12 11:18:21 2018
@@ -2,6 +2,9 @@
 ; RUN: llvm-dwarfdump -v %t | FileCheck %s
 ; RUN: llvm-objdump -h %t | FileCheck --check-prefix=HDR %s
 
+; RUN: llc -dwarf-version=5 -O0 %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t
+; RUN: llvm-dwarfdump -v %t | FileCheck --check-prefix=V5RNGLISTS %s
+
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_compile_unit
 ; CHECK-NEXT: DW_AT_stmt_list
@@ -10,7 +13,6 @@
 ; CHECK-NEXT: DW_AT_GNU_dwo_id
 ; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset]                   (0x00000000)
 
-
 ; CHECK: .debug_info.dwo contents:
 ; CHECK: DW_AT_location [DW_FORM_sec_offset]   ([[A:0x[0-9a-z]*]]
 ; CHECK: DW_AT_location [DW_FORM_sec_offset]   ([[E:0x[0-9a-z]*]]
@@ -34,7 +36,6 @@
 ; CHECK:      [[D]]:
 ; CHECK-NEXT:   Addr idx 6 (w/ length 17): DW_OP_reg0 RAX
 
-
 ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo)
 ; HDR-NOT: .rela.{{.*}}.dwo
 
@@ -45,6 +46,22 @@
 ; HDR: .debug_addr 00000038
 ; HDR-NOT: .rela.{{.*}}.dwo
 
+; Check for the existence of a DWARF v5-style range list table in the .debug_rnglists
+; section and that the compile unit has a DW_AT_rnglists_base attribute.
+; The table should contain at least one rangelist with at least 2 individual ranges.
+
+; V5RNGLISTS:      .debug_info contents:
+; V5RNGLISTS:      DW_TAG_compile_unit
+; V5RNGLISTS-NOT:  DW_TAG
+; V5RNGLISTS:      DW_AT_rnglists_base [DW_FORM_sec_offset]  (0x0000000c)
+; V5RNGLISTS:      .debug_rnglists contents:
+; V5RNGLISTS-NEXT: 0x00000000: Range List Header: length = 0x00000014, version = 0x0005,
+; V5RNGLISTS-SAME: addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+; V5RNGLISTS-NEXT: Ranges:
+; V5RNGLISTS-NEXT: 0x0000000c: [DW_RLE_offset_pair]:
+; V5RNGLISTS-NEXT: 0x0000000f: [DW_RLE_offset_pair]:
+; V5RNGLISTS:      0x{{[0-9a-f]+}}: [DW_RLE_end_of_list]
+
 ; From the code:
 
 ; extern int c;

Added: llvm/trunk/test/DebugInfo/X86/rnglists-nobase.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/rnglists-nobase.ll?rev=336927&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/rnglists-nobase.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/rnglists-nobase.ll Thu Jul 12 11:18:21 2018
@@ -0,0 +1,87 @@
+; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t < %s
+; RUN: llvm-dwarfdump -v %t | FileCheck %s
+
+; We make sure that we generate DW_RLE_start_length range list entries when 
+; we do not have a base, which is the case when functions go into different
+; sections. We should have 3 individual range list entries because there are
+; 3 functions.
+; 
+; From the following source:
+;
+; class A
+; {
+; public:
+;   A();
+; };
+; 
+; static A glob;
+; void foo() {
+; }
+;
+; Compile with clang -O1 -gdwarf-5 -S -emit-llvm
+;
+; CHECK:      .debug_rnglists contents:
+; CHECK-NEXT: 0x00000000: Range List Header: length = 0x00000027, version = 0x0005,
+; CHECK-SAME: addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+; CHECK-NEXT: Ranges:
+; CHECK-NEXT: 0x0000000c: [DW_RLE_start_length]:
+; CHECK-NEXT: 0x00000016: [DW_RLE_start_length]:
+; CHECK-NEXT: 0x00000020: [DW_RLE_start_length]:
+; CHECK-NEXT: 0x0000002a: [DW_RLE_end_of_list ]
+
+%class.A = type { i8 }
+
+ at _ZL4glob = internal global %class.A zeroinitializer, align 1, !dbg !0
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_xx.cpp, i8* null }]
+
+; Function Attrs: uwtable
+define internal fastcc void @__cxx_global_var_init() unnamed_addr section ".text.startup" !dbg !16 {
+entry:
+  tail call void @_ZN1AC1Ev(%class.A* nonnull @_ZL4glob), !dbg !19
+  ret void, !dbg !19
+}
+
+declare dso_local void @_ZN1AC1Ev(%class.A*) unnamed_addr
+
+; Function Attrs: norecurse nounwind readnone uwtable
+define dso_local void @_Z3foov() local_unnamed_addr !dbg !20 {
+entry:
+  ret void, !dbg !21
+}
+
+; Function Attrs: uwtable
+define internal void @_GLOBAL__sub_I_xx.cpp() section ".text.startup" !dbg !22 {
+entry:
+  tail call fastcc void @__cxx_global_var_init(), !dbg !24
+  ret void
+}
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "glob", linkageName: "_ZL4glob", scope: !2, file: !3, line: 7, type: !6, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk 335191)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "test.cpp", directory: "/home/test", checksumkind: CSK_MD5, checksum: "535784cf49522e3a6d1166f6c4e482ba")
+!4 = !{}
+!5 = !{!0}
+!6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A", file: !3, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTS1A")
+!7 = !{!8}
+!8 = !DISubprogram(name: "A", scope: !6, file: !3, line: 4, type: !9, isLocal: false, isDefinition: false, scopeLine: 4, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: true)
+!9 = !DISubroutineType(types: !10)
+!10 = !{null, !11}
+!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
+!12 = !{i32 2, !"Dwarf Version", i32 5}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"wchar_size", i32 4}
+!15 = !{!"clang version 7.0.0 (trunk 335191)"}
+!16 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, line: 7, type: !17, isLocal: true, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!17 = !DISubroutineType(types: !18)
+!18 = !{null}
+!19 = !DILocation(line: 7, column: 10, scope: !16)
+!20 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 9, type: !17, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!21 = !DILocation(line: 10, column: 1, scope: !20)
+!22 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_xx.cpp", scope: !3, file: !3, type: !23, isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: true, unit: !2, retainedNodes: !4)
+!23 = !DISubroutineType(types: !4)
+!24 = !DILocation(line: 0, scope: !22)




More information about the llvm-commits mailing list