[UBSan] Embed UBSan into ASan runtime (compiler-rt part).

Summary:
Change the way we use ASan and UBSan together. Instead of keeping two
separate runtimes (libclang_rt.asan and libclang_rt.ubsan), embed UBSan
into ASan and get rid of libclang_rt.ubsan. If UBSan is not supported on
a platform, all UBSan sources are just compiled into dummy empty object
files. UBSan initialization code (e.g. flag parsing) is directly called
from ASan initialization, so we are able to enforce correct
initialization order.

This mirrors the approach we already use for ASan+LSan. This change
doesn't modify the way we use standalone UBSan.

Test Plan: regression test suite

Reviewers: kubabrecka, zaks.anna, rsmith, kcc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D8646

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@233861 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexey Samsonov 2015-04-01 22:42:36 +00:00
parent 06dcedbe14
commit b05184a296
19 changed files with 204 additions and 118 deletions

View File

@ -305,9 +305,9 @@ if(APPLE)
-stdlib=libc++
-mios-simulator-version-min=7.0 -isysroot ${IOSSIM_SDK_DIR})
set(DARWIN_osx_LINKFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}
-stdlib=libc++ -lc++)
-stdlib=libc++ -lc++ -lc++abi)
set(DARWIN_iossim_LINKFLAGS
-stdlib=libc++ -lc++
-stdlib=libc++ -lc++ -lc++abi
-Wl,-ios_simulator_version_min,7.0.0
-mios-simulator-version-min=7.0
-isysroot ${IOSSIM_SDK_DIR})

View File

@ -221,10 +221,12 @@ endfunction()
# Architectures supported by compiler-rt libraries.
filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
x86_64 i386 i686 powerpc64 powerpc64le arm aarch64 mips mips64 mipsel mips64el)
# LSan common files should be available on all architectures supported
# LSan and UBSan common files should be available on all architectures supported
# by other sanitizers (even if they build into dummy object files).
filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH
${SANITIZER_COMMON_SUPPORTED_ARCH})
filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH
${SANITIZER_COMMON_SUPPORTED_ARCH})
filter_available_targets(ASAN_SUPPORTED_ARCH
x86_64 i386 i686 powerpc64 powerpc64le arm mips mipsel mips64 mips64el)
filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)

View File

@ -8,6 +8,7 @@ if(COMPILER_RT_HAS_SANITIZER_COMMON)
add_subdirectory(interception)
add_subdirectory(sanitizer_common)
add_subdirectory(lsan)
add_subdirectory(ubsan)
endif()
if(COMPILER_RT_HAS_ASAN)
@ -33,7 +34,3 @@ if(COMPILER_RT_HAS_TSAN)
add_subdirectory(tsan/dd)
endif()
if(COMPILER_RT_HAS_UBSAN)
add_subdirectory(ubsan)
endif()

View File

