summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorPaul Robinson <paul.robinson@sony.com>2017-11-22 15:14:49 +0000
committerPaul Robinson <paul.robinson@sony.com>2017-11-22 15:14:49 +0000
commita513cc4aa1fa4e0e6a0c3c427e408ad42e2947c7 (patch)
treefec23ed676af4b8476d0947fa7c2198b29f933d1 /lib/DebugInfo
parent72bc6f1e396bd737764e7c35fbef7e4fbe70526d (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.cpp29
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);