• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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