1# Build for the ThreadSanitizer runtime support library. 2 3include_directories(..) 4 5set(TSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS}) 6# SANITIZER_COMMON_CFLAGS contains -fPIC, but it's performance-critical for 7# TSan runtime to be built with -fPIE to reduce the number of register spills. 8append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE TSAN_CFLAGS) 9append_rtti_flag(OFF TSAN_CFLAGS) 10 11if(COMPILER_RT_TSAN_DEBUG_OUTPUT) 12 # Add extra debug information to TSan runtime. This configuration is rarely 13 # used, but we need to support it so that debug output will not bitrot. 14 list(APPEND TSAN_CFLAGS -DTSAN_COLLECT_STATS=1 15 -DTSAN_DEBUG_OUTPUT=2) 16endif() 17 18set(TSAN_RTL_CFLAGS ${TSAN_CFLAGS}) 19append_list_if(COMPILER_RT_HAS_MSSE3_FLAG -msse3 TSAN_RTL_CFLAGS) 20append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=512 21 TSAN_RTL_CFLAGS) 22append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors 23 TSAN_RTL_CFLAGS) 24 25set(TSAN_SOURCES 26 rtl/tsan_clock.cc 27 rtl/tsan_debugging.cc 28 rtl/tsan_fd.cc 29 rtl/tsan_flags.cc 30 rtl/tsan_ignoreset.cc 31 rtl/tsan_interceptors.cc 32 rtl/tsan_interface.cc 33 rtl/tsan_interface_ann.cc 34 rtl/tsan_interface_atomic.cc 35 rtl/tsan_interface_java.cc 36 rtl/tsan_malloc_mac.cc 37 rtl/tsan_md5.cc 38 rtl/tsan_mman.cc 39 rtl/tsan_mutex.cc 40 rtl/tsan_mutexset.cc 41 rtl/tsan_preinit.cc 42 rtl/tsan_report.cc 43 rtl/tsan_rtl.cc 44 rtl/tsan_rtl_mutex.cc 45 rtl/tsan_rtl_proc.cc 46 rtl/tsan_rtl_report.cc 47 rtl/tsan_rtl_thread.cc 48 rtl/tsan_stack_trace.cc 49 rtl/tsan_stat.cc 50 rtl/tsan_suppressions.cc 51 rtl/tsan_symbolize.cc 52 rtl/tsan_sync.cc) 53 54set(TSAN_CXX_SOURCES 55 rtl/tsan_new_delete.cc) 56 57if(APPLE) 58 list(APPEND TSAN_SOURCES 59 rtl/tsan_interceptors_mac.cc 60 rtl/tsan_libdispatch_mac.cc 61 rtl/tsan_platform_mac.cc 62 rtl/tsan_platform_posix.cc) 63elseif(UNIX) 64 # Assume Linux 65 list(APPEND TSAN_SOURCES 66 rtl/tsan_platform_linux.cc 67 rtl/tsan_platform_posix.cc) 68endif() 69 70set(TSAN_HEADERS 71 rtl/tsan_clock.h 72 rtl/tsan_defs.h 73 rtl/tsan_dense_alloc.h 74 rtl/tsan_fd.h 75 rtl/tsan_flags.h 76 rtl/tsan_flags.inc 77 rtl/tsan_ignoreset.h 78 rtl/tsan_interceptors.h 79 rtl/tsan_interface_ann.h 80 rtl/tsan_interface.h 81 rtl/tsan_interface_inl.h 82 rtl/tsan_interface_java.h 83 rtl/tsan_mman.h 84 rtl/tsan_mutex.h 85 rtl/tsan_mutexset.h 86 rtl/tsan_platform.h 87 rtl/tsan_report.h 88 rtl/tsan_rtl.h 89 rtl/tsan_stack_trace.h 90 rtl/tsan_stat.h 91 rtl/tsan_suppressions.h 92 rtl/tsan_symbolize.h 93 rtl/tsan_sync.h 94 rtl/tsan_trace.h 95 rtl/tsan_update_shadow_word_inl.h 96 rtl/tsan_vector.h) 97 98set(TSAN_RUNTIME_LIBRARIES) 99add_custom_target(tsan) 100set_target_properties(tsan PROPERTIES FOLDER "Compiler-RT Misc") 101 102if(APPLE) 103 set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S) 104 # Xcode will try to compile this file as C ('clang -x c'), and that will fail. 105 if (${CMAKE_GENERATOR} STREQUAL "Xcode") 106 enable_language(ASM) 107 else() 108 # Pass ASM file directly to the C++ compiler. 109 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C) 110 endif() 111 add_compiler_rt_runtime(clang_rt.tsan 112 SHARED 113 OS ${TSAN_SUPPORTED_OS} 114 ARCHS ${TSAN_SUPPORTED_ARCH} 115 SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES} 116 OBJECT_LIBS RTInterception 117 RTSanitizerCommon 118 RTSanitizerCommonLibc 119 RTUbsan 120 CFLAGS ${TSAN_RTL_CFLAGS} 121 PARENT_TARGET tsan) 122 add_compiler_rt_object_libraries(RTTsan_dynamic 123 OS ${TSAN_SUPPORTED_OS} 124 ARCHS ${TSAN_SUPPORTED_ARCH} 125 SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES} 126 CFLAGS ${TSAN_RTL_CFLAGS}) 127 128 # Build and check Go runtime. 129 set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh) 130 add_custom_target(GotsanRuntimeCheck 131 COMMAND env "CC=${CMAKE_C_COMPILER} ${OSX_SYSROOT_FLAG}" 132 IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT} 133 DEPENDS tsan ${BUILDGO_SCRIPT} 134 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go 135 COMMENT "Checking TSan Go runtime..." 136 VERBATIM) 137else() 138 foreach(arch ${TSAN_SUPPORTED_ARCH}) 139 if(arch STREQUAL "x86_64") 140 set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S) 141 # Pass ASM file directly to the C++ compiler. 142 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 143 LANGUAGE C) 144 # Sanity check for Go runtime. 145 set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh) 146 add_custom_target(GotsanRuntimeCheck 147 COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" 148 IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT} 149 DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT} 150 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go 151 COMMENT "Checking TSan Go runtime..." 152 VERBATIM) 153 elseif(arch STREQUAL "aarch64") 154 set(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S) 155 # Pass ASM file directly to the C++ compiler. 156 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 157 LANGUAGE C) 158 elseif(arch MATCHES "powerpc64|powerpc64le") 159 set(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S) 160 # Pass ASM file directly to the C++ compiler. 161 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 162 LANGUAGE C) 163 else() 164 set(TSAN_ASM_SOURCES) 165 endif() 166 add_compiler_rt_runtime(clang_rt.tsan 167 STATIC 168 ARCHS ${arch} 169 SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES} 170 $<TARGET_OBJECTS:RTInterception.${arch}> 171 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 172 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> 173 $<TARGET_OBJECTS:RTUbsan.${arch}> 174 CFLAGS ${TSAN_RTL_CFLAGS}) 175 add_compiler_rt_runtime(clang_rt.tsan_cxx 176 STATIC 177 ARCHS ${arch} 178 SOURCES ${TSAN_CXX_SOURCES} 179 $<TARGET_OBJECTS:RTUbsan_cxx.${arch}> 180 CFLAGS ${TSAN_RTL_CFLAGS}) 181 list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch} 182 clang_rt.tsan_cxx-${arch}) 183 add_sanitizer_rt_symbols(clang_rt.tsan 184 ARCHS ${arch} 185 EXTRA rtl/tsan.syms.extra) 186 add_sanitizer_rt_symbols(clang_rt.tsan_cxx 187 ARCHS ${arch} 188 EXTRA rtl/tsan.syms.extra) 189 add_dependencies(tsan clang_rt.tsan-${arch} 190 clang_rt.tsan_cxx-${arch} 191 clang_rt.tsan-${arch}-symbols 192 clang_rt.tsan_cxx-${arch}-symbols) 193 endforeach() 194endif() 195 196add_dependencies(compiler-rt tsan) 197 198# Make sure that non-platform-specific files don't include any system headers. 199# FreeBSD does not install a number of Clang-provided headers for the compiler 200# in the base system due to incompatibilities between FreeBSD's and Clang's 201# versions. As a workaround do not use --sysroot=. on FreeBSD until this is 202# addressed. 203if(COMPILER_RT_HAS_SYSROOT_FLAG AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 204 file(GLOB _tsan_generic_sources rtl/tsan*) 205 file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac* 206 rtl/tsan*linux*) 207 list(REMOVE_ITEM _tsan_generic_sources ${_tsan_platform_sources}) 208 set_source_files_properties(${_tsan_generic_sources} 209 PROPERTIES COMPILE_FLAGS "--sysroot=.") 210endif() 211 212# Build libcxx instrumented with TSan. 213if(COMPILER_RT_HAS_LIBCXX_SOURCES AND 214 COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang") 215 set(libcxx_tsan_deps) 216 foreach(arch ${TSAN_SUPPORTED_ARCH}) 217 get_target_flags_for_arch(${arch} TARGET_CFLAGS) 218 set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_tsan_${arch}) 219 add_custom_libcxx(libcxx_tsan_${arch} ${LIBCXX_PREFIX} 220 DEPS ${TSAN_RUNTIME_LIBRARIES} 221 CFLAGS ${TARGET_CFLAGS} -fsanitize=thread) 222 list(APPEND libcxx_tsan_deps libcxx_tsan_${arch}) 223 endforeach() 224 225 add_custom_target(libcxx_tsan DEPENDS ${libcxx_tsan_deps}) 226endif() 227 228if(COMPILER_RT_INCLUDE_TESTS) 229 add_subdirectory(tests) 230endif() 231