Skip to content

Commit a508249

Browse files
authored
[UBsan] add -fsanitize-handler-preserve-all-regs flag (#168644)
This is currently a no op. This will be supported for the minimal runtime in a follow up. This allows to improve codegen for fsanitize-recover by compiling the handlers with [[clang::preserve_all]]. This makes sure that the caller does not need to spill any registers. We do not expect this function to be called frequently, so this is beneficial for code size.
1 parent 590bb3e commit a508249

File tree

5 files changed

+24
-0
lines changed

5 files changed

+24
-0
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0, Benign) ///< Enable use-after-delet
270270
CODEGENOPT(SanitizeCfiCrossDso, 1, 0, Benign) ///< Enable cross-dso support in CFI.
271271
CODEGENOPT(SanitizeMinimalRuntime, 1, 0, Benign) ///< Use "_minimal" sanitizer runtime for
272272
///< diagnostics.
273+
CODEGENOPT(SanitizeHandlerPreserveAllRegs, 1, 0, Benign) ///< Use "_preserve" sanitizer runtime for
274+
///< diagnostics.
273275
CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0, Benign) ///< Generalize pointer types in
274276
///< CFI icall function signatures
275277
CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0, Benign) ///< Normalize integer types in

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class SanitizerArgs {
6868
bool TsanAtomics = true;
6969
bool MinimalRuntime = false;
7070
bool TysanOutlineInstrumentation = true;
71+
bool HandlerPreserveAllRegs = false;
7172
// True if cross-dso CFI support if provided by the system (i.e. Android).
7273
bool ImplicitCfiRuntime = false;
7374
bool NeedsMemProfRt = false;

clang/include/clang/Options/Options.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,6 +2666,15 @@ defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime",
26662666
PosFlag<SetTrue>,
26672667
NegFlag<SetFalse>>,
26682668
Group<f_clang_Group>;
2669+
defm sanitize_handler_preserve_all_regs
2670+
: BoolOption<
2671+
"f", "sanitize-handler-preserve-all-regs",
2672+
CodeGenOpts<"SanitizeHandlerPreserveAllRegs">, DefaultFalse,
2673+
PosFlag<SetTrue, [], [],
2674+
"Enable handlers with preserve_all calling convention">,
2675+
NegFlag<SetFalse, [], [],
2676+
"Disable handlers with preserve_all calling convention">>,
2677+
Group<f_clang_Group>;
26692678
def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">,
26702679
Group<f_clang_Group>;
26712680
def fno_sanitize_link_runtime : Flag<["-"], "fno-sanitize-link-runtime">,

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
423423
MinimalRuntime =
424424
Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
425425
options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
426+
HandlerPreserveAllRegs =
427+
Args.hasFlag(options::OPT_fsanitize_handler_preserve_all_regs,
428+
options::OPT_fno_sanitize_handler_preserve_all_regs,
429+
HandlerPreserveAllRegs);
426430

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

1483+
if (HandlerPreserveAllRegs)
1484+
CmdArgs.push_back("-fsanitize-handler-preserve-all-regs");
1485+
14791486
if (AsanFieldPadding)
14801487
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
14811488
Twine(AsanFieldPadding)));

clang/test/Driver/fsanitize.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,11 @@
984984
// 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}"}}
985985
// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"
986986

987+
// 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
988+
// 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}"}}
989+
// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-minimal-runtime"
990+
// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-handler-preserve-all-regs
991+
987992
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer -fsanitize-trap=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTSAN-TRAP
988993
// 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"
989994

0 commit comments

Comments
 (0)