Skip to content

Commit cd66c9b

Browse files
authored
[Ubsan][Driver] Remove UBSAN C++ runtime from other sanitizers (#121006)
Linking this runtime requires C++ ABI, which breaks -nostdlib++ builds. However, UBSAN C++ runtime is only needed for CFI and VPTR checks. Unblocks #120370.
1 parent 48a6e51 commit cd66c9b

File tree

10 files changed

+34
-11
lines changed

10 files changed

+34
-11
lines changed

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class SanitizerArgs {
9999
}
100100
bool needsFuzzerInterceptors() const;
101101
bool needsUbsanRt() const;
102+
bool needsUbsanCXXRt() const;
102103
bool requiresMinimalRuntime() const { return MinimalRuntime; }
103104
bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
104105
bool needsSafeStackRt() const { return SafeStackRuntime; }

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,14 @@ bool SanitizerArgs::needsUbsanRt() const {
338338
CoverageFeatures;
339339
}
340340

341+
bool SanitizerArgs::needsUbsanCXXRt() const {
342+
// Link UBSAN C++ runtime very selectively, as it's needed in only very
343+
// specific cases, but forces the program to depend on C++ ABI. UBSAN C++
344+
// runtime is not included with other sanitizers.
345+
return static_cast<bool>(Sanitizers.Mask & NeedsUbsanCxxRt &
346+
~TrapSanitizers.Mask);
347+
}
348+
341349
bool SanitizerArgs::needsCfiRt() const {
342350
return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
343351
CfiCrossDso && !ImplicitCfiRuntime;

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
14541454
SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
14551455
SmallVectorImpl<StringRef> &HelperStaticRuntimes,
14561456
SmallVectorImpl<StringRef> &RequiredSymbols) {
1457+
assert(!TC.getTriple().isOSDarwin() && "it's not used by Darwin");
14571458
const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
14581459
// Collect shared runtimes.
14591460
if (SanArgs.needsSharedRt()) {
@@ -1574,7 +1575,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
15741575
StaticRuntimes.push_back("cfi_diag");
15751576
}
15761577
if (SanArgs.linkCXXRuntimes() && !SanArgs.requiresMinimalRuntime() &&
1577-
((!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) ||
1578+
((!SanArgs.needsSharedRt() && SanArgs.needsUbsanCXXRt()) ||
15781579
SanArgs.needsCfiDiagRt())) {
15791580
StaticRuntimes.push_back("ubsan_standalone_cxx");
15801581
}

clang/test/Driver/sanitizer-ld.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,25 @@
579579
// CHECK-ASAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive"
580580
// CHECK-ASAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.asan_cxx.a" "--no-whole-archive"
581581
// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
582+
// CHECK-ASAN-UBSAN-LINUX-CXX: libclang_rt.ubsan_standalone_cxx
583+
// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
582584
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++"
583585
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread"
584586
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lresolv"
585587

588+
// RUN: %clangxx -fsanitize=address,undefined -fno-sanitize=vptr -### %s 2>&1 \
589+
// RUN: --target=i386-unknown-linux -fuse-ld=ld -stdlib=platform \
590+
// RUN: -resource-dir=%S/Inputs/resource_dir \
591+
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
592+
// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX %s
593+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
594+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan.a" "--no-whole-archive"
595+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "--whole-archive" "{{.*}}libclang_rt.asan_cxx.a" "--no-whole-archive"
596+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-NOT: libclang_rt.ubsan
597+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "-lstdc++"
598+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "-lpthread"
599+
// CHECK-ASAN-UBSAN-NOVPTR-LINUX-CXX-SAME: "-lresolv"
600+
586601
// RUN: %clangxx -fsanitize=memory,undefined -### %s 2>&1 \
587602
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
588603
// RUN: -resource-dir=%S/Inputs/resource_dir \
@@ -591,6 +606,8 @@
591606
// CHECK-MSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
592607
// CHECK-MSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.msan.a" "--no-whole-archive"
593608
// CHECK-MSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
609+
// CHECK-MSAN-UBSAN-LINUX-CXX: libclang_rt.ubsan_standalone_cxx
610+
// CHECK-MSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
594611

595612
// RUN: %clangxx -fsanitize=thread,undefined -### %s 2>&1 \
596613
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
@@ -600,6 +617,8 @@
600617
// CHECK-TSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
601618
// CHECK-TSAN-UBSAN-LINUX-CXX: "--whole-archive" "{{.*}}libclang_rt.tsan.a" "--no-whole-archive"
602619
// CHECK-TSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
620+
// CHECK-TSAN-UBSAN-LINUX-CXX: libclang_rt.ubsan_standalone_cxx
621+
// CHECK-TSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
603622

604623
// RUN: %clang -fsanitize=undefined -### %s 2>&1 \
605624
// RUN: --target=i386-unknown-linux -fuse-ld=ld \

compiler-rt/lib/asan/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ else()
260260
STATIC
261261
ARCHS ${ASAN_SUPPORTED_ARCH}
262262
OBJECT_LIBS RTAsan_cxx
263-
RTUbsan_cxx
264263
CFLAGS ${ASAN_CFLAGS}
265264
DEFS ${ASAN_COMMON_DEFINITIONS}
266265
PARENT_TARGET asan)
@@ -319,7 +318,6 @@ else()
319318
# add_dependencies(clang_rt.asan-dynamic-${arch} clang_rt.asan-dynamic-${arch}-version-list)
320319
# generates an order-only dependency in ninja.
321320
RTAsan_dynamic_version_script_dummy
322-
RTUbsan_cxx
323321
${ASAN_DYNAMIC_WEAK_INTERCEPTION}
324322
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
325323
LINK_FLAGS ${ASAN_DYNAMIC_LINK_FLAGS}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
275275
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
276276
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
277277
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
278-
$<TARGET_OBJECTS:RTUbsan.${arch}>
279-
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
278+
$<TARGET_OBJECTS:RTUbsan.${arch}>)
280279
endif()
281280
add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
282281
set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
@@ -302,8 +301,7 @@ if(ANDROID)
302301
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
303302
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
304303
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
305-
$<TARGET_OBJECTS:RTUbsan.${arch}>
306-
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
304+
$<TARGET_OBJECTS:RTUbsan.${arch}>>
307305
${COMPILER_RT_GTEST_SOURCE}
308306
${ASAN_NOINST_TEST_SOURCES})
309307
set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})

