Skip to content

Commit

Permalink
Minimal runtime for UBSan.
Browse files Browse the repository at this point in the history
Summary:
An implementation of ubsan runtime library suitable for use in production.

Minimal attack surface.
* No stack traces.
* Definitely no C++ demangling.
* No UBSAN_OPTIONS=log_file=/path (very suid-unfriendly). And no UBSAN_OPTIONS in general.
* as simple as possible

Minimal CPU and RAM overhead.
* Source locations unnecessary in the presence of (split) debug info.
* Values and types (as in A+B overflows T) can be reconstructed from register/stack dumps, once you know what type of error you are looking at.
* above two items save 3% binary size.

When UBSan is used with -ftrap-function=abort, sometimes it is hard to reason about failures. This library replaces abort with a slightly more informative message without much extra overhead. Since ubsan interface in not stable, this code must reside in compiler-rt.

Reviewers: pcc, kcc

Subscribers: srhines, mgorny, aprantl, krytarowski, llvm-commits

Differential Revision: https://reviews.llvm.org/D36810

llvm-svn: 312029
  • Loading branch information
eugenis committed Aug 29, 2017
1 parent 75fa173 commit 6d2b6f0
Show file tree
Hide file tree
Showing 20 changed files with 436 additions and 26 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,10 @@ def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on
Group<f_clang_Group>;
def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
Group<f_clang_Group>;
def fsanitize_minimal_runtime : Flag<["-"], "fsanitize-minimal-runtime">,
Group<f_clang_Group>;
def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">,
Group<f_clang_Group>;
def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
Group<f_clang_Group>;
def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/SanitizerArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class SanitizerArgs {
bool TsanMemoryAccess = true;
bool TsanFuncEntryExit = true;
bool TsanAtomics = true;
bool MinimalRuntime = false;

public:
/// Parses the sanitizer arguments from an argument list.
Expand All @@ -58,6 +59,7 @@ class SanitizerArgs {
!Sanitizers.has(SanitizerKind::Address);
}
bool needsUbsanRt() const;
bool requiresMinimalRuntime() const { return MinimalRuntime; }
bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
bool needsSafeStackRt() const { return SafeStackRuntime; }
bool needsCfiRt() const;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Frontend/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
///< in MemorySanitizer
CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime for
///< diagnostics.
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
///< instrumentation.
CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
Expand Down
49 changes: 27 additions & 22 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2724,13 +2724,16 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
bool NeedsAbortSuffix =
IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
bool MinimalRuntime = CGF.CGM.getCodeGenOpts().SanitizeMinimalRuntime;
const SanitizerHandlerInfo &CheckInfo = SanitizerHandlers[CheckHandler];
const StringRef CheckName = CheckInfo.Name;
std::string FnName =
("__ubsan_handle_" + CheckName +
(CheckInfo.Version ? "_v" + llvm::utostr(CheckInfo.Version) : "") +
(NeedsAbortSuffix ? "_abort" : ""))
.str();
std::string FnName = "__ubsan_handle_" + CheckName.str();
if (CheckInfo.Version && !MinimalRuntime)
FnName += "_v" + llvm::utostr(CheckInfo.Version);
if (MinimalRuntime)
FnName += "_minimal";
if (NeedsAbortSuffix)
FnName += "_abort";
bool MayReturn =
!IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;

Expand Down Expand Up @@ -2817,24 +2820,26 @@ void CodeGenFunction::EmitCheck(
// representing operand values.
SmallVector<llvm::Value *, 4> Args;
SmallVector<llvm::Type *, 4> ArgTypes;
Args.reserve(DynamicArgs.size() + 1);
ArgTypes.reserve(DynamicArgs.size() + 1);

// Emit handler arguments and create handler function type.
if (!StaticArgs.empty()) {
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
auto *InfoPtr =
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
llvm::GlobalVariable::PrivateLinkage, Info);
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
ArgTypes.push_back(Int8PtrTy);
}
if (!CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
Args.reserve(DynamicArgs.size() + 1);
ArgTypes.reserve(DynamicArgs.size() + 1);

// Emit handler arguments and create handler function type.
if (!StaticArgs.empty()) {
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
auto *InfoPtr =
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
llvm::GlobalVariable::PrivateLinkage, Info);
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
ArgTypes.push_back(Int8PtrTy);
}

for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
Args.push_back(EmitCheckValue(DynamicArgs[i]));
ArgTypes.push_back(IntPtrTy);
for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
Args.push_back(EmitCheckValue(DynamicArgs[i]));
ArgTypes.push_back(IntPtrTy);
}
}

