[llvm] dba683c - [DWARF] Use DWARFDataExtractor::getInitialLength to parse debug_names

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 2 02:24:49 PST 2020


Author: Pavel Labath
Date: 2020-03-02T11:21:23+01:00
New Revision: dba683ccbe994911c2d7ab65e6cb5b2caae10fb0

URL: https://github.com/llvm/llvm-project/commit/dba683ccbe994911c2d7ab65e6cb5b2caae10fb0
DIFF: https://github.com/llvm/llvm-project/commit/dba683ccbe994911c2d7ab65e6cb5b2caae10fb0.diff

LOG: [DWARF] Use DWARFDataExtractor::getInitialLength to parse debug_names

Summary:
In this patch I've done a slightly bigger rewrite to also remove the
hardcoded header lengths.

Reviewers: jhenderson, dblaikie, ikudrin

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    

Modified: 
    llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
    llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s
    llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s
    llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index bfcd0960faec..a089263f3e5c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -377,56 +377,36 @@ void DWARFDebugNames::Header::dump(ScopedPrinter &W) const {
 
 Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
                                              uint64_t *Offset) {
-  uint64_t StartingOffset = *Offset;
-  // Check that we can read the unit length field.
-  if (!AS.isValidOffsetForDataOfSize(StartingOffset, 4))
+  auto HeaderError = [Offset = *Offset](Error E) {
     return createStringError(errc::illegal_byte_sequence,
-                             "Section too small: cannot read header.");
-  UnitLength = AS.getU32(Offset);
-  if (UnitLength >= dwarf::DW_LENGTH_lo_reserved &&
-      UnitLength != dwarf::DW_LENGTH_DWARF64)
-    return createStringError(errc::illegal_byte_sequence,
-                             "Unsupported reserved unit length value");
-  Format = (UnitLength == dwarf::DW_LENGTH_DWARF64) ? dwarf::DWARF64
-                                                    : dwarf::DWARF32;
-
-  // These fields are the same for 32-bit and 64-bit DWARF formats.
-  constexpr unsigned CommonHeaderSize = 2 + // Version
-                                        2 + // Padding
-                                        4 + // CU count
-                                        4 + // Local TU count
-                                        4 + // Foreign TU count
-                                        4 + // Bucket count
-                                        4 + // Name count
-                                        4 + // Abbreviations table size
-                                        4;  // Augmentation string size
-  // Check that we can read the fixed-size part.
-  if (!AS.isValidOffsetForDataOfSize(
-          StartingOffset,
-          CommonHeaderSize + dwarf::getUnitLengthFieldByteSize(Format)))
-    return createStringError(errc::illegal_byte_sequence,
-                             "Section too small: cannot read header.");
-  if (Format == dwarf::DWARF64)
-    UnitLength = AS.getU64(Offset);
-  Version = AS.getU16(Offset);
-  // Skip padding
-  *Offset += 2;
-  CompUnitCount = AS.getU32(Offset);
-  LocalTypeUnitCount = AS.getU32(Offset);
-  ForeignTypeUnitCount = AS.getU32(Offset);
-  BucketCount = AS.getU32(Offset);
-  NameCount = AS.getU32(Offset);
-  AbbrevTableSize = AS.getU32(Offset);
-  AugmentationStringSize = alignTo(AS.getU32(Offset), 4);
-
-  if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize))
-    return createStringError(
-        errc::illegal_byte_sequence,
-        "Section too small: cannot read header augmentation.");
+                             "parsing .debug_names header at 0x%" PRIx64 ": %s",
+                             Offset, toString(std::move(E)).c_str());
+  };
+
+  DataExtractor::Cursor C(*Offset);
+  std::tie(UnitLength, Format) = AS.getInitialLength(C);
+
+  Version = AS.getU16(C);
+  AS.skip(C, 2); // padding
+  CompUnitCount = AS.getU32(C);
+  LocalTypeUnitCount = AS.getU32(C);
+  ForeignTypeUnitCount = AS.getU32(C);
+  BucketCount = AS.getU32(C);
+  NameCount = AS.getU32(C);
+  AbbrevTableSize = AS.getU32(C);
+  AugmentationStringSize = alignTo(AS.getU32(C), 4);
+
+  if (!C)
+    return HeaderError(C.takeError());
+
+  if (!AS.isValidOffsetForDataOfSize(C.tell(), AugmentationStringSize))
+    return HeaderError(createStringError(errc::illegal_byte_sequence,
+                                         "cannot read header augmentation"));
   AugmentationString.resize(AugmentationStringSize);