compiler-rt/lib/hwasan/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ function(add_hwasan_runtimes arch use_aliases)
188188
STATIC
189189
ARCHS ${arch}
190190
OBJECT_LIBS RTHwasan_cxx
191-
RTUbsan_cxx
192191
CFLAGS ${hwasan_rtl_flags}
193192
PARENT_TARGET hwasan)
194193

@@ -220,7 +219,6 @@ function(add_hwasan_runtimes arch use_aliases)
220219
RTSanitizerCommonSymbolizerInternal
221220
RTLSanCommon
222221
RTUbsan
223-
RTUbsan_cxx
224222
# The only purpose of RTHWAsan_dynamic_version_script_dummy is to
225223
# carry a dependency of the shared runtime on the version script.
226224
# Replacing it with a straightforward

compiler-rt/lib/msan/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ foreach(arch ${MSAN_SUPPORTED_ARCH})
6666
STATIC
6767
ARCHS ${arch}
6868
SOURCES ${MSAN_RTL_CXX_SOURCES}
69-
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
7069
ADDITIONAL_HEADERS ${MSAN_RTL_HEADERS}
7170
CFLAGS ${MSAN_RTL_CFLAGS}
7271
PARENT_TARGET msan)

compiler-rt/lib/tsan/rtl/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ else()
259259
STATIC
260260
ARCHS ${arch}
261261
SOURCES ${TSAN_CXX_SOURCES}
262-
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
263262
ADDITIONAL_HEADERS ${TSAN_HEADERS}
264263
CFLAGS ${TSAN_RTL_CFLAGS}
265264
PARENT_TARGET tsan)

compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
// RUN: | grep -v "__sanitizer_weak_hook" \
2424
// RUN: | grep -v "__sanitizer_override_function" \
2525
// RUN: | grep -v "__sanitizer_override_function_by_addr" \
26+
// RUN: | grep -v "__ubsan_handle_dynamic_type_cache_miss" \
27+
// RUN: | grep -v "__ubsan_handle_dynamic_type_cache_miss_abort" \
2628
// RUN: | grep -v "__sanitizer_register_weak_function" \
2729
// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports
2830
//

0 commit comments

Comments
 (0)