Skip to content

Commit 66c60d9

Browse files
committed
[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
1 parent 91ecb69 commit 66c60d9

File tree

16 files changed

+74
-46
lines changed

16 files changed

+74
-46
lines changed

compiler-rt/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,15 @@ if(COMPILER_RT_USE_LIBCXX)
484484
break()
485485
endif()
486486
endforeach()
487+
foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxxabi
488+
${LLVM_MAIN_SRC_DIR}/runtimes/libcxxabi
489+
${LLVM_MAIN_SRC_DIR}/../libcxxabi
490+
${LLVM_EXTERNAL_LIBCXXABI_SOURCE_DIR})
491+
if(IS_DIRECTORY ${path})
492+
set(COMPILER_RT_LIBCXXABI_PATH ${path})
493+
break()
494+
endif()
495+
endforeach()
487496
endif()
488497

489498
set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/tools/lld)

compiler-rt/cmake/Modules/AddCompilerRT.cmake

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ macro(add_custom_libcxx name prefix)
509509
if(NOT COMPILER_RT_LIBCXX_PATH)
510510
message(FATAL_ERROR "libcxx not found!")
511511
endif()
512+
if(NOT COMPILER_RT_LIBCXXABI_PATH)
513+
message(FATAL_ERROR "libcxxabi not found!")
514+
endif()
512515

513516
cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN})
514517

@@ -584,7 +587,7 @@ macro(add_custom_libcxx name prefix)
584587
ExternalProject_Add(${name}
585588
DEPENDS ${name}-clobber ${LIBCXX_DEPS}
586589
PREFIX ${prefix}
587-
SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
590+
SOURCE_DIR ${COMPILER_RT_SOURCE_DIR}/cmake/Modules/CustomLibcxx
588591
STAMP_DIR ${STAMP_DIR}
589592
BINARY_DIR ${BINARY_DIR}
590593
CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES}
@@ -595,7 +598,8 @@ macro(add_custom_libcxx name prefix)
595598
-DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
596599
-DLLVM_BINARY_DIR=${prefix}
597600
-DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib
598-
-DLIBCXX_STANDALONE_BUILD=ON
601+
-DCOMPILER_RT_LIBCXX_PATH=${COMPILER_RT_LIBCXX_PATH}
602+
-DCOMPILER_RT_LIBCXXABI_PATH=${COMPILER_RT_LIBCXXABI_PATH}
599603
${LIBCXX_CMAKE_ARGS}
600604
INSTALL_COMMAND ""
601605
STEP_TARGETS configure build
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
cmake_minimum_required(VERSION 3.4.3)
2+
3+
# Build static libcxxabi.
4+
set(LIBCXXABI_STANDALONE_BUILD 1)
5+
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
6+
set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE STRING "")
7+
set(LIBCXXABI_LIBCXX_PATH ${COMPILER_RT_LIBCXX_PATH} CACHE PATH "")
8+
set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "")
9+
add_subdirectory(${COMPILER_RT_LIBCXXABI_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxxabi)
10+
11+
# Build static libcxx without exceptions.
12+
set(LIBCXX_STANDALONE_BUILD 1)
13+
set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "")
14+
set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
15+
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
16+
set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
17+
18+
# Use above libcxxabi.
19+
set(LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "")
20+
set(LIBCXX_CXX_ABI_INTREE 1)
21+
set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
22+
set(LIBCXX_CXX_ABI_INCLUDE_PATHS ${COMPILER_RT_LIBCXXABI_PATH}/include CACHE PATH "")
23+
24+
add_subdirectory(${COMPILER_RT_LIBCXX_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxx)

compiler-rt/lib/fuzzer/CMakeLists.txt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ CHECK_CXX_SOURCE_COMPILES("
5555

5656
set(LIBFUZZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})
5757

58-
if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
58+
if(OS_NAME MATCHES "Linux|Fuchsia" AND
59+
COMPILER_RT_LIBCXX_PATH AND
60+
COMPILER_RT_LIBCXXABI_PATH)
5961
list(APPEND LIBFUZZER_CFLAGS -nostdinc++ -D_LIBCPP_ABI_VERSION=Fuzzer)
6062
# Remove -stdlib= which is unused when passing -nostdinc++.
6163
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
113115
CFLAGS ${LIBFUZZER_CFLAGS}
114116
PARENT_TARGET fuzzer)
115117

116-
if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
118+
if(OS_NAME MATCHES "Linux|Fuchsia" AND
119+
COMPILER_RT_LIBCXX_PATH AND
120+
COMPILER_RT_LIBCXXABI_PATH)
117121
macro(partially_link_libcxx name dir arch)
118122
set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir")
119123
file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir})
@@ -131,13 +135,8 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
131135
set(LIBCXX_${arch}_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_fuzzer_${arch})
132136
add_custom_libcxx(libcxx_fuzzer_${arch} ${LIBCXX_${arch}_PREFIX}
133137
CFLAGS ${TARGET_CFLAGS}
134-
-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=1
135-
-fvisibility=hidden
136138
CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
137-
-DLIBCXX_ENABLE_EXCEPTIONS=OFF
138-
-DLIBCXX_ENABLE_SHARED=OFF
139-
-DLIBCXX_ABI_NAMESPACE=Fuzzer
140-
-DLIBCXX_CXX_ABI=none)
139+
-DLIBCXX_ABI_NAMESPACE=Fuzzer)
141140
target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
142141
add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
143142
target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)

