summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h5
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h4
-rw-r--r--llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coffbin0 -> 20396 bytes
-rw-r--r--llvm/test/tools/llvm-readobj/codeview-vftable.test51
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
new file mode 100644
index 00000000000..388a7212eb2
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/Inputs/codeview-vftable.obj.coff
Binary files differ
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: }
OpenPOWER on IntegriCloud