[compiler-rt] r241745 - CFI: Get check-cfi passing on Windows.
Peter Collingbourne
peter at pcc.me.uk
Wed Jul 8 15:10:35 PDT 2015
Author: pcc
Date: Wed Jul 8 17:10:34 2015
New Revision: 241745
URL: http://llvm.org/viewvc/llvm-project?rev=241745&view=rev
Log:
CFI: Get check-cfi passing on Windows.
Specifically:
- Start using %expect_crash.
- Provide an implementation of __ubsan::getDynamicTypeInfoFromVtable
for the Microsoft C++ ABI. This is all that is needed for CFI
diagnostics; UBSan's -fsanitize=vptr also requires an implementation of
__ubsan::checkDynamicType.
- Build the sanitizer runtimes against the release version of the C
runtime, even in debug builds.
- Accommodate demangling differences in tests.
Differential Revision: http://reviews.llvm.org/D11029
Added:
compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
- copied, changed from r241571, compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
Modified:
compiler-rt/trunk/CMakeLists.txt
compiler-rt/trunk/lib/ubsan/CMakeLists.txt
compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
compiler-rt/trunk/lib/ubsan/ubsan_diag.h
compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
compiler-rt/trunk/test/cfi/CMakeLists.txt
compiler-rt/trunk/test/cfi/anon-namespace.cpp
compiler-rt/trunk/test/cfi/bad-cast.cpp
compiler-rt/trunk/test/cfi/multiple-inheritance.cpp
compiler-rt/trunk/test/cfi/nvcall.cpp
compiler-rt/trunk/test/cfi/overwrite.cpp
compiler-rt/trunk/test/cfi/sibling.cpp
compiler-rt/trunk/test/cfi/simple-fail.cpp
compiler-rt/trunk/test/cfi/vdtor.cpp
compiler-rt/trunk/test/lit.common.cfg
compiler-rt/trunk/test/ubsan/lit.common.cfg
Modified: compiler-rt/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/CMakeLists.txt (original)
+++ compiler-rt/trunk/CMakeLists.txt Wed Jul 8 17:10:34 2015
@@ -213,17 +213,16 @@ append_list_if(COMPILER_RT_HAS_FNO_FUNCT
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
if(MSVC)
- # Replace the /MD[d] flags with /MT.
+ # Replace the /M[DT][d] flags with /MT, and strip any definitions of _DEBUG,
+ # which cause definition mismatches at link time.
# FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214.
if(COMPILER_RT_HAS_MT_FLAG)
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
- if(${flag_var} MATCHES "/MD")
- string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
- elseif(${flag_var} MATCHES "/MDd")
- string(REGEX REPLACE "/MDd" "/MT" ${flag_var} "${${flag_var}}")
- endif()
+ string(REGEX REPLACE "/M[DT]d" "/MT" ${flag_var} "${${flag_var}}")
+ string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+ string(REGEX REPLACE "/D_DEBUG" "" ${flag_var} "${${flag_var}}")
endforeach()
endif()
append_list_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS)
@@ -333,9 +332,6 @@ if(APPLE AND SANITIZER_MIN_OSX_VERSION V
# Mac OS X prior to 10.9 had problems with exporting symbols from
# libc++/libc++abi.
set(SANITIZER_CAN_USE_CXXABI FALSE)
-elseif(WIN32)
- # We do not currently support the Microsoft C++ ABI.
- set(SANITIZER_CAN_USE_CXXABI FALSE)
else()
set(SANITIZER_CAN_USE_CXXABI TRUE)
endif()
Modified: compiler-rt/trunk/lib/ubsan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/ubsan/CMakeLists.txt Wed Jul 8 17:10:34 2015
@@ -15,6 +15,8 @@ set(UBSAN_STANDALONE_SOURCES
set(UBSAN_CXX_SOURCES
ubsan_handlers_cxx.cc
ubsan_type_hash.cc
+ ubsan_type_hash_itanium.cc
+ ubsan_type_hash_win.cc
)
include_directories(..)
Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Wed Jul 8 17:10:34 2015
@@ -165,8 +165,12 @@ static void renderText(const char *Messa
case Diag::AK_String:
Printf("%s", A.String);
break;
- case Diag::AK_Mangled: {
- Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));
+ case Diag::AK_TypeName: {
+ if (SANITIZER_WINDOWS)
+ // The Windows implementation demangles names early.
+ Printf("'%s'", A.String);
+ else
+ Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));
break;
}
case Diag::AK_SInt:
Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.h?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.h Wed Jul 8 17:10:34 2015
@@ -113,11 +113,11 @@ public:
const char *getText() const { return Text; }
};
-/// \brief A mangled C++ name. Really just a strong typedef for 'const char*'.
-class MangledName {
+/// \brief A C++ type name. Really just a strong typedef for 'const char*'.
+class TypeName {
const char *Name;
public:
- MangledName(const char *Name) : Name(Name) {}
+ TypeName(const char *Name) : Name(Name) {}
const char *getName() const { return Name; }
};
@@ -141,7 +141,7 @@ public:
/// Kinds of arguments, corresponding to members of \c Arg's union.
enum ArgKind {
AK_String, ///< A string argument, displayed as-is.
- AK_Mangled,///< A C++ mangled name, demangled before display.
+ AK_TypeName,///< A C++ type name, possibly demangled before display.
AK_UInt, ///< An unsigned integer argument.
AK_SInt, ///< A signed integer argument.
AK_Float, ///< A floating-point argument.
@@ -152,7 +152,7 @@ public:
struct Arg {
Arg() {}
Arg(const char *String) : Kind(AK_String), String(String) {}
- Arg(MangledName MN) : Kind(AK_Mangled), String(MN.getName()) {}
+ Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}
Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
Arg(SIntMax SInt) : Kind(AK_SInt), SInt(SInt) {}
Arg(FloatMax Float) : Kind(AK_Float), Float(Float) {}
@@ -202,7 +202,7 @@ public:
~Diag();
Diag &operator<<(const char *Str) { return AddArg(Str); }
- Diag &operator<<(MangledName MN) { return AddArg(MN); }
+ Diag &operator<<(TypeName TN) { return AddArg(TN); }
Diag &operator<<(unsigned long long V) { return AddArg(UIntMax(V)); }
Diag &operator<<(const void *V) { return AddArg(V); }
Diag &operator<<(const TypeDescriptor &V);
Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Wed Jul 8 17:10:34 2015
@@ -54,19 +54,19 @@ static void HandleDynamicTypeCacheMiss(
// If possible, say what type it actually points to.
if (!DTI.isValid())
Diag(Pointer, DL_Note, "object has invalid vptr")
- << MangledName(DTI.getMostDerivedTypeName())
+ << TypeName(DTI.getMostDerivedTypeName())
<< Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
else if (!DTI.getOffset())
Diag(Pointer, DL_Note, "object is of type %0")
- << MangledName(DTI.getMostDerivedTypeName())
+ << TypeName(DTI.getMostDerivedTypeName())
<< Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
else
// FIXME: Find the type at the specified offset, and include that
// in the note.
Diag(Pointer - DTI.getOffset(), DL_Note,
"object is base class subobject at offset %0 within object of type %1")
- << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
- << MangledName(DTI.getSubobjectTypeName())
+ << DTI.getOffset() << TypeName(DTI.getMostDerivedTypeName())
+ << TypeName(DTI.getSubobjectTypeName())
<< Range(Pointer, Pointer + sizeof(uptr),
"vptr for %2 base class of %1");
}
@@ -104,7 +104,7 @@ static void HandleCFIBadType(CFIBadTypeD
Diag(Vtable, DL_Note, "invalid vtable");
else
Diag(Vtable, DL_Note, "vtable is of type %0")
- << MangledName(DTI.getMostDerivedTypeName());
+ << TypeName(DTI.getMostDerivedTypeName());
}
void __ubsan::__ubsan_handle_cfi_bad_type(CFIBadTypeData *Data,
Modified: compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc Wed Jul 8 17:10:34 2015
@@ -11,6 +11,9 @@
// relationships. This file is only linked into C++ compilations, and is
// permitted to use language features which require a C++ ABI library.
//
+// Most of the implementation lives in an ABI-specific source file
+// (ubsan_type_hash_{itanium,win}.cc).
+//
//===----------------------------------------------------------------------===//
#include "ubsan_platform.h"
@@ -19,243 +22,13 @@
#include "sanitizer_common/sanitizer_common.h"
-// The following are intended to be binary compatible with the definitions
-// given in the Itanium ABI. We make no attempt to be ODR-compatible with
-// those definitions, since existing ABI implementations aren't.
-
-namespace std {
- class type_info {
- public:
- virtual ~type_info();
-
- const char *__type_name;
- };
-}
-
-namespace __cxxabiv1 {
-
-/// Type info for classes with no bases, and base class for type info for
-/// classes with bases.
-class __class_type_info : public std::type_info {
- ~__class_type_info() override;
-};
-
-/// Type info for classes with simple single public inheritance.
-class __si_class_type_info : public __class_type_info {
-public:
- ~__si_class_type_info() override;
-
- const __class_type_info *__base_type;
-};
-
-class __base_class_type_info {
-public:
- const __class_type_info *__base_type;
- long __offset_flags;
-
- enum __offset_flags_masks {
- __virtual_mask = 0x1,
- __public_mask = 0x2,
- __offset_shift = 8
- };
-};
-
-/// Type info for classes with multiple, virtual, or non-public inheritance.
-class __vmi_class_type_info : public __class_type_info {
-public:
- ~__vmi_class_type_info() override;
-
- unsigned int flags;
- unsigned int base_count;
- __base_class_type_info base_info[1];
-};
-
-}
-
-namespace abi = __cxxabiv1;
-
-// We implement a simple two-level cache for type-checking results. For each
-// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
-// unique; if it collides, we will get false negatives, but:
-// * such a collision would have to occur on the *first* bad access,
-// * the probability of such a collision is low (and for a 64-bit target, is
-// negligible), and
-// * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
-// give better coverage.
-//
-// The first caching layer is a small hash table with no chaining; buckets are
-// reused as needed. The second caching layer is a large hash table with open
-// chaining. We can freely evict from either layer since this is just a cache.
-//
-// FIXME: Make these hash table accesses thread-safe. The races here are benign:
-// assuming the unsequenced loads and stores don't misbehave too badly,
-// the worst case is false negatives or poor cache behavior, not false
-// positives or crashes.
-
-/// Find a bucket to store the given hash value in.
-static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
- static const unsigned HashTableSize = 65537;
- static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];
-
- unsigned First = (V & 65535) ^ 1;
- unsigned Probe = First;
- for (int Tries = 5; Tries; --Tries) {
- if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
- return &__ubsan_vptr_hash_set[Probe];
- Probe += ((V >> 16) & 65535) + 1;
- if (Probe >= HashTableSize)
- Probe -= HashTableSize;
- }
- // FIXME: Pick a random entry from the probe sequence to evict rather than
- // just taking the first.
- return &__ubsan_vptr_hash_set[First];
-}
-
/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
__ubsan::HashValue
__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
-/// \brief Determine whether \p Derived has a \p Base base class subobject at
-/// offset \p Offset.
-static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
- const abi::__class_type_info *Base,
- sptr Offset) {
- if (Derived->__type_name == Base->__type_name)
- return Offset == 0;
-
- if (const abi::__si_class_type_info *SI =
- dynamic_cast<const abi::__si_class_type_info*>(Derived))
- return isDerivedFromAtOffset(SI->__base_type, Base, Offset);
-
- const abi::__vmi_class_type_info *VTI =
- dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
- if (!VTI)
- // No base class subobjects.
- return false;
-
- // Look for a base class which is derived from \p Base at the right offset.
- for (unsigned int base = 0; base != VTI->base_count; ++base) {
- // FIXME: Curtail the recursion if this base can't possibly contain the
- // given offset.
- sptr OffsetHere = VTI->base_info[base].__offset_flags >>
- abi::__base_class_type_info::__offset_shift;
- if (VTI->base_info[base].__offset_flags &
- abi::__base_class_type_info::__virtual_mask)
- // For now, just punt on virtual bases and say 'yes'.
- // FIXME: OffsetHere is the offset in the vtable of the virtual base
- // offset. Read the vbase offset out of the vtable and use it.
- return true;
- if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
- Base, Offset - OffsetHere))
- return true;
- }
-
- return false;
-}
-
-/// \brief Find the derived-most dynamic base class of \p Derived at offset
-/// \p Offset.
-static const abi::__class_type_info *findBaseAtOffset(
- const abi::__class_type_info *Derived, sptr Offset) {
- if (!Offset)
- return Derived;
-
- if (const abi::__si_class_type_info *SI =
- dynamic_cast<const abi::__si_class_type_info*>(Derived))
- return findBaseAtOffset(SI->__base_type, Offset);
-
- const abi::__vmi_class_type_info *VTI =
- dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
- if (!VTI)
- // No base class subobjects.
- return 0;
-
- for (unsigned int base = 0; base != VTI->base_count; ++base) {
- sptr OffsetHere = VTI->base_info[base].__offset_flags >>
- abi::__base_class_type_info::__offset_shift;
- if (VTI->base_info[base].__offset_flags &
- abi::__base_class_type_info::__virtual_mask)
- // FIXME: Can't handle virtual bases yet.
- continue;
- if (const abi::__class_type_info *Base =
- findBaseAtOffset(VTI->base_info[base].__base_type,
- Offset - OffsetHere))
- return Base;
- }
-
- return 0;
-}
-
-namespace {
-
-struct VtablePrefix {
- /// The offset from the vptr to the start of the most-derived object.
- /// This should never be greater than zero, and will usually be exactly
- /// zero.
- sptr Offset;
- /// The type_info object describing the most-derived class type.
- std::type_info *TypeInfo;
-};
-VtablePrefix *getVtablePrefix(void *Vtable) {
- VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
- if (!Vptr)
- return 0;
- VtablePrefix *Prefix = Vptr - 1;
- if (Prefix->Offset > 0 || !Prefix->TypeInfo)
- // This can't possibly be a valid vtable.
- return 0;
- return Prefix;
-}
-
-}
-
-bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
- // A crash anywhere within this function probably means the vptr is corrupted.
- // FIXME: Perform these checks more cautiously.
-
- // Check whether this is something we've evicted from the cache.
- HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
- if (*Bucket == Hash) {
- __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
- return true;
- }
-
- void *VtablePtr = *reinterpret_cast<void **>(Object);
- VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
- if (!Vtable)
- return false;
-
- // Check that this is actually a type_info object for a class type.
- abi::__class_type_info *Derived =
- dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
- if (!Derived)
- return false;
-
- abi::__class_type_info *Base = (abi::__class_type_info*)Type;
- if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
- return false;
-
- // Success. Cache this result.
- __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
- *Bucket = Hash;
- return true;
-}
-
__ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfoFromObject(void *Object) {
void *VtablePtr = *reinterpret_cast<void **>(Object);
return getDynamicTypeInfoFromVtable(VtablePtr);
}
-__ubsan::DynamicTypeInfo
-__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
- VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
- if (!Vtable)
- return DynamicTypeInfo(0, 0, 0);
- const abi::__class_type_info *ObjectType = findBaseAtOffset(
- static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
- -Vtable->Offset);
- return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
- ObjectType ? ObjectType->__type_name : "<unknown>");
-}
-
#endif // CAN_SANITIZE_UB
Copied: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc (from r241571, compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc?p2=compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc&p1=compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc&r1=241571&r2=241745&rev=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc Wed Jul 8 17:10:34 2015
@@ -1,4 +1,4 @@
-//===-- ubsan_type_hash.cc ------------------------------------------------===//
+//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,13 @@
//
//===----------------------------------------------------------------------===//
//
-// Implementation of a hash table for fast checking of inheritance
-// relationships. This file is only linked into C++ compilations, and is
-// permitted to use language features which require a C++ ABI library.
+// Implementation of type hashing/lookup for Itanium C++ ABI.
//
//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
-#if CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB && !SANITIZER_WINDOWS
#include "ubsan_type_hash.h"
#include "sanitizer_common/sanitizer_common.h"
@@ -111,10 +110,6 @@ static __ubsan::HashValue *getTypeCacheH
return &__ubsan_vptr_hash_set[First];
}
-/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
-__ubsan::HashValue
-__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
-
/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
@@ -241,11 +236,6 @@ bool __ubsan::checkDynamicType(void *Obj
return true;
}
-__ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfoFromObject(void *Object) {
- void *VtablePtr = *reinterpret_cast<void **>(Object);
- return getDynamicTypeInfoFromVtable(VtablePtr);
-}
-
__ubsan::DynamicTypeInfo
__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
@@ -258,4 +248,4 @@ __ubsan::getDynamicTypeInfoFromVtable(vo
ObjectType ? ObjectType->__type_name : "<unknown>");
}
-#endif // CAN_SANITIZE_UB
+#endif // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
Added: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc?rev=241745&view=auto
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc (added)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc Wed Jul 8 17:10:34 2015
@@ -0,0 +1,72 @@
+//===-- ubsan_type_hash_win.cc --------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of type hashing/lookup for Microsoft C++ ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_platform.h"
+#include "ubsan_platform.h"
+#if CAN_SANITIZE_UB && SANITIZER_WINDOWS
+#include "ubsan_type_hash.h"
+
+#include "sanitizer_common/sanitizer_common.h"
+
+#include <typeinfo>
+#include <windows.h>
+
+struct CompleteObjectLocator {
+ int is_image_relative;
+ int offset_to_top;
+ int vfptr_offset;
+};
+
+bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
+ // FIXME: Implement.
+ return false;
+}
+
+__ubsan::DynamicTypeInfo
+__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
+ // The virtual table may not have a complete object locator if the object
+ // was compiled without RTTI (i.e. we might be reading from some other global
+ // laid out before the virtual table), so we need to carefully validate each
+ // pointer dereference and perform sanity checks.
+ CompleteObjectLocator **obj_locator_ptr =
+ ((CompleteObjectLocator**)VtablePtr)-1;
+ if (!IsAccessibleMemoryRange((uptr)obj_locator_ptr, sizeof(void*)))
+ return DynamicTypeInfo(0, 0, 0);
+
+ CompleteObjectLocator *obj_locator = *obj_locator_ptr;
+ if (!IsAccessibleMemoryRange((uptr)obj_locator,
+ sizeof(CompleteObjectLocator)+sizeof(void*)))
+ return DynamicTypeInfo(0, 0, 0);
+
+ std::type_info *tinfo;
+ if (obj_locator->is_image_relative == 1) {
+ MEMORY_BASIC_INFORMATION mbi;
+ VirtualQuery(obj_locator, &mbi, sizeof(mbi));
+ tinfo = (std::type_info*)(*(int*)(obj_locator+1) +
+ (char*)mbi.AllocationBase);
+ } else if (obj_locator->is_image_relative == 0)
+ tinfo = *(std::type_info**)(obj_locator+1);
+ else
+ // Probably not a complete object locator.
+ return DynamicTypeInfo(0, 0, 0);
+
+ if (!IsAccessibleMemoryRange((uptr)tinfo, sizeof(std::type_info)))
+ return DynamicTypeInfo(0, 0, 0);
+
+ // Okay, this is probably a std::type_info. Request its name.
+ // FIXME: Implement a base class search like we do for Itanium.
+ return DynamicTypeInfo(tinfo->name(), obj_locator->offset_to_top,
+ "<unknown>");
+}
+
+#endif // CAN_SANITIZE_UB && SANITIZER_WINDOWS
Modified: compiler-rt/trunk/test/cfi/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/CMakeLists.txt (original)
+++ compiler-rt/trunk/test/cfi/CMakeLists.txt Wed Jul 8 17:10:34 2015
@@ -21,6 +21,11 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
LTO
)
endif()
+ if(WIN32 AND EXISTS ${CMAKE_SOURCE_DIR}/tools/lld)
+ list(APPEND CFI_TEST_DEPS
+ lld
+ )
+ endif()
endif()
add_lit_testsuite(check-cfi "Running the cfi regression tests"
Modified: compiler-rt/trunk/test/cfi/anon-namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/anon-namespace.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/anon-namespace.cpp (original)
+++ compiler-rt/trunk/test/cfi/anon-namespace.cpp Wed Jul 8 17:10:34 2015
@@ -1,32 +1,32 @@
// RUN: %clangxx_cfi -c -DTU1 -o %t1.o %s
// RUN: %clangxx_cfi -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %t1.o %t2.o
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
// RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s
// RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t2 %t1.o %t2.o
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
// RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s
// RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t3 %t1.o %t2.o
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
// RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s
// RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t4 %t1.o %t2.o
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
// RUN: %clangxx -c -DTU1 -o %t1.o %s
// RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx -o %t %t1.o %t2.o
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %t1.o %t2.o
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
// RUN: %clangxx_cfi_diag -c -DTU1 -o %t1.o %s
// RUN: %clangxx_cfi_diag -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi_diag -o %t %t1.o %t2.o
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %t1.o %t2.o
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
// Tests that the CFI mechanism treats classes in the anonymous namespace in
// different translation units as having distinct identities. This is done by
@@ -91,13 +91,13 @@ int main() {
fprintf(stderr, "1\n");
// CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during base-to-derived cast
- // CFI-DIAG-NEXT: note: vtable is of type '(anonymous namespace)::B'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
// CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during virtual call
- // CFI-DIAG-NEXT: note: vtable is of type '(anonymous namespace)::B'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
((B *)a)->f(); // UB here
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/bad-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/bad-cast.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/bad-cast.cpp (original)
+++ compiler-rt/trunk/test/cfi/bad-cast.cpp Wed Jul 8 17:10:34 2015
@@ -1,68 +1,68 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t d 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t e 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t f 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t h 2>&1 | FileCheck --check-prefix=FAIL %s
-
-// RUN: %clangxx -o %t %s
-// RUN: %t a 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t b 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t c 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t g 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t1 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t1 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t1 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t1 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t1 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t1 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t1 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t2 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t2 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t2 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t2 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t2 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t2 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t2 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t3 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t3 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t3 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t3 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t3 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t3 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t3 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t4 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t4 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t4 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t4 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t4 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t4 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t4 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t5 %s
+// RUN: %expect_crash %t5 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 d 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 e 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 f 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 h 2>&1 | FileCheck --check-prefix=FAIL %s
+
+// RUN: %clangxx -o %t6 %s
+// RUN: %t6 a 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 b 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 c 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 g 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi_diag -o %t7 %s
+// RUN: %t7 a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s
// Tests that the CFI enforcement detects bad casts.
@@ -112,10 +112,10 @@ int main(int argc, char **argv) {
A a;
// CFI-DIAG-D: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast
- // CFI-DIAG-D-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-D-NEXT: note: vtable is of type '{{(struct )?}}A'
// CFI-DIAG-U: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
- // CFI-DIAG-U-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-U-NEXT: note: vtable is of type '{{(struct )?}}A'
switch (argv[1][0]) {
case 'a':
@@ -144,7 +144,7 @@ int main(int argc, char **argv) {
break;
}
- // FAIL-NOT: 2
- // PASS: 2
+ // FAIL-NOT: {{^2$}}
+ // PASS: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/multiple-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/multiple-inheritance.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/multiple-inheritance.cpp (original)
+++ compiler-rt/trunk/test/cfi/multiple-inheritance.cpp Wed Jul 8 17:10:34 2015
@@ -1,26 +1,26 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
-// RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s
-
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s
-// RUN: %t x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t1 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t2 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t3 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t4 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %t5 x 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s
+// RUN: %t6 x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s
// Tests that the CFI mechanism is sensitive to multiple inheritance and only
// permits calls via virtual tables for the correct base class.
@@ -77,16 +77,16 @@ int main(int argc, char **argv) {
if (argc > 1) {
A *a = c;
// CFI-DIAG1: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
- // CFI-DIAG1-NEXT: note: vtable is of type 'C'
+ // CFI-DIAG1-NEXT: note: vtable is of type '{{(struct )?}}C'
((B *)a)->g(); // UB here
} else {
// CFI-DIAG2: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
- // CFI-DIAG2-NEXT: note: vtable is of type 'C'
+ // CFI-DIAG2-NEXT: note: vtable is of type '{{(struct )?}}C'
B *b = c;
((A *)b)->f(); // UB here
}
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/nvcall.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/nvcall.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/nvcall.cpp (original)
+++ compiler-rt/trunk/test/cfi/nvcall.cpp Wed Jul 8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
// Tests that the CFI mechanism crashes the program when making a non-virtual
// call to an object of the wrong class, by casting a pointer to such an object
@@ -63,10 +63,10 @@ int main() {
fprintf(stderr, "1\n");
// CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during non-virtual call
- // CFI-DIAG-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
((B *)a)->f(); // UB here
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/overwrite.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/overwrite.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/overwrite.cpp (original)
+++ compiler-rt/trunk/test/cfi/overwrite.cpp Wed Jul 8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
// Tests that the CFI mechanism crashes the program when a virtual table is
// replaced with a compatible table of function pointers that does not belong to
@@ -68,7 +68,7 @@ int main() {
// CFI-DIAG-NEXT: note: invalid vtable
a->f();
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/sibling.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/sibling.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/sibling.cpp (original)
+++ compiler-rt/trunk/test/cfi/sibling.cpp Wed Jul 8 17:10:34 2015
@@ -1,19 +1,19 @@
// XFAIL: *
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
// Tests that the CFI enforcement distinguishes betwen non-overriding siblings.
// XFAILed as not implemented yet.
Modified: compiler-rt/trunk/test/cfi/simple-fail.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/simple-fail.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/simple-fail.cpp (original)
+++ compiler-rt/trunk/test/cfi/simple-fail.cpp Wed Jul 8 17:10:34 2015
@@ -1,56 +1,56 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O1 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -o %t5 %s
+// RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O1 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s
+// RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O1 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s
+// RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O1 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DBM -o %t8 %s
+// RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O2 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -o %t9 %s
+// RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O2 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s
+// RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O2 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s
+// RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O2 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DBM -o %t12 %s
+// RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O3 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -o %t13 %s
+// RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O3 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s
+// RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O3 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s
+// RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -O3 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DBM -o %t16 %s
+// RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t17 %s
+// RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t18 %s
+// RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s
// Tests that the CFI mechanism crashes the program when making a virtual call
// to an object of the wrong class but with a compatible vtable, by casting a
@@ -97,12 +97,12 @@ int main() {
fprintf(stderr, "1\n");
// CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
- // CFI-DIAG-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
// CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call
- // CFI-DIAG-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
((B *)a)->f(); // UB here
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/cfi/vdtor.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/vdtor.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/vdtor.cpp (original)
+++ compiler-rt/trunk/test/cfi/vdtor.cpp Wed Jul 8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
// Tests that the CFI enforcement also applies to virtual destructor calls made
// via 'delete'.
@@ -60,10 +60,10 @@ int main() {
fprintf(stderr, "1\n");
// CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call
- // CFI-DIAG-NEXT: note: vtable is of type 'A'
+ // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
delete (B *)a; // UB here
- // CFI-NOT: 2
- // NCFI: 2
+ // CFI-NOT: {{^2$}}
+ // NCFI: {{^2$}}
fprintf(stderr, "2\n");
}
Modified: compiler-rt/trunk/test/lit.common.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lit.common.cfg?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/lit.common.cfg (original)
+++ compiler-rt/trunk/test/lit.common.cfg Wed Jul 8 17:10:34 2015
@@ -121,13 +121,20 @@ def is_linux_lto_supported():
return True
-if sys.platform == 'darwin' and is_darwin_lto_supported():
+def is_windows_lto_supported():
+ return os.path.exists(os.path.join(config.llvm_tools_dir, 'lld-link2.exe'))
+
+if config.host_os == 'Darwin' and is_darwin_lto_supported():
config.lto_supported = True
config.lto_launch = ["env", "DYLD_LIBRARY_PATH=" + config.llvm_shlib_dir]
config.lto_flags = []
-elif sys.platform.startswith('linux') and is_linux_lto_supported():
+elif config.host_os == 'Linux' and is_linux_lto_supported():
config.lto_supported = True
config.lto_launch = []
config.lto_flags = ["-fuse-ld=gold"]
+elif config.host_os == 'Windows' and is_windows_lto_supported():
+ config.lto_supported = True
+ config.lto_launch = []
+ config.lto_flags = ["-fuse-ld=lld-link2"]
else:
config.lto_supported = False
Modified: compiler-rt/trunk/test/ubsan/lit.common.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/lit.common.cfg?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/ubsan/lit.common.cfg (original)
+++ compiler-rt/trunk/test/ubsan/lit.common.cfg Wed Jul 8 17:10:34 2015
@@ -54,6 +54,11 @@ config.suffixes = ['.c', '.cc', '.cpp']
if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']:
config.unsupported = True
+if config.host_os == 'Windows':
+ # We do not currently support enough of the Microsoft ABI for UBSan to work on
+ # Windows.
+ config.available_features.remove('cxxabi')
+
# Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL
# because the test hangs or fails on one configuration and not the other.
if config.target_arch.startswith('arm') == False:
More information about the llvm-commits
mailing list