[llvm] d381b6a - [DWARF] Fix v5 debug_line parsing of prologues with many files

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 24 07:12:02 PDT 2020


Author: Pavel Labath
Date: 2020-03-24T15:11:54+01:00
New Revision: d381b6a8d3e87d65f4ae9ca4d4333203e01825f5

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

LOG: [DWARF] Fix v5 debug_line parsing of prologues with many files

Summary:
The directory_count and file_name_count fields are (section 6.2.4 of
DWARF5 spec) supposed to be uleb128s, not bytes. This bug meant that it
was not possible to correctly parse headers with more than 128 files or
directories.

I've found this bug by code inspection, though the limit is so small
someone would have run into it for real sooner or later. I've verified
that the producer side handles many files correctly, and that we are
able to parse such files after this fix.

Reviewers: dblaikie, jhenderson

Subscribers: aprantl, hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files_v5.s

Modified: 
    llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 3c8fd0da6296..366f0479c93a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -255,8 +255,8 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
     return DirDescriptors.takeError();
 
   // Get the directory entries, according to the format described above.
-  int DirEntryCount = DebugLineData.getU8(OffsetPtr);
-  for (int I = 0; I != DirEntryCount; ++I) {
+  uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
+  for (uint64_t I = 0; I != DirEntryCount; ++I) {
     for (auto Descriptor : *DirDescriptors) {
       DWARFFormValue Value(Descriptor.Form);
       switch (Descriptor.Type) {
@@ -283,8 +283,8 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
     return FileDescriptors.takeError();
 
   // Get the file entries, according to the format described above.
-  int FileEntryCount = DebugLineData.getU8(OffsetPtr);
-  for (int I = 0; I != FileEntryCount; ++I) {
+  uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
+  for (uint64_t I = 0; I != FileEntryCount; ++I) {
     DWARFDebugLine::FileNameEntry FileEntry;
     for (auto Descriptor : *FileDescriptors) {
       DWARFFormValue Value(Descriptor.Form);

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files_v5.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files_v5.s
new file mode 100644
index 000000000000..280ec6df1f34
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files_v5.s
@@ -0,0 +1,67 @@
+## An object with many files and directories in a single debug_line contribution
+## meant to test the handling of directory_count and file_name_count fields.
+
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
+# RUN: llvm-dwarfdump -debug-line %t | FileCheck %s
+
+# CHECK:      include_directories[  0] = "/d000"
+# CHECK:      include_directories[299] = "/d299"
+# CHECK:      file_names[  0]:
+# CHECK-NEXT:            name: "000.c"
+# CHECK-NEXT:       dir_index: 0
+# CHECK:      file_names[299]:
+# CHECK-NEXT:            name: "299.c"
+# CHECK-NEXT:       dir_index: 299
+
+.section .debug_line,"", at progbits
+.long   .Lunit_end0-.Lunit_start0   # Length of Unit
+.Lunit_start0:
+.short  5               # DWARF version number
+.byte   8               # Address Size
+.byte   0               # Segment Selector Size
+.long   .Lunit_header_end0 - .Lunit_params0 # Length of Prologue (invalid)
+.Lunit_params0:
+.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   13              # Opcode Base
+.byte   0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # Standard Opcode Lengths
+
+# Directory table format
+.byte   1               # One element per directory entry
+.byte   1               # DW_LNCT_path
+.byte   0x08            # DW_FORM_string
+
+# Directory table entries
+.uleb128 300            # 300 directories
+.irpc a,012
+.irpc b,0123456789
+.irpc c,0123456789
+.byte '/', 'd', '0'+\a, '0'+\b, '0'+\c, 0
+.endr
+.endr
+.endr
+
+# File table format
+.byte   2               # 2 elements per file entry
+.byte   1               # DW_LNCT_path
+.byte   0x08            # DW_FORM_string
+.byte   2               # DW_LNCT_directory_index
+.byte   0x05            # DW_FORM_data2
+
+# File table entries
+.uleb128 300            # 300 files
+.irpc a,012
+.irpc b,0123456789
+.irpc c,0123456789
+.byte '0'+\a, '0'+\b, '0'+\c, '.', 'c', 0 # File name
+.word \a*100+\b*10+\c   # Dir index
+.endr
+.endr
+.endr
+
+.Lunit_header_end0:
+.byte   0, 1, 1         # DW_LNE_end_sequence
+.Lunit_end0:


        


More information about the llvm-commits mailing list