@ -96,6 +96,7 @@ if(APPLE)
$<TARGET_OBJECTS:RTInterception.${os}>
$<TARGET_OBJECTS:RTSanitizerCommon.${os}>
$<TARGET_OBJECTS:RTLSanCommon.${os}>
$<TARGET_OBJECTS:RTUbsan.${os}>
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
DEFS ${ASAN_DYNAMIC_DEFINITIONS})
add_dependencies(asan clang_rt.asan_${os}_dynamic)
@ -107,7 +108,8 @@ else()
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>)
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>)
add_compiler_rt_runtime(clang_rt.asan-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTAsan_preinit.${arch}>
@ -119,6 +121,7 @@ else()
add_compiler_rt_runtime(clang_rt.asan_cxx-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
CFLAGS ${ASAN_CFLAGS}
DEFS ${ASAN_COMMON_DEFINITIONS})
add_dependencies(asan clang_rt.asan_cxx-${arch})
@ -137,6 +140,7 @@ else()
add_compiler_rt_runtime(clang_rt.asan-dynamic-${arch} ${arch} SHARED
OUTPUT_NAME ${SHARED_ASAN_NAME}
SOURCES $<TARGET_OBJECTS:RTAsan_dynamic.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
${ASAN_COMMON_RUNTIME_OBJECTS}
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
DEFS ${ASAN_DYNAMIC_DEFINITIONS})

View File

@ -20,6 +20,8 @@
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_platform.h"
namespace __asan {
@ -72,8 +74,8 @@ void InitializeFlags() {
RegisterAsanFlags(&asan_parser, f);
RegisterCommonFlags(&asan_parser);
// Set the default values and prepare for parsing LSan flags (which can also
// overwrite common flags).
// Set the default values and prepare for parsing LSan and UBSan flags
// (which can also overwrite common flags).
#if CAN_SANITIZE_LEAKS
__lsan::Flags *lf = __lsan::flags();
lf->SetDefaults();
@ -83,6 +85,15 @@ void InitializeFlags() {
RegisterCommonFlags(&lsan_parser);
#endif
#if CAN_SANITIZE_UB
__ubsan::Flags *uf = __ubsan::flags();
uf->SetDefaults();
FlagParser ubsan_parser;
__ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
RegisterCommonFlags(&ubsan_parser);
#endif
// Override from ASan compile definition.
const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
asan_parser.ParseString(asan_compile_def);
@ -90,12 +101,19 @@ void InitializeFlags() {
// Override from user-specified string.
const char *asan_default_options = MaybeCallAsanDefaultOptions();
asan_parser.ParseString(asan_default_options);
#if CAN_SANITIZE_UB
const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
ubsan_parser.ParseString(ubsan_default_options);
#endif
// Override from command line.
asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
#if CAN_SANITIZE_LEAKS
lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
#endif
#if CAN_SANITIZE_UB
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
#endif
// Let activation flags override current settings. On Android they come
// from a system property. On other platforms this is no-op.

View File

@ -28,6 +28,8 @@
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
#include "lsan/lsan_common.h"
#include "ubsan/ubsan_init.h"
#include "ubsan/ubsan_platform.h"
int __asan_option_detect_stack_use_after_return; // Global interface symbol.
uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
@ -495,6 +497,10 @@ static void AsanInitInternal() {
}
#endif // CAN_SANITIZE_LEAKS
#if CAN_SANITIZE_UB
__ubsan::InitAsPlugin();
#endif
InitializeSuppressions();
VReport(1, "AddressSanitizer Init done\n");

View File

@ -214,18 +214,18 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
$<TARGET_OBJECTS:RTAsan.osx>
$<TARGET_OBJECTS:RTInterception.osx>
$<TARGET_OBJECTS:RTSanitizerCommon.osx>
$<TARGET_OBJECTS:RTLSanCommon.osx>)
$<TARGET_OBJECTS:RTLSanCommon.osx>
$<TARGET_OBJECTS:RTUbsan.osx>)
else()
set(ASAN_TEST_RUNTIME_OBJECTS
$<TARGET_OBJECTS:RTAsan.${arch}>
$<TARGET_OBJECTS:RTAsan_cxx.${arch}>
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
if(NOT WIN32)
list(APPEND ASAN_TEST_RUNTIME_OBJECTS
$<TARGET_OBJECTS:RTLSanCommon.${arch}>)
endif()
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTLSanCommon.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
endif()
add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES

View File

@ -8,6 +8,10 @@ set(UBSAN_SOURCES
ubsan_value.cc
)
set(UBSAN_STANDALONE_SOURCES
ubsan_init_standalone.cc
)
set(UBSAN_CXX_SOURCES
ubsan_handlers_cxx.cc
ubsan_type_hash.cc
@ -17,64 +21,69 @@ include_directories(..)
set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_no_rtti_flag(UBSAN_CFLAGS)
set(UBSAN_STANDALONE_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_no_rtti_flag(UBSAN_STANDALONE_CFLAGS)
set(UBSAN_CXXFLAGS ${SANITIZER_COMMON_CFLAGS})
add_custom_target(ubsan)
if(APPLE)
foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
# Common parts of UBSan runtime.
add_compiler_rt_darwin_object_library(RTUbsan ${os}
ARCH ${UBSAN_SUPPORTED_ARCH}
ARCH ${UBSAN_COMMON_SUPPORTED_ARCH}
SOURCES ${UBSAN_SOURCES} ${UBSAN_CXX_SOURCES}
CFLAGS ${UBSAN_CXXFLAGS})
add_compiler_rt_darwin_dynamic_runtime(clang_rt.ubsan_${os}_dynamic ${os}
ARCH ${UBSAN_SUPPORTED_ARCH}
SOURCES $<TARGET_OBJECTS:RTUbsan.${os}>
$<TARGET_OBJECTS:RTSanitizerCommon.${os}>
LINKFLAGS -lc++abi)
if(UBSAN_SUPPORTED_ARCH)
# Initializer of standalone UBSan runtime.
add_compiler_rt_darwin_object_library(RTUbsan_standalone ${os}
ARCH ${UBSAN_SUPPORTED_ARCH}
SOURCES ${UBSAN_STANDALONE_SOURCES}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})
add_dependencies(ubsan clang_rt.ubsan_${os}_dynamic)
add_compiler_rt_darwin_dynamic_runtime(clang_rt.ubsan_${os}_dynamic ${os}
ARCH ${UBSAN_SUPPORTED_ARCH}
SOURCES $<TARGET_OBJECTS:RTUbsan.${os}>
$<TARGET_OBJECTS:RTUbsan_standalone.${os}>
$<TARGET_OBJECTS:RTSanitizerCommon.${os}>)
add_dependencies(ubsan clang_rt.ubsan_${os}_dynamic)
endif()
endforeach()
else()
# Build separate libraries for each target.
foreach(arch ${UBSAN_SUPPORTED_ARCH})
# Common parts of UBSan runtime.
foreach(arch ${UBSAN_COMMON_SUPPORTED_ARCH})
add_compiler_rt_object_library(RTUbsan ${arch}
SOURCES ${UBSAN_SOURCES} CFLAGS ${UBSAN_CFLAGS})
# C++-specific parts of UBSan runtime. Requires a C++ ABI library.
add_compiler_rt_object_library(RTUbsan_cxx ${arch}
SOURCES ${UBSAN_CXX_SOURCES} CFLAGS ${UBSAN_CXXFLAGS})
endforeach()
foreach(arch ${UBSAN_SUPPORTED_ARCH})
# Initializer of standalone UBSan runtime.
add_compiler_rt_object_library(RTUbsan_standalone ${arch}
SOURCES ${UBSAN_STANDALONE_SOURCES} CFLAGS ${UBSAN_STANDALONE_CFLAGS})
# Standalone UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_standalone-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
$<TARGET_OBJECTS:RTUbsan_standalone.${arch}>
CFLAGS ${UBSAN_CFLAGS})
add_compiler_rt_runtime(clang_rt.ubsan_standalone_cxx-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
CFLAGS ${UBSAN_CXXFLAGS})
# UBSan runtimes used when another sanitizer is available.
add_compiler_rt_runtime(clang_rt.ubsan-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTUbsan.${arch}>
CFLAGS ${UBSAN_CFLAGS})
add_compiler_rt_runtime(clang_rt.ubsan_cxx-${arch} ${arch} STATIC
SOURCES $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
CFLAGS ${UBSAN_CXXFLAGS})
add_dependencies(ubsan
clang_rt.ubsan-${arch}
clang_rt.ubsan_cxx-${arch}
clang_rt.ubsan_standalone-${arch}
clang_rt.ubsan_standalone_cxx-${arch})
if (UNIX AND NOT ${arch} MATCHES "i386|i686")
add_sanitizer_rt_symbols(clang_rt.ubsan-${arch} ubsan.syms.extra)
add_sanitizer_rt_symbols(clang_rt.ubsan_cxx-${arch} ubsan.syms.extra)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone-${arch} ubsan.syms.extra)
add_sanitizer_rt_symbols(clang_rt.ubsan_standalone_cxx-${arch} ubsan.syms.extra)
add_dependencies(ubsan
clang_rt.ubsan-${arch}-symbols
clang_rt.ubsan_cxx-${arch}-symbols
clang_rt.ubsan_standalone-${arch}-symbols
clang_rt.ubsan_standalone_cxx-${arch}-symbols)
endif()

View File

@ -11,8 +11,9 @@ ModuleName := ubsan
SubDirs :=
Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))
StandaloneSources := ubsan_init_standalone.cc
CXXSources := ubsan_type_hash.cc ubsan_handlers_cxx.cc
CSources := $(filter-out $(CXXSources),$(Sources))
CSources := $(filter-out $(StandaloneSources),$(filter-out $(CXXSources),$(Sources)))
ObjNames := $(Sources:%.cc=%.o)
Implementation := Generic
@ -24,3 +25,4 @@ Dependencies += $(wildcard $(Dir)/../sanitizer_common/*.h)
# Define a convenience variable for all the ubsan functions.
UbsanFunctions := $(CSources:%.cc=%)
UbsanCXXFunctions := $(CXXSources:%.cc=%)
UbsanStandaloneFunctions := $(StandaloneSources:%.cc=%)

View File

@ -27,7 +27,7 @@
using namespace __ubsan;
static void MaybePrintStackTrace(uptr pc, uptr bp) {
// We assume that flags are already parsed: InitIfNecessary
// We assume that flags are already parsed, as UBSan runtime
// will definitely be called when we print the first diagnostics message.
if (!flags()->print_stacktrace)
return;
@ -76,7 +76,7 @@ class Decorator : public SanitizerCommonDecorator {
}
SymbolizedStack *__ubsan::getSymbolizedLocation(uptr PC) {
InitIfNecessary();
InitAsStandaloneIfNecessary();
return Symbolizer::GetOrInit()->SymbolizePC(PC);
}
@ -330,7 +330,7 @@ Diag::~Diag() {
ScopedReport::ScopedReport(ReportOptions Opts, Location SummaryLoc)
: Opts(Opts), SummaryLoc(SummaryLoc) {
InitIfNecessary();
InitAsStandaloneIfNecessary();
CommonSanitizerReportMutex.Lock();
}
@ -355,10 +355,7 @@ void __ubsan::InitializeSuppressions() {
}
bool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {
// If .preinit_array is not used, it is possible that the UBSan runtime is not
// initialized.
if (!SANITIZER_CAN_USE_PREINIT_ARRAY)
InitIfNecessary();
InitAsStandaloneIfNecessary();
CHECK(suppression_ctx);
Suppression *s;
return suppression_ctx->Match(TypeName, kVptrCheck, &s);

View File

@ -20,7 +20,7 @@
namespace __ubsan {
static const char *MaybeCallUbsanDefaultOptions() {
const char *MaybeCallUbsanDefaultOptions() {
return (&__ubsan_default_options) ? __ubsan_default_options() : "";
}
@ -39,31 +39,22 @@ void RegisterUbsanFlags(FlagParser *parser, Flags *f) {
#undef UBSAN_FLAG
}
void InitializeFlags(bool standalone) {
Flags *f = flags();
FlagParser parser;
RegisterUbsanFlags(&parser, f);
if (standalone) {
RegisterCommonFlags(&parser);
SetCommonFlagsDefaults();
void InitializeFlags() {
SetCommonFlagsDefaults();
{
CommonFlags cf;
cf.CopyFrom(*common_flags());
cf.print_summary = false;
OverrideCommonFlags(cf);
} else {
// Ignore common flags if not standalone.
// This is inconsistent with LSan, which allows common flags in LSAN_FLAGS.
// This is caused by undefined initialization order between ASan and UBsan,
// which makes it impossible to make sure that common flags from ASAN_OPTIONS
// have not been used (in __asan_init) before they are overwritten with flags
// from UBSAN_OPTIONS.
CommonFlags cf_ignored;
RegisterCommonFlags(&parser, &cf_ignored);
}
Flags *f = flags();
f->SetDefaults();
FlagParser parser;
RegisterCommonFlags(&parser);
RegisterUbsanFlags(&parser, f);
// Override from user-specified string.
parser.ParseString(MaybeCallUbsanDefaultOptions());
// Override from environment variable.

View File

@ -15,6 +15,10 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
namespace __sanitizer {
class FlagParser;
}
namespace __ubsan {
struct Flags {
@ -28,7 +32,10 @@ struct Flags {
extern Flags ubsan_flags;
inline Flags *flags() { return &ubsan_flags; }
void InitializeFlags(bool standalone);
void InitializeFlags();
void RegisterUbsanFlags(FlagParser *parser, Flags *f);
const char *MaybeCallUbsanDefaultOptions();
} // namespace __ubsan

View File

@ -23,45 +23,54 @@
using namespace __ubsan;
static bool ubsan_inited;
static enum {
UBSAN_MODE_UNKNOWN = 0,
UBSAN_MODE_STANDALONE,
UBSAN_MODE_PLUGIN
} ubsan_mode;
static StaticSpinMutex ubsan_init_mu;
void __ubsan::InitIfNecessary() {
#if !SANITIZER_CAN_USE_PREINIT_ARRAY
// No need to lock mutex if we're initializing from preinit array.
static StaticSpinMutex init_mu;
SpinMutexLock l(&init_mu);
#endif
if (LIKELY(ubsan_inited))
return;
bool standalone = false;
if (0 == internal_strcmp(SanitizerToolName, "SanitizerTool")) {
// WARNING: If this condition holds, then either UBSan runs in a standalone
// mode, or initializer for another sanitizer hasn't run yet. In a latter
// case, another sanitizer will overwrite "SanitizerToolName" and reparse
// common flags. It means, that we are not allowed to *use* common flags
// in this function.
SanitizerToolName = "UndefinedBehaviorSanitizer";
standalone = true;
}
// Initialize UBSan-specific flags.
InitializeFlags(standalone);
static void CommonInit() {
InitializeSuppressions();
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
ubsan_inited = true;
}
#if SANITIZER_CAN_USE_PREINIT_ARRAY
__attribute__((section(".preinit_array"), used))
void (*__local_ubsan_preinit)(void) = __ubsan::InitIfNecessary;
#else
// Use a dynamic initializer.
class UbsanInitializer {
public:
UbsanInitializer() {
InitIfNecessary();
static void CommonStandaloneInit() {
SanitizerToolName = "UndefinedBehaviorSanitizer";
InitializeFlags();
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
CommonInit();
ubsan_mode = UBSAN_MODE_STANDALONE;
}
void __ubsan::InitAsStandalone() {
if (SANITIZER_CAN_USE_PREINIT_ARRAY) {
CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);
CommonStandaloneInit();
return;
}
};
static UbsanInitializer ubsan_initializer;
#endif // SANITIZER_CAN_USE_PREINIT_ARRAY
SpinMutexLock l(&ubsan_init_mu);
CHECK_NE(UBSAN_MODE_PLUGIN, ubsan_mode);
if (ubsan_mode == UBSAN_MODE_UNKNOWN)
CommonStandaloneInit();
}
void __ubsan::InitAsStandaloneIfNecessary() {
if (SANITIZER_CAN_USE_PREINIT_ARRAY) {
CHECK_NE(UBSAN_MODE_UNKNOWN, ubsan_mode);
return;
}
SpinMutexLock l(&ubsan_init_mu);
if (ubsan_mode == UBSAN_MODE_UNKNOWN)
CommonStandaloneInit();
}
void __ubsan::InitAsPlugin() {
#if !SANITIZER_CAN_USE_PREINIT_ARRAY
SpinMutexLock l(&ubsan_init_mu);
#endif
CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);
CommonInit();
ubsan_mode = UBSAN_MODE_PLUGIN;
}
#endif // CAN_SANITIZE_UB

View File

@ -15,9 +15,16 @@
namespace __ubsan {
// NOTE: This function might take a lock (if .preinit_array initialization is
// not used). It's generally a bad idea to call it on a fast path.
void InitIfNecessary();
// Initialize UBSan as a standalone tool. Typically should be called early
// during initialization.
void InitAsStandalone();
// Initialize UBSan as a standalone tool, if it hasn't been initialized before.
void InitAsStandaloneIfNecessary();
// Initializes UBSan as a plugin tool. This function should be called once
// from "parent tool" (e.g. ASan) initialization.
void InitAsPlugin();
} // namespace __ubsan

View File

@ -0,0 +1,34 @@
//===-- ubsan_init_standalone.cc ------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Initialization of standalone UBSan runtime.
//
//===----------------------------------------------------------------------===//
#include "ubsan_platform.h"
#if !CAN_SANITIZE_UB
# error "UBSan is not supported on this platform!
#endif
#include "ubsan_init.h"
#if SANITIZER_CAN_USE_PREINIT_ARRAY
__attribute__((section(".preinit_array"), used))
void (*__local_ubsan_preinit)(void) = __ubsan::InitAsStandalone;
#else
// Use a dynamic initializer.
class UbsanStandaloneInitializer {
public:
UbsanStandaloneInitializer() {
__ubsan::InitAsStandalone();
}
};
static UbsanStandaloneInitializer ubsan_standalone_initializer;
#endif // SANITIZER_CAN_USE_PREINIT_ARRAY

View File

@ -20,7 +20,6 @@
# define CAN_SANITIZE_UB 1
#else
# define CAN_SANITIZE_UB 0
# error "UBSan not supported for this platform!"
#endif
#endif

View File

@ -230,7 +230,7 @@ CFLAGS.profile_ios.armv7k := $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)
CFLAGS.profile_ios.armv7s := $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)
CFLAGS.profile_ios.arm64 := $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
SANITIZER_LDFLAGS := -stdlib=libc++ -lc++
SANITIZER_LDFLAGS := -stdlib=libc++ -lc++ -lc++abi
SHARED_LIBRARY.asan_osx_dynamic := 1
LDFLAGS.asan_osx_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.asan_osx_dynamic.dylib \
@ -241,11 +241,11 @@ LDFLAGS.asan_iossim_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclan
-Wl,-ios_simulator_version_min,7.0.0 $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS)
SHARED_LIBRARY.ubsan_osx_dynamic := 1
LDFLAGS.ubsan_osx_dynamic := $(SANITIZER_LDFLAGS) -lc++abi -install_name @rpath/libclang_rt.ubsan_osx_dynamic.dylib \
LDFLAGS.ubsan_osx_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.ubsan_osx_dynamic.dylib \
$(SANITIZER_MACOSX_DEPLOYMENT_ARGS)
SHARED_LIBRARY.ubsan_iossim_dynamic := 1
LDFLAGS.ubsan_iossim_dynamic := $(SANITIZER_LDFLAGS) -lc++abi -install_name @rpath/libclang_rt.ubsan_iossim_dynamic.dylib \
LDFLAGS.ubsan_iossim_dynamic := $(SANITIZER_LDFLAGS) -install_name @rpath/libclang_rt.ubsan_iossim_dynamic.dylib \
-Wl,-ios_simulator_version_min,7.0.0 $(SANITIZER_IOSSIM_DEPLOYMENT_ARGS)
ifneq ($(OSX_SDK),)
@ -275,18 +275,22 @@ FUNCTIONS.profile_ios := $(FUNCTIONS.profile_osx)
FUNCTIONS.asan_osx_dynamic := $(AsanFunctions) $(AsanCXXFunctions) \
$(InterceptionFunctions) \
$(SanitizerCommonFunctions) \
$(AsanDynamicFunctions)
$(AsanDynamicFunctions) \
$(UbsanFunctions) $(UbsanCXXFunctions)
FUNCTIONS.asan_iossim_dynamic := $(AsanFunctions) $(AsanCXXFunctions) \
$(InterceptionFunctions) \
$(SanitizerCommonFunctions) \
$(AsanDynamicFunctions)
$(AsanDynamicFunctions) \
$(UbsanFunctions) $(UbsanCXXFunctions)
FUNCTIONS.ubsan_osx_dynamic := $(UbsanFunctions) $(UbsanCXXFunctions) \
$(SanitizerCommonFunctions)
$(SanitizerCommonFunctions) \
$(UbsanStandaloneFunctions)
FUNCTIONS.ubsan_iossim_dynamic := $(UbsanFunctions) $(UbsanCXXFunctions) \
$(SanitizerCommonFunctions)
$(SanitizerCommonFunctions) \
$(UbsanStandaloneFunctions)
CCKEXT_PROFILE_FUNCTIONS := \
InstrProfiling \

View File

@ -3,16 +3,16 @@
// RUN: mkdir -p %T/coverage-levels
// RUN: OPT=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels
// RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t
// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: %clangxx -fsanitize=undefined -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t
// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=1 %s -o %t
// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=2 %s -o %t
// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3 %s -o %t
// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
volatile int sink;
int main(int argc, char **argv) {

View File

@ -1,7 +1,7 @@
// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
// RUN: %run %t 2>&1 | FileCheck %s
// Verify that we can disable symbolization if needed:
// RUN: UBSAN_OPTIONS=symbolize=0 ASAN_OPTIONS=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
// RUN: UBSAN_OPTIONS=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
// -fsanitize=function is unsupported on Darwin yet.
// XFAIL: darwin