UBSan: crash less often on corrupted Vtables.

Summary:
This CL adds a weak check for a Vtable prefix: for a well-formed
Vtable, we require the prefix to be within [-1<<20; 1<<20].

Practically, this solves most of the known cases when UBSan segfaults
without providing any useful diagnostics.

Reviewers: pcc

Subscribers: kubabrecka

Differential Revision: http://reviews.llvm.org/D19750

llvm-svn: 271560
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc b/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
index 593b15e..d97ec48 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
+++ b/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
@@ -55,11 +55,17 @@
     << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
 
   // If possible, say what type it actually points to.
-  if (!DTI.isValid())
-    Diag(Pointer, DL_Note, "object has invalid vptr")
-        << TypeName(DTI.getMostDerivedTypeName())
-        << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
-  else if (!DTI.getOffset())
+  if (!DTI.isValid()) {
+    if (DTI.getOffset() < -VptrMaxOffsetToTop || DTI.getOffset() > VptrMaxOffsetToTop) {
+      Diag(Pointer, DL_Note, "object has a possibly invalid vptr: abs(offset to top) too big")
+          << TypeName(DTI.getMostDerivedTypeName())
+          << Range(Pointer, Pointer + sizeof(uptr), "possibly invalid vptr");
+    } else {
+      Diag(Pointer, DL_Note, "object has invalid vptr")
+          << TypeName(DTI.getMostDerivedTypeName())
+          << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
+    }
+  } else if (!DTI.getOffset())
     Diag(Pointer, DL_Note, "object is of type %0")
         << TypeName(DTI.getMostDerivedTypeName())
         << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");