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 | e0833349b61eec11a27cb2f831836f852a4712a4 (patch) | |
tree | 9bae1b2e75ed090596a459db97075b3561814587 /llvm/lib | |
parent | 891c7fb19daad97e34b2f7742ac03403930722f7 (diff) | |
download | bcm5719-llvm-e0833349b61eec11a27cb2f831836f852a4712a4.tar.gz bcm5719-llvm-e0833349b61eec11a27cb2f831836f852a4712a4.zip |
[DWARF] Fix handling of extended line-number opcodes
Differential Revision: https://reviews.llvm.org/D40200
llvm-svn: 318838
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index c99c7a9277e..1753d57ada6 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/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); |