llvm::FunctionType *FnType =
Expand Down
39 changes: 39 additions & 0 deletions clang/lib/Driver/SanitizerArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum : SanitizerMask {
NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
NeedsUbsanCxxRt = Vptr | CFI,
NotAllowedWithTrap = Vptr,
NotAllowedWithMinimalRuntime = Vptr,
RequiresPIE = DataFlow,
NeedsUnwindTables = Address | Thread | Memory | DataFlow,
SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
Expand All @@ -41,6 +42,7 @@ enum : SanitizerMask {
Nullability | LocalBounds | CFI,
TrappingDefault = CFI,
CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
CompatibleWithMinimalRuntime = TrappingSupported,
};

enum CoverageFeature {
Expand Down Expand Up @@ -212,6 +214,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;

MinimalRuntime =
Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);

// The object size sanitizer should not be enabled at -O0.
Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
bool RemoveObjectSizeAtO0 =
Expand Down Expand Up @@ -249,6 +255,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
DiagnosedKinds |= KindsToDiagnose;
}
Add &= ~InvalidTrappingKinds;

if (MinimalRuntime) {
if (SanitizerMask KindsToDiagnose =
Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
D.Diag(diag::err_drv_argument_not_allowed_with)
<< Desc << "-fsanitize-minimal-runtime";
DiagnosedKinds |= KindsToDiagnose;
}
Add &= ~NotAllowedWithMinimalRuntime;
}

if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
D.Diag(diag::err_drv_unsupported_opt_for_target)
Expand Down Expand Up @@ -285,6 +303,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// Silently discard any unsupported sanitizers implicitly enabled through
// group expansion.
Add &= ~InvalidTrappingKinds;
if (MinimalRuntime) {
Add &= ~NotAllowedWithMinimalRuntime;
}
Add &= Supported;

if (Add & Fuzzer)
Expand Down Expand Up @@ -496,6 +517,21 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
Stats = Args.hasFlag(options::OPT_fsanitize_stats,
options::OPT_fno_sanitize_stats, false);

if (MinimalRuntime) {
SanitizerMask IncompatibleMask =
Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
if (IncompatibleMask)
D.Diag(clang::diag::err_drv_argument_not_allowed_with)
<< "-fsanitize-minimal-runtime"
<< lastArgumentForMask(D, Args, IncompatibleMask);

SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds;
if (NonTrappingCfi)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< "fsanitize-minimal-runtime"
<< "fsanitize-trap=cfi";
}

// Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
// enabled sanitizers.
for (const auto *Arg : Args) {
Expand Down Expand Up @@ -762,6 +798,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
if (Stats)
CmdArgs.push_back("-fsanitize-stats");

if (MinimalRuntime)
CmdArgs.push_back("-fsanitize-minimal-runtime");

if (AsanFieldPadding)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
llvm::utostr(AsanFieldPadding)));
Expand Down
11 changes: 8 additions & 3 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
SharedRuntimes.push_back("asan");
}

// The stats_client library is also statically linked into DSOs.
if (SanArgs.needsStatsRt())
StaticRuntimes.push_back("stats_client");
Expand Down Expand Up @@ -588,9 +589,13 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("tsan_cxx");
}
if (SanArgs.needsUbsanRt()) {
StaticRuntimes.push_back("ubsan_standalone");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("ubsan_standalone_cxx");
if (SanArgs.requiresMinimalRuntime()) {
StaticRuntimes.push_back("ubsan_minimal");
} else {
StaticRuntimes.push_back("ubsan_standalone");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("ubsan_standalone_cxx");
}
}
if (SanArgs.needsSafeStackRt()) {
NonWholeStaticRuntimes.push_back("safestack");
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
Opts.SanitizeMemoryUseAfterDtor =
Args.hasArg(OPT_fsanitize_memory_use_after_dtor);
Opts.SanitizeMinimalRuntime = Args.hasArg(OPT_fsanitize_minimal_runtime);
Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso);
Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope,
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CodeGen/unsigned-overflow-minimal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=unsigned-integer-overflow -fsanitize-minimal-runtime %s -emit-llvm -o - | FileCheck %s

