aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
diff options
context:
space:
mode:
authorJames Henderson <james.henderson@sony.com>2020-02-03 16:43:03 +0000
committerJames Henderson <james.henderson@sony.com>2020-02-14 11:08:12 +0000
commitfe6983a75ae08dc63e2068f521670562ad77c599 (patch)
treeae4bf878e41791776233a0d4094a9fae617db51c /llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
parent9dc84e9b02d1e402503906099d42fbae4da7d8d9 (diff)
downloadllvm-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.cpp94
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 &LT = 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 &LT = 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 &LT = 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;