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_no_rtti_flag(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_flags.cc 28 rtl/tsan_fd.cc 29 rtl/tsan_ignoreset.cc 30 rtl/tsan_interceptors.cc 31 rtl/tsan_interface_ann.cc 32 rtl/tsan_interface_atomic.cc 33 rtl/tsan_interface.cc 34 rtl/tsan_interface_java.cc 35 rtl/tsan_malloc_mac.cc 36 rtl/tsan_md5.cc 37 rtl/tsan_mman.cc 38 rtl/tsan_mutex.cc 39 rtl/tsan_mutexset.cc 40 rtl/tsan_report.cc 41 rtl/tsan_rtl.cc 42 rtl/tsan_rtl_mutex.cc 43 rtl/tsan_rtl_report.cc 44 rtl/tsan_rtl_thread.cc 45 rtl/tsan_stack_trace.cc 46 rtl/tsan_stat.cc 47 rtl/tsan_suppressions.cc 48 rtl/tsan_symbolize.cc 49 rtl/tsan_sync.cc) 50 51set(TSAN_CXX_SOURCES 52 rtl/tsan_new_delete.cc) 53 54if(APPLE) 55 list(APPEND TSAN_SOURCES 56 rtl/tsan_interceptors_mac.cc 57 rtl/tsan_libdispatch_mac.cc 58 rtl/tsan_platform_mac.cc 59 rtl/tsan_platform_posix.cc) 60elseif(UNIX) 61 # Assume Linux 62 list(APPEND TSAN_SOURCES 63 rtl/tsan_platform_linux.cc 64 rtl/tsan_platform_posix.cc) 65endif() 66 67set(TSAN_HEADERS 68 rtl/tsan_clock.h 69 rtl/tsan_defs.h 70 rtl/tsan_dense_alloc.h 71 rtl/tsan_fd.h 72 rtl/tsan_flags.h 73 rtl/tsan_flags.inc 74 rtl/tsan_ignoreset.h 75 rtl/tsan_interceptors.h 76 rtl/tsan_interface_ann.h 77 rtl/tsan_interface.h 78 rtl/tsan_interface_inl.h 79 rtl/tsan_interface_java.h 80 rtl/tsan_mman.h 81 rtl/tsan_mutex.h 82 rtl/tsan_mutexset.h 83 rtl/tsan_platform.h 84 rtl/tsan_report.h 85 rtl/tsan_rtl.h 86 rtl/tsan_stack_trace.h 87 rtl/tsan_stat.h 88 rtl/tsan_suppressions.h 89 rtl/tsan_symbolize.h 90 rtl/tsan_sync.h 91 rtl/tsan_trace.h 92 rtl/tsan_update_shadow_word_inl.h 93 rtl/tsan_vector.h) 94 95set(TSAN_RUNTIME_LIBRARIES) 96add_custom_target(tsan) 97 98if(APPLE) 99 set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S) 100 # Xcode will try to compile this file as C ('clang -x c'), and that will fail. 101 if (${CMAKE_GENERATOR} STREQUAL "Xcode") 102 enable_language(ASM) 103 else() 104 # Pass ASM file directly to the C++ compiler. 105 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C) 106 endif() 107 add_compiler_rt_runtime(clang_rt.tsan 108 SHARED 109 OS ${TSAN_SUPPORTED_OS} 110 ARCHS ${TSAN_SUPPORTED_ARCH} 111 SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES} 112 OBJECT_LIBS RTInterception 113 RTSanitizerCommon 114 RTSanitizerCommonLibc 115 RTUbsan 116 CFLAGS ${TSAN_RTL_CFLAGS} 117 PARENT_TARGET tsan) 118 add_compiler_rt_object_libraries(RTTsan_dynamic 119 OS ${TSAN_SUPPORTED_OS} 120 ARCHS ${TSAN_SUPPORTED_ARCH} 121 SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES} 122 CFLAGS ${TSAN_RTL_CFLAGS}) 123 124 # Build and check Go runtime. 125 set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh) 126 add_custom_target(GotsanRuntimeCheck 127 COMMAND env "CC=${CMAKE_C_COMPILER} ${OSX_SYSROOT_FLAG}" 128 IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT} 129 DEPENDS tsan ${BUILDGO_SCRIPT} 130 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go 131 COMMENT "Checking TSan Go runtime..." 132 VERBATIM) 133else() 134 foreach(arch ${TSAN_SUPPORTED_ARCH}) 135 if(arch STREQUAL "x86_64") 136 set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S) 137 # Pass ASM file directly to the C++ compiler. 138 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 139 LANGUAGE C) 140 # Sanity check for Go runtime. 141 set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh) 142 add_custom_target(GotsanRuntimeCheck 143 COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" 144 IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT} 145 DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT} 146 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go 147 COMMENT "Checking TSan Go runtime..." 148 VERBATIM) 149 elseif(arch STREQUAL "aarch64") 150 set(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S) 151 # Pass ASM file directly to the C++ compiler. 152 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 153 LANGUAGE C) 154 elseif(arch MATCHES "powerpc64|powerpc64le") 155 set(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S) 156 # Pass ASM file directly to the C++ compiler. 157 set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES 158 LANGUAGE C) 159 else() 160 set(TSAN_ASM_SOURCES) 161 endif() 162 add_compiler_rt_runtime(clang_rt.tsan 163 STATIC 164 ARCHS ${arch} 165 SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES} 166 $<TARGET_OBJECTS:RTInterception.${arch}> 167 $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> 168 $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> 169 $<TARGET_OBJECTS:RTUbsan.${arch}> 170 CFLAGS ${TSAN_RTL_CFLAGS}) 171 add_compiler_rt_runtime(clang_rt.tsan_cxx 172 STATIC 173 ARCHS ${arch} 174 SOURCES ${TSAN_CXX_SOURCES} 175 $<TARGET_OBJECTS:RTUbsan_cxx.${arch}> 176 CFLAGS ${TSAN_RTL_CFLAGS}) 177 list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch} 178 clang_rt.tsan_cxx-${arch}) 179 add_sanitizer_rt_symbols(clang_rt.tsan 180 ARCHS ${arch} 181 EXTRA rtl/tsan.syms.extra) 182 add_sanitizer_rt_symbols(clang_rt.tsan_cxx 183 ARCHS ${arch} 184 EXTRA rtl/tsan.syms.extra) 185 add_dependencies(tsan clang_rt.tsan-${arch} 186 clang_rt.tsan_cxx-${arch} 187 clang_rt.tsan-${arch}-symbols 188 clang_rt.tsan_cxx-${arch}-symbols) 189 endforeach() 190endif() 191 192add_dependencies(compiler-rt tsan) 193 194# Make sure that non-platform-specific files don't include any system headers. 195if(COMPILER_RT_HAS_SYSROOT_FLAG) 196 file(GLOB _tsan_generic_sources rtl/tsan*) 197 file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac* 198 rtl/tsan*linux*) 199 list(REMOVE_ITEM _tsan_generic_sources ${_tsan_platform_sources}) 200 set_source_files_properties(${_tsan_generic_sources} 201 PROPERTIES COMPILE_FLAGS "--sysroot=.") 202endif() 203 204# Build libcxx instrumented with TSan. 205if(COMPILER_RT_HAS_LIBCXX_SOURCES AND 206 COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang") 207 set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_tsan) 208 add_custom_libcxx(libcxx_tsan ${LIBCXX_PREFIX} 209 DEPS ${TSAN_RUNTIME_LIBRARIES} 210 CFLAGS -fsanitize=thread) 211endif() 212 213if(COMPILER_RT_INCLUDE_TESTS) 214 add_subdirectory(tests) 215endif() 216