[llvm] 9782c92 - [DebugInfo] Print line table extended opcode bytes if parsing fails

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 23 02:04:24 PDT 2020


Author: James Henderson
Date: 2020-06-23T10:04:02+01:00
New Revision: 9782c922cb218cd39b7510be469f61f586414cb7

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

LOG: [DebugInfo] Print line table extended opcode bytes if parsing fails

Previously, if there was an error whilst parsing the operands of an
extended opcode, the operands would be treated as zero and printed. This
could potentially be slightly confusing. This patch changes the
behaviour to print the raw bytes instead.

Reviewed by: ikudrin

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

Added: 
    

Modified: 
    llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
    llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
    llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index f45ab85b0ed8..d10a4734bf3c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -784,15 +784,21 @@ Error DWARFDebugLine::LineTable::parse(
 
       // Tolerate zero-length; assume length is correct and soldier on.
       if (Len == 0) {
-        if (Verbose)
+        if (Cursor && Verbose)
           *OS << "Badly formed extended line op (length 0)\n";
-        if (!Cursor)
+        if (!Cursor) {
+          if (Verbose)
+            *OS << "\n";
           RecoverableErrorHandler(Cursor.takeError());
+        }
         *OffsetPtr = Cursor.tell();
         continue;
       }
 
       uint8_t SubOpcode = TableData.getU8(Cursor);
+      // OperandOffset will be the same as ExtOffset, if it was not possible to
+      // read the SubOpcode.
+      uint64_t OperandOffset = Cursor.tell();
       if (Verbose)
         *OS << LNExtendedString(SubOpcode);
       switch (SubOpcode) {
@@ -805,6 +811,9 @@ Error DWARFDebugLine::LineTable::parse(
         // address is that of the byte after the last target machine instruction
         // of the sequence.
         State.Row.EndSequence = true;
+        // No need to test the Cursor is valid here, since it must be to get
+        // into this code path - if it were invalid, the default case would be
+        // followed.
         if (Verbose) {
           *OS << "\n";
           OS->indent(12);
@@ -858,7 +867,7 @@ Error DWARFDebugLine::LineTable::parse(
               TableData.setAddressSize(ExtractorAddressSize);
           }
 
-          if (Verbose)
+          if (Cursor && Verbose)
             *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
         }
         break;
@@ -893,7 +902,7 @@ Error DWARFDebugLine::LineTable::parse(
           FileEntry.ModTime = TableData.getULEB128(Cursor);
           FileEntry.Length = TableData.getULEB128(Cursor);
           Prologue.FileNames.push_back(FileEntry);
-          if (Verbose)
+          if (Cursor && Verbose)
             *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
                 << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
                 << ", length=" << FileEntry.Length << ")";
@@ -902,12 +911,12 @@ Error DWARFDebugLine::LineTable::parse(
 
       case DW_LNE_set_discriminator:
         State.Row.Discriminator = TableData.getULEB128(Cursor);
-        if (Verbose)
+        if (Cursor && Verbose)
           *OS << " (" << State.Row.Discriminator << ")";
         break;
 
       default:
-        if (Verbose)
+        if (Cursor && Verbose)
           *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
               << format(" length %" PRIx64, Len);
         // Len doesn't include the zero opcode byte or the length itself, but
@@ -926,6 +935,23 @@ Error DWARFDebugLine::LineTable::parse(
             "unexpected line op length at offset 0x%8.8" PRIx64
             " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
             ExtOffset, Len, Cursor.tell() - ExtOffset));
+      if (!Cursor && Verbose) {
+        DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
+        uint8_t Byte = TableData.getU8(ByteCursor);
+        if (ByteCursor) {
+          *OS << " (<parsing error>";
+          do {
+            *OS << format(" %2.2" PRIx8, Byte);
+            Byte = TableData.getU8(ByteCursor);
+          } while (ByteCursor);
+          *OS << ")";
+        }
+
+        // The only parse failure in this case should be if the end was reached.
+        // In that case, throw away the error, as the main Cursor's error will
+        // be sufficient.
+        consumeError(ByteCursor.takeError());
+      }
       *OffsetPtr = End;
     } else if (Opcode < Prologue.OpcodeBase) {
       if (Verbose)

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
index d662d9e16a04..dbcfba39d309 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
@@ -244,7 +244,7 @@
 # VERBOSE-NEXT:  DW_LNE_set_address (0x00000000feedfeed)
 # VERBOSE-NEXT:  DW_LNS_copy
 # NONFATAL-NEXT: 0x00000000feedfeed
-# VERBOSE-NEXT:  DW_LNE_set_address (0x0000000000000000)
+# VERBOSE-NEXT:  DW_LNE_set_address (<parsing error> 00 f0 01 f0 f0 00 01)
 # MORE-ERR-NEXT: warning: unexpected end of data at offset 0x3ed while reading [0x3e6, 0x3ee)
 # MORE-ERR-NEXT: warning: last sequence in debug line table at offset 0x0000039d is not terminated
 

diff  --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
index 11256610fadb..c8b7535b9066 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
@@ -1461,64 +1461,71 @@ TEST_P(TruncatedExtendedOpcodeFixture, ErrorForTruncatedExtendedOpcode) {
 INSTANTIATE_TEST_CASE_P(
     TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture,
     Values(
-        std::make_tuple(1, 1, DW_LNE_end_sequence, ValueAndLengths(),
-                        "Badly formed extended line op (length 0)",
+        // Truncated length:
+        std::make_tuple(1, 1, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",
                         "unable to decode LEB128 at offset 0x00000030: "
                         "malformed uleb128, extends past end"),
+        // Truncated opcode:
         std::make_tuple(
-            2, 9, DW_LNE_set_address,
-            ValueAndLengths{{0x12345678, LineTable::Quad}},
-            "Unrecognized extended op 0x00 length 9",
+            2, 9, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",
             "unexpected end of data at offset 0x31 while reading [0x31, 0x32)"),
+        // Truncated operands:
         std::make_tuple(
             3, 9, DW_LNE_set_address,
-            ValueAndLengths{{0x12345678, LineTable::Quad}},
-            "DW_LNE_set_address (0x0000000000000000)",
+            ValueAndLengths{{0x1234567890abcdef, LineTable::Quad}},
+            "DW_LNE_set_address",
             "unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"),
-        std::make_tuple(3, 5, DW_LNE_define_file,
+        std::make_tuple(
+            10, 9, DW_LNE_set_address,
+            ValueAndLengths{{0x1234567890abcdef, LineTable::Quad}},
+            "DW_LNE_set_address (<parsing error> ef cd ab 90 78 56 34)",
+            "unexpected end of data at offset 0x39 while reading [0x32, 0x3a)"),
+        std::make_tuple(3, 6, DW_LNE_define_file,
                         ValueAndLengths{{'a', LineTable::Byte},
                                         {'\0', LineTable::Byte},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB}},
-                        "DW_LNE_define_file (, dir=0, "
-                        "mod_time=(0x0000000000000000), length=0)",
+                        "DW_LNE_define_file",
                         "no null terminated string at offset 0x32"),
-        std::make_tuple(5, 5, DW_LNE_define_file,
+        std::make_tuple(5, 6, DW_LNE_define_file,
                         ValueAndLengths{{'a', LineTable::Byte},
                                         {'\0', LineTable::Byte},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB}},
-                        "DW_LNE_define_file (a, dir=0, "
-                        "mod_time=(0x0000000000000000), length=0)",
+                        "DW_LNE_define_file (<parsing error> 61 00)",
                         "unable to decode LEB128 at offset 0x00000034: "
                         "malformed uleb128, extends past end"),
-        std::make_tuple(6, 5, DW_LNE_define_file,
+        std::make_tuple(6, 6, DW_LNE_define_file,
                         ValueAndLengths{{'a', LineTable::Byte},
                                         {'\0', LineTable::Byte},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB}},
-                        "DW_LNE_define_file (a, dir=1, "
-                        "mod_time=(0x0000000000000000), length=0)",
+                        "DW_LNE_define_file (<parsing error> 61 00 01)",
                         "unable to decode LEB128 at offset 0x00000035: "
                         "malformed uleb128, extends past end"),
-        std::make_tuple(7, 5, DW_LNE_define_file,
+        std::make_tuple(7, 6, DW_LNE_define_file,
                         ValueAndLengths{{'a', LineTable::Byte},
                                         {'\0', LineTable::Byte},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB},
                                         {1, LineTable::ULEB}},
-                        "DW_LNE_define_file (a, dir=1, "
-                        "mod_time=(0x0000000000000001), length=0)",
+                        "DW_LNE_define_file (<parsing error> 61 00 01 01)",
                         "unable to decode LEB128 at offset 0x00000036: "
                         "malformed uleb128, extends past end"),
         std::make_tuple(3, 2, DW_LNE_set_discriminator,
                         ValueAndLengths{{1, LineTable::ULEB}},
-                        "DW_LNE_set_discriminator (0)",
+                        "DW_LNE_set_discriminator",
                         "unable to decode LEB128 at offset 0x00000032: "
-                        "malformed uleb128, extends past end")), );
+                        "malformed uleb128, extends past end"),
+        std::make_tuple(
+            6, 5, /*Unknown=*/0x7f,
+            ValueAndLengths{{0x12345678, LineTable::Long}},
+            "Unrecognized extended op 0x7f length 5 (<parsing error> 78 56 34)",
+            "unexpected end of data at offset 0x35 while reading [0x32, "
+            "0x36)")), );
 
 TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) {
   if (!setupGenerator())


        


More information about the llvm-commits mailing list