diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h @@ -69,8 +69,9 @@ /// Extracts an address-sized value and applies a relocation to the result if /// one exists for the given offset. - uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const { - return getRelocatedValue(getAddressSize(), Off, SecIx); + uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr, + Error *Err = nullptr) const { + return getRelocatedValue(getAddressSize(), Off, SecIx, Err); } uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx = nullptr) const { return getRelocatedValue(getAddressSize(), &getOffset(C), SecIx, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -749,17 +749,18 @@ if (Opcode == 0) { // Extended Opcodes always start with a zero opcode followed by // a uleb128 length so you can skip ones you don't know about - uint64_t Len = TableData.getULEB128(OffsetPtr); + Error Err = Error::success(); + uint64_t Len = TableData.getULEB128(OffsetPtr, &Err); uint64_t ExtOffset = *OffsetPtr; // Tolerate zero-length; assume length is correct and soldier on. - if (Len == 0) { + if (!Err && Len == 0) { if (OS) *OS << "Badly formed extended line op (length 0)\n"; continue; } - uint8_t SubOpcode = TableData.getU8(OffsetPtr); + uint8_t SubOpcode = TableData.getU8(OffsetPtr, &Err); if (OS) *OS << LNExtendedString(SubOpcode); switch (SubOpcode) { @@ -817,7 +818,7 @@ } else { TableData.setAddressSize(OpcodeAddressSize); State.Row.Address.Address = TableData.getRelocatedAddress( - OffsetPtr, &State.Row.Address.SectionIndex); + OffsetPtr, &State.Row.Address.SectionIndex, &Err); // Restore the address size if the extractor already had it. if (ExtractorAddressSize != 0) @@ -852,12 +853,12 @@ // the file register of the state machine. { FileNameEntry FileEntry; - const char *Name = TableData.getCStr(OffsetPtr); + const char *Name = TableData.getCStr(OffsetPtr, &Err); FileEntry.Name = DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name); - FileEntry.DirIdx = TableData.getULEB128(OffsetPtr); - FileEntry.ModTime = TableData.getULEB128(OffsetPtr); - FileEntry.Length = TableData.getULEB128(OffsetPtr); + FileEntry.DirIdx = TableData.getULEB128(OffsetPtr, &Err); + FileEntry.ModTime = TableData.getULEB128(OffsetPtr, &Err); + FileEntry.Length = TableData.getULEB128(OffsetPtr, &Err); Prologue.FileNames.push_back(FileEntry); if (OS) *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time=" @@ -867,13 +868,13 @@ break; case DW_LNE_set_discriminator: - State.Row.Discriminator = TableData.getULEB128(OffsetPtr); + State.Row.Discriminator = TableData.getULEB128(OffsetPtr, &Err); if (OS) *OS << " (" << State.Row.Discriminator << ")"; break; default: - if (OS) + if (!Err && OS) *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode) << format(" length %" PRIx64, Len); // Len doesn't include the zero opcode byte or the length itself, but @@ -883,16 +884,18 @@ } // Make sure the length as recorded in the table and the standard length // for the opcode match. If they don't, continue from the end as claimed - // by the table. + // by the table. Similarly, continue from the claimed end in the event of + // parsing error. uint64_t End = ExtOffset + Len; - if (*OffsetPtr != End) { + if (Err) + RecoverableErrorHandler(std::move(Err)); + else if (*OffsetPtr != End) RecoverableErrorHandler(createStringError( errc::illegal_byte_sequence, "unexpected line op length at offset 0x%8.8" PRIx64 " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64, ExtOffset, Len, *OffsetPtr - ExtOffset)); - *OffsetPtr = End; - } + *OffsetPtr = End; } else if (Opcode < Prologue.OpcodeBase) { if (OS) *OS << LNStandardString(Opcode); diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test @@ -279,6 +279,6 @@ # ALL-NEXT: warning: include directories table was not null terminated before the end of the prologue # ALL-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bf # ALL-NEXT: warning: file names table was not null terminated before the end of the prologue -# OTHER-NEXT: warning: unexpected line op length at offset 0x00000411 expected 0x09 found 0x01 +# OTHER-NEXT: warning: unexpected end of data at offset 0x412 # OTHER-NEXT: warning: last sequence in debug line table at offset 0x000003c9 is not terminated # ALL-NOT: warning: