diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 49 | ||||
-rw-r--r-- | clang/lib/Driver/SanitizerArgs.cpp | 39 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/CommonArgs.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 1 |
4 files changed, 75 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5f8f34e9bcc..bff3fcf6db2 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -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; @@ -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 = diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 6afa4872958..a2a1373c8d8 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -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 | @@ -41,6 +42,7 @@ enum : SanitizerMask { Nullability | LocalBounds | CFI, TrappingDefault = CFI, CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast, + CompatibleWithMinimalRuntime = TrappingSupported, }; enum CoverageFeature { @@ -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 = @@ -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) @@ -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) @@ -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) { @@ -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))); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 690f3b3a96b..d052bb2001c 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -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"); @@ -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"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index abf6b0b302f..2cc93c1f13d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -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, |