Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -484,6 +484,15 @@ break() endif() endforeach() + foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxxabi + ${LLVM_MAIN_SRC_DIR}/runtimes/libcxxabi + ${LLVM_MAIN_SRC_DIR}/../libcxxabi + ${LLVM_EXTERNAL_LIBCXXABI_SOURCE_DIR}) + if(IS_DIRECTORY ${path}) + set(COMPILER_RT_LIBCXXABI_PATH ${path}) + break() + endif() + endforeach() endif() set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/tools/lld) Index: cmake/Modules/AddCompilerRT.cmake =================================================================== --- cmake/Modules/AddCompilerRT.cmake +++ cmake/Modules/AddCompilerRT.cmake @@ -509,6 +509,9 @@ if(NOT COMPILER_RT_LIBCXX_PATH) message(FATAL_ERROR "libcxx not found!") endif() + if(NOT COMPILER_RT_LIBCXXABI_PATH) + message(FATAL_ERROR "libcxxabi not found!") + endif() cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) @@ -584,7 +587,7 @@ ExternalProject_Add(${name} DEPENDS ${name}-clobber ${LIBCXX_DEPS} PREFIX ${prefix} - SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} + SOURCE_DIR ${COMPILER_RT_SOURCE_DIR}/cmake/Modules/CustomLibcxx STAMP_DIR ${STAMP_DIR} BINARY_DIR ${BINARY_DIR} CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} @@ -595,7 +598,8 @@ -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} -DLLVM_BINARY_DIR=${prefix} -DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib - -DLIBCXX_STANDALONE_BUILD=ON + -DCOMPILER_RT_LIBCXX_PATH=${COMPILER_RT_LIBCXX_PATH} + -DCOMPILER_RT_LIBCXXABI_PATH=${COMPILER_RT_LIBCXXABI_PATH} ${LIBCXX_CMAKE_ARGS} INSTALL_COMMAND "" STEP_TARGETS configure build Index: cmake/Modules/CustomLibcxx/CMakeLists.txt =================================================================== --- cmake/Modules/CustomLibcxx/CMakeLists.txt +++ cmake/Modules/CustomLibcxx/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.4.3) + +# Build static libcxxabi. +set(LIBCXXABI_STANDALONE_BUILD 1) +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE STRING "") +set(LIBCXXABI_LIBCXX_PATH ${COMPILER_RT_LIBCXX_PATH} CACHE PATH "") +set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "") +add_subdirectory(${COMPILER_RT_LIBCXXABI_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxxabi) + +# Build static libcxx without exceptions. +set(LIBCXX_STANDALONE_BUILD 1) +set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") + +# Use above libcxxabi. +set(LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") +set(LIBCXX_CXX_ABI_INTREE 1) +set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") +set(LIBCXX_CXX_ABI_INCLUDE_PATHS ${COMPILER_RT_LIBCXXABI_PATH}/include CACHE PATH "") + +add_subdirectory(${COMPILER_RT_LIBCXX_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxx) Index: lib/fuzzer/CMakeLists.txt =================================================================== --- lib/fuzzer/CMakeLists.txt +++ lib/fuzzer/CMakeLists.txt @@ -55,7 +55,9 @@ set(LIBFUZZER_CFLAGS ${SANITIZER_COMMON_CFLAGS}) -if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH) +if(OS_NAME MATCHES "Linux|Fuchsia" AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) list(APPEND LIBFUZZER_CFLAGS -nostdinc++ -D_LIBCPP_ABI_VERSION=Fuzzer) # Remove -stdlib= which is unused when passing -nostdinc++. string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) @@ -113,7 +115,9 @@ CFLAGS ${LIBFUZZER_CFLAGS} PARENT_TARGET fuzzer) -if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH) +if(OS_NAME MATCHES "Linux|Fuchsia" AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) macro(partially_link_libcxx name dir arch) set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir") file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir}) @@ -131,13 +135,8 @@ set(LIBCXX_${arch}_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_fuzzer_${arch}) add_custom_libcxx(libcxx_fuzzer_${arch} ${LIBCXX_${arch}_PREFIX} CFLAGS ${TARGET_CFLAGS} - -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=1 - -fvisibility=hidden CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON - -DLIBCXX_ENABLE_EXCEPTIONS=OFF - -DLIBCXX_ENABLE_SHARED=OFF - -DLIBCXX_ABI_NAMESPACE=Fuzzer - -DLIBCXX_CXX_ABI=none) + -DLIBCXX_ABI_NAMESPACE=Fuzzer) target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build) target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) Index: lib/fuzzer/tests/CMakeLists.txt =================================================================== --- lib/fuzzer/tests/CMakeLists.txt +++ lib/fuzzer/tests/CMakeLists.txt @@ -24,7 +24,9 @@ list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lpthread) endif() -if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) list(APPEND LIBFUZZER_UNITTEST_CFLAGS -nostdinc++) endif() @@ -46,7 +48,9 @@ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} FOLDER "Compiler-RT Runtime tests") - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) file(GLOB libfuzzer_headers ../*.h) set(LIBFUZZER_TEST_RUNTIME_DEPS libcxx_fuzzer_${arch}-build ${libfuzzer_headers}) set(LIBFUZZER_TEST_RUNTIME_CFLAGS -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) Index: lib/msan/tests/CMakeLists.txt =================================================================== --- lib/msan/tests/CMakeLists.txt +++ lib/msan/tests/CMakeLists.txt @@ -48,10 +48,8 @@ ) set(MSAN_UNITTEST_LINK_FLAGS -fsanitize=memory - # Don't need -stdlib=libc++ because we explicitly list libc++.so in the linker + # Don't need -stdlib=libc++ because we explicitly list libc++.a in the linker # inputs. - # FIXME: we build libcxx without cxxabi and need libstdc++ to provide it. - -lstdc++ ) append_list_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS) @@ -116,16 +114,16 @@ endif() get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) add_compiler_rt_test(MsanUnitTests "Msan-${arch}${kind}-Test" ${arch} - OBJECTS ${MSAN_TEST_OBJECTS} ${MSAN_LIBCXX_SO} + OBJECTS ${MSAN_TEST_OBJECTS} "${MSAN_LIBCXX_DIR}/libc++.a" DEPS ${MSAN_TEST_DEPS} LINK_FLAGS ${MSAN_UNITTEST_LINK_FLAGS} - ${TARGET_LINK_FLAGS} - "-Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}" - "-Wl,-rpath=${LIBCXX_PREFIX}/lib") + ${TARGET_LINK_FLAGS}) endmacro() # We should only build MSan unit tests if we can build instrumented libcxx. -if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_LIBCXX_PATH) +if(COMPILER_RT_CAN_EXECUTE_TESTS AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) foreach(arch ${MSAN_SUPPORTED_ARCH}) get_target_flags_for_arch(${arch} TARGET_CFLAGS) set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan_${arch}) @@ -133,7 +131,7 @@ DEPS ${MSAN_RUNTIME_LIBRARIES} CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS} USE_TOOLCHAIN) - set(MSAN_LIBCXX_SO ${LIBCXX_PREFIX}/lib/libc++.so) + set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/) add_msan_tests_for_arch(${arch} "" "") add_msan_tests_for_arch(${arch} "-with-call" Index: lib/tsan/CMakeLists.txt =================================================================== --- lib/tsan/CMakeLists.txt +++ lib/tsan/CMakeLists.txt @@ -236,6 +236,7 @@ # Build libcxx instrumented with TSan. if(COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH AND COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang" AND NOT ANDROID) set(libcxx_tsan_deps) Index: test/fuzzer/lit.cfg =================================================================== --- test/fuzzer/lit.cfg +++ test/fuzzer/lit.cfg @@ -63,17 +63,6 @@ def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False): compiler_cmd = config.clang extra_cmd = config.target_flags - if config.clang and config.stdlib == 'libc++': - link_cmd = '-stdlib=libc++ -Wl,-rpath=%s' % config.runtime_library_dir - elif config.clang and config.stdlib == 'static-libc++': - link_cmd = '-stdlib=libc++ -lc++abi -static-libstdc++ -Wl,-rpath=%s' % ( - config.runtime_library_dir) - elif any(x in config.target_triple for x in ('darwin', 'freebsd')): - link_cmd = '-lc++' - elif 'windows-msvc' in config.target_triple: - link_cmd = '' - else: - link_cmd = '-lstdc++' if is_cpp and 'windows-msvc' in config.target_triple: std_cmd = '--driver-mode=cl' @@ -92,7 +81,6 @@ return " ".join([ compiler_cmd, std_cmd, - link_cmd, "-O2 -gline-tables-only", sanitizers_cmd, "-I%s" % libfuzzer_src_root, Index: test/msan/CMakeLists.txt =================================================================== --- test/msan/CMakeLists.txt +++ test/msan/CMakeLists.txt @@ -43,7 +43,9 @@ list(APPEND MSAN_TEST_DEPS msan) endif() -if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_LIBCXX_PATH) +if(COMPILER_RT_INCLUDE_TESTS AND + COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg) Index: test/tsan/CMakeLists.txt =================================================================== --- test/tsan/CMakeLists.txt +++ test/tsan/CMakeLists.txt @@ -8,6 +8,7 @@ list(APPEND TSAN_TEST_DEPS tsan) endif() if(COMPILER_RT_LIBCXX_PATH AND + COMPILER_RT_LIBCXXABI_PATH AND COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang" AND NOT APPLE AND NOT ANDROID) list(APPEND TSAN_TEST_DEPS libcxx_tsan) Index: test/tsan/Linux/check_memcpy.c =================================================================== --- test/tsan/Linux/check_memcpy.c +++ test/tsan/Linux/check_memcpy.c @@ -0,0 +1,17 @@ +// Test that verifies TSan runtime doesn't contain compiler-emitted +// memcpy/memmove calls. It builds the binary with TSan and check's +// its objdump. + +// RUN: %clang_tsan -O1 %s -o %t +// RUN: llvm-objdump -d %t | FileCheck %s + +// REQUIRES: compiler-rt-optimized + +int main() { + return 0; +} + +// CHECK-NOT: callq {{.*<(__interceptor_)?mem(cpy|set)>}} +// tail calls: +// CHECK-NOT: jmpq {{.*<(__interceptor_)?mem(cpy|set)>}} + Index: test/tsan/Linux/check_memcpy.cc =================================================================== --- test/tsan/Linux/check_memcpy.cc +++ test/tsan/Linux/check_memcpy.cc @@ -1,17 +0,0 @@ -// Test that verifies TSan runtime doesn't contain compiler-emitted -// memcpy/memmove calls. It builds the binary with TSan and passes it to -// check_memcpy.sh script. - -// RUN: %clangxx_tsan -O1 %s -o %t -// RUN: llvm-objdump -d %t | FileCheck %s - -// REQUIRES: compiler-rt-optimized - -int main() { - return 0; -} - -// CHECK-NOT: callq {{.*<(__interceptor_)?mem(cpy|set)>}} -// tail calls: -// CHECK-NOT: jmpq {{.*<(__interceptor_)?mem(cpy|set)>}} - Index: test/tsan/lit.cfg =================================================================== --- test/tsan/lit.cfg +++ test/tsan/lit.cfg @@ -38,7 +38,7 @@ # GCC driver doesn't add necessary compile/link flags with -fsanitize=thread. if config.compiler_id == 'GNU': - extra_cflags = ["-fPIE", "-pthread", "-ldl", "-lstdc++", "-lrt", "-pie"] + extra_cflags = ["-fPIE", "-pthread", "-ldl", "-lrt", "-pie"] else: extra_cflags = [] @@ -59,11 +59,10 @@ "tsan", "libcxx_tsan_%s" % config.target_arch) libcxx_incdir = os.path.join(libcxx_path, "include", "c++", "v1") libcxx_libdir = os.path.join(libcxx_path, "lib") - libcxx_so = os.path.join(libcxx_libdir, "libc++.so") + libcxx_a = os.path.join(libcxx_libdir, "libc++.a") clang_tsan_cxxflags += ["-nostdinc++", "-I%s" % libcxx_incdir, - libcxx_so, - "-Wl,-rpath=%s" % libcxx_libdir] + libcxx_a] def build_invocation(compile_flags): return " " + " ".join([config.clang] + compile_flags) + " " Index: test/tsan/static_init6.cc =================================================================== --- test/tsan/static_init6.cc +++ test/tsan/static_init6.cc @@ -1,5 +1,4 @@ -// RUN: %clangxx_tsan %linux_static_libstdcplusplus -O1 %s -o %t && %run %t 2>&1 \ -// RUN: | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include #include #include