diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Driver/SanitizerArgs.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/MultiplexConsumer.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 2 |
14 files changed, 123 insertions, 18 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 2e566de6d8a..d55b73a4136 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -26,6 +26,7 @@ #include "clang/Frontend/CodeGenOptions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Metadata.h" +#include "llvm/Transforms/Utils/SanitizerStats.h" using namespace clang; using namespace CodeGen; @@ -2551,6 +2552,22 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, return; SanitizerScope SanScope(this); + llvm::SanitizerStatKind SSK; + switch (TCK) { + case CFITCK_VCall: + SSK = llvm::SanStat_CFI_VCall; + break; + case CFITCK_NVCall: + SSK = llvm::SanStat_CFI_NVCall; + break; + case CFITCK_DerivedCast: + SSK = llvm::SanStat_CFI_DerivedCast; + break; + case CFITCK_UnrelatedCast: + SSK = llvm::SanStat_CFI_UnrelatedCast; + break; + } + EmitSanitizerStatReport(SSK); llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e918cd81f0b..7d1c77a14f9 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -32,6 +32,7 @@ #include "llvm/IR/MDBuilder.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Transforms/Utils/SanitizerStats.h" using namespace clang; using namespace CodeGen; @@ -3852,6 +3853,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, if (SanOpts.has(SanitizerKind::CFIICall) && (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) { SanitizerScope SanScope(this); + EmitSanitizerStatReport(llvm::SanStat_CFI_ICall); llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(FnType, 0)); llvm::Value *BitSetName = llvm::MetadataAsValue::get(getLLVMContext(), MD); diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 0a670ab19aa..cdd9d09d048 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -214,8 +214,8 @@ namespace clang { Gen->HandleVTable(RD); } - void HandleLinkerOptionPragma(llvm::StringRef Opts) override { - Gen->HandleLinkerOptionPragma(Opts); + void HandleLinkerOption(llvm::StringRef Opts) override { + Gen->HandleLinkerOption(Opts); } void HandleDetectMismatch(llvm::StringRef Name, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index e38ff0a39da..e41aa81bdef 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1956,3 +1956,12 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E, << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; } } + +void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) { + if (!CGM.getCodeGenOpts().SanitizeStats) + return; + + llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint()); + IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation()); + CGM.getSanStats().create(IRB, SSK); +} diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index b3d50352532..3dc0f35b0db 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -36,6 +36,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Utils/SanitizerStats.h" namespace llvm { class BasicBlock; @@ -3187,6 +3188,8 @@ public: Address EmitPointerWithAlignment(const Expr *Addr, AlignmentSource *Source = nullptr); + void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); + private: QualType getVarArgType(const Expr *Arg); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 41a4a1212ea..5a85de7e234 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -392,6 +392,8 @@ void CodeGenModule::Release() { if (CoverageMapping) CoverageMapping->emit(); emitLLVMUsed(); + if (SanStats) + SanStats->finish(); if (CodeGenOpts.Autolink && (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { @@ -4066,3 +4068,10 @@ void CodeGenModule::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap, Target.getTargetOpts().Features); } } + +llvm::SanitizerStatReport &CodeGenModule::getSanStats() { + if (!SanStats) + SanStats = llvm::make_unique<llvm::SanitizerStatReport>(&getModule()); + + return *SanStats; +} diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index c7b82580034..046bc2a9fe5 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -33,6 +33,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" +#include "llvm/Transforms/Utils/SanitizerStats.h" namespace llvm { class Module; @@ -289,6 +290,7 @@ private: llvm::MDNode *NoObjCARCExceptionsMetadata; std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader; InstrProfStats PGOStats; + std::unique_ptr<llvm::SanitizerStatReport> SanStats; // A set of references that have only been seen via a weakref so far. This is // used to remove the weak of the reference if we ever see a direct reference @@ -1129,6 +1131,8 @@ public: /// \breif Get the declaration of std::terminate for the platform. llvm::Constant *getTerminateFn(); + llvm::SanitizerStatReport &getSanStats(); + private: llvm::Constant * GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 0be5c5592b2..bce19ab2fdb 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -103,8 +103,10 @@ namespace { PreprocessorOpts, CodeGenOpts, *M, Diags, CoverageInfo)); - for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i) - HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]); + for (auto &&Lib : CodeGenOpts.DependentLibraries) + HandleDependentLibrary(Lib); + for (auto &&Opt : CodeGenOpts.LinkerOptions) + HandleLinkerOption(Opt); } void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { @@ -222,7 +224,7 @@ namespace { Builder->EmitVTable(RD); } - void HandleLinkerOptionPragma(llvm::StringRef Opts) override { + void HandleLinkerOption(llvm::StringRef Opts) override { Builder->AppendLinkerOptions(Opts); } diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 7e617a43e40..cf8d39d6efe 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -431,6 +431,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, NeedPIE |= CfiCrossDso; } + Stats = Args.hasFlag(options::OPT_fsanitize_stats, + options::OPT_fno_sanitize_stats, false); + // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the // enabled sanitizers. if (AllAddedKinds & SupportsCoverage) { @@ -548,6 +551,20 @@ static std::string toString(const clang::SanitizerSet &Sanitizers) { return Res; } +static void addIncludeLinkerOption(const ToolChain &TC, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + StringRef SymbolName) { + SmallString<64> LinkerOptionFlag; + LinkerOptionFlag = "--linker-option=/include:"; + if (TC.getTriple().getArch() == llvm::Triple::x86) { + // Win32 mangles C function names with a '_' prefix. + LinkerOptionFlag += '_'; + } + LinkerOptionFlag += SymbolName; + CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag)); +} + void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const { @@ -584,6 +601,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (CfiCrossDso) CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso")); + if (Stats) + CmdArgs.push_back(Args.MakeArgString("-fsanitize-stats")); + if (AsanFieldPadding) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + llvm::utostr(AsanFieldPadding))); @@ -619,6 +639,18 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx"))); } + if (TC.getTriple().isOSWindows() && needsStatsRt()) { + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + + TC.getCompilerRT(Args, "stats_client"))); + + // The main executable must export the stats runtime. + // FIXME: Only exporting from the main executable (e.g. based on whether the + // translation unit defines main()) would save a little space, but having + // multiple copies of the runtime shouldn't hurt. + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + + TC.getCompilerRT(Args, "stats"))); + addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register"); + } } SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 15b36778220..f57d0871c20 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -413,6 +413,13 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); if (Sanitize.needsTsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); + if (Sanitize.needsStatsRt()) { + StringRef OS = isTargetMacOS() ? "osx" : "iossim"; + AddLinkRuntimeLib(Args, CmdArgs, + (Twine("libclang_rt.stats_client_") + OS + ".a").str(), + /*AlwaysLink=*/true); + AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); + } // Otherwise link libSystem, then the dynamic runtime library, and finally any // target specific static runtime library. diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index e498f98355c..90c25726df2 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2773,12 +2773,12 @@ static void addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer, - bool IsShared) { - // Static runtimes must be forced into executable, so we wrap them in + bool IsShared, bool IsWhole) { + // Wrap any static runtimes that must be forced into executable in // whole-archive. - if (!IsShared) CmdArgs.push_back("-whole-archive"); + if (IsWhole) CmdArgs.push_back("-whole-archive"); CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared)); - if (!IsShared) CmdArgs.push_back("-no-whole-archive"); + if (IsWhole) CmdArgs.push_back("-no-whole-archive"); } // Tries to use a file with the list of dynamic symbols that need to be exported @@ -2811,12 +2811,17 @@ static void collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, SmallVectorImpl<StringRef> &SharedRuntimes, SmallVectorImpl<StringRef> &StaticRuntimes, - SmallVectorImpl<StringRef> &HelperStaticRuntimes) { + SmallVectorImpl<StringRef> &NonWholeStaticRuntimes, + SmallVectorImpl<StringRef> &HelperStaticRuntimes, + SmallVectorImpl<StringRef> &RequiredSymbols) { const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); // Collect shared runtimes. 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"); // Collect static runtimes. if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) { @@ -2857,6 +2862,10 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("cfi"); if (SanArgs.needsCfiDiagRt()) StaticRuntimes.push_back("cfi_diag"); + if (SanArgs.needsStatsRt()) { + NonWholeStaticRuntimes.push_back("stats"); + RequiredSymbols.push_back("__sanitizer_stats_register"); + } } // Should be called before we add system libraries (C++ ABI, libstdc++/libc++, @@ -2864,18 +2873,27 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes, - HelperStaticRuntimes; + NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols; collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes, - HelperStaticRuntimes); + NonWholeStaticRuntimes, HelperStaticRuntimes, + RequiredSymbols); for (auto RT : SharedRuntimes) - addSanitizerRuntime(TC, Args, CmdArgs, RT, true); + addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false); for (auto RT : HelperStaticRuntimes) - addSanitizerRuntime(TC, Args, CmdArgs, RT, false); + addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true); bool AddExportDynamic = false; for (auto RT : StaticRuntimes) { - addSanitizerRuntime(TC, Args, CmdArgs, RT, false); + addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true); + AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT); + } + for (auto RT : NonWholeStaticRuntimes) { + addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false); AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT); } + for (auto S : RequiredSymbols) { + CmdArgs.push_back("-u"); + CmdArgs.push_back(Args.MakeArgString(S)); + } // If there is a static runtime with no dynamic list, force all the symbols // to be dynamic to be sure we export sanitizer interface functions. if (AddExportDynamic) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 237a4470409..d0b8b27b052 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -623,6 +623,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeMemoryUseAfterDtor = Args.hasArg(OPT_fsanitize_memory_use_after_dtor); Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso); + Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats); Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); @@ -697,6 +698,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option); bool NeedLocTracking = false; if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) { diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index f8b73e9034b..fdeb04f6248 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -317,9 +317,9 @@ void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { Consumer->HandleImplicitImportDecl(D); } -void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) { +void MultiplexConsumer::HandleLinkerOption(llvm::StringRef Opts) { for (auto &Consumer : Consumers) - Consumer->HandleLinkerOptionPragma(Opts); + Consumer->HandleLinkerOption(Opts); } void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 5a29bad29f4..f3145713d58 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -275,7 +275,7 @@ void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) { case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind"); case PCK_Linker: - Consumer.HandleLinkerOptionPragma(Arg); + Consumer.HandleLinkerOption(Arg); return; case PCK_Lib: Consumer.HandleDependentLibrary(Arg); |