diff options
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h | 4 | ||||
-rw-r--r-- | llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coff | bin | 0 -> 20396 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-readobj/codeview-vftable.test | 51 |
4 files changed, 58 insertions, 2 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index e13c1496e7b..bab18f247d0 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -78,8 +78,11 @@ public: /// Visits the type records in Data. Sets the error flag on parse failures. void visitTypeStream(ArrayRef<uint8_t> Data) { - for (const auto &I : makeTypeRange(Data)) + for (const auto &I : makeTypeRange(Data)) { visitTypeRecord(I); + if (hadError()) + break; + } } /// Action to take on unknown types. By default, they are ignored. diff --git a/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h index 4f429307f91..3596360d5bc 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h +++ b/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h @@ -14,6 +14,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include <cinttypes> #include <tuple> @@ -113,7 +114,8 @@ template <typename T> struct serialize_array_tail_impl { std::error_code deserialize(ArrayRef<uint8_t> &Data) const { T Field; - while (!Data.empty()) { + // Stop when we run out of bytes or we hit record padding bytes. + while (!Data.empty() && Data.front() < LF_PAD0) { if (auto EC = consume(Data, Field)) return EC; Item.push_back(Field); diff --git a/llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coff b/llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coff Binary files differnew file mode 100644 index 00000000000..388a7212eb2 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coff diff --git a/llvm/test/tools/llvm-readobj/codeview-vftable.test b/llvm/test/tools/llvm-readobj/codeview-vftable.test new file mode 100644 index 00000000000..4091ccacf78 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/codeview-vftable.test @@ -0,0 +1,51 @@ +; The following two object files were generated using the following command: +; $ cl /Z7 /c t.cpp +; The contents of t.cpp follow: +; struct A { +; virtual void f(); +; }; +; struct B { +; virtual void f(); +; virtual void g(); +; }; +; struct C { +; virtual void f(); +; virtual void g(); +; virtual void h(); +; }; +; A a; +; B b; +; C c; + +RUN: llvm-readobj -codeview %p/Inputs/codeview-vftable.obj.coff | FileCheck %s + +CHECK: VFTableType { +CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D) +CHECK-NEXT: TypeIndex: 0x10F0 +CHECK-NEXT: CompleteClass: A +CHECK-NEXT: OverriddenVFTable: 0x0 +CHECK-NEXT: VFPtrOffset: 0x0 +CHECK-NEXT: VFTableName: ??_7A@@6B@ +CHECK-NEXT: MethodName: ?f@A@@UEAAXXZ +CHECK-NEXT: } +CHECK-NEXT: VFTableType { +CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D) +CHECK-NEXT: TypeIndex: 0x10F1 +CHECK-NEXT: CompleteClass: B +CHECK-NEXT: OverriddenVFTable: ??_7A@@6B@ (0x10F0) +CHECK-NEXT: VFPtrOffset: 0x0 +CHECK-NEXT: VFTableName: ??_7B@@6B@ +CHECK-NEXT: MethodName: ?f@B@@UEAAXXZ +CHECK-NEXT: MethodName: ?g@B@@UEAAXXZ +CHECK-NEXT: } +CHECK-NEXT: VFTableType { +CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D) +CHECK-NEXT: TypeIndex: 0x10F2 +CHECK-NEXT: CompleteClass: C +CHECK-NEXT: OverriddenVFTable: ??_7B@@6B@ (0x10F1) +CHECK-NEXT: VFPtrOffset: 0x0 +CHECK-NEXT: VFTableName: ??_7C@@6B@ +CHECK-NEXT: MethodName: ?f@C@@UEAAXXZ +CHECK-NEXT: MethodName: ?g@C@@UEAAXXZ +CHECK-NEXT: MethodName: ?h@C@@UEAAXXZ +CHECK-NEXT: } |