mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[DWARFDebugLine] Avoid dumping prologue members we did not parse
Summary: This patch if motivated by D74560, specifically the subthread about what to print upon encountering reserved initial length values. If the debug_line prologue has an unsupported version, we skip parsing the rest of the data. If we encounter an reserved initial length field, we don't even parse the version. However, we still print out all members (with value 0) in the dump function. This patch introduces early exits in the Prologue::dump function so that we print only the fields that were parsed successfully. In case of an unsupported version, we skip printing all subsequent prologue fields -- because we don't even know if this version has those fields. In case of a reserved unit length, we don't print anything -- if the very first field of the prologue is invalid, it's hard to say if we even have a prologue to begin with. Note that the user will still be able to see the invalid/reserved initial length value in the error message. I've modified (reordered) debug_line_invalid.test to show that the error message comes straight after the debug_line offset. I've also added some flush() calls to the dumping code to ensure this is the case in all situations (without that, the warnings could get out of sync if the output was not a terminal -- I guess this is why std::iostreams have the tie() function). Reviewers: jhenderson, ikudrin, dblaikie Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75043
This commit is contained in:
parent
b9cd5773e4
commit
0028727768
@ -474,6 +474,7 @@ void DWARFContext::dump(
|
||||
}
|
||||
OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
|
||||
<< "]\n";
|
||||
OS.flush();
|
||||
if (DumpOpts.Verbose) {
|
||||
Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS);
|
||||
} else {
|
||||
@ -481,6 +482,7 @@ void DWARFContext::dump(
|
||||
Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
|
||||
LineTable.dump(OS, DumpOpts);
|
||||
}
|
||||
OS.flush();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,10 @@ using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
static bool versionIsSupported(uint16_t Version) {
|
||||
return Version >= 2 && Version <= 5;
|
||||
}
|
||||
|
||||
void DWARFDebugLine::ContentTypeTracker::trackContentType(
|
||||
dwarf::LineNumberEntryFormat ContentType) {
|
||||
switch (ContentType) {
|
||||
@ -100,9 +104,13 @@ void DWARFDebugLine::Prologue::clear() {
|
||||
|
||||
void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
|
||||
DIDumpOptions DumpOptions) const {
|
||||
if (!totalLengthIsValid())
|
||||
return;
|
||||
OS << "Line table prologue:\n"
|
||||
<< format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
|
||||
<< format(" version: %u\n", getVersion());
|
||||
if (!versionIsSupported(getVersion()))
|
||||
return;
|
||||
if (getVersion() >= 5)
|
||||
OS << format(" address_size: %u\n", getAddressSize())
|
||||
<< format(" seg_select_size: %u\n", SegSelectorSize);
|
||||
@ -345,7 +353,7 @@ Error DWARFDebugLine::Prologue::parse(
|
||||
PrologueOffset, TotalLength);
|
||||
}
|
||||
FormParams.Version = DebugLineData.getU16(OffsetPtr);
|
||||
if (getVersion() < 2 || getVersion() > 5)
|
||||
if (!versionIsSupported(getVersion()))
|
||||
// Treat this error as unrecoverable - we cannot be sure what any of
|
||||
// the data represents including the length field, so cannot skip it or make
|
||||
// any reasonable assumptions.
|
||||
|
@ -3,42 +3,34 @@
|
||||
|
||||
## Show that a bad length stops parsing of the section.
|
||||
# RUN: llvm-mc -triple x86_64-pc-linux %S/Inputs/debug_line_reserved_length.s -filetype=obj -o %t-reserved.o
|
||||
# RUN: llvm-dwarfdump -debug-line %t-reserved.o 2> %t-reserved.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL
|
||||
# RUN: FileCheck %s --input-file=%t-reserved.err --check-prefix=RESERVED
|
||||
# RUN: llvm-dwarfdump -debug-line %t-reserved.o -verbose 2> %t-reserved-verbose.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL
|
||||
# RUN: FileCheck %s --input-file=%t-reserved-verbose.err --check-prefix=RESERVED
|
||||
# RUN: llvm-dwarfdump -debug-line %t-reserved.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL,RESERVED
|
||||
# RUN: llvm-dwarfdump -debug-line %t-reserved.o -verbose 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL,RESERVED
|
||||
|
||||
## We only produce warnings for malformed tables after the specified unit if
|
||||
## parsing can continue.
|
||||
# RUN: llvm-dwarfdump -debug-line=0 %t-reserved.o 2> %t-reserved-off-first.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER
|
||||
# RUN: FileCheck %s --input-file=%t-reserved-off-first.err --check-prefix=RESERVED
|
||||
# RUN: llvm-dwarfdump -debug-line=0 %t-reserved.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER,RESERVED
|
||||
|
||||
## Stop looking for the specified unit, if a fatally-bad prologue is detected.
|
||||
# RUN: llvm-dwarfdump -debug-line=0x4b %t-reserved.o 2> %t-reserved-off-last.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=NOFIRST,NOLATER
|
||||
# RUN: FileCheck %s --input-file=%t-reserved-off-last.err --check-prefix=RESERVED
|
||||
# RUN: llvm-dwarfdump -debug-line=0x4b %t-reserved.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=NOFIRST,NOLATER,RESERVED
|
||||
|
||||
## Show that non-fatal errors do not prevent parsing the rest of the section.
|
||||
# RUN: llvm-mc -triple x86_64-pc-linux %S/Inputs/debug_line_malformed.s -filetype=obj -o %t-malformed.o
|
||||
# RUN: llvm-dwarfdump -debug-line %t-malformed.o 2> %t-malformed.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]'
|
||||
# RUN: FileCheck %s --input-file=%t-malformed.err --check-prefixes=ALL,OTHER
|
||||
# RUN: llvm-dwarfdump -debug-line %t-malformed.o -verbose 2> %t-malformed-verbose.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]'
|
||||
# RUN: FileCheck %s --input-file=%t-malformed-verbose.err --check-prefixes=ALL,OTHER
|
||||
# RUN: llvm-dwarfdump -debug-line %t-malformed.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST,ALL,OTHER --implicit-check-not='debug_line[{{.*}}]'
|
||||
# RUN: llvm-dwarfdump -debug-line %t-malformed.o -verbose 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST,ALL,OTHER --implicit-check-not='debug_line[{{.*}}]'
|
||||
|
||||
## We should still produce warnings for malformed tables after the specified unit.
|
||||
# RUN: llvm-dwarfdump -debug-line=0 %t-malformed.o 2> %t-malformed-off-first.err \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER
|
||||
# RUN: FileCheck %s --input-file=%t-malformed-off-first.err --check-prefix=ALL
|
||||
# RUN: llvm-dwarfdump -debug-line=0 %t-malformed.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER,ALL
|
||||
|
||||
## Don't stop looking for the later unit if non-fatal issues are found.
|
||||
# RUN: llvm-dwarfdump -debug-line=0x3c9 %t-malformed.o 2> %t-malformed-off-last.err \
|
||||
# RUN: | FileCheck %s --check-prefix=LAST --implicit-check-not='debug_line[{{.*}}]'
|
||||
# RUN: FileCheck %s --input-file=%t-malformed-off-last.err --check-prefix=ALL
|
||||
# RUN: llvm-dwarfdump -debug-line=0x3c9 %t-malformed.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefixes=LAST,ALL --implicit-check-not='debug_line[{{.*}}]'
|
||||
|
||||
# FIRST: debug_line[0x00000000]
|
||||
# FIRST: 0x000000000badbeef {{.*}} end_sequence
|
||||
@ -49,31 +41,44 @@
|
||||
|
||||
## For fatal issues, the following table(s) should not be dumped:
|
||||
# FATAL: debug_line[0x00000048]
|
||||
# FATAL-NEXT: Line table prologue
|
||||
# FATAL-NEXT: total_length: 0xfffffffe
|
||||
# RESERVED-NOT: prologue
|
||||
# RESERVED: warning: parsing line table prologue at offset 0x00000048 unsupported reserved unit length found of value 0xfffffffe
|
||||
# RESERVED-NOT: prologue
|
||||
# FATAL-NOT: debug_line
|
||||
|
||||
## For non-fatal issues, the table data should be dumped:
|
||||
|
||||
## Version 0 table.
|
||||
# NONFATAL: debug_line[0x00000048]
|
||||
# ALL: warning: parsing line table prologue at offset 0x00000048 found unsupported version 0
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL-NOT: Address
|
||||
# NONFATAL-NEXT: total_length: 0x00000002
|
||||
# NONFATAL-NEXT: version: 0
|
||||
# NONFATAL-NOT: prologue_length
|
||||
|
||||
## Version 1 table.
|
||||
# NONFATAL: debug_line[0x0000004e]
|
||||
# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e found unsupported version 1
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL-NOT: Address
|
||||
# NONFATAL-NEXT: total_length: 0x00000002
|
||||
# NONFATAL-NEXT: version: 1
|
||||
# NONFATAL-NOT: prologue_length
|
||||
|
||||
## Malformed directory format with no path component.
|
||||
# NONFATAL: debug_line[0x00000054]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073
|
||||
# ALL-NEXT: warning: failed to parse entry content descriptions because no path was found
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: prologue_length: 0x00000013
|
||||
# NONFATAL-NOT: include_directories
|
||||
# NONFATAL-NOT: file_names
|
||||
# NONFATAL: 0x8877665544332211 {{.*}} end_sequence
|
||||
|
||||
## Prologue with length shorter than parsed.
|
||||
# NONFATAL: debug_line[0x00000081]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba
|
||||
# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000081 should have ended at 0x000000b9 but it ended at 0x000000ba
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: file_names[ 2]:
|
||||
# NONFATAL-NEXT: name: "file2"
|
||||
@ -84,6 +89,7 @@
|
||||
|
||||
## Prologue with length longer than parsed.
|
||||
# NONFATAL: debug_line[0x000000c8]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000000c8 should have ended at 0x00000103 but it ended at 0x00000102
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: file_names[ 2]:
|
||||
# NONFATAL-NEXT: name: "file2"
|
||||
@ -95,18 +101,24 @@
|
||||
|
||||
## Extended opcode with incorrect length versus expected.
|
||||
# NONFATAL: debug_line[0x00000111]
|
||||
# OTHER-NEXT: warning: unexpected line op length at offset 0x00000158 expected 0x02 found 0x01
|
||||
# OTHER-NEXT: warning: unexpected line op length at offset 0x0000015c expected 0x01 found 0x02
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: prologue_length: 0x00000030
|
||||
# NONFATAL: 0x00000000abbadaba {{.*}} end_sequence
|
||||
# NONFATAL: 0x00000000babb1e45 {{.*}} 10 is_stmt prologue_end end_sequence{{$}}
|
||||
|
||||
## No end of sequence.
|
||||
# NONFATAL: debug_line[0x0000016c]
|
||||
# OTHER-NEXT: warning: last sequence in debug line table at offset 0x0000016c is not terminated
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: prologue_length: 0x00000030
|
||||
# NONFATAL: 0x00000000deadfade {{.*}} is_stmt
|
||||
# NONFATAL-NOT: end_sequence
|
||||
|
||||
## Very short prologue length for V5 (ends during parameters).
|
||||
# NONFATAL: debug_line[0x000001b2]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000001b2 should have ended at 0x000001ce but it ended at 0x000001e1
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: standard_opcode_lengths[DW_LNS_set_isa] = 1
|
||||
# NONFATAL-NEXT: include_directories[ 0] = "/tmp"
|
||||
@ -117,6 +129,7 @@
|
||||
|
||||
## V5 prologue ends during file table.
|
||||
# NONFATAL: debug_line[0x000001ee]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000001ee should have ended at 0x00000219 but it ended at 0x00000220
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 0] = "/tmp"
|
||||
# NONFATAL-NEXT: file_names[ 0]:
|
||||
@ -127,6 +140,7 @@
|
||||
|
||||
## V5 prologue ends during directory table.
|
||||
# NONFATAL: debug_line[0x0000022f]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x0000022f should have ended at 0x00000251 but it ended at 0x0000025e
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 0] = "/tmp"
|
||||
# NONFATAL-NEXT: file_names[ 0]:
|
||||
@ -136,6 +150,8 @@
|
||||
|
||||
## V5 invalid MD5 hash form when there is still data to be read.
|
||||
# NONFATAL: debug_line[0x0000026b]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x0000026b found an invalid directory or file table description at 0x0000029f
|
||||
# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 0] = "/tmp"
|
||||
# NONFATAL-NOT: file_names
|
||||
@ -145,6 +161,9 @@
|
||||
## V5 invalid MD5 hash form when data beyond the prologue length has
|
||||
## been read before the MD5 problem is identified.
|
||||
# NONFATAL: debug_line[0x000002ae]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ae found an invalid directory or file table description at 0x000002e0
|
||||
# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ae should have ended at 0x000002d9 but it ended at 0x000002e0
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 0] = "/tmp"
|
||||
# NONFATAL-NOT: file_names
|
||||
@ -153,6 +172,8 @@
|
||||
|
||||
## V5 invalid directory content description has unsupported form.
|
||||
# NONFATAL: debug_line[0x000002ec]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ec found an invalid directory or file table description at 0x00000315
|
||||
# ALL-NEXT: warning: failed to parse directory entry because skipping the form value failed.
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 0] = "/foo"
|
||||
# NONFATAL-NOT: include_directories
|
||||
@ -161,6 +182,7 @@
|
||||
|
||||
## Opcode base field of value zero.
|
||||
# NONFATAL: debug_line[0x00000332]
|
||||
# ALL-NEXT: warning: parsing line table prologue at offset 0x00000332 found opcode base of 0. Assuming no standard opcodes
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: include_directories[ 1] = "dir1"
|
||||
# NONFATAL-NEXT: file_names[ 1]:
|
||||
@ -173,6 +195,8 @@
|
||||
|
||||
## V4 table with unterminated include directory table.
|
||||
# NONFATAL: debug_line[0x00000361]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000361 found an invalid directory or file table description at 0x00000382
|
||||
# ALL-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"
|
||||
# NONFATAL-NOT: file_names
|
||||
@ -180,6 +204,8 @@
|
||||
|
||||
## V4 table with unterminated file name table.
|
||||
# NONFATAL: debug_line[0x00000390]
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bb
|
||||
# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue
|
||||
# NONFATAL-NEXT: Line table prologue
|
||||
# NONFATAL: file_names[ 1]:
|
||||
# NONFATAL-NEXT: name: "foo.c"
|
||||
@ -191,34 +217,3 @@
|
||||
|
||||
# LAST: debug_line[0x000003c9]
|
||||
# LAST: 0x00000000cafebabe {{.*}} end_sequence
|
||||
|
||||
# RESERVED: warning: parsing line table prologue at offset 0x00000048 unsupported reserved unit length found of value 0xfffffffe
|
||||
|
||||
# ALL-NOT: warning:
|
||||
# ALL: warning: parsing line table prologue at offset 0x00000048 found unsupported version 0
|
||||
# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e found unsupported version 1
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073
|
||||
# ALL-NEXT: warning: failed to parse entry content descriptions because no path was found
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba
|
||||
# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000081 should have ended at 0x000000b9 but it ended at 0x000000ba
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000000c8 should have ended at 0x00000103 but it ended at 0x00000102
|
||||
# OTHER-NEXT: warning: unexpected line op length at offset 0x00000158 expected 0x02 found 0x01
|
||||
# OTHER-NEXT: warning: unexpected line op length at offset 0x0000015c expected 0x01 found 0x02
|
||||
# OTHER-NEXT: warning: last sequence in debug line table at offset 0x0000016c is not terminated
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000001b2 should have ended at 0x000001ce but it ended at 0x000001e1
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000001ee should have ended at 0x00000219 but it ended at 0x00000220
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x0000022f should have ended at 0x00000251 but it ended at 0x0000025e
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x0000026b found an invalid directory or file table description at 0x0000029f
|
||||
# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ae found an invalid directory or file table description at 0x000002e0
|
||||
# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ae should have ended at 0x000002d9 but it ended at 0x000002e0
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x000002ec found an invalid directory or file table description at 0x00000315
|
||||
# ALL-NEXT: warning: failed to parse directory entry because skipping the form value failed.
|
||||
# ALL-NEXT: warning: parsing line table prologue at offset 0x00000332 found opcode base of 0. Assuming no standard opcodes
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000361 found an invalid directory or file table description at 0x00000382
|
||||
# ALL-NEXT: warning: include directories table was not null terminated before the end of the prologue
|
||||
# ALL-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bb
|
||||
# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue
|
||||
# ALL-NOT: warning:
|
||||
|
Loading…
Reference in New Issue
Block a user