1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[DebugInfo] Make debug line address size mismatch non-fatal to parsing

Reasonable assumptions can be made when a parsed address length does not
match the expected length, so there's no need for this to be fatal.

Reviewed by: ikudrin

Differential Revision: https://reviews.llvm.org/D72154
This commit is contained in:
James Henderson 2020-01-13 16:27:05 +00:00
parent e884b78242
commit 69703dcf78
2 changed files with 72 additions and 19 deletions

View File

@ -607,19 +607,28 @@ Error DWARFDebugLine::LineTable::parse(
//
// Make sure the extractor knows the address size. If not, infer it
// from the size of the operand.
if (DebugLineData.getAddressSize() == 0)
{
uint8_t ExtractorAddressSize = DebugLineData.getAddressSize();
if (ExtractorAddressSize != Len - 1 && ExtractorAddressSize != 0)
RecoverableErrorCallback(createStringError(
errc::invalid_argument,
"mismatching address size at offset 0x%8.8" PRIx64
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
ExtOffset, ExtractorAddressSize, Len - 1));
// Assume that the line table is correct and temporarily override the
// address size.
DebugLineData.setAddressSize(Len - 1);
else if (DebugLineData.getAddressSize() != Len - 1) {
return createStringError(errc::invalid_argument,
"mismatching address size at offset 0x%8.8" PRIx64
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
ExtOffset, DebugLineData.getAddressSize(),
Len - 1);
State.Row.Address.Address = DebugLineData.getRelocatedAddress(
OffsetPtr, &State.Row.Address.SectionIndex);
// Restore the address size if the extractor already had it.
if (ExtractorAddressSize != 0)
DebugLineData.setAddressSize(ExtractorAddressSize);
if (OS)
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
}
State.Row.Address.Address = DebugLineData.getRelocatedAddress(
OffsetPtr, &State.Row.Address.SectionIndex);
if (OS)
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
break;
case DW_LNE_define_file:

View File

@ -36,8 +36,10 @@ struct CommonFixture {
EXPECT_FALSE(Unrecoverable);
}
bool setupGenerator(uint16_t Version = 4) {
Triple T = getDefaultTargetTripleForAddrSize(8);
bool setupGenerator(uint16_t Version = 4, uint8_t AddrSize = 8) {
AddressSize = AddrSize;
Triple T =
getDefaultTargetTripleForAddrSize(AddressSize == 0 ? 8 : AddressSize);
if (!isConfigurationSupported(T))
return false;
auto ExpectedGenerator = Generator::create(T, Version);
@ -50,9 +52,11 @@ struct CommonFixture {
Context = createContext();
assert(Context != nullptr && "test state is not valid");
const DWARFObject &Obj = Context->getDWARFObj();
uint8_t TargetAddrSize = AddressSize == 0 ? 8 : AddressSize;
LineData = DWARFDataExtractor(
Obj, Obj.getLineSection(),
getDefaultTargetTripleForAddrSize(8).isLittleEndian(), 8);
getDefaultTargetTripleForAddrSize(TargetAddrSize).isLittleEndian(),
AddressSize);
}
std::unique_ptr<DWARFContext> createContext() {
@ -130,6 +134,7 @@ struct CommonFixture {
checkError(ExpectedMsgs, ExpectedLineTable.takeError());
}
uint8_t AddressSize;
std::unique_ptr<Generator> Gen;
std::unique_ptr<DWARFContext> Context;
DWARFDataExtractor LineData;
@ -468,20 +473,59 @@ TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) {
}
TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {
if (!setupGenerator())
if (!setupGenerator(4, 8))
return;
LineTable &LT = Gen->addLineTable();
// The line data extractor expects size 8 (Quad) addresses.
LT.addExtendedOpcode(5, DW_LNE_set_address, {{0x11223344, LineTable::Long}});
uint64_t Addr1 = 0x11223344;
LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
LT.addStandardOpcode(DW_LNS_copy, {});
LT.addByte(0xaa);
// Show that the expected address size is unchanged, so later valid lines
// don't cause a problem.
uint64_t Addr2 = 0x1122334455667788;
LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});
LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
generate();
checkGetOrParseLineTableEmitsFatalError(
"mismatching address size at offset 0x00000030 expected 0x08 found 0x04");
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable);
checkError(
"mismatching address size at offset 0x00000030 expected 0x08 found 0x04",
std::move(Recoverable));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);
EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);
}
TEST_F(DebugLineBasicFixture,
ErrorForMismatchedAddressSizeUnsetInitialAddress) {
if (!setupGenerator(4, 0))
return;
LineTable &LT = Gen->addLineTable();
uint64_t Addr1 = 0x11223344;
LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
LT.addStandardOpcode(DW_LNS_copy, {});
uint64_t Addr2 = 0x1122334455667788;
LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});
LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
generate();
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable);
checkError(
"mismatching address size at offset 0x00000038 expected 0x04 found 0x08",
std::move(Recoverable));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);
EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);
}
TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {