344 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			CMake
		
	
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			CMake
		
	
	
	
| # Testing rules for AddressSanitizer.
 | |
| #
 | |
| # These are broken into two buckets. One set of tests directly interacts with
 | |
| # the runtime library and checks its functionality. These are the
 | |
| # no-instrumentation tests.
 | |
| #
 | |
| # Another group of tests relies upon the ability to compile the test with
 | |
| # address sanitizer instrumentation pass. These tests form "integration" tests
 | |
| # and have some elements of version skew -- they test the *host* compiler's
 | |
| # instrumentation against the just-built runtime library.
 | |
| 
 | |
| include(CheckCXXCompilerFlag)
 | |
| include(CompilerRTCompile)
 | |
| 
 | |
| include_directories(..)
 | |
| include_directories(../..)
 | |
| 
 | |
| set(ASAN_UNITTEST_HEADERS
 | |
|   asan_mac_test.h
 | |
|   asan_test_config.h
 | |
|   asan_test_utils.h)
 | |
| 
 | |
| set(ASAN_UNITTEST_COMMON_CFLAGS
 | |
|   ${COMPILER_RT_UNITTEST_CFLAGS}
 | |
|   ${COMPILER_RT_GTEST_CFLAGS}
 | |
|   -I${COMPILER_RT_SOURCE_DIR}/include
 | |
|   -I${COMPILER_RT_SOURCE_DIR}/lib
 | |
|   -I${COMPILER_RT_SOURCE_DIR}/lib/asan
 | |
|   -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
 | |
|   -fno-rtti
 | |
|   -O2
 | |
|   -Wno-format
 | |
|   -Werror=sign-compare
 | |
|   -Wno-non-virtual-dtor)
 | |
| append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
 | |
| 
 | |
| # This will ensure the target linker is used
 | |
| # during cross compilation
 | |
| set(ASAN_UNITTEST_COMMON_LINKFLAGS
 | |
|   ${COMPILER_RT_UNITTEST_LINKFLAGS})
 | |
| 
 | |
| # -gline-tables-only must be enough for ASan, so use it if possible.
 | |
| if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
 | |
| else()
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
 | |
| endif()
 | |
| if(MSVC)
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
 | |
| endif()
 | |
| list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -g)
 | |
| 
 | |
| # Use -D instead of definitions to please custom compile command.
 | |
| list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
 | |
|   -DASAN_HAS_BLACKLIST=1
 | |
|   -DASAN_HAS_EXCEPTIONS=1
 | |
|   -DASAN_UAR=0)
 | |
| 
 | |
| if(APPLE)
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})
 | |
| endif()
 | |
| 
 | |
| if(MSVC)
 | |
|   # Disable exceptions on Windows until they work reliably.
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0)
 | |
| endif()
 | |
| 
 | |
| set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
 | |
| set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
 | |
|   ${ASAN_UNITTEST_COMMON_CFLAGS}
 | |
|   -fsanitize=address
 | |
|   "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
 | |
| )
 | |
| if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
 | |
|   list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)
 | |
| endif()
 | |
| 
 | |
| if(NOT MSVC)
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
 | |
| endif()
 | |
| 
 | |
| # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
 | |
| if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
 | |
| endif()
 | |
| 
 | |
| # Unit tests on Mac depend on Foundation.
 | |
| if(APPLE)
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
 | |
| endif()
 | |
| if(ANDROID)
 | |
|   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
 | |
| endif()
 | |
| 
 | |
| set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
 | |
|   ${ASAN_UNITTEST_COMMON_LINKFLAGS})
 | |
| list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
 | |
| 
 | |
| set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
 | |
|   ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
 | |
|   -shared-libasan)
 | |
| 
 | |
| set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
 | |
| # NDK r10 requires -latomic almost always.
 | |
| append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)
 | |
| 
 | |
| set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
 | |
| append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
 | |
| append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
 | |
| append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS)
 | |
| append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
 | |
| append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
 | |
|           ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
 | |
| 
 | |
| # TODO(eugenis): move all -l flags above to _LIBS?
 | |
| set(ASAN_UNITTEST_NOINST_LIBS)
 | |
| append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)
 | |
| # NDK r10 requires -latomic almost always.
 | |
| append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)
 | |
| 
 | |
| # Compile source for the given architecture, using compiler
 | |
| # options in ${ARGN}, and add it to the object list.
 | |
| macro(asan_compile obj_list source arch kind)
 | |
|   get_filename_component(basename ${source} NAME)
 | |
|   if(CMAKE_CONFIGURATION_TYPES)
 | |
|     set(output_obj "${CMAKE_CFG_INTDIR}/${obj_list}.${basename}.${arch}${kind}.o")
 | |
|   else()
 | |
|     set(output_obj "${obj_list}.${basename}.${arch}${kind}.o")
 | |
|   endif()
 | |
|   get_target_flags_for_arch(${arch} TARGET_CFLAGS)
 | |
|   set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})
 | |
|   if(NOT COMPILER_RT_STANDALONE_BUILD)
 | |
|     list(APPEND COMPILE_DEPS gtest asan)
 | |
|   endif()
 | |
|   clang_compile(${output_obj} ${source}
 | |
|                 CFLAGS ${ARGN} ${TARGET_CFLAGS}
 | |
|                 DEPS ${COMPILE_DEPS})
 | |
|   list(APPEND ${obj_list} ${output_obj})
 | |
| endmacro()
 | |
| 
 | |
| # Link ASan unit test for a given architecture from a set
 | |
| # of objects in with given linker flags.
 | |
| macro(add_asan_test test_suite test_name arch kind)
 | |
|   cmake_parse_arguments(TEST "WITH_TEST_RUNTIME" "" "OBJECTS;LINKFLAGS;SUBDIR" ${ARGN})
 | |
|   get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
 | |
|   set(TEST_DEPS ${TEST_OBJECTS})
 | |
|   if(NOT COMPILER_RT_STANDALONE_BUILD)
 | |
|     list(APPEND TEST_DEPS asan)
 | |
|   endif()
 | |
|   if(TEST_WITH_TEST_RUNTIME)
 | |
|     list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
 | |
|     if(CMAKE_CONFIGURATION_TYPES)
 | |
|      set(configuration_path "${CMAKE_CFG_INTDIR}/")
 | |
|     else()
 | |
|      set(configuration_path "")
 | |
|     endif()
 | |
|     if(NOT MSVC)
 | |
|       set(asan_test_runtime_path ${configuration_path}lib${ASAN_TEST_RUNTIME}.a)
 | |
|     else()
 | |
|       set(asan_test_runtime_path ${configuration_path}${ASAN_TEST_RUNTIME}.lib)
 | |
|     endif()
 | |
|     list(APPEND TEST_OBJECTS ${asan_test_runtime_path})
 | |
|   endif()
 | |
|   add_compiler_rt_test(${test_suite} ${test_name}
 | |
|                        SUBDIR ${TEST_SUBDIR}
 | |
|                        OBJECTS ${TEST_OBJECTS}
 | |
|                        DEPS ${TEST_DEPS}
 | |
|                        LINK_FLAGS ${TEST_LINKFLAGS}
 | |
|                                   ${TARGET_LINK_FLAGS})
 | |
| endmacro()
 | |
| 
 | |
| # Main AddressSanitizer unit tests.
 | |
| add_custom_target(AsanUnitTests)
 | |
| set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
 | |
| 
 | |
| # AddressSanitizer unit tests with dynamic runtime (on platforms where it's
 | |
| # not the default).
 | |
| add_custom_target(AsanDynamicUnitTests)
 | |
| set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
 | |
| # ASan benchmarks (not actively used now).
 | |
| add_custom_target(AsanBenchmarks)
 | |
| set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT Tests")
 | |
| 
 | |
| set(ASAN_NOINST_TEST_SOURCES
 | |
|   ${COMPILER_RT_GTEST_SOURCE}
 | |
|   asan_fake_stack_test.cc
 | |
|   asan_noinst_test.cc
 | |
|   asan_test_main.cc)
 | |
| 
 | |
| set(ASAN_INST_TEST_SOURCES
 | |
|   ${COMPILER_RT_GTEST_SOURCE}
 | |
|   asan_asm_test.cc
 | |
|   asan_globals_test.cc
 | |
|   asan_interface_test.cc
 | |
|   asan_test.cc
 | |
|   asan_oob_test.cc
 | |
|   asan_mem_test.cc
 | |
|   asan_str_test.cc
 | |
|   asan_test_main.cc)
 | |
| if(APPLE)
 | |
|   list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)
 | |
| endif()
 | |
| 
 | |
| set(ASAN_BENCHMARKS_SOURCES
 | |
|   ${COMPILER_RT_GTEST_SOURCE}
 | |
|   asan_benchmarks_test.cc)
 | |
| 
 | |
| # Adds ASan unit tests and benchmarks for architecture.
 | |
| macro(add_asan_tests_for_arch_and_kind arch kind)
 | |
|   # Instrumented tests.
 | |
|   set(ASAN_INST_TEST_OBJECTS)
 | |
|   foreach(src ${ASAN_INST_TEST_SOURCES})
 | |
|     asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}
 | |
|       ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
 | |
|   endforeach()
 | |
|   if (APPLE)
 | |
|     # Add Mac-specific helper.
 | |
|     asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}
 | |
|                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})
 | |
|   endif()
 | |
| 
 | |
|   # Create the 'default' folder where ASAN tests are produced.
 | |
|   if(CMAKE_CONFIGURATION_TYPES)
 | |
|     foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
 | |
|       file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/default/${build_mode}")
 | |
|     endforeach()
 | |
|   else()
 | |
|     file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/default")
 | |
|   endif()
 | |
| 
 | |
|   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test"
 | |
|                 ${arch} ${kind} SUBDIR "default"
 | |
|                 OBJECTS ${ASAN_INST_TEST_OBJECTS}
 | |
|                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
 | |
|   if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
 | |
|     # Create the 'dynamic' folder where ASAN tests are produced.
 | |
|     if(CMAKE_CONFIGURATION_TYPES)
 | |
|       foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
 | |
|         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic/${build_mode}")
 | |
|       endforeach()
 | |
|     else()
 | |
|       file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic")
 | |
|     endif()
 | |
| 
 | |
|     add_asan_test(AsanDynamicUnitTests "Asan-${arch}${kind}-Dynamic-Test"
 | |
|                   ${arch} ${kind} SUBDIR "dynamic"
 | |
|                   OBJECTS ${ASAN_INST_TEST_OBJECTS}
 | |
|                   LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
 | |
|   endif()
 | |
| 
 | |
|   # Add static ASan runtime that will be linked with uninstrumented tests.
 | |
|   set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
 | |
|   if(APPLE)
 | |
|     set(ASAN_TEST_RUNTIME_OBJECTS
 | |
|       $<TARGET_OBJECTS:RTAsan_dynamic.osx>
 | |
|       $<TARGET_OBJECTS:RTInterception.osx>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommon.osx>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
 | |
|       $<TARGET_OBJECTS:RTLSanCommon.osx>
 | |
|       $<TARGET_OBJECTS:RTUbsan.osx>)
 | |
|   else()
 | |
|     set(ASAN_TEST_RUNTIME_OBJECTS
 | |
|       $<TARGET_OBJECTS:RTAsan.${arch}>
 | |
|       $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
 | |
|       $<TARGET_OBJECTS:RTInterception.${arch}>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
 | |
|       $<TARGET_OBJECTS:RTLSanCommon.${arch}>
 | |
|       $<TARGET_OBJECTS:RTUbsan.${arch}>
 | |
|       $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
 | |
|   endif()
 | |
|   add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
 | |
|   set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
 | |
|     ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
 | |
|     FOLDER "Compiler-RT Runtime tests")
 | |
|   # Uninstrumented tests.
 | |
|   set(ASAN_NOINST_TEST_OBJECTS)
 | |
|   foreach(src ${ASAN_NOINST_TEST_SOURCES})
 | |
|     asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}
 | |
|                  ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})
 | |
|   endforeach()
 | |
|   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test"
 | |
|                 ${arch} ${kind} SUBDIR "default"
 | |
|                 OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
 | |
|                 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
 | |
|                 WITH_TEST_RUNTIME)
 | |
| 
 | |
|   # Benchmarks.
 | |
|   set(ASAN_BENCHMARKS_OBJECTS)
 | |
|   foreach(src ${ASAN_BENCHMARKS_SOURCES})
 | |
|     asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}
 | |
|                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
 | |
|   endforeach()
 | |
|   add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark"
 | |
|                 ${arch} ${kind} SUBDIR "default"
 | |
|                 OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
 | |
|                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
 | |
| endmacro()
 | |
| 
 | |
| if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
 | |
|   set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
 | |
|   if(APPLE)
 | |
|     darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
 | |
|   endif()
 | |
|   foreach(arch ${ASAN_TEST_ARCH})
 | |
|     add_asan_tests_for_arch_and_kind(${arch} "-inline")
 | |
|     add_asan_tests_for_arch_and_kind(${arch} "-with-calls"
 | |
|       -mllvm -asan-instrumentation-with-call-threshold=0)
 | |
|   endforeach()
 | |
| endif()
 | |
| 
 | |
| if(ANDROID)
 | |
|   foreach(arch ${ASAN_SUPPORTED_ARCH})
 | |
|     # Test w/o ASan instrumentation. Link it with ASan statically.
 | |
|     add_executable(AsanNoinstTest # FIXME: .arch?
 | |
|       $<TARGET_OBJECTS:RTAsan.${arch}>
 | |
|       $<TARGET_OBJECTS:RTInterception.${arch}>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
 | |
|       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
 | |
|       $<TARGET_OBJECTS:RTUbsan.${arch}>
 | |
|       $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
 | |
|       ${COMPILER_RT_GTEST_SOURCE}
 | |
|       ${ASAN_NOINST_TEST_SOURCES})
 | |
|     set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
 | |
|     set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
 | |
|     target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
 | |
| 
 | |
|     # Test with ASan instrumentation. Link with ASan dynamic runtime.
 | |
|     add_executable(AsanTest
 | |
|       ${COMPILER_RT_GTEST_SOURCE}
 | |
|       ${ASAN_INST_TEST_SOURCES})
 | |
|     set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
 | |
|     set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
 | |
|     target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
 | |
| 
 | |
|     # Setup correct output directory and link flags.
 | |
|     set_target_properties(AsanNoinstTest AsanTest PROPERTIES
 | |
|       RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
 | |
|     # Add unit tests to the test suite.
 | |
|     add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
 | |
|   endforeach()
 | |
| endif()
 |