Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0, Benign) ///< Enable use-after-delet
CODEGENOPT(SanitizeCfiCrossDso, 1, 0, Benign) ///< Enable cross-dso support in CFI.
CODEGENOPT(SanitizeMinimalRuntime, 1, 0, Benign) ///< Use "_minimal" sanitizer runtime for
///< diagnostics.
CODEGENOPT(SanitizeHandlerPreserveAllRegs, 1, 0, Benign) ///< Use "_preserve" sanitizer runtime for
///< diagnostics.
CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0, Benign) ///< Generalize pointer types in
///< CFI icall function signatures
CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0, Benign) ///< Normalize integer types in
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Driver/SanitizerArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class SanitizerArgs {
bool TsanFuncEntryExit = true;
bool TsanAtomics = true;
bool MinimalRuntime = false;
bool HandlerPreserveAllRegs = false;
// True if cross-dso CFI support if provided by the system (i.e. Android).
bool ImplicitCfiRuntime = false;
bool NeedsMemProfRt = false;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2656,6 +2656,11 @@ defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime",
PosFlag<SetTrue>,
NegFlag<SetFalse>>,
Group<f_clang_Group>;
defm sanitize_handler_preserve_all_regs
: BoolOption<"f", "sanitize-handler-preserve-all-regs",
CodeGenOpts<"SanitizeHandlerPreserveAllRegs">, DefaultFalse,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HelpText<>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

PosFlag<SetTrue>, NegFlag<SetFalse>>,
Group<f_clang_Group>;
def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">,
Group<f_clang_Group>;
def fno_sanitize_link_runtime : Flag<["-"], "fno-sanitize-link-runtime">,
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Driver/SanitizerArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
MinimalRuntime =
Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
HandlerPreserveAllRegs =
Args.hasFlag(options::OPT_fsanitize_handler_preserve_all_regs,
options::OPT_fno_sanitize_handler_preserve_all_regs,
HandlerPreserveAllRegs);

// The object size sanitizer should not be enabled at -O0.
Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
Expand Down Expand Up @@ -1469,6 +1473,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
if (MinimalRuntime)
CmdArgs.push_back("-fsanitize-minimal-runtime");

if (HandlerPreserveAllRegs)
CmdArgs.push_back("-fsanitize-handler-preserve-all-regs");

if (AsanFieldPadding)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
Twine(AsanFieldPadding)));
Expand Down
5 changes: 5 additions & 0 deletions clang/test/Driver/fsanitize.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,11 @@
// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-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),?){18}"}}
// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"

// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime -fsanitize-handler-preserve-all-regs %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL-PRESERVE
// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize={{((signed-integer-overflow|integer-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),?){18}"}}
// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-minimal-runtime"
// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-handler-preserve-all-regs

// RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer -fsanitize-trap=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTSAN-TRAP
// CHECK-INTSAN-TRAP: "-fsanitize-trap=integer-divide-by-zero,shift-base,shift-exponent,signed-integer-overflow,unsigned-integer-overflow,unsigned-shift-base,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change"

Expand Down
19 changes: 19 additions & 0 deletions compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, const char *kind,
}
}

SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error_preserve,
const char *kind, uintptr_t caller,
const uintptr_t *address)
[[clang::preserve_all]] {
// Additional indirecton so the user can override this with their own
// preserve_all function. This would allow, e.g., a function that reports the
// first error only, so for all subsequent calls we can skip the register save
// / restore.
__ubsan_report_error(kind, caller, address);
}

SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error_fatal, const char *kind,
uintptr_t caller, const uintptr_t *address) {
// Use another handlers, in case it's already overriden.
Expand Down Expand Up @@ -130,6 +141,10 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
#define HANDLER_RECOVER(name, kind) \
INTERFACE void __ubsan_handle_##name##_minimal() { \
__ubsan_report_error(kind, GET_CALLER_PC(), nullptr); \
} \
INTERFACE void __ubsan_handle_##name##_minimal_preserve() \
[[clang::preserve_all]] { \
__ubsan_report_error_preserve(kind, GET_CALLER_PC(), nullptr); \
}

#define HANDLER_NORECOVER(name, kind) \
Expand All @@ -146,6 +161,10 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
#define HANDLER_RECOVER_PTR(name, kind) \
INTERFACE void __ubsan_handle_##name##_minimal(const uintptr_t address) { \
__ubsan_report_error(kind, GET_CALLER_PC(), &address); \
} \
INTERFACE void __ubsan_handle_##name##_minimal_preserve( \
const uintptr_t address) [[clang::preserve_all]] { \
__ubsan_report_error_preserve(kind, GET_CALLER_PC(), &address); \
}

#define HANDLER_NORECOVER_PTR(name, kind) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// REQUIRES: x86_64-darwin

// RUN: nm -jgU `%clangxx_min_runtime -fsanitize-minimal-runtime -fsanitize=undefined %s -o %t '-###' 2>&1 | grep "libclang_rt.ubsan_minimal_osx_dynamic.dylib" | sed -e 's/.*"\(.*libclang_rt.ubsan_minimal_osx_dynamic.dylib\)".*/\1/'` | grep "^___ubsan_handle" \
// RUN: | grep -vE "_minimal_preserve" \
// RUN: | sed 's/_minimal//g' \
// RUN: > %t.minimal.symlist
//
Expand Down
Loading