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  ${COMPILER_RT_ASAN_SHADOW_SCALE_LLVM_FLAG}
27  -I${COMPILER_RT_SOURCE_DIR}/include
28  -I${COMPILER_RT_SOURCE_DIR}/lib
29  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
30  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
31  -fno-rtti
32  -O2
33  -Wno-format
34  -Werror=sign-compare)
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_LINK_FLAGS
40  ${COMPILER_RT_UNITTEST_LINK_FLAGS})
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_LINK_FLAGS -g)
52
53# Use -D instead of definitions to please custom compile command.
54list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
55  ${COMPILER_RT_ASAN_SHADOW_SCALE_FLAG}
56  -DASAN_HAS_IGNORELIST=1
57  -DASAN_HAS_EXCEPTIONS=1
58  -DASAN_UAR=0
59  )
60
61if(APPLE)
62  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
63  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
64
65  add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
66  add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
67  add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
68  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS})
69endif()
70
71set(ASAN_IGNORELIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
72set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
73  ${ASAN_UNITTEST_COMMON_CFLAGS}
74  -fsanitize=address
75  "-fsanitize-ignorelist=${ASAN_IGNORELIST_FILE}"
76)
77if(NOT MSVC)
78  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++)
79endif()
80
81# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
82if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
83  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS "-lc++")
84endif()
85
86# Unit tests on Mac depend on Foundation.
87if(APPLE)
88  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -framework Foundation)
89endif()
90if(ANDROID)
91  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -pie)
92endif()
93
94set(ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS
95  ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
96list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS -fsanitize=address)
97
98set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS
99  ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}
100  -shared-libasan)
101
102set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
103# NDK r10 requires -latomic almost always.
104append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)
105
106set(ASAN_UNITTEST_NOINST_LINK_FLAGS ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
107if(NOT APPLE)
108  append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINK_FLAGS)
109  append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINK_FLAGS)
110  append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINK_FLAGS)
111  append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINK_FLAGS)
112  append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS)
113endif()
114
115# TODO(eugenis): move all -l flags above to _LIBS?
116set(ASAN_UNITTEST_NOINST_LIBS)
117append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)
118# NDK r10 requires -latomic almost always.
119append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)
120
121# Main AddressSanitizer unit tests.
122add_custom_target(AsanUnitTests)
123set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
124
125# AddressSanitizer unit tests with dynamic runtime (on platforms where it's
126# not the default).
127add_custom_target(AsanDynamicUnitTests)
128set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
129# ASan benchmarks (not actively used now).
130add_custom_target(AsanBenchmarks)
131set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT Tests")
132
133set(ASAN_NOINST_TEST_SOURCES
134  ${COMPILER_RT_GTEST_SOURCE}
135  asan_fake_stack_test.cpp
136  asan_noinst_test.cpp
137  asan_test_main.cpp
138  )
139
140set(ASAN_INST_TEST_SOURCES
141  ${COMPILER_RT_GTEST_SOURCE}
142  asan_globals_test.cpp
143  asan_interface_test.cpp
144  asan_internal_interface_test.cpp
145  asan_test.cpp
146  asan_oob_test.cpp
147  asan_mem_test.cpp
148  asan_str_test.cpp
149  asan_test_main.cpp
150  )
151if(APPLE)
152  list(APPEND ASAN_INST_TEST_SOURCES
153    asan_mac_test.cpp
154    asan_mac_test_helpers.mm
155    )
156endif()
157
158set(ASAN_BENCHMARKS_SOURCES
159  ${COMPILER_RT_GTEST_SOURCE}
160  asan_benchmarks_test.cpp
161  )
162
163function(add_asan_tests arch test_runtime)
164  cmake_parse_arguments(TEST "" "KIND" "CFLAGS" ${ARGN})
165
166  # Closure to keep the values.
167  function(generate_asan_tests test_objects test_suite testname)
168    generate_compiler_rt_tests(${test_objects} ${test_suite} ${testname} ${arch}
169      COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_IGNORELIST_FILE}
170      DEPS gtest asan
171      KIND ${TEST_KIND}
172      ${ARGN}
173      )
174    set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)
175  endfunction()
176
177  set(ASAN_INST_TEST_OBJECTS)
178  generate_asan_tests(ASAN_INST_TEST_OBJECTS AsanUnitTests
179    "Asan-${arch}${TEST_KIND}-Test"
180    SUBDIR "default"
181    LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}
182    SOURCES ${ASAN_INST_TEST_SOURCES}
183    CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${TEST_CFLAGS})
184
185  if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
186    set(dynamic_test_name "Asan-${arch}${TEST_KIND}-Dynamic-Test")
187    if(MSVC)
188
189      # With the MSVC CRT, the choice between static and dynamic CRT is made at
190      # compile time with a macro. Simulate the effect of passing /MD to clang-cl.
191      set(ASAN_DYNAMIC_TEST_OBJECTS)
192      generate_asan_tests(ASAN_DYNAMIC_TEST_OBJECTS
193        AsanDynamicUnitTests "${dynamic_test_name}"
194        SUBDIR "dynamic"
195        CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -D_MT -D_DLL
196        SOURCES ${ASAN_INST_TEST_SOURCES}
197        LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
198          -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames
199        )
200    else()
201
202      # Otherwise, reuse ASAN_INST_TEST_OBJECTS.
203      add_compiler_rt_test(AsanDynamicUnitTests "${dynamic_test_name}" "${arch}"
204        SUBDIR "dynamic"
205        OBJECTS ${ASAN_INST_TEST_OBJECTS}
206        DEPS asan ${ASAN_INST_TEST_OBJECTS}
207        LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
208        )
209    endif()
210  endif()
211
212  # Uninstrumented tests.
213  set(ASAN_NOINST_TEST_OBJECTS)
214  generate_asan_tests(ASAN_NOINST_TEST_OBJECTS
215    AsanUnitTests "Asan-${arch}${TEST_KIND}-Noinst-Test"
216    SUBDIR "default"
217    CFLAGS ${ASAN_UNITTEST_COMMON_CFLAGS}
218    LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS}
219    SOURCES ${ASAN_NOINST_TEST_SOURCES}
220    RUNTIME ${test_runtime})
221
222  set(ASAN_BENCHMARK_OBJECTS)
223  generate_asan_tests(ASAN_BENCHMARK_OBJECTS
224    AsanBenchmarks "Asan-${arch}${TEST_KIND}-Benchmark"
225    SUBDIR "default"
226    CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}
227    SOURCES ${ASAN_BENCHMARKS_SOURCES}
228    LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
229endfunction()
230
231if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
232  set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
233  if(APPLE)
234    darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
235  endif()
236  list(REMOVE_ITEM ASAN_TEST_ARCH sparc sparcv9)
237  if(OS_NAME MATCHES "SunOS")
238    list(REMOVE_ITEM ASAN_TEST_ARCH x86_64)
239  endif()
240
241  foreach(arch ${ASAN_TEST_ARCH})
242
243    # Add static ASan runtime that will be linked with uninstrumented tests.
244    set(ASAN_TEST_RUNTIME RTAsanTest.${arch})
245    if(APPLE)
246      set(ASAN_TEST_RUNTIME_OBJECTS
247        $<TARGET_OBJECTS:RTAsan_dynamic.osx>
248        $<TARGET_OBJECTS:RTInterception.osx>
249        $<TARGET_OBJECTS:RTSanitizerCommon.osx>
250        $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
251        $<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
252        $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
253        $<TARGET_OBJECTS:RTLSanCommon.osx>
254        $<TARGET_OBJECTS:RTUbsan.osx>)
255    else()
256      set(ASAN_TEST_RUNTIME_OBJECTS
257        $<TARGET_OBJECTS:RTAsan.${arch}>
258        $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
259        $<TARGET_OBJECTS:RTInterception.${arch}>
260        $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
261        $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
262        $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
263        $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
264        $<TARGET_OBJECTS:RTLSanCommon.${arch}>
265        $<TARGET_OBJECTS:RTUbsan.${arch}>
266        $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
267    endif()
268    add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
269    set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
270      ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
271      FOLDER "Compiler-RT Runtime tests")
272
273    add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-inline")
274    add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-calls"
275      CFLAGS -mllvm -asan-instrumentation-with-call-threshold=0)
276  endforeach()
277endif()
278
279if(ANDROID)
280  foreach(arch ${ASAN_SUPPORTED_ARCH})
281    # Test w/o ASan instrumentation. Link it with ASan statically.
282    add_executable(AsanNoinstTest # FIXME: .arch?
283      $<TARGET_OBJECTS:RTAsan.${arch}>
284      $<TARGET_OBJECTS:RTInterception.${arch}>
285      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
286      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
287      $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
288      $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
289      $<TARGET_OBJECTS:RTLSanCommon.${arch}>
290      $<TARGET_OBJECTS:RTUbsan.${arch}>
291      $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
292      ${COMPILER_RT_GTEST_SOURCE}
293      ${ASAN_NOINST_TEST_SOURCES})
294    set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
295    set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINK_FLAGS})
296    target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
297
298    # Test with ASan instrumentation. Link with ASan dynamic runtime.
299    add_executable(AsanTest
300      ${COMPILER_RT_GTEST_SOURCE}
301      ${ASAN_INST_TEST_SOURCES})
302    set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
303    set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
304    target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
305
306    # Setup correct output directory and link flags.
307    set_target_properties(AsanNoinstTest AsanTest PROPERTIES
308      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
309    # Add unit tests to the test suite.
310    add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
311  endforeach()
312endif()
313