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 34 -Wno-non-virtual-dtor) 35append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS) 36 37# -gline-tables-only must be enough for ASan, so use it if possible. 38if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") 39 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only) 40else() 41 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g) 42endif() 43 44# Use -D instead of definitions to please custom compile command. 45list(APPEND ASAN_UNITTEST_COMMON_CFLAGS 46 -DASAN_HAS_BLACKLIST=1 47 -DASAN_HAS_EXCEPTIONS=1 48 -DASAN_UAR=0) 49 50if(APPLE) 51 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS}) 52 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS}) 53endif() 54 55if(MSVC) 56 # Disable exceptions on Windows until they work reliably. 57 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0) 58endif() 59 60set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore") 61set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS 62 ${ASAN_UNITTEST_COMMON_CFLAGS} 63 -fsanitize=address 64 "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}" 65) 66if(CAN_TARGET_x86_64 OR CAN_TARGET_i386) 67 list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly) 68endif() 69 70if(NOT MSVC) 71 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++) 72endif() 73 74# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. 75if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE") 76 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++") 77endif() 78 79# Unit tests on Mac depend on Foundation. 80if(APPLE) 81 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation) 82endif() 83if(ANDROID) 84 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie) 85endif() 86 87set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS 88 ${ASAN_UNITTEST_COMMON_LINKFLAGS}) 89list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address) 90 91set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS 92 ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS} 93 -shared-libasan) 94 95set(ASAN_UNITTEST_INSTRUMENTED_LIBS) 96# NDK r10 requires -latomic almost always. 97append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS) 98 99set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS}) 100append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS) 101append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS) 102append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS) 103append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS) 104append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread 105 ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS) 106 107# TODO(eugenis): move all -l flags above to _LIBS? 108set(ASAN_UNITTEST_NOINST_LIBS) 109append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS) 110# NDK r10 requires -latomic almost always. 111append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS) 112 113# Compile source for the given architecture, using compiler 114# options in ${ARGN}, and add it to the object list. 115macro(asan_compile obj_list source arch kind) 116 get_filename_component(basename ${source} NAME) 117 set(output_obj "${obj_list}.${basename}.${arch}${kind}.o") 118 get_target_flags_for_arch(${arch} TARGET_CFLAGS) 119 set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE}) 120 if(NOT COMPILER_RT_STANDALONE_BUILD) 121 list(APPEND COMPILE_DEPS gtest asan) 122 endif() 123 clang_compile(${output_obj} ${source} 124 CFLAGS ${ARGN} ${TARGET_CFLAGS} 125 DEPS ${COMPILE_DEPS}) 126 list(APPEND ${obj_list} ${output_obj}) 127endmacro() 128 129# Link ASan unit test for a given architecture from a set 130# of objects in with given linker flags. 131macro(add_asan_test test_suite test_name arch kind) 132 cmake_parse_arguments(TEST "WITH_TEST_RUNTIME" "" "OBJECTS;LINKFLAGS;SUBDIR" ${ARGN}) 133 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 134 set(TEST_DEPS ${TEST_OBJECTS}) 135 if(NOT COMPILER_RT_STANDALONE_BUILD) 136 list(APPEND TEST_DEPS asan) 137 endif() 138 if(TEST_WITH_TEST_RUNTIME) 139 list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME}) 140 if(NOT MSVC) 141 list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a) 142 else() 143 list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib) 144 endif() 145 endif() 146 add_compiler_rt_test(${test_suite} ${test_name} 147 SUBDIR ${TEST_SUBDIR} 148 OBJECTS ${TEST_OBJECTS} 149 DEPS ${TEST_DEPS} 150 LINK_FLAGS ${TEST_LINKFLAGS} 151 ${TARGET_LINK_FLAGS}) 152endmacro() 153 154# Main AddressSanitizer unit tests. 155add_custom_target(AsanUnitTests) 156set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests") 157# AddressSanitizer unit tests with dynamic runtime (on platforms where it's 158# not the default). 159add_custom_target(AsanDynamicUnitTests) 160set_target_properties(AsanDynamicUnitTests 161 PROPERTIES FOLDER "ASan unit tests with dynamic runtime") 162# ASan benchmarks (not actively used now). 163add_custom_target(AsanBenchmarks) 164set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks") 165 166set(ASAN_NOINST_TEST_SOURCES 167 ${COMPILER_RT_GTEST_SOURCE} 168 asan_fake_stack_test.cc 169 asan_noinst_test.cc 170 asan_test_main.cc) 171 172set(ASAN_INST_TEST_SOURCES 173 ${COMPILER_RT_GTEST_SOURCE} 174 asan_asm_test.cc 175 asan_globals_test.cc 176 asan_interface_test.cc 177 asan_test.cc 178 asan_oob_test.cc 179 asan_mem_test.cc 180 asan_str_test.cc 181 asan_test_main.cc) 182if(APPLE) 183 list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc) 184endif() 185 186set(ASAN_BENCHMARKS_SOURCES 187 ${COMPILER_RT_GTEST_SOURCE} 188 asan_benchmarks_test.cc) 189 190# Adds ASan unit tests and benchmarks for architecture. 191macro(add_asan_tests_for_arch_and_kind arch kind) 192 # Instrumented tests. 193 set(ASAN_INST_TEST_OBJECTS) 194 foreach(src ${ASAN_INST_TEST_SOURCES}) 195 asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind} 196 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) 197 endforeach() 198 if (APPLE) 199 # Add Mac-specific helper. 200 asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind} 201 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN}) 202 endif() 203 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/default") 204 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" 205 ${arch} ${kind} SUBDIR "default" 206 OBJECTS ${ASAN_INST_TEST_OBJECTS} 207 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 208 if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME) 209 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic") 210 add_asan_test(AsanDynamicUnitTests "Asan-${arch}${kind}-Dynamic-Test" 211 ${arch} ${kind} SUBDIR "dynamic" 212 OBJECTS ${ASAN_INST_TEST_OBJECTS} 213 LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}) 214 endif() 215 216 # Add static ASan runtime that will be linked with uninstrumented tests. 217 set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind}) 218 if(APPLE) 219 set(ASAN_TEST_RUNTIME_OBJECTS 220 $<TARGET_OBJECTS:RTAsan_dynamic.osx> 221 $<TARGET_OBJECTS:RTInterception.osx> 222 $<TARGET_OBJECTS:RTSanitizerCommon.osx> 223 $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx> 224 $<TARGET_OBJECTS:RTLSanCommon.osx> 225 $<TARGET_OBJECTS:RTUbsan.osx>) 226 else() 227 set(ASAN_TEST_RUNTIME_OBJECTS 228 $<TARGET_OBJECTS:RTAsan.${arch}> 229 $<TARGET_OBJECTS:RTAsan_cxx.${arch}> 230 $<TARGET_OBJECTS:RTInterception.${arch}> 231 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 232 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> 233 $<TARGET_OBJECTS:RTLSanCommon.${arch}> 234 $<TARGET_OBJECTS:RTUbsan.${arch}> 235 $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>) 236 endif() 237 add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS}) 238 set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES 239 ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 240 # Uninstrumented tests. 241 set(ASAN_NOINST_TEST_OBJECTS) 242 foreach(src ${ASAN_NOINST_TEST_SOURCES}) 243 asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind} 244 ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN}) 245 endforeach() 246 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" 247 ${arch} ${kind} SUBDIR "default" 248 OBJECTS ${ASAN_NOINST_TEST_OBJECTS} 249 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS} 250 WITH_TEST_RUNTIME) 251 252 # Benchmarks. 253 set(ASAN_BENCHMARKS_OBJECTS) 254 foreach(src ${ASAN_BENCHMARKS_SOURCES}) 255 asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind} 256 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) 257 endforeach() 258 add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" 259 ${arch} ${kind} SUBDIR "default" 260 OBJECTS ${ASAN_BENCHMARKS_OBJECTS} 261 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 262endmacro() 263 264if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID) 265 set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH}) 266 if(APPLE) 267 darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH) 268 endif() 269 foreach(arch ${ASAN_TEST_ARCH}) 270 add_asan_tests_for_arch_and_kind(${arch} "-inline") 271 add_asan_tests_for_arch_and_kind(${arch} "-with-calls" 272 -mllvm -asan-instrumentation-with-call-threshold=0) 273 endforeach() 274endif() 275 276if(ANDROID) 277 foreach(arch ${ASAN_SUPPORTED_ARCH}) 278 # Test w/o ASan instrumentation. Link it with ASan statically. 279 add_executable(AsanNoinstTest # FIXME: .arch? 280 $<TARGET_OBJECTS:RTAsan.${arch}> 281 $<TARGET_OBJECTS:RTInterception.${arch}> 282 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 283 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> 284 $<TARGET_OBJECTS:RTUbsan.${arch}> 285 $<TARGET_OBJECTS:RTUbsan_cxx.${arch}> 286 ${COMPILER_RT_GTEST_SOURCE} 287 ${ASAN_NOINST_TEST_SOURCES}) 288 set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS}) 289 set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS}) 290 target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS}) 291 292 # Test with ASan instrumentation. Link with ASan dynamic runtime. 293 add_executable(AsanTest 294 ${COMPILER_RT_GTEST_SOURCE} 295 ${ASAN_INST_TEST_SOURCES}) 296 set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 297 set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 298 target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS}) 299 300 # Setup correct output directory and link flags. 301 set_target_properties(AsanNoinstTest AsanTest PROPERTIES 302 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 303 # Add unit tests to the test suite. 304 add_dependencies(AsanUnitTests AsanNoinstTest AsanTest) 305 endforeach() 306endif() 307