[DWARFDebugLine] Use new DWARFDataExtractor::getInitialLength
authorPavel Labath <pavel@labath.sk>
Fri, 14 Feb 2020 14:41:38 +0000 (15:41 +0100)
committerPavel Labath <pavel@labath.sk>
Mon, 2 Mar 2020 10:14:29 +0000 (11:14 +0100)
Summary:
The error messages change somewhat, but I believe the overall
informational value remains unchanged.

Reviewers: jhenderson, dblaikie, ikudrin

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp

index d4a6beb..3c1f48a 100644 (file)
@@ -340,18 +340,15 @@ Error DWARFDebugLine::Prologue::parse(
   const uint64_t PrologueOffset = *OffsetPtr;
 
   clear();
-  TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr);
-  if (TotalLength == dwarf::DW_LENGTH_DWARF64) {
-    FormParams.Format = dwarf::DWARF64;
-    TotalLength = DebugLineData.getU64(OffsetPtr);
-  } else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) {
-    // Treat this error as unrecoverable - we have no way of knowing where the
-    // table ends.
-    return createStringError(errc::invalid_argument,
-        "parsing line table prologue at offset 0x%8.8" PRIx64
-        " unsupported reserved unit length found of value 0x%8.8" PRIx64,
-        PrologueOffset, TotalLength);
-  }
+  Error Err = Error::success();
+  std::tie(TotalLength, FormParams.Format) =
+      DebugLineData.getInitialLength(OffsetPtr, &Err);
+  if (Err)
+    return createStringError(
+        errc::invalid_argument,
+        "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
+        PrologueOffset, toString(std::move(Err)).c_str());
+
   FormParams.Version = DebugLineData.getU16(OffsetPtr);
   if (!versionIsSupported(getVersion()))
     // Treat this error as unrecoverable - we cannot be sure what any of
@@ -360,7 +357,7 @@ Error DWARFDebugLine::Prologue::parse(
     return createStringError(
         errc::not_supported,
         "parsing line table prologue at offset 0x%8.8" PRIx64
-        " found unsupported version %" PRIu16,
+        ": unsupported version %" PRIu16,
         PrologueOffset, getVersion());
 
   if (getVersion() >= 5) {
@@ -1218,8 +1215,7 @@ DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
 }
 
 bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
-  return TotalLength == dwarf::DW_LENGTH_DWARF64 ||
-         TotalLength < dwarf::DW_LENGTH_lo_reserved;
+  return TotalLength != 0u;
 }
 
 DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s
new file mode 100644 (file)
index 0000000..a66ac7a
--- /dev/null
@@ -0,0 +1,37 @@
+## Test that we can dump the (intact) prologue of a large table which was
+## truncated. Also, make sure we don't get confused by a DWARF64 length which
+## matches one of the reserved initial length values.
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s >%t
+# RUN: llvm-dwarfdump %t -debug-line 2>&1 | FileCheck %s
+
+# CHECK: debug_line[0x00000000]
+# CHECK-NEXT: warning: line table program with offset 0x00000000 has length 0xfffffffc but only 0x0000003a bytes are available
+# CHECK-NEXT: Line table prologue:
+# CHECK-NEXT:     total_length: 0xfffffff0
+# CHECK-NEXT:          version: 4
+# CHECK-NEXT:  prologue_length: 0x00000016
+
+# CHECK:      0x000000000badbeef      1      0      1   0             0  is_stmt end_sequence
+
+.section .debug_line,"",@progbits
+.long   0xffffffff      # Length of Unit (DWARF-64 format)
+.quad   0xfffffff0
+.short  4               # DWARF version number
+.quad   .Lprologue1_end-.Lprologue1_start # Length of Prologue
+.Lprologue1_start:
+.byte   1               # Minimum Instruction Length
+.byte   1               # Maximum Operations per Instruction
+.byte   1               # Default is_stmt
+.byte   -5              # Line Base
+.byte   14              # Line Range
+.byte   1               # Opcode Base
+.asciz "dir1"           # Include table
+.byte   0
+.asciz "file1"          # File table
+.byte   0, 0, 0
+.byte   0
+.Lprologue1_end:
+.byte   0, 9, 2         # DW_LNE_set_address
+.quad   0x0badbeef
+.byte   0, 1, 1         # DW_LNE_end_sequence
index 871d6e9..797eb2f 100644 (file)
@@ -46,7 +46,7 @@
 ## For fatal issues, the following table(s) should not be dumped:
 # FATAL:      debug_line[0x00000048]
 # RESERVED-NOT: prologue
