]> granicus.if.org Git - llvm/commitdiff
DebugInfo/DWARF: Provide some (pretty half-hearted) error handling access when parsin...
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Aug 2019 01:14:33 +0000 (01:14 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 9 Aug 2019 01:14:33 +0000 (01:14 +0000)
This isn't the most robust error handling API, but does allow clients to
opt-in to getting Errors they can handle. I suspect the long-term
solution would be to move away from the lazy unit parsing and have an
explicit step that parses the unit and then allows access to the other
APIs that require a parsed unit.

llvm-dwarfdump could be expanded to use this (or newer/better API) to
demonstrate the benefit of it - but for now lld will use this in a
follow-up cl which ensures lld can exit non-zero on errors like this (&
provide more descriptive diagnostics including which object file the
error came from).

(error access to later errors when parsing nested DIEs would be good too
- but, again, exposing that without it being a hassle for every consumer
may be tricky)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368377 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFUnit.h
lib/DebugInfo/DWARF/DWARFUnit.cpp
test/DebugInfo/X86/dwarfdump-str-offsets-invalid.s

index 13cc9a52b44cee8671f4451b427c7f27582adb8a..bd7e3e967c3f8001ff7aa7e557bc558b6470e991 100644 (file)
@@ -495,6 +495,9 @@ public:
   }
 
   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
+
+  Error tryExtractDIEsIfNeeded(bool CUDieOnly);
+
 private:
   /// Size in bytes of the .debug_info data associated with this compile unit.
   size_t getDebugInfoSize() const {
index b333c1c5bf3da22d51c9f3c95fd4f51b70892e2c..cc5a8d77ebc26719d341c9b5cc5b914af0ec458e 100644 (file)
@@ -402,21 +402,26 @@ void DWARFUnit::extractDIEsToVector(
 }
 
 void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+  if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
+    WithColor::error() << toString(std::move(e));
+}
+
+Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
   if ((CUDieOnly && !DieArray.empty()) ||
       DieArray.size() > 1)
-    return; // Already parsed.
+    return Error::success(); // Already parsed.
 
   bool HasCUDie = !DieArray.empty();
   extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
 
   if (DieArray.empty())
-    return;
+    return Error::success();
 
   // If CU DIE was just parsed, copy several attribute values from it.
   if (HasCUDie)
-    return;
+    return Error::success();
 
-  DWARFDie UnitDie = getUnitDIE();
+  DWARFDie UnitDie(this, &DieArray[0]);
   if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
     Header.setDWOId(*DWOId);
   if (!IsDWO) {
@@ -442,13 +447,13 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
     auto StringOffsetOrError =
         IsDWO ? determineStringOffsetsTableContributionDWO(DA)
               : determineStringOffsetsTableContribution(DA);
-    if (!StringOffsetOrError) {
-      WithColor::error() << "invalid contribution to string offsets table in "
-                            "section .debug_str_offsets[.dwo]: "
-                         << toString(StringOffsetOrError.takeError()) << '\n';
-    } else {
-      StringOffsetsTableContribution = *StringOffsetOrError;
-    }
+    if (!StringOffsetOrError)
+      return createStringError(errc::invalid_argument,
+                               "invalid reference to or invalid content in "
+                               ".debug_str_offsets[.dwo]: " +
+                                   toString(StringOffsetOrError.takeError()));
+
+    StringOffsetsTableContribution = *StringOffsetOrError;
   }
 
   // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
@@ -464,12 +469,14 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
       // extracted lazily.
       DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
                                   isLittleEndian, 0);
-      if (auto TableOrError =
-              parseRngListTableHeader(RangesDA, RangeSectionBase))
-        RngListTable = TableOrError.get();
-      else
-        WithColor::error() << "parsing a range list table: "
-                           << toString(TableOrError.takeError()) << '\n';
+      auto TableOrError =
+              parseRngListTableHeader(RangesDA, RangeSectionBase);
+      if (!TableOrError)
+        return createStringError(errc::invalid_argument,
+                                 "parsing a range list table: " +
+                                     toString(TableOrError.takeError()));
+
+      RngListTable = TableOrError.get();
 
       // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
       // Adjust RangeSectionBase to point past the table header.
@@ -480,6 +487,7 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
 
   // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
   // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+  return Error::success();
 }
 
 bool DWARFUnit::parseDWO() {
index a4c22b961b332f5ba2704908d1617b4338a944d0..a3abfaa7f12be96aef06970a72f01066351a2002 100644 (file)
@@ -144,11 +144,11 @@ CU9_end:
 .str_off_end:
 
 
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: insufficient space for 64 bit header prefix
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: invalid length
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: length exceeds section size
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: 32 bit contribution referenced from a 64 bit unit
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: section offset exceeds section size
-# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: section offset exceeds section size
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: insufficient space for 64 bit header prefix
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: invalid length
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: length exceeds section size
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: 32 bit contribution referenced from a 64 bit unit
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: section offset exceeds section size
+# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: section offset exceeds section size
 # CHECK: error: overlapping contributions to string offsets table in section .debug_str_offsets.