10b57cec5SDimitry Andric //===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "NetBSD.h" 100b57cec5SDimitry Andric #include "Arch/ARM.h" 110b57cec5SDimitry Andric #include "Arch/Mips.h" 120b57cec5SDimitry Andric #include "Arch/Sparc.h" 130b57cec5SDimitry Andric #include "CommonArgs.h" 14bdd1243dSDimitry Andric #include "clang/Config/config.h" 150b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 160b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 170b57cec5SDimitry Andric #include "clang/Driver/Options.h" 180b57cec5SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 190b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 200b57cec5SDimitry Andric #include "llvm/Support/VirtualFileSystem.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang::driver; 230b57cec5SDimitry Andric using namespace clang::driver::tools; 240b57cec5SDimitry Andric using namespace clang::driver::toolchains; 250b57cec5SDimitry Andric using namespace clang; 260b57cec5SDimitry Andric using namespace llvm::opt; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 290b57cec5SDimitry Andric const InputInfo &Output, 300b57cec5SDimitry Andric const InputInfoList &Inputs, 310b57cec5SDimitry Andric const ArgList &Args, 320b57cec5SDimitry Andric const char *LinkingOutput) const { 335f757f3fSDimitry Andric const auto &ToolChain = static_cast<const NetBSD &>(getToolChain()); 34349cc55cSDimitry Andric const Driver &D = ToolChain.getDriver(); 35349cc55cSDimitry Andric const llvm::Triple &Triple = ToolChain.getTriple(); 365f757f3fSDimitry Andric ArgStringList CmdArgs; 37349cc55cSDimitry Andric 380b57cec5SDimitry Andric claimNoWarnArgs(Args); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // GNU as needs different flags for creating the correct output format 410b57cec5SDimitry Andric // on architectures with different ABIs or optional feature sets. 42349cc55cSDimitry Andric switch (ToolChain.getArch()) { 430b57cec5SDimitry Andric case llvm::Triple::x86: 440b57cec5SDimitry Andric CmdArgs.push_back("--32"); 450b57cec5SDimitry Andric break; 460b57cec5SDimitry Andric case llvm::Triple::arm: 470b57cec5SDimitry Andric case llvm::Triple::armeb: 480b57cec5SDimitry Andric case llvm::Triple::thumb: 490b57cec5SDimitry Andric case llvm::Triple::thumbeb: { 500b57cec5SDimitry Andric StringRef MArch, MCPU; 510b57cec5SDimitry Andric arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true); 52349cc55cSDimitry Andric std::string Arch = arm::getARMTargetCPU(MCPU, MArch, Triple); 530b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch)); 540b57cec5SDimitry Andric break; 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric case llvm::Triple::mips: 580b57cec5SDimitry Andric case llvm::Triple::mipsel: 590b57cec5SDimitry Andric case llvm::Triple::mips64: 600b57cec5SDimitry Andric case llvm::Triple::mips64el: { 610b57cec5SDimitry Andric StringRef CPUName; 620b57cec5SDimitry Andric StringRef ABIName; 63349cc55cSDimitry Andric mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric CmdArgs.push_back("-march"); 660b57cec5SDimitry Andric CmdArgs.push_back(CPUName.data()); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric CmdArgs.push_back("-mabi"); 690b57cec5SDimitry Andric CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data()); 700b57cec5SDimitry Andric 71349cc55cSDimitry Andric if (Triple.isLittleEndian()) 720b57cec5SDimitry Andric CmdArgs.push_back("-EL"); 730b57cec5SDimitry Andric else 740b57cec5SDimitry Andric CmdArgs.push_back("-EB"); 750b57cec5SDimitry Andric 76349cc55cSDimitry Andric AddAssemblerKPIC(ToolChain, Args, CmdArgs); 770b57cec5SDimitry Andric break; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 805f757f3fSDimitry Andric case llvm::Triple::sparc: { 810b57cec5SDimitry Andric CmdArgs.push_back("-32"); 82349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, Triple); 83349cc55cSDimitry Andric CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, Triple)); 84349cc55cSDimitry Andric AddAssemblerKPIC(ToolChain, Args, CmdArgs); 850b57cec5SDimitry Andric break; 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric case llvm::Triple::sparcv9: { 890b57cec5SDimitry Andric CmdArgs.push_back("-64"); 90349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, Triple); 91349cc55cSDimitry Andric CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, Triple)); 92349cc55cSDimitry Andric AddAssemblerKPIC(ToolChain, Args, CmdArgs); 930b57cec5SDimitry Andric break; 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric default: 970b57cec5SDimitry Andric break; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1030b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric for (const auto &II : Inputs) 1060b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename()); 1070b57cec5SDimitry Andric 108349cc55cSDimitry Andric const char *Exec = Args.MakeArgString((ToolChain.GetProgramPath("as"))); 109e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 110e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 111e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, 1150b57cec5SDimitry Andric const InputInfo &Output, 1160b57cec5SDimitry Andric const InputInfoList &Inputs, 1170b57cec5SDimitry Andric const ArgList &Args, 1180b57cec5SDimitry Andric const char *LinkingOutput) const { 1195f757f3fSDimitry Andric const auto &ToolChain = static_cast<const NetBSD &>(getToolChain()); 1200b57cec5SDimitry Andric const Driver &D = ToolChain.getDriver(); 121349cc55cSDimitry Andric const llvm::Triple &Triple = ToolChain.getTriple(); 1225f757f3fSDimitry Andric const llvm::Triple::ArchType Arch = ToolChain.getArch(); 1235f757f3fSDimitry Andric const bool Static = Args.hasArg(options::OPT_static); 1245f757f3fSDimitry Andric const bool Shared = Args.hasArg(options::OPT_shared); 1255f757f3fSDimitry Andric const bool Pie = Args.hasArg(options::OPT_pie); 1260b57cec5SDimitry Andric ArgStringList CmdArgs; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric if (!D.SysRoot.empty()) 1290b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric CmdArgs.push_back("--eh-frame-hdr"); 1325f757f3fSDimitry Andric if (Static) { 1330b57cec5SDimitry Andric CmdArgs.push_back("-Bstatic"); 1345f757f3fSDimitry Andric if (Pie) { 1350b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_pie); 1360b57cec5SDimitry Andric CmdArgs.push_back("--no-dynamic-linker"); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric } else { 1390b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 1400b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 1415f757f3fSDimitry Andric if (Shared) { 1425f757f3fSDimitry Andric CmdArgs.push_back("-shared"); 143fcaf7f86SDimitry Andric } else if (!Args.hasArg(options::OPT_r)) { 1440b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_pie); 1450b57cec5SDimitry Andric CmdArgs.push_back("-dynamic-linker"); 1460b57cec5SDimitry Andric CmdArgs.push_back("/libexec/ld.elf_so"); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // Many NetBSD architectures support more than one ABI. 1510b57cec5SDimitry Andric // Determine the correct emulation for ld. 1525f757f3fSDimitry Andric switch (Arch) { 1530b57cec5SDimitry Andric case llvm::Triple::x86: 1540b57cec5SDimitry Andric CmdArgs.push_back("-m"); 1550b57cec5SDimitry Andric CmdArgs.push_back("elf_i386"); 1560b57cec5SDimitry Andric break; 1570b57cec5SDimitry Andric case llvm::Triple::arm: 1580b57cec5SDimitry Andric case llvm::Triple::thumb: 1590b57cec5SDimitry Andric CmdArgs.push_back("-m"); 160349cc55cSDimitry Andric switch (Triple.getEnvironment()) { 1610b57cec5SDimitry Andric case llvm::Triple::EABI: 1620b57cec5SDimitry Andric case llvm::Triple::GNUEABI: 1630b57cec5SDimitry Andric CmdArgs.push_back("armelf_nbsd_eabi"); 1640b57cec5SDimitry Andric break; 1650b57cec5SDimitry Andric case llvm::Triple::EABIHF: 1660b57cec5SDimitry Andric case llvm::Triple::GNUEABIHF: 1670b57cec5SDimitry Andric CmdArgs.push_back("armelf_nbsd_eabihf"); 1680b57cec5SDimitry Andric break; 1690b57cec5SDimitry Andric default: 1700b57cec5SDimitry Andric CmdArgs.push_back("armelf_nbsd"); 1710b57cec5SDimitry Andric break; 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric break; 1740b57cec5SDimitry Andric case llvm::Triple::armeb: 1750b57cec5SDimitry Andric case llvm::Triple::thumbeb: 1760b57cec5SDimitry Andric arm::appendBE8LinkFlag(Args, CmdArgs, ToolChain.getEffectiveTriple()); 1770b57cec5SDimitry Andric CmdArgs.push_back("-m"); 178349cc55cSDimitry Andric switch (Triple.getEnvironment()) { 1790b57cec5SDimitry Andric case llvm::Triple::EABI: 1800b57cec5SDimitry Andric case llvm::Triple::GNUEABI: 1810b57cec5SDimitry Andric CmdArgs.push_back("armelfb_nbsd_eabi"); 1820b57cec5SDimitry Andric break; 1830b57cec5SDimitry Andric case llvm::Triple::EABIHF: 1840b57cec5SDimitry Andric case llvm::Triple::GNUEABIHF: 1850b57cec5SDimitry Andric CmdArgs.push_back("armelfb_nbsd_eabihf"); 1860b57cec5SDimitry Andric break; 1870b57cec5SDimitry Andric default: 1880b57cec5SDimitry Andric CmdArgs.push_back("armelfb_nbsd"); 1890b57cec5SDimitry Andric break; 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric break; 1920b57cec5SDimitry Andric case llvm::Triple::mips64: 1930b57cec5SDimitry Andric case llvm::Triple::mips64el: 1940b57cec5SDimitry Andric if (mips::hasMipsAbiArg(Args, "32")) { 1950b57cec5SDimitry Andric CmdArgs.push_back("-m"); 1965f757f3fSDimitry Andric if (Arch == llvm::Triple::mips64) 1970b57cec5SDimitry Andric CmdArgs.push_back("elf32btsmip"); 1980b57cec5SDimitry Andric else 1990b57cec5SDimitry Andric CmdArgs.push_back("elf32ltsmip"); 2000b57cec5SDimitry Andric } else if (mips::hasMipsAbiArg(Args, "64")) { 2010b57cec5SDimitry Andric CmdArgs.push_back("-m"); 2025f757f3fSDimitry Andric if (Arch == llvm::Triple::mips64) 2030b57cec5SDimitry Andric CmdArgs.push_back("elf64btsmip"); 2040b57cec5SDimitry Andric else 2050b57cec5SDimitry Andric CmdArgs.push_back("elf64ltsmip"); 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric break; 2080b57cec5SDimitry Andric case llvm::Triple::ppc: 2090b57cec5SDimitry Andric CmdArgs.push_back("-m"); 2100b57cec5SDimitry Andric CmdArgs.push_back("elf32ppc_nbsd"); 2110b57cec5SDimitry Andric break; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric case llvm::Triple::ppc64: 2140b57cec5SDimitry Andric case llvm::Triple::ppc64le: 2150b57cec5SDimitry Andric CmdArgs.push_back("-m"); 2160b57cec5SDimitry Andric CmdArgs.push_back("elf64ppc"); 2170b57cec5SDimitry Andric break; 2180b57cec5SDimitry Andric 2195f757f3fSDimitry Andric case llvm::Triple::riscv32: 2205f757f3fSDimitry Andric CmdArgs.push_back("-m"); 2215f757f3fSDimitry Andric CmdArgs.push_back("elf32lriscv"); 2225f757f3fSDimitry Andric break; 2235f757f3fSDimitry Andric 2245f757f3fSDimitry Andric case llvm::Triple::riscv64: 2255f757f3fSDimitry Andric CmdArgs.push_back("-m"); 2265f757f3fSDimitry Andric CmdArgs.push_back("elf64lriscv"); 2275f757f3fSDimitry Andric break; 2285f757f3fSDimitry Andric 2290b57cec5SDimitry Andric case llvm::Triple::sparc: 2300b57cec5SDimitry Andric CmdArgs.push_back("-m"); 2310b57cec5SDimitry Andric CmdArgs.push_back("elf32_sparc"); 2320b57cec5SDimitry Andric break; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric case llvm::Triple::sparcv9: 2350b57cec5SDimitry Andric CmdArgs.push_back("-m"); 2360b57cec5SDimitry Andric CmdArgs.push_back("elf64_sparc"); 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric default: 2400b57cec5SDimitry Andric break; 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 243*0fca6ea1SDimitry Andric if (Triple.isRISCV()) { 2445f757f3fSDimitry Andric CmdArgs.push_back("-X"); 245*0fca6ea1SDimitry Andric if (Args.hasArg(options::OPT_mno_relax)) 246*0fca6ea1SDimitry Andric CmdArgs.push_back("--no-relax"); 247*0fca6ea1SDimitry Andric } 2485f757f3fSDimitry Andric 2495f757f3fSDimitry Andric assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); 2500b57cec5SDimitry Andric if (Output.isFilename()) { 2510b57cec5SDimitry Andric CmdArgs.push_back("-o"); 2520b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 255d781ede6SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 256d781ede6SDimitry Andric options::OPT_r)) { 2575f757f3fSDimitry Andric const char *crt0 = nullptr; 2585f757f3fSDimitry Andric const char *crtbegin = nullptr; 2595f757f3fSDimitry Andric if (!Shared) 2605f757f3fSDimitry Andric crt0 = "crt0.o"; 2615f757f3fSDimitry Andric 2625f757f3fSDimitry Andric if (Shared || Pie) 2635f757f3fSDimitry Andric crtbegin = "crtbeginS.o"; 2645f757f3fSDimitry Andric else 2655f757f3fSDimitry Andric crtbegin = "crtbegin.o"; 2665f757f3fSDimitry Andric 2675f757f3fSDimitry Andric if (crt0) 2685f757f3fSDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt0))); 2695f757f3fSDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 2705f757f3fSDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric 2735f757f3fSDimitry Andric Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, 274*0fca6ea1SDimitry Andric options::OPT_s, options::OPT_t}); 2755f757f3fSDimitry Andric ToolChain.AddFilePathLibArgs(Args, CmdArgs); 2760b57cec5SDimitry Andric 277349cc55cSDimitry Andric bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); 2780b57cec5SDimitry Andric bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); 279349cc55cSDimitry Andric AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 2800b57cec5SDimitry Andric 281349cc55cSDimitry Andric const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(Args); 2820b57cec5SDimitry Andric if (SanArgs.needsSharedRt()) { 2830b57cec5SDimitry Andric CmdArgs.push_back("-rpath"); 284349cc55cSDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.getCompilerRTPath())); 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric bool useLibgcc = true; 2880b57cec5SDimitry Andric switch (ToolChain.getArch()) { 2890b57cec5SDimitry Andric case llvm::Triple::aarch64: 2900b57cec5SDimitry Andric case llvm::Triple::aarch64_be: 2910b57cec5SDimitry Andric case llvm::Triple::arm: 2920b57cec5SDimitry Andric case llvm::Triple::armeb: 2930b57cec5SDimitry Andric case llvm::Triple::thumb: 2940b57cec5SDimitry Andric case llvm::Triple::thumbeb: 2950b57cec5SDimitry Andric case llvm::Triple::ppc: 2960b57cec5SDimitry Andric case llvm::Triple::ppc64: 2970b57cec5SDimitry Andric case llvm::Triple::ppc64le: 2985f757f3fSDimitry Andric case llvm::Triple::riscv32: 2995f757f3fSDimitry Andric case llvm::Triple::riscv64: 3000b57cec5SDimitry Andric case llvm::Triple::sparc: 3010b57cec5SDimitry Andric case llvm::Triple::sparcv9: 3020b57cec5SDimitry Andric case llvm::Triple::x86: 3030b57cec5SDimitry Andric case llvm::Triple::x86_64: 3040b57cec5SDimitry Andric useLibgcc = false; 3050b57cec5SDimitry Andric break; 3060b57cec5SDimitry Andric default: 3070b57cec5SDimitry Andric break; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 310d781ede6SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 311d781ede6SDimitry Andric options::OPT_r)) { 312a7dea167SDimitry Andric // Use the static OpenMP runtime with -static-openmp 3135f757f3fSDimitry Andric bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; 314*0fca6ea1SDimitry Andric addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); 315a7dea167SDimitry Andric 3160b57cec5SDimitry Andric if (D.CCCIsCXX()) { 3170b57cec5SDimitry Andric if (ToolChain.ShouldLinkCXXStdlib(Args)) 3180b57cec5SDimitry Andric ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 3190b57cec5SDimitry Andric CmdArgs.push_back("-lm"); 3200b57cec5SDimitry Andric } 3215f757f3fSDimitry Andric 3225f757f3fSDimitry Andric // Silence warnings when linking C code with a C++ '-stdlib' argument. 3235f757f3fSDimitry Andric Args.ClaimAllArgs(options::OPT_stdlib_EQ); 3245f757f3fSDimitry Andric 3255f757f3fSDimitry Andric // Additional linker set-up and flags for Fortran. This is required in order 3265f757f3fSDimitry Andric // to generate executables. As Fortran runtime depends on the C runtime, 3275f757f3fSDimitry Andric // these dependencies need to be listed before the C runtime below (i.e. 3285f757f3fSDimitry Andric // AddRunTimeLibs). 3295f757f3fSDimitry Andric if (D.IsFlangMode()) { 3305f757f3fSDimitry Andric addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); 3315f757f3fSDimitry Andric addFortranRuntimeLibs(ToolChain, Args, CmdArgs); 3325f757f3fSDimitry Andric CmdArgs.push_back("-lm"); 3335f757f3fSDimitry Andric } 3345f757f3fSDimitry Andric 3350b57cec5SDimitry Andric if (NeedsSanitizerDeps) 3365f757f3fSDimitry Andric linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs); 3370b57cec5SDimitry Andric if (NeedsXRayDeps) 3385f757f3fSDimitry Andric linkXRayRuntimeDeps(ToolChain, Args, CmdArgs); 3390b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) 3400b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 3410b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric if (useLibgcc) { 3445f757f3fSDimitry Andric if (Static) { 3450b57cec5SDimitry Andric // libgcc_eh depends on libc, so resolve as much as possible, 3460b57cec5SDimitry Andric // pull in any new requirements from libc and then get the rest 3470b57cec5SDimitry Andric // of libgcc. 3480b57cec5SDimitry Andric CmdArgs.push_back("-lgcc_eh"); 3490b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 3500b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 3510b57cec5SDimitry Andric } else { 3520b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 3530b57cec5SDimitry Andric CmdArgs.push_back("--as-needed"); 3540b57cec5SDimitry Andric CmdArgs.push_back("-lgcc_s"); 3550b57cec5SDimitry Andric CmdArgs.push_back("--no-as-needed"); 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 360d781ede6SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 361d781ede6SDimitry Andric options::OPT_r)) { 3625f757f3fSDimitry Andric const char *crtend = nullptr; 3635f757f3fSDimitry Andric if (Shared || Pie) 3645f757f3fSDimitry Andric crtend = "crtendS.o"; 3650b57cec5SDimitry Andric else 3665f757f3fSDimitry Andric crtend = "crtend.o"; 3675f757f3fSDimitry Andric 3685f757f3fSDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); 3690b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric ToolChain.addProfileRTLibs(Args, CmdArgs); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); 375e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 376e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 377e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 3830b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 3840b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib)) { 3850b57cec5SDimitry Andric // When targeting a 32-bit platform, try the special directory used on 3860b57cec5SDimitry Andric // 64-bit hosts, and only fall back to the main library directory if that 3870b57cec5SDimitry Andric // doesn't work. 3880b57cec5SDimitry Andric // FIXME: It'd be nicer to test if this directory exists, but I'm not sure 3890b57cec5SDimitry Andric // what all logic is needed to emulate the '=' prefix here. 3900b57cec5SDimitry Andric switch (Triple.getArch()) { 3910b57cec5SDimitry Andric case llvm::Triple::x86: 3925f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/i386")); 3930b57cec5SDimitry Andric break; 3940b57cec5SDimitry Andric case llvm::Triple::arm: 3950b57cec5SDimitry Andric case llvm::Triple::armeb: 3960b57cec5SDimitry Andric case llvm::Triple::thumb: 3970b57cec5SDimitry Andric case llvm::Triple::thumbeb: 3980b57cec5SDimitry Andric switch (Triple.getEnvironment()) { 3990b57cec5SDimitry Andric case llvm::Triple::EABI: 4000b57cec5SDimitry Andric case llvm::Triple::GNUEABI: 4015f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/eabi")); 4020b57cec5SDimitry Andric break; 4030b57cec5SDimitry Andric case llvm::Triple::EABIHF: 4040b57cec5SDimitry Andric case llvm::Triple::GNUEABIHF: 4055f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/eabihf")); 4060b57cec5SDimitry Andric break; 4070b57cec5SDimitry Andric default: 4085f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/oabi")); 4090b57cec5SDimitry Andric break; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric break; 4120b57cec5SDimitry Andric case llvm::Triple::mips64: 4130b57cec5SDimitry Andric case llvm::Triple::mips64el: 4140b57cec5SDimitry Andric if (tools::mips::hasMipsAbiArg(Args, "o32")) 4155f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/o32")); 4160b57cec5SDimitry Andric else if (tools::mips::hasMipsAbiArg(Args, "64")) 4175f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/64")); 4180b57cec5SDimitry Andric break; 4190b57cec5SDimitry Andric case llvm::Triple::ppc: 4205f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/powerpc")); 4210b57cec5SDimitry Andric break; 4220b57cec5SDimitry Andric case llvm::Triple::sparc: 4235f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/sparc")); 4240b57cec5SDimitry Andric break; 4250b57cec5SDimitry Andric default: 4260b57cec5SDimitry Andric break; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4295f757f3fSDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib")); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric Tool *NetBSD::buildAssembler() const { 4340b57cec5SDimitry Andric return new tools::netbsd::Assembler(*this); 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const { 4400b57cec5SDimitry Andric switch (getArch()) { 4410b57cec5SDimitry Andric case llvm::Triple::aarch64: 4420b57cec5SDimitry Andric case llvm::Triple::aarch64_be: 4430b57cec5SDimitry Andric case llvm::Triple::arm: 4440b57cec5SDimitry Andric case llvm::Triple::armeb: 4450b57cec5SDimitry Andric case llvm::Triple::thumb: 4460b57cec5SDimitry Andric case llvm::Triple::thumbeb: 4470b57cec5SDimitry Andric case llvm::Triple::ppc: 4480b57cec5SDimitry Andric case llvm::Triple::ppc64: 4490b57cec5SDimitry Andric case llvm::Triple::ppc64le: 4505f757f3fSDimitry Andric case llvm::Triple::riscv32: 4515f757f3fSDimitry Andric case llvm::Triple::riscv64: 4520b57cec5SDimitry Andric case llvm::Triple::sparc: 4530b57cec5SDimitry Andric case llvm::Triple::sparcv9: 4540b57cec5SDimitry Andric case llvm::Triple::x86: 4550b57cec5SDimitry Andric case llvm::Triple::x86_64: 4560b57cec5SDimitry Andric return ToolChain::CST_Libcxx; 4570b57cec5SDimitry Andric default: 4580b57cec5SDimitry Andric break; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric return ToolChain::CST_Libstdcxx; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 463bdd1243dSDimitry Andric void NetBSD::AddClangSystemIncludeArgs( 464bdd1243dSDimitry Andric const llvm::opt::ArgList &DriverArgs, 465bdd1243dSDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 466bdd1243dSDimitry Andric const Driver &D = getDriver(); 467bdd1243dSDimitry Andric 468bdd1243dSDimitry Andric if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) 469bdd1243dSDimitry Andric return; 470bdd1243dSDimitry Andric 471bdd1243dSDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 472bdd1243dSDimitry Andric SmallString<128> Dir(D.ResourceDir); 473bdd1243dSDimitry Andric llvm::sys::path::append(Dir, "include"); 474bdd1243dSDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str()); 475bdd1243dSDimitry Andric } 476bdd1243dSDimitry Andric 477bdd1243dSDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 478bdd1243dSDimitry Andric return; 479bdd1243dSDimitry Andric 480bdd1243dSDimitry Andric // Check for configure-time C include directories. 481bdd1243dSDimitry Andric StringRef CIncludeDirs(C_INCLUDE_DIRS); 482bdd1243dSDimitry Andric if (CIncludeDirs != "") { 483bdd1243dSDimitry Andric SmallVector<StringRef, 5> dirs; 484bdd1243dSDimitry Andric CIncludeDirs.split(dirs, ":"); 485bdd1243dSDimitry Andric for (StringRef dir : dirs) { 486bdd1243dSDimitry Andric StringRef Prefix = 487bdd1243dSDimitry Andric llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; 488bdd1243dSDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 489bdd1243dSDimitry Andric } 490bdd1243dSDimitry Andric return; 491bdd1243dSDimitry Andric } 492bdd1243dSDimitry Andric 493bdd1243dSDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 494bdd1243dSDimitry Andric concat(D.SysRoot, "/usr/include")); 495bdd1243dSDimitry Andric } 496bdd1243dSDimitry Andric 4970b57cec5SDimitry Andric void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 4980b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 4990b57cec5SDimitry Andric const std::string Candidates[] = { 5000b57cec5SDimitry Andric // directory relative to build tree 5015f757f3fSDimitry Andric concat(getDriver().Dir, "/../include/c++/v1"), 5020b57cec5SDimitry Andric // system install with full upstream path 5035f757f3fSDimitry Andric concat(getDriver().SysRoot, "/usr/include/c++/v1"), 5040b57cec5SDimitry Andric // system install from src 5055f757f3fSDimitry Andric concat(getDriver().SysRoot, "/usr/include/c++"), 5060b57cec5SDimitry Andric }; 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric for (const auto &IncludePath : Candidates) { 5090b57cec5SDimitry Andric if (!getVFS().exists(IncludePath + "/__config")) 5100b57cec5SDimitry Andric continue; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric // Use the first candidate that looks valid. 5130b57cec5SDimitry Andric addSystemInclude(DriverArgs, CC1Args, IncludePath); 5140b57cec5SDimitry Andric return; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 5190b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 5205f757f3fSDimitry Andric addLibStdCXXIncludePaths(concat(getDriver().SysRoot, "/usr/include/g++"), "", "", 521fe6060f1SDimitry Andric DriverArgs, CC1Args); 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const { 5250b57cec5SDimitry Andric // NetBSD uses Dwarf exceptions on ARM. 5260b57cec5SDimitry Andric llvm::Triple::ArchType TArch = getTriple().getArch(); 5270b57cec5SDimitry Andric if (TArch == llvm::Triple::arm || TArch == llvm::Triple::armeb || 5280b57cec5SDimitry Andric TArch == llvm::Triple::thumb || TArch == llvm::Triple::thumbeb) 5290b57cec5SDimitry Andric return llvm::ExceptionHandling::DwarfCFI; 5300b57cec5SDimitry Andric return llvm::ExceptionHandling::None; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric SanitizerMask NetBSD::getSupportedSanitizers() const { 5340b57cec5SDimitry Andric const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; 5350b57cec5SDimitry Andric const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 5360b57cec5SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 5370b57cec5SDimitry Andric if (IsX86 || IsX86_64) { 5380b57cec5SDimitry Andric Res |= SanitizerKind::Address; 5390b57cec5SDimitry Andric Res |= SanitizerKind::PointerCompare; 5400b57cec5SDimitry Andric Res |= SanitizerKind::PointerSubtract; 5410b57cec5SDimitry Andric Res |= SanitizerKind::Leak; 5420b57cec5SDimitry Andric Res |= SanitizerKind::SafeStack; 5430b57cec5SDimitry Andric Res |= SanitizerKind::Scudo; 5440b57cec5SDimitry Andric Res |= SanitizerKind::Vptr; 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric if (IsX86_64) { 5470b57cec5SDimitry Andric Res |= SanitizerKind::DataFlow; 5480b57cec5SDimitry Andric Res |= SanitizerKind::Fuzzer; 5490b57cec5SDimitry Andric Res |= SanitizerKind::FuzzerNoLink; 5500b57cec5SDimitry Andric Res |= SanitizerKind::HWAddress; 5510b57cec5SDimitry Andric Res |= SanitizerKind::KernelAddress; 5520b57cec5SDimitry Andric Res |= SanitizerKind::KernelHWAddress; 5530b57cec5SDimitry Andric Res |= SanitizerKind::KernelMemory; 5540b57cec5SDimitry Andric Res |= SanitizerKind::Memory; 5550b57cec5SDimitry Andric Res |= SanitizerKind::Thread; 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric return Res; 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 560a7dea167SDimitry Andric void NetBSD::addClangTargetOptions(const ArgList &DriverArgs, 5610b57cec5SDimitry Andric ArgStringList &CC1Args, 5620b57cec5SDimitry Andric Action::OffloadKind) const { 563349cc55cSDimitry Andric const SanitizerArgs &SanArgs = getSanitizerArgs(DriverArgs); 5640b57cec5SDimitry Andric if (SanArgs.hasAnySanitizer()) 5650b57cec5SDimitry Andric CC1Args.push_back("-D_REENTRANT"); 566a7dea167SDimitry Andric 5670eae32dcSDimitry Andric VersionTuple OsVersion = getTriple().getOSVersion(); 568a7dea167SDimitry Andric bool UseInitArrayDefault = 5690eae32dcSDimitry Andric OsVersion >= VersionTuple(9) || OsVersion.getMajor() == 0 || 570a7dea167SDimitry Andric getTriple().getArch() == llvm::Triple::aarch64 || 571a7dea167SDimitry Andric getTriple().getArch() == llvm::Triple::aarch64_be || 572a7dea167SDimitry Andric getTriple().getArch() == llvm::Triple::arm || 5735f757f3fSDimitry Andric getTriple().getArch() == llvm::Triple::armeb || 5745f757f3fSDimitry Andric getTriple().getArch() == llvm::Triple::riscv32 || 5755f757f3fSDimitry Andric getTriple().getArch() == llvm::Triple::riscv64; 576a7dea167SDimitry Andric 577480093f4SDimitry Andric if (!DriverArgs.hasFlag(options::OPT_fuse_init_array, 578a7dea167SDimitry Andric options::OPT_fno_use_init_array, UseInitArrayDefault)) 579480093f4SDimitry Andric CC1Args.push_back("-fno-use-init-array"); 5800b57cec5SDimitry Andric } 581