brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 1bbabdf Raw
216 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Managarm.h"10#include "Arch/RISCV.h"11#include "clang/Config/config.h"12#include "clang/Driver/CommonArgs.h"13#include "clang/Driver/Driver.h"14#include "clang/Driver/SanitizerArgs.h"15#include "clang/Options/Options.h"16#include "llvm/Option/ArgList.h"17#include "llvm/Support/Path.h"18 19using namespace clang::driver;20using namespace clang::driver::toolchains;21using namespace clang;22using namespace llvm::opt;23 24using tools::addPathIfExists;25 26std::string Managarm::getMultiarchTriple(const Driver &D,27                                         const llvm::Triple &TargetTriple,28                                         StringRef SysRoot) const {29  switch (TargetTriple.getArch()) {30  default:31    return TargetTriple.str();32  case llvm::Triple::x86_64:33    return "x86_64-managarm-" + TargetTriple.getEnvironmentName().str();34  case llvm::Triple::aarch64:35    return "aarch64-managarm-" + TargetTriple.getEnvironmentName().str();36  case llvm::Triple::riscv64:37    return "riscv64-managarm-" + TargetTriple.getEnvironmentName().str();38  }39}40 41static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {42  // It happens that only x86, PPC and SPARC use the 'lib32' variant of43  // oslibdir, and using that variant while targeting other architectures causes44  // problems because the libraries are laid out in shared system roots that45  // can't cope with a 'lib32' library search path being considered. So we only46  // enable them when we know we may need it.47  //48  // FIXME: This is a bit of a hack. We should really unify this code for49  // reasoning about oslibdir spellings with the lib dir spellings in the50  // GCCInstallationDetector, but that is a more significant refactoring.51  if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||52      Triple.getArch() == llvm::Triple::sparc)53    return "lib32";54 55  if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())56    return "libx32";57 58  if (Triple.getArch() == llvm::Triple::riscv32)59    return "lib32";60 61  return Triple.isArch32Bit() ? "lib" : "lib64";62}63 64Managarm::Managarm(const Driver &D, const llvm::Triple &Triple,65                   const ArgList &Args)66    : Generic_ELF(D, Triple, Args) {67  GCCInstallation.init(Triple, Args);68  Multilibs = GCCInstallation.getMultilibs();69  SelectedMultilibs.assign({GCCInstallation.getMultilib()});70  std::string SysRoot = computeSysRoot();71 72  ToolChain::path_list &PPaths = getProgramPaths();73 74  Generic_GCC::PushPPaths(PPaths);75 76#ifdef ENABLE_LINKER_BUILD_ID77  ExtraOpts.push_back("--build-id");78#endif79 80  // The selection of paths to try here is designed to match the patterns which81  // the GCC driver itself uses, as this is part of the GCC-compatible driver.82  // This was determined by running GCC in a fake filesystem, creating all83  // possible permutations of these directories, and seeing which ones it added84  // to the link paths.85  path_list &Paths = getFilePaths();86 87  const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));88  const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);89 90  Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);91 92  addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths);93  addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths);94  addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);95  addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);96 97  Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);98 99  addPathIfExists(D, concat(SysRoot, "/lib"), Paths);100  addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);101}102 103bool Managarm::HasNativeLLVMSupport() const { return true; }104 105Tool *Managarm::buildLinker() const {106  return new tools::gnutools::Linker(*this);107}108 109Tool *Managarm::buildAssembler() const {110  return new tools::gnutools::Assembler(*this);111}112 113std::string Managarm::computeSysRoot() const {114  if (!getDriver().SysRoot.empty())115    return getDriver().SysRoot;116  return std::string();117}118 119std::string Managarm::getDynamicLinker(const ArgList &Args) const {120  switch (getTriple().getArch()) {121  case llvm::Triple::aarch64:122    return "/lib/aarch64-managarm/ld.so";123  case llvm::Triple::riscv64: {124    StringRef ABIName = tools::riscv::getRISCVABI(Args, getTriple());125    return ("/lib/riscv64-managarm/ld-riscv64-" + ABIName + ".so").str();126  }127  case llvm::Triple::x86_64:128    return "/lib/x86_64-managarm/ld.so";129  default:130    llvm_unreachable("unsupported architecture");131  }132}133 134void Managarm::AddClangSystemIncludeArgs(const ArgList &DriverArgs,135                                         ArgStringList &CC1Args) const {136  const Driver &D = getDriver();137  std::string SysRoot = computeSysRoot();138 139  if (DriverArgs.hasArg(options::OPT_nostdinc))140    return;141 142  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))143    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");144 145  // Add 'include' in the resource directory, which is similar to146  // GCC_INCLUDE_DIR (private headers) in GCC.147  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {148    SmallString<128> ResourceDirInclude(D.ResourceDir);149    llvm::sys::path::append(ResourceDirInclude, "include");150    addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);151  }152 153  if (DriverArgs.hasArg(options::OPT_nostdlibinc))154    return;155 156  // TOOL_INCLUDE_DIR157  AddMultilibIncludeArgs(DriverArgs, CC1Args);158 159  // Check for configure-time C include directories.160  StringRef CIncludeDirs(C_INCLUDE_DIRS);161  if (CIncludeDirs != "") {162    SmallVector<StringRef, 5> dirs;163    CIncludeDirs.split(dirs, ":");164    for (StringRef dir : dirs) {165      StringRef Prefix =166          llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";167      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);168    }169    return;170  }171 172  // On systems using multiarch, add /usr/include/$triple before173  // /usr/include.174  std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot);175  if (!MultiarchIncludeDir.empty())176    addExternCSystemInclude(177        DriverArgs, CC1Args,178        concat(SysRoot, "/usr/include", MultiarchIncludeDir));179 180  // Add an include of '/include' directly. This isn't provided by default by181  // system GCCs, but is often used with cross-compiling GCCs, and harmless to182  // add even when Clang is acting as-if it were a system compiler.183  addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));184 185  addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));186}187 188void Managarm::addLibStdCxxIncludePaths(189    const llvm::opt::ArgList &DriverArgs,190    llvm::opt::ArgStringList &CC1Args) const {191  // We need a detected GCC installation on Managarm to provide libstdc++'s192  // headers.193  if (!GCCInstallation.isValid())194    return;195 196  // Try generic GCC detection.197  addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args);198}199 200SanitizerMask Managarm::getSupportedSanitizers() const {201  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;202  SanitizerMask Res = ToolChain::getSupportedSanitizers();203  Res |= SanitizerKind::PointerCompare;204  Res |= SanitizerKind::PointerSubtract;205  Res |= SanitizerKind::KernelAddress;206  Res |= SanitizerKind::Vptr;207  if (IsX86_64)208    Res |= SanitizerKind::KernelMemory;209  return Res;210}211 212void Managarm::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {213  for (const auto &Opt : ExtraOpts)214    CmdArgs.push_back(Opt.c_str());215}216