Skip to content

Commit 5c05165

Browse files
committed
Revert "[DebugInfo] Make most debug line prologue errors non-fatal to parsing"
This reverts commit b94191f. The change broke both an LLD test and the LLDB build.
1 parent b94191f commit 5c05165

File tree

6 files changed

+114
-177
lines changed

6 files changed

+114
-177
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ class DWARFDebugLine {
138138
void clear();
139139
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
140140
Error parse(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
141-
function_ref<void(Error)> RecoverableErrorCallback,
142141
const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
143142
};
144143

@@ -342,12 +341,9 @@ class DWARFDebugLine {
342341
/// Skip the current line table and go to the following line table (if
343342
/// present) immediately.
344343
///
345-
/// \param RecoverableErrorCallback - report any recoverable prologue
346-
/// parsing issues via this callback.
347-
/// \param UnrecoverableErrorCallback - report any unrecoverable prologue
348-
/// parsing issues via this callback.
349-
void skip(function_ref<void(Error)> RecoverableErrorCallback,
350-
function_ref<void(Error)> UnrecoverableErrorCallback);
344+
/// \param ErrorCallback - report any prologue parsing issues via this
345+
/// callback.
346+
void skip(function_ref<void(Error)> ErrorCallback);
351347

352348
/// Indicates if the parser has parsed as much as possible.
353349
///

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ void DWARFContext::dump(
467467
Optional<uint64_t> DumpOffset) {
468468
while (!Parser.done()) {
469469
if (DumpOffset && Parser.getOffset() != *DumpOffset) {
470-
Parser.skip(dumpWarning, dumpWarning);
470+
Parser.skip(dumpWarning);
471471
continue;
472472
}
473473
OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,10 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
299299
return Error::success();
300300
}
301301

302-
Error DWARFDebugLine::Prologue::parse(
303-
const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
304-
function_ref<void(Error)> RecoverableErrorCallback, const DWARFContext &Ctx,
305-
const DWARFUnit *U) {
302+
Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
303+
uint64_t *OffsetPtr,
304+
const DWARFContext &Ctx,
305+
const DWARFUnit *U) {
306306
const uint64_t PrologueOffset = *OffsetPtr;
307307

308308
clear();
@@ -311,18 +311,13 @@ Error DWARFDebugLine::Prologue::parse(
311311
FormParams.Format = dwarf::DWARF64;
312312
TotalLength = DebugLineData.getU64(OffsetPtr);
313313
} else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) {
314-
// Treat this error as unrecoverable - we have no way of knowing where the
315-
// table ends.
316314
return createStringError(errc::invalid_argument,
317315
"parsing line table prologue at offset 0x%8.8" PRIx64
318316
" unsupported reserved unit length found of value 0x%8.8" PRIx64,
319317
PrologueOffset, TotalLength);
320318
}
321319
FormParams.Version = DebugLineData.getU16(OffsetPtr);
322320
if (getVersion() < 2)
323-
// Treat this error as unrecoverable - we cannot be sure what any of
324-
// the data represents including the length field, so cannot skip it or make
325-
// any reasonable assumptions.
326321
return createStringError(errc::not_supported,
327322
"parsing line table prologue at offset 0x%8.8" PRIx64
328323
" found unsupported version 0x%2.2" PRIx16,
@@ -357,32 +352,25 @@ Error DWARFDebugLine::Prologue::parse(
357352
if (Error E =
358353
parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
359354
ContentTypes, IncludeDirectories, FileNames)) {
360-
RecoverableErrorCallback(joinErrors(
355+
return joinErrors(
361356
createStringError(
362357
errc::invalid_argument,
363358
"parsing line table prologue at 0x%8.8" PRIx64
364359
" found an invalid directory or file table description at"
365360
" 0x%8.8" PRIx64,
366361
PrologueOffset, *OffsetPtr),
367-
std::move(E)));
368-
// Skip to the end of the prologue, since the chances are that the parser
369-
// did not read the whole table. This prevents the length check below from
370-
// executing.
371-
if (*OffsetPtr < EndPrologueOffset)
372-
*OffsetPtr = EndPrologueOffset;
362+
std::move(E));
373363
}
374364
} else
375365
parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
376366
ContentTypes, IncludeDirectories, FileNames);
377367

378-
if (*OffsetPtr != EndPrologueOffset) {
379-
RecoverableErrorCallback(createStringError(
380-
errc::invalid_argument,
381-
"parsing line table prologue at 0x%8.8" PRIx64
382-
" should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64,
383-
PrologueOffset, EndPrologueOffset, *OffsetPtr));
384-
*OffsetPtr = EndPrologueOffset;
385-
}
368+
if (*OffsetPtr != EndPrologueOffset)
369+
return createStringError(errc::invalid_argument,
370+
"parsing line table prologue at 0x%8.8" PRIx64
371+
" should have ended at 0x%8.8" PRIx64
372+
" but it ended at 0x%8.8" PRIx64,
373+
PrologueOffset, EndPrologueOffset, *OffsetPtr);
386374
return Error::success();
387375
}
388376

@@ -528,8 +516,7 @@ Error DWARFDebugLine::LineTable::parse(
528516

529517
clear();
530518

531-
Error PrologueErr = Prologue.parse(DebugLineData, OffsetPtr,
532-
RecoverableErrorCallback, Ctx, U);
519+
Error PrologueErr = Prologue.parse(DebugLineData, OffsetPtr, Ctx, U);
533520

534521
if (OS) {
535522
// The presence of OS signals verbose dumping.
@@ -1171,16 +1158,14 @@ DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
11711158
}
11721159

11731160
void DWARFDebugLine::SectionParser::skip(
1174-
function_ref<void(Error)> RecoverableErrorCallback,
1175-
function_ref<void(Error)> UnrecoverableErrorCallback) {
1161+
function_ref<void(Error)> ErrorCallback) {
11761162
assert(DebugLineData.isValidOffset(Offset) &&
11771163
"parsing should have terminated");
11781164
DWARFUnit *U = prepareToParse(Offset);
11791165
uint64_t OldOffset = Offset;
11801166
LineTable LT;
1181-
if (Error Err = LT.Prologue.parse(DebugLineData, &Offset,
1182-
RecoverableErrorCallback, Context, U))
1183-
UnrecoverableErrorCallback(std::move(Err));
1167+
if (Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U))
1168+
ErrorCallback(std::move(Err));
11841169
moveToNextTable(OldOffset, LT.Prologue);
11851170
}
11861171

llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s

Lines changed: 51 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
.long .Lunit_short_prologue_end - .Lunit_short_prologue_start # unit length
6565
.Lunit_short_prologue_start:
6666
.short 4 # version
67-
.long .Lprologue_short_prologue_end-.Lprologue_short_prologue_start # Length of Prologue
67+
.long .Lprologue_short_prologue_end-.Lprologue_short_prologue_start - 2 # Length of Prologue
6868
.Lprologue_short_prologue_start:
6969
.byte 1 # Minimum Instruction Length
7070
.byte 1 # Maximum Operations per Instruction
@@ -79,13 +79,9 @@
7979
.asciz "file1" # File table
8080
.byte 0, 0, 0
8181
.asciz "file2"
82-
.byte 1, 2
82+
.byte 1, 2, 3
83+
.byte 0
8384
.Lprologue_short_prologue_end:
84-
.byte 6 # Read as part of the prologue,
85-
# then later again as DW_LNS_negate_stmt.
86-
# FIXME: There should be an additional 0 byte here, but the file name parsing
87-
# code does not recognise a missing null terminator.
88-
# Header end
8985
.byte 0, 9, 2 # DW_LNE_set_address
9086
.quad 0x1122334455667788
9187
.byte 0, 1, 1 # DW_LNE_end_sequence
@@ -95,7 +91,7 @@
9591
.long .Lunit_long_prologue_end - .Lunit_long_prologue_start # unit length
9692
.Lunit_long_prologue_start:
9793
.short 4 # version
98-
.long .Lprologue_long_prologue_end-.Lprologue_long_prologue_start # Length of Prologue
94+
.long .Lprologue_long_prologue_end-.Lprologue_long_prologue_start + 1 # Length of Prologue
9995
.Lprologue_long_prologue_start:
10096
.byte 1 # Minimum Instruction Length
10197
.byte 1 # Maximum Operations per Instruction
@@ -112,8 +108,6 @@
112108
.asciz "file2"
113109
.byte 1, 2, 3
114110
.byte 0
115-
# Skipped byte (treated as part of prologue).
116-
.byte 6
117111
.Lprologue_long_prologue_end:
118112
.byte 0, 9, 2 # DW_LNE_set_address
119113
.quad 0x1111222233334444
@@ -186,35 +180,34 @@
186180
.short 5 # DWARF version number
187181
.byte 8 # Address Size
188182
.byte 0 # Segment Selector Size
189-
.long .Linvalid_description_header_end0 - .Linvalid_description_params0 # Length of Prologue (invalid)
183+
.long 15 # Length of Prologue (invalid)
190184
.Linvalid_description_params0:
191185
.byte 1 # Minimum Instruction Length
192186
.byte 1 # Maximum Operations per Instruction
193187
.byte 1 # Default is_stmt
194188
.byte -5 # Line Base
195189
.byte 14 # Line Range
196190
.byte 13 # Opcode Base
197-
.byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0 # Standard Opcode Lengths
198-
.Linvalid_description_header_end0:
199-
# The bytes from here onwards will also be read as part of the main body.
200-
# --- Prologue interpretation --- | --- Main body interpretation ---
201-
.byte 0, 1 # More standard opcodes | First part of DW_LNE_end_sequence
191+
.byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # Standard Opcode Lengths
202192
# Directory table format
203-
.byte 1 # One element per directory entry | End of DW_LNE_end_sequence
204-
.byte 1 # DW_LNCT_path | DW_LNS_copy
205-
.byte 0x08 # DW_FORM_string | DW_LNS_const_add_pc
193+
.byte 1 # One element per directory entry
194+
.byte 1 # DW_LNCT_path
195+
.byte 0x08 # DW_FORM_string
206196
# Directory table entries
207-
.byte 1 # 1 directory | DW_LNS_copy
208-
.asciz "/tmp" # Directory name | four special opcodes + start of DW_LNE_end_sequence
197+
.byte 1 # 1 directory
198+
.asciz "/tmp"
209199
# File table format
210-
.byte 1 # 1 element per file entry | DW_LNE_end_sequence length
211-
.byte 1 # DW_LNCT_path | DW_LNE_end_sequence opcode
212-
.byte 0x08 # DW_FORM_string | DW_LNS_const_add_pc
200+
.byte 2 # 2 elements per file entry
201+
.byte 1 # DW_LNCT_path
202+
.byte 0x08 # DW_FORM_string
203+
.byte 2 # DW_LNCT_directory_index
204+
.byte 0x0b # DW_FORM_data1
213205
# File table entries
214-
.byte 1 # 1 file | DW_LNS_copy
215-
.asciz "xyz" # File name | three special opcodes + start of DW_LNE_set_address
216-
# Header end
217-
.byte 9, 2 # Remainder of DW_LNE_set_address
206+
.byte 1 # 1 file
207+
.asciz "a.c"
208+
.byte 1
209+
.Linvalid_description_header_end0:
210+
.byte 0, 9, 2 # DW_LNE_set_address
218211
.quad 0xbabb1ebabb1e
219212
.byte 0, 1, 1 # DW_LNE_end_sequence
220213
.Linvalid_description_end0:
@@ -225,7 +218,7 @@
225218
.short 5 # DWARF version number
226219
.byte 8 # Address Size
227220
.byte 0 # Segment Selector Size
228-
.long .Linvalid_file_header_end0 - .Linvalid_file_params0 # Length of Prologue (invalid)
221+
.long .Linvalid_file_header_end0-.Linvalid_file_params0-7 # Length of Prologue (invalid)
229222
.Linvalid_file_params0:
230223
.byte 1 # Minimum Instruction Length
231224
.byte 1 # Maximum Operations per Instruction
@@ -246,16 +239,12 @@
246239
.byte 1 # DW_LNCT_path
247240
.byte 0x08 # DW_FORM_string
248241
.byte 2 # DW_LNCT_directory_index
249-
.Linvalid_file_header_end0:
250-
# The bytes from here onwards will also be read as part of the main body.
251-
# --- Prologue interpretation --- | --- Main body interpretation ---
252-
.byte 0x0b # DW_FORM_data1 | DW_LNS_set_epilogue_begin
242+
.byte 0x0b # DW_FORM_data1
253243
# File table entries
254-
.byte 1 # 1 file | DW_LNS_copy
255-
.asciz "xyz" # File name | 3 special opcodes + start of DW_LNE_end_sequence
256-
.byte 1 # Dir index | DW_LNE_end_sequence length
257-
# Header end
258-
.byte 1 # DW_LNE_end_sequence opcode
244+
.byte 1 # 1 file
245+
.asciz "a.c"
246+
.byte 1
247+
.Linvalid_file_header_end0:
259248
.byte 0, 9, 2 # DW_LNE_set_address
260249
.quad 0xab4acadab4a
261250
.byte 0, 1, 1 # DW_LNE_end_sequence
@@ -267,7 +256,7 @@
267256
.short 5 # DWARF version number
268257
.byte 8 # Address Size
269258
.byte 0 # Segment Selector Size
270-
.long .Linvalid_dir_header_end0 - .Linvalid_dir_params0 # Length of Prologue (invalid)
259+
.long .Linvalid_dir_header_end0-.Linvalid_dir_params0-16 # Length of Prologue (invalid)
271260
.Linvalid_dir_params0:
272261
.byte 1 # Minimum Instruction Length
273262
.byte 1 # Maximum Operations per Instruction
@@ -282,19 +271,19 @@
282271
.byte 0x08 # DW_FORM_string
283272
# Directory table entries
284273
.byte 1 # 1 directory
285-
.Linvalid_dir_header_end0:
286-
# The bytes from here onwards will also be read as part of the main body.
287-
# --- Prologue interpretation --- | --- Main body interpretation ---
288-
.asciz "/tmp" # Directory name | 4 special opcodes + start of DW_LNE_end_sequence
274+
.asciz "/tmp"
289275
# File table format
290-
.byte 1 # 1 element per file entry | DW_LNE_end_sequence length
291-
.byte 1 # DW_LNCT_path | DW_LNE_end_sequence length opcode
292-
.byte 0x08 # DW_FORM_string | DW_LNS_const_add_pc
276+
.byte 2 # 2 elements per file entry
277+
.byte 1 # DW_LNCT_path
278+
.byte 0x08 # DW_FORM_string
279+
.byte 2 # DW_LNCT_directory_index
280+
.byte 0x0b # DW_FORM_data1
293281
# File table entries
294-
.byte 1 # 1 file | DW_LNS_copy
295-
.asciz "xyz" # File name | start of DW_LNE_set_address
296-
# Header end
297-
.byte 9, 2 # DW_LNE_set_address length + opcode
282+
.byte 1 # 1 file
283+
.asciz "a.c"
284+
.byte 1
285+
.Linvalid_dir_header_end0:
286+
.byte 0, 9, 2 # DW_LNE_set_address
298287
.quad 0x4444333322221111
299288
.byte 0, 1, 1 # DW_LNE_end_sequence
300289
.Linvalid_dir_end0:
@@ -334,7 +323,7 @@
334323
.asciz "a.c"
335324
.byte 0
336325
# Data to show that the rest of the prologue is skipped.
337-
.byte 1
326+
.byte 6
338327
.Linvalid_md5_header_end0:
339328
.byte 0, 9, 2 # DW_LNE_set_address
340329
.quad 0x1234123412341234
@@ -348,7 +337,7 @@
348337
.short 5 # DWARF version number
349338
.byte 8 # Address Size
350339
.byte 0 # Segment Selector Size
351-
.long .Linvalid_md5_header_end1 - .Linvalid_md5_params1 # Length of Prologue
340+
.long .Linvalid_md5_header_end1-.Linvalid_md5_params1 - 10 # Length of Prologue
352341
.Linvalid_md5_params1:
353342
.byte 1 # Minimum Instruction Length
354343
.byte 1 # Maximum Operations per Instruction
@@ -365,20 +354,20 @@
365354
.byte 1 # 1 directory
366355
.asciz "/tmp"
367356
# File table format
368-
.byte 2 # 2 elements per file entry
357+
.byte 3 # 2 elements per file entry
369358
.byte 1 # DW_LNCT_path
370359
.byte 0x08 # DW_FORM_string
371360
.byte 5 # DW_LNCT_MD5
372-
.Linvalid_md5_header_end1:
373-
# The bytes from here onwards will also be read as part of the main body.
374-
# --- Prologue interpretation --- | --- Main body interpretation ---
375-
.byte 0x0b # DW_FORM_data1 | DW_LNS_set_epilogue_begin
361+
.byte 0x0b # DW_FORM_data1
362+
.byte 2 # DW_LNCT_directory_index
363+
.byte 0x0b # DW_FORM_data1
376364
# File table entries
377-
.byte 1 # 1 file | DW_LNS_copy
378-
.asciz "xyz" # File name | 3 special opcodes + DW_LNE_set_address start
379-
.byte 9 # MD5 hash value | DW_LNE_set_address length
380-
# Header end
381-
.byte 2 # DW_LNE_set_address opcode
365+
.byte 1 # 1 file
366+
.asciz "a.c"
367+
.byte 6 # This byte will be consumed when reading the MD5 value.
368+
.byte 0xb # This byte will not be read as part of the prologue.
369+
.Linvalid_md5_header_end1:
370+
.byte 0, 9, 2 # DW_LNE_set_address
382371
.quad 0x4321432143214321
383372
.byte 0, 1, 1 # DW_LNE_end_sequence
384373
.Linvalid_md5_end1:

0 commit comments

Comments
 (0)