From 216796f234c757b832898adec28d5d523c80dce2 Mon Sep 17 00:00:00 2001 From: James Henderson Date: Tue, 7 Jan 2020 10:21:20 +0000 Subject: [DebugInfo] Fix infinite loop caused by reading past debug_line end If the claimed unit length of a debug line program is such that the line table would finish past the end of the .debug_line section, an infinite loop occurs because the data extractor will continue to "read" zeroes without changing the offset. This previously didn't hit an error because the line table program handles a series of zeroes as a bad extended opcode. This patch fixes the inifinite loop and adds a warning if the program doesn't fit in the available data. Reviewed by: JDevlieghere Differential Revision: https://reviews.llvm.org/D72279 --- .../DebugInfo/DWARF/DWARFDebugLineTest.cpp | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'llvm/unittests/DebugInfo') diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp index b38e8dfcacc..f29709442d4 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -438,6 +438,35 @@ TEST_F(DebugLineBasicFixture, ErrorForInvalidExtendedOpcodeLength) { "0x00000030 expected 0x02 found 0x01"); } +TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) { + if (!setupGenerator()) + return; + + LineTable &Padding = Gen->addLineTable(); + // Add some padding to show that a non-zero offset is handled correctly. + Padding.setCustomPrologue({{0, LineTable::Byte}}); + LineTable < = Gen->addLineTable(); + LT.addStandardOpcode(DW_LNS_copy, {}); + LT.addStandardOpcode(DW_LNS_const_add_pc, {}); + LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); + DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); + // Set the total length to 1 higher than the actual length. The program body + // has size 5. + Prologue.TotalLength += 6; + LT.setPrologue(Prologue); + + generate(); + + auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 1, *Context, + nullptr, RecordRecoverable); + checkError("line table program with offset 0x00000001 has length 0x00000034 " + "but only 0x00000033 bytes are available", + std::move(Recoverable)); + ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); + EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 2u); + EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); +} + TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) { if (!setupGenerator()) return; -- cgit v1.2.3