CMakeLists.txt revision 5d9d807a9d82b566387e3064882a87cb8fd4ef22
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 18# Use zero-based shadow on Android. 19if(ANDROID) 20 set(ASAN_TESTS_USE_ZERO_BASE_SHADOW TRUE) 21else() 22 set(ASAN_TESTS_USE_ZERO_BASE_SHADOW FALSE) 23endif() 24 25set(ASAN_UNITTEST_HEADERS 26 asan_mac_test.h 27 asan_test_config.h 28 asan_test_utils.h) 29 30set(ASAN_UNITTEST_COMMON_CFLAGS 31 ${COMPILER_RT_GTEST_INCLUDE_CFLAGS} 32 -I${COMPILER_RT_SOURCE_DIR}/include 33 -I${COMPILER_RT_SOURCE_DIR}/lib 34 -I${COMPILER_RT_SOURCE_DIR}/lib/asan 35 -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests 36 -Wall 37 -Wno-format 38 -Werror 39 -Werror=sign-compare 40 -g 41 -O2) 42if(SUPPORTS_NO_VARIADIC_MACROS_FLAG) 43 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros) 44endif() 45 46# Use -D instead of definitions to please custom compile command. 47list(APPEND ASAN_UNITTEST_COMMON_CFLAGS 48 -DASAN_HAS_BLACKLIST=1 49 -DASAN_HAS_EXCEPTIONS=1 50 -DASAN_UAR=0) 51if(ANDROID) 52 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS 53 -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=0 54 -DASAN_NEEDS_SEGV=0) 55else() 56 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS 57 -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1 58 -DASAN_NEEDS_SEGV=1) 59endif() 60 61set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore") 62set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS 63 ${ASAN_UNITTEST_COMMON_CFLAGS} 64 -fsanitize=address 65 "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}" 66 -mllvm -asan-stack=1 67 -mllvm -asan-globals=1 68 -mllvm -asan-mapping-scale=0 # default will be used 69 -mllvm -asan-mapping-offset-log=-1 # default will be used 70 -mllvm -asan-use-after-return=0 71) 72if(ASAN_TESTS_USE_ZERO_BASE_SHADOW) 73 list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS 74 -fsanitize-address-zero-base-shadow) 75endif() 76 77# Unit tests require libstdc++. 78set(ASAN_UNITTEST_COMMON_LINKFLAGS -lstdc++) 79# Unit tests on Mac depend on Foundation. 80if(APPLE) 81 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation) 82endif() 83if(ASAN_TESTS_USE_ZERO_BASE_SHADOW) 84 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie) 85endif() 86 87set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS 88 ${ASAN_UNITTEST_COMMON_LINKFLAGS}) 89# On Android, we link with ASan runtime manually. On other platforms we depend 90# on Clang driver behavior, passing -fsanitize=address flag. 91if(NOT ANDROID) 92 list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address) 93endif() 94 95set(ASAN_UNITTEST_NOINST_LINKFLAGS 96 ${ASAN_UNITTEST_COMMON_LINKFLAGS} 97 -ldl) 98if(NOT ANDROID) 99 list(APPEND ASAN_UNITTEST_NOINST_LINKFLAGS -lpthread) 100endif() 101 102# Compile source for the given architecture, using compiler 103# options in ${ARGN}, and add it to the object list. 104macro(asan_compile obj_list source arch) 105 get_filename_component(basename ${source} NAME) 106 set(output_obj "${obj_list}.${basename}.${arch}.o") 107 get_target_flags_for_arch(${arch} TARGET_CFLAGS) 108 clang_compile(${output_obj} ${source} 109 CFLAGS ${ARGN} ${TARGET_CFLAGS} 110 DEPS gtest ${ASAN_RUNTIME_LIBRARIES} 111 ${ASAN_UNITTEST_HEADERS} 112 ${ASAN_BLACKLIST_FILE}) 113 list(APPEND ${obj_list} ${output_obj}) 114endmacro() 115 116# Link ASan unit test for a given architecture from a set 117# of objects in with given linker flags. 118macro(add_asan_test test_suite test_name arch) 119 parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN}) 120 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 121 set(TEST_DEPS ${ASAN_RUNTIME_LIBRARIES} ${TEST_OBJECTS}) 122 if(TEST_WITH_TEST_RUNTIME) 123 list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME}) 124 list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a) 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_noinst_test.cc 143 asan_test_main.cc) 144if(NOT APPLE AND NOT ANDROID) 145 # Do not build asan_fake_stack_test.cc on OS X and Android, since it requires 146 # exposing additional functions from the runtime. 147 # See also https://code.google.com/p/address-sanitizer/issues/detail?id=222 148 list(APPEND ASAN_NOINST_TEST_SOURCES asan_fake_stack_test.cc) 149endif() 150 151set(ASAN_INST_TEST_SOURCES 152 ${COMPILER_RT_GTEST_SOURCE} 153 asan_globals_test.cc 154 asan_interface_test.cc 155 asan_test.cc 156 asan_oob_test.cc 157 asan_mem_test.cc 158 asan_str_test.cc 159 asan_test_main.cc) 160if(APPLE) 161 list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc) 162endif() 163 164set(ASAN_BENCHMARKS_SOURCES 165 ${COMPILER_RT_GTEST_SOURCE} 166 asan_benchmarks_test.cc) 167 168# Adds ASan unit tests and benchmarks for architecture. 169macro(add_asan_tests_for_arch arch) 170 # Instrumented tests. 171 set(ASAN_INST_TEST_OBJECTS) 172 foreach(src ${ASAN_INST_TEST_SOURCES}) 173 asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} 174 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 175 endforeach() 176 if (APPLE) 177 # Add Mac-specific helper. 178 asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} 179 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC) 180 endif() 181 add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch} 182 OBJECTS ${ASAN_INST_TEST_OBJECTS} 183 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 184 185 # Add static ASan runtime that will be linked with uninstrumented tests. 186 set(ASAN_TEST_RUNTIME RTAsanTest.${arch}) 187 if(APPLE) 188 set(ASAN_TEST_RUNTIME_OBJECTS 189 $<TARGET_OBJECTS:RTAsan.osx> 190 $<TARGET_OBJECTS:RTInterception.osx> 191 $<TARGET_OBJECTS:RTSanitizerCommon.osx> 192 $<TARGET_OBJECTS:RTLSanCommon.osx>) 193 else() 194 set(ASAN_TEST_RUNTIME_OBJECTS 195 $<TARGET_OBJECTS:RTAsan.${arch}> 196 $<TARGET_OBJECTS:RTInterception.${arch}> 197 $<TARGET_OBJECTS:RTLSanCommon.${arch}> 198 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 199 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>) 200 endif() 201 add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS}) 202 set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES 203 ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 204 # Uninstrumented tests. 205 set(ASAN_NOINST_TEST_OBJECTS) 206 foreach(src ${ASAN_NOINST_TEST_SOURCES}) 207 asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} 208 ${ASAN_UNITTEST_COMMON_CFLAGS}) 209 endforeach() 210 add_asan_test(AsanUnitTests "Asan-${arch}-Noinst-Test" ${arch} 211 OBJECTS ${ASAN_NOINST_TEST_OBJECTS} 212 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS} 213 WITH_TEST_RUNTIME) 214 215 # Benchmarks. 216 set(ASAN_BENCHMARKS_OBJECTS) 217 foreach(src ${ASAN_BENCHMARKS_SOURCES}) 218 asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} 219 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 220 endforeach() 221 add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch} 222 OBJECTS ${ASAN_BENCHMARKS_OBJECTS} 223 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 224endmacro() 225 226if(COMPILER_RT_CAN_EXECUTE_TESTS) 227 foreach(arch ${ASAN_SUPPORTED_ARCH}) 228 add_asan_tests_for_arch(${arch}) 229 endforeach() 230endif() 231 232if(ANDROID) 233 # We assume that unit tests on Android are built in a build 234 # tree with fresh Clang as a host compiler. 235 236 # Test w/o ASan instrumentation. Link it with ASan statically. 237 add_executable(AsanNoinstTest 238 $<TARGET_OBJECTS:RTAsan.arm.android> 239 $<TARGET_OBJECTS:RTInterception.arm.android> 240 $<TARGET_OBJECTS:RTSanitizerCommon.arm.android> 241 ${COMPILER_RT_GTEST_SOURCE} 242 ${ASAN_NOINST_TEST_SOURCES}) 243 set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS}) 244 set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS}) 245 246 # Test with ASan instrumentation. Link with ASan dynamic runtime. 247 add_executable(AsanTest 248 ${COMPILER_RT_GTEST_SOURCE} 249 ${ASAN_INST_TEST_SOURCES}) 250 set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 251 set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) 252 target_link_libraries(AsanTest clang_rt.asan-arm-android) 253 254 # Setup correct output directory and link flags. 255 set_target_properties(AsanNoinstTest AsanTest PROPERTIES 256 RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 257 # Add unit test to test suite. 258 add_dependencies(AsanUnitTests AsanNoinstTest AsanTest) 259endif() 260