Index: compiler-rt/CMakeLists.txt =================================================================== --- compiler-rt/CMakeLists.txt +++ compiler-rt/CMakeLists.txt @@ -112,9 +112,6 @@ # COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. pythonize_bool(COMPILER_RT_DEBUG) -include(HandleCompilerRT) -include(config-ix) - if(APPLE AND SANITIZER_MIN_OSX_VERSION AND SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.9") # Mac OS X prior to 10.9 had problems with exporting symbols from # libc++/libc++abi. @@ -123,7 +120,7 @@ set(cxxabi_supported ON) endif() -option(SANITIZER_ALLOW_CXXABI "Allow use of C++ ABI details in ubsan" ON) +option(SANITIZER_ALLOW_CXXABI "Allow use of C++ ABI details in sanitizers" ON) set(SANITIZE_CAN_USE_CXXABI OFF) if (cxxabi_supported AND SANITIZER_ALLOW_CXXABI) @@ -131,47 +128,53 @@ endif() pythonize_bool(SANITIZER_CAN_USE_CXXABI) +check_link_libraries(cxx_link_libraries) + set(SANITIZER_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") -set(CXXABIS none default libcxxabi libstdc++ libc++) +set(CXXABIS none default libc++ libc++abi libstdc++) set_property(CACHE SANITIZER_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) if (SANITIZER_CXX_ABI STREQUAL "default") - if (HAVE_LIBCXXABI AND COMPILER_RT_DEFAULT_TARGET_ONLY) - set(SANITIZER_CXX_ABI_LIBNAME "libcxxabi") - set(SANITIZER_CXX_ABI_INTREE 1) - elseif (APPLE) - set(SANITIZER_CXX_ABI_LIBNAME "libcxxabi") + if(APPLE) + set(SANITIZER_CXX_ABI_LIBNAME "libc++") set(SANITIZER_CXX_ABI_SYSTEM 1) - else() + elseif("stdc++" IN_LIST cxx_link_libraries) set(SANITIZER_CXX_ABI_LIBNAME "libstdc++") + set(SANITIZER_CXX_ABI_SYSTEM 1) + elseif("c++abi" IN_LIST cxx_link_libraries) + set(SANITIZER_CXX_ABI_LIBNAME "libc++abi") + elseif("c++" IN_LIST cxx_link_libraries) + set(SANITIZER_CXX_ABI_LIBNAME "libc++") endif() else() set(SANITIZER_CXX_ABI_LIBNAME "${SANITIZER_CXX_ABI}") endif() -if (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libcxxabi") - if (SANITIZER_CXX_ABI_INTREE) - if (NOT LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_shared OR HAVE_LIBUNWIND)) - list(APPEND SANITIZER_CXX_ABI_LIBRARY unwind_shared) - elseif (LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_static OR HAVE_LIBUNWIND)) - list(APPEND SANITIZER_CXX_ABI_LIBRARY unwind_static) - endif() - if (NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND (TARGET cxxabi_shared OR HAVE_LIBCXXABI)) +if (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libc++") + if(SANITIZER_CXX_ABI_SYSTEM) + list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") + else() + if(TARGET cxxabi_shared OR (HAVE_LIBCXXABI AND NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY)) list(APPEND SANITIZER_CXX_ABI_LIBRARY cxxabi_shared) - elseif (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND (TARGET cxxabi_static OR HAVE_LIBCXXABI)) + elseif(TARGET cxxabi_shared OR (HAVE_LIBCXXABI AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY)) list(APPEND SANITIZER_CXX_ABI_LIBRARY cxxabi_static) + else() + list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") endif() - else() - list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++abi") endif() -elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libc++") - list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libstdc++") - append_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ SANITIZER_CXX_ABI_LIBRARY) + list(APPEND SANITIZER_CXX_ABI_LIBRARY "stdc++") endif() -option(SANITIZER_USE_COMPILER_RT "Use compiler-rt builtins instead of libgcc" OFF) +check_runtime_library(runtime_library) +if(runtime_library MATCHES ".*libgcc.*") + set(COMPILER_RT_RUNTIME_LIBRARY "libgcc") +elseif(runtime_library MATCHES ".*libclang_rt.builtins.*") + set(COMPILER_RT_RUNTIME_LIBRARY "compiler-rt") +endif() + +include(config-ix) #================================ # Setup Compiler Flags @@ -319,9 +322,7 @@ # Set common link flags. append_list_if(COMPILER_RT_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs SANITIZER_COMMON_LINK_FLAGS) -if (SANITIZER_USE_COMPILER_RT) - list(APPEND SANITIZER_COMMON_LINK_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) +if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") list(APPEND SANITIZER_COMMON_LINK_LIBS ${COMPILER_RT_BUILTINS_LIBRARY}) else() if (ANDROID) Index: compiler-rt/cmake/Modules/CompilerRTUtils.cmake =================================================================== --- compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -144,10 +144,15 @@ endif() set(SAVED_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${argstring}") + if(SANITIZER_CXX_ABI_SYSTEM) + set(FLAG_LINK_LIBRARIES ${SANITIZER_CXX_ABI_LIBRARY}) + endif() try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE} COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS} ${FLAG_NO_EXCEPTIONS}" + LINK_LIBRARIES ${FLAG_LINK_LIBRARIES} OUTPUT_VARIABLE TARGET_${arch}_OUTPUT) set(CMAKE_EXE_LINKER_FLAGS ${SAVED_CMAKE_EXE_LINKER_FLAGS}) + message(ERROR "Cannot compile ${TARGET_${arch}_OUTPUT}") endif() endif() if(${CAN_TARGET_${arch}}) @@ -314,3 +319,58 @@ endforeach () set(${output_var} ${intermediate} PARENT_SCOPE) endfunction() + +function(check_runtime_library variable) + set(COMPILER_COMMAND ${CMAKE_CXX_COMPILER} ${SANITIZER_COMMON_CFLAGS} + "--print-libgcc-file-name") + if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) + list(APPEND COMPILER_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") + endif() + execute_process( + COMMAND ${COMPILER_COMMAND} + RESULT_VARIABLE COMMAND_RESULT + OUTPUT_VARIABLE LIBRARY_FILE + ) + string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) + if(COMMAND_RESULT EQUAL 0) + set(${variable} "${LIBRARY_FILE}" PARENT_SCOPE) + endif() +endfunction() + +function(check_link_libraries variable) + set(COMPILER_COMMAND "${CMAKE_CXX_COMPILER}" "${SANITIZER_COMMON_CFLAGS}" + "${CMAKE_ROOT}/Modules/DummyCXXFile.cxx" "-###") + if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) + list(APPEND COMPILER_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") + endif() + execute_process( + COMMAND ${COMPILER_COMMAND} + RESULT_VARIABLE COMMAND_RESULT + ERROR_VARIABLE COMMAND_OUTPUT + ) + if(COMMAND_RESULT EQUAL 0) + get_filename_component(linker ${CMAKE_LINKER} NAME) + string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" linker "${linker}") + set(linker_regex "^( *|.*[/\\])(${linker}|([^/\\]+-)?ld|collect2)[^/\\]*( |$)") + set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=|/ldfe ") + string(REGEX REPLACE "\r?\n" ";" output_lines "${COMMAND_OUTPUT}") + foreach(line IN LISTS output_lines) + if(line MATCHES "${linker_regex}" AND NOT line MATCHES "${linker_exclude_regex}") + separate_arguments(args NATIVE_COMMAND "${line}") + list(GET args 0 cmd) + endif() + if("${cmd}" MATCHES "${linker_regex}") + foreach(arg IN LISTS args) + if("${arg}" MATCHES "^-l([^:].*)$") + set(lib "${CMAKE_MATCH_1}") + list(APPEND libs ${lib}) + elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.a$") + list(APPEND libs ${arg}) + endif() + endforeach() + break() + endif() + endforeach() + set(${variable} "${libs}" PARENT_SCOPE) + endif() +endfunction() Index: compiler-rt/cmake/Modules/HandleCompilerRT.cmake =================================================================== --- compiler-rt/cmake/Modules/HandleCompilerRT.cmake +++ compiler-rt/cmake/Modules/HandleCompilerRT.cmake @@ -1,5 +1,4 @@ -function(find_compiler_rt_library name dest) - set(dest "" PARENT_SCOPE) +function(find_compiler_rt_library name variable) set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${SANITIZER_COMMON_CFLAGS} "--rtlib=compiler-rt" "--print-libgcc-file-name") if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) @@ -14,7 +13,7 @@ string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}") if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}") message(STATUS "Found compiler-rt ${name} library: ${LIBRARY_FILE}") - set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE) + set(${variable} "${LIBRARY_FILE}" PARENT_SCOPE) else() message(STATUS "Failed to find compiler-rt ${name} library") endif() Index: compiler-rt/cmake/config-ix.cmake =================================================================== --- compiler-rt/cmake/config-ix.cmake +++ compiler-rt/cmake/config-ix.cmake @@ -13,7 +13,10 @@ endfunction() check_library_exists(c fopen "" COMPILER_RT_HAS_LIBC) -if (NOT SANITIZER_USE_COMPILER_RT) +if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") + include(HandleCompilerRT) + find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) +else() if (ANDROID) check_library_exists(gcc __gcc_personality_v0 "" COMPILER_RT_HAS_GCC_LIB) else() @@ -27,9 +30,7 @@ if (COMPILER_RT_HAS_LIBC) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () - if (SANITIZER_USE_COMPILER_RT) - list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) + if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") list(APPEND CMAKE_REQUIRED_LIBRARIES "${COMPILER_RT_BUILTINS_LIBRARY}") elseif (COMPILER_RT_HAS_GCC_S_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s) @@ -125,7 +126,7 @@ # platform. We use the results of these tests to build only the various target # runtime libraries supported by our current compilers cross-compiling # abilities. -set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc) +set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.c) file(WRITE ${SIMPLE_SOURCE} "#include \n#include \nint main() { printf(\"hello, world\"); }\n") # Detect whether the current target platform is 32-bit or 64-bit, and setup