Object of class `Command` contains various properties of a command to execute, but output file was missed from them. This change adds this property. It is required for reporting consumed time and memory implemented in D78903 and may be used in other cases too. Differential Revision: https://reviews.llvm.org/D78902
516 lines
17 KiB
C++
516 lines
17 KiB
C++
//===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "NetBSD.h"
|
|
#include "Arch/ARM.h"
|
|
#include "Arch/Mips.h"
|
|
#include "Arch/Sparc.h"
|
|
#include "CommonArgs.h"
|
|
#include "clang/Driver/Compilation.h"
|
|
#include "clang/Driver/Driver.h"
|
|
#include "clang/Driver/Options.h"
|
|
#include "clang/Driver/SanitizerArgs.h"
|
|
#include "llvm/Option/ArgList.h"
|
|
#include "llvm/Support/VirtualFileSystem.h"
|
|
|
|
using namespace clang::driver;
|
|
using namespace clang::driver::tools;
|
|
using namespace clang::driver::toolchains;
|
|
using namespace clang;
|
|
using namespace llvm::opt;
|
|
|
|
void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
|
const InputInfo &Output,
|
|
const InputInfoList &Inputs,
|
|
const ArgList &Args,
|
|
const char *LinkingOutput) const {
|
|
claimNoWarnArgs(Args);
|
|
ArgStringList CmdArgs;
|
|
|
|
// GNU as needs different flags for creating the correct output format
|
|
// on architectures with different ABIs or optional feature sets.
|
|
switch (getToolChain().getArch()) {
|
|
case llvm::Triple::x86:
|
|
CmdArgs.push_back("--32");
|
|
break;
|
|
case llvm::Triple::arm:
|
|
case llvm::Triple::armeb:
|
|
case llvm::Triple::thumb:
|
|
case llvm::Triple::thumbeb: {
|
|
StringRef MArch, MCPU;
|
|
arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
|
|
std::string Arch =
|
|
arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
|
|
CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
|
|
break;
|
|
}
|
|
|
|
case llvm::Triple::mips:
|
|
case llvm::Triple::mipsel:
|
|
case llvm::Triple::mips64:
|
|
case llvm::Triple::mips64el: {
|
|
StringRef CPUName;
|
|
StringRef ABIName;
|
|
mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
|
|
|
|
CmdArgs.push_back("-march");
|
|
CmdArgs.push_back(CPUName.data());
|
|
|
|
CmdArgs.push_back("-mabi");
|
|
CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
|
|
|
|
if (getToolChain().getTriple().isLittleEndian())
|
|
CmdArgs.push_back("-EL");
|
|
else
|
|
CmdArgs.push_back("-EB");
|
|
|
|
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
|
|
break;
|
|
}
|
|
|
|
case llvm::Triple::sparc:
|
|
case llvm::Triple::sparcel: {
|
|
CmdArgs.push_back("-32");
|
|
std::string CPU = getCPUName(Args, getToolChain().getTriple());
|
|
CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
|
|
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
|
|
break;
|
|
}
|
|
|
|
case llvm::Triple::sparcv9: {
|
|
CmdArgs.push_back("-64");
|
|
std::string CPU = getCPUName(Args, getToolChain().getTriple());
|
|
CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
|
|
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
|
|
|
|
CmdArgs.push_back("-o");
|
|
CmdArgs.push_back(Output.getFilename());
|
|
|
|
for (const auto &II : Inputs)
|
|
CmdArgs.push_back(II.getFilename());
|
|
|
|
const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
|
|
C.addCommand(std::make_unique<Command>(JA, *this,
|
|
ResponseFileSupport::AtFileCurCP(),
|
|
Exec, CmdArgs, Inputs, Output));
|
|
}
|
|
|
|
void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|
const InputInfo &Output,
|
|
const InputInfoList &Inputs,
|
|
const ArgList &Args,
|
|
const char *LinkingOutput) const {
|
|
const toolchains::NetBSD &ToolChain =
|
|
static_cast<const toolchains::NetBSD &>(getToolChain());
|
|
const Driver &D = ToolChain.getDriver();
|
|
ArgStringList CmdArgs;
|
|
|
|
if (!D.SysRoot.empty())
|
|
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
|
|
|
|
CmdArgs.push_back("--eh-frame-hdr");
|
|
if (Args.hasArg(options::OPT_static)) {
|
|
CmdArgs.push_back("-Bstatic");
|
|
if (Args.hasArg(options::OPT_pie)) {
|
|
Args.AddAllArgs(CmdArgs, options::OPT_pie);
|
|
CmdArgs.push_back("--no-dynamic-linker");
|
|
}
|
|
} else {
|
|
if (Args.hasArg(options::OPT_rdynamic))
|
|
CmdArgs.push_back("-export-dynamic");
|
|
if (Args.hasArg(options::OPT_shared)) {
|
|
CmdArgs.push_back("-Bshareable");
|
|
} else {
|
|
Args.AddAllArgs(CmdArgs, options::OPT_pie);
|
|
CmdArgs.push_back("-dynamic-linker");
|
|
CmdArgs.push_back("/libexec/ld.elf_so");
|
|
}
|
|
}
|
|
|
|
// Many NetBSD architectures support more than one ABI.
|
|
// Determine the correct emulation for ld.
|
|
switch (ToolChain.getArch()) {
|
|
case llvm::Triple::x86:
|
|
CmdArgs.push_back("-m");
|
|
CmdArgs.push_back("elf_i386");
|
|
break;
|
|
case llvm::Triple::arm:
|
|
case llvm::Triple::thumb:
|
|
CmdArgs.push_back("-m");
|
|
switch (ToolChain.getTriple().getEnvironment()) {
|
|
case llvm::Triple::EABI:
|
|
case llvm::Triple::GNUEABI:
|
|
CmdArgs.push_back("armelf_nbsd_eabi");
|
|
break;
|
|
case llvm::Triple::EABIHF:
|
|
case llvm::Triple::GNUEABIHF:
|
|
CmdArgs.push_back("armelf_nbsd_eabihf");
|
|
break;
|
|
default:
|
|
CmdArgs.push_back("armelf_nbsd");
|
|
break;
|
|
}
|
|
break;
|
|
case llvm::Triple::armeb:
|
|
case llvm::Triple::thumbeb:
|
|
arm::appendBE8LinkFlag(Args, CmdArgs, ToolChain.getEffectiveTriple());
|
|
CmdArgs.push_back("-m");
|
|
switch (ToolChain.getTriple().getEnvironment()) {
|
|
case llvm::Triple::EABI:
|
|
case llvm::Triple::GNUEABI:
|
|
CmdArgs.push_back("armelfb_nbsd_eabi");
|
|
break;
|
|
case llvm::Triple::EABIHF:
|
|
case llvm::Triple::GNUEABIHF:
|
|
CmdArgs.push_back("armelfb_nbsd_eabihf");
|
|
break;
|
|
default:
|
|
CmdArgs.push_back("armelfb_nbsd");
|
|
break;
|
|
}
|
|
break;
|
|
case llvm::Triple::mips64:
|
|
case llvm::Triple::mips64el:
|
|
if (mips::hasMipsAbiArg(Args, "32")) {
|
|
CmdArgs.push_back("-m");
|
|
if (ToolChain.getArch() == llvm::Triple::mips64)
|
|
CmdArgs.push_back("elf32btsmip");
|
|
else
|
|
CmdArgs.push_back("elf32ltsmip");
|
|
} else if (mips::hasMipsAbiArg(Args, "64")) {
|
|
CmdArgs.push_back("-m");
|
|
if (ToolChain.getArch() == llvm::Triple::mips64)
|
|
CmdArgs.push_back("elf64btsmip");
|
|
else
|
|
CmdArgs.push_back("elf64ltsmip");
|
|
}
|
|
break;
|
|
case llvm::Triple::ppc:
|
|
CmdArgs.push_back("-m");
|
|
CmdArgs.push_back("elf32ppc_nbsd");
|
|
break;
|
|
|
|
case llvm::Triple::ppc64:
|
|
case llvm::Triple::ppc64le:
|
|
CmdArgs.push_back("-m");
|
|
CmdArgs.push_back("elf64ppc");
|
|
break;
|
|
|
|
case llvm::Triple::sparc:
|
|
CmdArgs.push_back("-m");
|
|
CmdArgs.push_back("elf32_sparc");
|
|
break;
|
|
|
|
case llvm::Triple::sparcv9:
|
|
CmdArgs.push_back("-m");
|
|
CmdArgs.push_back("elf64_sparc");
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (Output.isFilename()) {
|
|
CmdArgs.push_back("-o");
|
|
CmdArgs.push_back(Output.getFilename());
|
|
} else {
|
|
assert(Output.isNothing() && "Invalid output.");
|
|
}
|
|
|
|
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
|
|
if (!Args.hasArg(options::OPT_shared)) {
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
|
|
}
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
|
|
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o")));
|
|
} else {
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
|
|
}
|
|
}
|
|
|
|
Args.AddAllArgs(CmdArgs, options::OPT_L);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_e);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_s);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_t);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
|
|
Args.AddAllArgs(CmdArgs, options::OPT_r);
|
|
|
|
bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
|
|
bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
|
|
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
|
|
|
|
const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs();
|
|
if (SanArgs.needsSharedRt()) {
|
|
CmdArgs.push_back("-rpath");
|
|
CmdArgs.push_back(Args.MakeArgString(
|
|
ToolChain.getCompilerRTPath().c_str()));
|
|
}
|
|
|
|
unsigned Major, Minor, Micro;
|
|
ToolChain.getTriple().getOSVersion(Major, Minor, Micro);
|
|
bool useLibgcc = true;
|
|
if (Major >= 7 || Major == 0) {
|
|
switch (ToolChain.getArch()) {
|
|
case llvm::Triple::aarch64:
|
|
case llvm::Triple::aarch64_be:
|
|
case llvm::Triple::arm:
|
|
case llvm::Triple::armeb:
|
|
case llvm::Triple::thumb:
|
|
case llvm::Triple::thumbeb:
|
|
case llvm::Triple::ppc:
|
|
case llvm::Triple::ppc64:
|
|
case llvm::Triple::ppc64le:
|
|
case llvm::Triple::sparc:
|
|
case llvm::Triple::sparcv9:
|
|
case llvm::Triple::x86:
|
|
case llvm::Triple::x86_64:
|
|
useLibgcc = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
|
|
// Use the static OpenMP runtime with -static-openmp
|
|
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
|
|
!Args.hasArg(options::OPT_static);
|
|
addOpenMPRuntime(CmdArgs, getToolChain(), Args, StaticOpenMP);
|
|
|
|
if (D.CCCIsCXX()) {
|
|
if (ToolChain.ShouldLinkCXXStdlib(Args))
|
|
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
|
|
CmdArgs.push_back("-lm");
|
|
}
|
|
if (NeedsSanitizerDeps)
|
|
linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
|
|
if (NeedsXRayDeps)
|
|
linkXRayRuntimeDeps(ToolChain, CmdArgs);
|
|
if (Args.hasArg(options::OPT_pthread))
|
|
CmdArgs.push_back("-lpthread");
|
|
CmdArgs.push_back("-lc");
|
|
|
|
if (useLibgcc) {
|
|
if (Args.hasArg(options::OPT_static)) {
|
|
// libgcc_eh depends on libc, so resolve as much as possible,
|
|
// pull in any new requirements from libc and then get the rest
|
|
// of libgcc.
|
|
CmdArgs.push_back("-lgcc_eh");
|
|
CmdArgs.push_back("-lc");
|
|
CmdArgs.push_back("-lgcc");
|
|
} else {
|
|
CmdArgs.push_back("-lgcc");
|
|
CmdArgs.push_back("--as-needed");
|
|
CmdArgs.push_back("-lgcc_s");
|
|
CmdArgs.push_back("--no-as-needed");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
|
|
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
|
|
else
|
|
CmdArgs.push_back(
|
|
Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
|
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
|
|
}
|
|
|
|
ToolChain.addProfileRTLibs(Args, CmdArgs);
|
|
|
|
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
|
|
C.addCommand(std::make_unique<Command>(JA, *this,
|
|
ResponseFileSupport::AtFileCurCP(),
|
|
Exec, CmdArgs, Inputs, Output));
|
|
}
|
|
|
|
/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
|
|
|
|
NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
|
: Generic_ELF(D, Triple, Args) {
|
|
if (!Args.hasArg(options::OPT_nostdlib)) {
|
|
// When targeting a 32-bit platform, try the special directory used on
|
|
// 64-bit hosts, and only fall back to the main library directory if that
|
|
// doesn't work.
|
|
// FIXME: It'd be nicer to test if this directory exists, but I'm not sure
|
|
// what all logic is needed to emulate the '=' prefix here.
|
|
switch (Triple.getArch()) {
|
|
case llvm::Triple::x86:
|
|
getFilePaths().push_back("=/usr/lib/i386");
|
|
break;
|
|
case llvm::Triple::arm:
|
|
case llvm::Triple::armeb:
|
|
case llvm::Triple::thumb:
|
|
case llvm::Triple::thumbeb:
|
|
switch (Triple.getEnvironment()) {
|
|
case llvm::Triple::EABI:
|
|
case llvm::Triple::GNUEABI:
|
|
getFilePaths().push_back("=/usr/lib/eabi");
|
|
break;
|
|
case llvm::Triple::EABIHF:
|
|
case llvm::Triple::GNUEABIHF:
|
|
getFilePaths().push_back("=/usr/lib/eabihf");
|
|
break;
|
|
default:
|
|
getFilePaths().push_back("=/usr/lib/oabi");
|
|
break;
|
|
}
|
|
break;
|
|
case llvm::Triple::mips64:
|
|
case llvm::Triple::mips64el:
|
|
if (tools::mips::hasMipsAbiArg(Args, "o32"))
|
|
getFilePaths().push_back("=/usr/lib/o32");
|
|
else if (tools::mips::hasMipsAbiArg(Args, "64"))
|
|
getFilePaths().push_back("=/usr/lib/64");
|
|
break;
|
|
case llvm::Triple::ppc:
|
|
getFilePaths().push_back("=/usr/lib/powerpc");
|
|
break;
|
|
case llvm::Triple::sparc:
|
|
getFilePaths().push_back("=/usr/lib/sparc");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
getFilePaths().push_back("=/usr/lib");
|
|
}
|
|
}
|
|
|
|
Tool *NetBSD::buildAssembler() const {
|
|
return new tools::netbsd::Assembler(*this);
|
|
}
|
|
|
|
Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
|
|
|
|
ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
|
|
unsigned Major, Minor, Micro;
|
|
getTriple().getOSVersion(Major, Minor, Micro);
|
|
if (Major >= 7 || Major == 0) {
|
|
switch (getArch()) {
|
|
case llvm::Triple::aarch64:
|
|
case llvm::Triple::aarch64_be:
|
|
case llvm::Triple::arm:
|
|
case llvm::Triple::armeb:
|
|
case llvm::Triple::thumb:
|
|
case llvm::Triple::thumbeb:
|
|
case llvm::Triple::ppc:
|
|
case llvm::Triple::ppc64:
|
|
case llvm::Triple::ppc64le:
|
|
case llvm::Triple::sparc:
|
|
case llvm::Triple::sparcv9:
|
|
case llvm::Triple::x86:
|
|
case llvm::Triple::x86_64:
|
|
return ToolChain::CST_Libcxx;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return ToolChain::CST_Libstdcxx;
|
|
}
|
|
|
|
void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
llvm::opt::ArgStringList &CC1Args) const {
|
|
const std::string Candidates[] = {
|
|
// directory relative to build tree
|
|
getDriver().Dir + "/../include/c++/v1",
|
|
// system install with full upstream path
|
|
getDriver().SysRoot + "/usr/include/c++/v1",
|
|
// system install from src
|
|
getDriver().SysRoot + "/usr/include/c++",
|
|
};
|
|
|
|
for (const auto &IncludePath : Candidates) {
|
|
if (!getVFS().exists(IncludePath + "/__config"))
|
|
continue;
|
|
|
|
// Use the first candidate that looks valid.
|
|
addSystemInclude(DriverArgs, CC1Args, IncludePath);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
llvm::opt::ArgStringList &CC1Args) const {
|
|
addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
|
|
"", DriverArgs, CC1Args);
|
|
}
|
|
|
|
llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const {
|
|
// NetBSD uses Dwarf exceptions on ARM.
|
|
llvm::Triple::ArchType TArch = getTriple().getArch();
|
|
if (TArch == llvm::Triple::arm || TArch == llvm::Triple::armeb ||
|
|
TArch == llvm::Triple::thumb || TArch == llvm::Triple::thumbeb)
|
|
return llvm::ExceptionHandling::DwarfCFI;
|
|
return llvm::ExceptionHandling::None;
|
|
}
|
|
|
|
SanitizerMask NetBSD::getSupportedSanitizers() const {
|
|
const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
|
|
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
|
|
SanitizerMask Res = ToolChain::getSupportedSanitizers();
|
|
if (IsX86 || IsX86_64) {
|
|
Res |= SanitizerKind::Address;
|
|
Res |= SanitizerKind::PointerCompare;
|
|
Res |= SanitizerKind::PointerSubtract;
|
|
Res |= SanitizerKind::Function;
|
|
Res |= SanitizerKind::Leak;
|
|
Res |= SanitizerKind::SafeStack;
|
|
Res |= SanitizerKind::Scudo;
|
|
Res |= SanitizerKind::Vptr;
|
|
}
|
|
if (IsX86_64) {
|
|
Res |= SanitizerKind::DataFlow;
|
|
Res |= SanitizerKind::Fuzzer;
|
|
Res |= SanitizerKind::FuzzerNoLink;
|
|
Res |= SanitizerKind::HWAddress;
|
|
Res |= SanitizerKind::KernelAddress;
|
|
Res |= SanitizerKind::KernelHWAddress;
|
|
Res |= SanitizerKind::KernelMemory;
|
|
Res |= SanitizerKind::Memory;
|
|
Res |= SanitizerKind::Thread;
|
|
}
|
|
return Res;
|
|
}
|
|
|
|
void NetBSD::addClangTargetOptions(const ArgList &DriverArgs,
|
|
ArgStringList &CC1Args,
|
|
Action::OffloadKind) const {
|
|
const SanitizerArgs &SanArgs = getSanitizerArgs();
|
|
if (SanArgs.hasAnySanitizer())
|
|
CC1Args.push_back("-D_REENTRANT");
|
|
|
|
unsigned Major, Minor, Micro;
|
|
getTriple().getOSVersion(Major, Minor, Micro);
|
|
bool UseInitArrayDefault =
|
|
Major >= 9 || Major == 0 ||
|
|
getTriple().getArch() == llvm::Triple::aarch64 ||
|
|
getTriple().getArch() == llvm::Triple::aarch64_be ||
|
|
getTriple().getArch() == llvm::Triple::arm ||
|
|
getTriple().getArch() == llvm::Triple::armeb;
|
|
|
|
if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
|
|
options::OPT_fno_use_init_array, UseInitArrayDefault))
|
|
CC1Args.push_back("-fno-use-init-array");
|
|
}
|