diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h @@ -113,7 +113,7 @@ void dump(DataExtractor Data, raw_ostream &OS, DIDumpOptions DumpOpts = {}) const; Optional getOffsetEntry(DataExtractor Data, uint32_t Index) const { - if (Index > HeaderData.OffsetEntryCount) + if (Index >= HeaderData.OffsetEntryCount) return None; return getOffsetEntry(Data, getHeaderOffset() + getHeaderSize(Format), Format, Index); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp @@ -73,4 +73,30 @@ EXPECT_EQ(Header.length(), 6u); } +TEST(DWARFListTableHeader, OffsetEntryCount) { + static const char SecData[] = "\x10\x00\x00\x00" // Length + "\x05\x00" // Version + "\x08" // Address size + "\x00" // Segment selector size + "\x01\x00\x00\x00" // Offset entry count + "\x04\x00\x00\x00" // offset[0] + "\x04" // DW_RLE_offset_pair + "\x01" // ULEB128 starting offset + "\x02" // ULEB128 ending offset + "\x00"; // DW_RLE_end_of_list + DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1), + /*isLittleEndian=*/true, + /*AddrSize=*/4); + DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists", + /*ListTypeString=*/"range"); + uint64_t Offset = 0; + EXPECT_FALSE(!!Header.extract(Extractor, &Offset)); + Optional Offset0 = Header.getOffsetEntry(Extractor, 0); + EXPECT_TRUE(!!Offset0); + EXPECT_EQ(*Offset0, uint64_t(4)); + Optional Offset1 = Header.getOffsetEntry(Extractor, 1); + EXPECT_FALSE(!!Offset1); + EXPECT_EQ(Header.length(), sizeof(SecData) - 1); +} + } // end anonymous namespace