summaryrefslogtreecommitdiff
path: root/lib/asan/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan/tests')
-rw-r--r--lib/asan/tests/CMakeLists.txt219
-rw-r--r--lib/asan/tests/asan_asm_test.cc267
-rw-r--r--lib/asan/tests/asan_fake_stack_test.cc10
-rw-r--r--lib/asan/tests/asan_interface_test.cc67
-rw-r--r--lib/asan/tests/asan_mem_test.cc15
-rw-r--r--lib/asan/tests/asan_noinst_test.cc110
-rw-r--r--lib/asan/tests/asan_oob_test.cc4
-rw-r--r--lib/asan/tests/asan_racy_double_free_test.cc4
-rw-r--r--lib/asan/tests/asan_str_test.cc52
-rw-r--r--lib/asan/tests/asan_test.cc193
-rw-r--r--lib/asan/tests/asan_test_config.h12
-rw-r--r--lib/asan/tests/asan_test_utils.h20
12 files changed, 678 insertions, 295 deletions
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt
index fc0f1788bd354..7b363714e8a53 100644
--- a/lib/asan/tests/CMakeLists.txt
+++ b/lib/asan/tests/CMakeLists.txt
@@ -15,32 +15,29 @@ include(CompilerRTCompile)
include_directories(..)
include_directories(../..)
-# Use zero-based shadow on Android.
-if(ANDROID)
- set(ASAN_TESTS_USE_ZERO_BASE_SHADOW TRUE)
-else()
- set(ASAN_TESTS_USE_ZERO_BASE_SHADOW FALSE)
-endif()
-
set(ASAN_UNITTEST_HEADERS
asan_mac_test.h
asan_test_config.h
asan_test_utils.h)
set(ASAN_UNITTEST_COMMON_CFLAGS
- ${COMPILER_RT_GTEST_INCLUDE_CFLAGS}
+ ${COMPILER_RT_TEST_CFLAGS}
+ ${COMPILER_RT_GTEST_CFLAGS}
-I${COMPILER_RT_SOURCE_DIR}/include
-I${COMPILER_RT_SOURCE_DIR}/lib
-I${COMPILER_RT_SOURCE_DIR}/lib/asan
-I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
- -Wall
+ -fno-rtti
+ -O2
-Wno-format
- -Werror
- -Werror=sign-compare
- -g
- -O2)
-if(SUPPORTS_NO_VARIADIC_MACROS_FLAG)
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros)
+ -Werror=sign-compare)
+append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
+
+# -gline-tables-only must be enough for ASan, so use it if possible.
+if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
+ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
+else()
+ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
endif()
# Use -D instead of definitions to please custom compile command.
@@ -48,79 +45,91 @@ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
-DASAN_HAS_BLACKLIST=1
-DASAN_HAS_EXCEPTIONS=1
-DASAN_UAR=0)
-if(ANDROID)
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
- -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=0
- -DASAN_NEEDS_SEGV=0)
-else()
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
- -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
- -DASAN_NEEDS_SEGV=1)
-endif()
set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
${ASAN_UNITTEST_COMMON_CFLAGS}
-fsanitize=address
"-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
- -mllvm -asan-stack=1
- -mllvm -asan-globals=1
- -mllvm -asan-mapping-scale=0 # default will be used
- -mllvm -asan-mapping-offset-log=-1 # default will be used
)
-if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
- list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS
- -fsanitize-address-zero-base-shadow)
+if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
+ list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)
+endif()
+
+if(NOT MSVC)
+ list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
+endif()
+
+# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
+if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
+ list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
endif()
-# Unit tests require libstdc++.
-set(ASAN_UNITTEST_COMMON_LINKFLAGS -lstdc++)
# Unit tests on Mac depend on Foundation.
if(APPLE)
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
endif()
-if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
+if(ANDROID)
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
endif()
set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
${ASAN_UNITTEST_COMMON_LINKFLAGS})
-# On Android, we link with ASan runtime manually. On other platforms we depend
-# on Clang driver behavior, passing -fsanitize=address flag.
-if(NOT ANDROID)
- list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
-endif()
+list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
-set(ASAN_UNITTEST_NOINST_LINKFLAGS
- ${ASAN_UNITTEST_COMMON_LINKFLAGS}
- -ldl -lm)
-if(NOT ANDROID)
- list(APPEND ASAN_UNITTEST_NOINST_LINKFLAGS -lpthread)
-endif()
+set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
+ ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
+ -shared-libasan)
+
+set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
+# NDK r10 requires -latomic almost always.
+append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)
+
+set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
+append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
+append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
+ ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
+
+# TODO(eugenis): move all -l flags above to _LIBS?
+set(ASAN_UNITTEST_NOINST_LIBS)
+append_list_if(ANDROID log ASAN_UNITTEST_NOINST_LIBS)
+# NDK r10 requires -latomic almost always.
+append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)
# Compile source for the given architecture, using compiler
# options in ${ARGN}, and add it to the object list.
-macro(asan_compile obj_list source arch)
+macro(asan_compile obj_list source arch kind)
get_filename_component(basename ${source} NAME)
- set(output_obj "${obj_list}.${basename}.${arch}.o")
+ set(output_obj "${obj_list}.${basename}.${arch}${kind}.o")
get_target_flags_for_arch(${arch} TARGET_CFLAGS)
+ set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})
+ if(NOT COMPILER_RT_STANDALONE_BUILD)
+ list(APPEND COMPILE_DEPS gtest asan)
+ endif()
clang_compile(${output_obj} ${source}
CFLAGS ${ARGN} ${TARGET_CFLAGS}
- DEPS gtest asan_runtime_libraries
- ${ASAN_UNITTEST_HEADERS}
- ${ASAN_BLACKLIST_FILE})
+ DEPS ${COMPILE_DEPS})
list(APPEND ${obj_list} ${output_obj})
endmacro()
# Link ASan unit test for a given architecture from a set
# of objects in with given linker flags.
-macro(add_asan_test test_suite test_name arch)
+macro(add_asan_test test_suite test_name arch kind)
parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN})
get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
- set(TEST_DEPS asan_runtime_libraries ${TEST_OBJECTS})
+ set(TEST_DEPS ${TEST_OBJECTS})
+ if(NOT COMPILER_RT_STANDALONE_BUILD)
+ list(APPEND TEST_DEPS asan)
+ endif()
if(TEST_WITH_TEST_RUNTIME)
list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
- list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)
+ if(NOT MSVC)
+ list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)
+ else()
+ list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib)
+ endif()
endif()
add_compiler_rt_test(${test_suite} ${test_name}
OBJECTS ${TEST_OBJECTS}
@@ -144,6 +153,7 @@ set(ASAN_NOINST_TEST_SOURCES
set(ASAN_INST_TEST_SOURCES
${COMPILER_RT_GTEST_SOURCE}
+ asan_asm_test.cc
asan_globals_test.cc
asan_interface_test.cc
asan_test.cc
@@ -157,27 +167,32 @@ endif()
set(ASAN_BENCHMARKS_SOURCES
${COMPILER_RT_GTEST_SOURCE}
- asan_benchmarks_test.cc)
+ asan_benchmarks_test.cc)
# Adds ASan unit tests and benchmarks for architecture.
-macro(add_asan_tests_for_arch arch)
+macro(add_asan_tests_for_arch_and_kind arch kind)
# Instrumented tests.
set(ASAN_INST_TEST_OBJECTS)
foreach(src ${ASAN_INST_TEST_SOURCES})
- asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch}
- ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
+ asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}
+ ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
endforeach()
if (APPLE)
# Add Mac-specific helper.
- asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch}
- ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
+ asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}
+ ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})
endif()
- add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
+ add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" ${arch} ${kind}
OBJECTS ${ASAN_INST_TEST_OBJECTS}
LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
+ if(COMPILER_RT_BUILD_SHARED_ASAN)
+ add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Dynamic-Test" ${arch} ${kind}
+ OBJECTS ${ASAN_INST_TEST_OBJECTS}
+ LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
+ endif()
# Add static ASan runtime that will be linked with uninstrumented tests.
- set(ASAN_TEST_RUNTIME RTAsanTest.${arch})
+ set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
if(APPLE)
set(ASAN_TEST_RUNTIME_OBJECTS
$<TARGET_OBJECTS:RTAsan.osx>
@@ -187,10 +202,14 @@ macro(add_asan_tests_for_arch arch)
else()
set(ASAN_TEST_RUNTIME_OBJECTS
$<TARGET_OBJECTS:RTAsan.${arch}>
+ $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
$<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTLSanCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
+ if(NOT WIN32)
+ list(APPEND ASAN_TEST_RUNTIME_OBJECTS
+ $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
+ endif()
endif()
add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
@@ -198,10 +217,10 @@ macro(add_asan_tests_for_arch arch)
# Uninstrumented tests.
set(ASAN_NOINST_TEST_OBJECTS)
foreach(src ${ASAN_NOINST_TEST_SOURCES})
- asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch}
- ${ASAN_UNITTEST_COMMON_CFLAGS})
+ asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}
+ ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})
endforeach()
- add_asan_test(AsanUnitTests "Asan-${arch}-Noinst-Test" ${arch}
+ add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind}
OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
WITH_TEST_RUNTIME)
@@ -209,45 +228,53 @@ macro(add_asan_tests_for_arch arch)
# Benchmarks.
set(ASAN_BENCHMARKS_OBJECTS)
foreach(src ${ASAN_BENCHMARKS_SOURCES})
- asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch}
- ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
+ asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}
+ ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
endforeach()
- add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
+ add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" ${arch} ${kind}
OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
+ if(COMPILER_RT_BUILD_SHARED_ASAN)
+ add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Dynamic-Benchmark" ${arch} ${kind}
+ OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
+ LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
+ endif()
endmacro()
-if(COMPILER_RT_CAN_EXECUTE_TESTS)
+if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
foreach(arch ${ASAN_SUPPORTED_ARCH})
- add_asan_tests_for_arch(${arch})
+ add_asan_tests_for_arch_and_kind(${arch} "-inline")
+ add_asan_tests_for_arch_and_kind(${arch} "-with-calls"
+ -mllvm -asan-instrumentation-with-call-threshold=0)
endforeach()
endif()
if(ANDROID)
- # We assume that unit tests on Android are built in a build
- # tree with fresh Clang as a host compiler.
-
- # Test w/o ASan instrumentation. Link it with ASan statically.
- add_executable(AsanNoinstTest
- $<TARGET_OBJECTS:RTAsan.arm.android>
- $<TARGET_OBJECTS:RTInterception.arm.android>
- $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>
- ${COMPILER_RT_GTEST_SOURCE}
- ${ASAN_NOINST_TEST_SOURCES})
- set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
- set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
-
- # Test with ASan instrumentation. Link with ASan dynamic runtime.
- add_executable(AsanTest
- ${COMPILER_RT_GTEST_SOURCE}
- ${ASAN_INST_TEST_SOURCES})
- set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
- set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
- target_link_libraries(AsanTest clang_rt.asan-arm-android)
-
- # Setup correct output directory and link flags.
- set_target_properties(AsanNoinstTest AsanTest PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- # Add unit test to test suite.
- add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
+ foreach(arch ${ASAN_SUPPORTED_ARCH})
+ # Test w/o ASan instrumentation. Link it with ASan statically.
+ add_executable(AsanNoinstTest # FIXME: .arch?
+ $<TARGET_OBJECTS:RTAsan.${arch}>
+ $<TARGET_OBJECTS:RTInterception.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ ${COMPILER_RT_GTEST_SOURCE}
+ ${ASAN_NOINST_TEST_SOURCES})
+ set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
+ set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
+ target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
+
+ # Test with ASan instrumentation. Link with ASan dynamic runtime.
+ add_executable(AsanTest
+ ${COMPILER_RT_GTEST_SOURCE}
+ ${ASAN_INST_TEST_SOURCES})
+ set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
+ set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
+ target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
+
+ # Setup correct output directory and link flags.
+ set_target_properties(AsanNoinstTest AsanTest PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ # Add unit tests to the test suite.
+ add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
+ endforeach()
endif()
diff --git a/lib/asan/tests/asan_asm_test.cc b/lib/asan/tests/asan_asm_test.cc
new file mode 100644
index 0000000000000..1d8b04d611bd5
--- /dev/null
+++ b/lib/asan/tests/asan_asm_test.cc
@@ -0,0 +1,267 @@
+//===-- asan_asm_test.cc --------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+#include "asan_test_utils.h"
+
+#if defined(__linux__)
+
+#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
+
+#include <emmintrin.h>
+
+namespace {
+
+template<typename T> void asm_write(T *ptr, T val);
+template<typename T> T asm_read(T *ptr);
+template<typename T> void asm_rep_movs(T *dst, T *src, size_t n);
+
+} // End of anonymous namespace
+
+#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
+
+#if defined(__x86_64__)
+
+namespace {
+
+#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
+template<> void asm_write<Type>(Type *ptr, Type val) { \
+ __asm__( \
+ Mov " %[val], (%[ptr]) \n\t" \
+ : \
+ : [ptr] "r" (ptr), [val] Reg (val) \
+ : "memory" \
+ ); \
+}
+
+#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
+template<> Type asm_read<Type>(Type *ptr) { \
+ Type res; \
+ __asm__( \
+ Mov " (%[ptr]), %[res] \n\t" \
+ : [res] Reg (res) \
+ : [ptr] "r" (ptr) \
+ : "memory" \
+ ); \
+ return res; \
+}
+
+#define DECLARE_ASM_REP_MOVS(Type, Movs) \
+ template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
+ __asm__("rep " Movs " \n\t" \
+ : \
+ : "D"(dst), "S"(src), "c"(size) \
+ : "rsi", "rdi", "rcx", "memory"); \
+ }
+
+DECLARE_ASM_WRITE(U8, "8", "movq", "r");
+DECLARE_ASM_READ(U8, "8", "movq", "=r");
+DECLARE_ASM_REP_MOVS(U8, "movsq");
+
+} // End of anonymous namespace
+
+#endif // defined(__x86_64__)
+
+#if defined(__i386__) && defined(__SSE2__)
+
+namespace {
+
+#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
+template<> void asm_write<Type>(Type *ptr, Type val) { \
+ __asm__( \
+ Mov " %[val], (%[ptr]) \n\t" \
+ : \
+ : [ptr] "r" (ptr), [val] Reg (val) \
+ : "memory" \
+ ); \
+}
+
+#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
+template<> Type asm_read<Type>(Type *ptr) { \
+ Type res; \
+ __asm__( \
+ Mov " (%[ptr]), %[res] \n\t" \
+ : [res] Reg (res) \
+ : [ptr] "r" (ptr) \
+ : "memory" \
+ ); \
+ return res; \
+}
+
+#define DECLARE_ASM_REP_MOVS(Type, Movs) \
+ template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
+ __asm__("rep " Movs " \n\t" \
+ : \
+ : "D"(dst), "S"(src), "c"(size) \
+ : "esi", "edi", "ecx", "memory"); \
+ }
+
+} // End of anonymous namespace
+
+#endif // defined(__i386__) && defined(__SSE2__)
+
+#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
+
+namespace {
+
+DECLARE_ASM_WRITE(U1, "1", "movb", "r");
+DECLARE_ASM_WRITE(U2, "2", "movw", "r");
+DECLARE_ASM_WRITE(U4, "4", "movl", "r");
+DECLARE_ASM_WRITE(__m128i, "16", "movaps", "x");
+
+DECLARE_ASM_READ(U1, "1", "movb", "=r");
+DECLARE_ASM_READ(U2, "2", "movw", "=r");
+DECLARE_ASM_READ(U4, "4", "movl", "=r");
+DECLARE_ASM_READ(__m128i, "16", "movaps", "=x");
+
+DECLARE_ASM_REP_MOVS(U1, "movsb");
+DECLARE_ASM_REP_MOVS(U2, "movsw");
+DECLARE_ASM_REP_MOVS(U4, "movsl");
+
+template<typename T> void TestAsmWrite(const char *DeathPattern) {
+ T *buf = new T;
+ EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern);
+ T var = 0x12;
+ asm_write(&var, static_cast<T>(0x21));
+ ASSERT_EQ(static_cast<T>(0x21), var);
+ delete buf;
+}
+
+template<> void TestAsmWrite<__m128i>(const char *DeathPattern) {
+ char *buf = new char[16];
+ char *p = buf + 16;
+ if (((uintptr_t) p % 16) != 0)
+ p = buf + 8;
+ assert(((uintptr_t) p % 16) == 0);
+ __m128i val = _mm_set1_epi16(0x1234);
+ EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern);
+ __m128i var = _mm_set1_epi16(0x4321);
+ asm_write(&var, val);
+ ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0));
+ delete [] buf;
+}
+
+template<typename T> void TestAsmRead(const char *DeathPattern) {
+ T *buf = new T;
+ EXPECT_DEATH(asm_read(&buf[1]), DeathPattern);
+ T var = 0x12;
+ ASSERT_EQ(static_cast<T>(0x12), asm_read(&var));
+ delete buf;
+}
+
+template<> void TestAsmRead<__m128i>(const char *DeathPattern) {
+ char *buf = new char[16];
+ char *p = buf + 16;
+ if (((uintptr_t) p % 16) != 0)
+ p = buf + 8;
+ assert(((uintptr_t) p % 16) == 0);
+ EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern);
+ __m128i val = _mm_set1_epi16(0x1234);
+ ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0));
+ delete [] buf;
+}
+
+U4 AsmLoad(U4 *a) {
+ U4 r;
+ __asm__("movl (%[a]), %[r] \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory");
+ return r;
+}
+
+void AsmStore(U4 r, U4 *a) {
+ __asm__("movl %[r], (%[a]) \n\t" : : [a] "r" (a), [r] "r" (r) : "memory");
+}
+
+template <typename T>
+void TestAsmRepMovs(const char *DeathPatternRead,
+ const char *DeathPatternWrite) {
+ T src_good[4] = { 0x0, 0x1, 0x2, 0x3 };
+ T dst_good[4] = {};
+ asm_rep_movs(dst_good, src_good, 4);
+ ASSERT_EQ(static_cast<T>(0x0), dst_good[0]);
+ ASSERT_EQ(static_cast<T>(0x1), dst_good[1]);
+ ASSERT_EQ(static_cast<T>(0x2), dst_good[2]);
+ ASSERT_EQ(static_cast<T>(0x3), dst_good[3]);
+
+ T dst_bad[3];
+ EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite);
+
+ T src_bad[3] = { 0x0, 0x1, 0x2 };
+ EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead);
+
+ T* dp = dst_bad + 4;
+ T* sp = src_bad + 4;
+ asm_rep_movs(dp, sp, 0);
+}
+
+} // End of anonymous namespace
+
+TEST(AddressSanitizer, asm_load_store) {
+ U4* buf = new U4[2];
+ EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4");
+ EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4");
+ delete [] buf;
+}
+
+TEST(AddressSanitizer, asm_rw) {
+ TestAsmWrite<U1>("WRITE of size 1");
+ TestAsmWrite<U2>("WRITE of size 2");
+ TestAsmWrite<U4>("WRITE of size 4");
+#if defined(__x86_64__)
+ TestAsmWrite<U8>("WRITE of size 8");
+#endif // defined(__x86_64__)
+ TestAsmWrite<__m128i>("WRITE of size 16");
+
+ TestAsmRead<U1>("READ of size 1");
+ TestAsmRead<U2>("READ of size 2");
+ TestAsmRead<U4>("READ of size 4");
+#if defined(__x86_64__)
+ TestAsmRead<U8>("READ of size 8");
+#endif // defined(__x86_64__)
+ TestAsmRead<__m128i>("READ of size 16");
+}
+
+TEST(AddressSanitizer, asm_flags) {
+ long magic = 0x1234;
+ long r = 0x0;
+
+#if defined(__x86_64__)
+ __asm__("xorq %%rax, %%rax \n\t"
+ "movq (%[p]), %%rax \n\t"
+ "sete %%al \n\t"
+ "movzbq %%al, %[r] \n\t"
+ : [r] "=r"(r)
+ : [p] "r"(&magic)
+ : "rax", "memory");
+#else
+ __asm__("xorl %%eax, %%eax \n\t"
+ "movl (%[p]), %%eax \n\t"
+ "sete %%al \n\t"
+ "movzbl %%al, %[r] \n\t"
+ : [r] "=r"(r)
+ : [p] "r"(&magic)
+ : "eax", "memory");
+#endif // defined(__x86_64__)
+
+ ASSERT_EQ(0x1, r);
+}
+
+TEST(AddressSanitizer, asm_rep_movs) {
+ TestAsmRepMovs<U1>("READ of size 1", "WRITE of size 1");
+ TestAsmRepMovs<U2>("READ of size 2", "WRITE of size 2");
+ TestAsmRepMovs<U4>("READ of size 4", "WRITE of size 4");
+#if defined(__x86_64__)
+ TestAsmRepMovs<U8>("READ of size 8", "WRITE of size 8");
+#endif // defined(__x86_64__)
+}
+
+#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
+
+#endif // defined(__linux__)
diff --git a/lib/asan/tests/asan_fake_stack_test.cc b/lib/asan/tests/asan_fake_stack_test.cc
index 1c98125eb45e6..516142f0c3b73 100644
--- a/lib/asan/tests/asan_fake_stack_test.cc
+++ b/lib/asan/tests/asan_fake_stack_test.cc
@@ -59,14 +59,16 @@ TEST(FakeStack, FlagsOffset) {
}
}
+#if !defined(_WIN32) // FIXME: Fails due to OOM on Windows.
TEST(FakeStack, CreateDestroy) {
for (int i = 0; i < 1000; i++) {
for (uptr stack_size_log = 20; stack_size_log <= 22; stack_size_log++) {
FakeStack *fake_stack = FakeStack::Create(stack_size_log);
- fake_stack->Destroy();
+ fake_stack->Destroy(0);
}
}
}
+#endif
TEST(FakeStack, ModuloNumberOfFrames) {
EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, 0), 0U);
@@ -98,7 +100,7 @@ TEST(FakeStack, GetFrame) {
EXPECT_EQ(base + 0*stack_size + 64 * 7, fs->GetFrame(stack_size_log, 0, 7U));
EXPECT_EQ(base + 1*stack_size + 128 * 3, fs->GetFrame(stack_size_log, 1, 3U));
EXPECT_EQ(base + 2*stack_size + 256 * 5, fs->GetFrame(stack_size_log, 2, 5U));
- fs->Destroy();
+ fs->Destroy(0);
}
TEST(FakeStack, Allocate) {
@@ -127,7 +129,7 @@ TEST(FakeStack, Allocate) {
fs->Deallocate(reinterpret_cast<uptr>(it->first), it->second);
}
}
- fs->Destroy();
+ fs->Destroy(0);
}
static void RecursiveFunction(FakeStack *fs, int depth) {
@@ -144,7 +146,7 @@ TEST(FakeStack, RecursiveStressTest) {
const uptr stack_size_log = 16;
FakeStack *fs = FakeStack::Create(stack_size_log);
RecursiveFunction(fs, 22); // with 26 runs for 2-3 seconds.
- fs->Destroy();
+ fs->Destroy(0);
}
} // namespace __asan
diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc
index f36679012f278..50fdf1119f0ba 100644
--- a/lib/asan/tests/asan_interface_test.cc
+++ b/lib/asan/tests/asan_interface_test.cc
@@ -11,18 +11,19 @@
//
//===----------------------------------------------------------------------===//
#include "asan_test_utils.h"
-#include "sanitizer/asan_interface.h"
+#include <sanitizer/allocator_interface.h>
+#include <sanitizer/asan_interface.h>
TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
- EXPECT_EQ(0U, __asan_get_estimated_allocated_size(0));
+ EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
const size_t sizes[] = { 1, 30, 1<<30 };
for (size_t i = 0; i < 3; i++) {
- EXPECT_EQ(sizes[i], __asan_get_estimated_allocated_size(sizes[i]));
+ EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
}
}
static const char* kGetAllocatedSizeErrorMsg =
- "attempting to call __asan_get_allocated_size()";
+ "attempting to call __sanitizer_get_allocated_size";
TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
const size_t kArraySize = 100;
@@ -31,38 +32,41 @@ TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
// Allocated memory is owned by allocator. Allocated size should be
// equal to requested size.
- EXPECT_EQ(true, __asan_get_ownership(array));
- EXPECT_EQ(kArraySize, __asan_get_allocated_size(array));
- EXPECT_EQ(true, __asan_get_ownership(int_ptr));
- EXPECT_EQ(sizeof(int), __asan_get_allocated_size(int_ptr));
+ EXPECT_EQ(true, __sanitizer_get_ownership(array));
+ EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
+ EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
+ EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
// We cannot call GetAllocatedSize from the memory we didn't map,
// and from the interior pointers (not returned by previous malloc).
void *wild_addr = (void*)0x1;
- EXPECT_FALSE(__asan_get_ownership(wild_addr));
- EXPECT_DEATH(__asan_get_allocated_size(wild_addr), kGetAllocatedSizeErrorMsg);
- EXPECT_FALSE(__asan_get_ownership(array + kArraySize / 2));
- EXPECT_DEATH(__asan_get_allocated_size(array + kArraySize / 2),
+ EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
+ EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
+ kGetAllocatedSizeErrorMsg);
+ EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
+ EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
kGetAllocatedSizeErrorMsg);
- // NULL is not owned, but is a valid argument for __asan_get_allocated_size().
- EXPECT_FALSE(__asan_get_ownership(NULL));
- EXPECT_EQ(0U, __asan_get_allocated_size(NULL));
+ // NULL is not owned, but is a valid argument for
+ // __sanitizer_get_allocated_size().
+ EXPECT_FALSE(__sanitizer_get_ownership(NULL));
+ EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
// When memory is freed, it's not owned, and call to GetAllocatedSize
// is forbidden.
free(array);
- EXPECT_FALSE(__asan_get_ownership(array));
- EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg);
+ EXPECT_FALSE(__sanitizer_get_ownership(array));
+ EXPECT_DEATH(__sanitizer_get_allocated_size(array),
+ kGetAllocatedSizeErrorMsg);
delete int_ptr;
void *zero_alloc = Ident(malloc(0));
if (zero_alloc != 0) {
// If malloc(0) is not null, this pointer is owned and should have valid
// allocated size.
- EXPECT_TRUE(__asan_get_ownership(zero_alloc));
+ EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
// Allocated size is 0 or 1 depending on the allocator used.
- EXPECT_LT(__asan_get_allocated_size(zero_alloc), 2U);
+ EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
}
free(zero_alloc);
}
@@ -71,14 +75,14 @@ TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
size_t before_malloc, after_malloc, after_free;
char *array;
const size_t kMallocSize = 100;
- before_malloc = __asan_get_current_allocated_bytes();
+ before_malloc = __sanitizer_get_current_allocated_bytes();
array = Ident((char*)malloc(kMallocSize));
- after_malloc = __asan_get_current_allocated_bytes();
+ after_malloc = __sanitizer_get_current_allocated_bytes();
EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
free(array);
- after_free = __asan_get_current_allocated_bytes();
+ after_free = __sanitizer_get_current_allocated_bytes();
EXPECT_EQ(before_malloc, after_free);
}
@@ -88,11 +92,11 @@ TEST(AddressSanitizerInterface, GetHeapSizeTest) {
// otherwise it will be stuck in quarantine instead of being unmaped.
static const size_t kLargeMallocSize = (1 << 28) + 1; // 256M
free(Ident(malloc(kLargeMallocSize))); // Drain quarantine.
- size_t old_heap_size = __asan_get_heap_size();
+ size_t old_heap_size = __sanitizer_get_heap_size();
for (int i = 0; i < 3; i++) {
// fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
free(Ident(malloc(kLargeMallocSize)));
- EXPECT_EQ(old_heap_size, __asan_get_heap_size());
+ EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
}
}
@@ -116,7 +120,7 @@ static void *ManyThreadsWithStatsWorker(void *arg) {
TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
size_t before_test, after_test, i;
pthread_t threads[kManyThreadsNumThreads];
- before_test = __asan_get_current_allocated_bytes();
+ before_test = __sanitizer_get_current_allocated_bytes();
for (i = 0; i < kManyThreadsNumThreads; i++) {
PTHREAD_CREATE(&threads[i], 0,
(void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
@@ -124,7 +128,7 @@ TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
for (i = 0; i < kManyThreadsNumThreads; i++) {
PTHREAD_JOIN(threads[i], 0);
}
- after_test = __asan_get_current_allocated_bytes();
+ after_test = __sanitizer_get_current_allocated_bytes();
// ASan stats also reflect memory usage of internal ASan RTL structs,
// so we can't check for equality here.
EXPECT_LT(after_test, before_test + (1UL<<20));
@@ -148,6 +152,7 @@ TEST(AddressSanitizerInterface, ExitCode) {
static void MyDeathCallback() {
fprintf(stderr, "MyDeathCallback\n");
+ fflush(0); // On Windows, stderr doesn't flush on crash.
}
TEST(AddressSanitizerInterface, DeathCallbackTest) {
@@ -389,6 +394,7 @@ TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
free(array);
}
+#if !defined(_WIN32) // FIXME: This should really be a lit test.
static void ErrorReportCallbackOneToZ(const char *report) {
int report_len = strlen(report);
ASSERT_EQ(6, write(2, "ABCDEF", 6));
@@ -403,6 +409,7 @@ TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
__asan_set_error_report_callback(NULL);
}
+#endif
TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
std::vector<char *> pointers;
@@ -414,11 +421,11 @@ TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
sizes.push_back(size);
}
for (size_t i = 0; i < 4000000; i++) {
- EXPECT_FALSE(__asan_get_ownership(&pointers));
- EXPECT_FALSE(__asan_get_ownership((void*)0x1234));
+ EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
+ EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
size_t idx = i % kNumMallocs;
- EXPECT_TRUE(__asan_get_ownership(pointers[idx]));
- EXPECT_EQ(sizes[idx], __asan_get_allocated_size(pointers[idx]));
+ EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
+ EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
}
for (size_t i = 0, n = pointers.size(); i < n; i++)
free(pointers[i]);
diff --git a/lib/asan/tests/asan_mem_test.cc b/lib/asan/tests/asan_mem_test.cc
index 60f5cd4cf7609..4a941faa0430f 100644
--- a/lib/asan/tests/asan_mem_test.cc
+++ b/lib/asan/tests/asan_mem_test.cc
@@ -76,17 +76,17 @@ TEST(AddressSanitizer, MemSetOOBTest) {
// Strictly speaking we are not guaranteed to find such two pointers,
// but given the structure of asan's allocator we will.
static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
- vector<char *> v;
+ vector<uintptr_t> v;
bool res = false;
for (size_t i = 0; i < 1000U && !res; i++) {
- v.push_back(new char[size]);
+ v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
if (i == 0) continue;
sort(v.begin(), v.end());
for (size_t j = 1; j < v.size(); j++) {
assert(v[j] > v[j-1]);
if ((size_t)(v[j] - v[j-1]) < size * 2) {
- *x2 = v[j];
- *x1 = v[j-1];
+ *x2 = reinterpret_cast<char*>(v[j]);
+ *x1 = reinterpret_cast<char*>(v[j-1]);
res = true;
break;
}
@@ -94,9 +94,10 @@ static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
}
for (size_t i = 0; i < v.size(); i++) {
- if (res && v[i] == *x1) continue;
- if (res && v[i] == *x2) continue;
- delete [] v[i];
+ char *p = reinterpret_cast<char *>(v[i]);
+ if (res && p == *x1) continue;
+ if (res && p == *x2) continue;
+ delete [] p;
}
return res;
}
diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc
index cb6223c09a469..bb6af45bddf90 100644
--- a/lib/asan/tests/asan_noinst_test.cc
+++ b/lib/asan/tests/asan_noinst_test.cc
@@ -16,6 +16,7 @@
#include "asan_internal.h"
#include "asan_mapping.h"
#include "asan_test_utils.h"
+#include <sanitizer/allocator_interface.h>
#include <assert.h>
#include <stdio.h>
@@ -25,40 +26,19 @@
#include <vector>
#include <limits>
-#if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1
-// Manually set correct ASan mapping scale and offset, as they won't be
-// exported from instrumented sources (there are none).
-# define FLEXIBLE_SHADOW_SCALE kDefaultShadowScale
-# if SANITIZER_ANDROID
-# define FLEXIBLE_SHADOW_OFFSET (0)
-# else
-# if SANITIZER_WORDSIZE == 32
-# if defined(__mips__)
-# define FLEXIBLE_SHADOW_OFFSET kMIPS32_ShadowOffset32
-# else
-# define FLEXIBLE_SHADOW_OFFSET kDefaultShadowOffset32
-# endif
-# else
-# if defined(__powerpc64__)
-# define FLEXIBLE_SHADOW_OFFSET kPPC64_ShadowOffset64
-# elif SANITIZER_MAC
-# define FLEXIBLE_SHADOW_OFFSET kDefaultShadowOffset64
-# else
-# define FLEXIBLE_SHADOW_OFFSET kDefaultShort64bitShadowOffset
-# endif
-# endif
-# endif
-SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale = FLEXIBLE_SHADOW_SCALE;
-SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset =
- FLEXIBLE_SHADOW_OFFSET;
-#endif // ASAN_FLEXIBLE_MAPPING_AND_OFFSET
+// ATTENTION!
+// Please don't call intercepted functions (including malloc() and friends)
+// in this test. The static runtime library is linked explicitly (without
+// -fsanitize=address), thus the interceptors do not work correctly on OS X.
+#if !defined(_WIN32)
extern "C" {
// Set specific ASan options for uninstrumented unittest.
const char* __asan_default_options() {
return "allow_reexec=0";
}
} // extern "C"
+#endif
// Make sure __asan_init is called before any test case is run.
struct AsanInitCaller {
@@ -72,19 +52,19 @@ TEST(AddressSanitizer, InternalSimpleDeathTest) {
static void MallocStress(size_t n) {
u32 seed = my_rand();
- StackTrace stack1;
- stack1.trace[0] = 0xa123;
- stack1.trace[1] = 0xa456;
+ BufferedStackTrace stack1;
+ stack1.trace_buffer[0] = 0xa123;
+ stack1.trace_buffer[1] = 0xa456;
stack1.size = 2;
- StackTrace stack2;
- stack2.trace[0] = 0xb123;
- stack2.trace[1] = 0xb456;
+ BufferedStackTrace stack2;
+ stack2.trace_buffer[0] = 0xb123;
+ stack2.trace_buffer[1] = 0xb456;
stack2.size = 2;
- StackTrace stack3;
- stack3.trace[0] = 0xc123;
- stack3.trace[1] = 0xc456;
+ BufferedStackTrace stack3;
+ stack3.trace_buffer[0] = 0xc123;
+ stack3.trace_buffer[1] = 0xc456;
stack3.size = 2;
std::vector<void *> vec;
@@ -160,8 +140,8 @@ TEST(AddressSanitizer, DISABLED_InternalPrintShadow) {
}
TEST(AddressSanitizer, QuarantineTest) {
- StackTrace stack;
- stack.trace[0] = 0x890;
+ BufferedStackTrace stack;
+ stack.trace_buffer[0] = 0x890;
stack.size = 1;
const int size = 1024;
@@ -181,8 +161,8 @@ TEST(AddressSanitizer, QuarantineTest) {
void *ThreadedQuarantineTestWorker(void *unused) {
(void)unused;
u32 seed = my_rand();
- StackTrace stack;
- stack.trace[0] = 0x890;
+ BufferedStackTrace stack;
+ stack.trace_buffer[0] = 0x890;
stack.size = 1;
for (size_t i = 0; i < 1000; i++) {
@@ -196,20 +176,20 @@ void *ThreadedQuarantineTestWorker(void *unused) {
// destroyed.
TEST(AddressSanitizer, ThreadedQuarantineTest) {
const int n_threads = 3000;
- size_t mmaped1 = __asan_get_heap_size();
+ size_t mmaped1 = __sanitizer_get_heap_size();
for (int i = 0; i < n_threads; i++) {
pthread_t t;
PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);
PTHREAD_JOIN(t, 0);
- size_t mmaped2 = __asan_get_heap_size();
+ size_t mmaped2 = __sanitizer_get_heap_size();
EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));
}
}
void *ThreadedOneSizeMallocStress(void *unused) {
(void)unused;
- StackTrace stack;
- stack.trace[0] = 0x890;
+ BufferedStackTrace stack;
+ stack.trace_buffer[0] = 0x890;
stack.size = 1;
const size_t kNumMallocs = 1000;
for (int iter = 0; iter < 1000; iter++) {
@@ -245,3 +225,45 @@ TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {
ptr = kHighShadowBeg + 200;
EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
}
+
+// Test __asan_load1 & friends.
+TEST(AddressSanitizer, LoadStoreCallbacks) {
+ typedef void (*CB)(uptr p);
+ CB cb[2][5] = {
+ {
+ __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
+ }, {
+ __asan_store1, __asan_store2, __asan_store4, __asan_store8,
+ __asan_store16,
+ }
+ };
+
+ uptr buggy_ptr;
+
+ __asan_test_only_reported_buggy_pointer = &buggy_ptr;
+ BufferedStackTrace stack;
+ stack.trace_buffer[0] = 0x890;
+ stack.size = 1;
+
+ for (uptr len = 16; len <= 32; len++) {
+ char *ptr = (char*) __asan::asan_malloc(len, &stack);
+ uptr p = reinterpret_cast<uptr>(ptr);
+ for (uptr is_write = 0; is_write <= 1; is_write++) {
+ for (uptr size_log = 0; size_log <= 4; size_log++) {
+ uptr size = 1 << size_log;
+ CB call = cb[is_write][size_log];
+ // Iterate only size-aligned offsets.
+ for (uptr offset = 0; offset <= len; offset += size) {
+ buggy_ptr = 0;
+ call(p + offset);
+ if (offset + size <= len)
+ EXPECT_EQ(buggy_ptr, 0U);
+ else
+ EXPECT_EQ(buggy_ptr, p + offset);
+ }
+ }
+ }
+ __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC);
+ }
+ __asan_test_only_reported_buggy_pointer = 0;
+}
diff --git a/lib/asan/tests/asan_oob_test.cc b/lib/asan/tests/asan_oob_test.cc
index f8343f19cfcb0..0c6bea2858649 100644
--- a/lib/asan/tests/asan_oob_test.cc
+++ b/lib/asan/tests/asan_oob_test.cc
@@ -75,7 +75,9 @@ TEST(AddressSanitizer, OOB_int) {
}
TEST(AddressSanitizer, OOBRightTest) {
- for (size_t access_size = 1; access_size <= 8; access_size *= 2) {
+ size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4;
+ for (size_t access_size = 1; access_size <= max_access_size;
+ access_size *= 2) {
for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {
for (size_t offset = 0; offset <= 8; offset += access_size) {
void *p = malloc(alloc_size);
diff --git a/lib/asan/tests/asan_racy_double_free_test.cc b/lib/asan/tests/asan_racy_double_free_test.cc
index deeeb4f45e2fb..23240e714d561 100644
--- a/lib/asan/tests/asan_racy_double_free_test.cc
+++ b/lib/asan/tests/asan_racy_double_free_test.cc
@@ -7,7 +7,7 @@ void *x[N];
void *Thread1(void *unused) {
for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __FUNCTION__, i);
+ fprintf(stderr, "%s %d\n", __func__, i);
free(x[i]);
}
return NULL;
@@ -15,7 +15,7 @@ void *Thread1(void *unused) {
void *Thread2(void *unused) {
for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __FUNCTION__, i);
+ fprintf(stderr, "%s %d\n", __func__, i);
free(x[i]);
}
return NULL;
diff --git a/lib/asan/tests/asan_str_test.cc b/lib/asan/tests/asan_str_test.cc
index 178d00d4da862..1cd2a08b90213 100644
--- a/lib/asan/tests/asan_str_test.cc
+++ b/lib/asan/tests/asan_str_test.cc
@@ -77,7 +77,7 @@ TEST(AddressSanitizer, WcsLenTest) {
free(heap_string);
}
-#ifndef __APPLE__
+#if SANITIZER_TEST_HAS_STRNLEN
TEST(AddressSanitizer, StrNLenOOBTest) {
size_t size = Ident(123);
char *str = MallocAndMemsetString(size);
@@ -95,7 +95,7 @@ TEST(AddressSanitizer, StrNLenOOBTest) {
EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
free(str);
}
-#endif
+#endif // SANITIZER_TEST_HAS_STRNLEN
TEST(AddressSanitizer, StrDupOOBTest) {
size_t size = Ident(42);
@@ -186,7 +186,7 @@ TEST(AddressSanitizer, StrNCpyOOBTest) {
typedef char*(*PointerToStrChr1)(const char*, int);
typedef char*(*PointerToStrChr2)(char*, int);
-USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
+UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {
size_t size = Ident(100);
char *str = MallocAndMemsetString(size);
str[10] = 'q';
@@ -202,7 +202,7 @@ USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
free(str);
}
-USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
+UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {
size_t size = Ident(100);
char *str = MallocAndMemsetString(size);
str[10] = 'q';
@@ -221,7 +221,10 @@ USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
RunStrChrTest(&strchr);
+// No index() on Windows and on Android L.
+#if !defined(_WIN32) && !defined(__ANDROID__)
RunStrChrTest(&index);
+#endif
}
TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
@@ -244,6 +247,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
EXPECT_LT(0, strncmp("baa", "aaa", 1));
EXPECT_LT(0, strncmp("zyx", "", 2));
+#if !defined(_WIN32) // no str[n]casecmp on Windows.
// strcasecmp
EXPECT_EQ(0, strcasecmp("", ""));
EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
@@ -263,6 +267,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
EXPECT_LT(0, strncasecmp("zyx", "", 2));
+#endif
// memcmp
EXPECT_EQ(0, memcmp("a", "b", 0));
@@ -305,9 +310,11 @@ TEST(AddressSanitizer, StrCmpOOBTest) {
RunStrCmpTest(&strcmp);
}
+#if !defined(_WIN32) // no str[n]casecmp on Windows.
TEST(AddressSanitizer, StrCaseCmpOOBTest) {
RunStrCmpTest(&strcasecmp);
}
+#endif
typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
@@ -340,9 +347,12 @@ TEST(AddressSanitizer, StrNCmpOOBTest) {
RunStrNCmpTest(&strncmp);
}
+#if !defined(_WIN32) // no str[n]casecmp on Windows.
TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
RunStrNCmpTest(&strncasecmp);
}
+#endif
+
TEST(AddressSanitizer, StrCatOOBTest) {
// strcat() reads strlen(to) bytes from |to| before concatenating.
size_t to_size = Ident(100);
@@ -489,15 +499,6 @@ TEST(AddressSanitizer, StrArgsOverlapTest) {
free(str);
}
-void CallAtoi(const char *nptr) {
- Ident(atoi(nptr));
-}
-void CallAtol(const char *nptr) {
- Ident(atol(nptr));
-}
-void CallAtoll(const char *nptr) {
- Ident(atoll(nptr));
-}
typedef void(*PointerToCallAtoi)(const char*);
void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
@@ -524,18 +525,23 @@ void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
free(array);
}
+#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
+void CallAtoi(const char *nptr) {
+ Ident(atoi(nptr));
+}
+void CallAtol(const char *nptr) {
+ Ident(atol(nptr));
+}
+void CallAtoll(const char *nptr) {
+ Ident(atoll(nptr));
+}
TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
RunAtoiOOBTest(&CallAtoi);
RunAtoiOOBTest(&CallAtol);
RunAtoiOOBTest(&CallAtoll);
}
+#endif
-void CallStrtol(const char *nptr, char **endptr, int base) {
- Ident(strtol(nptr, endptr, base));
-}
-void CallStrtoll(const char *nptr, char **endptr, int base) {
- Ident(strtoll(nptr, endptr, base));
-}
typedef void(*PointerToCallStrtol)(const char*, char**, int);
void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
@@ -578,11 +584,19 @@ void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
free(array);
}
+#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
+void CallStrtol(const char *nptr, char **endptr, int base) {
+ Ident(strtol(nptr, endptr, base));
+}
+void CallStrtoll(const char *nptr, char **endptr, int base) {
+ Ident(strtoll(nptr, endptr, base));
+}
TEST(AddressSanitizer, StrtollOOBTest) {
RunStrtolOOBTest(&CallStrtoll);
}
TEST(AddressSanitizer, StrtolOOBTest) {
RunStrtolOOBTest(&CallStrtol);
}
+#endif
diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc
index 6539ae8af4ead..67bcbaca1e40b 100644
--- a/lib/asan/tests/asan_test.cc
+++ b/lib/asan/tests/asan_test.cc
@@ -25,27 +25,10 @@ NOINLINE void *malloc_bbb(size_t size) {
NOINLINE void *malloc_aaa(size_t size) {
void *res = malloc_bbb(size); break_optimization(0); return res;}
-#ifndef __APPLE__
-NOINLINE void *memalign_fff(size_t alignment, size_t size) {
- void *res = memalign/**/(alignment, size); break_optimization(0); return res;}
-NOINLINE void *memalign_eee(size_t alignment, size_t size) {
- void *res = memalign_fff(alignment, size); break_optimization(0); return res;}
-NOINLINE void *memalign_ddd(size_t alignment, size_t size) {
- void *res = memalign_eee(alignment, size); break_optimization(0); return res;}
-NOINLINE void *memalign_ccc(size_t alignment, size_t size) {
- void *res = memalign_ddd(alignment, size); break_optimization(0); return res;}
-NOINLINE void *memalign_bbb(size_t alignment, size_t size) {
- void *res = memalign_ccc(alignment, size); break_optimization(0); return res;}
-NOINLINE void *memalign_aaa(size_t alignment, size_t size) {
- void *res = memalign_bbb(alignment, size); break_optimization(0); return res;}
-#endif // __APPLE__
-
-
NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
-
template<typename T>
NOINLINE void uaf_test(int size, int off) {
char *p = (char *)malloc_aaa(size);
@@ -90,19 +73,19 @@ TEST(AddressSanitizer, VariousMallocsTest) {
*c = 0;
delete c;
-#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
+#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
int *pm;
int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize);
EXPECT_EQ(0, pm_res);
free(pm);
-#endif
+#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
-#if !defined(__APPLE__)
+#if SANITIZER_TEST_HAS_MEMALIGN
int *ma = (int*)memalign(kPageSize, kPageSize);
EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
ma[123] = 0;
free(ma);
-#endif // __APPLE__
+#endif // SANITIZER_TEST_HAS_MEMALIGN
}
TEST(AddressSanitizer, CallocTest) {
@@ -124,18 +107,25 @@ TEST(AddressSanitizer, CallocReturnsZeroMem) {
EXPECT_EQ(x[size / 4], 0);
memset(x, 0x42, size);
free(Ident(x));
+#if !defined(_WIN32)
+ // FIXME: OOM on Windows. We should just make this a lit test
+ // with quarantine size set to 1.
free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.
+#endif
}
}
}
+// No valloc on Windows or Android.
+#if !defined(_WIN32) && !defined(__ANDROID__)
TEST(AddressSanitizer, VallocTest) {
void *a = valloc(100);
EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
free(a);
}
+#endif
-#ifndef __APPLE__
+#if SANITIZER_TEST_HAS_PVALLOC
TEST(AddressSanitizer, PvallocTest) {
char *a = (char*)pvalloc(kPageSize + 100);
EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
@@ -147,8 +137,10 @@ TEST(AddressSanitizer, PvallocTest) {
a[101] = 1; // we should not report an error here.
free(a);
}
-#endif // __APPLE__
+#endif // SANITIZER_TEST_HAS_PVALLOC
+#if !defined(_WIN32)
+// FIXME: Use an equivalent of pthread_setspecific on Windows.
void *TSDWorker(void *test_key) {
if (test_key) {
pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
@@ -178,6 +170,7 @@ TEST(AddressSanitizer, DISABLED_TSDTest) {
PTHREAD_JOIN(th, NULL);
pthread_key_delete(test_key);
}
+#endif
TEST(AddressSanitizer, UAF_char) {
const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
@@ -191,18 +184,27 @@ TEST(AddressSanitizer, UAF_char) {
TEST(AddressSanitizer, UAF_long_double) {
if (sizeof(long double) == sizeof(double)) return;
long double *p = Ident(new long double[10]);
- EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[06]");
- EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[06]");
+ EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");
+ EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");
delete [] Ident(p);
}
+#if !defined(_WIN32)
struct Packed5 {
int x;
char c;
} __attribute__((packed));
-
+#else
+# pragma pack(push, 1)
+struct Packed5 {
+ int x;
+ char c;
+};
+# pragma pack(pop)
+#endif
TEST(AddressSanitizer, UAF_Packed5) {
+ static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
Packed5 *p = Ident(new Packed5[2]);
EXPECT_DEATH(p[0] = p[3], "READ of size 5");
EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
@@ -299,12 +301,14 @@ TEST(AddressSanitizer, LargeMallocTest) {
}
TEST(AddressSanitizer, HugeMallocTest) {
- if (SANITIZER_WORDSIZE != 64) return;
+ if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
size_t n_megs = 4100;
- TestLargeMalloc(n_megs << 20);
+ EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
+ "is located 1 bytes to the left|"
+ "AddressSanitizer failed to allocate");
}
-#ifndef __APPLE__
+#if SANITIZER_TEST_HAS_MEMALIGN
void MemalignRun(size_t align, size_t size, int idx) {
char *p = (char *)memalign(align, size);
Ident(p)[idx] = 0;
@@ -320,7 +324,7 @@ TEST(AddressSanitizer, memalign) {
"is located 1 bytes to the right");
}
}
-#endif
+#endif // SANITIZER_TEST_HAS_MEMALIGN
void *ManyThreadsWorker(void *a) {
for (int iter = 0; iter < 100; iter++) {
@@ -379,12 +383,12 @@ TEST(AddressSanitizer, ZeroSizeMallocTest) {
void *ptr = Ident(malloc(0));
EXPECT_TRUE(NULL != ptr);
free(ptr);
-#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
+#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
int pm_res = posix_memalign(&ptr, 1<<20, 0);
EXPECT_EQ(0, pm_res);
EXPECT_TRUE(NULL != ptr);
free(ptr);
-#endif
+#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
int *int_ptr = new int[0];
int *int_ptr2 = new int[0];
EXPECT_TRUE(NULL != int_ptr);
@@ -394,7 +398,7 @@ TEST(AddressSanitizer, ZeroSizeMallocTest) {
delete[] int_ptr2;
}
-#ifndef __APPLE__
+#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
static const char *kMallocUsableSizeErrorMsg =
"AddressSanitizer: attempting to call malloc_usable_size()";
@@ -412,7 +416,7 @@ TEST(AddressSanitizer, MallocUsableSizeTest) {
EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
delete int_ptr;
}
-#endif
+#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
void WrongFree() {
int *x = (int*)malloc(100 * sizeof(int));
@@ -421,12 +425,14 @@ void WrongFree() {
free(x + 1);
}
+#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, WrongFreeTest) {
EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
"ERROR: AddressSanitizer: attempting free.*not malloc"
".*is located 4 bytes inside of 400-byte region"
".*allocated by thread");
}
+#endif
void DoubleFree() {
int *x = (int*)malloc(100 * sizeof(int));
@@ -437,6 +443,7 @@ void DoubleFree() {
abort();
}
+#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, DoubleFreeTest) {
EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
"ERROR: AddressSanitizer: attempting double-free"
@@ -444,20 +451,22 @@ TEST(AddressSanitizer, DoubleFreeTest) {
".*freed by thread T0 here"
".*previously allocated by thread T0 here");
}
+#endif
template<int kSize>
NOINLINE void SizedStackTest() {
char a[kSize];
char *A = Ident((char*)&a);
+ const char *expected_death = "AddressSanitizer: stack-buffer-";
for (size_t i = 0; i < kSize; i++)
A[i] = i;
- EXPECT_DEATH(A[-1] = 0, "");
- EXPECT_DEATH(A[-20] = 0, "");
- EXPECT_DEATH(A[-31] = 0, "");
- EXPECT_DEATH(A[kSize] = 0, "");
- EXPECT_DEATH(A[kSize + 1] = 0, "");
- EXPECT_DEATH(A[kSize + 10] = 0, "");
- EXPECT_DEATH(A[kSize + 31] = 0, "");
+ EXPECT_DEATH(A[-1] = 0, expected_death);
+ EXPECT_DEATH(A[-5] = 0, expected_death);
+ EXPECT_DEATH(A[kSize] = 0, expected_death);
+ EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
+ EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
+ if (kSize > 16)
+ EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
}
TEST(AddressSanitizer, SimpleStackTest) {
@@ -478,6 +487,9 @@ TEST(AddressSanitizer, SimpleStackTest) {
SizedStackTest<128>();
}
+#if !defined(_WIN32)
+// FIXME: It's a bit hard to write multi-line death test expectations
+// in a portable way. Anyways, this should just be turned into a lit test.
TEST(AddressSanitizer, ManyStackObjectsTest) {
char XXX[10];
char YYY[20];
@@ -486,6 +498,7 @@ TEST(AddressSanitizer, ManyStackObjectsTest) {
Ident(YYY);
EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
}
+#endif
#if 0 // This test requires online symbolizer.
// Moved to lit_tests/stack-oob-frames.cc.
@@ -538,6 +551,24 @@ NOINLINE void LongJmpFunc1(jmp_buf buf) {
longjmp(buf, 1);
}
+NOINLINE void TouchStackFunc() {
+ int a[100]; // long array will intersect with redzones from LongJmpFunc1.
+ int *A = Ident(a);
+ for (int i = 0; i < 100; i++)
+ A[i] = i*i;
+}
+
+// Test that we handle longjmp and do not report false positives on stack.
+TEST(AddressSanitizer, LongJmpTest) {
+ static jmp_buf buf;
+ if (!setjmp(buf)) {
+ LongJmpFunc1(buf);
+ } else {
+ TouchStackFunc();
+ }
+}
+
+#if !defined(_WIN32) // Only basic longjmp is available on Windows.
NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
// create three red zones for these two stack objects.
int a;
@@ -571,27 +602,9 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {
siglongjmp(buf, 1);
}
-
-NOINLINE void TouchStackFunc() {
- int a[100]; // long array will intersect with redzones from LongJmpFunc1.
- int *A = Ident(a);
- for (int i = 0; i < 100; i++)
- A[i] = i*i;
-}
-
-// Test that we handle longjmp and do not report fals positives on stack.
-TEST(AddressSanitizer, LongJmpTest) {
- static jmp_buf buf;
- if (!setjmp(buf)) {
- LongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-
-#if !defined(__ANDROID__) && \
+#if !defined(__ANDROID__) && !defined(__arm__) && \
!defined(__powerpc64__) && !defined(__powerpc__)
-// Does not work on Power:
+// Does not work on Power and ARM:
// https://code.google.com/p/address-sanitizer/issues/detail?id=185
TEST(AddressSanitizer, BuiltinLongJmpTest) {
static jmp_buf buf;
@@ -601,7 +614,8 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) {
TouchStackFunc();
}
}
-#endif // not defined(__ANDROID__)
+#endif // !defined(__ANDROID__) && !defined(__powerpc64__) &&
+ // !defined(__powerpc__) && !defined(__arm__)
TEST(AddressSanitizer, UnderscopeLongJmpTest) {
static jmp_buf buf;
@@ -620,8 +634,10 @@ TEST(AddressSanitizer, SigLongJmpTest) {
TouchStackFunc();
}
}
+#endif
-#ifdef __EXCEPTIONS
+// FIXME: Why does clang-cl define __EXCEPTIONS?
+#if defined(__EXCEPTIONS) && !defined(_WIN32)
NOINLINE void ThrowFunc() {
// create three red zones for these two stack objects.
int a;
@@ -688,12 +704,19 @@ TEST(AddressSanitizer, Store128Test) {
}
#endif
+// FIXME: All tests that use this function should be turned into lit tests.
string RightOOBErrorMessage(int oob_distance, bool is_write) {
assert(oob_distance >= 0);
char expected_str[100];
sprintf(expected_str, ASAN_PCRE_DOTALL
- "buffer-overflow.*%s.*located %d bytes to the right",
- is_write ? "WRITE" : "READ", oob_distance);
+#if !GTEST_USES_SIMPLE_RE
+ "buffer-overflow.*%s.*"
+#endif
+ "located %d bytes to the right",
+#if !GTEST_USES_SIMPLE_RE
+ is_write ? "WRITE" : "READ",
+#endif
+ oob_distance);
return string(expected_str);
}
@@ -705,11 +728,19 @@ string RightOOBReadMessage(int oob_distance) {
return RightOOBErrorMessage(oob_distance, /*is_write*/false);
}
+// FIXME: All tests that use this function should be turned into lit tests.
string LeftOOBErrorMessage(int oob_distance, bool is_write) {
assert(oob_distance > 0);
char expected_str[100];
- sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the left",
- is_write ? "WRITE" : "READ", oob_distance);
+ sprintf(expected_str,
+#if !GTEST_USES_SIMPLE_RE
+ ASAN_PCRE_DOTALL "%s.*"
+#endif
+ "located %d bytes to the left",
+#if !GTEST_USES_SIMPLE_RE
+ is_write ? "WRITE" : "READ",
+#endif
+ oob_distance);
return string(expected_str);
}
@@ -738,7 +769,7 @@ char* MallocAndMemsetString(size_t size) {
return MallocAndMemsetString(size, 'z');
}
-#if defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)
+#if defined(__linux__) && !defined(__ANDROID__)
#define READ_TEST(READ_N_BYTES) \
char *x = new char[10]; \
int fd = open("/proc/self/stat", O_RDONLY); \
@@ -761,7 +792,7 @@ TEST(AddressSanitizer, pread64) {
TEST(AddressSanitizer, read) {
READ_TEST(read(fd, x, 15));
}
-#endif // defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)
+#endif // defined(__linux__) && !defined(__ANDROID__)
// This test case fails
// Clang optimizes memcpy/memset calls which lead to unaligned access
@@ -801,7 +832,7 @@ NOINLINE static int LargeFunction(bool do_bad_access) {
x[18]++;
x[19]++;
- delete x;
+ delete[] x;
return res;
}
@@ -863,6 +894,7 @@ void ThreadedTestSpawn() {
PTHREAD_JOIN(t, 0);
}
+#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, ThreadedTest) {
EXPECT_DEATH(ThreadedTestSpawn(),
ASAN_PCRE_DOTALL
@@ -870,6 +902,7 @@ TEST(AddressSanitizer, ThreadedTest) {
".*Thread T.*created"
".*Thread T.*created");
}
+#endif
void *ThreadedTestFunc(void *unused) {
// Check if prctl(PR_SET_NAME) is supported. Return if not.
@@ -1064,7 +1097,8 @@ TEST(AddressSanitizer, PthreadExitTest) {
}
}
-#ifdef __EXCEPTIONS
+// FIXME: Why does clang-cl define __EXCEPTIONS?
+#if defined(__EXCEPTIONS) && !defined(_WIN32)
NOINLINE static void StackReuseAndException() {
int large_stack[1000];
Ident(large_stack);
@@ -1082,12 +1116,14 @@ TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {
}
#endif
+#if !defined(_WIN32)
TEST(AddressSanitizer, MlockTest) {
EXPECT_EQ(0, mlockall(MCL_CURRENT));
EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
EXPECT_EQ(0, munlockall());
EXPECT_EQ(0, munlock((void*)0x987, 0x654));
}
+#endif
struct LargeStruct {
int foo[100];
@@ -1111,10 +1147,15 @@ TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
Ident(NoSanitizeAddress)();
}
-// It doesn't work on Android, as calls to new/delete go through malloc/free.
-// Neither it does on OS X, see
-// https://code.google.com/p/address-sanitizer/issues/detail?id=131.
-#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(__APPLE__)
+// The new/delete/etc mismatch checks don't work on Android,
+// as calls to new/delete go through malloc/free.
+// OS X support is tracked here:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=131
+// Windows support is tracked here:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=309
+#if !defined(__ANDROID__) && \
+ !defined(__APPLE__) && \
+ !defined(_WIN32)
static string MismatchStr(const string &str) {
return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
}
@@ -1229,6 +1270,7 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) {
memcpy(Ident(&c), Ident(&b), sizeof(long double));
}
+#if !defined(_WIN32)
TEST(AddressSanitizer, pthread_getschedparam) {
int policy;
struct sched_param param;
@@ -1241,3 +1283,4 @@ TEST(AddressSanitizer, pthread_getschedparam) {
int res = pthread_getschedparam(pthread_self(), &policy, &param);
ASSERT_EQ(0, res);
}
+#endif
diff --git a/lib/asan/tests/asan_test_config.h b/lib/asan/tests/asan_test_config.h
index 6eb33ce4431b8..92f276307481f 100644
--- a/lib/asan/tests/asan_test_config.h
+++ b/lib/asan/tests/asan_test_config.h
@@ -21,12 +21,6 @@
#include <string>
#include <map>
-#if ASAN_USE_DEJAGNU_GTEST
-# include "dejagnu-gtest.h"
-#else
-# include "gtest/gtest.h"
-#endif
-
using std::string;
using std::vector;
using std::map;
@@ -44,7 +38,11 @@ using std::map;
#endif
#ifndef ASAN_NEEDS_SEGV
-# error "please define ASAN_NEEDS_SEGV"
+# if defined(_WIN32)
+# define ASAN_NEEDS_SEGV 0
+# else
+# define ASAN_NEEDS_SEGV 1
+# endif
#endif
#ifndef ASAN_AVOID_EXPENSIVE_TESTS
diff --git a/lib/asan/tests/asan_test_utils.h b/lib/asan/tests/asan_test_utils.h
index b6bf6b82066dc..03d17cfb26a75 100644
--- a/lib/asan/tests/asan_test_utils.h
+++ b/lib/asan/tests/asan_test_utils.h
@@ -14,24 +14,28 @@
#ifndef ASAN_TEST_UTILS_H
#define ASAN_TEST_UTILS_H
-#if !defined(ASAN_EXTERNAL_TEST_CONFIG)
+#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
# define INCLUDED_FROM_ASAN_TEST_UTILS_H
# include "asan_test_config.h"
# undef INCLUDED_FROM_ASAN_TEST_UTILS_H
#endif
#include "sanitizer_test_utils.h"
+#include "sanitizer_pthread_wrappers.h"
+
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
-#include <pthread.h>
#include <stdint.h>
-#include <setjmp.h>
#include <assert.h>
#include <algorithm>
-#include <sys/mman.h>
+
+#if !defined(_WIN32)
+# include <strings.h>
+# include <sys/mman.h>
+# include <setjmp.h>
+#endif
#ifdef __linux__
# include <sys/prctl.h>
@@ -41,14 +45,10 @@
#include <unistd.h>
#endif
-#ifndef __APPLE__
+#if !defined(__APPLE__) && !defined(__FreeBSD__)
#include <malloc.h>
#endif
-// Check that pthread_create/pthread_join return success.
-#define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
-#define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
-
#if ASAN_HAS_EXCEPTIONS
# define ASAN_THROW(x) throw (x)
#else