compiler-rt/lib/fuzzer/tests/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ if(NOT WIN32)
2424
list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lpthread)
2525
endif()
2626

27-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH)
27+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
28+
COMPILER_RT_LIBCXX_PATH AND
29+
COMPILER_RT_LIBCXXABI_PATH)
2830
list(APPEND LIBFUZZER_UNITTEST_CFLAGS -nostdinc++)
2931
endif()
3032

@@ -46,7 +48,9 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH)
4648
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
4749
FOLDER "Compiler-RT Runtime tests")
4850

49-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH)
51+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
52+
COMPILER_RT_LIBCXX_PATH AND
53+
COMPILER_RT_LIBCXXABI_PATH)
5054
file(GLOB libfuzzer_headers ../*.h)
5155
set(LIBFUZZER_TEST_RUNTIME_DEPS libcxx_fuzzer_${arch}-build ${libfuzzer_headers})
5256
set(LIBFUZZER_TEST_RUNTIME_CFLAGS -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)

compiler-rt/lib/msan/tests/CMakeLists.txt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,8 @@ set(MSAN_UNITTEST_INSTRUMENTED_CFLAGS
4848
)
4949
set(MSAN_UNITTEST_LINK_FLAGS
5050
-fsanitize=memory
51-
# Don't need -stdlib=libc++ because we explicitly list libc++.so in the linker
51+
# Don't need -stdlib=libc++ because we explicitly list libc++.a in the linker
5252
# inputs.
53-
# FIXME: we build libcxx without cxxabi and need libstdc++ to provide it.
54-
-lstdc++
5553
)
5654

5755
append_list_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS)
@@ -116,24 +114,24 @@ macro(add_msan_tests_for_arch arch kind cflags)
116114
endif()
117115
get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
118116
add_compiler_rt_test(MsanUnitTests "Msan-${arch}${kind}-Test" ${arch}
119-
OBJECTS ${MSAN_TEST_OBJECTS} ${MSAN_LIBCXX_SO}
117+
OBJECTS ${MSAN_TEST_OBJECTS} "${MSAN_LIBCXX_DIR}/libc++.a"
120118
DEPS ${MSAN_TEST_DEPS}
121119
LINK_FLAGS ${MSAN_UNITTEST_LINK_FLAGS}
122-
${TARGET_LINK_FLAGS}
123-
"-Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}"
124-
"-Wl,-rpath=${LIBCXX_PREFIX}/lib")
120+
${TARGET_LINK_FLAGS})
125121
endmacro()
126122

127123
# We should only build MSan unit tests if we can build instrumented libcxx.
128-
if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_LIBCXX_PATH)
124+
if(COMPILER_RT_CAN_EXECUTE_TESTS AND
125+
COMPILER_RT_LIBCXX_PATH AND
126+
COMPILER_RT_LIBCXXABI_PATH)
129127
foreach(arch ${MSAN_SUPPORTED_ARCH})
130128
get_target_flags_for_arch(${arch} TARGET_CFLAGS)
131129
set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan_${arch})
132130
add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX}
133131
DEPS ${MSAN_RUNTIME_LIBRARIES}
134132
CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS}
135133
USE_TOOLCHAIN)
136-
set(MSAN_LIBCXX_SO ${LIBCXX_PREFIX}/lib/libc++.so)
134+
set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/)
137135

138136
add_msan_tests_for_arch(${arch} "" "")
139137
add_msan_tests_for_arch(${arch} "-with-call"

compiler-rt/lib/tsan/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ endif()
236236

237237
# Build libcxx instrumented with TSan.
238238
if(COMPILER_RT_LIBCXX_PATH AND
239+
COMPILER_RT_LIBCXXABI_PATH AND
239240
COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang" AND
240241
NOT ANDROID)
241242
set(libcxx_tsan_deps)

compiler-rt/test/fuzzer/lit.cfg

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,6 @@ config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root))
6363
def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
6464
compiler_cmd = config.clang
6565
extra_cmd = config.target_flags
66-
if config.clang and config.stdlib == 'libc++':
67-
link_cmd = '-stdlib=libc++ -Wl,-rpath=%s' % config.runtime_library_dir
68-
elif config.clang and config.stdlib == 'static-libc++':
69-
link_cmd = '-stdlib=libc++ -lc++abi -static-libstdc++ -Wl,-rpath=%s' % (
70-
config.runtime_library_dir)
71-
elif any(x in config.target_triple for x in ('darwin', 'freebsd')):
72-
link_cmd = '-lc++'
73-
elif 'windows-msvc' in config.target_triple:
74-
link_cmd = ''
75-
else:
76-
link_cmd = '-lstdc++'
7766

7867
if is_cpp and 'windows-msvc' in config.target_triple:
7968
std_cmd = '--driver-mode=cl'
@@ -92,7 +81,6 @@ def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
9281
return " ".join([
9382
compiler_cmd,
9483
std_cmd,
95-
link_cmd,
9684
"-O2 -gline-tables-only",
9785
sanitizers_cmd,
9886
"-I%s" % libfuzzer_src_root,

compiler-rt/test/msan/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
4343
list(APPEND MSAN_TEST_DEPS msan)
4444
endif()
4545

46-
if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_LIBCXX_PATH)
46+
if(COMPILER_RT_INCLUDE_TESTS AND
47+
COMPILER_RT_LIBCXX_PATH AND
48+
COMPILER_RT_LIBCXXABI_PATH)
4749
configure_lit_site_cfg(
4850
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
4951
${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)

compiler-rt/test/tsan/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
88
list(APPEND TSAN_TEST_DEPS tsan)
99
endif()
1010
if(COMPILER_RT_LIBCXX_PATH AND
11+
COMPILER_RT_LIBCXXABI_PATH AND
1112
COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang"
1213
AND NOT APPLE AND NOT ANDROID)
1314
list(APPEND TSAN_TEST_DEPS libcxx_tsan)

compiler-rt/test/tsan/Linux/check_memcpy.cc renamed to compiler-rt/test/tsan/Linux/check_memcpy.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Test that verifies TSan runtime doesn't contain compiler-emitted
2-
// memcpy/memmove calls. It builds the binary with TSan and passes it to
3-
// check_memcpy.sh script.
2+
// memcpy/memmove calls. It builds the binary with TSan and check's
3+
// its objdump.
44

5-
// RUN: %clangxx_tsan -O1 %s -o %t
5+
// RUN: %clang_tsan -O1 %s -o %t
66
// RUN: llvm-objdump -d %t | FileCheck %s
77

88
// REQUIRES: compiler-rt-optimized

compiler-rt/test/tsan/lit.cfg

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ config.substitutions.append(('%env_tsan_opts=',
3838

3939
# GCC driver doesn't add necessary compile/link flags with -fsanitize=thread.
4040
if config.compiler_id == 'GNU':
41-
extra_cflags = ["-fPIE", "-pthread", "-ldl", "-lstdc++", "-lrt", "-pie"]
41+
extra_cflags = ["-fPIE", "-pthread", "-ldl", "-lrt", "-pie"]
4242
else:
4343
extra_cflags = []
4444

@@ -59,11 +59,10 @@ if config.has_libcxx and config.host_os != 'Darwin':
5959
"tsan", "libcxx_tsan_%s" % config.target_arch)
6060
libcxx_incdir = os.path.join(libcxx_path, "include", "c++", "v1")
6161
libcxx_libdir = os.path.join(libcxx_path, "lib")
62-
libcxx_so = os.path.join(libcxx_libdir, "libc++.so")
62+
libcxx_a = os.path.join(libcxx_libdir, "libc++.a")
6363
clang_tsan_cxxflags += ["-nostdinc++",
6464
"-I%s" % libcxx_incdir,
65-
libcxx_so,
66-
"-Wl,-rpath=%s" % libcxx_libdir]
65+
libcxx_a]
6766

6867
def build_invocation(compile_flags):
6968
return " " + " ".join([config.clang] + compile_flags) + " "

compiler-rt/test/tsan/static_init6.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// RUN: %clangxx_tsan %linux_static_libstdcplusplus -O1 %s -o %t && %run %t 2>&1 \
2-
// RUN: | FileCheck %s
1+
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
32
#include <pthread.h>
43
#include <stdlib.h>
54
#include <stdio.h>

libcxx/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ set(CMAKE_MODULE_PATH
2323
${CMAKE_MODULE_PATH}
2424
)
2525

26-
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
26+
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUILD)
2727
project(libcxx CXX C)
2828

2929
set(PACKAGE_NAME libcxx)

libcxx/cmake/Modules/HandleLibCXXABI.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
9898
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
9999
if (LIBCXX_CXX_ABI_INTREE)
100100
# Link against just-built "cxxabi" target.
101-
if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
101+
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
102102
set(CXXABI_LIBNAME cxxabi_static)
103103
else()
104104
set(CXXABI_LIBNAME cxxabi_shared)

libcxxabi/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ set(CMAKE_MODULE_PATH
1717
${CMAKE_MODULE_PATH}
1818
)
1919

20-
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
20+
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXXABI_STANDALONE_BUILD)
2121
project(libcxxabi CXX C)
2222

2323
set(PACKAGE_NAME libcxxabi)

0 commit comments

Comments
 (0)