Skip to content

Commit 07804f7

Browse files
committed
[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
1 parent 81e7922 commit 07804f7

File tree

2 files changed

+72
-19
lines changed

2 files changed

+72
-19
lines changed

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -607,19 +607,28 @@ Error DWARFDebugLine::LineTable::parse(
607607
//
608608
// Make sure the extractor knows the address size. If not, infer it
609609
// from the size of the operand.
610-
if (DebugLineData.getAddressSize() == 0)
610+
{
611+
uint8_t ExtractorAddressSize = DebugLineData.getAddressSize();
612+
if (ExtractorAddressSize != Len - 1 && ExtractorAddressSize != 0)
613+
RecoverableErrorCallback(createStringError(
614+
errc::invalid_argument,
615+
"mismatching address size at offset 0x%8.8" PRIx64
616+
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
617+
ExtOffset, ExtractorAddressSize, Len - 1));
618+
619+
// Assume that the line table is correct and temporarily override the
620+
// address size.
611621
DebugLineData.setAddressSize(Len - 1);
612-
else if (DebugLineData.getAddressSize() != Len - 1) {
613-
return createStringError(errc::invalid_argument,
614-
"mismatching address size at offset 0x%8.8" PRIx64
615-
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
616-
ExtOffset, DebugLineData.getAddressSize(),
617-
Len - 1);
622+
State.Row.Address.Address = DebugLineData.getRelocatedAddress(
623+
OffsetPtr, &State.Row.Address.SectionIndex);
624+
625+
// Restore the address size if the extractor already had it.
626+
if (ExtractorAddressSize != 0)
627+
DebugLineData.setAddressSize(ExtractorAddressSize);
628+
629+
if (OS)
630+
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
618631
}
619-
State.Row.Address.Address = DebugLineData.getRelocatedAddress(
620-
OffsetPtr, &State.Row.Address.SectionIndex);
621-
if (OS)
622-
*OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
623632
break;
624633

625634
case DW_LNE_define_file:

llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ struct CommonFixture {
3636
EXPECT_FALSE(Unrecoverable);
3737
}
3838

39-
bool setupGenerator(uint16_t Version = 4) {
40-
Triple T = getDefaultTargetTripleForAddrSize(8);
39+
bool setupGenerator(uint16_t Version = 4, uint8_t AddrSize = 8) {
40+
AddressSize = AddrSize;
41+
Triple T =
42+
getDefaultTargetTripleForAddrSize(AddressSize == 0 ? 8 : AddressSize);
4143
if (!isConfigurationSupported(T))
4244
return false;
4345
auto ExpectedGenerator = Generator::create(T, Version);
@@ -50,9 +52,11 @@ struct CommonFixture {
5052
Context = createContext();
5153
assert(Context != nullptr && "test state is not valid");
5254
const DWARFObject &Obj = Context->getDWARFObj();
55+
uint8_t TargetAddrSize = AddressSize == 0 ? 8 : AddressSize;
5356
LineData = DWARFDataExtractor(
5457
Obj, Obj.getLineSection(),
55-
getDefaultTargetTripleForAddrSize(8).isLittleEndian(), 8);
58+
getDefaultTargetTripleForAddrSize(TargetAddrSize).isLittleEndian(),
59+
AddressSize);
5660
}
5761

5862
std::unique_ptr<DWARFContext> createContext() {
@@ -130,6 +134,7 @@ struct CommonFixture {
130134
checkError(ExpectedMsgs, ExpectedLineTable.takeError());
131135
}
132136

137+
uint8_t AddressSize;
133138
std::unique_ptr<Generator> Gen;
134139
std::unique_ptr<DWARFContext> Context;
135140
DWARFDataExtractor LineData;
@@ -468,20 +473,59 @@ TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) {
468473
}
469474

470475
TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {
471-
if (!setupGenerator())
476+
if (!setupGenerator(4, 8))
472477
return;
473478

474479
LineTable &LT = Gen->addLineTable();
475480
// The line data extractor expects size 8 (Quad) addresses.
476-
LT.addExtendedOpcode(5, DW_LNE_set_address, {{0x11223344, LineTable::Long}});
481+
uint64_t Addr1 = 0x11223344;
482+
LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
477483
LT.addStandardOpcode(DW_LNS_copy, {});
478-
LT.addByte(0xaa);
484+
// Show that the expected address size is unchanged, so later valid lines
485+
// don't cause a problem.
486+
uint64_t Addr2 = 0x1122334455667788;
487+
LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});
479488
LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
480489

481490
generate();
482491

483-
checkGetOrParseLineTableEmitsFatalError(
484-
"mismatching address size at offset 0x00000030 expected 0x08 found 0x04");
492+
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
493+
nullptr, RecordRecoverable);
494+
checkError(
495+
"mismatching address size at offset 0x00000030 expected 0x08 found 0x04",
496+
std::move(Recoverable));
497+
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
498+
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
499+
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
500+
EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);
501+
EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);
502+
}
503+
504+
TEST_F(DebugLineBasicFixture,
505+
ErrorForMismatchedAddressSizeUnsetInitialAddress) {
506+
if (!setupGenerator(4, 0))
507+
return;
508+
509+
LineTable &LT = Gen->addLineTable();
510+
uint64_t Addr1 = 0x11223344;
511+
LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
512+
LT.addStandardOpcode(DW_LNS_copy, {});
513+
uint64_t Addr2 = 0x1122334455667788;
514+
LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});
515+
LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
516+
517+
generate();
518+
519+
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
520+
nullptr, RecordRecoverable);
521+
checkError(
522+
"mismatching address size at offset 0x00000038 expected 0x04 found 0x08",
523+
std::move(Recoverable));
524+
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
525+
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
526+
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
527+
EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);
528+
EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);
485529
}
486530

487531
TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {

0 commit comments

Comments
 (0)