[llvm] 6f55b5a - [DWARFDebugLine] Use truncating data extractors for prologue parsing

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 07:13:03 PDT 2020


Author: Pavel Labath
Date: 2020-06-10T16:12:53+02:00
New Revision: 6f55b5a101d95b1049643f87a6572b36d6b4b44c

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

LOG: [DWARFDebugLine] Use truncating data extractors for prologue parsing

Summary:
This makes the code easier to reason about, as it will behave the same
way regardless of whether there is any more data coming after the
presumed end of the prologue.

Reviewers: jhenderson, dblaikie, probinson, ikudrin

Subscribers: hiraditya, MaskRay, llvm-commits

Tags: #llvm

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

Added: 
    

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
    llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
    llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
    llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
    llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 1b4df10c48be..fe46d613aedd 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -129,7 +129,7 @@ class DWARFDebugLine {
 
     void clear();
     void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
-    Error parse(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+    Error parse(DWARFDataExtractor Data, uint64_t *OffsetPtr,
                 function_ref<void(Error)> RecoverableErrorHandler,
                 const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
   };

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index be4c5d305cce..05effc959c0e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -169,14 +169,14 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
 // Parse v2-v4 directory and file tables.
 static Error
 parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
-                     uint64_t *OffsetPtr, uint64_t EndPrologueOffset,
+                     uint64_t *OffsetPtr,
                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
                      std::vector<DWARFFormValue> &IncludeDirectories,
                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
   while (true) {
     Error Err = Error::success();
     StringRef S = DebugLineData.getCStrRef(OffsetPtr, &Err);
-    if (Err || *OffsetPtr > EndPrologueOffset) {
+    if (Err) {
       consumeError(std::move(Err));
       return createStringError(errc::invalid_argument,
                                "include directories table was not null "
@@ -195,7 +195,7 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
   while (true) {
     Error Err = Error::success();
     StringRef Name = DebugLineData.getCStrRef(OffsetPtr, &Err);
-    if (!Err && *OffsetPtr <= EndPrologueOffset && Name.empty())
+    if (!Err && Name.empty())
       break;
 
     DWARFDebugLine::FileNameEntry FileEntry;
@@ -205,7 +205,7 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
     FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr, &Err);
     FileEntry.Length = DebugLineData.getULEB128(OffsetPtr, &Err);
 
-    if (Err || *OffsetPtr > EndPrologueOffset) {
+    if (Err) {
       consumeError(std::move(Err));
       return createStringError(
           errc::invalid_argument,
@@ -345,7 +345,7 @@ uint64_t DWARFDebugLine::Prologue::getLength() const {
 }
 
 Error DWARFDebugLine::Prologue::parse(
-    const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+    DWARFDataExtractor DebugLineData, uint64_t *OffsetPtr,
     function_ref<void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx,
     const DWARFUnit *U) {
   const uint64_t PrologueOffset = *OffsetPtr;
@@ -360,6 +360,7 @@ Error DWARFDebugLine::Prologue::parse(
         "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
         PrologueOffset, toString(std::move(Err)).c_str());
 
+  DebugLineData = DWARFDataExtractor(DebugLineData, *OffsetPtr + TotalLength);
   FormParams.Version = DebugLineData.getU16(OffsetPtr);
   if (!versionIsSupported(getVersion()))
     // Treat this error as unrecoverable - we cannot be sure what any of
@@ -382,6 +383,7 @@ Error DWARFDebugLine::Prologue::parse(
   PrologueLength =
       DebugLineData.getRelocatedValue(sizeofPrologueLength(), OffsetPtr);
   const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
+  DebugLineData = DWARFDataExtractor(DebugLineData, EndPrologueOffset);
   MinInstLength = DebugLineData.getU8(OffsetPtr);
   if (getVersion() >= 4)
     MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
@@ -411,8 +413,8 @@ Error DWARFDebugLine::Prologue::parse(
       getVersion() >= 5
           ? parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
                                  ContentTypes, IncludeDirectories, FileNames)
-          : parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
-                                 ContentTypes, IncludeDirectories, FileNames);
+          : parseV2DirFileTables(DebugLineData, OffsetPtr, ContentTypes,
+                                 IncludeDirectories, FileNames);
   if (E) {
     RecoverableErrorHandler(joinErrors(
         createStringError(
@@ -425,13 +427,14 @@ Error DWARFDebugLine::Prologue::parse(
     return Error::success();
   }
 
+  assert(*OffsetPtr <= EndPrologueOffset);
   if (*OffsetPtr != EndPrologueOffset) {
     RecoverableErrorHandler(createStringError(
         errc::invalid_argument,
-        "parsing line table prologue at 0x%8.8" PRIx64
-        " should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64,
-        PrologueOffset, EndPrologueOffset, *OffsetPtr));
-    *OffsetPtr = EndPrologueOffset;
+        "unknown data in line table prologue at offset 0x%8.8" PRIx64
+        ": parsing ended (at offset 0x%8.8" PRIx64
+        ") before reaching the prologue at offset 0x%8.8" PRIx64,
+        PrologueOffset, *OffsetPtr, EndPrologueOffset));
   }
   return Error::success();
 }

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
index 9a40b5674575..2bd960308f87 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
@@ -81,9 +81,6 @@
 .asciz "file2"
 .byte   1, 2
 .Lprologue_short_prologue_end:
-.byte   6               # Read as part of the prologue,
-                        # then later again as DW_LNS_negate_stmt.
-# Header end
 .byte   0, 9, 2         # DW_LNE_set_address
 .quad   0x1122334455667788
 .byte   0, 1, 1         # DW_LNE_end_sequence
@@ -192,27 +189,9 @@
 .byte   -5              # Line Base
 .byte   14              # Line Range
 .byte   13              # Opcode Base
-.byte   0, 1, 1, 1, 1, 0, 0, 0, 1, 0 # Standard Opcode Lengths
+.byte   0, 1, 1, 1, 1, 0, 0, 0, 0, 1 # Standard Opcode Lengths
 .Linvalid_description_header_end0:
-# The bytes from here onwards will also be read as part of the main body.
-                        # --- Prologue interpretation --- | --- Main body interpretation ---
-.byte   0, 1            # More standard opcodes           | First part of DW_LNE_end_sequence
-# Directory table format
-.byte   1               # One element per directory entry | End of DW_LNE_end_sequence
-.byte   1               # DW_LNCT_path                    | DW_LNS_copy
-.byte   0x08            # DW_FORM_string                  | DW_LNS_const_add_pc
-# Directory table entries
-.byte   1               # 1 directory                     | DW_LNS_copy
-.asciz  "/tmp"          # Directory name                  | four special opcodes + start of DW_LNE_end_sequence
-# File table format
-.byte   1               # 1 element per file entry        | DW_LNE_end_sequence length
-.byte   1               # DW_LNCT_path                    | DW_LNE_end_sequence opcode
-.byte   0x08            # DW_FORM_string                  | DW_LNS_const_add_pc
-# File table entries
-.byte   1               # 1 file                          | DW_LNS_copy
-.asciz  "xyz"           # File name                       | three special opcodes + start of DW_LNE_set_address
-# Header end
-.byte   9, 2            # Remainder of DW_LNE_set_address
+.byte   0, 9, 2        # DW_LNE_set_address
 .quad   0xbabb1ebabb1e
 .byte   0, 1, 1         # DW_LNE_end_sequence
 .Linvalid_description_end0:
@@ -245,15 +224,6 @@
 .byte   0x08            # DW_FORM_string
 .byte   2               # DW_LNCT_directory_index
 .Linvalid_file_header_end0:
-# The bytes from here onwards will also be read as part of the main body.
-                        # --- Prologue interpretation --- | --- Main body interpretation ---
-.byte   0x0b            # DW_FORM_data1                   | DW_LNS_set_epilogue_begin
-# File table entries
-.byte   1               # 1 file                          | DW_LNS_copy
-.asciz  "xyz"           # File name                       | 3 special opcodes + start of DW_LNE_end_sequence
-.byte   1               # Dir index                       | DW_LNE_end_sequence length
-# Header end
-.byte   1               # DW_LNE_end_sequence opcode
 .byte   0, 9, 2         # DW_LNE_set_address
 .quad   0xab4acadab4a
 .byte   0, 1, 1         # DW_LNE_end_sequence
@@ -281,23 +251,12 @@
 # Directory table entries
 .byte   1               # 1 directory
 .Linvalid_dir_header_end0:
-# The bytes from here onwards will also be read as part of the main body.
-                        # --- Prologue interpretation --- | --- Main body interpretation ---
-.asciz  "/tmp"          # Directory name                  | 4 special opcodes + start of DW_LNE_end_sequence
-# File table format
-.byte   1               # 1 element per file entry        | DW_LNE_end_sequence length
-.byte   1               # DW_LNCT_path                    | DW_LNE_end_sequence length opcode
-.byte   0x08            # DW_FORM_string                  | DW_LNS_const_add_pc
-# File table entries
-.byte   1               # 1 file                          | DW_LNS_copy
-.asciz  "xyz"           # File name                       | start of DW_LNE_set_address
-# Header end
-.byte   9, 2            # DW_LNE_set_address length + opcode
+.byte   0, 9, 2         # DW_LNE_set_address
 .quad   0x4444333322221111
 .byte   0, 1, 1         # DW_LNE_end_sequence
 .Linvalid_dir_end0:
 
-# Invalid MD5 hash, where there is data still to be read afterwards.
+# Header truncated while reading the MD5 data.
 .long   .Linvalid_md5_end0-.Linvalid_md5_start0   # Length of Unit
 .Linvalid_md5_start0:
 .short  5               # DWARF version number
@@ -324,7 +283,7 @@
 .byte   1               # DW_LNCT_path
 .byte   0x08            # DW_FORM_string
 .byte   5               # DW_LNCT_MD5
-.byte   0x0b            # DW_FORM_data1
+.byte   0x1e            # DW_FORM_data16
 .byte   2               # DW_LNCT_directory_index
 .byte   0x0b            # DW_FORM_data1
 # File table entries
@@ -339,8 +298,7 @@
 .byte   0, 1, 1         # DW_LNE_end_sequence
 .Linvalid_md5_end0:
 
-# Invalid MD5 hash, when data beyond the prologue length has
-# been read before the MD5 problem is identified.
+# Header truncated while reading the MD5 form.
 .long   .Linvalid_md5_end1-.Linvalid_md5_start1   # Length of Unit
 .Linvalid_md5_start1:
 .short  5               # DWARF version number
@@ -368,15 +326,7 @@
 .byte   0x08            # DW_FORM_string
 .byte   5               # DW_LNCT_MD5
 .Linvalid_md5_header_end1:
-# The bytes from here onwards will also be read as part of the main body.
-                        # --- Prologue interpretation --- | --- Main body interpretation ---
-.byte   0x0b            # DW_FORM_data1                   | DW_LNS_set_epilogue_begin
-# File table entries
-.byte   1               # 1 file                          | DW_LNS_copy
-.asciz  "xyz"           # File name                       | 3 special opcodes + DW_LNE_set_address start
-.byte   9               # MD5 hash value                  | DW_LNE_set_address length
-# Header end
-.byte   2               # DW_LNE_set_address opcode
+.byte   0, 9, 2         # DW_LNE_set_address
 .quad   0x4321432143214321
 .byte   0, 1, 1         # DW_LNE_end_sequence
 .Linvalid_md5_end1:

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 31f2fd31efb3..cb0e0ac37968 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
@@ -33,7 +33,7 @@
 # RUN:   | FileCheck %s --check-prefixes=HEADER,FIRST,NOLATER,SOME-ERR --implicit-check-not='warning:'
 
 ## Don't stop looking for the later unit if non-fatal issues are found.
-# RUN: llvm-dwarfdump -debug-line=0x419 %t-malformed.o 2>&1 \
+# RUN: llvm-dwarfdump -debug-line=0x3ed %t-malformed.o 2>&1 \
 # RUN:   | FileCheck %s --check-prefixes=HEADER,LAST,SOME-ERR --implicit-check-not='debug_line[{{.*}}]' \
 # RUN:       --implicit-check-not='warning:'
 
@@ -92,7 +92,7 @@
 
 ## Prologue with length shorter than parsed.
 # NONFATAL:      debug_line[0x00000081]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000b9
 # SOME-ERR-NEXT: warning: file names table was not null terminated before the end of the prologue
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      file_names[  1]:
@@ -100,13 +100,12 @@
 # NONFATAL-NEXT:       dir_index: 1
 # NONFATAL-NEXT:        mod_time: 0x00000002
 # NONFATAL-NEXT:          length: 0x00000003
-# VERBOSE:       DW_LNS_negate_stmt
-# VERBOSE-NEXT:  DW_LNE_set_address (0x1122334455667788)
+# VERBOSE:       DW_LNE_set_address (0x1122334455667788)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## Prologue with length longer than parsed.
-# NONFATAL:      debug_line[0x000000c8]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000000c8 should have ended at 0x00000103 but it ended at 0x00000102
+# NONFATAL:      debug_line[0x000000c7]
+# SOME-ERR-NEXT: warning: unknown data in line table prologue at offset 0x000000c7: parsing ended (at offset 0x00000101) before reaching the prologue at offset 0x00000102
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      file_names[  2]:
 # NONFATAL-NEXT:            name: "file2"
@@ -118,117 +117,79 @@
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## Extended opcode with incorrect length versus expected.
-# NONFATAL:      debug_line[0x00000111]
+# NONFATAL:      debug_line[0x00000110]
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      prologue_length: 0x00000030
 # VERBOSE:       DW_LNE_set_address (0x00000000abbadaba)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
-# MORE-ERR:      warning: unexpected line op length at offset 0x00000158 expected 0x02 found 0x01
+# MORE-ERR:      warning: unexpected line op length at offset 0x00000157 expected 0x02 found 0x01
 # VERBOSE:       DW_LNE_set_discriminator (10)
-# MORE-ERR:      warning: unexpected line op length at offset 0x0000015c expected 0x01 found 0x02
+# MORE-ERR:      warning: unexpected line op length at offset 0x0000015b expected 0x01 found 0x02
 # VERBOSE:       DW_LNS_set_prologue_end
 # VERBOSE-NEXT:  DW_LNE_set_address (0x00000000babb1e45)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## No end of sequence.
-# NONFATAL:      debug_line[0x0000016c]
+# NONFATAL:      debug_line[0x0000016b]
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      prologue_length: 0x00000030
 # VERBOSE:       DW_LNE_set_address (0x00000000deadfade)
 # VERBOSE-NEXT:  DW_LNS_copy
-# MORE-ERR:      warning: last sequence in debug line table at offset 0x0000016c is not terminated
+# MORE-ERR:      warning: last sequence in debug line table at offset 0x0000016b is not terminated
 
 ## Very short prologue length for V5 (ends during parameters).
-# NONFATAL:      debug_line[0x000001b2]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001b2 should have ended at 0x000001ce but it ended at 0x000001e1
+# NONFATAL:      debug_line[0x000001b1]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001b1 found an invalid directory or file table description at 0x000001cd
+# SOME-ERR-NEXT: warning: failed to parse entry content descriptors: unexpected end of data at offset 0x1cd while reading [0x1cd, 0x1ce)
 # NONFATAL-NEXT: Line table prologue
-# NONFATAL:      standard_opcode_lengths[DW_LNS_set_isa] = 1
-# NONFATAL-NEXT: include_directories[  0] = "/tmp"
-# NONFATAL-NEXT: file_names[  0]:
-# NONFATAL-NEXT:            name: "xyz"
-# VERBOSE:       DW_LNE_end_sequence
-# VERBOSE:       DW_LNS_copy
-# VERBOSE:       DW_LNS_const_add_pc (0x0000000000000011)
-# VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       address += 2, line += 1
-# VERBOSE:       address += 7, line += 0
-# VERBOSE:       address += 6, line += 7
-# VERBOSE:       address += 7, line += -4
-# VERBOSE:       DW_LNE_end_sequence
-# VERBOSE:       DW_LNS_const_add_pc (0x0000000000000011)
-# VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       address += 7, line += 4
-# VERBOSE:       address += 7, line += 5
-# VERBOSE:       address += 7, line += 6
+# NONFATAL:      standard_opcode_lengths[DW_LNS_set_prologue_end] = 1
+# NONFATAL-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
+# NONFATAL-NOT:  include_directories
 # VERBOSE:       DW_LNE_set_address (0x0000babb1ebabb1e)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## V5 prologue ends during file table.
-# NONFATAL:      debug_line[0x000001ee]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001ee should have ended at 0x00000219 but it ended at 0x00000220
+# NONFATAL:      debug_line[0x000001db]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001db found an invalid directory or file table description at 0x00000206
+# SOME-ERR-NEXT: warning: failed to parse entry content descriptors: unable to decode LEB128 at offset 0x00000206: malformed uleb128, extends past end
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  0] = "/tmp"
-# NONFATAL-NEXT: file_names[  0]:
-# NONFATAL-NEXT:            name: "xyz"
-# NONFATAL-NEXT:       dir_index: 1
-# VERBOSE:       DW_LNS_set_epilogue_begin
-# VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       address += 7, line += 4
-# VERBOSE:       address += 7, line += 5
-# VERBOSE:       address += 7, line += 6
-# VERBOSE:       DW_LNE_end_sequence
+# NONFATAL-NOT:  file_names
 # VERBOSE:       DW_LNE_set_address (0x00000ab4acadab4a)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## V5 prologue ends during directory table.
-# NONFATAL:      debug_line[0x0000022f]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x0000022f should have ended at 0x00000251 but it ended at 0x0000025e
+# NONFATAL:      debug_line[0x00000214]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000214 found an invalid directory or file table description at 0x00000236
+# SOME-ERR-NEXT: warning: failed to parse directory entry because extracting the form value failed.
 # NONFATAL-NEXT: Line table prologue
-# NONFATAL:      include_directories[  0] = "/tmp"
-# NONFATAL-NEXT: file_names[  0]:
-# NONFATAL-NEXT:            name: "xyz"
-# VERBOSE:       address += 2, line += 1
-# VERBOSE:       address += 7, line += 0
-# VERBOSE:       address += 6, line += 7
-# VERBOSE:       address += 7, line += -4
-# VERBOSE:       DW_LNE_end_sequence
-# VERBOSE:       DW_LNS_const_add_pc (0x0000000000000011)
-# VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       address += 7, line += 4
-# VERBOSE:       address += 7, line += 5
-# VERBOSE:       address += 7, line += 6
+# NONFATAL-NOT:  include_directories
 # VERBOSE:       DW_LNE_set_address (0x4444333322221111)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## V5 invalid MD5 hash form when there is still data to be read.
-# NONFATAL:      debug_line[0x0000026b]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x0000026b found an invalid directory or file table description at 0x0000029f
-# SOME-ERR-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
+# NONFATAL:      debug_line[0x00000244]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000244 found an invalid directory or file table description at 0x00000277
+# SOME-ERR-NEXT: warning: failed to parse file entry because extracting the form value failed.
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  0] = "/tmp"
 # NONFATAL-NOT:  file_names
 # VERBOSE:       DW_LNE_set_address (0x1234123412341234)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
-## V5 invalid MD5 hash form when data beyond the prologue length has
-## been read before the MD5 problem is identified.
-# NONFATAL:      debug_line[0x000002ae]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000002ae found an invalid directory or file table description at 0x000002e0
-# SOME-ERR-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
+## V5 prologue ends while reading an MD5 hash
+# NONFATAL:      debug_line[0x00000287]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000287 found an invalid directory or file table description at 0x000002b2
+# SOME-ERR-NEXT: warning: failed to parse entry content descriptors: unable to decode LEB128 at offset 0x000002b2: malformed uleb128, extends past end
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  0] = "/tmp"
 # NONFATAL-NOT:  file_names
-# VERBOSE:       DW_LNS_set_epilogue_begin
-# VERBOSE-NEXT:  DW_LNS_copy
-# VERBOSE:       address += 7, line += 4
-# VERBOSE:       address += 7, line += 5
-# VERBOSE:       address += 7, line += 6
 # VERBOSE:       DW_LNE_set_address (0x4321432143214321)
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## V5 invalid directory content description has unsupported form.
-# NONFATAL:      debug_line[0x000002ec]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000002ec found an invalid directory or file table description at 0x00000315
+# NONFATAL:      debug_line[0x000002c0]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000002c0 found an invalid directory or file table description at 0x000002e9
 # SOME-ERR-NEXT: warning: failed to parse directory entry because skipping the form value failed.
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  0] = "/foo"
@@ -238,8 +199,8 @@
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## Opcode base field of value zero.
-# NONFATAL:      debug_line[0x00000332]
-# SOME-ERR-NEXT: warning: parsing line table prologue at offset 0x00000332 found opcode base of 0. Assuming no standard opcodes
+# NONFATAL:      debug_line[0x00000306]
+# SOME-ERR-NEXT: warning: parsing line table prologue at offset 0x00000306 found opcode base of 0. Assuming no standard opcodes
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  1] = "dir1"
 # NONFATAL-NEXT: file_names[  1]:
@@ -252,8 +213,8 @@
 # VERBOSE:       DW_LNE_end_sequence
 
 ## V4 table with unterminated include directory table.
-# NONFATAL:      debug_line[0x00000361]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000361 found an invalid directory or file table description at 0x00000383
+# NONFATAL:      debug_line[0x00000335]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000335 found an invalid directory or file table description at 0x00000356
 # SOME-ERR-NEXT: warning: include directories table was not null terminated before the end of the prologue
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      include_directories[  1] = "dir1"
@@ -262,8 +223,8 @@
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## V4 table with unterminated file name table.
-# NONFATAL:      debug_line[0x00000390]
-# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bf
+# NONFATAL:      debug_line[0x00000364]
+# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000364 found an invalid directory or file table description at 0x0000038f
 # SOME-ERR-NEXT: warning: file names table was not null terminated before the end of the prologue
 # NONFATAL-NEXT: Line table prologue
 # NONFATAL:      file_names[  1]:
@@ -276,14 +237,14 @@
 # VERBOSE-NEXT:  DW_LNE_end_sequence
 
 ## Table with extended opcode that overruns table end.
-# NONFATAL:      debug_line[0x000003c9]
+# NONFATAL:      debug_line[0x0000039d]
 # NONFATAL-NEXT: Line table prologue
 # VERBOSE:       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 0x419 while reading [0x412, 0x41a)
-# MORE-ERR:      warning: last sequence in debug line table at offset 0x000003c9 is not terminated
+# 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
 
-# LAST:          debug_line[0x00000419]
+# LAST:          debug_line[0x000003ed]
 # VERBOSE:       DW_LNE_set_address (0x00000000cafebabe)
 # VERBOSE-NEXT:  DW_LNE_end_sequence

diff  --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
index a7a8f934e87c..d00d4c8938e2 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
@@ -423,12 +423,13 @@ TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) {
       Prologue.TotalLength + 1 + Prologue.sizeofTotalLength();
   EXPECT_THAT_ERROR(
       std::move(Recoverable),
-      FailedWithMessage(("parsing line table prologue at 0x00000000 should "
-                         "have ended at 0x000000" +
-                         Twine::utohexstr(ExpectedEnd) +
-                         " but it ended at 0x000000" +
-                         Twine::utohexstr(ExpectedEnd - 1))
-                            .str()));
+      FailedWithMessage(
+          ("unknown data in line table prologue at offset 0x00000000: "
+           "parsing ended (at offset 0x000000" +
+           Twine::utohexstr(ExpectedEnd - 1) +
+           ") before reaching the prologue at offset 0x000000" +
+           Twine::utohexstr(ExpectedEnd))
+              .str()));
 }
 
 TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {
@@ -450,37 +451,28 @@ TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {
   ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
   DWARFDebugLine::LineTable Result(**ExpectedLineTable);
 
-  if (Version != 5) {
-    // Parsing will stop before reading a complete file entry.
-    ASSERT_EQ(Result.Prologue.IncludeDirectories.size(), 1u);
-    EXPECT_EQ(toStringRef(Result.Prologue.IncludeDirectories[0]), "a dir");
-    EXPECT_EQ(Result.Prologue.FileNames.size(), 0u);
-  } else {
-    // Parsing will continue past the presumed end of prologue.
-    ASSERT_EQ(Result.Prologue.FileNames.size(), 1u);
-    ASSERT_EQ(Result.Prologue.FileNames[0].Name.getForm(), DW_FORM_string);
-    ASSERT_EQ(Result.Prologue.FileNames[0].DirIdx, 0u);
-    EXPECT_EQ(toStringRef(Result.Prologue.FileNames[0].Name), "a file");
-  }
+  // Parsing will stop before reading a complete file entry.
+  ASSERT_EQ(Result.Prologue.IncludeDirectories.size(), 1u);
+  EXPECT_EQ(toStringRef(Result.Prologue.IncludeDirectories[0]), "a dir");
+  EXPECT_EQ(Result.Prologue.FileNames.size(), 0u);
 
-  uint64_t ExpectedEnd =
-      Prologue.TotalLength - 2 + Prologue.sizeofTotalLength();
+  // The exact place where the parsing will stop depends on the structure of the
+  // prologue and the last complete field we are able to read. Before V5 we stop
+  // before reading the file length. In V5, we stop before the filename.
+  uint64_t ExpectedEnd = Prologue.TotalLength + Prologue.sizeofTotalLength() -
+                         (Version < 5 ? 2 : 8);
   std::vector<std::string> Errs;
-  if (Version != 5) {
-    Errs.emplace_back(
-        (Twine("parsing line table prologue at 0x00000000 found an invalid "
-               "directory or file table description at 0x000000") +
-         Twine::utohexstr(ExpectedEnd + 1))
-            .str());
+  Errs.emplace_back(
+      (Twine("parsing line table prologue at 0x00000000 found an invalid "
+             "directory or file table description at 0x000000") +
+       Twine::utohexstr(ExpectedEnd))
+          .str());
+  if (Version < 5) {
     Errs.emplace_back("file names table was not null terminated before the end "
                       "of the prologue");
   } else {
     Errs.emplace_back(
-        (Twine("parsing line table prologue at 0x00000000 should have ended at "
-               "0x000000") +
-         Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" +
-         Twine::utohexstr(ExpectedEnd + 2))
-            .str());
+        "failed to parse file entry because extracting the form value failed.");
   }
   EXPECT_THAT_ERROR(std::move(Recoverable),
                     FailedWithMessageArray(testing::ElementsAreArray(Errs)));
@@ -1514,6 +1506,7 @@ TEST_F(DebugLineBasicFixture, PrintPathsProperly) {
   P.FileNames.back().Name =
       DWARFFormValue::createFromPValue(DW_FORM_string, "b file");
   P.FileNames.back().DirIdx = 1;
+  P.TotalLength += 14;
   P.PrologueLength += 14;
   LT.setPrologue(P);
   generate();


        


More information about the llvm-commits mailing list