diff options
author | Paul Robinson <paul.robinson@sony.com> | 2017-11-22 15:14:49 +0000 |
---|---|---|
committer | Paul Robinson <paul.robinson@sony.com> | 2017-11-22 15:14:49 +0000 |
commit | a513cc4aa1fa4e0e6a0c3c427e408ad42e2947c7 (patch) | |
tree | fec23ed676af4b8476d0947fa7c2198b29f933d1 /lib/DebugInfo | |
parent | 72bc6f1e396bd737764e7c35fbef7e4fbe70526d (diff) |
[DWARF] Fix handling of extended line-number opcodes
Differential Revision: https://reviews.llvm.org/D40200
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318838 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index c99c7a9277e..1753d57ada6 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -427,9 +427,15 @@ bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData, 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 - uint32_t ExtOffset = *OffsetPtr; uint64_t Len = DebugLineData.getULEB128(OffsetPtr); - uint32_t ArgSize = Len - (*OffsetPtr - ExtOffset); + uint32_t ExtOffset = *OffsetPtr; + + // Tolerate zero-length; assume length is correct and soldier on. + if (Len == 0) { + if (OS) + *OS << "Badly formed extended line op (length 0)\n"; + continue; + } uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr); if (OS) @@ -508,11 +514,24 @@ bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData, break; default: - // Length doesn't include the zero opcode byte or the length itself, but - // it does include the sub_opcode, so we have to adjust for that below - (*OffsetPtr) += ArgSize; + if (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 + // it does include the sub_opcode, so we have to adjust for that. + (*OffsetPtr) += Len - 1; break; } + // Make sure the stated and parsed lengths are the same. + // Otherwise we have an unparseable line-number program. + if (*OffsetPtr - ExtOffset != Len) { + fprintf(stderr, "Unexpected line op length at offset 0x%8.8" PRIx32 + " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32 "\n", + ExtOffset, Len, *OffsetPtr - ExtOffset); + // Skip the rest of the line-number program. + *OffsetPtr = EndOffset; + return false; + } } else if (Opcode < Prologue.OpcodeBase) { if (OS) *OS << LNStandardString(Opcode); |