diff options
Diffstat (limited to 'lib/Driver/ToolChains/Fuchsia.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Fuchsia.cpp | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp index de2c7411c5..c906379f19 100644 --- a/lib/Driver/ToolChains/Fuchsia.cpp +++ b/lib/Driver/ToolChains/Fuchsia.cpp @@ -1,9 +1,8 @@ //===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -16,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; @@ -24,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, @@ -99,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()) { @@ -149,7 +150,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("--wrap=pthread_create"); - CmdArgs.push_back("-lc"); + if (!Args.hasArg(options::OPT_nolibc)) + CmdArgs.push_back("-lc"); } C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); @@ -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, @@ -283,6 +331,8 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args, SanitizerMask Fuchsia::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::SafeStack; |