forked from OSchip/llvm-project
[compiler-rt] Build custom libcxx with libcxxabi
This changes add_custom_libcxx to also build libcxxabi and merges the two into a static and hermetic library. There are multiple advantages: 1) The resulting libFuzzer doesn't expose C++ internals and looks like a plain C library. 2) We don't have to manually link in libstdc++ to provide cxxabi. 3) The sanitizer tests cannot interfere with an installed version of libc++.so in LD_LIBRARY_PATH. Differential Revision: https://reviews.llvm.org/D58013 llvm-svn: 354212
This commit is contained in:
parent
91ecb69acd
commit
66c60d9d71
|
@ -484,6 +484,15 @@ if(COMPILER_RT_USE_LIBCXX)
|
|||
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)
|
||||
|
|
|
@ -509,6 +509,9 @@ macro(add_custom_libcxx name prefix)
|
|||
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 @@ macro(add_custom_libcxx name prefix)
|
|||
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 @@ macro(add_custom_libcxx name prefix)
|
|||
-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
|
||||
|
|
|
@ -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)
|
|
@ -55,7 +55,9 @@ CHECK_CXX_SOURCE_COMPILES("
|
|||
|
||||
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 @@ add_compiler_rt_runtime(clang_rt.fuzzer_no_main
|
|||
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 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
|
|||
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)
|
||||
|
|
|
@ -24,7 +24,9 @@ if(NOT WIN32)
|
|||
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 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH)
|
|||
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)
|
||||
|
|
|
@ -48,10 +48,8 @@ set(MSAN_UNITTEST_INSTRUMENTED_CFLAGS
|
|||
)
|
||||
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 @@ macro(add_msan_tests_for_arch arch kind cflags)
|
|||
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 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_LIBCXX_PATH)
|
|||
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"
|
||||
|
|
|
@ -236,6 +236,7 @@ endif()
|
|||
|
||||
# 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)
|
||||
|
|
|
@ -63,17 +63,6 @@ config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root))
|
|||
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 @@ def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
|
|||
return " ".join([
|
||||
compiler_cmd,
|
||||
std_cmd,
|
||||
link_cmd,
|
||||
"-O2 -gline-tables-only",
|
||||
sanitizers_cmd,
|
||||
"-I%s" % libfuzzer_src_root,
|
||||
|
|
|
@ -43,7 +43,9 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
|
|||
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)
|
||||
|
|
|
@ -8,6 +8,7 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
|
|||
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)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// 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.
|
||||
// memcpy/memmove calls. It builds the binary with TSan and check's
|
||||
// its objdump.
|
||||
|
||||
// RUN: %clangxx_tsan -O1 %s -o %t
|
||||
// RUN: %clang_tsan -O1 %s -o %t
|
||||
// RUN: llvm-objdump -d %t | FileCheck %s
|
||||
|
||||
// REQUIRES: compiler-rt-optimized
|
|
@ -38,7 +38,7 @@ config.substitutions.append(('%env_tsan_opts=',
|
|||
|
||||
# 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 @@ if config.has_libcxx and config.host_os != 'Darwin':
|
|||
"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) + " "
|
||||
|
|
|
@ -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 <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -23,7 +23,7 @@ set(CMAKE_MODULE_PATH
|
|||
${CMAKE_MODULE_PATH}
|
||||
)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUILD)
|
||||
project(libcxx CXX C)
|
||||
|
||||
set(PACKAGE_NAME libcxx)
|
||||
|
|
|
@ -98,7 +98,7 @@ if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
|
|||
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
|
||||
if (LIBCXX_CXX_ABI_INTREE)
|
||||
# Link against just-built "cxxabi" target.
|
||||
if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
|
||||
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
|
||||
set(CXXABI_LIBNAME cxxabi_static)
|
||||
else()
|
||||
set(CXXABI_LIBNAME cxxabi_shared)
|
||||
|
|
|
@ -17,7 +17,7 @@ set(CMAKE_MODULE_PATH
|
|||
${CMAKE_MODULE_PATH}
|
||||
)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXXABI_STANDALONE_BUILD)
|
||||
project(libcxxabi CXX C)
|
||||
|
||||
set(PACKAGE_NAME libcxxabi)
|
||||
|
|
Loading…
Reference in New Issue