[llvm] r335188 - [DWARF] Improved error reporting for range lists.

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 20 15:56:38 PDT 2018


Author: wolfgangp
Date: Wed Jun 20 15:56:37 2018
New Revision: 335188

URL: http://llvm.org/viewvc/llvm-project?rev=335188&view=rev
Log:
[DWARF] Improved error reporting for range lists. 
Errors found processing the DW_AT_ranges attribute are propagated by lower level 
routines and reported by their callers.

Reviewer: JDevlieghere

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


Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
    llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-rnglists.s
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp
    llvm/trunk/tools/llvm-dwarfdump/Statistics.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=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h Wed Jun 20 15:56:37 2018
@@ -71,7 +71,7 @@ public:
 
   void clear();
   void dump(raw_ostream &OS) const;
-  bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
+  Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
   const std::vector<RangeListEntry> &getEntries() { return Entries; }
 
   /// getAbsoluteRanges - Returns absolute address ranges defined by this range

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h Wed Jun 20 15:56:37 2018
@@ -97,7 +97,7 @@ public:
   Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
   /// Look up a rangelist based on a given offset. Extract it and enter it into
   /// the ranges map if necessary.
-  Optional<DWARFDebugRnglist> findRangeList(DWARFDataExtractor Data,
+  Expected<DWARFDebugRnglist> findRangeList(DWARFDataExtractor Data,
                                             uint32_t Offset);
   uint32_t getHeaderOffset() const { return HeaderOffset; }
   uint8_t getAddrSize() const { return HeaderData.AddrSize; }

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h Wed Jun 20 15:56:37 2018
@@ -207,7 +207,7 @@ public:
   ///
   /// \returns a address range vector that might be empty if no address range
   /// information is available.
-  DWARFAddressRangesVector getAddressRanges() const;
+  Expected<DWARFAddressRangesVector> getAddressRanges() const;
 
   /// Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any
   /// of its children.

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=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Jun 20 15:56:37 2018
@@ -371,11 +371,12 @@ public:
     return DataExtractor(StringSection, false, 0);
   }
 
-  /// extractRangeList - extracts the range list referenced by this compile
-  /// unit from .debug_ranges section. Returns true on success.
-  /// Requires that compile unit is already extracted.
-  bool extractRangeList(uint32_t RangeListOffset,
-                        DWARFDebugRangeList &RangeList) const;
+  /// Extract the range list referenced by this compile unit from the
+  /// .debug_ranges section. If the extraction is unsuccessful, an error
+  /// is returned. Successful extraction requires that the compile unit
+  /// has already been extracted.
+  Error extractRangeList(uint32_t RangeListOffset,
+                         DWARFDebugRangeList &RangeList) const;
   void clear();
 
   const Optional<StrOffsetsContributionDescriptor> &
@@ -450,12 +451,12 @@ public:
 
   /// Return a vector of address ranges resulting from a (possibly encoded)
   /// range list starting at a given offset in the appropriate ranges section.
-  DWARFAddressRangesVector findRnglistFromOffset(uint32_t Offset);
+  Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset);
 
   /// Return a vector of address ranges retrieved from an encoded range
   /// list whose offset is found via a table lookup given an index (DWARF v5
   /// and later).
-  DWARFAddressRangesVector findRnglistFromIndex(uint32_t Index);
+  Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
 
   /// Return a rangelist's offset based on an index. The index designates
   /// an entry in the rangelist table's offset array and is supplied by

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Jun 20 15:56:37 2018
@@ -470,8 +470,13 @@ void DWARFContext::dump(
                                   isLittleEndian(), savedAddressByteSize);
     uint32_t offset = 0;
     DWARFDebugRangeList rangeList;
-    while (rangeList.extract(rangesData, &offset))
+    while (rangesData.isValidOffset(offset)) {
+      if (Error E = rangeList.extract(rangesData, &offset)) {
+        WithColor::error() << toString(std::move(E)) << '\n';
+        break;  
+      }
       rangeList.dump(OS);
+    }
   }
 
   if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp Wed Jun 20 15:56:37 2018
@@ -16,20 +16,30 @@
 
 using namespace llvm;
 
