Skip to content

Commit d381b6a

Browse files
committed
[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
1 parent 7802be4 commit d381b6a

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
255255
return DirDescriptors.takeError();
256256

257257
// Get the directory entries, according to the format described above.
258-
int DirEntryCount = DebugLineData.getU8(OffsetPtr);
259-
for (int I = 0; I != DirEntryCount; ++I) {
258+
uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
259+
for (uint64_t I = 0; I != DirEntryCount; ++I) {
260260
for (auto Descriptor : *DirDescriptors) {
261261
DWARFFormValue Value(Descriptor.Form);
262262
switch (Descriptor.Type) {
@@ -283,8 +283,8 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
283283
return FileDescriptors.takeError();
284284

285285
// Get the file entries, according to the format described above.
286-
int FileEntryCount = DebugLineData.getU8(OffsetPtr);
287-
for (int I = 0; I != FileEntryCount; ++I) {
286+
uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
287+
for (uint64_t I = 0; I != FileEntryCount; ++I) {
288288
DWARFDebugLine::FileNameEntry FileEntry;
289289
for (auto Descriptor : *FileDescriptors) {
290290
DWARFFormValue Value(Descriptor.Form);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
## An object with many files and directories in a single debug_line contribution
2+
## meant to test the handling of directory_count and file_name_count fields.
3+
4+
# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
5+
# RUN: llvm-dwarfdump -debug-line %t | FileCheck %s
6+
7+
# CHECK: include_directories[ 0] = "/d000"
8+
# CHECK: include_directories[299] = "/d299"
9+
# CHECK: file_names[ 0]:
10+
# CHECK-NEXT: name: "000.c"
11+
# CHECK-NEXT: dir_index: 0
12+
# CHECK: file_names[299]:
13+
# CHECK-NEXT: name: "299.c"
14+
# CHECK-NEXT: dir_index: 299
15+
16+
.section .debug_line,"",@progbits
17+
.long .Lunit_end0-.Lunit_start0 # Length of Unit
18+
.Lunit_start0:
19+
.short 5 # DWARF version number
20+
.byte 8 # Address Size
21+
.byte 0 # Segment Selector Size
22+
.long .Lunit_header_end0 - .Lunit_params0 # Length of Prologue (invalid)
23+
.Lunit_params0:
24+
.byte 1 # Minimum Instruction Length
25+
.byte 1 # Maximum Operations per Instruction
26+
.byte 1 # Default is_stmt
27+
.byte -5 # Line Base
28+
.byte 14 # Line Range
29+
.byte 13 # Opcode Base
30+
.byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # Standard Opcode Lengths
31+
32+
# Directory table format
33+
.byte 1 # One element per directory entry
34+
.byte 1 # DW_LNCT_path
35+
.byte 0x08 # DW_FORM_string
36+
37+
# Directory table entries
38+
.uleb128 300 # 300 directories
39+
.irpc a,012
40+
.irpc b,0123456789
41+
.irpc c,0123456789
42+
.byte '/', 'd', '0'+\a, '0'+\b, '0'+\c, 0
43+
.endr
44+
.endr
45+
.endr
46+
47+
# File table format
48+
.byte 2 # 2 elements per file entry
49+
.byte 1 # DW_LNCT_path
50+
.byte 0x08 # DW_FORM_string
51+
.byte 2 # DW_LNCT_directory_index
52+
.byte 0x05 # DW_FORM_data2
53+
54+
# File table entries
55+
.uleb128 300 # 300 files
56+
.irpc a,012
57+
.irpc b,0123456789
58+
.irpc c,0123456789
59+
.byte '0'+\a, '0'+\b, '0'+\c, '.', 'c', 0 # File name
60+
.word \a*100+\b*10+\c # Dir index
61+
.endr
62+
.endr
63+
.endr
64+
65+
.Lunit_header_end0:
66+
.byte 0, 1, 1 # DW_LNE_end_sequence
67+
.Lunit_end0:

0 commit comments

Comments
 (0)