-  AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()),
+  AS.getU8(C, reinterpret_cast<uint8_t *>(AugmentationString.data()),
            AugmentationStringSize);
-  return Error::success();
+  *Offset = C.tell();
+  return C.takeError();
 }
 
 void DWARFDebugNames::Abbrev::dump(ScopedPrinter &W) const {

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s
index 9c119726c47f..e09a1bfcfd03 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
 # RUN:   not llvm-dwarfdump -verify - | FileCheck %s
 
-# CHECK: Section too small: cannot read header.
+# CHECK: parsing .debug_names header at 0x0: unexpected end of data at offset 0x20
 
 	.section	.debug_str,"MS", at progbits,1
 .Lstring_producer:

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s
index 60d9c78a695a..a7c051740504 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
 # RUN:   not llvm-dwarfdump -verify - | FileCheck %s
 
-# CHECK: Section too small: cannot read header augmentation.
+# CHECK: parsing .debug_names header at 0x0: cannot read header augmentation
 
 	.section	.debug_str,"MS", at progbits,1
 .Lstring_producer:

diff  --git a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp
index 17a4b7474bfb..0d68083407d5 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp
@@ -8,45 +8,42 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
 
-namespace {
-
-void ExpectDebugNamesExtractError(StringRef NamesSecData, StringRef StrSecData,
-                                  const char *ErrorMessage) {
-  DWARFSection NamesDWARFSection;
-  NamesDWARFSection.Data = NamesSecData;
-  StringMap<std::unique_ptr<MemoryBuffer>> Sections;
-  auto Context = DWARFContext::create(Sections, /* AddrSize = */ 4,
-                                      /* isLittleEndian = */ true);
-  DWARFDataExtractor NamesExtractor(Context->getDWARFObj(), NamesDWARFSection,
-                                    /* isLittleEndian = */ true,
-                                    /* AddrSize = */ 4);
+static Error ExtractDebugNames(StringRef NamesSecData, StringRef StrSecData) {
+  DWARFDataExtractor NamesExtractor(NamesSecData,
+                                    /*isLittleEndian=*/true,
+                                    /*AddrSize=*/4);
   DataExtractor StrExtractor(StrSecData,
-                             /* isLittleEndian = */ true,
-                             /* AddrSize = */ 4);
+                             /*isLittleEndian=*/true,
+                             /*AddrSize=*/4);
   DWARFDebugNames Table(NamesExtractor, StrExtractor);
-  Error E = Table.extract();
-  ASSERT_TRUE(E.operator bool());
-  EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
+  return Table.extract();
 }
 
+namespace {
+
 TEST(DWARFDebugNames, ReservedUnitLength) {
   static const char NamesSecData[64] =
       "\xf0\xff\xff\xff"; // Reserved unit length value
-  ExpectDebugNamesExtractError(StringRef(NamesSecData, sizeof(NamesSecData)),
-                               StringRef(),
-                               "Unsupported reserved unit length value");
+  EXPECT_THAT_ERROR(
+      ExtractDebugNames(StringRef(NamesSecData, sizeof(NamesSecData)),
+                        StringRef()),
+      FailedWithMessage("parsing .debug_names header at 0x0: unsupported "
+                        "reserved unit length of value 0xfffffff0"));
 }
 
 TEST(DWARFDebugNames, TooSmallForDWARF64) {
   // DWARF64 header takes at least 44 bytes.
   static const char NamesSecData[43] = "\xff\xff\xff\xff"; // DWARF64 mark
-  ExpectDebugNamesExtractError(
-      StringRef(NamesSecData, sizeof(NamesSecData)), StringRef(),
-      "Section too small: cannot read header.");
+  EXPECT_THAT_ERROR(
+      ExtractDebugNames(StringRef(NamesSecData, sizeof(NamesSecData)),
+                        StringRef()),
+      FailedWithMessage("parsing .debug_names header at 0x0: unexpected end of "
+                        "data at offset 0x28"));
 }
 
 } // end anonymous namespace


        


More information about the llvm-commits mailing list