+// FIXME: There are several versions of this. Consolidate them.
+template <typename... Ts>
+static Error createError(char const *Fmt, const Ts &... Vals) {
+  std::string Buffer;
+  raw_string_ostream Stream(Buffer);
+  Stream << format(Fmt, Vals...);
+  return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
+}
+
 void DWARFDebugRangeList::clear() {
   Offset = -1U;
   AddressSize = 0;
   Entries.clear();
 }
 
-bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
-                                  uint32_t *offset_ptr) {
+Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
+                                   uint32_t *offset_ptr) {
   clear();
   if (!data.isValidOffset(*offset_ptr))
-    return false;
+    return createError("invalid range list offset 0x%" PRIx32, *offset_ptr);
+
   AddressSize = data.getAddressSize();
   if (AddressSize != 4 && AddressSize != 8)
-    return false;
+    return createError("invalid address size: %d", AddressSize);
   Offset = *offset_ptr;
   while (true) {
     RangeListEntry Entry;
@@ -43,13 +53,14 @@ bool DWARFDebugRangeList::extract(const
     // Check that both values were extracted correctly.
     if (*offset_ptr != prev_offset + 2 * AddressSize) {
       clear();
-      return false;
+      return createError("invalid range list entry at offset 0x%" PRIx32,
+                         prev_offset);
     }
     if (Entry.isEndOfListEntry())
       break;
     Entries.push_back(Entry);
   }
-  return true;
+  return Error::success();
 }
 
 void DWARFDebugRangeList::dump(raw_ostream &OS) const {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp Wed Jun 20 15:56:37 2018
@@ -208,6 +208,8 @@ DWARFAddressRangesVector DWARFDebugRngli
 
 Error DWARFDebugRnglist::extract(DWARFDataExtractor Data, uint32_t HeaderOffset,
                                  uint32_t End, uint32_t *OffsetPtr) {
+  if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
+    return createError("invalid range list offset 0x%" PRIx32, *OffsetPtr);
   Entries.clear();
   while (*OffsetPtr < End) {
     RangeListEntry Entry{0, 0, 0, 0, 0};
@@ -351,7 +353,7 @@ uint32_t DWARFDebugRnglistTable::length(
   return HeaderData.Length + sizeof(uint32_t);
 }
 
-Optional<DWARFDebugRnglist>
+Expected<DWARFDebugRnglist>
 DWARFDebugRnglistTable::findRangeList(DWARFDataExtractor Data,
                                       uint32_t Offset) {
   auto Entry = Ranges.find(Offset);
@@ -362,10 +364,8 @@ DWARFDebugRnglistTable::findRangeList(DW
   DWARFDebugRnglist RngList;
   uint32_t End = HeaderOffset + length();
   uint32_t StartingOffset = Offset;
-  if (Error E = RngList.extract(Data, HeaderOffset, End, &Offset)) {
-    llvm::consumeError(std::move(E));
-    return None;
-  }
+  if (Error E = RngList.extract(Data, HeaderOffset, End, &Offset))
+    return std::move(E);
   Ranges[StartingOffset] = RngList;
   return RngList;
 }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Wed Jun 20 15:56:37 2018
@@ -270,8 +270,12 @@ static void dumpAttribute(raw_ostream &O
         FV.setUValue(*RangeListOffset);
         FV.dump(OS, DumpOpts);
       }
-    dumpRanges(Obj, OS, Die.getAddressRanges(), U->getAddressByteSize(),
-               sizeof(BaseIndent) + Indent + 4, DumpOpts);
+    if (auto RangesOrError = Die.getAddressRanges())
+      dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
+                 sizeof(BaseIndent) + Indent + 4, DumpOpts);
+    else
+      WithColor::error() << "decoding address ranges: "
+                         << toString(RangesOrError.takeError()) << '\n';
   }
 
   OS << ")\n";
@@ -385,13 +389,13 @@ bool DWARFDie::getLowAndHighPC(uint64_t
   return false;
 }
 
-DWARFAddressRangesVector DWARFDie::getAddressRanges() const {
+Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const {
   if (isNULL())
     return DWARFAddressRangesVector();
   // Single range specified by low/high PC.
   uint64_t LowPC, HighPC, Index;
   if (getLowAndHighPC(LowPC, HighPC, Index))
-    return {{LowPC, HighPC, Index}};
+    return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
 
   Optional<DWARFFormValue> Value = find(DW_AT_ranges);
   if (Value) {
@@ -407,8 +411,11 @@ void DWARFDie::collectChildrenAddressRan
   if (isNULL())
     return;
   if (isSubprogramDIE()) {
-    const auto &DIERanges = getAddressRanges();
-    Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+    if (auto DIERangesOrError = getAddressRanges())
+      Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
+                    DIERangesOrError.get().end());
+    else
+      llvm::consumeError(DIERangesOrError.takeError());
   }
 
   for (auto Child : children())
@@ -416,10 +423,15 @@ void DWARFDie::collectChildrenAddressRan
 }
 
 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
-  for (const auto &R : getAddressRanges()) {
+  auto RangesOrError = getAddressRanges();
+  if (!RangesOrError) {
+    llvm::consumeError(RangesOrError.takeError());
+    return false;
+  }
+
+  for (const auto &R : RangesOrError.get())
     if (R.LowPC <= Address && Address < R.HighPC)
       return true;
-  }
   return false;
 }
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Wed Jun 20 15:56:37 2018
@@ -181,8 +181,8 @@ parseRngListTableHeader(DWARFDataExtract
   return Table;
 }
 
-bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
-                                 DWARFDebugRangeList &RangeList) const {
+Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
+                                  DWARFDebugRangeList &RangeList) const {
   // Require that compile unit is extracted.
   assert(!DieArray.empty());
   DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
@@ -397,26 +397,39 @@ void DWARFUnit::clearDIEs(bool KeepCUDie
   }
 }
 
-DWARFAddressRangesVector DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
   if (getVersion() <= 4) {
     DWARFDebugRangeList RangeList;
-    if (extractRangeList(Offset, RangeList))
-      return RangeList.getAbsoluteRanges(getBaseAddress());
-    return DWARFAddressRangesVector();
+    if (Error E = extractRangeList(Offset, RangeList))
+      return std::move(E);
+    return RangeList.getAbsoluteRanges(getBaseAddress());
   }
   if (RngListTable) {
     DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
                                   isLittleEndian, RngListTable->getAddrSize());
-    if (auto RangeList = RngListTable->findRangeList(RangesData, Offset))
-      return RangeList->getAbsoluteRanges(getBaseAddress());
+    auto RangeListOrError = RngListTable->findRangeList(RangesData, Offset);
+    if (RangeListOrError)
+      return RangeListOrError.get().getAbsoluteRanges(getBaseAddress());
+    return RangeListOrError.takeError();
   }
-  return DWARFAddressRangesVector();
+
+  return make_error<StringError>("missing or invalid range list table",
+                                 inconvertibleErrorCode());
 }
 
