summaryrefslogtreecommitdiffstats
path: root/lib/Driver/XRayArgs.cpp
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-03-30 00:29:36 +0000
committerDean Michael Berris <dberris@google.com>2017-03-30 00:29:36 +0000
commitca9fad67afe0d4c4757747486a116b3fca09e565 (patch)
treed1585384d6ac980a0e4946f28d27568ed7908bfb /lib/Driver/XRayArgs.cpp
parent6cecba61e47d6be93136d0caaeba3d7e54962e8f (diff)
[XRay] Add -fxray-{always,never}-instrument= flags to clang
Summary: The -fxray-always-instrument= and -fxray-never-instrument= flags take filenames that are used to imbue the XRay instrumentation attributes using a whitelist mechanism (similar to the sanitizer special cases list). We use the same syntax and semantics as the sanitizer blacklists files in the implementation. As implemented, we respect the attributes that are already defined in the source file (i.e. those that have the [[clang::xray_{always,never}_instrument]] attributes) before applying the always/never instrument lists. Reviewers: rsmith, chandlerc Subscribers: jfb, mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D30388 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299041 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/XRayArgs.cpp')
-rw-r--r--lib/Driver/XRayArgs.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/lib/Driver/XRayArgs.cpp b/lib/Driver/XRayArgs.cpp
new file mode 100644
index 0000000000..59a35f1115
--- /dev/null
+++ b/lib/Driver/XRayArgs.cpp
@@ -0,0 +1,113 @@
+//===--- XRayArgs.cpp - Arguments for XRay --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Driver/XRayArgs.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SpecialCaseList.h"
+
+using namespace clang;
+using namespace clang::driver;
+using namespace llvm::opt;
+
+namespace {
+constexpr char XRayInstrumentOption[] = "-fxray-instrument";
+constexpr char XRayInstructionThresholdOption[] =
+ "-fxray-instruction-threshold=";
+constexpr char XRayAlwaysInstrumentOption[] = "-fxray-always-instrument=";
+constexpr char XRayNeverInstrumentOption[] = "-fxray-never-instrument=";
+} // namespace
+
+XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
+ const Driver &D = TC.getDriver();
+ const llvm::Triple &Triple = TC.getTriple();
+ if (Args.hasFlag(options::OPT_fxray_instrument,
+ options::OPT_fnoxray_instrument, false)) {
+ if (Triple.getOS() == llvm::Triple::Linux)
+ switch (Triple.getArch()) {
+ case llvm::Triple::x86_64:
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ break;
+ default:
+ D.Diag(diag::err_drv_clang_unsupported)
+ << (std::string(XRayInstrumentOption) + " on " + Triple.str());
+ }
+ else
+ D.Diag(diag::err_drv_clang_unsupported)
+ << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
+ XRayInstrument = true;
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_fxray_instruction_threshold_,
+ options::OPT_fxray_instruction_threshold_EQ)) {
+ StringRef S = A->getValue();
+ if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
+ D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+ }
+
+ // Validate the always/never attribute files. We also make sure that they
+ // are treated as actual dependencies.
+ for (const auto &Filename :
+ Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
+ if (llvm::sys::fs::exists(Filename)) {
+ AlwaysInstrumentFiles.push_back(Filename);
+ ExtraDeps.push_back(Filename);
+ } else
+ D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+ }
+
+ for (const auto &Filename :
+ Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
+ if (llvm::sys::fs::exists(Filename)) {
+ NeverInstrumentFiles.push_back(Filename);
+ ExtraDeps.push_back(Filename);
+ } else
+ D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+ }
+ }
+}
+
+void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs, types::ID InputType) const {
+ if (!XRayInstrument)
+ return;
+
+ CmdArgs.push_back(XRayInstrumentOption);
+ CmdArgs.push_back(Args.MakeArgString(XRayInstructionThresholdOption +
+ std::to_string(InstructionThreshold)));
+
+ for (const auto &Always : AlwaysInstrumentFiles) {
+ SmallString<64> AlwaysInstrumentOpt(XRayAlwaysInstrumentOption);
+ AlwaysInstrumentOpt += Always;
+ CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
+ }
+
+ for (const auto &Never : NeverInstrumentFiles) {
+ SmallString<64> NeverInstrumentOpt(XRayNeverInstrumentOption);
+ NeverInstrumentOpt += Never;
+ CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
+ }
+
+ for (const auto &Dep : ExtraDeps) {
+ SmallString<64> ExtraDepOpt("-fdepfile-entry=");
+ ExtraDepOpt += Dep;
+ CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
+ }
+}