1# Testing rules for AddressSanitizer. 2# 3# These are broken into two buckets. One set of tests directly interacts with 4# the runtime library and checks its functionality. These are the 5# no-instrumentation tests. 6# 7# Another group of tests relies upon the ability to compile the test with 8# address sanitizer instrumentation pass. These tests form "integration" tests 9# and have some elements of version skew -- they test the *host* compiler's 10# instrumentation against the just-built runtime library. 11 12include(CheckCXXCompilerFlag) 13include(CompilerRTCompile) 14 15include_directories(..) 16include_directories(../..) 17 18set(ASAN_UNITTEST_HEADERS 19 asan_mac_test.h 20 asan_test_config.h 21 asan_test_utils.h) 22 23set(ASAN_UNITTEST_COMMON_CFLAGS 24 ${COMPILER_RT_TEST_CFLAGS} 25 ${COMPILER_RT_GTEST_CFLAGS} 26 -I${COMPILER_RT_SOURCE_DIR}/include 27 -I${COMPILER_RT_SOURCE_DIR}/lib 28 -I${COMPILER_RT_SOURCE_DIR}/lib/asan 29 -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests 30 -fno-rtti 31 -O2 32 -Wno-format 33 -Werror=sign-compare) 34append_if(COMPILER_RT_HAS_WNO_VARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS) 35 36# -gline-tables-only must be enough for ASan, so use it if possible. 37if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") 38 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only) 39else() 40 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g) 41endif() 42 43# Use -D instead of definitions to please custom compile command. 44list(APPEND ASAN_UNITTEST_COMMON_CFLAGS 45 -DASAN_HAS_BLACKLIST=1 46 -DASAN_HAS_EXCEPTIONS=1 47 -DASAN_UAR=0) 48 49set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore") 50set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS 51 ${ASAN_UNITTEST_COMMON_CFLAGS} 52 -fsanitize=address 53 "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}" 54 -mllvm -asan-instrument-assembly 55) 56 57if(NOT MSVC) 58 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++) 59endif() 60 61# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. 62if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE") 63 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++") 64endif() 65 66# Unit tests on Mac depend on Foundation. 67if(APPLE) 68 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation) 69endif() 70if(ANDROID) 71 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie) 72endif() 73 74set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS 75 ${ASAN_UNITTEST_COMMON_LINKFLAGS}) 76# On Android, we link with ASan runtime manually. On other platforms we depend 77# on Clang driver behavior, passing -fsanitize=address flag. 78if(NOT ANDROID) 79 list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address) 80endif() 81 82set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS 83 ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS} 84 -shared-libasan) 85 86set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS}) 87append_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS) 88append_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS) 89append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS) 90append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread 91 ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS) 92 93# Compile source for the given architecture, using compiler 94# options in ${ARGN}, and add it to the object list. 95macro(asan_compile obj_list source arch kind) 96 get_filename_component(basename ${source} NAME) 97 set(output_obj "${obj_list}.${basename}.${arch}${kind}.o") 98 get_target_flags_for_arch(${arch} TARGET_CFLAGS) 99 set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE}) 100 if(NOT COMPILER_RT_STANDALONE_BUILD) 101 list(APPEND COMPILE_DEPS gtest asan) 102 endif() 103 clang_compile(${output_obj} ${source} 104 CFLAGS ${ARGN} ${TARGET_CFLAGS} 105 DEPS ${COMPILE_DEPS}) 106 list(APPEND ${obj_list} ${output_obj}) 107endmacro() 108 109# Link ASan unit test for a given architecture from a set 110# of objects in with given linker flags. 111macro(add_asan_test test_suite test_name arch kind) 112 parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN}) 113 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 114 set(TEST_DEPS ${TEST_OBJECTS}) 115 if(NOT COMPILER_RT_STANDALONE_BUILD) 116 list(APPEND TEST_DEPS asan) 117 endif() 118 if(TEST_WITH_TEST_RUNTIME) 119 list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME}) 120 if(NOT MSVC) 121 list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a) 122 else() 123 list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib) 124 endif() 125 endif() 126 add_compiler_rt_test(${test_suite} ${test_name} 127 OBJECTS ${TEST_OBJECTS} 128 DEPS ${TEST_DEPS} 129 LINK_FLAGS ${TEST_LINKFLAGS} 130 ${TARGET_LINK_FLAGS}) 131endmacro() 132 133# Main AddressSanitizer unit tests. 134add_custom_target(AsanUnitTests) 135set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests") 136# ASan benchmarks (not actively used now). 137add_custom_target(AsanBenchmarks) 138set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks") 139 140set(ASAN_NOINST_TEST_SOURCES 141 ${COMPILER_RT_GTEST_SOURCE} 142 asan_fake_stack_test.cc 143 asan_noinst_test.cc 144 asan_test_main.cc) 145 146set(ASAN_INST_TEST_SOURCES 147 ${COMPILER_RT_GTEST_SOURCE} 148 asan_asm_test.cc 149 asan_globals_test.cc 150 asan_interface_test.cc 151 asan_test.cc 152 asan_oob_test.cc 153 asan_mem_test.cc 154 asan_str_test.cc 155 asan_test_main.cc) 156if(APPLE) 157 list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc) 158endif() 159 160set(ASAN_BENCHMARKS_SOURCES 161 ${COMPILER_RT_GTEST_SOURCE} 162 asan_benchmarks_test.cc) 163 164# Adds ASan unit tests and benchmarks for architecture. 165macro(add_asan_tests_for_arch_and_kind arch kind) 166 # Instrumented tests. 167 set(ASAN_INST_TEST_OBJECTS) 168 foreach(src ${ASAN_INST_TEST_SOURCES}) 169 asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind} 170 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) 171 endforeach() 172 if (APPLE) 173 # Add Mac-specific helper. 174 asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind} 175 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN}) 176 endif() 177 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" ${arch} ${kind} 178 OBJECTS ${ASAN_INST_TEST_OBJECTS} 179 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 180 if(COMPILER_RT_BUILD_SHARED_ASAN) 181 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Dynamic-Test" ${arch} ${kind} 182 OBJECTS ${ASAN_INST_TEST_OBJECTS} 183 LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}) 184 endif() 185 186 # Add static ASan runtime that will be linked with uninstrumented tests. 187 set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind}) 188 if(APPLE) 189 set(ASAN_TEST_RUNTIME_OBJECTS 190 $<TARGET_OBJECTS:RTAsan.osx> 191 $<TARGET_OBJECTS:RTInterception.osx> 192 $<TARGET_OBJECTS:RTSanitizerCommon.osx> 193 $<TARGET_OBJECTS:RTLSanCommon.osx>) 194 else() 195 set(ASAN_TEST_RUNTIME_OBJECTS 196 $<TARGET_OBJECTS:RTAsan.${arch}> 197 $<TARGET_OBJECTS:RTAsan_cxx.${arch}> 198 $<TARGET_OBJECTS:RTInterception.${arch}> 199 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 200 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>) 201 if(NOT MSVC) 202 list(APPEND ASAN_TEST_RUNTIME_OBJECTS 203 $<TARGET_OBJECTS:RTLSanCommon.${arch}>) 204 endif() 205 endif() 206 add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS}) 207 set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES 208 ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 209 # Uninstrumented tests. 210 set(ASAN_NOINST_TEST_OBJECTS) 211 foreach(src ${ASAN_NOINST_TEST_SOURCES}) 212 asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind} 213 ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN}) 214 endforeach() 215 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind} 216 OBJECTS ${ASAN_NOINST_TEST_OBJECTS} 217 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS} 218 WITH_TEST_RUNTIME) 219 220 # Benchmarks. 221 set(ASAN_BENCHMARKS_OBJECTS) 222 foreach(src ${ASAN_BENCHMARKS_SOURCES}) 223 asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind} 224 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) 225 endforeach() 226 add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" ${arch} ${kind} 227 OBJECTS ${ASAN_BENCHMARKS_OBJECTS} 228 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 229 if(COMPILER_RT_BUILD_SHARED_ASAN) 230 add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Dynamic-Benchmark" ${arch} ${kind} 231 OBJECTS ${ASAN_BENCHMARKS_OBJECTS} 232 LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}) 233 endif() 234endmacro() 235 236if(COMPILER_RT_CAN_EXECUTE_TESTS) 237 foreach(arch ${ASAN_SUPPORTED_ARCH}) 238 add_asan_tests_for_arch_and_kind(${arch} "-inline") 239 add_asan_tests_for_arch_and_kind(${arch} "-with-calls" 240 -mllvm -asan-instrumentation-with-call-threshold=0) 241 endforeach() 242endif() 243 244if(ANDROID) 245 # We assume that unit tests on Android are built in a build 246 # tree with fresh Clang as a host compiler. 247 248 # Test w/o ASan instrumentation. Link it with ASan statically. 249 add_executable(AsanNoinstTest 250 $<TARGET_OBJECTS:RTAsan.arm.android> 251 $<TARGET_OBJECTS:RTInterception.arm.android> 252 $<TARGET_OBJECTS:RTSanitizerCommon.arm.android> 253 ${COMPILER_RT_GTEST_SOURCE} 254 ${ASAN_NOINST_TEST_SOURCES}) 255 set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS}) 256 set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS}) 257 target_link_libraries(AsanNoinstTest log) 258 259 # Test with ASan instrumentation. Link with ASan dynamic runtime. 260 add_executable(AsanTest 261 ${COMPILER_RT_GTEST_SOURCE} 262 ${ASAN_INST_TEST_SOURCES}) 263 set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 264 set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 265 target_link_libraries(AsanTest clang_rt.asan-arm-android) 266 267 # Setup correct output directory and link flags. 268 set_target_properties(AsanNoinstTest AsanTest PROPERTIES 269 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 270 # Add unit test to test suite. 271 add_dependencies(AsanUnitTests AsanNoinstTest AsanTest) 272endif() 273