brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · d4a6d6a Raw
251 lines · cpp
1//===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===//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 "DragonFly.h"10#include "clang/Driver/CommonArgs.h"11#include "clang/Driver/Compilation.h"12#include "clang/Driver/Driver.h"13#include "clang/Options/Options.h"14#include "llvm/Option/ArgList.h"15#include "llvm/Support/Path.h"16 17using namespace clang::driver;18using namespace clang::driver::tools;19using namespace clang::driver::toolchains;20using namespace clang;21using namespace llvm::opt;22 23void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,24                                        const InputInfo &Output,25                                        const InputInfoList &Inputs,26                                        const ArgList &Args,27                                        const char *LinkingOutput) const {28  const auto &ToolChain = static_cast<const DragonFly &>(getToolChain());29  ArgStringList CmdArgs;30 31  claimNoWarnArgs(Args);32 33  // When building 32-bit code on DragonFly/pc64, we have to explicitly34  // instruct as in the base system to assemble 32-bit code.35  if (ToolChain.getArch() == llvm::Triple::x86)36    CmdArgs.push_back("--32");37 38  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);39 40  CmdArgs.push_back("-o");41  CmdArgs.push_back(Output.getFilename());42 43  for (const auto &II : Inputs)44    CmdArgs.push_back(II.getFilename());45 46  const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("as"));47  C.addCommand(std::make_unique<Command>(JA, *this,48                                         ResponseFileSupport::AtFileCurCP(),49                                         Exec, CmdArgs, Inputs, Output));50}51 52void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,53                                     const InputInfo &Output,54                                     const InputInfoList &Inputs,55                                     const ArgList &Args,56                                     const char *LinkingOutput) const {57  const auto &ToolChain = static_cast<const DragonFly &>(getToolChain());58  const Driver &D = ToolChain.getDriver();59  const llvm::Triple::ArchType Arch = ToolChain.getArch();60  const bool Static = Args.hasArg(options::OPT_static);61  const bool Shared = Args.hasArg(options::OPT_shared);62  const bool Profiling = Args.hasArg(options::OPT_pg);63  const bool Pie = Args.hasArg(options::OPT_pie);64  ArgStringList CmdArgs;65 66  if (!D.SysRoot.empty())67    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));68 69  CmdArgs.push_back("--eh-frame-hdr");70  if (Static) {71    CmdArgs.push_back("-Bstatic");72  } else {73    if (Args.hasArg(options::OPT_rdynamic))74      CmdArgs.push_back("-export-dynamic");75    if (Shared)76      CmdArgs.push_back("-shared");77    else if (!Args.hasArg(options::OPT_r)) {78      CmdArgs.push_back("-dynamic-linker");79      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");80    }81    CmdArgs.push_back("--hash-style=gnu");82    CmdArgs.push_back("--enable-new-dtags");83  }84 85  // When building 32-bit code on DragonFly/pc64, we have to explicitly86  // instruct ld in the base system to link 32-bit code.87  if (Arch == llvm::Triple::x86) {88    CmdArgs.push_back("-m");89    CmdArgs.push_back("elf_i386");90  }91 92  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");93  if (Output.isFilename()) {94    CmdArgs.push_back("-o");95    CmdArgs.push_back(Output.getFilename());96  }97 98  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,99                   options::OPT_r)) {100    const char *crt1 = nullptr;101    const char *crtbegin = nullptr;102    if (!Shared) {103      if (Profiling)104        crt1 = "gcrt1.o";105      else {106        if (Pie)107          crt1 = "Scrt1.o";108        else109          crt1 = "crt1.o";110      }111    }112 113    if (Shared || Pie)114      crtbegin = "crtbeginS.o";115    else116      crtbegin = "crtbegin.o";117 118    if (crt1)119      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));120    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));121    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));122  }123 124  Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,125                            options::OPT_s, options::OPT_t});126  ToolChain.AddFilePathLibArgs(Args, CmdArgs);127 128  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);129 130  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,131                   options::OPT_r)) {132    if (!Static) {133      CmdArgs.push_back("-rpath");134      CmdArgs.push_back("/usr/lib/gcc80");135    }136 137    // Use the static OpenMP runtime with -static-openmp138    bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;139    addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);140 141    if (D.CCCIsCXX()) {142      if (ToolChain.ShouldLinkCXXStdlib(Args))143        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);144      CmdArgs.push_back("-lm");145    }146 147    // Silence warnings when linking C code with a C++ '-stdlib' argument.148    Args.ClaimAllArgs(options::OPT_stdlib_EQ);149 150    // Additional linker set-up and flags for Fortran. This is required in order151    // to generate executables. As Fortran runtime depends on the C runtime,152    // these dependencies need to be listed before the C runtime below (i.e.153    // AddRunTimeLibs).154    if (D.IsFlangMode() &&155        !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {156      ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);157      ToolChain.addFortranRuntimeLibs(Args, CmdArgs);158      CmdArgs.push_back("-lm");159    }160 161    if (Args.hasArg(options::OPT_pthread))162      CmdArgs.push_back("-lpthread");163 164    if (!Args.hasArg(options::OPT_nolibc))165      CmdArgs.push_back("-lc");166 167    if (Static || Args.hasArg(options::OPT_static_libgcc)) {168        CmdArgs.push_back("-lgcc");169        CmdArgs.push_back("-lgcc_eh");170    } else {171      if (Args.hasArg(options::OPT_shared_libgcc)) {172          CmdArgs.push_back("-lgcc_pic");173          if (!Shared)174            CmdArgs.push_back("-lgcc");175      } else {176          CmdArgs.push_back("-lgcc");177          CmdArgs.push_back("--as-needed");178          CmdArgs.push_back("-lgcc_pic");179          CmdArgs.push_back("--no-as-needed");180      }181    }182  }183 184  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,185                   options::OPT_r)) {186    const char *crtend = nullptr;187    if (Shared || Pie)188      crtend ="crtendS.o";189    else190      crtend = "crtend.o";191 192    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));193    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));194  }195 196  ToolChain.addProfileRTLibs(Args, CmdArgs);197 198  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());199  C.addCommand(std::make_unique<Command>(JA, *this,200                                         ResponseFileSupport::AtFileCurCP(),201                                         Exec, CmdArgs, Inputs, Output));202}203 204/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.205 206DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,207                     const ArgList &Args)208    : Generic_ELF(D, Triple, Args) {209  // Path mangling to find libexec210  getProgramPaths().push_back(getDriver().Dir);211 212  getFilePaths().push_back(getDriver().Dir + "/../lib");213  getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib"));214  getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/gcc80"));215}216 217void DragonFly::AddClangSystemIncludeArgs(218    const llvm::opt::ArgList &DriverArgs,219    llvm::opt::ArgStringList &CC1Args) const {220  const Driver &D = getDriver();221 222  if (DriverArgs.hasArg(options::OPT_nostdinc))223    return;224 225  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {226    SmallString<128> Dir(D.ResourceDir);227    llvm::sys::path::append(Dir, "include");228    addSystemInclude(DriverArgs, CC1Args, Dir.str());229  }230 231  if (DriverArgs.hasArg(options::OPT_nostdlibinc))232    return;233 234  addExternCSystemInclude(DriverArgs, CC1Args,235                          concat(D.SysRoot, "/usr/include"));236}237 238void DragonFly::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,239                                         llvm::opt::ArgStringList &CC1Args) const {240  addLibStdCXXIncludePaths(concat(getDriver().SysRoot, "/usr/include/c++/8.0"), "", "",241                           DriverArgs, CC1Args);242}243 244Tool *DragonFly::buildAssembler() const {245  return new tools::dragonfly::Assembler(*this);246}247 248Tool *DragonFly::buildLinker() const {249  return new tools::dragonfly::Linker(*this);250}251