[DebugInfo] Unify Cursor usage for all debug line opcodes
authorJames Henderson <james.henderson@sony.com>
Wed, 10 Jun 2020 13:00:36 +0000 (14:00 +0100)
committerJames Henderson <james.henderson@sony.com>
Wed, 17 Jun 2020 08:19:24 +0000 (09:19 +0100)
This is a natural extension of the previous changes to use the Cursor
class independently in the standard and extended opcode paths, and in
turn allows delaying error handling until the entire line has been
printed in verbose mode, removing interleaved output in some cases.

Reviewed by: MaskRay, JDevlieghere

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

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test

index 398d38e..f45ab85 100644 (file)
@@ -764,20 +764,21 @@ Error DWARFDebugLine::LineTable::parse(
     Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
   }
   while (*OffsetPtr < EndOffset) {
+    DataExtractor::Cursor Cursor(*OffsetPtr);
+
     if (Verbose)
       *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
 
     uint64_t OpcodeOffset = *OffsetPtr;
-    uint8_t Opcode = TableData.getU8(OffsetPtr);
+    uint8_t Opcode = TableData.getU8(Cursor);
     size_t RowCount = Rows.size();
 
-    if (Verbose)
+    if (Cursor && Verbose)
       *OS << format("%02.02" PRIx8 " ", Opcode);
 
     if (Opcode == 0) {
       // Extended Opcodes always start with a zero opcode followed by
       // a uleb128 length so you can skip ones you don't know about
-      DataExtractor::Cursor Cursor(*OffsetPtr);
       uint64_t Len = TableData.getULEB128(Cursor);
       uint64_t ExtOffset = Cursor.tell();
 
@@ -919,9 +920,7 @@ Error DWARFDebugLine::LineTable::parse(
       // by the table. Similarly, continue from the claimed end in the event of
       // a parsing error.
       uint64_t End = ExtOffset + Len;
-      if (!Cursor)
-        RecoverableErrorHandler(Cursor.takeError());
-      else if (Cursor.tell() != End)
+      if (Cursor && Cursor.tell() != End)
         RecoverableErrorHandler(createStringError(
             errc::illegal_byte_sequence,
             "unexpected line op length at offset 0x%8.8" PRIx64
@@ -929,7 +928,6 @@ Error DWARFDebugLine::LineTable::parse(
             ExtOffset, Len, Cursor.tell() - ExtOffset));
       *OffsetPtr = End;
     } else if (Opcode < Prologue.OpcodeBase) {
-      DataExtractor::Cursor Cursor(*OffsetPtr);
       if (Verbose)
         *OS << LNStandardString(Opcode);
       switch (Opcode) {
@@ -1103,15 +1101,6 @@ Error DWARFDebugLine::LineTable::parse(
       }
 
       *OffsetPtr = Cursor.tell();
-
-      // Most standard opcode failures are due to failures to read ULEBs. Bail
-      // out of parsing, since we don't know where to continue reading from as
-      // there is no stated length for such byte sequences.
-      if (!Cursor) {
-        if (Verbose)
-          *OS << "\n\n";
-        return Cursor.takeError();
-      }
     } else {
       // Special Opcodes.
       ParsingState::AddrAndLineDelta Delta =
@@ -1126,12 +1115,26 @@ Error DWARFDebugLine::LineTable::parse(
         State.Row.dump(*OS);
 
       State.appendRowToMatrix();
+      *OffsetPtr = Cursor.tell();
     }
 
     // When a row is added to the matrix, it is also dumped, which includes a
     // new line already, so don't add an extra one.
     if (Verbose && Rows.size() == RowCount)
       *OS << "\n";
+
+    // Most parse failures other than when parsing extended opcodes are due to
+    // failures to read ULEBs. Bail out of parsing, since we don't know where to
+    // continue reading from as there is no stated length for such byte
+    // sequences. Print the final trailing new line if needed before doing so.
+    if (!Cursor && Opcode != 0) {
+      if (Verbose)
+        *OS << "\n";
+      return Cursor.takeError();
+    }
+
+    if (!Cursor)
+      RecoverableErrorHandler(Cursor.takeError());
   }
 
   if (!State.Sequence.Empty)
index 053063e..d662d9e 100644 (file)
 ## Table with extended opcode that overruns table end.
 # NONFATAL:      debug_line[0x0000039d]
 # NONFATAL-NEXT: Line table prologue
-# VERBOSE:       DW_LNE_set_address (0x00000000feedfeed)
+# NONFATAL:      Address
+# NONFATAL-NEXT: ------------------
+# VERBOSE-NEXT:  DW_LNE_set_address (0x00000000feedfeed)
 # VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       DW_LNE_set_address (0x0000000000000000)
-# MORE-ERR:      warning: unexpected end of data at offset 0x3ed while reading [0x3e6, 0x3ee)
-# MORE-ERR:      warning: last sequence in debug line table at offset 0x0000039d is not terminated
+# NONFATAL-NEXT: 0x00000000feedfeed
+# VERBOSE-NEXT:  DW_LNE_set_address (0x0000000000000000)
+# 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
 
 # LAST:          debug_line[0x000003ed]
 # VERBOSE:       DW_LNE_set_address (0x00000000cafebabe)