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