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

Pavel Labath via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 20 08:05:21 PDT 2020


labath created this revision.
labath added reviewers: dblaikie, jhenderson.
Herald added subscribers: hiraditya, aprantl.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76498

Files:
  llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
  llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files.s


Index: llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files.s
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-dwarfdump/X86/debug_line_many_files.s
@@ -0,0 +1,65 @@
+# 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:
+
Index: llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -255,8 +255,8 @@
     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 @@
     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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76498.251638.patch
Type: text/x-patch
Size: 3449 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200320/d629543b/attachment.bin>


More information about the llvm-commits mailing list