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 @@ -55,6 +55,9 @@ /// table in the .debug_rnglists section. class DWARFListTableHeader { struct Header { + // Perform basic validation of the header fields. + Error verify() const; + /// The total length of the entries for this table, not including the length /// field itself. uint64_t Length = 0; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp @@ -15,6 +15,20 @@ using namespace llvm; +Error DWARFListTableHeader::Header::verify() const { + if (Version != 5) + return createStringError(errc::invalid_argument, + "unrecognised version %" PRIu16, Version); + if (AddrSize != 4 && AddrSize != 8) + return createStringError(errc::not_supported, + "unsupported address size %" PRIu8, AddrSize); + if (SegSize != 0) + return createStringError(errc::not_supported, + "unsupported segment selector size %" PRIu8, + SegSize); + return Error::success(); +} + Error DWARFListTableHeader::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) { HeaderOffset = *OffsetPtr; @@ -48,22 +62,12 @@ HeaderData.SegSize = Data.getU8(OffsetPtr); HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr); - // Perform basic validation of the remaining header fields. - if (HeaderData.Version != 5) - return createStringError(errc::invalid_argument, - "unrecognised %s table version %" PRIu16 - " in table at offset 0x%" PRIx64, - SectionName.data(), HeaderData.Version, HeaderOffset); - if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8) - return createStringError(errc::not_supported, - "%s table at offset 0x%" PRIx64 - " has unsupported address size %" PRIu8, - SectionName.data(), HeaderOffset, HeaderData.AddrSize); - if (HeaderData.SegSize != 0) - return createStringError(errc::not_supported, - "%s table at offset 0x%" PRIx64 - " has unsupported segment selector size %" PRIu8, - SectionName.data(), HeaderOffset, HeaderData.SegSize); + Err = HeaderData.verify(); + if (Err) + return createStringError( + errc::invalid_argument, "parsing %s table at offset 0x%" PRIx64 ": %s", + SectionName.data(), HeaderOffset, toString(std::move(Err)).c_str()); + if (End < HeaderOffset + getHeaderSize(Format) + HeaderData.OffsetEntryCount * OffsetByteSize) return createStringError(errc::invalid_argument, diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s @@ -26,9 +26,9 @@ # CHECK-NOT: error: # CHECK: error: .debug_rnglists table at offset 0x22 has too small length (0xb) to contain a complete header -# CHECK-NEXT: error: unrecognised .debug_rnglists table version 4 in table at offset 0x2d -# CHECK-NEXT: error: .debug_rnglists table at offset 0x39 has unsupported address size 2 -# CHECK-NEXT: error: .debug_rnglists table at offset 0x45 has unsupported segment selector size 4 +# CHECK-NEXT: error: parsing .debug_rnglists table at offset 0x2d: unrecognised version 4 +# CHECK-NEXT: error: parsing .debug_rnglists table at offset 0x39: unsupported address size 2 +# CHECK-NEXT: error: parsing .debug_rnglists table at offset 0x45: unsupported segment selector size 4 # CHECK-NEXT: error: .debug_rnglists table at offset 0x51 has more offset entries (12345678) than there is space for # CHECK-NEXT: error: read past end of table when reading DW_RLE_start_end encoding at offset 0x69 # CHECK-NEXT: error: read past end of table when reading DW_RLE_start_length encoding at offset 0x82