diff options
author | James Henderson <james.henderson@sony.com> | 2020-02-03 16:43:03 +0000 |
---|---|---|
committer | James Henderson <james.henderson@sony.com> | 2020-02-14 11:08:12 +0000 |
commit | fe6983a75ae08dc63e2068f521670562ad77c599 (patch) | |
tree | ae4bf878e41791776233a0d4094a9fae617db51c /llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp | |
parent | 9dc84e9b02d1e402503906099d42fbae4da7d8d9 (diff) | |
download | llvm-fe6983a75ae08dc63e2068f521670562ad77c599.zip llvm-fe6983a75ae08dc63e2068f521670562ad77c599.tar.gz llvm-fe6983a75ae08dc63e2068f521670562ad77c599.tar.bz2 |
[DebugInfo] Error if unsupported address size detected in line table
Prior to this patch, if a DW_LNE_set_address opcode was parsed with an
address size (i.e. with a length after the opcode) of anything other 1,
2, 4, or 8, an llvm_unreachable would be hit, as the data extractor does
not support other values. This patch introduces a new error check that
verifies the address size is one of the supported sizes, in common with
other places within the DWARF parsing.
This patch also fixes calculation of a generated line table's size in
unit tests. One of the tests in this patch highlighted a bug introduced
in 1271cde4745, when non-byte operands were used as arguments for
extended or standard opcodes.
Reviewed by: dblaikie
Differential Revision: https://reviews.llvm.org/D73962
Diffstat (limited to 'llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp')
-rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp index d6d9691..0552b5a 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -640,6 +640,100 @@ TEST_F(DebugLineBasicFixture, EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2); } +TEST_F(DebugLineBasicFixture, + ErrorForUnsupportedAddressSizeInSetAddressLength) { + // Use DWARF v4, and 0 for data extractor address size so that the address + // size is derived from the opcode length. + if (!setupGenerator(4, 0)) + return; + + LineTable < = Gen->addLineTable(); + // 4 == length of the extended opcode, i.e. 1 for the opcode itself and 3 for + // the Half (2) + Byte (1) operand, representing the unsupported address size. + LT.addExtendedOpcode(4, DW_LNE_set_address, + {{0x1234, LineTable::Half}, {0x56, LineTable::Byte}}); + LT.addStandardOpcode(DW_LNS_copy, {}); + // Special opcode to ensure the address has changed between the first and last + // row in the sequence. Without this, the sequence will not be recorded. + LT.addByte(0xaa); + LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); + + generate(); + + auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, + nullptr, RecordRecoverable); + checkError( + "address size 0x03 of DW_LNE_set_address opcode at offset 0x00000030 is " + "unsupported", + std::move(Recoverable)); + ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); + ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); + EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); + // Show that the set address opcode is ignored in this case. + EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0); +} + +TEST_F(DebugLineBasicFixture, ErrorForAddressSizeGreaterThanByteSize) { + // Use DWARF v4, and 0 for data extractor address size so that the address + // size is derived from the opcode length. + if (!setupGenerator(4, 0)) + return; + + LineTable < = Gen->addLineTable(); + // Specifically use an operand size that has a trailing byte of a supported + // size (8), so that any potential truncation would result in a valid size. + std::vector<LineTable::ValueAndLength> Operands(0x108); + LT.addExtendedOpcode(Operands.size() + 1, DW_LNE_set_address, Operands); + LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); + + generate(); + + auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, + nullptr, RecordRecoverable); + checkError( + "address size 0x108 of DW_LNE_set_address opcode at offset 0x00000031 is " + "unsupported", + std::move(Recoverable)); + ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); +} + +TEST_F(DebugLineBasicFixture, ErrorForUnsupportedAddressSizeDefinedInHeader) { + // Use 0 for data extractor address size so that it does not clash with the + // header address size. + if (!setupGenerator(5, 0)) + return; + + LineTable < = Gen->addLineTable(); + // AddressSize + 1 == length of the extended opcode, i.e. 1 for the opcode + // itself and 9 for the Quad (8) + Byte (1) operand representing the + // unsupported address size. + uint8_t AddressSize = 9; + LT.addExtendedOpcode(AddressSize + 1, DW_LNE_set_address, + {{0x12345678, LineTable::Quad}, {0, LineTable::Byte}}); + LT.addStandardOpcode(DW_LNS_copy, {}); + // Special opcode to ensure the address has changed between the first and last + // row in the sequence. Without this, the sequence will not be recorded. + LT.addByte(0xaa); + LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); + DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); + Prologue.FormParams.AddrSize = AddressSize; + LT.setPrologue(Prologue); + + generate(); + + auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, + nullptr, RecordRecoverable); + checkError( + "address size 0x09 of DW_LNE_set_address opcode at offset 0x00000038 is " + "unsupported", + std::move(Recoverable)); + ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); + ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); + EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); + // Show that the set address opcode is ignored in this case. + EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0); +} + TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) { if (!setupGenerator()) return; |