unsigned long li, lj, lk;

// CHECK-LABEL: define void @testlongadd()
void testlongadd() {
// CHECK: call void @__ubsan_handle_add_overflow_minimal_abort()
li = lj + lk;
}

// CHECK-LABEL: define void @testlongsub()
void testlongsub() {
// CHECK: call void @__ubsan_handle_sub_overflow_minimal_abort()
li = lj - lk;
}

// CHECK-LABEL: define void @testlongmul()
void testlongmul() {
// CHECK: call void @__ubsan_handle_mul_overflow_minimal_abort()
li = lj * lk;
}
29 changes: 29 additions & 0 deletions clang/test/Driver/fsanitize.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,32 @@
// Make sure there are no *.{o,bc} or -l passed before the ASan library.
// CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}}
// CHECK-ASAN-PS4: -lSceDbgAddressSanitizer_stub_weak

// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-MINIMAL
// CHECK-ASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'

// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MINIMAL
// CHECK-TSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=thread'

// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL
// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"

// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize=vptr -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-VPTR-MINIMAL
// CHECK-UBSAN-VPTR-MINIMAL: error: invalid argument '-fsanitize=vptr' not allowed with '-fsanitize-minimal-runtime'

// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-UBSAN-MINIMAL
// CHECK-ASAN-UBSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'

// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-MINIMAL
// CHECK-CFI-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
// CHECK-CFI-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
// CHECK-CFI-MINIMAL: "-fsanitize-minimal-runtime"

// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-MINIMAL
// CHECK-CFI-NOTRAP-MINIMAL: error: invalid argument 'fsanitize-minimal-runtime' only allowed with 'fsanitize-trap=cfi'

// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -fno-sanitize=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOICALL-MINIMAL
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-minimal-runtime"
8 changes: 8 additions & 0 deletions clang/test/Driver/sanitizer-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@
// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-CXX: "-lpthread"

// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBSAN-MINIMAL-LINUX %s
// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-UBSAN-MINIMAL-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan_minimal-i386.a" "-no-whole-archive"
// CHECK-UBSAN-MINIMAL-LINUX: "-lpthread"

// RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
Expand Down
9 changes: 8 additions & 1 deletion compiler-rt/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ else()
set(OS_NAME "${CMAKE_SYSTEM_NAME}")
endif()

set(ALL_SANITIZERS asan;dfsan;msan;tsan;safestack;cfi;esan;scudo)
set(ALL_SANITIZERS asan;dfsan;msan;tsan;safestack;cfi;esan;scudo;ubsan_minimal)
set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING
"sanitizers to build if supported on the target (all;${ALL_SANITIZERS})")
list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}")
Expand Down Expand Up @@ -545,6 +545,13 @@ else()
set(COMPILER_RT_HAS_UBSAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Android")
set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE)
else()
set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD")
set(COMPILER_RT_HAS_SAFESTACK TRUE)
Expand Down
50 changes: 50 additions & 0 deletions compiler-rt/lib/ubsan_minimal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Build for the undefined behavior sanitizer runtime support library.

set(UBSAN_MINIMAL_SOURCES
ubsan_minimal_handlers.cc
)

include_directories(..)

set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_rtti_flag(OFF UBSAN_CFLAGS)

set(UBSAN_STANDALONE_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_rtti_flag(OFF UBSAN_STANDALONE_CFLAGS)

add_compiler_rt_component(ubsan-minimal)

# Common parts of UBSan runtime.
add_compiler_rt_object_libraries(RTUbsan_minimal
ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}
SOURCES ${UBSAN_MINIMAL_SOURCES} CFLAGS ${UBSAN_CFLAGS})


if(COMPILER_RT_HAS_UBSAN)
# Initializer of standalone UBSan runtime.

# Standalone UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_minimal
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
PARENT_TARGET ubsan-minimal)

add_compiler_rt_runtime(clang_rt.ubsan_minimal
SHARED
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
PARENT_TARGET ubsan-minimal)

if (UNIX)
set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386 i686)
add_sanitizer_rt_symbols(clang_rt.ubsan_minimal
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan-minimal
EXTRA ubsan.syms.extra)
endif()
endif()
1 change: 1 addition & 0 deletions compiler-rt/lib/ubsan_minimal/ubsan.syms.extra
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__ubsan_*
Loading

0 comments on commit 6d2b6f0

Please sign in to comment.