-DWARFAddressRangesVector DWARFUnit::findRnglistFromIndex(uint32_t Index) {
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromIndex(uint32_t Index) {
   if (auto Offset = getRnglistOffset(Index))
     return findRnglistFromOffset(*Offset + RangeSectionBase);
-  return DWARFAddressRangesVector();
+
+  std::string Buffer;
+  raw_string_ostream Stream(Buffer);
+  if (RngListTable)
+    Stream << format("invalid range list table index %d", Index);
+  else
+    Stream << "missing or invalid range list table";
+  return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
 }
 
 void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
@@ -424,11 +437,16 @@ void DWARFUnit::collectAddressRanges(DWA
   if (!UnitDie)
     return;
   // First, check if unit DIE describes address ranges for the whole unit.
-  const auto &CUDIERanges = UnitDie.getAddressRanges();
-  if (!CUDIERanges.empty()) {
-    CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
-    return;
-  }
+  auto CUDIERangesOrError = UnitDie.getAddressRanges();
+  if (CUDIERangesOrError) {
+    if (!CUDIERangesOrError.get().empty()) {
+      CURanges.insert(CURanges.end(), CUDIERangesOrError.get().begin(),
+                      CUDIERangesOrError.get().end());
+      return;
+    }
+  } else
+    WithColor::error() << "decoding address ranges: "
+                       << toString(CUDIERangesOrError.takeError()) << '\n';
 
   // This function is usually called if there in no .debug_aranges section
   // in order to produce a compile unit level set of address ranges that
@@ -454,21 +472,25 @@ void DWARFUnit::collectAddressRanges(DWA
 
 void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
   if (Die.isSubroutineDIE()) {
-    for (const auto &R : Die.getAddressRanges()) {
-      // Ignore 0-sized ranges.
-      if (R.LowPC == R.HighPC)
-        continue;
-      auto B = AddrDieMap.upper_bound(R.LowPC);
-      if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
-        // The range is a sub-range of existing ranges, we need to split the
-        // existing range.
-        if (R.HighPC < B->second.first)
-          AddrDieMap[R.HighPC] = B->second;
-        if (R.LowPC > B->first)
-          AddrDieMap[B->first].first = R.LowPC;
+    auto DIERangesOrError = Die.getAddressRanges();
+    if (DIERangesOrError) {
+      for (const auto &R : DIERangesOrError.get()) {
+        // Ignore 0-sized ranges.
+        if (R.LowPC == R.HighPC)
+          continue;
+        auto B = AddrDieMap.upper_bound(R.LowPC);
+        if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
+          // The range is a sub-range of existing ranges, we need to split the
+          // existing range.
+          if (R.HighPC < B->second.first)
+            AddrDieMap[R.HighPC] = B->second;
+          if (R.LowPC > B->first)
+            AddrDieMap[B->first].first = R.LowPC;
+        }
+        AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
       }
-      AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
-    }
+    } else
+      llvm::consumeError(DIERangesOrError.takeError());
   }
   // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
   // simplify the logic to update AddrDieMap. The child's range will always

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Wed Jun 20 15:56:37 2018
@@ -324,8 +324,15 @@ unsigned DWARFVerifier::verifyDieRanges(
   if (!Die.isValid())
     return NumErrors;
 
-  DWARFAddressRangesVector Ranges = Die.getAddressRanges();
+  auto RangesOrError = Die.getAddressRanges();
+  if (!RangesOrError) {
+    // FIXME: Report the error.
+    ++NumErrors;
+    llvm::consumeError(RangesOrError.takeError());
+    return NumErrors;
+  }
 
+  DWARFAddressRangesVector Ranges = RangesOrError.get();
   // Build RI for this DIE and check that ranges within this DIE do not
   // overlap.
   DieRangeInfo RI(Die);

Modified: 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=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s Wed Jun 20 15:56:37 2018
@@ -1,5 +1,6 @@
 # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
-# RUN: llvm-dwarfdump -v %t | FileCheck %s
+# RUN: llvm-dwarfdump -v %t 2>%t.err | FileCheck %s
+# RUN: FileCheck %s <%t.err -check-prefix=ERR
 
 # CHECK: .debug_info contents:
 # CHECK: 0x0000000b: DW_TAG_compile_unit [1]
@@ -68,6 +69,38 @@ foo:
 .quad .Lfunc_begin0           # DW_AT_low_pc
 .long .Ldebug_ranges0         # DW_AT_ranges
 
+# A CU with an invalid DW_AT_ranges attribute
+.Lcu_begin1:
+.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 0x4000                  # DW_AT_ranges
+
+# ERR: error: decoding address ranges: invalid range list offset 0x4000
+
+# A CU where the DW_AT_ranges attribute points to an invalid range list.
+.Lcu_begin2:
+.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_ranges1         # DW_AT_ranges
+
 .section .debug_ranges,"", at progbits
 .Ldebug_ranges0:
  .quad .Lfunc_begin0-.Lfunc_begin0
@@ -80,3 +113,7 @@ foo:
  .quad .Ltmp5-.text.foo1
  .quad 0
  .quad 0
+.Ldebug_ranges1:
+ .quad 0
+
+# ERR: error: decoding address ranges: invalid range list entry at offset 0x50

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-rnglists.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-rnglists.s?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-rnglists.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-rnglists.s Wed Jun 20 15:56:37 2018
@@ -1,6 +1,8 @@
 # RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
 # RUN: llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
 # RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
+# RUN: llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
+# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
 
 # Test object to verify dwarfdump handles v5 range lists.
 # We use very simplified compile unit dies.
@@ -42,7 +44,6 @@
         .byte 0x00  # EOM(3)
         
         .section .debug_info,"", at progbits
-# DWARF v5 CU header.
         .long  CU1_5_end-CU1_5_version  # Length of Unit
 CU1_5_version:
         .short 5               # DWARF version number
@@ -57,7 +58,6 @@ CU1_5_version:
         .byte 0 # NULL
 CU1_5_end:
 
-# DWARF v5 CU header
         .long  CU2_5_end-CU2_5_version  # Length of Unit
 CU2_5_version:
         .short 5               # DWARF version number
@@ -83,6 +83,19 @@ CU3_5_version:
         .long 0                # DW_AT_ranges
         .byte 0                # NULL
 CU3_5_end:
+# A CU DIE with an incorrect DW_AT_ranges attribute
+        .long  CU4_5_end-CU4_5_version  # Length of Unit
+CU4_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 4                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# The compile-unit DIE, which has DW_AT_rnglists_base and DW_AT_ranges.
+        .byte 1                # Abbreviation code
+        .long Rnglist_Table0_base   # DW_AT_rnglists_base
+        .long 4000             # DW_AT_ranges
+        .byte 0                # NULL
+CU4_5_end:
 
         .section .debug_info.dwo,"", at progbits
 
@@ -190,3 +203,5 @@ Range1_end:
 # CHECK-NEXT: [0x0000002a, 0x00000034))
 
 #ERR: error: parsing a range list table: Did not detect a valid range list table with base = 0x8
+#ERR: error: decoding address ranges: missing or invalid range list table
+#ERR: error: decoding address ranges: invalid range list offset 0xfa0

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Wed Jun 20 15:56:37 2018
@@ -3503,7 +3503,11 @@ void DwarfLinker::patchRangesForUnit(con
   for (const auto &RangeAttribute : Unit.getRangesAttributes()) {
     uint32_t Offset = RangeAttribute.get();
     RangeAttribute.set(Streamer->getRangesSectionSize());
-    RangeList.extract(RangeExtractor, &Offset);
+    if (Error E = RangeList.extract(RangeExtractor, &Offset)) {
+      llvm::consumeError(std::move(E));
+      reportWarning("invalid range list ignored.", DMO);
+      RangeList.clear();
+    }
     const auto &Entries = RangeList.getEntries();
     if (!Entries.empty()) {
       const DWARFDebugRangeList::RangeListEntry &First = Entries.front();

Modified: llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp?rev=335188&r1=335187&r2=335188&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/Statistics.cpp Wed Jun 20 15:56:37 2018
@@ -34,8 +34,14 @@ struct GlobalStats {
 
 /// Extract the low pc from a Die.
 static uint64_t getLowPC(DWARFDie Die) {
-  if (Die.getAddressRanges().size())
-    return Die.getAddressRanges()[0].LowPC;
+  auto RangesOrError = Die.getAddressRanges();
+  DWARFAddressRangesVector Ranges;
+  if (RangesOrError)
+    Ranges = RangesOrError.get();
+  else
+    llvm::consumeError(RangesOrError.takeError());
+  if (Ranges.size())
+    return Ranges[0].LowPC;
   return dwarf::toAddress(Die.find(dwarf::DW_AT_low_pc), 0);
 }
 
@@ -137,7 +143,13 @@ static void collectStatsRecursive(DWARFD
     }
 
     // PC Ranges.
-    auto Ranges = Die.getAddressRanges();
+    auto RangesOrError = Die.getAddressRanges();
+    if (!RangesOrError) {
+      llvm::consumeError(RangesOrError.takeError());
+      return;
+    }
+       
+    auto Ranges = RangesOrError.get();
     uint64_t BytesInThisScope = 0;
     for (auto Range : Ranges)
       BytesInThisScope += Range.HighPC - Range.LowPC;




More information about the llvm-commits mailing list