-# RESERVED: warning: parsing line table prologue at offset 0x00000048 unsupported reserved unit length found of value 0xfffffffe
+# RESERVED: warning: parsing line table prologue at offset 0x00000048: unsupported reserved unit length of value 0xfffffffe
 # RESERVED-NOT: prologue
 # FATAL-NOT:  debug_line
 
 # LAST:          0x00000000cafebabe {{.*}} end_sequence
 
 # ALL-NOT:  warning:
-# ALL:      warning: parsing line table prologue at offset 0x00000048 found unsupported version 0
-# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e found unsupported version 1
+# ALL:      warning: parsing line table prologue at offset 0x00000048: unsupported version 0
+# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e: unsupported version 1
 # ALL-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073
 # ALL-NEXT: warning: failed to parse entry content descriptions because no path was found
 # ALL-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba
index 0ec04a7..25db5af 100644 (file)
@@ -210,6 +210,11 @@ TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {
   generate();
 
   EXPECT_THAT_EXPECTED(
+      getOrParseLineTableFatalErrors(0),
+      FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+                        "unexpected end of data at offset 0x0"));
+
+  EXPECT_THAT_EXPECTED(
       getOrParseLineTableFatalErrors(1),
       FailedWithMessage(
           "offset 0x00000001 is not a valid debug line section offset"));
@@ -316,8 +321,8 @@ TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {
   EXPECT_THAT_EXPECTED(
       getOrParseLineTableFatalErrors(),
       FailedWithMessage(
-          "parsing line table prologue at offset 0x00000000 unsupported "
-          "reserved unit length found of value 0xfffffff0"));
+          "parsing line table prologue at offset 0x00000000: unsupported "
+          "reserved unit length of value 0xfffffff0"));
 }
 
 struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>,
@@ -339,8 +344,8 @@ TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) {
 
   EXPECT_THAT_EXPECTED(
       getOrParseLineTableFatalErrors(),
-      FailedWithMessage("parsing line table prologue at offset 0x00000000 "
-                        "found unsupported version " +
+      FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+                        "unsupported version " +
                         std::to_string(Version)));
 }
 
@@ -807,7 +812,7 @@ TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) {
   EXPECT_TRUE(Parser.done());
 }
 
-TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
+TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) {
   if (!setupGenerator())
     return;
 
@@ -819,18 +824,18 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
   DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
   Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
 
-  EXPECT_EQ(Parser.getOffset(), 4u);
+  EXPECT_EQ(Parser.getOffset(), 0u);
   EXPECT_TRUE(Parser.done());
   EXPECT_FALSE(Recoverable);
 
   EXPECT_THAT_ERROR(
       std::move(Unrecoverable),
       FailedWithMessage(
-          "parsing line table prologue at offset 0x00000000 unsupported "
-          "reserved unit length found of value 0xfffffff0"));
+          "parsing line table prologue at offset 0x00000000: unsupported "
+          "reserved unit length of value 0xfffffff0"));
 }
 
-TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
+TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenSkipping) {
   if (!setupGenerator())
     return;
 
@@ -842,15 +847,15 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
   DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
   Parser.skip(RecordRecoverable, RecordUnrecoverable);
 
-  EXPECT_EQ(Parser.getOffset(), 4u);
+  EXPECT_EQ(Parser.getOffset(), 0u);
   EXPECT_TRUE(Parser.done());
   EXPECT_FALSE(Recoverable);
 
   EXPECT_THAT_ERROR(
       std::move(Unrecoverable),
       FailedWithMessage(
-          "parsing line table prologue at offset 0x00000000 unsupported "
-          "reserved unit length found of value 0xfffffff0"));
+          "parsing line table prologue at offset 0x00000000: unsupported "
+          "reserved unit length of value 0xfffffff0"));
 }
 
 TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
@@ -873,10 +878,10 @@ TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
 
   EXPECT_THAT_ERROR(
       std::move(Unrecoverable),
-      FailedWithMessage("parsing line table prologue at offset 0x00000000 "
-                        "found unsupported version 0",
-                        "parsing line table prologue at offset 0x00000006 "
-                        "found unsupported version 1"));
+      FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+                        "unsupported version 0",
+                        "parsing line table prologue at offset 0x00000006: "
+                        "unsupported version 1"));
 }
 
 TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
@@ -932,10 +937,10 @@ TEST_F(DebugLineBasicFixture,
 
   EXPECT_THAT_ERROR(
       std::move(Unrecoverable),
-      FailedWithMessage("parsing line table prologue at offset 0x00000000 "
-                        "found unsupported version 0",
-                        "parsing line table prologue at offset 0x00000006 "
-                        "found unsupported version 1"));
+      FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+                        "unsupported version 0",
+                        "parsing line table prologue at offset 0x00000006: "
+                        "unsupported version 1"));
 }
 
 TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {