diff --git a/lib/tsan/builtins/assembly.h b/lib/tsan/builtins/assembly.h index 8c42fc7734..34c7124152 100644 --- a/lib/tsan/builtins/assembly.h +++ b/lib/tsan/builtins/assembly.h @@ -290,4 +290,16 @@ CFI_END #endif +#ifdef __arm__ +#include "int_endianness.h" + +#if _YUGA_BIG_ENDIAN +#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src1, src0 SEPARATOR +#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst1, dst0, src SEPARATOR +#else +#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src0, src1 SEPARATOR +#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst0, dst1, src SEPARATOR +#endif +#endif + #endif // COMPILERRT_ASSEMBLY_H diff --git a/lib/tsan/interception/interception.h b/lib/tsan/interception/interception.h index 38c152952e..3cb6b44663 100644 --- a/lib/tsan/interception/interception.h +++ b/lib/tsan/interception/interception.h @@ -25,8 +25,19 @@ // These typedefs should be used only in the interceptor definitions to replace // the standard system types (e.g. SSIZE_T instead of ssize_t) -typedef __sanitizer::uptr SIZE_T; -typedef __sanitizer::sptr SSIZE_T; +// On Windows the system headers (basetsd.h) provide a conflicting definition +// of SIZE_T/SSIZE_T that do not match the real size_t/ssize_t for 32-bit +// systems (using long instead of the expected int). Work around the typedef +// redefinition by #defining SIZE_T instead of using a typedef. +// TODO: We should be using __sanitizer::usize (and a new ssize) instead of +// these new macros as long as we ensure they match the real system definitions. +#if SANITIZER_WINDOWS +// Ensure that (S)SIZE_T were already defined as we are about to override them. +# include +#endif + +#define SIZE_T __sanitizer::usize +#define SSIZE_T __sanitizer::ssize typedef __sanitizer::sptr PTRDIFF_T; typedef __sanitizer::s64 INTMAX_T; typedef __sanitizer::u64 UINTMAX_T; @@ -338,16 +349,8 @@ const interpose_substitution substitution_##func_name[] \ #endif // ISO C++ forbids casting between pointer-to-function and pointer-to-object, -// so we use casting via an integral type __interception::uptr, -// assuming that system is POSIX-compliant. Using other hacks seem -// challenging, as we don't even pass function type to -// INTERCEPT_FUNCTION macro, only its name. +// so we use casts via uintptr_t (the local __sanitizer::uptr equivalent). namespace __interception { -#if defined(_WIN64) -typedef unsigned long long uptr; -#else -typedef unsigned long uptr; -#endif // _WIN64 #if defined(__ELF__) && !SANITIZER_FUCHSIA // The use of interceptors makes many sanitizers unusable for static linking. diff --git a/lib/tsan/interception/interception_type_test.cpp b/lib/tsan/interception/interception_type_test.cpp index 7c3de82a1e..41041ce6f9 100644 --- a/lib/tsan/interception/interception_type_test.cpp +++ b/lib/tsan/interception/interception_type_test.cpp @@ -12,28 +12,35 @@ //===----------------------------------------------------------------------===// #include "interception.h" +#include "sanitizer_common/sanitizer_type_traits.h" -#if SANITIZER_LINUX || SANITIZER_APPLE - -#include +#if __has_include() +# include +#endif #include #include -COMPILER_CHECK(sizeof(::SIZE_T) == sizeof(size_t)); -COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t)); -COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::uptr, ::uintptr_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::sptr, ::intptr_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::usize, ::size_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<::PTRDIFF_T, ::ptrdiff_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<::SIZE_T, ::size_t>::value)); +#if !SANITIZER_WINDOWS +// No ssize_t on Windows. +COMPILER_CHECK((__sanitizer::is_same<::SSIZE_T, ::ssize_t>::value)); +#endif +// TODO: These are not actually the same type on Linux (long vs long long) COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t)); +COMPILER_CHECK(sizeof(::UINTMAX_T) == sizeof(uintmax_t)); -# if SANITIZER_GLIBC || SANITIZER_ANDROID +#if SANITIZER_GLIBC || SANITIZER_ANDROID COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); -# endif +#endif // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ - _FILE_OFFSET_BITS != 64 +#if !SANITIZER_WINDOWS && (SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ + _FILE_OFFSET_BITS != 64) COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); -# endif - #endif diff --git a/lib/tsan/interception/interception_win.cpp b/lib/tsan/interception/interception_win.cpp index a638e66ecc..002b37468a 100644 --- a/lib/tsan/interception/interception_win.cpp +++ b/lib/tsan/interception/interception_win.cpp @@ -27,7 +27,7 @@ // // 1) Detour // -// The Detour hooking technique is assuming the presence of an header with +// The Detour hooking technique is assuming the presence of a header with // padding and an overridable 2-bytes nop instruction (mov edi, edi). The // nop instruction can safely be replaced by a 2-bytes jump without any need // to save the instruction. A jump to the target is encoded in the function @@ -47,7 +47,7 @@ // // func: jmp