ldrumm updated this revision to Diff 249663. ldrumm added a comment. I found similar unittests for other DWARF entries which allow me to check more about the parser state, so I went with Pavel's suggestion for the testcase
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75925/new/ https://reviews.llvm.org/D75925 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp Index: lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp +++ lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp @@ -18,6 +18,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h" #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h" +#include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" @@ -310,3 +311,34 @@ EXPECT_EQ("abbreviation declaration attribute list not terminated with a " "null entry", llvm::toString(std::move(error))); } + +TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) { + // This `.debug_aranges` table header is a valid 32bit big-endian section + // according to the DWARFv5 spec:6.2.1, but contains segment selectors which + // are not supported by lldb, and should be gracefully rejected + const unsigned char binary_data[] = { + 0, 0, 0, 41, // unit_length (length field not including this field itself) + 0, 2, // DWARF version number (half) + 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes of this test + 4, // address size + 1, // segment size + // alignment for the first tuple which "begins at an offset that is a + // multiple of the size of a single tuple". Tuples are nine bytes in this example. + 0, 0, 0, 0, 0, 0, + // BEGIN TUPLES + 1, 0, 0, 0, 4, 0, 0, 0, 1, // a 1byte object starting at address 4 in segment 1 + 0, 0, 0, 0, 4, 0, 0, 0, 1, // a 1byte object starting at address 4 in segment 0 + // END TUPLES + 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator + }; + DWARFDataExtractor data; + data.SetData(static_cast<const void *>(binary_data), sizeof binary_data, + lldb::ByteOrder::eByteOrderBig); + DWARFDebugArangeSet debug_aranges; + offset_t off = 0; + llvm::Error error = debug_aranges.extract(data, &off); + EXPECT_TRUE(bool(error)); + EXPECT_EQ("segmented arange entries are not supported", + llvm::toString(std::move(error))); + EXPECT_EQ(off, 12); // Parser should read no further than the segment size +} Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -63,7 +63,8 @@ // 1 - the version looks good // 2 - the address byte size looks plausible // 3 - the length seems to make sense - // size looks plausible + // 4 - size looks plausible + // 5 - the arange tuples do not contain a segment field if (m_header.version < 2 || m_header.version > 5) return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header version"); @@ -81,6 +82,10 @@ return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header length"); + if (m_header.seg_size) + return llvm::make_error<llvm::object::GenericBinaryError>( + "segmented arange entries are not supported"); + // The first tuple following the header in each set begins at an offset // that is a multiple of the size of a single tuple (that is, twice the // size of an address). The header is padded, if necessary, to the
Index: lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp +++ lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp @@ -18,6 +18,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h" #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h" +#include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" @@ -310,3 +311,34 @@ EXPECT_EQ("abbreviation declaration attribute list not terminated with a " "null entry", llvm::toString(std::move(error))); } + +TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) { + // This `.debug_aranges` table header is a valid 32bit big-endian section + // according to the DWARFv5 spec:6.2.1, but contains segment selectors which + // are not supported by lldb, and should be gracefully rejected + const unsigned char binary_data[] = { + 0, 0, 0, 41, // unit_length (length field not including this field itself) + 0, 2, // DWARF version number (half) + 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes of this test + 4, // address size + 1, // segment size + // alignment for the first tuple which "begins at an offset that is a + // multiple of the size of a single tuple". Tuples are nine bytes in this example. + 0, 0, 0, 0, 0, 0, + // BEGIN TUPLES + 1, 0, 0, 0, 4, 0, 0, 0, 1, // a 1byte object starting at address 4 in segment 1 + 0, 0, 0, 0, 4, 0, 0, 0, 1, // a 1byte object starting at address 4 in segment 0 + // END TUPLES + 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator + }; + DWARFDataExtractor data; + data.SetData(static_cast<const void *>(binary_data), sizeof binary_data, + lldb::ByteOrder::eByteOrderBig); + DWARFDebugArangeSet debug_aranges; + offset_t off = 0; + llvm::Error error = debug_aranges.extract(data, &off); + EXPECT_TRUE(bool(error)); + EXPECT_EQ("segmented arange entries are not supported", + llvm::toString(std::move(error))); + EXPECT_EQ(off, 12); // Parser should read no further than the segment size +} Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -63,7 +63,8 @@ // 1 - the version looks good // 2 - the address byte size looks plausible // 3 - the length seems to make sense - // size looks plausible + // 4 - size looks plausible + // 5 - the arange tuples do not contain a segment field if (m_header.version < 2 || m_header.version > 5) return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header version"); @@ -81,6 +82,10 @@ return llvm::make_error<llvm::object::GenericBinaryError>( "Invalid arange header length"); + if (m_header.seg_size) + return llvm::make_error<llvm::object::GenericBinaryError>( + "segmented arange entries are not supported"); + // The first tuple following the header in each set begins at an offset // that is a multiple of the size of a single tuple (that is, twice the // size of an address). The header is padded, if necessary, to the
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits