mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[DebugInfo] Print line table extended opcode bytes if parsing fails
Previously, if there was an error whilst parsing the operands of an extended opcode, the operands would be treated as zero and printed. This could potentially be slightly confusing. This patch changes the behaviour to print the raw bytes instead. Reviewed by: ikudrin Differential Revision: https://reviews.llvm.org/D81570
This commit is contained in:
parent
1892553dd7
commit
79ce6f32e6
@ -784,15 +784,21 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
|
|
||||||
// Tolerate zero-length; assume length is correct and soldier on.
|
// Tolerate zero-length; assume length is correct and soldier on.
|
||||||
if (Len == 0) {
|
if (Len == 0) {
|
||||||
if (Verbose)
|
if (Cursor && Verbose)
|
||||||
*OS << "Badly formed extended line op (length 0)\n";
|
*OS << "Badly formed extended line op (length 0)\n";
|
||||||
if (!Cursor)
|
if (!Cursor) {
|
||||||
|
if (Verbose)
|
||||||
|
*OS << "\n";
|
||||||
RecoverableErrorHandler(Cursor.takeError());
|
RecoverableErrorHandler(Cursor.takeError());
|
||||||
|
}
|
||||||
*OffsetPtr = Cursor.tell();
|
*OffsetPtr = Cursor.tell();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SubOpcode = TableData.getU8(Cursor);
|
uint8_t SubOpcode = TableData.getU8(Cursor);
|
||||||
|
// OperandOffset will be the same as ExtOffset, if it was not possible to
|
||||||
|
// read the SubOpcode.
|
||||||
|
uint64_t OperandOffset = Cursor.tell();
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
*OS << LNExtendedString(SubOpcode);
|
*OS << LNExtendedString(SubOpcode);
|
||||||
switch (SubOpcode) {
|
switch (SubOpcode) {
|
||||||
@ -805,6 +811,9 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
// address is that of the byte after the last target machine instruction
|
// address is that of the byte after the last target machine instruction
|
||||||
// of the sequence.
|
// of the sequence.
|
||||||
State.Row.EndSequence = true;
|
State.Row.EndSequence = true;
|
||||||
|
// No need to test the Cursor is valid here, since it must be to get
|
||||||
|
// into this code path - if it were invalid, the default case would be
|
||||||
|
// followed.
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
*OS << "\n";
|
*OS << "\n";
|
||||||
OS->indent(12);
|
OS->indent(12);
|
||||||
@ -858,7 +867,7 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
TableData.setAddressSize(ExtractorAddressSize);
|
TableData.setAddressSize(ExtractorAddressSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Verbose)
|
if (Cursor && Verbose)
|
||||||
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
|
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -893,7 +902,7 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
FileEntry.ModTime = TableData.getULEB128(Cursor);
|
FileEntry.ModTime = TableData.getULEB128(Cursor);
|
||||||
FileEntry.Length = TableData.getULEB128(Cursor);
|
FileEntry.Length = TableData.getULEB128(Cursor);
|
||||||
Prologue.FileNames.push_back(FileEntry);
|
Prologue.FileNames.push_back(FileEntry);
|
||||||
if (Verbose)
|
if (Cursor && Verbose)
|
||||||
*OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
|
*OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
|
||||||
<< format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
|
<< format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
|
||||||
<< ", length=" << FileEntry.Length << ")";
|
<< ", length=" << FileEntry.Length << ")";
|
||||||
@ -902,12 +911,12 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
|
|
||||||
case DW_LNE_set_discriminator:
|
case DW_LNE_set_discriminator:
|
||||||
State.Row.Discriminator = TableData.getULEB128(Cursor);
|
State.Row.Discriminator = TableData.getULEB128(Cursor);
|
||||||
if (Verbose)
|
if (Cursor && Verbose)
|
||||||
*OS << " (" << State.Row.Discriminator << ")";
|
*OS << " (" << State.Row.Discriminator << ")";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (Verbose)
|
if (Cursor && Verbose)
|
||||||
*OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
|
*OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
|
||||||
<< format(" length %" PRIx64, Len);
|
<< format(" length %" PRIx64, Len);
|
||||||
// Len doesn't include the zero opcode byte or the length itself, but
|
// Len doesn't include the zero opcode byte or the length itself, but
|
||||||
@ -926,6 +935,23 @@ Error DWARFDebugLine::LineTable::parse(
|
|||||||
"unexpected line op length at offset 0x%8.8" PRIx64
|
"unexpected line op length at offset 0x%8.8" PRIx64
|
||||||
" expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
|
" expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
|
||||||
ExtOffset, Len, Cursor.tell() - ExtOffset));
|
ExtOffset, Len, Cursor.tell() - ExtOffset));
|
||||||
|
if (!Cursor && Verbose) {
|
||||||
|
DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
|
||||||
|
uint8_t Byte = TableData.getU8(ByteCursor);
|
||||||
|
if (ByteCursor) {
|
||||||
|
*OS << " (<parsing error>";
|
||||||
|
do {
|
||||||
|
*OS << format(" %2.2" PRIx8, Byte);
|
||||||
|
Byte = TableData.getU8(ByteCursor);
|
||||||
|
} while (ByteCursor);
|
||||||
|
*OS << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// The only parse failure in this case should be if the end was reached.
|
||||||
|
// In that case, throw away the error, as the main Cursor's error will
|
||||||
|
// be sufficient.
|
||||||
|
consumeError(ByteCursor.takeError());
|
||||||
|
}
|
||||||
*OffsetPtr = End;
|
*OffsetPtr = End;
|
||||||
} else if (Opcode < Prologue.OpcodeBase) {
|
} else if (Opcode < Prologue.OpcodeBase) {
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
|
@ -244,7 +244,7 @@
|
|||||||
# VERBOSE-NEXT: DW_LNE_set_address (0x00000000feedfeed)
|
# VERBOSE-NEXT: DW_LNE_set_address (0x00000000feedfeed)
|
||||||
# VERBOSE-NEXT: DW_LNS_copy
|
# VERBOSE-NEXT: DW_LNS_copy
|
||||||
# NONFATAL-NEXT: 0x00000000feedfeed
|
# NONFATAL-NEXT: 0x00000000feedfeed
|
||||||
# VERBOSE-NEXT: DW_LNE_set_address (0x0000000000000000)
|
# VERBOSE-NEXT: DW_LNE_set_address (<parsing error> 00 f0 01 f0 f0 00 01)
|
||||||
# MORE-ERR-NEXT: warning: unexpected end of data at offset 0x3ed while reading [0x3e6, 0x3ee)
|
# MORE-ERR-NEXT: warning: unexpected end of data at offset 0x3ed while reading [0x3e6, 0x3ee)
|
||||||
# MORE-ERR-NEXT: warning: last sequence in debug line table at offset 0x0000039d is not terminated
|
# MORE-ERR-NEXT: warning: last sequence in debug line table at offset 0x0000039d is not terminated
|
||||||
|
|
||||||
|
@ -1461,64 +1461,71 @@ TEST_P(TruncatedExtendedOpcodeFixture, ErrorForTruncatedExtendedOpcode) {
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture,
|
TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture,
|
||||||
Values(
|
Values(
|
||||||
std::make_tuple(1, 1, DW_LNE_end_sequence, ValueAndLengths(),
|
// Truncated length:
|
||||||
"Badly formed extended line op (length 0)",
|
std::make_tuple(1, 1, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",
|
||||||
"unable to decode LEB128 at offset 0x00000030: "
|
"unable to decode LEB128 at offset 0x00000030: "
|
||||||
"malformed uleb128, extends past end"),
|
"malformed uleb128, extends past end"),
|
||||||
|
// Truncated opcode:
|
||||||
std::make_tuple(
|
std::make_tuple(
|
||||||
2, 9, DW_LNE_set_address,
|
2, 9, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",
|
||||||
ValueAndLengths{{0x12345678, LineTable::Quad}},
|
|
||||||
"Unrecognized extended op 0x00 length 9",
|
|
||||||
"unexpected end of data at offset 0x31 while reading [0x31, 0x32)"),
|
"unexpected end of data at offset 0x31 while reading [0x31, 0x32)"),
|
||||||
|
// Truncated operands:
|
||||||
std::make_tuple(
|
std::make_tuple(
|
||||||
3, 9, DW_LNE_set_address,
|
3, 9, DW_LNE_set_address,
|
||||||
ValueAndLengths{{0x12345678, LineTable::Quad}},
|
ValueAndLengths{{0x1234567890abcdef, LineTable::Quad}},
|
||||||
"DW_LNE_set_address (0x0000000000000000)",
|
"DW_LNE_set_address",
|
||||||
"unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"),
|
"unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"),
|
||||||
std::make_tuple(3, 5, DW_LNE_define_file,
|
std::make_tuple(
|
||||||
|
10, 9, DW_LNE_set_address,
|
||||||
|
ValueAndLengths{{0x1234567890abcdef, LineTable::Quad}},
|
||||||
|
"DW_LNE_set_address (<parsing error> ef cd ab 90 78 56 34)",
|
||||||
|
"unexpected end of data at offset 0x39 while reading [0x32, 0x3a)"),
|
||||||
|
std::make_tuple(3, 6, DW_LNE_define_file,
|
||||||
ValueAndLengths{{'a', LineTable::Byte},
|
ValueAndLengths{{'a', LineTable::Byte},
|
||||||
{'\0', LineTable::Byte},
|
{'\0', LineTable::Byte},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB}},
|
{1, LineTable::ULEB}},
|
||||||
"DW_LNE_define_file (, dir=0, "
|
"DW_LNE_define_file",
|
||||||
"mod_time=(0x0000000000000000), length=0)",
|
|
||||||
"no null terminated string at offset 0x32"),
|
"no null terminated string at offset 0x32"),
|
||||||
std::make_tuple(5, 5, DW_LNE_define_file,
|
std::make_tuple(5, 6, DW_LNE_define_file,
|
||||||
ValueAndLengths{{'a', LineTable::Byte},
|
ValueAndLengths{{'a', LineTable::Byte},
|
||||||
{'\0', LineTable::Byte},
|
{'\0', LineTable::Byte},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB}},
|
{1, LineTable::ULEB}},
|
||||||
"DW_LNE_define_file (a, dir=0, "
|
"DW_LNE_define_file (<parsing error> 61 00)",
|
||||||
"mod_time=(0x0000000000000000), length=0)",
|
|
||||||
"unable to decode LEB128 at offset 0x00000034: "
|
"unable to decode LEB128 at offset 0x00000034: "
|
||||||
"malformed uleb128, extends past end"),
|
"malformed uleb128, extends past end"),
|
||||||
std::make_tuple(6, 5, DW_LNE_define_file,
|
std::make_tuple(6, 6, DW_LNE_define_file,
|
||||||
ValueAndLengths{{'a', LineTable::Byte},
|
ValueAndLengths{{'a', LineTable::Byte},
|
||||||
{'\0', LineTable::Byte},
|
{'\0', LineTable::Byte},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB}},
|
{1, LineTable::ULEB}},
|
||||||
"DW_LNE_define_file (a, dir=1, "
|
"DW_LNE_define_file (<parsing error> 61 00 01)",
|
||||||
"mod_time=(0x0000000000000000), length=0)",
|
|
||||||
"unable to decode LEB128 at offset 0x00000035: "
|
"unable to decode LEB128 at offset 0x00000035: "
|
||||||
"malformed uleb128, extends past end"),
|
"malformed uleb128, extends past end"),
|
||||||
std::make_tuple(7, 5, DW_LNE_define_file,
|
std::make_tuple(7, 6, DW_LNE_define_file,
|
||||||
ValueAndLengths{{'a', LineTable::Byte},
|
ValueAndLengths{{'a', LineTable::Byte},
|
||||||
{'\0', LineTable::Byte},
|
{'\0', LineTable::Byte},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB},
|
{1, LineTable::ULEB},
|
||||||
{1, LineTable::ULEB}},
|
{1, LineTable::ULEB}},
|
||||||
"DW_LNE_define_file (a, dir=1, "
|
"DW_LNE_define_file (<parsing error> 61 00 01 01)",
|
||||||
"mod_time=(0x0000000000000001), length=0)",
|
|
||||||
"unable to decode LEB128 at offset 0x00000036: "
|
"unable to decode LEB128 at offset 0x00000036: "
|
||||||
"malformed uleb128, extends past end"),
|
"malformed uleb128, extends past end"),
|
||||||
std::make_tuple(3, 2, DW_LNE_set_discriminator,
|
std::make_tuple(3, 2, DW_LNE_set_discriminator,
|
||||||
ValueAndLengths{{1, LineTable::ULEB}},
|
ValueAndLengths{{1, LineTable::ULEB}},
|
||||||
"DW_LNE_set_discriminator (0)",
|
"DW_LNE_set_discriminator",
|
||||||
"unable to decode LEB128 at offset 0x00000032: "
|
"unable to decode LEB128 at offset 0x00000032: "
|
||||||
"malformed uleb128, extends past end")), );
|
"malformed uleb128, extends past end"),
|
||||||
|
std::make_tuple(
|
||||||
|
6, 5, /*Unknown=*/0x7f,
|
||||||
|
ValueAndLengths{{0x12345678, LineTable::Long}},
|
||||||
|
"Unrecognized extended op 0x7f length 5 (<parsing error> 78 56 34)",
|
||||||
|
"unexpected end of data at offset 0x35 while reading [0x32, "
|
||||||
|
"0x36)")), );
|
||||||
|
|
||||||
TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) {
|
TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) {
|
||||||
if (!setupGenerator())
|
if (!setupGenerator())
|
||||||
|
Loading…
Reference in New Issue
Block a user