]> granicus.if.org Git - clang/commitdiff
[Fuchsia] Support multilib for -fsanitize=address and -fno-exceptions
authorPetr Hosek <phosek@chromium.org>
Sat, 27 Apr 2019 00:25:13 +0000 (00:25 +0000)
committerPetr Hosek <phosek@chromium.org>
Sat, 27 Apr 2019 00:25:13 +0000 (00:25 +0000)
This introduces a support for multilibs to Fuchsia driver. Unlike the
existing multilibs that are used primarily for handling different
architecture variants, we use multilibs to handle different variants
of Clang runtime libraries: -fsanitize=address and -fno-exceptions
are the two we support initially. This replaces the existing support
for sanitized runtimes libraries that was only used by Fuchsia driver
and it also refactors some of the logic to allow sharing between GNU
and Fuchsia drivers.

Differential Revision: https://reviews.llvm.org/D61040

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359360 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/ToolChains/CommonArgs.cpp
lib/Driver/ToolChains/CommonArgs.h
lib/Driver/ToolChains/Fuchsia.cpp
lib/Driver/ToolChains/Gnu.cpp
test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep [new file with mode: 0644]
test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep [new file with mode: 0644]
test/Driver/fuchsia.cpp

index 16548c2aa412923c9d22877f2ae123e3f6d5e952..d0c9d7d396272e90c617e53505d81d2135746e1f 100644 (file)
@@ -570,40 +570,6 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
   return false;
 }
 
-static void addSanitizerLibPath(const ToolChain &TC, const ArgList &Args,
-                                ArgStringList &CmdArgs, StringRef Name) {
-  for (const auto &LibPath : TC.getLibraryPaths()) {
-    if (!LibPath.empty()) {
-      SmallString<128> P(LibPath);
-      llvm::sys::path::append(P, Name);
-      if (TC.getVFS().exists(P))
-        CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
-    }
-  }
-}
-
-void tools::addSanitizerPathLibArgs(const ToolChain &TC, const ArgList &Args,
-                                    ArgStringList &CmdArgs) {
-  const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
-  if (SanArgs.needsAsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "asan");
-  }
-  if (SanArgs.needsHwasanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "hwasan");
-  }
-  if (SanArgs.needsLsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "lsan");
-  }
-  if (SanArgs.needsMsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "msan");
-  }
-  if (SanArgs.needsTsanRt()) {
-    addSanitizerLibPath(TC, Args, CmdArgs, "tsan");
-  }
-}
-
-
-
 void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
                                      ArgStringList &CmdArgs) {
   // Force linking against the system libraries sanitizers depends on
@@ -1535,3 +1501,8 @@ SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
   llvm::sys::path::replace_extension(StatsFile, "stats");
   return StatsFile;
 }
+
+void tools::addMultilibFlag(bool Enabled, const char *const Flag,
+                            Multilib::flags_list &Flags) {
+  Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
+}
index 9c64a50d56549b0996c3cc72e7882c2b016d20fb..9a311708f3ae33df1ec9513f07e660f63bce9cde 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "InputInfo.h"
 #include "clang/Driver/Driver.h"
+#include "clang/Driver/Multilib.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/Support/CodeGen.h"
@@ -31,10 +32,6 @@ void claimNoWarnArgs(const llvm::opt::ArgList &Args);
 bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args,
                           llvm::opt::ArgStringList &CmdArgs);
 
-void addSanitizerPathLibArgs(const ToolChain &TC,
-                             const llvm::opt::ArgList &Args,
-                             llvm::opt::ArgStringList &CmdArgs);
-
 void linkSanitizerRuntimeDeps(const ToolChain &TC,
                               llvm::opt::ArgStringList &CmdArgs);
 
@@ -121,6 +118,12 @@ void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args,
 SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
                                   const InputInfo &Output,
                                   const InputInfo &Input, const Driver &D);
+
+/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
+//     otherwise '-print-multi-lib' will not emit them correctly.
+void addMultilibFlag(bool Enabled, const char *const Flag,
+                     Multilib::flags_list &Flags);
+
 } // end namespace tools
 } // end namespace driver
 } // end namespace clang
index 2db2d889d04e47f1cbe9ee15e342a56153c8d4ff..c906379f19b476f9cd4a7768b669e14e6cbb7457 100644 (file)
@@ -15,7 +15,9 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -23,6 +25,8 @@ using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
+using tools::addMultilibFlag;
+
 void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                    const InputInfo &Output,
                                    const InputInfoList &Inputs,
@@ -98,8 +102,6 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_u);
 
-  addSanitizerPathLibArgs(ToolChain, Args, CmdArgs);
-
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
   if (D.isUsingLTO()) {
@@ -169,6 +171,52 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
     llvm::sys::path::append(P, "lib");
     getFilePaths().push_back(P.str());
   }
+
+  auto RuntimeDirs = [&](const Multilib &M) -> std::vector<std::string> {
+    SmallString<128> P;
+    std::vector<std::string> RD;
+
+    P.assign(D.ResourceDir);
+    llvm::sys::path::append(P, D.getTargetTriple(), "lib", M.gccSuffix());
+    if (getVFS().exists(P))
+      RD.push_back(P.str());
+
+    P.assign(D.ResourceDir);
+    llvm::sys::path::append(P, Triple.str(), "lib", M.gccSuffix());
+    if (getVFS().exists(P))
+      RD.push_back(P.str());
+
+    return RD;
+  };
+
+  Multilibs.push_back(Multilib());
+  // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
+  Multilibs.push_back(Multilib("noexcept", {}, {}, 1)
+                          .flag("-fexceptions")
+                          .flag("+fno-exceptions"));
+  // ASan has higher priority because we always want the instrumentated version.
+  Multilibs.push_back(Multilib("asan", {}, {}, 2)
+                          .flag("+fsanitize=address"));
+  Multilibs.FilterOut([&](const Multilib &M) {
+    std::vector<std::string> RD = RuntimeDirs(M);
+    return std::all_of(RD.begin(), RD.end(), [&](std::string P) {
+      return !getVFS().exists(P);
+    });
+  });
+
+  Multilib::flags_list Flags;
+  addMultilibFlag(
+      Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
+      "fexceptions", Flags);
+  addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
+  Multilibs.setFilePathsCallback(RuntimeDirs);
+
+  if (Multilibs.select(Flags, SelectedMultilib))
+    if (!SelectedMultilib.isDefault())
+      if (const auto &PathsCallback = Multilibs.filePathsCallback())
+        for (const auto &Path : PathsCallback(SelectedMultilib))
+          // We need to prepend the multilib path to ensure it takes precedence.
+          getLibraryPaths().insert(getLibraryPaths().begin(), Path);
 }
 
 std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
index 8915e3f948ffffe4664170a97d95802bb14c3c83..41c9abec3f12e49016e4517535ef5510b9b6c232 100644 (file)
@@ -33,6 +33,8 @@ using namespace clang::driver::toolchains;
 using namespace clang;
 using namespace llvm::opt;
 
+using tools::addMultilibFlag;
+
 void tools::GnuTool::anchor() {}
 
 static bool forwardToGCC(const Option &O) {
@@ -871,16 +873,6 @@ static bool isSoftFloatABI(const ArgList &Args) {
           A->getValue() == StringRef("soft"));
 }
 
-/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
-//     otherwise '-print-multi-lib' will not emit them correctly.
-static void addMultilibFlag(bool Enabled, const char *const Flag,
-                            std::vector<std::string> &Flags) {
-  if (Enabled)
-    Flags.push_back(std::string("+") + Flag);
-  else
-    Flags.push_back(std::string("-") + Flag);
-}
-
 static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
   return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
 }
diff --git a/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep b/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep b/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep
new file mode 100644 (file)
index 0000000..e69de29
index d18d496359f66fa974b62e5ec344a2e7ff8a5a68..a6d9b8e343cc29ff52ae042e7b3ab1ac2dc546a9 100644 (file)
 // CHECK-NOSTDLIBXX-NOT: "-lc++"
 // CHECK-NOSTDLIBXX-NOT: "-lm"
 // CHECK-NOSTDLIBXX: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fno-exceptions \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-NOEXCEPT-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address -fno-exceptions \
+// RUN:     -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:     -fuse-ld=lld 2>&1\
+// RUN:     | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86
+// CHECK-MULTILIB-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-MULTILIB-ASAN-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}asan"
+// CHECK-MULTILIB-NOEXCEPT-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}noexcept"
+// CHECK-MULTILIB-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib"