diff --git a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s --- a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s +++ b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s @@ -2,6 +2,7 @@ # RUN: -split-dwarf-file=%t.dwo -dwarf-version=5 # RUN: not llvm-dwp %t.dwo -o %t.dwp 2>&1 | FileCheck %s -# CHECK: error: Cannot parse compile unit length: unexpected end of data at offset 0x2 while reading [0x0, 0x4 - .section .debug_info.dwo,"e",@progbits - .short 0 # Length of Unit +# CHECK: error: compile unit header exceeds .debug_info section range: 20 >= 6 + .section .debug_info.dwo,"e",@progbits + .long 16 # Length of Unit + .short 5 # Version \ No newline at end of file diff --git a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length_type.s copy from llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s copy to llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length_type.s --- a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s +++ b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length_type.s @@ -2,6 +2,6 @@ # RUN: -split-dwarf-file=%t.dwo -dwarf-version=5 # RUN: not llvm-dwp %t.dwo -o %t.dwp 2>&1 | FileCheck %s -# CHECK: error: Cannot parse compile unit length: unexpected end of data at offset 0x2 while reading [0x0, 0x4 - .section .debug_info.dwo,"e",@progbits - .short 0 # Length of Unit +# CHECK: error: cannot parse compile unit length: unexpected end of data at offset 0x2 while reading [0x0, 0x4 + .section .debug_info.dwo,"e",@progbits + .short 0 # Length of Unit diff --git a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_unittype.s b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_unittype.s deleted file mode 100644 --- a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_unittype.s +++ /dev/null @@ -1,8 +0,0 @@ -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o \ -# RUN: -split-dwarf-file=%t.dwo -dwarf-version=5 -# RUN: not llvm-dwp %t.dwo -o %t.dwp 2>&1 | FileCheck %s - -# CHECK: error: Cannot parse compile unit header: unexpected end of data at offset 0x6 while reading [0x6, 0x7) - .section .debug_info.dwo,"e",@progbits - .long 2 # Length of Unit - .short 5 diff --git a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_version.s b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_version.s --- a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_version.s +++ b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_version.s @@ -2,6 +2,6 @@ # RUN: -split-dwarf-file=%t.dwo -dwarf-version=5 # RUN: not llvm-dwp %t.dwo -o %t.dwp 2>&1 | FileCheck %s -# CHECK: error: Cannot parse compile unit version: unexpected end of data at offset 0x4 while reading [0x4, 0x6) - .section .debug_info.dwo,"e",@progbits - .long 0 # Length of Unit +# CHECK: error: cannot parse compile unit version: unexpected end of data at offset 0x4 while reading [0x4, 0x6) + .section .debug_info.dwo,"e",@progbits + .long 0 # Length of Unit diff --git a/llvm/test/tools/llvm-dwp/X86/invalid_string_form.test b/llvm/test/tools/llvm-dwp/X86/invalid_string_form.test --- a/llvm/test/tools/llvm-dwp/X86/invalid_string_form.test +++ b/llvm/test/tools/llvm-dwp/X86/invalid_string_form.test @@ -1,4 +1,3 @@ -RUN: not llvm-dwp %p/../Inputs/invalid_string_form.dwo -o %t 2>&1 | xargs echo RUN: not llvm-dwp %p/../Inputs/invalid_string_form.dwo -o %t 2>&1 | FileCheck %s CHECK: error: {{.*}}: string field must be encoded with one of the following: diff --git a/llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s b/llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s --- a/llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s +++ b/llvm/test/tools/llvm-dwp/X86/unsupported_cu_index_version.s @@ -2,9 +2,6 @@ # RUN: not llvm-dwp %t.dwp -o %t 2>&1 | FileCheck %s # CHECK: error: unsupported cu_index version: 5 (only version 2 is supported) - -## To reach the test point, no real data is needed in .debug_info.dwo, -## but the section should not be empty. .section .debug_info.dwo, "e", @progbits .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit .Ldebug_info_dwo_start0: diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -117,12 +117,35 @@ std::tie(Header.Length, Header.Format) = InfoData.getInitialLength(&Offset, &Err); if (Err) - return make_error("Cannot parse compile unit length: " + - llvm::toString(std::move(Err)) + "\n"); + return make_error("cannot parse compile unit length: " + + llvm::toString(std::move(Err))); + + if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) { + return make_error( + "compile unit header exceeds .debug_info section range: " + + utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size())); + } + Header.Version = InfoData.getU16(&Offset, &Err); if (Err) - return make_error("Cannot parse compile unit version: " + - llvm::toString(std::move(Err)) + "\n"); + return make_error("cannot parse compile unit version: " + + llvm::toString(std::move(Err))); + + uint64_t MinHeaderLength; + if (Header.Version >= 5) { + // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4), + // Signature (8) + MinHeaderLength = 16; + } else { + // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1) + MinHeaderLength = 7; + } + if (Header.Length < MinHeaderLength) { + return make_error( + "compile unit length is too small: expected at least " + + utostr(MinHeaderLength) + " got " + utostr(Header.Length) + "."); + } + if (Header.Version >= 5) { Header.UnitType = InfoData.getU8(&Offset, &Err); Header.AddrSize = InfoData.getU8(&Offset, &Err); @@ -134,9 +157,8 @@ Header.DebugAbbrevOffset = InfoData.getU32(&Offset, &Err); Header.AddrSize = InfoData.getU8(&Offset, &Err); } - if (Err) - return make_error("Cannot parse compile unit header: " + - llvm::toString(std::move(Err)) + "\n"); + assert(!Err && "Compile unit header is missing fields"); + Header.HeaderSize = Offset; return Header; }