summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp17
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp8
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp32
-rw-r--r--clang/lib/Driver/ToolChains.cpp7
-rw-r--r--clang/lib/Driver/Tools.cpp38
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/lib/Frontend/MultiplexConsumer.cpp4
-rw-r--r--clang/lib/Sema/SemaAttr.cpp2
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);
OpenPOWER on IntegriCloud