1include(CMakePushCheckState)
2include(CheckCCompilerFlag)
3include(CheckCXXCompilerFlag)
4include(CheckIncludeFiles)
5include(CheckLibraryExists)
6include(CheckSymbolExists)
7include(TestBigEndian)
8
9function(check_linker_flag flag out_var)
10  cmake_push_check_state()
11  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
12  check_cxx_compiler_flag("" ${out_var})
13  cmake_pop_check_state()
14endfunction()
15
16check_library_exists(c fopen "" COMPILER_RT_HAS_LIBC)
17if (COMPILER_RT_USE_BUILTINS_LIBRARY)
18  include(HandleCompilerRT)
19  find_compiler_rt_library(builtins "" COMPILER_RT_BUILTINS_LIBRARY)
20else()
21  if (ANDROID)
22    check_library_exists(gcc __gcc_personality_v0 "" COMPILER_RT_HAS_GCC_LIB)
23  else()
24    check_library_exists(gcc_s __gcc_personality_v0 "" COMPILER_RT_HAS_GCC_S_LIB)
25  endif()
26endif()
27
28check_c_compiler_flag(-nodefaultlibs COMPILER_RT_HAS_NODEFAULTLIBS_FLAG)
29if (COMPILER_RT_HAS_NODEFAULTLIBS_FLAG)
30  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
31  if (COMPILER_RT_HAS_LIBC)
32    list(APPEND CMAKE_REQUIRED_LIBRARIES c)
33  endif ()
34  if (COMPILER_RT_USE_BUILTINS_LIBRARY)
35    list(APPEND CMAKE_REQUIRED_LIBRARIES "${COMPILER_RT_BUILTINS_LIBRARY}")
36  elseif (COMPILER_RT_HAS_GCC_S_LIB)
37    list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)
38  elseif (COMPILER_RT_HAS_GCC_LIB)
39    list(APPEND CMAKE_REQUIRED_LIBRARIES gcc)
40  endif ()
41  if (MINGW)
42    # Mingw64 requires quite a few "C" runtime libraries in order for basic
43    # programs to link successfully with -nodefaultlibs.
44    if (COMPILER_RT_USE_BUILTINS_LIBRARY)
45      set(MINGW_RUNTIME ${COMPILER_RT_BUILTINS_LIBRARY})
46    else ()
47      set(MINGW_RUNTIME gcc_s gcc)
48    endif()
49    set(MINGW_LIBRARIES mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt advapi32
50                        shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME}
51                        moldname mingwex msvcrt)
52    list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES})
53  endif()
54endif ()
55
56# CodeGen options.
57check_c_compiler_flag(-ffreestanding         COMPILER_RT_HAS_FFREESTANDING_FLAG)
58check_c_compiler_flag(-std=c11               COMPILER_RT_HAS_STD_C11_FLAG)
59check_cxx_compiler_flag(-fPIC                COMPILER_RT_HAS_FPIC_FLAG)
60check_cxx_compiler_flag(-fPIE                COMPILER_RT_HAS_FPIE_FLAG)
61check_cxx_compiler_flag(-fno-builtin         COMPILER_RT_HAS_FNO_BUILTIN_FLAG)
62check_cxx_compiler_flag(-fno-exceptions      COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG)
63check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)
64check_cxx_compiler_flag(-funwind-tables      COMPILER_RT_HAS_FUNWIND_TABLES_FLAG)
65check_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG)
66check_cxx_compiler_flag(-fno-sanitize=safe-stack COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG)
67check_cxx_compiler_flag(-fvisibility=hidden  COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)
68check_cxx_compiler_flag(-frtti               COMPILER_RT_HAS_FRTTI_FLAG)
69check_cxx_compiler_flag(-fno-rtti            COMPILER_RT_HAS_FNO_RTTI_FLAG)
70check_cxx_compiler_flag("-Werror -fno-function-sections" COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG)
71check_cxx_compiler_flag(-std=c++14           COMPILER_RT_HAS_STD_CXX14_FLAG)
72check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC)
73check_cxx_compiler_flag(-fno-lto             COMPILER_RT_HAS_FNO_LTO_FLAG)
74check_cxx_compiler_flag(-fno-profile-generate COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)
75check_cxx_compiler_flag(-fno-profile-instr-generate COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
76check_cxx_compiler_flag(-fno-profile-instr-use COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
77check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
78check_cxx_compiler_flag("-Werror -msse4.2"   COMPILER_RT_HAS_MSSE4_2_FLAG)
79check_cxx_compiler_flag(--sysroot=.          COMPILER_RT_HAS_SYSROOT_FLAG)
80check_cxx_compiler_flag("-Werror -mcrc"      COMPILER_RT_HAS_MCRC_FLAG)
81check_cxx_compiler_flag(-fno-partial-inlining COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG)
82
83if(NOT WIN32 AND NOT CYGWIN)
84  # MinGW warns if -fvisibility-inlines-hidden is used.
85  check_cxx_compiler_flag("-fvisibility-inlines-hidden" COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG)
86endif()
87
88check_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG)
89check_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG)
90check_cxx_compiler_flag(/MT COMPILER_RT_HAS_MT_FLAG)
91check_cxx_compiler_flag(/Oy COMPILER_RT_HAS_Oy_FLAG)
92
93# Debug info flags.
94check_cxx_compiler_flag(-gline-tables-only COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG)
95check_cxx_compiler_flag(-g COMPILER_RT_HAS_G_FLAG)
96check_cxx_compiler_flag(/Zi COMPILER_RT_HAS_Zi_FLAG)
97
98# Warnings.
99check_cxx_compiler_flag(-Wall COMPILER_RT_HAS_WALL_FLAG)
100check_cxx_compiler_flag(-Werror COMPILER_RT_HAS_WERROR_FLAG)
101check_cxx_compiler_flag("-Werror -Wframe-larger-than=512" COMPILER_RT_HAS_WFRAME_LARGER_THAN_FLAG)
102check_cxx_compiler_flag("-Werror -Wglobal-constructors"   COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG)
103check_cxx_compiler_flag("-Werror -Wc99-extensions"     COMPILER_RT_HAS_WC99_EXTENSIONS_FLAG)
104check_cxx_compiler_flag("-Werror -Wgnu"                COMPILER_RT_HAS_WGNU_FLAG)
105check_cxx_compiler_flag("-Werror -Wnon-virtual-dtor"   COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG)
106check_cxx_compiler_flag("-Werror -Wvariadic-macros"    COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG)
107check_cxx_compiler_flag("-Werror -Wunused-parameter"   COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG)
108check_cxx_compiler_flag("-Werror -Wcovered-switch-default" COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG)
109check_cxx_compiler_flag(-Wno-pedantic COMPILER_RT_HAS_WNO_PEDANTIC)
110
111check_cxx_compiler_flag(/W4 COMPILER_RT_HAS_W4_FLAG)
112check_cxx_compiler_flag(/WX COMPILER_RT_HAS_WX_FLAG)
113check_cxx_compiler_flag(/wd4146 COMPILER_RT_HAS_WD4146_FLAG)
114check_cxx_compiler_flag(/wd4291 COMPILER_RT_HAS_WD4291_FLAG)
115check_cxx_compiler_flag(/wd4221 COMPILER_RT_HAS_WD4221_FLAG)
116check_cxx_compiler_flag(/wd4391 COMPILER_RT_HAS_WD4391_FLAG)
117check_cxx_compiler_flag(/wd4722 COMPILER_RT_HAS_WD4722_FLAG)
118check_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG)
119
120# Symbols.
121check_symbol_exists(__func__ "" COMPILER_RT_HAS_FUNC_SYMBOL)
122
123# Includes.
124check_include_files("sys/auxv.h" COMPILER_RT_HAS_AUXV)
125
126# Libraries.
127check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL)
128check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT)
129check_library_exists(m pow "" COMPILER_RT_HAS_LIBM)
130check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD)
131check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO)
132
133# Look for terminfo library, used in unittests that depend on LLVMSupport.
134if(LLVM_ENABLE_TERMINFO)
135  foreach(library terminfo tinfo curses ncurses ncursesw)
136    string(TOUPPER ${library} library_suffix)
137    check_library_exists(
138      ${library} setupterm "" COMPILER_RT_HAS_TERMINFO_${library_suffix})
139    if(COMPILER_RT_HAS_TERMINFO_${library_suffix})
140      set(COMPILER_RT_HAS_TERMINFO TRUE)
141      set(COMPILER_RT_TERMINFO_LIB "${library}")
142      break()
143    endif()
144  endforeach()
145endif()
146
147if (ANDROID AND COMPILER_RT_HAS_LIBDL)
148  # Android's libstdc++ has a dependency on libdl.
149  list(APPEND CMAKE_REQUIRED_LIBRARIES dl)
150endif()
151check_library_exists(c++ __cxa_throw "" COMPILER_RT_HAS_LIBCXX)
152check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX)
153
154# Linker flags.
155check_linker_flag("-Wl,-z,text" COMPILER_RT_HAS_Z_TEXT)
156check_linker_flag("-fuse-ld=lld" COMPILER_RT_HAS_FUSE_LD_LLD_FLAG)
157
158if(ANDROID)
159  check_linker_flag("-Wl,-z,global" COMPILER_RT_HAS_Z_GLOBAL)
160  check_library_exists(log __android_log_write "" COMPILER_RT_HAS_LIBLOG)
161endif()
162
163# Architectures.
164
165# List of all architectures we can target.
166set(COMPILER_RT_SUPPORTED_ARCH)
167
168# Try to compile a very simple source file to ensure we can target the given
169# platform. We use the results of these tests to build only the various target
170# runtime libraries supported by our current compilers cross-compiling
171# abilities.
172set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc)
173file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <stdio.h>\nint main() { printf(\"hello, world\"); }\n")
174
175# Detect whether the current target platform is 32-bit or 64-bit, and setup
176# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
177if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
178    NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
179  message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
180endif()
181
182test_targets()
183
184# Returns a list of architecture specific target cflags in @out_var list.
185function(get_target_flags_for_arch arch out_var)
186  list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
187  if(ARCH_INDEX EQUAL -1)
188    message(FATAL_ERROR "Unsupported architecture: ${arch}")
189  else()
190    if (NOT APPLE)
191      set(${out_var} ${TARGET_${arch}_CFLAGS} PARENT_SCOPE)
192    else()
193      # This is only called in constructing cflags for tests executing on the
194      # host. This will need to all be cleaned up to support building tests
195      # for cross-targeted hardware (i.e. iOS).
196      set(${out_var} -arch ${arch} PARENT_SCOPE)
197    endif()
198  endif()
199endfunction()
200
201# Returns a compiler and CFLAGS that should be used to run tests for the
202# specific architecture.  When cross-compiling, this is controled via
203# COMPILER_RT_TEST_COMPILER and COMPILER_RT_TEST_COMPILER_CFLAGS.
204macro(get_test_cc_for_arch arch cc_out cflags_out)
205  if(ANDROID OR ${arch} MATCHES "arm|aarch64")
206    # This is only true if we are cross-compiling.
207    # Build all tests with host compiler and use host tools.
208    set(${cc_out} ${COMPILER_RT_TEST_COMPILER})
209    set(${cflags_out} ${COMPILER_RT_TEST_COMPILER_CFLAGS})
210  else()
211    get_target_flags_for_arch(${arch} ${cflags_out})
212    if(APPLE)
213      list(APPEND ${cflags_out} ${DARWIN_osx_CFLAGS})
214    endif()
215    string(REPLACE ";" " " ${cflags_out} "${${cflags_out}}")
216  endif()
217endmacro()
218
219# Returns CFLAGS that should be used to run tests for the
220# specific apple platform and architecture.
221function(get_test_cflags_for_apple_platform platform arch cflags_out)
222  is_valid_apple_platform("${platform}" is_valid_platform)
223  if (NOT is_valid_platform)
224    message(FATAL_ERROR "\"${platform}\" is not a valid apple platform")
225  endif()
226  set(test_cflags "")
227  get_target_flags_for_arch(${arch} test_cflags)
228  list(APPEND test_cflags ${DARWIN_${platform}_CFLAGS})
229  string(REPLACE ";" " " test_cflags_str "${test_cflags}")
230  string(APPEND test_cflags_str "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
231  set(${cflags_out} "${test_cflags_str}" PARENT_SCOPE)
232endfunction()
233
234function(get_capitalized_apple_platform platform platform_capitalized)
235  # TODO(dliew): Remove uses of this function. It exists to preserve needlessly complex
236  # directory naming conventions used by the Sanitizer lit test suites.
237  is_valid_apple_platform("${platform}" is_valid_platform)
238  if (NOT is_valid_platform)
239    message(FATAL_ERROR "\"${platform}\" is not a valid apple platform")
240  endif()
241  string(TOUPPER "${platform}" platform_upper)
242  string(REGEX REPLACE "OSSIM$" "OSSim" platform_upper_capitalized "${platform_upper}")
243  set(${platform_capitalized} "${platform_upper_capitalized}" PARENT_SCOPE)
244endfunction()
245
246function(is_valid_apple_platform platform is_valid_out)
247  set(is_valid FALSE)
248  if ("${platform}" STREQUAL "")
249    message(FATAL_ERROR "platform cannot be empty")
250  endif()
251  if ("${platform}" MATCHES "^(osx|((ios|watchos|tvos)(sim)?))$")
252    set(is_valid TRUE)
253  endif()
254  set(${is_valid_out} ${is_valid} PARENT_SCOPE)
255endfunction()
256
257set(ARM64 aarch64)
258set(ARM32 arm armhf)
259set(HEXAGON hexagon)
260set(X86 i386)
261set(X86_64 x86_64)
262set(MIPS32 mips mipsel)
263set(MIPS64 mips64 mips64el)
264set(PPC64 powerpc64 powerpc64le)
265set(RISCV32 riscv32)
266set(RISCV64 riscv64)
267set(S390X s390x)
268set(SPARC sparc)
269set(SPARCV9 sparcv9)
270set(WASM32 wasm32)
271set(WASM64 wasm64)
272
273if(APPLE)
274  set(ARM64 arm64)
275  set(ARM32 armv7 armv7s armv7k)
276  set(X86_64 x86_64 x86_64h)
277endif()
278
279set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64}
280    ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9})
281set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
282    ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9})
283set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV32} ${RISCV64})
284set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
285
286if(ANDROID)
287  set(OS_NAME "Android")
288else()
289  set(OS_NAME "${CMAKE_SYSTEM_NAME}")
290endif()
291
292if(OS_NAME MATCHES "Linux")
293  set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})
294elseif (OS_NAME MATCHES "Windows")
295  set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64})
296elseif(OS_NAME MATCHES "Android")
297  set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64})
298else()
299  set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64})
300endif()
301
302set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64})
303if(APPLE)
304  set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64})
305else()
306  set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64} ${S390X})
307endif()
308set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X})
309set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64})
310set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}
311    ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9})
312set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
313set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
314    ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9})
315set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64})
316set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64})
317set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64})
318set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64})
319if(APPLE)
320set(ALL_XRAY_SUPPORTED_ARCH ${X86_64})
321else()
322set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} powerpc64le)
323endif()
324set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64})
325
326if(APPLE)
327  include(CompilerRTDarwinUtils)
328
329  find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
330  find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
331  find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
332  find_darwin_sdk_dir(DARWIN_watchossim_SYSROOT watchsimulator)
333  find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos)
334  find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator)
335  find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos)
336
337  if(NOT DARWIN_osx_SYSROOT)
338    message(WARNING "Could not determine OS X sysroot, trying /usr/include")
339    if(EXISTS /usr/include)
340      set(DARWIN_osx_SYSROOT /)
341    else()
342      message(ERROR "Could not detect OS X Sysroot. Either install Xcode or the Apple Command Line Tools")
343    endif()
344  endif()
345
346  if(COMPILER_RT_ENABLE_IOS)
347    list(APPEND DARWIN_EMBEDDED_PLATFORMS ios)
348    set(DARWIN_ios_MIN_VER 9.0)
349    set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
350    set(DARWIN_ios_SANITIZER_MIN_VER_FLAG
351      ${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_MIN_VER})
352    set(DARWIN_iossim_MIN_VER_FLAG -mios-simulator-version-min)
353    set(DARWIN_iossim_SANITIZER_MIN_VER_FLAG
354      ${DARWIN_iossim_MIN_VER_FLAG}=${DARWIN_ios_MIN_VER})
355  endif()
356  if(COMPILER_RT_ENABLE_WATCHOS)
357    list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
358    set(DARWIN_watchos_MIN_VER 2.0)
359    set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
360    set(DARWIN_watchos_SANITIZER_MIN_VER_FLAG
361      ${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_MIN_VER})
362    set(DARWIN_watchossim_MIN_VER_FLAG -mwatchos-simulator-version-min)
363    set(DARWIN_watchossim_SANITIZER_MIN_VER_FLAG
364      ${DARWIN_watchossim_MIN_VER_FLAG}=${DARWIN_watchos_MIN_VER})
365  endif()
366  if(COMPILER_RT_ENABLE_TVOS)
367    list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
368    set(DARWIN_tvos_MIN_VER 9.0)
369    set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
370    set(DARWIN_tvos_SANITIZER_MIN_VER_FLAG
371      ${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_MIN_VER})
372    set(DARWIN_tvossim_MIN_VER_FLAG -mtvos-simulator-version-min)
373    set(DARWIN_tvossim_SANITIZER_MIN_VER_FLAG
374      ${DARWIN_tvossim_MIN_VER_FLAG}=${DARWIN_tvos_MIN_VER})
375  endif()
376
377  set(SANITIZER_COMMON_SUPPORTED_OS osx)
378  set(PROFILE_SUPPORTED_OS osx)
379  set(TSAN_SUPPORTED_OS osx)
380  set(XRAY_SUPPORTED_OS osx)
381  set(FUZZER_SUPPORTED_OS osx)
382
383  # Note: In order to target x86_64h on OS X the minimum deployment target must
384  # be 10.8 or higher.
385  set(DEFAULT_SANITIZER_MIN_OSX_VERSION 10.10)
386  set(DARWIN_osx_MIN_VER_FLAG "-mmacosx-version-min")
387  if(NOT SANITIZER_MIN_OSX_VERSION)
388    string(REGEX MATCH "${DARWIN_osx_MIN_VER_FLAG}=([.0-9]+)"
389           MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
390    if(MACOSX_VERSION_MIN_FLAG)
391      set(SANITIZER_MIN_OSX_VERSION "${CMAKE_MATCH_1}")
392    elseif(CMAKE_OSX_DEPLOYMENT_TARGET)
393      set(SANITIZER_MIN_OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
394    else()
395      set(SANITIZER_MIN_OSX_VERSION ${DEFAULT_SANITIZER_MIN_OSX_VERSION})
396    endif()
397    if(SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.7")
398      message(FATAL_ERROR "macOS deployment target '${SANITIZER_MIN_OSX_VERSION}' is too old.")
399    endif()
400    if(SANITIZER_MIN_OSX_VERSION VERSION_GREATER ${DEFAULT_SANITIZER_MIN_OSX_VERSION})
401      message(WARNING "macOS deployment target '${SANITIZER_MIN_OSX_VERSION}' is too new, setting to '${DEFAULT_SANITIZER_MIN_OSX_VERSION}' instead.")
402      set(SANITIZER_MIN_OSX_VERSION ${DEFAULT_SANITIZER_MIN_OSX_VERSION})
403    endif()
404  endif()
405
406  # We're setting the flag manually for each target OS
407  set(CMAKE_OSX_DEPLOYMENT_TARGET "")
408
409  set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
410  set(DARWIN_COMMON_LINK_FLAGS
411    -stdlib=libc++
412    -lc++
413    -lc++abi)
414
415  check_linker_flag("-fapplication-extension" COMPILER_RT_HAS_APP_EXTENSION)
416  if(COMPILER_RT_HAS_APP_EXTENSION)
417    list(APPEND DARWIN_COMMON_LINK_FLAGS "-fapplication-extension")
418  endif()
419
420  set(DARWIN_osx_CFLAGS
421    ${DARWIN_COMMON_CFLAGS}
422    ${DARWIN_osx_MIN_VER_FLAG}=${SANITIZER_MIN_OSX_VERSION})
423  set(DARWIN_osx_LINK_FLAGS
424    ${DARWIN_COMMON_LINK_FLAGS}
425    ${DARWIN_osx_MIN_VER_FLAG}=${SANITIZER_MIN_OSX_VERSION})
426
427  if(DARWIN_osx_SYSROOT)
428    list(APPEND DARWIN_osx_CFLAGS -isysroot ${DARWIN_osx_SYSROOT})
429    list(APPEND DARWIN_osx_LINK_FLAGS -isysroot ${DARWIN_osx_SYSROOT})
430  endif()
431
432  # Figure out which arches to use for each OS
433  darwin_get_toolchain_supported_archs(toolchain_arches)
434  message(STATUS "Toolchain supported arches: ${toolchain_arches}")
435
436  if(NOT MACOSX_VERSION_MIN_FLAG)
437    darwin_test_archs(osx
438      DARWIN_osx_ARCHS
439      ${toolchain_arches})
440    message(STATUS "OSX supported arches: ${DARWIN_osx_ARCHS}")
441    foreach(arch ${DARWIN_osx_ARCHS})
442      list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
443      set(CAN_TARGET_${arch} 1)
444    endforeach()
445
446    foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
447      if(DARWIN_${platform}sim_SYSROOT)
448        set(DARWIN_${platform}sim_CFLAGS
449          ${DARWIN_COMMON_CFLAGS}
450          ${DARWIN_${platform}sim_SANITIZER_MIN_VER_FLAG}
451          -isysroot ${DARWIN_${platform}sim_SYSROOT})
452        set(DARWIN_${platform}sim_LINK_FLAGS
453          ${DARWIN_COMMON_LINK_FLAGS}
454          ${DARWIN_${platform}sim_SANITIZER_MIN_VER_FLAG}
455          -isysroot ${DARWIN_${platform}sim_SYSROOT})
456
457        set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
458        darwin_test_archs(${platform}sim
459          DARWIN_${platform}sim_ARCHS
460          ${toolchain_arches})
461        message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}")
462        if(DARWIN_${platform}sim_ARCHS)
463          list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}sim)
464          list(APPEND PROFILE_SUPPORTED_OS ${platform}sim)
465          list(APPEND TSAN_SUPPORTED_OS ${platform}sim)
466          list(APPEND FUZZER_SUPPORTED_OS ${platform}sim)
467        endif()
468        foreach(arch ${DARWIN_${platform}sim_ARCHS})
469          list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
470          set(CAN_TARGET_${arch} 1)
471        endforeach()
472      endif()
473
474      if(DARWIN_${platform}_SYSROOT)
475        set(DARWIN_${platform}_CFLAGS
476          ${DARWIN_COMMON_CFLAGS}
477          ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
478          -isysroot ${DARWIN_${platform}_SYSROOT})
479        set(DARWIN_${platform}_LINK_FLAGS
480          ${DARWIN_COMMON_LINK_FLAGS}
481          ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
482          -isysroot ${DARWIN_${platform}_SYSROOT})
483
484        darwin_test_archs(${platform}
485          DARWIN_${platform}_ARCHS
486          ${toolchain_arches})
487        message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}")
488        if(DARWIN_${platform}_ARCHS)
489          list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform})
490          list(APPEND PROFILE_SUPPORTED_OS ${platform})
491
492          list_intersect(DARWIN_${platform}_TSAN_ARCHS DARWIN_${platform}_ARCHS ALL_TSAN_SUPPORTED_ARCH)
493          if(DARWIN_${platform}_TSAN_ARCHS)
494            list(APPEND TSAN_SUPPORTED_OS ${platform})
495          endif()
496          list(APPEND FUZZER_SUPPORTED_OS ${platform})
497        endif()
498        foreach(arch ${DARWIN_${platform}_ARCHS})
499          list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
500          set(CAN_TARGET_${arch} 1)
501        endforeach()
502      endif()
503    endforeach()
504  endif()
505
506  # Explictly disable unsupported Sanitizer configurations.
507  list(REMOVE_ITEM FUZZER_SUPPORTED_OS "watchos")
508  list(REMOVE_ITEM FUZZER_SUPPORTED_OS "watchossim")
509
510  # for list_intersect
511  include(CompilerRTUtils)
512
513  list_intersect(SANITIZER_COMMON_SUPPORTED_ARCH
514    ALL_SANITIZER_COMMON_SUPPORTED_ARCH
515    COMPILER_RT_SUPPORTED_ARCH
516    )
517  set(LSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})
518  set(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})
519  list_intersect(ASAN_SUPPORTED_ARCH
520    ALL_ASAN_SUPPORTED_ARCH
521    SANITIZER_COMMON_SUPPORTED_ARCH)
522  list_intersect(DFSAN_SUPPORTED_ARCH
523    ALL_DFSAN_SUPPORTED_ARCH
524    SANITIZER_COMMON_SUPPORTED_ARCH)
525  list_intersect(GWP_ASAN_SUPPORTED_ARCH
526    ALL_GWP_ASAN_SUPPORTED_ARCH
527    SANITIZER_COMMON_SUPPORTED_ARCH)
528  list_intersect(LSAN_SUPPORTED_ARCH
529    ALL_LSAN_SUPPORTED_ARCH
530    SANITIZER_COMMON_SUPPORTED_ARCH)
531  list_intersect(MSAN_SUPPORTED_ARCH
532    ALL_MSAN_SUPPORTED_ARCH
533    SANITIZER_COMMON_SUPPORTED_ARCH)
534  list_intersect(HWASAN_SUPPORTED_ARCH
535    ALL_HWASAN_SUPPORTED_ARCH
536    SANITIZER_COMMON_SUPPORTED_ARCH)
537  list_intersect(PROFILE_SUPPORTED_ARCH
538    ALL_PROFILE_SUPPORTED_ARCH
539    SANITIZER_COMMON_SUPPORTED_ARCH)
540  list_intersect(TSAN_SUPPORTED_ARCH
541    ALL_TSAN_SUPPORTED_ARCH
542    SANITIZER_COMMON_SUPPORTED_ARCH)
543  list_intersect(UBSAN_SUPPORTED_ARCH
544    ALL_UBSAN_SUPPORTED_ARCH
545    SANITIZER_COMMON_SUPPORTED_ARCH)
546  list_intersect(SAFESTACK_SUPPORTED_ARCH
547    ALL_SAFESTACK_SUPPORTED_ARCH
548    SANITIZER_COMMON_SUPPORTED_ARCH)
549  list_intersect(CFI_SUPPORTED_ARCH
550    ALL_CFI_SUPPORTED_ARCH
551    SANITIZER_COMMON_SUPPORTED_ARCH)
552  list_intersect(SCUDO_SUPPORTED_ARCH
553    ALL_SCUDO_SUPPORTED_ARCH
554    SANITIZER_COMMON_SUPPORTED_ARCH)
555  list_intersect(SCUDO_STANDALONE_SUPPORTED_ARCH
556    ALL_SCUDO_STANDALONE_SUPPORTED_ARCH
557    SANITIZER_COMMON_SUPPORTED_ARCH)
558  list_intersect(FUZZER_SUPPORTED_ARCH
559    ALL_FUZZER_SUPPORTED_ARCH
560    SANITIZER_COMMON_SUPPORTED_ARCH)
561  list_intersect(XRAY_SUPPORTED_ARCH
562    ALL_XRAY_SUPPORTED_ARCH
563    SANITIZER_COMMON_SUPPORTED_ARCH)
564  list_intersect(SHADOWCALLSTACK_SUPPORTED_ARCH
565    ALL_SHADOWCALLSTACK_SUPPORTED_ARCH
566    SANITIZER_COMMON_SUPPORTED_ARCH)
567
568else()
569  filter_available_targets(CRT_SUPPORTED_ARCH ${ALL_CRT_SUPPORTED_ARCH})
570  # Architectures supported by compiler-rt libraries.
571  filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
572    ${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})
573  # LSan and UBSan common files should be available on all architectures
574  # supported by other sanitizers (even if they build into dummy object files).
575  filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH
576    ${SANITIZER_COMMON_SUPPORTED_ARCH})
577  filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH
578    ${SANITIZER_COMMON_SUPPORTED_ARCH})
579  filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH})
580  filter_available_targets(FUZZER_SUPPORTED_ARCH ${ALL_FUZZER_SUPPORTED_ARCH})
581  filter_available_targets(DFSAN_SUPPORTED_ARCH ${ALL_DFSAN_SUPPORTED_ARCH})
582  filter_available_targets(LSAN_SUPPORTED_ARCH ${ALL_LSAN_SUPPORTED_ARCH})
583  filter_available_targets(MSAN_SUPPORTED_ARCH ${ALL_MSAN_SUPPORTED_ARCH})
584  filter_available_targets(HWASAN_SUPPORTED_ARCH ${ALL_HWASAN_SUPPORTED_ARCH})
585  filter_available_targets(PROFILE_SUPPORTED_ARCH ${ALL_PROFILE_SUPPORTED_ARCH})
586  filter_available_targets(TSAN_SUPPORTED_ARCH ${ALL_TSAN_SUPPORTED_ARCH})
587  filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH})
588  filter_available_targets(SAFESTACK_SUPPORTED_ARCH
589    ${ALL_SAFESTACK_SUPPORTED_ARCH})
590  filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
591  filter_available_targets(SCUDO_SUPPORTED_ARCH ${ALL_SCUDO_SUPPORTED_ARCH})
592  filter_available_targets(SCUDO_STANDALONE_SUPPORTED_ARCH ${ALL_SCUDO_STANDALONE_SUPPORTED_ARCH})
593  filter_available_targets(XRAY_SUPPORTED_ARCH ${ALL_XRAY_SUPPORTED_ARCH})
594  filter_available_targets(SHADOWCALLSTACK_SUPPORTED_ARCH
595    ${ALL_SHADOWCALLSTACK_SUPPORTED_ARCH})
596  filter_available_targets(GWP_ASAN_SUPPORTED_ARCH ${ALL_GWP_ASAN_SUPPORTED_ARCH})
597endif()
598
599if (MSVC)
600  # See if the DIA SDK is available and usable.
601  set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK")
602  if (IS_DIRECTORY ${MSVC_DIA_SDK_DIR})
603    set(CAN_SYMBOLIZE 1)
604  else()
605    set(CAN_SYMBOLIZE 0)
606  endif()
607else()
608  set(CAN_SYMBOLIZE 1)
609endif()
610
611find_program(GOLD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.gold ld.gold ${LLVM_DEFAULT_TARGET_TRIPLE}-ld ld DOC "The gold linker")
612
613if(COMPILER_RT_SUPPORTED_ARCH)
614  list(REMOVE_DUPLICATES COMPILER_RT_SUPPORTED_ARCH)
615endif()
616message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}")
617
618set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo;ubsan_minimal;gwp_asan)
619set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING
620    "sanitizers to build if supported on the target (all;${ALL_SANITIZERS})")
621list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}")
622
623if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
624    (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|OpenBSD|Fuchsia|SunOS" OR
625    (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND
626        (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"))))
627  set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE)
628else()
629  set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
630endif()
631
632if (COMPILER_RT_HAS_SANITIZER_COMMON)
633  set(COMPILER_RT_HAS_INTERCEPTION TRUE)
634else()
635  set(COMPILER_RT_HAS_INTERCEPTION FALSE)
636endif()
637
638if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND
639    NOT OS_NAME MATCHES "OpenBSD")
640  set(COMPILER_RT_HAS_ASAN TRUE)
641else()
642  set(COMPILER_RT_HAS_ASAN FALSE)
643endif()
644
645if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS")
646  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE)
647else()
648  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE)
649endif()
650
651# TODO: Add builtins support.
652
653if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER)
654  set(COMPILER_RT_HAS_CRT TRUE)
655else()
656  set(COMPILER_RT_HAS_CRT FALSE)
657endif()
658
659if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND
660    OS_NAME MATCHES "Linux")
661  set(COMPILER_RT_HAS_DFSAN TRUE)
662else()
663  set(COMPILER_RT_HAS_DFSAN FALSE)
664endif()
665
666if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND
667    OS_NAME MATCHES "Darwin|Linux|NetBSD|Fuchsia")
668  set(COMPILER_RT_HAS_LSAN TRUE)
669else()
670  set(COMPILER_RT_HAS_LSAN FALSE)
671endif()
672
673if (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND
674    OS_NAME MATCHES "Linux|FreeBSD|NetBSD")
675  set(COMPILER_RT_HAS_MSAN TRUE)
676else()
677  set(COMPILER_RT_HAS_MSAN FALSE)
678endif()
679
680if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
681    OS_NAME MATCHES "Linux|Android")
682  set(COMPILER_RT_HAS_HWASAN TRUE)
683else()
684  set(COMPILER_RT_HAS_HWASAN FALSE)
685endif()
686
687if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
688    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD")
689  set(COMPILER_RT_HAS_PROFILE TRUE)
690else()
691  set(COMPILER_RT_HAS_PROFILE FALSE)
692endif()
693
694if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND
695    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Android|NetBSD")
696  set(COMPILER_RT_HAS_TSAN TRUE)
697else()
698  set(COMPILER_RT_HAS_TSAN FALSE)
699endif()
700
701if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
702    OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|OpenBSD|Windows|Android|Fuchsia|SunOS")
703  set(COMPILER_RT_HAS_UBSAN TRUE)
704else()
705  set(COMPILER_RT_HAS_UBSAN FALSE)
706endif()
707
708if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
709    OS_NAME MATCHES "Linux|FreeBSD|NetBSD|OpenBSD|Android|Darwin")
710  set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE)
711else()
712  set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE)
713endif()
714
715if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND
716    OS_NAME MATCHES "Linux|FreeBSD|NetBSD")
717  set(COMPILER_RT_HAS_SAFESTACK TRUE)
718else()
719  set(COMPILER_RT_HAS_SAFESTACK FALSE)
720endif()
721
722if (COMPILER_RT_HAS_SANITIZER_COMMON AND CFI_SUPPORTED_ARCH)
723  set(COMPILER_RT_HAS_CFI TRUE)
724else()
725  set(COMPILER_RT_HAS_CFI FALSE)
726endif()
727
728#TODO(kostyak): add back Android & Fuchsia when the code settles a bit.
729if (SCUDO_STANDALONE_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND
730    COMPILER_RT_HAS_AUXV)
731  set(COMPILER_RT_HAS_SCUDO_STANDALONE TRUE)
732else()
733  set(COMPILER_RT_HAS_SCUDO_STANDALONE FALSE)
734endif()
735
736if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND
737    OS_NAME MATCHES "Linux|Android|Fuchsia")
738  set(COMPILER_RT_HAS_SCUDO TRUE)
739else()
740  set(COMPILER_RT_HAS_SCUDO FALSE)
741endif()
742
743if (COMPILER_RT_HAS_SANITIZER_COMMON AND XRAY_SUPPORTED_ARCH AND
744    OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|OpenBSD|Fuchsia")
745  set(COMPILER_RT_HAS_XRAY TRUE)
746else()
747  set(COMPILER_RT_HAS_XRAY FALSE)
748endif()
749
750if (COMPILER_RT_HAS_SANITIZER_COMMON AND FUZZER_SUPPORTED_ARCH AND
751    OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|OpenBSD|Fuchsia|Windows")
752  set(COMPILER_RT_HAS_FUZZER TRUE)
753else()
754  set(COMPILER_RT_HAS_FUZZER FALSE)
755endif()
756
757if (COMPILER_RT_HAS_SANITIZER_COMMON AND SHADOWCALLSTACK_SUPPORTED_ARCH AND
758    OS_NAME MATCHES "Linux|Android")
759  set(COMPILER_RT_HAS_SHADOWCALLSTACK TRUE)
760else()
761  set(COMPILER_RT_HAS_SHADOWCALLSTACK FALSE)
762endif()
763
764# Note: Fuchsia and Windows are not currently supported by GWP-ASan. Support
765# is planned for these platforms. Darwin is also not supported due to TLS
766# calling malloc on first use.
767# TODO(hctim): Enable this on Android again. Looks like it's causing a SIGSEGV
768# for Scudo and GWP-ASan, further testing needed.
769if (COMPILER_RT_HAS_SANITIZER_COMMON AND GWP_ASAN_SUPPORTED_ARCH AND
770    OS_NAME MATCHES "Linux")
771  set(COMPILER_RT_HAS_GWP_ASAN TRUE)
772else()
773  set(COMPILER_RT_HAS_GWP_ASAN FALSE)
774endif()
775pythonize_bool(COMPILER_RT_HAS_GWP_ASAN)
776