10b57cec5SDimitry Andric //===--- Gnu.cpp - Gnu Tool and 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 "Gnu.h" 100b57cec5SDimitry Andric #include "Arch/ARM.h" 1181ad6265SDimitry Andric #include "Arch/CSKY.h" 1206c3fb27SDimitry Andric #include "Arch/LoongArch.h" 130b57cec5SDimitry Andric #include "Arch/Mips.h" 140b57cec5SDimitry Andric #include "Arch/PPC.h" 150b57cec5SDimitry Andric #include "Arch/RISCV.h" 160b57cec5SDimitry Andric #include "Arch/Sparc.h" 170b57cec5SDimitry Andric #include "Arch/SystemZ.h" 180b57cec5SDimitry Andric #include "CommonArgs.h" 190b57cec5SDimitry Andric #include "Linux.h" 200b57cec5SDimitry Andric #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX 210b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 220b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 230b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 2406c3fb27SDimitry Andric #include "clang/Driver/MultilibBuilder.h" 250b57cec5SDimitry Andric #include "clang/Driver/Options.h" 260b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 270b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 28bdd1243dSDimitry Andric #include "llvm/ADT/StringSet.h" 29bdd1243dSDimitry Andric #include "llvm/ADT/Twine.h" 300b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 310b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 320b57cec5SDimitry Andric #include "llvm/Support/Path.h" 330b57cec5SDimitry Andric #include "llvm/Support/VirtualFileSystem.h" 340fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h" 3506c3fb27SDimitry Andric #include "llvm/TargetParser/TargetParser.h" 360b57cec5SDimitry Andric #include <system_error> 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric using namespace clang::driver; 390b57cec5SDimitry Andric using namespace clang::driver::toolchains; 400b57cec5SDimitry Andric using namespace clang; 410b57cec5SDimitry Andric using namespace llvm::opt; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric using tools::addMultilibFlag; 445ffd83dbSDimitry Andric using tools::addPathIfExists; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric static bool forwardToGCC(const Option &O) { 47e8d8bef9SDimitry Andric // LinkerInput options have been forwarded. Don't duplicate. 48e8d8bef9SDimitry Andric if (O.hasFlag(options::LinkerInput)) 49e8d8bef9SDimitry Andric return false; 50e8d8bef9SDimitry Andric return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption); 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // Switch CPU names not recognized by GNU assembler to a close CPU that it does 540b57cec5SDimitry Andric // recognize, instead of a lower march from being picked in the absence of a cpu 550b57cec5SDimitry Andric // flag. 560b57cec5SDimitry Andric static void normalizeCPUNamesForAssembler(const ArgList &Args, 570b57cec5SDimitry Andric ArgStringList &CmdArgs) { 580b57cec5SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 590b57cec5SDimitry Andric StringRef CPUArg(A->getValue()); 60fe6060f1SDimitry Andric if (CPUArg.equals_insensitive("krait")) 610b57cec5SDimitry Andric CmdArgs.push_back("-mcpu=cortex-a15"); 62fe6060f1SDimitry Andric else if (CPUArg.equals_insensitive("kryo")) 630b57cec5SDimitry Andric CmdArgs.push_back("-mcpu=cortex-a57"); 640b57cec5SDimitry Andric else 650b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, 700b57cec5SDimitry Andric const InputInfo &Output, 710b57cec5SDimitry Andric const InputInfoList &Inputs, 720b57cec5SDimitry Andric const ArgList &Args, 730b57cec5SDimitry Andric const char *LinkingOutput) const { 740b57cec5SDimitry Andric const Driver &D = getToolChain().getDriver(); 750b57cec5SDimitry Andric ArgStringList CmdArgs; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric for (const auto &A : Args) { 780b57cec5SDimitry Andric if (forwardToGCC(A->getOption())) { 790b57cec5SDimitry Andric // It is unfortunate that we have to claim here, as this means 800b57cec5SDimitry Andric // we will basically never report anything interesting for 810b57cec5SDimitry Andric // platforms using a generic gcc, even if we are just using gcc 820b57cec5SDimitry Andric // to get to the assembler. 830b57cec5SDimitry Andric A->claim(); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric A->render(Args, CmdArgs); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric RenderExtraToolArgs(JA, CmdArgs); 900b57cec5SDimitry Andric 91bdd1243dSDimitry Andric // If using a driver, force the arch. 920b57cec5SDimitry Andric if (getToolChain().getTriple().isOSDarwin()) { 930b57cec5SDimitry Andric CmdArgs.push_back("-arch"); 940b57cec5SDimitry Andric CmdArgs.push_back( 950b57cec5SDimitry Andric Args.MakeArgString(getToolChain().getDefaultUniversalArchName())); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // Try to force gcc to match the tool chain we want, if we recognize 990b57cec5SDimitry Andric // the arch. 1000b57cec5SDimitry Andric // 1010b57cec5SDimitry Andric // FIXME: The triple class should directly provide the information we want 1020b57cec5SDimitry Andric // here. 1030b57cec5SDimitry Andric switch (getToolChain().getArch()) { 1040b57cec5SDimitry Andric default: 1050b57cec5SDimitry Andric break; 1060b57cec5SDimitry Andric case llvm::Triple::x86: 1070b57cec5SDimitry Andric case llvm::Triple::ppc: 108e8d8bef9SDimitry Andric case llvm::Triple::ppcle: 1090b57cec5SDimitry Andric CmdArgs.push_back("-m32"); 1100b57cec5SDimitry Andric break; 1110b57cec5SDimitry Andric case llvm::Triple::x86_64: 1120b57cec5SDimitry Andric case llvm::Triple::ppc64: 1130b57cec5SDimitry Andric case llvm::Triple::ppc64le: 1140b57cec5SDimitry Andric CmdArgs.push_back("-m64"); 1150b57cec5SDimitry Andric break; 1160b57cec5SDimitry Andric case llvm::Triple::sparcel: 1170b57cec5SDimitry Andric CmdArgs.push_back("-EL"); 1180b57cec5SDimitry Andric break; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1215f757f3fSDimitry Andric assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); 1220b57cec5SDimitry Andric if (Output.isFilename()) { 1230b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1240b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1250b57cec5SDimitry Andric } else { 1260b57cec5SDimitry Andric CmdArgs.push_back("-fsyntax-only"); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // Only pass -x if gcc will understand it; otherwise hope gcc 1320b57cec5SDimitry Andric // understands the suffix correctly. The main use case this would go 1330b57cec5SDimitry Andric // wrong in is for linker inputs if they happened to have an odd 1340b57cec5SDimitry Andric // suffix; really the only way to get this to happen is a command 1350b57cec5SDimitry Andric // like '-x foobar a.c' which will treat a.c like a linker input. 1360b57cec5SDimitry Andric // 1370b57cec5SDimitry Andric // FIXME: For the linker case specifically, can we safely convert 1380b57cec5SDimitry Andric // inputs into '-Wl,' options? 1390b57cec5SDimitry Andric for (const auto &II : Inputs) { 1400b57cec5SDimitry Andric // Don't try to pass LLVM or AST inputs to a generic gcc. 1410b57cec5SDimitry Andric if (types::isLLVMIR(II.getType())) 1420b57cec5SDimitry Andric D.Diag(clang::diag::err_drv_no_linker_llvm_support) 1430b57cec5SDimitry Andric << getToolChain().getTripleString(); 1440b57cec5SDimitry Andric else if (II.getType() == types::TY_AST) 1450b57cec5SDimitry Andric D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString(); 1460b57cec5SDimitry Andric else if (II.getType() == types::TY_ModuleFile) 1470b57cec5SDimitry Andric D.Diag(diag::err_drv_no_module_support) 1480b57cec5SDimitry Andric << getToolChain().getTripleString(); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric if (types::canTypeBeUserSpecified(II.getType())) { 1510b57cec5SDimitry Andric CmdArgs.push_back("-x"); 1520b57cec5SDimitry Andric CmdArgs.push_back(types::getTypeName(II.getType())); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric if (II.isFilename()) 1560b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename()); 1570b57cec5SDimitry Andric else { 1580b57cec5SDimitry Andric const Arg &A = II.getInputArg(); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric // Reverse translate some rewritten options. 1610b57cec5SDimitry Andric if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) { 1620b57cec5SDimitry Andric CmdArgs.push_back("-lstdc++"); 1630b57cec5SDimitry Andric continue; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric // Don't render as input, we need gcc to do the translations. 1670b57cec5SDimitry Andric A.render(Args, CmdArgs); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric const std::string &customGCCName = D.getCCCGenericGCCName(); 1720b57cec5SDimitry Andric const char *GCCName; 1730b57cec5SDimitry Andric if (!customGCCName.empty()) 1740b57cec5SDimitry Andric GCCName = customGCCName.c_str(); 1750b57cec5SDimitry Andric else if (D.CCCIsCXX()) { 1760b57cec5SDimitry Andric GCCName = "g++"; 1770b57cec5SDimitry Andric } else 1780b57cec5SDimitry Andric GCCName = "gcc"; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); 181e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 182e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 183e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void tools::gcc::Preprocessor::RenderExtraToolArgs( 1870b57cec5SDimitry Andric const JobAction &JA, ArgStringList &CmdArgs) const { 1880b57cec5SDimitry Andric CmdArgs.push_back("-E"); 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA, 1920b57cec5SDimitry Andric ArgStringList &CmdArgs) const { 1930b57cec5SDimitry Andric const Driver &D = getToolChain().getDriver(); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric switch (JA.getType()) { 1960b57cec5SDimitry Andric // If -flto, etc. are present then make sure not to force assembly output. 1970b57cec5SDimitry Andric case types::TY_LLVM_IR: 1980b57cec5SDimitry Andric case types::TY_LTO_IR: 1990b57cec5SDimitry Andric case types::TY_LLVM_BC: 2000b57cec5SDimitry Andric case types::TY_LTO_BC: 2010b57cec5SDimitry Andric CmdArgs.push_back("-c"); 2020b57cec5SDimitry Andric break; 2030b57cec5SDimitry Andric // We assume we've got an "integrated" assembler in that gcc will produce an 2040b57cec5SDimitry Andric // object file itself. 2050b57cec5SDimitry Andric case types::TY_Object: 2060b57cec5SDimitry Andric CmdArgs.push_back("-c"); 2070b57cec5SDimitry Andric break; 2080b57cec5SDimitry Andric case types::TY_PP_Asm: 2090b57cec5SDimitry Andric CmdArgs.push_back("-S"); 2100b57cec5SDimitry Andric break; 2110b57cec5SDimitry Andric case types::TY_Nothing: 2120b57cec5SDimitry Andric CmdArgs.push_back("-fsyntax-only"); 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric default: 2150b57cec5SDimitry Andric D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType()); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA, 2200b57cec5SDimitry Andric ArgStringList &CmdArgs) const { 2210b57cec5SDimitry Andric // The types are (hopefully) good enough. 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { 2250b57cec5SDimitry Andric switch (T.getArch()) { 2260b57cec5SDimitry Andric case llvm::Triple::x86: 2270b57cec5SDimitry Andric if (T.isOSIAMCU()) 2280b57cec5SDimitry Andric return "elf_iamcu"; 2290b57cec5SDimitry Andric return "elf_i386"; 2300b57cec5SDimitry Andric case llvm::Triple::aarch64: 2310b57cec5SDimitry Andric return "aarch64linux"; 2320b57cec5SDimitry Andric case llvm::Triple::aarch64_be: 2330b57cec5SDimitry Andric return "aarch64linuxb"; 2340b57cec5SDimitry Andric case llvm::Triple::arm: 2350b57cec5SDimitry Andric case llvm::Triple::thumb: 2360b57cec5SDimitry Andric case llvm::Triple::armeb: 2370b57cec5SDimitry Andric case llvm::Triple::thumbeb: 23806c3fb27SDimitry Andric return tools::arm::isARMBigEndian(T, Args) ? "armelfb_linux_eabi" 23906c3fb27SDimitry Andric : "armelf_linux_eabi"; 240fe6060f1SDimitry Andric case llvm::Triple::m68k: 241fe6060f1SDimitry Andric return "m68kelf"; 2420b57cec5SDimitry Andric case llvm::Triple::ppc: 243e8d8bef9SDimitry Andric if (T.isOSLinux()) 2440b57cec5SDimitry Andric return "elf32ppclinux"; 245e8d8bef9SDimitry Andric return "elf32ppc"; 246e8d8bef9SDimitry Andric case llvm::Triple::ppcle: 247e8d8bef9SDimitry Andric if (T.isOSLinux()) 248e8d8bef9SDimitry Andric return "elf32lppclinux"; 249e8d8bef9SDimitry Andric return "elf32lppc"; 2500b57cec5SDimitry Andric case llvm::Triple::ppc64: 2510b57cec5SDimitry Andric return "elf64ppc"; 2520b57cec5SDimitry Andric case llvm::Triple::ppc64le: 2530b57cec5SDimitry Andric return "elf64lppc"; 2540b57cec5SDimitry Andric case llvm::Triple::riscv32: 2550b57cec5SDimitry Andric return "elf32lriscv"; 2560b57cec5SDimitry Andric case llvm::Triple::riscv64: 2570b57cec5SDimitry Andric return "elf64lriscv"; 2580b57cec5SDimitry Andric case llvm::Triple::sparc: 2590b57cec5SDimitry Andric case llvm::Triple::sparcel: 2600b57cec5SDimitry Andric return "elf32_sparc"; 2610b57cec5SDimitry Andric case llvm::Triple::sparcv9: 2620b57cec5SDimitry Andric return "elf64_sparc"; 263bdd1243dSDimitry Andric case llvm::Triple::loongarch32: 264bdd1243dSDimitry Andric return "elf32loongarch"; 265bdd1243dSDimitry Andric case llvm::Triple::loongarch64: 266bdd1243dSDimitry Andric return "elf64loongarch"; 2670b57cec5SDimitry Andric case llvm::Triple::mips: 2680b57cec5SDimitry Andric return "elf32btsmip"; 2690b57cec5SDimitry Andric case llvm::Triple::mipsel: 2700b57cec5SDimitry Andric return "elf32ltsmip"; 2710b57cec5SDimitry Andric case llvm::Triple::mips64: 2720b57cec5SDimitry Andric if (tools::mips::hasMipsAbiArg(Args, "n32") || 2730b57cec5SDimitry Andric T.getEnvironment() == llvm::Triple::GNUABIN32) 2740b57cec5SDimitry Andric return "elf32btsmipn32"; 2750b57cec5SDimitry Andric return "elf64btsmip"; 2760b57cec5SDimitry Andric case llvm::Triple::mips64el: 2770b57cec5SDimitry Andric if (tools::mips::hasMipsAbiArg(Args, "n32") || 2780b57cec5SDimitry Andric T.getEnvironment() == llvm::Triple::GNUABIN32) 2790b57cec5SDimitry Andric return "elf32ltsmipn32"; 2800b57cec5SDimitry Andric return "elf64ltsmip"; 2810b57cec5SDimitry Andric case llvm::Triple::systemz: 2820b57cec5SDimitry Andric return "elf64_s390"; 2830b57cec5SDimitry Andric case llvm::Triple::x86_64: 284fe6060f1SDimitry Andric if (T.isX32()) 2850b57cec5SDimitry Andric return "elf32_x86_64"; 2860b57cec5SDimitry Andric return "elf_x86_64"; 2875ffd83dbSDimitry Andric case llvm::Triple::ve: 2885ffd83dbSDimitry Andric return "elf64ve"; 28981ad6265SDimitry Andric case llvm::Triple::csky: 29081ad6265SDimitry Andric return "cskyelf_linux"; 2910b57cec5SDimitry Andric default: 2920b57cec5SDimitry Andric return nullptr; 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 296d65cd7a5SDimitry Andric static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { 2970b57cec5SDimitry Andric bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); 2985f757f3fSDimitry Andric if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) { 299d65cd7a5SDimitry Andric const Driver &D = TC.getDriver(); 3000b57cec5SDimitry Andric const llvm::opt::OptTable &Opts = D.getOpts(); 301bdd1243dSDimitry Andric StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie); 302bdd1243dSDimitry Andric StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie); 3030b57cec5SDimitry Andric D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric return HasStaticPIE; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric static bool getStatic(const ArgList &Args) { 3090b57cec5SDimitry Andric return Args.hasArg(options::OPT_static) && 3100b57cec5SDimitry Andric !Args.hasArg(options::OPT_static_pie); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 3135ffd83dbSDimitry Andric void tools::gnutools::StaticLibTool::ConstructJob( 3145ffd83dbSDimitry Andric Compilation &C, const JobAction &JA, const InputInfo &Output, 3155ffd83dbSDimitry Andric const InputInfoList &Inputs, const ArgList &Args, 3165ffd83dbSDimitry Andric const char *LinkingOutput) const { 3175ffd83dbSDimitry Andric const Driver &D = getToolChain().getDriver(); 3185ffd83dbSDimitry Andric 3195ffd83dbSDimitry Andric // Silence warning for "clang -g foo.o -o foo" 3205ffd83dbSDimitry Andric Args.ClaimAllArgs(options::OPT_g_Group); 3215ffd83dbSDimitry Andric // and "clang -emit-llvm foo.o -o foo" 3225ffd83dbSDimitry Andric Args.ClaimAllArgs(options::OPT_emit_llvm); 3235ffd83dbSDimitry Andric // and for "clang -w foo.o -o foo". Other warning options are already 3245ffd83dbSDimitry Andric // handled somewhere else. 3255ffd83dbSDimitry Andric Args.ClaimAllArgs(options::OPT_w); 3265ffd83dbSDimitry Andric // Silence warnings when linking C code with a C++ '-stdlib' argument. 3275ffd83dbSDimitry Andric Args.ClaimAllArgs(options::OPT_stdlib_EQ); 3285ffd83dbSDimitry Andric 329e8d8bef9SDimitry Andric // ar tool command "llvm-ar <options> <output_file> <input_files>". 3305ffd83dbSDimitry Andric ArgStringList CmdArgs; 3315ffd83dbSDimitry Andric // Create and insert file members with a deterministic index. 3325ffd83dbSDimitry Andric CmdArgs.push_back("rcsD"); 3335ffd83dbSDimitry Andric CmdArgs.push_back(Output.getFilename()); 334e8d8bef9SDimitry Andric 335e8d8bef9SDimitry Andric for (const auto &II : Inputs) { 336e8d8bef9SDimitry Andric if (II.isFilename()) { 337e8d8bef9SDimitry Andric CmdArgs.push_back(II.getFilename()); 338e8d8bef9SDimitry Andric } 339e8d8bef9SDimitry Andric } 3405ffd83dbSDimitry Andric 3415ffd83dbSDimitry Andric // Delete old output archive file if it already exists before generating a new 3425ffd83dbSDimitry Andric // archive file. 3435ffd83dbSDimitry Andric auto OutputFileName = Output.getFilename(); 3445ffd83dbSDimitry Andric if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) { 3455ffd83dbSDimitry Andric if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) { 3465ffd83dbSDimitry Andric D.Diag(diag::err_drv_unable_to_remove_file) << EC.message(); 3475ffd83dbSDimitry Andric return; 3485ffd83dbSDimitry Andric } 3495ffd83dbSDimitry Andric } 3505ffd83dbSDimitry Andric 3515ffd83dbSDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); 352e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 353e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 354e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 3555ffd83dbSDimitry Andric } 3565ffd83dbSDimitry Andric 3570b57cec5SDimitry Andric void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, 3580b57cec5SDimitry Andric const InputInfo &Output, 3590b57cec5SDimitry Andric const InputInfoList &Inputs, 3600b57cec5SDimitry Andric const ArgList &Args, 3610b57cec5SDimitry Andric const char *LinkingOutput) const { 362d65cd7a5SDimitry Andric // FIXME: The Linker class constructor takes a ToolChain and not a 363d65cd7a5SDimitry Andric // Generic_ELF, so the static_cast might return a reference to a invalid 364d65cd7a5SDimitry Andric // instance (see PR45061). Ideally, the Linker constructor needs to take a 365d65cd7a5SDimitry Andric // Generic_ELF instead. 3665f757f3fSDimitry Andric const auto &ToolChain = static_cast<const Generic_ELF &>(getToolChain()); 3670b57cec5SDimitry Andric const Driver &D = ToolChain.getDriver(); 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric const llvm::Triple::ArchType Arch = ToolChain.getArch(); 37206c3fb27SDimitry Andric const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily(); 3730b57cec5SDimitry Andric const bool isAndroid = ToolChain.getTriple().isAndroid(); 3740b57cec5SDimitry Andric const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); 3755ffd83dbSDimitry Andric const bool IsVE = ToolChain.getTriple().isVE(); 3760b57cec5SDimitry Andric const bool IsStaticPIE = getStaticPIE(Args, ToolChain); 3770b57cec5SDimitry Andric const bool IsStatic = getStatic(Args); 3780b57cec5SDimitry Andric const bool HasCRTBeginEndFiles = 3790b57cec5SDimitry Andric ToolChain.getTriple().hasEnvironment() || 3800b57cec5SDimitry Andric (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric ArgStringList CmdArgs; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric // Silence warning for "clang -g foo.o -o foo" 3850b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_g_Group); 3860b57cec5SDimitry Andric // and "clang -emit-llvm foo.o -o foo" 3870b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_emit_llvm); 3880b57cec5SDimitry Andric // and for "clang -w foo.o -o foo". Other warning options are already 3890b57cec5SDimitry Andric // handled somewhere else. 3900b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_w); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric if (!D.SysRoot.empty()) 3930b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric if (Args.hasArg(options::OPT_s)) 3960b57cec5SDimitry Andric CmdArgs.push_back("-s"); 3970b57cec5SDimitry Andric 39806c3fb27SDimitry Andric if (Triple.isARM() || Triple.isThumb()) { 39906c3fb27SDimitry Andric bool IsBigEndian = arm::isARMBigEndian(Triple, Args); 4000b57cec5SDimitry Andric if (IsBigEndian) 4010b57cec5SDimitry Andric arm::appendBE8LinkFlag(Args, CmdArgs, Triple); 4020b57cec5SDimitry Andric CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL"); 40306c3fb27SDimitry Andric } else if (Triple.isAArch64()) { 40406c3fb27SDimitry Andric CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL"); 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric // Most Android ARM64 targets should enable the linker fix for erratum 4080b57cec5SDimitry Andric // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. 40906c3fb27SDimitry Andric if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) { 410349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, Triple); 4110b57cec5SDimitry Andric if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") 4120b57cec5SDimitry Andric CmdArgs.push_back("--fix-cortex-a53-843419"); 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 415d65cd7a5SDimitry Andric ToolChain.addExtraOpts(CmdArgs); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric CmdArgs.push_back("--eh-frame-hdr"); 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) { 4200b57cec5SDimitry Andric CmdArgs.push_back("-m"); 4210b57cec5SDimitry Andric CmdArgs.push_back(LDMOption); 4220b57cec5SDimitry Andric } else { 4230b57cec5SDimitry Andric D.Diag(diag::err_target_unknown_triple) << Triple.str(); 4240b57cec5SDimitry Andric return; 4250b57cec5SDimitry Andric } 4260fca6ea1SDimitry Andric 4270fca6ea1SDimitry Andric if (Triple.isRISCV()) { 42881ad6265SDimitry Andric CmdArgs.push_back("-X"); 4290fca6ea1SDimitry Andric if (Args.hasArg(options::OPT_mno_relax)) 4300fca6ea1SDimitry Andric CmdArgs.push_back("--no-relax"); 4310fca6ea1SDimitry Andric } 4320b57cec5SDimitry Andric 4335f757f3fSDimitry Andric const bool IsShared = Args.hasArg(options::OPT_shared); 4345f757f3fSDimitry Andric if (IsShared) 4350b57cec5SDimitry Andric CmdArgs.push_back("-shared"); 4365f757f3fSDimitry Andric bool IsPIE = false; 4375f757f3fSDimitry Andric if (IsStaticPIE) { 438349cc55cSDimitry Andric CmdArgs.push_back("-static"); 4395f757f3fSDimitry Andric CmdArgs.push_back("-pie"); 4405f757f3fSDimitry Andric CmdArgs.push_back("--no-dynamic-linker"); 4415f757f3fSDimitry Andric CmdArgs.push_back("-z"); 4425f757f3fSDimitry Andric CmdArgs.push_back("text"); 4435f757f3fSDimitry Andric } else if (IsStatic) { 4445f757f3fSDimitry Andric CmdArgs.push_back("-static"); 4455f757f3fSDimitry Andric } else if (!Args.hasArg(options::OPT_r)) { 4460b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 4470b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 4485f757f3fSDimitry Andric if (!IsShared) { 4495f757f3fSDimitry Andric IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie, 4505f757f3fSDimitry Andric ToolChain.isPIEDefault(Args)); 4515f757f3fSDimitry Andric if (IsPIE) 4525f757f3fSDimitry Andric CmdArgs.push_back("-pie"); 4530b57cec5SDimitry Andric CmdArgs.push_back("-dynamic-linker"); 4545ffd83dbSDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) + 4555ffd83dbSDimitry Andric ToolChain.getDynamicLinker(Args))); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric CmdArgs.push_back("-o"); 4600b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 4610b57cec5SDimitry Andric 46204eeddc0SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 46304eeddc0SDimitry Andric options::OPT_r)) { 4640b57cec5SDimitry Andric if (!isAndroid && !IsIAMCU) { 4650b57cec5SDimitry Andric const char *crt1 = nullptr; 4660b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_shared)) { 4670b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pg)) 4680b57cec5SDimitry Andric crt1 = "gcrt1.o"; 4690b57cec5SDimitry Andric else if (IsPIE) 4700b57cec5SDimitry Andric crt1 = "Scrt1.o"; 4710b57cec5SDimitry Andric else if (IsStaticPIE) 4720b57cec5SDimitry Andric crt1 = "rcrt1.o"; 4730b57cec5SDimitry Andric else 4740b57cec5SDimitry Andric crt1 = "crt1.o"; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric if (crt1) 4770b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 4825ffd83dbSDimitry Andric if (IsVE) { 4835ffd83dbSDimitry Andric CmdArgs.push_back("-z"); 4845ffd83dbSDimitry Andric CmdArgs.push_back("max-page-size=0x4000000"); 4855ffd83dbSDimitry Andric } 4865ffd83dbSDimitry Andric 4870b57cec5SDimitry Andric if (IsIAMCU) 4880b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); 4890b57cec5SDimitry Andric else if (HasCRTBeginEndFiles) { 4900b57cec5SDimitry Andric std::string P; 4910b57cec5SDimitry Andric if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && 4920b57cec5SDimitry Andric !isAndroid) { 4930b57cec5SDimitry Andric std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin", 4940b57cec5SDimitry Andric ToolChain::FT_Object); 4950b57cec5SDimitry Andric if (ToolChain.getVFS().exists(crtbegin)) 4960b57cec5SDimitry Andric P = crtbegin; 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric if (P.empty()) { 4990b57cec5SDimitry Andric const char *crtbegin; 500349cc55cSDimitry Andric if (Args.hasArg(options::OPT_shared)) 5010b57cec5SDimitry Andric crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; 502349cc55cSDimitry Andric else if (IsStatic) 503349cc55cSDimitry Andric crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; 5040b57cec5SDimitry Andric else if (IsPIE || IsStaticPIE) 5050b57cec5SDimitry Andric crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; 5060b57cec5SDimitry Andric else 5070b57cec5SDimitry Andric crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; 5080b57cec5SDimitry Andric P = ToolChain.GetFilePath(crtbegin); 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(P)); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric // Add crtfastmath.o if available and fast math is enabled. 5145ffd83dbSDimitry Andric ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs); 5157a6dacacSDimitry Andric 5167a6dacacSDimitry Andric if (isAndroid && Args.hasFlag(options::OPT_fandroid_pad_segment, 5177a6dacacSDimitry Andric options::OPT_fno_android_pad_segment, false)) 5187a6dacacSDimitry Andric CmdArgs.push_back( 5197a6dacacSDimitry Andric Args.MakeArgString(ToolChain.GetFilePath("crt_pad_segment.o"))); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5225f757f3fSDimitry Andric Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u}); 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric ToolChain.AddFilePathLibArgs(Args, CmdArgs); 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric if (D.isUsingLTO()) { 5270b57cec5SDimitry Andric assert(!Inputs.empty() && "Must have at least one input."); 5285f757f3fSDimitry Andric // Find the first filename InputInfo object. 5295f757f3fSDimitry Andric auto Input = llvm::find_if( 5305f757f3fSDimitry Andric Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); }); 5315f757f3fSDimitry Andric if (Input == Inputs.end()) 5325f757f3fSDimitry Andric // For a very rare case, all of the inputs to the linker are 5335f757f3fSDimitry Andric // InputArg. If that happens, just use the first InputInfo. 5345f757f3fSDimitry Andric Input = Inputs.begin(); 5355f757f3fSDimitry Andric 5365f757f3fSDimitry Andric addLTOOptions(ToolChain, Args, CmdArgs, Output, *Input, 5370b57cec5SDimitry Andric D.getLTOMode() == LTOK_Thin); 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 5410b57cec5SDimitry Andric CmdArgs.push_back("--no-demangle"); 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); 5440b57cec5SDimitry Andric bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); 54519587d74SEd Maste addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs); 5460b57cec5SDimitry Andric AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 54781ad6265SDimitry Andric 5485f757f3fSDimitry Andric addHIPRuntimeLibArgs(ToolChain, C, Args, CmdArgs); 54981ad6265SDimitry Andric 5500b57cec5SDimitry Andric // The profile runtime also needs access to system libraries. 5510b57cec5SDimitry Andric getToolChain().addProfileRTLibs(Args, CmdArgs); 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric if (D.CCCIsCXX() && 55404eeddc0SDimitry Andric !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 55504eeddc0SDimitry Andric options::OPT_r)) { 5560b57cec5SDimitry Andric if (ToolChain.ShouldLinkCXXStdlib(Args)) { 5570b57cec5SDimitry Andric bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && 5580b57cec5SDimitry Andric !Args.hasArg(options::OPT_static); 5590b57cec5SDimitry Andric if (OnlyLibstdcxxStatic) 5600b57cec5SDimitry Andric CmdArgs.push_back("-Bstatic"); 5610b57cec5SDimitry Andric ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 5620b57cec5SDimitry Andric if (OnlyLibstdcxxStatic) 5630b57cec5SDimitry Andric CmdArgs.push_back("-Bdynamic"); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric CmdArgs.push_back("-lm"); 5660b57cec5SDimitry Andric } 56781ad6265SDimitry Andric 5680b57cec5SDimitry Andric // Silence warnings when linking C code with a C++ '-stdlib' argument. 5690b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_stdlib_EQ); 5700b57cec5SDimitry Andric 57181ad6265SDimitry Andric // Additional linker set-up and flags for Fortran. This is required in order 57281ad6265SDimitry Andric // to generate executables. As Fortran runtime depends on the C runtime, 57381ad6265SDimitry Andric // these dependencies need to be listed before the C runtime below (i.e. 5745f757f3fSDimitry Andric // AddRunTimeLibs). 57581ad6265SDimitry Andric if (D.IsFlangMode()) { 57681ad6265SDimitry Andric addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); 5775f757f3fSDimitry Andric addFortranRuntimeLibs(ToolChain, Args, CmdArgs); 57881ad6265SDimitry Andric CmdArgs.push_back("-lm"); 57981ad6265SDimitry Andric } 58081ad6265SDimitry Andric 58104eeddc0SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) { 5820b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nodefaultlibs)) { 5830b57cec5SDimitry Andric if (IsStatic || IsStaticPIE) 5840b57cec5SDimitry Andric CmdArgs.push_back("--start-group"); 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric if (NeedsSanitizerDeps) 5875f757f3fSDimitry Andric linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs); 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric if (NeedsXRayDeps) 5905f757f3fSDimitry Andric linkXRayRuntimeDeps(ToolChain, Args, CmdArgs); 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric bool WantPthread = Args.hasArg(options::OPT_pthread) || 5930b57cec5SDimitry Andric Args.hasArg(options::OPT_pthreads); 5940b57cec5SDimitry Andric 595a7dea167SDimitry Andric // Use the static OpenMP runtime with -static-openmp 596a7dea167SDimitry Andric bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && 597a7dea167SDimitry Andric !Args.hasArg(options::OPT_static); 598a7dea167SDimitry Andric 5990b57cec5SDimitry Andric // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that 6000b57cec5SDimitry Andric // require librt. Most modern Linux platforms do, but some may not. 6010fca6ea1SDimitry Andric if (addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP, 6020b57cec5SDimitry Andric JA.isHostOffloading(Action::OFK_OpenMP), 6030b57cec5SDimitry Andric /* GompNeedsRT= */ true)) 6040b57cec5SDimitry Andric // OpenMP runtimes implies pthreads when using the GNU toolchain. 6050b57cec5SDimitry Andric // FIXME: Does this really make sense for all GNU toolchains? 6060b57cec5SDimitry Andric WantPthread = true; 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args); 6090b57cec5SDimitry Andric 61061cfbce3SDimitry Andric // LLVM support for atomics on 32-bit SPARC V8+ is incomplete, so 61161cfbce3SDimitry Andric // forcibly link with libatomic as a workaround. 61261cfbce3SDimitry Andric // TODO: Issue #41880 and D118021. 61361cfbce3SDimitry Andric if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) { 61461cfbce3SDimitry Andric CmdArgs.push_back("--push-state"); 61561cfbce3SDimitry Andric CmdArgs.push_back("--as-needed"); 61661cfbce3SDimitry Andric CmdArgs.push_back("-latomic"); 61761cfbce3SDimitry Andric CmdArgs.push_back("--pop-state"); 61861cfbce3SDimitry Andric } 61961cfbce3SDimitry Andric 62006c3fb27SDimitry Andric // We don't need libpthread neither for bionic (Android) nor for musl, 62106c3fb27SDimitry Andric // (used by OHOS as runtime library). 62206c3fb27SDimitry Andric if (WantPthread && !isAndroid && !isOHOSFamily) 6230b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric if (Args.hasArg(options::OPT_fsplit_stack)) 6260b57cec5SDimitry Andric CmdArgs.push_back("--wrap=pthread_create"); 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nolibc)) 6290b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric // Add IAMCU specific libs, if needed. 6320b57cec5SDimitry Andric if (IsIAMCU) 6330b57cec5SDimitry Andric CmdArgs.push_back("-lgloss"); 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric if (IsStatic || IsStaticPIE) 6360b57cec5SDimitry Andric CmdArgs.push_back("--end-group"); 6370b57cec5SDimitry Andric else 6380b57cec5SDimitry Andric AddRunTimeLibs(ToolChain, D, CmdArgs, Args); 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric // Add IAMCU specific libs (outside the group), if needed. 6410b57cec5SDimitry Andric if (IsIAMCU) { 6420b57cec5SDimitry Andric CmdArgs.push_back("--as-needed"); 6430b57cec5SDimitry Andric CmdArgs.push_back("-lsoftfp"); 6440b57cec5SDimitry Andric CmdArgs.push_back("--no-as-needed"); 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) { 6490b57cec5SDimitry Andric if (HasCRTBeginEndFiles) { 6500b57cec5SDimitry Andric std::string P; 6510b57cec5SDimitry Andric if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && 6520b57cec5SDimitry Andric !isAndroid) { 6530b57cec5SDimitry Andric std::string crtend = ToolChain.getCompilerRT(Args, "crtend", 6540b57cec5SDimitry Andric ToolChain::FT_Object); 6550b57cec5SDimitry Andric if (ToolChain.getVFS().exists(crtend)) 6560b57cec5SDimitry Andric P = crtend; 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric if (P.empty()) { 6590b57cec5SDimitry Andric const char *crtend; 6600b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared)) 6610b57cec5SDimitry Andric crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; 6620b57cec5SDimitry Andric else if (IsPIE || IsStaticPIE) 6630b57cec5SDimitry Andric crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; 6640b57cec5SDimitry Andric else 6650b57cec5SDimitry Andric crtend = isAndroid ? "crtend_android.o" : "crtend.o"; 6660b57cec5SDimitry Andric P = ToolChain.GetFilePath(crtend); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(P)); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric if (!isAndroid) 6710b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 6755ffd83dbSDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_T); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); 678e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 679e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 680e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric void tools::gnutools::Assembler::ConstructJob(Compilation &C, 6840b57cec5SDimitry Andric const JobAction &JA, 6850b57cec5SDimitry Andric const InputInfo &Output, 6860b57cec5SDimitry Andric const InputInfoList &Inputs, 6870b57cec5SDimitry Andric const ArgList &Args, 6880b57cec5SDimitry Andric const char *LinkingOutput) const { 6890b57cec5SDimitry Andric const auto &D = getToolChain().getDriver(); 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric claimNoWarnArgs(Args); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric ArgStringList CmdArgs; 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric llvm::Reloc::Model RelocationModel; 6960b57cec5SDimitry Andric unsigned PICLevel; 6970b57cec5SDimitry Andric bool IsPIE; 6985ffd83dbSDimitry Andric const char *DefaultAssembler = "as"; 6995f757f3fSDimitry Andric // Enforce GNU as on Solaris; the native assembler's input syntax isn't fully 7005f757f3fSDimitry Andric // compatible. 7015f757f3fSDimitry Andric if (getToolChain().getTriple().isOSSolaris()) 7025f757f3fSDimitry Andric DefaultAssembler = "gas"; 7030b57cec5SDimitry Andric std::tie(RelocationModel, PICLevel, IsPIE) = 7040b57cec5SDimitry Andric ParsePICArgs(getToolChain(), Args); 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) { 7070b57cec5SDimitry Andric if (A->getOption().getID() == options::OPT_gz) { 7080b57cec5SDimitry Andric CmdArgs.push_back("--compress-debug-sections"); 7090b57cec5SDimitry Andric } else { 7100b57cec5SDimitry Andric StringRef Value = A->getValue(); 711bdd1243dSDimitry Andric if (Value == "none" || Value == "zlib" || Value == "zstd") { 7120b57cec5SDimitry Andric CmdArgs.push_back( 7130b57cec5SDimitry Andric Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); 7140b57cec5SDimitry Andric } else { 7150b57cec5SDimitry Andric D.Diag(diag::err_drv_unsupported_option_argument) 716bdd1243dSDimitry Andric << A->getSpelling() << Value; 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric switch (getToolChain().getArch()) { 7220b57cec5SDimitry Andric default: 7230b57cec5SDimitry Andric break; 7240b57cec5SDimitry Andric // Add --32/--64 to make sure we get the format we want. 7250b57cec5SDimitry Andric // This is incomplete 7260b57cec5SDimitry Andric case llvm::Triple::x86: 7270b57cec5SDimitry Andric CmdArgs.push_back("--32"); 7280b57cec5SDimitry Andric break; 7290b57cec5SDimitry Andric case llvm::Triple::x86_64: 730fe6060f1SDimitry Andric if (getToolChain().getTriple().isX32()) 7310b57cec5SDimitry Andric CmdArgs.push_back("--x32"); 7320b57cec5SDimitry Andric else 7330b57cec5SDimitry Andric CmdArgs.push_back("--64"); 7340b57cec5SDimitry Andric break; 7350b57cec5SDimitry Andric case llvm::Triple::ppc: { 7360b57cec5SDimitry Andric CmdArgs.push_back("-a32"); 7370b57cec5SDimitry Andric CmdArgs.push_back("-mppc"); 738e8d8bef9SDimitry Andric CmdArgs.push_back("-mbig-endian"); 739349cc55cSDimitry Andric CmdArgs.push_back(ppc::getPPCAsmModeForCPU( 740349cc55cSDimitry Andric getCPUName(D, Args, getToolChain().getTriple()))); 741e8d8bef9SDimitry Andric break; 742e8d8bef9SDimitry Andric } 743e8d8bef9SDimitry Andric case llvm::Triple::ppcle: { 744e8d8bef9SDimitry Andric CmdArgs.push_back("-a32"); 745e8d8bef9SDimitry Andric CmdArgs.push_back("-mppc"); 746e8d8bef9SDimitry Andric CmdArgs.push_back("-mlittle-endian"); 747349cc55cSDimitry Andric CmdArgs.push_back(ppc::getPPCAsmModeForCPU( 748349cc55cSDimitry Andric getCPUName(D, Args, getToolChain().getTriple()))); 7490b57cec5SDimitry Andric break; 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric case llvm::Triple::ppc64: { 7520b57cec5SDimitry Andric CmdArgs.push_back("-a64"); 7530b57cec5SDimitry Andric CmdArgs.push_back("-mppc64"); 754e8d8bef9SDimitry Andric CmdArgs.push_back("-mbig-endian"); 755349cc55cSDimitry Andric CmdArgs.push_back(ppc::getPPCAsmModeForCPU( 756349cc55cSDimitry Andric getCPUName(D, Args, getToolChain().getTriple()))); 7570b57cec5SDimitry Andric break; 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric case llvm::Triple::ppc64le: { 7600b57cec5SDimitry Andric CmdArgs.push_back("-a64"); 7610b57cec5SDimitry Andric CmdArgs.push_back("-mppc64"); 7620b57cec5SDimitry Andric CmdArgs.push_back("-mlittle-endian"); 763349cc55cSDimitry Andric CmdArgs.push_back(ppc::getPPCAsmModeForCPU( 764349cc55cSDimitry Andric getCPUName(D, Args, getToolChain().getTriple()))); 7650b57cec5SDimitry Andric break; 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric case llvm::Triple::riscv32: 7680b57cec5SDimitry Andric case llvm::Triple::riscv64: { 7690b57cec5SDimitry Andric StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple()); 7700b57cec5SDimitry Andric CmdArgs.push_back("-mabi"); 7710b57cec5SDimitry Andric CmdArgs.push_back(ABIName.data()); 7720fca6ea1SDimitry Andric std::string MArchName = 7730fca6ea1SDimitry Andric riscv::getRISCVArch(Args, getToolChain().getTriple()); 7740b57cec5SDimitry Andric CmdArgs.push_back("-march"); 7750fca6ea1SDimitry Andric CmdArgs.push_back(Args.MakeArgString(MArchName)); 77681ad6265SDimitry Andric if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) 77781ad6265SDimitry Andric Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax); 7780b57cec5SDimitry Andric break; 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric case llvm::Triple::sparc: 7810b57cec5SDimitry Andric case llvm::Triple::sparcel: { 7820b57cec5SDimitry Andric CmdArgs.push_back("-32"); 783349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); 7840b57cec5SDimitry Andric CmdArgs.push_back( 7850b57cec5SDimitry Andric sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); 7860b57cec5SDimitry Andric AddAssemblerKPIC(getToolChain(), Args, CmdArgs); 7870b57cec5SDimitry Andric break; 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric case llvm::Triple::sparcv9: { 7900b57cec5SDimitry Andric CmdArgs.push_back("-64"); 791349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); 7920b57cec5SDimitry Andric CmdArgs.push_back( 7930b57cec5SDimitry Andric sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); 7940b57cec5SDimitry Andric AddAssemblerKPIC(getToolChain(), Args, CmdArgs); 7950b57cec5SDimitry Andric break; 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric case llvm::Triple::arm: 7980b57cec5SDimitry Andric case llvm::Triple::armeb: 7990b57cec5SDimitry Andric case llvm::Triple::thumb: 8000b57cec5SDimitry Andric case llvm::Triple::thumbeb: { 8010b57cec5SDimitry Andric const llvm::Triple &Triple2 = getToolChain().getTriple(); 80206c3fb27SDimitry Andric CmdArgs.push_back(arm::isARMBigEndian(Triple2, Args) ? "-EB" : "-EL"); 8030b57cec5SDimitry Andric switch (Triple2.getSubArch()) { 8040b57cec5SDimitry Andric case llvm::Triple::ARMSubArch_v7: 8050b57cec5SDimitry Andric CmdArgs.push_back("-mfpu=neon"); 8060b57cec5SDimitry Andric break; 8070b57cec5SDimitry Andric case llvm::Triple::ARMSubArch_v8: 8080b57cec5SDimitry Andric CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8"); 8090b57cec5SDimitry Andric break; 8100b57cec5SDimitry Andric default: 8110b57cec5SDimitry Andric break; 8120b57cec5SDimitry Andric } 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric switch (arm::getARMFloatABI(getToolChain(), Args)) { 8150b57cec5SDimitry Andric case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!"); 8160b57cec5SDimitry Andric case arm::FloatABI::Soft: 8170b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft")); 8180b57cec5SDimitry Andric break; 8190b57cec5SDimitry Andric case arm::FloatABI::SoftFP: 8200b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp")); 8210b57cec5SDimitry Andric break; 8220b57cec5SDimitry Andric case arm::FloatABI::Hard: 8230b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard")); 8240b57cec5SDimitry Andric break; 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_march_EQ); 8280b57cec5SDimitry Andric normalizeCPUNamesForAssembler(Args, CmdArgs); 8290b57cec5SDimitry Andric 8300b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); 83106c3fb27SDimitry Andric // The integrated assembler doesn't implement e_flags setting behavior for 83206c3fb27SDimitry Andric // -meabi=gnu (gcc -mabi={apcs-gnu,atpcs} passes -meabi=gnu to gas). For 83306c3fb27SDimitry Andric // compatibility we accept but warn. 83406c3fb27SDimitry Andric if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ)) 83506c3fb27SDimitry Andric A->ignoreTargetSpecific(); 8360b57cec5SDimitry Andric break; 8370b57cec5SDimitry Andric } 8380b57cec5SDimitry Andric case llvm::Triple::aarch64: 8390b57cec5SDimitry Andric case llvm::Triple::aarch64_be: { 8400b57cec5SDimitry Andric CmdArgs.push_back( 8410b57cec5SDimitry Andric getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL"); 8420b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_march_EQ); 8430b57cec5SDimitry Andric normalizeCPUNamesForAssembler(Args, CmdArgs); 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric break; 8460b57cec5SDimitry Andric } 84706c3fb27SDimitry Andric // TODO: handle loongarch32. 84806c3fb27SDimitry Andric case llvm::Triple::loongarch64: { 84906c3fb27SDimitry Andric StringRef ABIName = 85006c3fb27SDimitry Andric loongarch::getLoongArchABI(D, Args, getToolChain().getTriple()); 85106c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName)); 85206c3fb27SDimitry Andric break; 85306c3fb27SDimitry Andric } 8540b57cec5SDimitry Andric case llvm::Triple::mips: 8550b57cec5SDimitry Andric case llvm::Triple::mipsel: 8560b57cec5SDimitry Andric case llvm::Triple::mips64: 8570b57cec5SDimitry Andric case llvm::Triple::mips64el: { 8580b57cec5SDimitry Andric StringRef CPUName; 8590b57cec5SDimitry Andric StringRef ABIName; 8600b57cec5SDimitry Andric mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); 8610b57cec5SDimitry Andric ABIName = mips::getGnuCompatibleMipsABIName(ABIName); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric CmdArgs.push_back("-march"); 8640b57cec5SDimitry Andric CmdArgs.push_back(CPUName.data()); 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric CmdArgs.push_back("-mabi"); 8670b57cec5SDimitry Andric CmdArgs.push_back(ABIName.data()); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE, 8700b57cec5SDimitry Andric // or -mshared (not implemented) is in effect. 8710b57cec5SDimitry Andric if (RelocationModel == llvm::Reloc::Static) 8720b57cec5SDimitry Andric CmdArgs.push_back("-mno-shared"); 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric // LLVM doesn't support -mplt yet and acts as if it is always given. 8750b57cec5SDimitry Andric // However, -mplt has no effect with the N64 ABI. 8760b57cec5SDimitry Andric if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls)) 8770b57cec5SDimitry Andric CmdArgs.push_back("-call_nonpic"); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric if (getToolChain().getTriple().isLittleEndian()) 8800b57cec5SDimitry Andric CmdArgs.push_back("-EL"); 8810b57cec5SDimitry Andric else 8820b57cec5SDimitry Andric CmdArgs.push_back("-EB"); 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { 8850b57cec5SDimitry Andric if (StringRef(A->getValue()) == "2008") 8860b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mnan=2008")); 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default. 8900b57cec5SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, 8910b57cec5SDimitry Andric options::OPT_mfp64)) { 8920b57cec5SDimitry Andric A->claim(); 8930b57cec5SDimitry Andric A->render(Args, CmdArgs); 8940b57cec5SDimitry Andric } else if (mips::shouldUseFPXX( 8950b57cec5SDimitry Andric Args, getToolChain().getTriple(), CPUName, ABIName, 8960b57cec5SDimitry Andric mips::getMipsFloatABI(getToolChain().getDriver(), Args, 8970b57cec5SDimitry Andric getToolChain().getTriple()))) 8980b57cec5SDimitry Andric CmdArgs.push_back("-mfpxx"); 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of 9010b57cec5SDimitry Andric // -mno-mips16 is actually -no-mips16. 9020b57cec5SDimitry Andric if (Arg *A = 9030b57cec5SDimitry Andric Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) { 9040b57cec5SDimitry Andric if (A->getOption().matches(options::OPT_mips16)) { 9050b57cec5SDimitry Andric A->claim(); 9060b57cec5SDimitry Andric A->render(Args, CmdArgs); 9070b57cec5SDimitry Andric } else { 9080b57cec5SDimitry Andric A->claim(); 9090b57cec5SDimitry Andric CmdArgs.push_back("-no-mips16"); 9100b57cec5SDimitry Andric } 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mmicromips, 9140b57cec5SDimitry Andric options::OPT_mno_micromips); 9150b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp); 9160b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2); 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) { 9190b57cec5SDimitry Andric // Do not use AddLastArg because not all versions of MIPS assembler 9200b57cec5SDimitry Andric // support -mmsa / -mno-msa options. 9210b57cec5SDimitry Andric if (A->getOption().matches(options::OPT_mmsa)) 9220b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mmsa")); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mhard_float, 9260b57cec5SDimitry Andric options::OPT_msoft_float); 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_mdouble_float, 9290b57cec5SDimitry Andric options::OPT_msingle_float); 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_modd_spreg, 9320b57cec5SDimitry Andric options::OPT_mno_odd_spreg); 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric AddAssemblerKPIC(getToolChain(), Args, CmdArgs); 9350b57cec5SDimitry Andric break; 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric case llvm::Triple::systemz: { 9380b57cec5SDimitry Andric // Always pass an -march option, since our default of z10 is later 9390b57cec5SDimitry Andric // than the GNU assembler's default. 940480093f4SDimitry Andric std::string CPUName = systemz::getSystemZTargetCPU(Args); 9410b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); 9420b57cec5SDimitry Andric break; 9430b57cec5SDimitry Andric } 9445ffd83dbSDimitry Andric case llvm::Triple::ve: 9455ffd83dbSDimitry Andric DefaultAssembler = "nas"; 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 948480093f4SDimitry Andric for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ, 949480093f4SDimitry Andric options::OPT_fdebug_prefix_map_EQ)) { 950480093f4SDimitry Andric StringRef Map = A->getValue(); 951349cc55cSDimitry Andric if (!Map.contains('=')) 952480093f4SDimitry Andric D.Diag(diag::err_drv_invalid_argument_to_option) 953480093f4SDimitry Andric << Map << A->getOption().getName(); 954480093f4SDimitry Andric else { 955480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map")); 956480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Map)); 957480093f4SDimitry Andric } 958480093f4SDimitry Andric A->claim(); 959480093f4SDimitry Andric } 960480093f4SDimitry Andric 9610b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_I); 9620b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric CmdArgs.push_back("-o"); 9650b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric for (const auto &II : Inputs) 9680b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename()); 9690b57cec5SDimitry Andric 970bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group, 971bdd1243dSDimitry Andric options::OPT_gdwarf_2, options::OPT_gdwarf_3, 972bdd1243dSDimitry Andric options::OPT_gdwarf_4, options::OPT_gdwarf_5, 973bdd1243dSDimitry Andric options::OPT_gdwarf)) 974bdd1243dSDimitry Andric if (!A->getOption().matches(options::OPT_g0)) { 975bdd1243dSDimitry Andric Args.AddLastArg(CmdArgs, options::OPT_g_Flag); 976bdd1243dSDimitry Andric 977bdd1243dSDimitry Andric unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args); 978bdd1243dSDimitry Andric CmdArgs.push_back(Args.MakeArgString("-gdwarf-" + Twine(DwarfVersion))); 979bdd1243dSDimitry Andric } 980bdd1243dSDimitry Andric 9815ffd83dbSDimitry Andric const char *Exec = 9825ffd83dbSDimitry Andric Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler)); 983e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 984e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 985e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric // Handle the debug info splitting at object creation time if we're 9880b57cec5SDimitry Andric // creating an object. 9890b57cec5SDimitry Andric // TODO: Currently only works on linux with newer objcopy. 9900b57cec5SDimitry Andric if (Args.hasArg(options::OPT_gsplit_dwarf) && 9910b57cec5SDimitry Andric getToolChain().getTriple().isOSLinux()) 9920b57cec5SDimitry Andric SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, 993e8d8bef9SDimitry Andric SplitDebugName(JA, Args, Inputs[0], Output)); 9940b57cec5SDimitry Andric } 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric namespace { 9970b57cec5SDimitry Andric // Filter to remove Multilibs that don't exist as a suffix to Path 9980b57cec5SDimitry Andric class FilterNonExistent { 9990b57cec5SDimitry Andric StringRef Base, File; 10000b57cec5SDimitry Andric llvm::vfs::FileSystem &VFS; 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric public: 10030b57cec5SDimitry Andric FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS) 10040b57cec5SDimitry Andric : Base(Base), File(File), VFS(VFS) {} 10050b57cec5SDimitry Andric bool operator()(const Multilib &M) { 10060b57cec5SDimitry Andric return !VFS.exists(Base + M.gccSuffix() + File); 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric }; 10090b57cec5SDimitry Andric } // end anonymous namespace 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric static bool isSoftFloatABI(const ArgList &Args) { 10120b57cec5SDimitry Andric Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 10130b57cec5SDimitry Andric options::OPT_mfloat_abi_EQ); 10140b57cec5SDimitry Andric if (!A) 10150b57cec5SDimitry Andric return false; 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric return A->getOption().matches(options::OPT_msoft_float) || 10180b57cec5SDimitry Andric (A->getOption().matches(options::OPT_mfloat_abi_EQ) && 10190b57cec5SDimitry Andric A->getValue() == StringRef("soft")); 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) { 10230b57cec5SDimitry Andric return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric static bool isMipsEL(llvm::Triple::ArchType Arch) { 10270b57cec5SDimitry Andric return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el; 10280b57cec5SDimitry Andric } 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric static bool isMips16(const ArgList &Args) { 10310b57cec5SDimitry Andric Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); 10320b57cec5SDimitry Andric return A && A->getOption().matches(options::OPT_mips16); 10330b57cec5SDimitry Andric } 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric static bool isMicroMips(const ArgList &Args) { 10360b57cec5SDimitry Andric Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); 10370b57cec5SDimitry Andric return A && A->getOption().matches(options::OPT_mmicromips); 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric static bool isMSP430(llvm::Triple::ArchType Arch) { 10410b57cec5SDimitry Andric return Arch == llvm::Triple::msp430; 10420b57cec5SDimitry Andric } 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric static bool findMipsCsMultilibs(const Multilib::flags_list &Flags, 10450b57cec5SDimitry Andric FilterNonExistent &NonExistent, 10460b57cec5SDimitry Andric DetectedMultilibs &Result) { 10470b57cec5SDimitry Andric // Check for Code Sourcery toolchain multilibs 10480b57cec5SDimitry Andric MultilibSet CSMipsMultilibs; 10490b57cec5SDimitry Andric { 105006c3fb27SDimitry Andric auto MArchMips16 = MultilibBuilder("/mips16").flag("-m32").flag("-mips16"); 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric auto MArchMicroMips = 105306c3fb27SDimitry Andric MultilibBuilder("/micromips").flag("-m32").flag("-mmicromips"); 10540b57cec5SDimitry Andric 105506c3fb27SDimitry Andric auto MArchDefault = MultilibBuilder("") 105606c3fb27SDimitry Andric .flag("-mips16", /*Disallow=*/true) 105706c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 10580b57cec5SDimitry Andric 105906c3fb27SDimitry Andric auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc"); 10600b57cec5SDimitry Andric 106106c3fb27SDimitry Andric auto SoftFloat = MultilibBuilder("/soft-float").flag("-msoft-float"); 10620b57cec5SDimitry Andric 106306c3fb27SDimitry Andric auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008"); 10640b57cec5SDimitry Andric 106506c3fb27SDimitry Andric auto DefaultFloat = MultilibBuilder("") 106606c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 106706c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true); 10680b57cec5SDimitry Andric 106906c3fb27SDimitry Andric auto BigEndian = 107006c3fb27SDimitry Andric MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true); 10710b57cec5SDimitry Andric 107206c3fb27SDimitry Andric auto LittleEndian = 107306c3fb27SDimitry Andric MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andric // Note that this one's osSuffix is "" 107606c3fb27SDimitry Andric auto MAbi64 = MultilibBuilder("") 10770b57cec5SDimitry Andric .gccSuffix("/64") 10780b57cec5SDimitry Andric .includeSuffix("/64") 107906c3fb27SDimitry Andric .flag("-mabi=n64") 108006c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 108106c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true); 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric CSMipsMultilibs = 108406c3fb27SDimitry Andric MultilibSetBuilder() 10850b57cec5SDimitry Andric .Either(MArchMips16, MArchMicroMips, MArchDefault) 10860b57cec5SDimitry Andric .Maybe(UCLibc) 10870b57cec5SDimitry Andric .Either(SoftFloat, Nan2008, DefaultFloat) 10880b57cec5SDimitry Andric .FilterOut("/micromips/nan2008") 10890b57cec5SDimitry Andric .FilterOut("/mips16/nan2008") 10900b57cec5SDimitry Andric .Either(BigEndian, LittleEndian) 10910b57cec5SDimitry Andric .Maybe(MAbi64) 10920b57cec5SDimitry Andric .FilterOut("/mips16.*/64") 10930b57cec5SDimitry Andric .FilterOut("/micromips.*/64") 109406c3fb27SDimitry Andric .makeMultilibSet() 10950b57cec5SDimitry Andric .FilterOut(NonExistent) 10960b57cec5SDimitry Andric .setIncludeDirsCallback([](const Multilib &M) { 10970b57cec5SDimitry Andric std::vector<std::string> Dirs({"/include"}); 10985f757f3fSDimitry Andric if (StringRef(M.includeSuffix()).starts_with("/uclibc")) 10990b57cec5SDimitry Andric Dirs.push_back( 11000b57cec5SDimitry Andric "/../../../../mips-linux-gnu/libc/uclibc/usr/include"); 11010b57cec5SDimitry Andric else 11020b57cec5SDimitry Andric Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include"); 11030b57cec5SDimitry Andric return Dirs; 11040b57cec5SDimitry Andric }); 11050b57cec5SDimitry Andric } 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andric MultilibSet DebianMipsMultilibs; 11080b57cec5SDimitry Andric { 110906c3fb27SDimitry Andric MultilibBuilder MAbiN32 = 111006c3fb27SDimitry Andric MultilibBuilder().gccSuffix("/n32").includeSuffix("/n32").flag( 111106c3fb27SDimitry Andric "-mabi=n32"); 11120b57cec5SDimitry Andric 111306c3fb27SDimitry Andric MultilibBuilder M64 = MultilibBuilder() 11140b57cec5SDimitry Andric .gccSuffix("/64") 11150b57cec5SDimitry Andric .includeSuffix("/64") 111606c3fb27SDimitry Andric .flag("-m64") 111706c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true) 111806c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true); 111906c3fb27SDimitry Andric 112006c3fb27SDimitry Andric MultilibBuilder M32 = MultilibBuilder() 112106c3fb27SDimitry Andric .gccSuffix("/32") 112206c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 11230b57cec5SDimitry Andric .flag("-m32") 112406c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true); 11250b57cec5SDimitry Andric 112606c3fb27SDimitry Andric DebianMipsMultilibs = MultilibSetBuilder() 112706c3fb27SDimitry Andric .Either(M32, M64, MAbiN32) 112806c3fb27SDimitry Andric .makeMultilibSet() 112906c3fb27SDimitry Andric .FilterOut(NonExistent); 11300b57cec5SDimitry Andric } 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric // Sort candidates. Toolchain that best meets the directories tree goes first. 11330b57cec5SDimitry Andric // Then select the first toolchains matches command line flags. 11340b57cec5SDimitry Andric MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs}; 11350b57cec5SDimitry Andric if (CSMipsMultilibs.size() < DebianMipsMultilibs.size()) 11360b57cec5SDimitry Andric std::iter_swap(Candidates, Candidates + 1); 11370b57cec5SDimitry Andric for (const MultilibSet *Candidate : Candidates) { 113806c3fb27SDimitry Andric if (Candidate->select(Flags, Result.SelectedMultilibs)) { 11390b57cec5SDimitry Andric if (Candidate == &DebianMipsMultilibs) 11400b57cec5SDimitry Andric Result.BiarchSibling = Multilib(); 11410b57cec5SDimitry Andric Result.Multilibs = *Candidate; 11420b57cec5SDimitry Andric return true; 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric return false; 11460b57cec5SDimitry Andric } 11470b57cec5SDimitry Andric 11480b57cec5SDimitry Andric static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path, 11490b57cec5SDimitry Andric const Multilib::flags_list &Flags, 11500b57cec5SDimitry Andric FilterNonExistent &NonExistent, 11510b57cec5SDimitry Andric DetectedMultilibs &Result) { 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric MultilibSet AndroidMipsMultilibs = 115406c3fb27SDimitry Andric MultilibSetBuilder() 115506c3fb27SDimitry Andric .Maybe(MultilibBuilder("/mips-r2", {}, {}).flag("-march=mips32r2")) 115606c3fb27SDimitry Andric .Maybe(MultilibBuilder("/mips-r6", {}, {}).flag("-march=mips32r6")) 115706c3fb27SDimitry Andric .makeMultilibSet() 11580b57cec5SDimitry Andric .FilterOut(NonExistent); 11590b57cec5SDimitry Andric 11600b57cec5SDimitry Andric MultilibSet AndroidMipselMultilibs = 116106c3fb27SDimitry Andric MultilibSetBuilder() 116206c3fb27SDimitry Andric .Either(MultilibBuilder().flag("-march=mips32"), 116306c3fb27SDimitry Andric MultilibBuilder("/mips-r2", "", "/mips-r2") 116406c3fb27SDimitry Andric .flag("-march=mips32r2"), 116506c3fb27SDimitry Andric MultilibBuilder("/mips-r6", "", "/mips-r6") 116606c3fb27SDimitry Andric .flag("-march=mips32r6")) 116706c3fb27SDimitry Andric .makeMultilibSet() 11680b57cec5SDimitry Andric .FilterOut(NonExistent); 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric MultilibSet AndroidMips64elMultilibs = 117106c3fb27SDimitry Andric MultilibSetBuilder() 117206c3fb27SDimitry Andric .Either(MultilibBuilder().flag("-march=mips64r6"), 117306c3fb27SDimitry Andric MultilibBuilder("/32/mips-r1", "", "/mips-r1") 117406c3fb27SDimitry Andric .flag("-march=mips32"), 117506c3fb27SDimitry Andric MultilibBuilder("/32/mips-r2", "", "/mips-r2") 117606c3fb27SDimitry Andric .flag("-march=mips32r2"), 117706c3fb27SDimitry Andric MultilibBuilder("/32/mips-r6", "", "/mips-r6") 117806c3fb27SDimitry Andric .flag("-march=mips32r6")) 117906c3fb27SDimitry Andric .makeMultilibSet() 11800b57cec5SDimitry Andric .FilterOut(NonExistent); 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric MultilibSet *MS = &AndroidMipsMultilibs; 11830b57cec5SDimitry Andric if (VFS.exists(Path + "/mips-r6")) 11840b57cec5SDimitry Andric MS = &AndroidMipselMultilibs; 11850b57cec5SDimitry Andric else if (VFS.exists(Path + "/32")) 11860b57cec5SDimitry Andric MS = &AndroidMips64elMultilibs; 118706c3fb27SDimitry Andric if (MS->select(Flags, Result.SelectedMultilibs)) { 11880b57cec5SDimitry Andric Result.Multilibs = *MS; 11890b57cec5SDimitry Andric return true; 11900b57cec5SDimitry Andric } 11910b57cec5SDimitry Andric return false; 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags, 11950b57cec5SDimitry Andric FilterNonExistent &NonExistent, 11960b57cec5SDimitry Andric DetectedMultilibs &Result) { 11970b57cec5SDimitry Andric // Musl toolchain multilibs 11980b57cec5SDimitry Andric MultilibSet MuslMipsMultilibs; 11990b57cec5SDimitry Andric { 120006c3fb27SDimitry Andric auto MArchMipsR2 = MultilibBuilder("") 12010b57cec5SDimitry Andric .osSuffix("/mips-r2-hard-musl") 12020b57cec5SDimitry Andric .flag("-EB") 120306c3fb27SDimitry Andric .flag("-EL", /*Disallow=*/true) 120406c3fb27SDimitry Andric .flag("-march=mips32r2"); 12050b57cec5SDimitry Andric 120606c3fb27SDimitry Andric auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl") 120706c3fb27SDimitry Andric .flag("-EB", /*Disallow=*/true) 120806c3fb27SDimitry Andric .flag("-EL") 120906c3fb27SDimitry Andric .flag("-march=mips32r2"); 121006c3fb27SDimitry Andric 121106c3fb27SDimitry Andric MuslMipsMultilibs = MultilibSetBuilder() 121206c3fb27SDimitry Andric .Either(MArchMipsR2, MArchMipselR2) 121306c3fb27SDimitry Andric .makeMultilibSet(); 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric // Specify the callback that computes the include directories. 12160b57cec5SDimitry Andric MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) { 12170b57cec5SDimitry Andric return std::vector<std::string>( 12180b57cec5SDimitry Andric {"/../sysroot" + M.osSuffix() + "/usr/include"}); 12190b57cec5SDimitry Andric }); 12200b57cec5SDimitry Andric } 122106c3fb27SDimitry Andric if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) { 12220b57cec5SDimitry Andric Result.Multilibs = MuslMipsMultilibs; 12230b57cec5SDimitry Andric return true; 12240b57cec5SDimitry Andric } 12250b57cec5SDimitry Andric return false; 12260b57cec5SDimitry Andric } 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags, 12290b57cec5SDimitry Andric FilterNonExistent &NonExistent, 12300b57cec5SDimitry Andric DetectedMultilibs &Result) { 12310b57cec5SDimitry Andric // CodeScape MTI toolchain v1.2 and early. 12320b57cec5SDimitry Andric MultilibSet MtiMipsMultilibsV1; 12330b57cec5SDimitry Andric { 123406c3fb27SDimitry Andric auto MArchMips32 = MultilibBuilder("/mips32") 12350b57cec5SDimitry Andric .flag("-m32") 123606c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 123706c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true) 123806c3fb27SDimitry Andric .flag("-march=mips32"); 12390b57cec5SDimitry Andric 124006c3fb27SDimitry Andric auto MArchMicroMips = MultilibBuilder("/micromips") 124106c3fb27SDimitry Andric .flag("-m32") 124206c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 124306c3fb27SDimitry Andric .flag("-mmicromips"); 12440b57cec5SDimitry Andric 124506c3fb27SDimitry Andric auto MArchMips64r2 = MultilibBuilder("/mips64r2") 124606c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true) 12470b57cec5SDimitry Andric .flag("-m64") 124806c3fb27SDimitry Andric .flag("-march=mips64r2"); 12490b57cec5SDimitry Andric 125006c3fb27SDimitry Andric auto MArchMips64 = MultilibBuilder("/mips64") 125106c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true) 125206c3fb27SDimitry Andric .flag("-m64") 125306c3fb27SDimitry Andric .flag("-march=mips64r2", /*Disallow=*/true); 12540b57cec5SDimitry Andric 125506c3fb27SDimitry Andric auto MArchDefault = MultilibBuilder("") 125606c3fb27SDimitry Andric .flag("-m32") 125706c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 125806c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true) 125906c3fb27SDimitry Andric .flag("-march=mips32r2"); 12600b57cec5SDimitry Andric 126106c3fb27SDimitry Andric auto Mips16 = MultilibBuilder("/mips16").flag("-mips16"); 12620b57cec5SDimitry Andric 126306c3fb27SDimitry Andric auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc"); 12640b57cec5SDimitry Andric 126506c3fb27SDimitry Andric auto MAbi64 = MultilibBuilder("/64") 126606c3fb27SDimitry Andric .flag("-mabi=n64") 126706c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 126806c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true); 12690b57cec5SDimitry Andric 127006c3fb27SDimitry Andric auto BigEndian = 127106c3fb27SDimitry Andric MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true); 12720b57cec5SDimitry Andric 127306c3fb27SDimitry Andric auto LittleEndian = 127406c3fb27SDimitry Andric MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); 127506c3fb27SDimitry Andric 127606c3fb27SDimitry Andric auto SoftFloat = MultilibBuilder("/sof").flag("-msoft-float"); 127706c3fb27SDimitry Andric 127806c3fb27SDimitry Andric auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008"); 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric MtiMipsMultilibsV1 = 128106c3fb27SDimitry Andric MultilibSetBuilder() 12820b57cec5SDimitry Andric .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64, 12830b57cec5SDimitry Andric MArchDefault) 12840b57cec5SDimitry Andric .Maybe(UCLibc) 12850b57cec5SDimitry Andric .Maybe(Mips16) 12860b57cec5SDimitry Andric .FilterOut("/mips64/mips16") 12870b57cec5SDimitry Andric .FilterOut("/mips64r2/mips16") 12880b57cec5SDimitry Andric .FilterOut("/micromips/mips16") 12890b57cec5SDimitry Andric .Maybe(MAbi64) 12900b57cec5SDimitry Andric .FilterOut("/micromips/64") 12910b57cec5SDimitry Andric .FilterOut("/mips32/64") 12920b57cec5SDimitry Andric .FilterOut("^/64") 12930b57cec5SDimitry Andric .FilterOut("/mips16/64") 12940b57cec5SDimitry Andric .Either(BigEndian, LittleEndian) 12950b57cec5SDimitry Andric .Maybe(SoftFloat) 12960b57cec5SDimitry Andric .Maybe(Nan2008) 12970b57cec5SDimitry Andric .FilterOut(".*sof/nan2008") 129806c3fb27SDimitry Andric .makeMultilibSet() 12990b57cec5SDimitry Andric .FilterOut(NonExistent) 13000b57cec5SDimitry Andric .setIncludeDirsCallback([](const Multilib &M) { 13010b57cec5SDimitry Andric std::vector<std::string> Dirs({"/include"}); 13025f757f3fSDimitry Andric if (StringRef(M.includeSuffix()).starts_with("/uclibc")) 13030b57cec5SDimitry Andric Dirs.push_back("/../../../../sysroot/uclibc/usr/include"); 13040b57cec5SDimitry Andric else 13050b57cec5SDimitry Andric Dirs.push_back("/../../../../sysroot/usr/include"); 13060b57cec5SDimitry Andric return Dirs; 13070b57cec5SDimitry Andric }); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric // CodeScape IMG toolchain starting from v1.3. 13110b57cec5SDimitry Andric MultilibSet MtiMipsMultilibsV2; 13120b57cec5SDimitry Andric { 131306c3fb27SDimitry Andric auto BeHard = MultilibBuilder("/mips-r2-hard") 131406c3fb27SDimitry Andric .flag("-EB") 131506c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 131606c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 131706c3fb27SDimitry Andric .flag("-muclibc", /*Disallow=*/true); 131806c3fb27SDimitry Andric auto BeSoft = MultilibBuilder("/mips-r2-soft") 131906c3fb27SDimitry Andric .flag("-EB") 13200b57cec5SDimitry Andric .flag("-msoft-float") 132106c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true); 132206c3fb27SDimitry Andric auto ElHard = MultilibBuilder("/mipsel-r2-hard") 132306c3fb27SDimitry Andric .flag("-EL") 132406c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 132506c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 132606c3fb27SDimitry Andric .flag("-muclibc", /*Disallow=*/true); 132706c3fb27SDimitry Andric auto ElSoft = MultilibBuilder("/mipsel-r2-soft") 132806c3fb27SDimitry Andric .flag("-EL") 132906c3fb27SDimitry Andric .flag("-msoft-float") 133006c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 133106c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 133206c3fb27SDimitry Andric auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008") 133306c3fb27SDimitry Andric .flag("-EB") 133406c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 133506c3fb27SDimitry Andric .flag("-mnan=2008") 133606c3fb27SDimitry Andric .flag("-muclibc", /*Disallow=*/true); 133706c3fb27SDimitry Andric auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008") 133806c3fb27SDimitry Andric .flag("-EL") 133906c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 134006c3fb27SDimitry Andric .flag("-mnan=2008") 134106c3fb27SDimitry Andric .flag("-muclibc", /*Disallow=*/true) 134206c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 134306c3fb27SDimitry Andric auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc") 134406c3fb27SDimitry Andric .flag("-EB") 134506c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 13460b57cec5SDimitry Andric .flag("-mnan=2008") 13470b57cec5SDimitry Andric .flag("-muclibc"); 134806c3fb27SDimitry Andric auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc") 134906c3fb27SDimitry Andric .flag("-EL") 135006c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 13510b57cec5SDimitry Andric .flag("-mnan=2008") 13520b57cec5SDimitry Andric .flag("-muclibc"); 135306c3fb27SDimitry Andric auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc") 135406c3fb27SDimitry Andric .flag("-EB") 135506c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 135606c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 135706c3fb27SDimitry Andric .flag("-muclibc"); 135806c3fb27SDimitry Andric auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc") 135906c3fb27SDimitry Andric .flag("-EL") 136006c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 136106c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 136206c3fb27SDimitry Andric .flag("-muclibc"); 136306c3fb27SDimitry Andric auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008") 136406c3fb27SDimitry Andric .flag("-EL") 136506c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 13660b57cec5SDimitry Andric .flag("-mnan=2008") 13670b57cec5SDimitry Andric .flag("-mmicromips"); 136806c3fb27SDimitry Andric auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft") 136906c3fb27SDimitry Andric .flag("-EL") 13700b57cec5SDimitry Andric .flag("-msoft-float") 137106c3fb27SDimitry Andric .flag("-mnan=2008", /*Disallow=*/true) 13720b57cec5SDimitry Andric .flag("-mmicromips"); 13730b57cec5SDimitry Andric 137406c3fb27SDimitry Andric auto O32 = MultilibBuilder("/lib") 137506c3fb27SDimitry Andric .osSuffix("") 137606c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 137706c3fb27SDimitry Andric .flag("-mabi=n64", /*Disallow=*/true); 137806c3fb27SDimitry Andric auto N32 = MultilibBuilder("/lib32") 137906c3fb27SDimitry Andric .osSuffix("") 138006c3fb27SDimitry Andric .flag("-mabi=n32") 138106c3fb27SDimitry Andric .flag("-mabi=n64", /*Disallow=*/true); 138206c3fb27SDimitry Andric auto N64 = MultilibBuilder("/lib64") 138306c3fb27SDimitry Andric .osSuffix("") 138406c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 138506c3fb27SDimitry Andric .flag("-mabi=n64"); 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric MtiMipsMultilibsV2 = 138806c3fb27SDimitry Andric MultilibSetBuilder() 13890b57cec5SDimitry Andric .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan, 13900b57cec5SDimitry Andric BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc, 13910b57cec5SDimitry Andric ElHardUclibc, ElMicroHardNan, ElMicroSoft}) 13920b57cec5SDimitry Andric .Either(O32, N32, N64) 139306c3fb27SDimitry Andric .makeMultilibSet() 13940b57cec5SDimitry Andric .FilterOut(NonExistent) 13950b57cec5SDimitry Andric .setIncludeDirsCallback([](const Multilib &M) { 13960b57cec5SDimitry Andric return std::vector<std::string>({"/../../../../sysroot" + 13970b57cec5SDimitry Andric M.includeSuffix() + 13980b57cec5SDimitry Andric "/../usr/include"}); 13990b57cec5SDimitry Andric }) 14000b57cec5SDimitry Andric .setFilePathsCallback([](const Multilib &M) { 14010b57cec5SDimitry Andric return std::vector<std::string>( 14020b57cec5SDimitry Andric {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()}); 14030b57cec5SDimitry Andric }); 14040b57cec5SDimitry Andric } 1405bdd1243dSDimitry Andric for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) { 140606c3fb27SDimitry Andric if (Candidate->select(Flags, Result.SelectedMultilibs)) { 14070b57cec5SDimitry Andric Result.Multilibs = *Candidate; 14080b57cec5SDimitry Andric return true; 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric return false; 14120b57cec5SDimitry Andric } 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric static bool findMipsImgMultilibs(const Multilib::flags_list &Flags, 14150b57cec5SDimitry Andric FilterNonExistent &NonExistent, 14160b57cec5SDimitry Andric DetectedMultilibs &Result) { 14170b57cec5SDimitry Andric // CodeScape IMG toolchain v1.2 and early. 14180b57cec5SDimitry Andric MultilibSet ImgMultilibsV1; 14190b57cec5SDimitry Andric { 142006c3fb27SDimitry Andric auto Mips64r6 = MultilibBuilder("/mips64r6") 142106c3fb27SDimitry Andric .flag("-m64") 142206c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true); 14230b57cec5SDimitry Andric 142406c3fb27SDimitry Andric auto LittleEndian = 142506c3fb27SDimitry Andric MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); 14260b57cec5SDimitry Andric 142706c3fb27SDimitry Andric auto MAbi64 = MultilibBuilder("/64") 142806c3fb27SDimitry Andric .flag("-mabi=n64") 142906c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 143006c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true); 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric ImgMultilibsV1 = 143306c3fb27SDimitry Andric MultilibSetBuilder() 14340b57cec5SDimitry Andric .Maybe(Mips64r6) 14350b57cec5SDimitry Andric .Maybe(MAbi64) 14360b57cec5SDimitry Andric .Maybe(LittleEndian) 143706c3fb27SDimitry Andric .makeMultilibSet() 14380b57cec5SDimitry Andric .FilterOut(NonExistent) 14390b57cec5SDimitry Andric .setIncludeDirsCallback([](const Multilib &M) { 14400b57cec5SDimitry Andric return std::vector<std::string>( 14410b57cec5SDimitry Andric {"/include", "/../../../../sysroot/usr/include"}); 14420b57cec5SDimitry Andric }); 14430b57cec5SDimitry Andric } 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric // CodeScape IMG toolchain starting from v1.3. 14460b57cec5SDimitry Andric MultilibSet ImgMultilibsV2; 14470b57cec5SDimitry Andric { 144806c3fb27SDimitry Andric auto BeHard = MultilibBuilder("/mips-r6-hard") 144906c3fb27SDimitry Andric .flag("-EB") 145006c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 145106c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 145206c3fb27SDimitry Andric auto BeSoft = MultilibBuilder("/mips-r6-soft") 145306c3fb27SDimitry Andric .flag("-EB") 145406c3fb27SDimitry Andric .flag("-msoft-float") 145506c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 145606c3fb27SDimitry Andric auto ElHard = MultilibBuilder("/mipsel-r6-hard") 145706c3fb27SDimitry Andric .flag("-EL") 145806c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 145906c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 146006c3fb27SDimitry Andric auto ElSoft = MultilibBuilder("/mipsel-r6-soft") 146106c3fb27SDimitry Andric .flag("-EL") 146206c3fb27SDimitry Andric .flag("-msoft-float") 146306c3fb27SDimitry Andric .flag("-mmicromips", /*Disallow=*/true); 146406c3fb27SDimitry Andric auto BeMicroHard = MultilibBuilder("/micromips-r6-hard") 146506c3fb27SDimitry Andric .flag("-EB") 146606c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 146706c3fb27SDimitry Andric .flag("-mmicromips"); 146806c3fb27SDimitry Andric auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft") 146906c3fb27SDimitry Andric .flag("-EB") 14700b57cec5SDimitry Andric .flag("-msoft-float") 14710b57cec5SDimitry Andric .flag("-mmicromips"); 147206c3fb27SDimitry Andric auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard") 147306c3fb27SDimitry Andric .flag("-EL") 147406c3fb27SDimitry Andric .flag("-msoft-float", /*Disallow=*/true) 14750b57cec5SDimitry Andric .flag("-mmicromips"); 147606c3fb27SDimitry Andric auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft") 147706c3fb27SDimitry Andric .flag("-EL") 14780b57cec5SDimitry Andric .flag("-msoft-float") 14790b57cec5SDimitry Andric .flag("-mmicromips"); 14800b57cec5SDimitry Andric 148106c3fb27SDimitry Andric auto O32 = MultilibBuilder("/lib") 148206c3fb27SDimitry Andric .osSuffix("") 148306c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 148406c3fb27SDimitry Andric .flag("-mabi=n64", /*Disallow=*/true); 148506c3fb27SDimitry Andric auto N32 = MultilibBuilder("/lib32") 148606c3fb27SDimitry Andric .osSuffix("") 148706c3fb27SDimitry Andric .flag("-mabi=n32") 148806c3fb27SDimitry Andric .flag("-mabi=n64", /*Disallow=*/true); 148906c3fb27SDimitry Andric auto N64 = MultilibBuilder("/lib64") 149006c3fb27SDimitry Andric .osSuffix("") 149106c3fb27SDimitry Andric .flag("-mabi=n32", /*Disallow=*/true) 149206c3fb27SDimitry Andric .flag("-mabi=n64"); 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric ImgMultilibsV2 = 149506c3fb27SDimitry Andric MultilibSetBuilder() 14960b57cec5SDimitry Andric .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft, 14970b57cec5SDimitry Andric ElMicroHard, ElMicroSoft}) 14980b57cec5SDimitry Andric .Either(O32, N32, N64) 149906c3fb27SDimitry Andric .makeMultilibSet() 15000b57cec5SDimitry Andric .FilterOut(NonExistent) 15010b57cec5SDimitry Andric .setIncludeDirsCallback([](const Multilib &M) { 15020b57cec5SDimitry Andric return std::vector<std::string>({"/../../../../sysroot" + 15030b57cec5SDimitry Andric M.includeSuffix() + 15040b57cec5SDimitry Andric "/../usr/include"}); 15050b57cec5SDimitry Andric }) 15060b57cec5SDimitry Andric .setFilePathsCallback([](const Multilib &M) { 15070b57cec5SDimitry Andric return std::vector<std::string>( 15080b57cec5SDimitry Andric {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()}); 15090b57cec5SDimitry Andric }); 15100b57cec5SDimitry Andric } 1511bdd1243dSDimitry Andric for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { 151206c3fb27SDimitry Andric if (Candidate->select(Flags, Result.SelectedMultilibs)) { 15130b57cec5SDimitry Andric Result.Multilibs = *Candidate; 15140b57cec5SDimitry Andric return true; 15150b57cec5SDimitry Andric } 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric return false; 15180b57cec5SDimitry Andric } 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric bool clang::driver::findMIPSMultilibs(const Driver &D, 15210b57cec5SDimitry Andric const llvm::Triple &TargetTriple, 15220b57cec5SDimitry Andric StringRef Path, const ArgList &Args, 15230b57cec5SDimitry Andric DetectedMultilibs &Result) { 15240b57cec5SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric StringRef CPUName; 15270b57cec5SDimitry Andric StringRef ABIName; 15280b57cec5SDimitry Andric tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName); 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric Multilib::flags_list Flags; 153306c3fb27SDimitry Andric addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags); 153406c3fb27SDimitry Andric addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags); 153506c3fb27SDimitry Andric addMultilibFlag(isMips16(Args), "-mips16", Flags); 153606c3fb27SDimitry Andric addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags); 15370b57cec5SDimitry Andric addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" || 15380b57cec5SDimitry Andric CPUName == "mips32r5" || CPUName == "p5600", 153906c3fb27SDimitry Andric "-march=mips32r2", Flags); 154006c3fb27SDimitry Andric addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags); 154106c3fb27SDimitry Andric addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags); 15420b57cec5SDimitry Andric addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" || 15430b57cec5SDimitry Andric CPUName == "mips64r5" || CPUName == "octeon" || 15440b57cec5SDimitry Andric CPUName == "octeon+", 154506c3fb27SDimitry Andric "-march=mips64r2", Flags); 154606c3fb27SDimitry Andric addMultilibFlag(CPUName == "mips64r6", "-march=mips64r6", Flags); 154706c3fb27SDimitry Andric addMultilibFlag(isMicroMips(Args), "-mmicromips", Flags); 154806c3fb27SDimitry Andric addMultilibFlag(tools::mips::isUCLibc(Args), "-muclibc", Flags); 154906c3fb27SDimitry Andric addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "-mnan=2008", 15500b57cec5SDimitry Andric Flags); 155106c3fb27SDimitry Andric addMultilibFlag(ABIName == "n32", "-mabi=n32", Flags); 155206c3fb27SDimitry Andric addMultilibFlag(ABIName == "n64", "-mabi=n64", Flags); 155306c3fb27SDimitry Andric addMultilibFlag(isSoftFloatABI(Args), "-msoft-float", Flags); 155406c3fb27SDimitry Andric addMultilibFlag(!isSoftFloatABI(Args), "-mhard-float", Flags); 155506c3fb27SDimitry Andric addMultilibFlag(isMipsEL(TargetArch), "-EL", Flags); 155606c3fb27SDimitry Andric addMultilibFlag(!isMipsEL(TargetArch), "-EB", Flags); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric if (TargetTriple.isAndroid()) 15590b57cec5SDimitry Andric return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent, 15600b57cec5SDimitry Andric Result); 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies && 15630b57cec5SDimitry Andric TargetTriple.getOS() == llvm::Triple::Linux && 15640b57cec5SDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment) 15650b57cec5SDimitry Andric return findMipsMuslMultilibs(Flags, NonExistent, Result); 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies && 15680b57cec5SDimitry Andric TargetTriple.getOS() == llvm::Triple::Linux && 15690b57cec5SDimitry Andric TargetTriple.isGNUEnvironment()) 15700b57cec5SDimitry Andric return findMipsMtiMultilibs(Flags, NonExistent, Result); 15710b57cec5SDimitry Andric 15720b57cec5SDimitry Andric if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies && 15730b57cec5SDimitry Andric TargetTriple.getOS() == llvm::Triple::Linux && 15740b57cec5SDimitry Andric TargetTriple.isGNUEnvironment()) 15750b57cec5SDimitry Andric return findMipsImgMultilibs(Flags, NonExistent, Result); 15760b57cec5SDimitry Andric 15770b57cec5SDimitry Andric if (findMipsCsMultilibs(Flags, NonExistent, Result)) 15780b57cec5SDimitry Andric return true; 15790b57cec5SDimitry Andric 15800b57cec5SDimitry Andric // Fallback to the regular toolchain-tree structure. 15810b57cec5SDimitry Andric Multilib Default; 15820b57cec5SDimitry Andric Result.Multilibs.push_back(Default); 15830b57cec5SDimitry Andric Result.Multilibs.FilterOut(NonExistent); 15840b57cec5SDimitry Andric 158506c3fb27SDimitry Andric if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) { 15860b57cec5SDimitry Andric Result.BiarchSibling = Multilib(); 15870b57cec5SDimitry Andric return true; 15880b57cec5SDimitry Andric } 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric return false; 15910b57cec5SDimitry Andric } 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric static void findAndroidArmMultilibs(const Driver &D, 15940b57cec5SDimitry Andric const llvm::Triple &TargetTriple, 15950b57cec5SDimitry Andric StringRef Path, const ArgList &Args, 15960b57cec5SDimitry Andric DetectedMultilibs &Result) { 15970b57cec5SDimitry Andric // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb. 15980b57cec5SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 159906c3fb27SDimitry Andric MultilibBuilder ArmV7Multilib = MultilibBuilder("/armv7-a") 16000b57cec5SDimitry Andric .flag("-march=armv7-a") 160106c3fb27SDimitry Andric .flag("-mthumb", /*Disallow=*/true); 160206c3fb27SDimitry Andric MultilibBuilder ThumbMultilib = MultilibBuilder("/thumb") 160306c3fb27SDimitry Andric .flag("-march=armv7-a", /*Disallow=*/true) 16040b57cec5SDimitry Andric .flag("-mthumb"); 160506c3fb27SDimitry Andric MultilibBuilder ArmV7ThumbMultilib = 160606c3fb27SDimitry Andric MultilibBuilder("/armv7-a/thumb").flag("-march=armv7-a").flag("-mthumb"); 160706c3fb27SDimitry Andric MultilibBuilder DefaultMultilib = 160806c3fb27SDimitry Andric MultilibBuilder("") 160906c3fb27SDimitry Andric .flag("-march=armv7-a", /*Disallow=*/true) 161006c3fb27SDimitry Andric .flag("-mthumb", /*Disallow=*/true); 16110b57cec5SDimitry Andric MultilibSet AndroidArmMultilibs = 161206c3fb27SDimitry Andric MultilibSetBuilder() 161306c3fb27SDimitry Andric .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib, 161406c3fb27SDimitry Andric DefaultMultilib) 161506c3fb27SDimitry Andric .makeMultilibSet() 16160b57cec5SDimitry Andric .FilterOut(NonExistent); 16170b57cec5SDimitry Andric 16180b57cec5SDimitry Andric Multilib::flags_list Flags; 16190b57cec5SDimitry Andric llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ); 16200b57cec5SDimitry Andric bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm; 16210b57cec5SDimitry Andric bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb; 16220b57cec5SDimitry Andric bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7; 16230b57cec5SDimitry Andric bool IsThumbMode = IsThumbArch || 16240b57cec5SDimitry Andric Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) || 16250b57cec5SDimitry Andric (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB); 16260b57cec5SDimitry Andric bool IsArmV7Mode = (IsArmArch || IsThumbArch) && 16270b57cec5SDimitry Andric (llvm::ARM::parseArchVersion(Arch) == 7 || 16280b57cec5SDimitry Andric (IsArmArch && Arch == "" && IsV7SubArch)); 162906c3fb27SDimitry Andric addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags); 163006c3fb27SDimitry Andric addMultilibFlag(IsThumbMode, "-mthumb", Flags); 16310b57cec5SDimitry Andric 163206c3fb27SDimitry Andric if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilibs)) 16330b57cec5SDimitry Andric Result.Multilibs = AndroidArmMultilibs; 16340b57cec5SDimitry Andric } 16350b57cec5SDimitry Andric 16360b57cec5SDimitry Andric static bool findMSP430Multilibs(const Driver &D, 16370b57cec5SDimitry Andric const llvm::Triple &TargetTriple, 16380b57cec5SDimitry Andric StringRef Path, const ArgList &Args, 16390b57cec5SDimitry Andric DetectedMultilibs &Result) { 16400b57cec5SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 164106c3fb27SDimitry Andric MultilibBuilder WithoutExceptions = 164206c3fb27SDimitry Andric MultilibBuilder("/430").flag("-exceptions", /*Disallow=*/true); 164306c3fb27SDimitry Andric MultilibBuilder WithExceptions = 164406c3fb27SDimitry Andric MultilibBuilder("/430/exceptions").flag("-exceptions"); 1645e8d8bef9SDimitry Andric 16460b57cec5SDimitry Andric // FIXME: when clang starts to support msp430x ISA additional logic 16470b57cec5SDimitry Andric // to select between multilib must be implemented 164806c3fb27SDimitry Andric // MultilibBuilder MSP430xMultilib = MultilibBuilder("/large"); 16490b57cec5SDimitry Andric 165006c3fb27SDimitry Andric Result.Multilibs.push_back(WithoutExceptions.makeMultilib()); 165106c3fb27SDimitry Andric Result.Multilibs.push_back(WithExceptions.makeMultilib()); 16520b57cec5SDimitry Andric Result.Multilibs.FilterOut(NonExistent); 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric Multilib::flags_list Flags; 1655e8d8bef9SDimitry Andric addMultilibFlag(Args.hasFlag(options::OPT_fexceptions, 1656e8d8bef9SDimitry Andric options::OPT_fno_exceptions, false), 165706c3fb27SDimitry Andric "-exceptions", Flags); 165806c3fb27SDimitry Andric if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) 16590b57cec5SDimitry Andric return true; 16600b57cec5SDimitry Andric 16610b57cec5SDimitry Andric return false; 16620b57cec5SDimitry Andric } 16630b57cec5SDimitry Andric 166481ad6265SDimitry Andric static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple, 166581ad6265SDimitry Andric StringRef Path, const ArgList &Args, 166681ad6265SDimitry Andric DetectedMultilibs &Result) { 166781ad6265SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 166881ad6265SDimitry Andric 166981ad6265SDimitry Andric tools::csky::FloatABI TheFloatABI = tools::csky::getCSKYFloatABI(D, Args); 1670bdd1243dSDimitry Andric std::optional<llvm::StringRef> Res = 1671bdd1243dSDimitry Andric tools::csky::getCSKYArchName(D, Args, TargetTriple); 167281ad6265SDimitry Andric 167381ad6265SDimitry Andric if (!Res) 167481ad6265SDimitry Andric return; 167581ad6265SDimitry Andric auto ARCHName = *Res; 167681ad6265SDimitry Andric 167781ad6265SDimitry Andric Multilib::flags_list Flags; 167806c3fb27SDimitry Andric addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "-hard-fp", 167981ad6265SDimitry Andric Flags); 168006c3fb27SDimitry Andric addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "-soft-fp", 168106c3fb27SDimitry Andric Flags); 168206c3fb27SDimitry Andric addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "-soft", Flags); 168306c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags); 168406c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags); 168506c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags); 168606c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags); 168706c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags); 168806c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags); 168906c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags); 169006c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags); 169106c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags); 169206c3fb27SDimitry Andric addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags); 169381ad6265SDimitry Andric 169481ad6265SDimitry Andric bool isBigEndian = false; 169581ad6265SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, 169681ad6265SDimitry Andric options::OPT_mbig_endian)) 169781ad6265SDimitry Andric isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); 169806c3fb27SDimitry Andric addMultilibFlag(isBigEndian, "-EB", Flags); 169981ad6265SDimitry Andric 170006c3fb27SDimitry Andric auto HardFloat = MultilibBuilder("/hard-fp").flag("-hard-fp"); 170106c3fb27SDimitry Andric auto SoftFpFloat = MultilibBuilder("/soft-fp").flag("-soft-fp"); 170206c3fb27SDimitry Andric auto SoftFloat = MultilibBuilder("").flag("-soft"); 170306c3fb27SDimitry Andric auto Arch801 = MultilibBuilder("/ck801").flag("-march=ck801"); 170406c3fb27SDimitry Andric auto Arch802 = MultilibBuilder("/ck802").flag("-march=ck802"); 170506c3fb27SDimitry Andric auto Arch803 = MultilibBuilder("/ck803").flag("-march=ck803"); 170681ad6265SDimitry Andric // CK804 use the same library as CK803 170706c3fb27SDimitry Andric auto Arch804 = MultilibBuilder("/ck803").flag("-march=ck804"); 170806c3fb27SDimitry Andric auto Arch805 = MultilibBuilder("/ck805").flag("-march=ck805"); 170906c3fb27SDimitry Andric auto Arch807 = MultilibBuilder("/ck807").flag("-march=ck807"); 171006c3fb27SDimitry Andric auto Arch810 = MultilibBuilder("").flag("-march=ck810"); 171106c3fb27SDimitry Andric auto Arch810v = MultilibBuilder("/ck810v").flag("-march=ck810v"); 171206c3fb27SDimitry Andric auto Arch860 = MultilibBuilder("/ck860").flag("-march=ck860"); 171306c3fb27SDimitry Andric auto Arch860v = MultilibBuilder("/ck860v").flag("-march=ck860v"); 171406c3fb27SDimitry Andric auto BigEndian = MultilibBuilder("/big").flag("-EB"); 171581ad6265SDimitry Andric 171681ad6265SDimitry Andric MultilibSet CSKYMultilibs = 171706c3fb27SDimitry Andric MultilibSetBuilder() 171881ad6265SDimitry Andric .Maybe(BigEndian) 171981ad6265SDimitry Andric .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807, 172081ad6265SDimitry Andric Arch810, Arch810v, Arch860, Arch860v}) 172181ad6265SDimitry Andric .Either(HardFloat, SoftFpFloat, SoftFloat) 172206c3fb27SDimitry Andric .makeMultilibSet() 172381ad6265SDimitry Andric .FilterOut(NonExistent); 172481ad6265SDimitry Andric 172506c3fb27SDimitry Andric if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs)) 172681ad6265SDimitry Andric Result.Multilibs = CSKYMultilibs; 172781ad6265SDimitry Andric } 172881ad6265SDimitry Andric 1729cb14a3feSDimitry Andric /// Extend the multi-lib re-use selection mechanism for RISC-V. 1730cb14a3feSDimitry Andric /// This function will try to re-use multi-lib if they are compatible. 1731cb14a3feSDimitry Andric /// Definition of compatible: 1732cb14a3feSDimitry Andric /// - ABI must be the same. 1733cb14a3feSDimitry Andric /// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im 1734cb14a3feSDimitry Andric /// is a subset of march=rv32imc. 1735cb14a3feSDimitry Andric /// - march that contains atomic extension can't reuse multi-lib that 1736cb14a3feSDimitry Andric /// doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and 1737cb14a3feSDimitry Andric /// march=rv32ima are not compatible, because software and hardware 1738cb14a3feSDimitry Andric /// atomic operation can't work together correctly. 1739cb14a3feSDimitry Andric static bool 1740cb14a3feSDimitry Andric selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch, 1741cb14a3feSDimitry Andric const Multilib::flags_list &Flags, 1742cb14a3feSDimitry Andric llvm::SmallVectorImpl<Multilib> &SelectedMultilibs) { 1743cb14a3feSDimitry Andric // Try to find the perfect matching multi-lib first. 1744cb14a3feSDimitry Andric if (RISCVMultilibSet.select(Flags, SelectedMultilibs)) 1745cb14a3feSDimitry Andric return true; 1746cb14a3feSDimitry Andric 1747cb14a3feSDimitry Andric Multilib::flags_list NewFlags; 1748cb14a3feSDimitry Andric std::vector<MultilibBuilder> NewMultilibs; 1749cb14a3feSDimitry Andric 1750cb14a3feSDimitry Andric llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> ParseResult = 1751cb14a3feSDimitry Andric llvm::RISCVISAInfo::parseArchString( 1752cb14a3feSDimitry Andric Arch, /*EnableExperimentalExtension=*/true, 1753cb14a3feSDimitry Andric /*ExperimentalExtensionVersionCheck=*/false); 1754cb14a3feSDimitry Andric // Ignore any error here, we assume it will be handled in another place. 1755647cbc5dSDimitry Andric if (llvm::errorToBool(ParseResult.takeError())) 1756cb14a3feSDimitry Andric return false; 1757cb14a3feSDimitry Andric 1758cb14a3feSDimitry Andric auto &ISAInfo = *ParseResult; 1759cb14a3feSDimitry Andric 1760cb14a3feSDimitry Andric addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags); 1761cb14a3feSDimitry Andric addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags); 1762cb14a3feSDimitry Andric 1763cb14a3feSDimitry Andric // Collect all flags except march=* 1764cb14a3feSDimitry Andric for (StringRef Flag : Flags) { 1765cb14a3feSDimitry Andric if (Flag.starts_with("!march=") || Flag.starts_with("-march=")) 1766cb14a3feSDimitry Andric continue; 1767cb14a3feSDimitry Andric 1768cb14a3feSDimitry Andric NewFlags.push_back(Flag.str()); 1769cb14a3feSDimitry Andric } 1770cb14a3feSDimitry Andric 1771cb14a3feSDimitry Andric llvm::StringSet<> AllArchExts; 1772cb14a3feSDimitry Andric // Reconstruct multi-lib list, and break march option into separated 1773cb14a3feSDimitry Andric // extension. e.g. march=rv32im -> +i +m 1774cb14a3feSDimitry Andric for (const auto &M : RISCVMultilibSet) { 1775cb14a3feSDimitry Andric bool Skip = false; 1776cb14a3feSDimitry Andric 1777cb14a3feSDimitry Andric MultilibBuilder NewMultilib = 1778cb14a3feSDimitry Andric MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix()); 1779cb14a3feSDimitry Andric for (StringRef Flag : M.flags()) { 1780cb14a3feSDimitry Andric // Add back all flags except -march. 1781cb14a3feSDimitry Andric if (!Flag.consume_front("-march=")) { 1782cb14a3feSDimitry Andric NewMultilib.flag(Flag); 1783cb14a3feSDimitry Andric continue; 1784cb14a3feSDimitry Andric } 1785cb14a3feSDimitry Andric 1786cb14a3feSDimitry Andric // Break down -march into individual extension. 1787cb14a3feSDimitry Andric llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> MLConfigParseResult = 1788cb14a3feSDimitry Andric llvm::RISCVISAInfo::parseArchString( 1789cb14a3feSDimitry Andric Flag, /*EnableExperimentalExtension=*/true, 1790cb14a3feSDimitry Andric /*ExperimentalExtensionVersionCheck=*/false); 1791cb14a3feSDimitry Andric // Ignore any error here, we assume it will handled in another place. 1792647cbc5dSDimitry Andric if (llvm::errorToBool(MLConfigParseResult.takeError())) { 1793cb14a3feSDimitry Andric // We might get a parsing error if rv32e in the list, we could just skip 1794cb14a3feSDimitry Andric // that and process the rest of multi-lib configs. 1795cb14a3feSDimitry Andric Skip = true; 1796cb14a3feSDimitry Andric continue; 1797cb14a3feSDimitry Andric } 1798cb14a3feSDimitry Andric auto &MLConfigISAInfo = *MLConfigParseResult; 1799cb14a3feSDimitry Andric 18000fca6ea1SDimitry Andric for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) { 1801cb14a3feSDimitry Andric auto ExtName = MLConfigArchExt.first; 1802cb14a3feSDimitry Andric NewMultilib.flag(Twine("-", ExtName).str()); 1803cb14a3feSDimitry Andric 1804cb14a3feSDimitry Andric if (AllArchExts.insert(ExtName).second) { 1805cb14a3feSDimitry Andric addMultilibFlag(ISAInfo->hasExtension(ExtName), 1806cb14a3feSDimitry Andric Twine("-", ExtName).str(), NewFlags); 1807cb14a3feSDimitry Andric } 1808cb14a3feSDimitry Andric } 1809cb14a3feSDimitry Andric 1810cb14a3feSDimitry Andric // Check the XLEN explicitly. 1811cb14a3feSDimitry Andric if (MLConfigISAInfo->getXLen() == 32) { 1812cb14a3feSDimitry Andric NewMultilib.flag("-m32"); 1813cb14a3feSDimitry Andric NewMultilib.flag("-m64", /*Disallow*/ true); 1814cb14a3feSDimitry Andric } else { 1815cb14a3feSDimitry Andric NewMultilib.flag("-m32", /*Disallow*/ true); 1816cb14a3feSDimitry Andric NewMultilib.flag("-m64"); 1817cb14a3feSDimitry Andric } 1818cb14a3feSDimitry Andric 1819cb14a3feSDimitry Andric // Atomic extension must be explicitly checked, soft and hard atomic 1820cb14a3feSDimitry Andric // operation never co-work correctly. 1821cb14a3feSDimitry Andric if (!MLConfigISAInfo->hasExtension("a")) 1822cb14a3feSDimitry Andric NewMultilib.flag("-a", /*Disallow*/ true); 1823cb14a3feSDimitry Andric } 1824cb14a3feSDimitry Andric 1825cb14a3feSDimitry Andric if (Skip) 1826cb14a3feSDimitry Andric continue; 1827cb14a3feSDimitry Andric 1828cb14a3feSDimitry Andric NewMultilibs.emplace_back(NewMultilib); 1829cb14a3feSDimitry Andric } 1830cb14a3feSDimitry Andric 1831cb14a3feSDimitry Andric // Build an internal used only multi-lib list, used for checking any 1832cb14a3feSDimitry Andric // compatible multi-lib. 1833cb14a3feSDimitry Andric MultilibSet NewRISCVMultilibs = 1834cb14a3feSDimitry Andric MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet(); 1835cb14a3feSDimitry Andric 1836cb14a3feSDimitry Andric if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs)) 1837cb14a3feSDimitry Andric for (const Multilib &NewSelectedM : SelectedMultilibs) 1838cb14a3feSDimitry Andric for (const auto &M : RISCVMultilibSet) 1839cb14a3feSDimitry Andric // Look up the corresponding multi-lib entry in original multi-lib set. 1840cb14a3feSDimitry Andric if (M.gccSuffix() == NewSelectedM.gccSuffix()) 1841cb14a3feSDimitry Andric return true; 1842cb14a3feSDimitry Andric 1843cb14a3feSDimitry Andric return false; 1844cb14a3feSDimitry Andric } 1845cb14a3feSDimitry Andric 1846480093f4SDimitry Andric static void findRISCVBareMetalMultilibs(const Driver &D, 1847480093f4SDimitry Andric const llvm::Triple &TargetTriple, 1848480093f4SDimitry Andric StringRef Path, const ArgList &Args, 1849480093f4SDimitry Andric DetectedMultilibs &Result) { 1850480093f4SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 1851480093f4SDimitry Andric struct RiscvMultilib { 1852480093f4SDimitry Andric StringRef march; 1853480093f4SDimitry Andric StringRef mabi; 1854480093f4SDimitry Andric }; 1855480093f4SDimitry Andric // currently only support the set of multilibs like riscv-gnu-toolchain does. 1856480093f4SDimitry Andric // TODO: support MULTILIB_REUSE 18575ffd83dbSDimitry Andric constexpr RiscvMultilib RISCVMultilibSet[] = { 1858480093f4SDimitry Andric {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, 1859480093f4SDimitry Andric {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, 1860480093f4SDimitry Andric {"rv64imafdc", "lp64d"}}; 1861480093f4SDimitry Andric 186206c3fb27SDimitry Andric std::vector<MultilibBuilder> Ms; 1863480093f4SDimitry Andric for (auto Element : RISCVMultilibSet) { 1864480093f4SDimitry Andric // multilib path rule is ${march}/${mabi} 1865480093f4SDimitry Andric Ms.emplace_back( 186606c3fb27SDimitry Andric MultilibBuilder( 186706c3fb27SDimitry Andric (Twine(Element.march) + "/" + Twine(Element.mabi)).str()) 186806c3fb27SDimitry Andric .flag(Twine("-march=", Element.march).str()) 186906c3fb27SDimitry Andric .flag(Twine("-mabi=", Element.mabi).str())); 1870480093f4SDimitry Andric } 1871480093f4SDimitry Andric MultilibSet RISCVMultilibs = 187206c3fb27SDimitry Andric MultilibSetBuilder() 187306c3fb27SDimitry Andric .Either(Ms) 187406c3fb27SDimitry Andric .makeMultilibSet() 1875480093f4SDimitry Andric .FilterOut(NonExistent) 1876480093f4SDimitry Andric .setFilePathsCallback([](const Multilib &M) { 1877480093f4SDimitry Andric return std::vector<std::string>( 1878480093f4SDimitry Andric {M.gccSuffix(), 1879480093f4SDimitry Andric "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), 1880480093f4SDimitry Andric "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); 1881480093f4SDimitry Andric }); 1882480093f4SDimitry Andric 1883480093f4SDimitry Andric Multilib::flags_list Flags; 1884480093f4SDimitry Andric llvm::StringSet<> Added_ABIs; 1885480093f4SDimitry Andric StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); 18860fca6ea1SDimitry Andric std::string MArch = tools::riscv::getRISCVArch(Args, TargetTriple); 1887480093f4SDimitry Andric for (auto Element : RISCVMultilibSet) { 1888480093f4SDimitry Andric addMultilibFlag(MArch == Element.march, 188906c3fb27SDimitry Andric Twine("-march=", Element.march).str().c_str(), Flags); 1890480093f4SDimitry Andric if (!Added_ABIs.count(Element.mabi)) { 1891480093f4SDimitry Andric Added_ABIs.insert(Element.mabi); 1892480093f4SDimitry Andric addMultilibFlag(ABIName == Element.mabi, 189306c3fb27SDimitry Andric Twine("-mabi=", Element.mabi).str().c_str(), Flags); 1894480093f4SDimitry Andric } 1895480093f4SDimitry Andric } 1896480093f4SDimitry Andric 1897cb14a3feSDimitry Andric if (selectRISCVMultilib(RISCVMultilibs, MArch, Flags, 1898cb14a3feSDimitry Andric Result.SelectedMultilibs)) 1899480093f4SDimitry Andric Result.Multilibs = RISCVMultilibs; 1900480093f4SDimitry Andric } 1901480093f4SDimitry Andric 19020b57cec5SDimitry Andric static void findRISCVMultilibs(const Driver &D, 19030b57cec5SDimitry Andric const llvm::Triple &TargetTriple, StringRef Path, 19040b57cec5SDimitry Andric const ArgList &Args, DetectedMultilibs &Result) { 1905480093f4SDimitry Andric if (TargetTriple.getOS() == llvm::Triple::UnknownOS) 1906480093f4SDimitry Andric return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result); 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andric FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); 190906c3fb27SDimitry Andric MultilibBuilder Ilp32 = 191006c3fb27SDimitry Andric MultilibBuilder("lib32/ilp32").flag("-m32").flag("-mabi=ilp32"); 191106c3fb27SDimitry Andric MultilibBuilder Ilp32f = 191206c3fb27SDimitry Andric MultilibBuilder("lib32/ilp32f").flag("-m32").flag("-mabi=ilp32f"); 191306c3fb27SDimitry Andric MultilibBuilder Ilp32d = 191406c3fb27SDimitry Andric MultilibBuilder("lib32/ilp32d").flag("-m32").flag("-mabi=ilp32d"); 191506c3fb27SDimitry Andric MultilibBuilder Lp64 = 191606c3fb27SDimitry Andric MultilibBuilder("lib64/lp64").flag("-m64").flag("-mabi=lp64"); 191706c3fb27SDimitry Andric MultilibBuilder Lp64f = 191806c3fb27SDimitry Andric MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f"); 191906c3fb27SDimitry Andric MultilibBuilder Lp64d = 192006c3fb27SDimitry Andric MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d"); 19210b57cec5SDimitry Andric MultilibSet RISCVMultilibs = 192206c3fb27SDimitry Andric MultilibSetBuilder() 19230b57cec5SDimitry Andric .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) 192406c3fb27SDimitry Andric .makeMultilibSet() 19250b57cec5SDimitry Andric .FilterOut(NonExistent); 19260b57cec5SDimitry Andric 19270b57cec5SDimitry Andric Multilib::flags_list Flags; 19280b57cec5SDimitry Andric bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; 19290b57cec5SDimitry Andric StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); 19300b57cec5SDimitry Andric 193106c3fb27SDimitry Andric addMultilibFlag(!IsRV64, "-m32", Flags); 193206c3fb27SDimitry Andric addMultilibFlag(IsRV64, "-m64", Flags); 193306c3fb27SDimitry Andric addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags); 193406c3fb27SDimitry Andric addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags); 193506c3fb27SDimitry Andric addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags); 193606c3fb27SDimitry Andric addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags); 193706c3fb27SDimitry Andric addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags); 193806c3fb27SDimitry Andric addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags); 19390b57cec5SDimitry Andric 194006c3fb27SDimitry Andric if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) 19410b57cec5SDimitry Andric Result.Multilibs = RISCVMultilibs; 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric static bool findBiarchMultilibs(const Driver &D, 19450b57cec5SDimitry Andric const llvm::Triple &TargetTriple, 19460b57cec5SDimitry Andric StringRef Path, const ArgList &Args, 19470b57cec5SDimitry Andric bool NeedsBiarchSuffix, 19480b57cec5SDimitry Andric DetectedMultilibs &Result) { 194906c3fb27SDimitry Andric MultilibBuilder DefaultBuilder; 19500b57cec5SDimitry Andric 19510b57cec5SDimitry Andric // Some versions of SUSE and Fedora on ppc64 put 32-bit libs 19520b57cec5SDimitry Andric // in what would normally be GCCInstallPath and put the 64-bit 19530b57cec5SDimitry Andric // libs in a subdirectory named 64. The simple logic we follow is that 19540b57cec5SDimitry Andric // *if* there is a subdirectory of the right name with crtbegin.o in it, 19550b57cec5SDimitry Andric // we use that. If not, and if not a biarch triple alias, we look for 19560b57cec5SDimitry Andric // crtbegin.o without the subdirectory. 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric StringRef Suff64 = "/64"; 19590b57cec5SDimitry Andric // Solaris uses platform-specific suffixes instead of /64. 19605f757f3fSDimitry Andric if (TargetTriple.isOSSolaris()) { 19610b57cec5SDimitry Andric switch (TargetTriple.getArch()) { 19620b57cec5SDimitry Andric case llvm::Triple::x86: 19630b57cec5SDimitry Andric case llvm::Triple::x86_64: 19640b57cec5SDimitry Andric Suff64 = "/amd64"; 19650b57cec5SDimitry Andric break; 19660b57cec5SDimitry Andric case llvm::Triple::sparc: 19670b57cec5SDimitry Andric case llvm::Triple::sparcv9: 19680b57cec5SDimitry Andric Suff64 = "/sparcv9"; 19690b57cec5SDimitry Andric break; 19700b57cec5SDimitry Andric default: 19710b57cec5SDimitry Andric break; 19720b57cec5SDimitry Andric } 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric 197506c3fb27SDimitry Andric Multilib Alt64 = MultilibBuilder() 19760b57cec5SDimitry Andric .gccSuffix(Suff64) 19770b57cec5SDimitry Andric .includeSuffix(Suff64) 197806c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true) 197906c3fb27SDimitry Andric .flag("-m64") 198006c3fb27SDimitry Andric .flag("-mx32", /*Disallow=*/true) 198106c3fb27SDimitry Andric .makeMultilib(); 198206c3fb27SDimitry Andric Multilib Alt32 = MultilibBuilder() 19830b57cec5SDimitry Andric .gccSuffix("/32") 19840b57cec5SDimitry Andric .includeSuffix("/32") 198506c3fb27SDimitry Andric .flag("-m32") 198606c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 198706c3fb27SDimitry Andric .flag("-mx32", /*Disallow=*/true) 198806c3fb27SDimitry Andric .makeMultilib(); 198906c3fb27SDimitry Andric Multilib Altx32 = MultilibBuilder() 19900b57cec5SDimitry Andric .gccSuffix("/x32") 19910b57cec5SDimitry Andric .includeSuffix("/x32") 199206c3fb27SDimitry Andric .flag("-m32", /*Disallow=*/true) 199306c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 199406c3fb27SDimitry Andric .flag("-mx32") 199506c3fb27SDimitry Andric .makeMultilib(); 19968a4dda33SDimitry Andric Multilib Alt32sparc = MultilibBuilder() 19978a4dda33SDimitry Andric .gccSuffix("/sparcv8plus") 19988a4dda33SDimitry Andric .includeSuffix("/sparcv8plus") 19998a4dda33SDimitry Andric .flag("-m32") 20008a4dda33SDimitry Andric .flag("-m64", /*Disallow=*/true) 20018a4dda33SDimitry Andric .makeMultilib(); 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a. 20040b57cec5SDimitry Andric FilterNonExistent NonExistent( 20050b57cec5SDimitry Andric Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS()); 20060b57cec5SDimitry Andric 20070b57cec5SDimitry Andric // Determine default multilib from: 32, 64, x32 20080b57cec5SDimitry Andric // Also handle cases such as 64 on 32, 32 on 64, etc. 20090b57cec5SDimitry Andric enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN; 2010fe6060f1SDimitry Andric const bool IsX32 = TargetTriple.isX32(); 20110b57cec5SDimitry Andric if (TargetTriple.isArch32Bit() && !NonExistent(Alt32)) 20120b57cec5SDimitry Andric Want = WANT64; 20138a4dda33SDimitry Andric if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc)) 20148a4dda33SDimitry Andric Want = WANT64; 20150b57cec5SDimitry Andric else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32)) 20160b57cec5SDimitry Andric Want = WANT64; 20170b57cec5SDimitry Andric else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64)) 20180b57cec5SDimitry Andric Want = WANT32; 20198a4dda33SDimitry Andric else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc)) 20208a4dda33SDimitry Andric Want = WANT64; 20210b57cec5SDimitry Andric else { 20220b57cec5SDimitry Andric if (TargetTriple.isArch32Bit()) 20230b57cec5SDimitry Andric Want = NeedsBiarchSuffix ? WANT64 : WANT32; 20240b57cec5SDimitry Andric else if (IsX32) 20250b57cec5SDimitry Andric Want = NeedsBiarchSuffix ? WANT64 : WANTX32; 20260b57cec5SDimitry Andric else 20270b57cec5SDimitry Andric Want = NeedsBiarchSuffix ? WANT32 : WANT64; 20280b57cec5SDimitry Andric } 20290b57cec5SDimitry Andric 20300b57cec5SDimitry Andric if (Want == WANT32) 203106c3fb27SDimitry Andric DefaultBuilder.flag("-m32") 203206c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 203306c3fb27SDimitry Andric .flag("-mx32", /*Disallow=*/true); 20340b57cec5SDimitry Andric else if (Want == WANT64) 203506c3fb27SDimitry Andric DefaultBuilder.flag("-m32", /*Disallow=*/true) 203606c3fb27SDimitry Andric .flag("-m64") 203706c3fb27SDimitry Andric .flag("-mx32", /*Disallow=*/true); 20380b57cec5SDimitry Andric else if (Want == WANTX32) 203906c3fb27SDimitry Andric DefaultBuilder.flag("-m32", /*Disallow=*/true) 204006c3fb27SDimitry Andric .flag("-m64", /*Disallow=*/true) 204106c3fb27SDimitry Andric .flag("-mx32"); 20420b57cec5SDimitry Andric else 20430b57cec5SDimitry Andric return false; 20440b57cec5SDimitry Andric 204506c3fb27SDimitry Andric Multilib Default = DefaultBuilder.makeMultilib(); 204606c3fb27SDimitry Andric 20470b57cec5SDimitry Andric Result.Multilibs.push_back(Default); 20480b57cec5SDimitry Andric Result.Multilibs.push_back(Alt64); 20490b57cec5SDimitry Andric Result.Multilibs.push_back(Alt32); 20500b57cec5SDimitry Andric Result.Multilibs.push_back(Altx32); 20518a4dda33SDimitry Andric Result.Multilibs.push_back(Alt32sparc); 20520b57cec5SDimitry Andric 20530b57cec5SDimitry Andric Result.Multilibs.FilterOut(NonExistent); 20540b57cec5SDimitry Andric 20550b57cec5SDimitry Andric Multilib::flags_list Flags; 205606c3fb27SDimitry Andric addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "-m64", Flags); 205706c3fb27SDimitry Andric addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags); 205806c3fb27SDimitry Andric addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "-mx32", Flags); 20590b57cec5SDimitry Andric 206006c3fb27SDimitry Andric if (!Result.Multilibs.select(Flags, Result.SelectedMultilibs)) 20610b57cec5SDimitry Andric return false; 20620b57cec5SDimitry Andric 206306c3fb27SDimitry Andric if (Result.SelectedMultilibs.back() == Alt64 || 206406c3fb27SDimitry Andric Result.SelectedMultilibs.back() == Alt32 || 20658a4dda33SDimitry Andric Result.SelectedMultilibs.back() == Altx32 || 20668a4dda33SDimitry Andric Result.SelectedMultilibs.back() == Alt32sparc) 20670b57cec5SDimitry Andric Result.BiarchSibling = Default; 20680b57cec5SDimitry Andric 20690b57cec5SDimitry Andric return true; 20700b57cec5SDimitry Andric } 20710b57cec5SDimitry Andric 20720b57cec5SDimitry Andric /// Generic_GCC - A tool chain using the 'gcc' command to perform 20730b57cec5SDimitry Andric /// all subcommands; this relies on gcc translating the majority of 20740b57cec5SDimitry Andric /// command line options. 20750b57cec5SDimitry Andric 20760b57cec5SDimitry Andric /// Less-than for GCCVersion, implementing a Strict Weak Ordering. 20770b57cec5SDimitry Andric bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, 20780b57cec5SDimitry Andric int RHSPatch, 20790b57cec5SDimitry Andric StringRef RHSPatchSuffix) const { 20800b57cec5SDimitry Andric if (Major != RHSMajor) 20810b57cec5SDimitry Andric return Major < RHSMajor; 2082bdd1243dSDimitry Andric if (Minor != RHSMinor) { 2083bdd1243dSDimitry Andric // Note that versions without a specified minor sort higher than those with 2084bdd1243dSDimitry Andric // a minor. 2085bdd1243dSDimitry Andric if (RHSMinor == -1) 2086bdd1243dSDimitry Andric return true; 2087bdd1243dSDimitry Andric if (Minor == -1) 2088bdd1243dSDimitry Andric return false; 20890b57cec5SDimitry Andric return Minor < RHSMinor; 2090bdd1243dSDimitry Andric } 20910b57cec5SDimitry Andric if (Patch != RHSPatch) { 20920b57cec5SDimitry Andric // Note that versions without a specified patch sort higher than those with 20930b57cec5SDimitry Andric // a patch. 20940b57cec5SDimitry Andric if (RHSPatch == -1) 20950b57cec5SDimitry Andric return true; 20960b57cec5SDimitry Andric if (Patch == -1) 20970b57cec5SDimitry Andric return false; 20980b57cec5SDimitry Andric 20990b57cec5SDimitry Andric // Otherwise just sort on the patch itself. 21000b57cec5SDimitry Andric return Patch < RHSPatch; 21010b57cec5SDimitry Andric } 21020b57cec5SDimitry Andric if (PatchSuffix != RHSPatchSuffix) { 21030b57cec5SDimitry Andric // Sort empty suffixes higher. 21040b57cec5SDimitry Andric if (RHSPatchSuffix.empty()) 21050b57cec5SDimitry Andric return true; 21060b57cec5SDimitry Andric if (PatchSuffix.empty()) 21070b57cec5SDimitry Andric return false; 21080b57cec5SDimitry Andric 21090b57cec5SDimitry Andric // Provide a lexicographic sort to make this a total ordering. 21100b57cec5SDimitry Andric return PatchSuffix < RHSPatchSuffix; 21110b57cec5SDimitry Andric } 21120b57cec5SDimitry Andric 21130b57cec5SDimitry Andric // The versions are equal. 21140b57cec5SDimitry Andric return false; 21150b57cec5SDimitry Andric } 21160b57cec5SDimitry Andric 21170b57cec5SDimitry Andric /// Parse a GCCVersion object out of a string of text. 21180b57cec5SDimitry Andric /// 21190b57cec5SDimitry Andric /// This is the primary means of forming GCCVersion objects. 21200b57cec5SDimitry Andric /*static*/ 21210b57cec5SDimitry Andric Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) { 21220b57cec5SDimitry Andric const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; 21230b57cec5SDimitry Andric std::pair<StringRef, StringRef> First = VersionText.split('.'); 21240b57cec5SDimitry Andric std::pair<StringRef, StringRef> Second = First.second.split('.'); 21250b57cec5SDimitry Andric 21265f757f3fSDimitry Andric StringRef MajorStr = First.first; 21270b57cec5SDimitry Andric StringRef MinorStr = Second.first; 21285f757f3fSDimitry Andric StringRef PatchStr = Second.second; 21290b57cec5SDimitry Andric 21305f757f3fSDimitry Andric GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; 21315f757f3fSDimitry Andric 21325f757f3fSDimitry Andric // Parse version number strings such as: 21335f757f3fSDimitry Andric // 5 21340b57cec5SDimitry Andric // 4.4 21350b57cec5SDimitry Andric // 4.4-patched 21360b57cec5SDimitry Andric // 4.4.0 21370b57cec5SDimitry Andric // 4.4.x 21380b57cec5SDimitry Andric // 4.4.2-rc4 21390b57cec5SDimitry Andric // 4.4.x-patched 21405f757f3fSDimitry Andric // 10-win32 21415f757f3fSDimitry Andric // Split on '.', handle 1, 2 or 3 such segments. Each segment must contain 21425f757f3fSDimitry Andric // purely a number, except for the last one, where a non-number suffix 21435f757f3fSDimitry Andric // is stored in PatchSuffix. The third segment is allowed to not contain 21445f757f3fSDimitry Andric // a number at all. 21455f757f3fSDimitry Andric 21465f757f3fSDimitry Andric auto TryParseLastNumber = [&](StringRef Segment, int &Number, 21475f757f3fSDimitry Andric std::string &OutStr) -> bool { 21485f757f3fSDimitry Andric // Look for a number prefix and parse that, and split out any trailing 21495f757f3fSDimitry Andric // string into GoodVersion.PatchSuffix. 21505f757f3fSDimitry Andric 21515f757f3fSDimitry Andric if (size_t EndNumber = Segment.find_first_not_of("0123456789")) { 21525f757f3fSDimitry Andric StringRef NumberStr = Segment.slice(0, EndNumber); 21535f757f3fSDimitry Andric if (NumberStr.getAsInteger(10, Number) || Number < 0) 21545f757f3fSDimitry Andric return false; 21555f757f3fSDimitry Andric OutStr = NumberStr; 21565f757f3fSDimitry Andric GoodVersion.PatchSuffix = Segment.substr(EndNumber); 21575f757f3fSDimitry Andric return true; 21580b57cec5SDimitry Andric } 21595f757f3fSDimitry Andric return false; 21605f757f3fSDimitry Andric }; 21615f757f3fSDimitry Andric auto TryParseNumber = [](StringRef Segment, int &Number) -> bool { 21625f757f3fSDimitry Andric if (Segment.getAsInteger(10, Number) || Number < 0) 21635f757f3fSDimitry Andric return false; 21645f757f3fSDimitry Andric return true; 21655f757f3fSDimitry Andric }; 21665f757f3fSDimitry Andric 21675f757f3fSDimitry Andric if (MinorStr.empty()) { 21685f757f3fSDimitry Andric // If no minor string, major is the last segment 21695f757f3fSDimitry Andric if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr)) 21705f757f3fSDimitry Andric return BadVersion; 21715f757f3fSDimitry Andric return GoodVersion; 21720b57cec5SDimitry Andric } 21730b57cec5SDimitry Andric 21745f757f3fSDimitry Andric if (!TryParseNumber(MajorStr, GoodVersion.Major)) 21755f757f3fSDimitry Andric return BadVersion; 21765f757f3fSDimitry Andric GoodVersion.MajorStr = MajorStr; 21775f757f3fSDimitry Andric 21785f757f3fSDimitry Andric if (PatchStr.empty()) { 21795f757f3fSDimitry Andric // If no patch string, minor is the last segment 21805f757f3fSDimitry Andric if (!TryParseLastNumber(MinorStr, GoodVersion.Minor, GoodVersion.MinorStr)) 21815f757f3fSDimitry Andric return BadVersion; 21825f757f3fSDimitry Andric return GoodVersion; 21835f757f3fSDimitry Andric } 21845f757f3fSDimitry Andric 21855f757f3fSDimitry Andric if (!TryParseNumber(MinorStr, GoodVersion.Minor)) 21865f757f3fSDimitry Andric return BadVersion; 21875f757f3fSDimitry Andric GoodVersion.MinorStr = MinorStr; 21885f757f3fSDimitry Andric 21895f757f3fSDimitry Andric // For the last segment, tolerate a missing number. 21905f757f3fSDimitry Andric std::string DummyStr; 21915f757f3fSDimitry Andric TryParseLastNumber(PatchStr, GoodVersion.Patch, DummyStr); 21920b57cec5SDimitry Andric return GoodVersion; 21930b57cec5SDimitry Andric } 21940b57cec5SDimitry Andric 21950b57cec5SDimitry Andric static llvm::StringRef getGCCToolchainDir(const ArgList &Args, 21960b57cec5SDimitry Andric llvm::StringRef SysRoot) { 21970b57cec5SDimitry Andric const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain); 21980b57cec5SDimitry Andric if (A) 21990b57cec5SDimitry Andric return A->getValue(); 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andric // If we have a SysRoot, ignore GCC_INSTALL_PREFIX. 22020b57cec5SDimitry Andric // GCC_INSTALL_PREFIX specifies the gcc installation for the default 22030b57cec5SDimitry Andric // sysroot and is likely not valid with a different sysroot. 22040b57cec5SDimitry Andric if (!SysRoot.empty()) 22050b57cec5SDimitry Andric return ""; 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andric return GCC_INSTALL_PREFIX; 22080b57cec5SDimitry Andric } 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andric /// Initialize a GCCInstallationDetector from the driver. 22110b57cec5SDimitry Andric /// 22120b57cec5SDimitry Andric /// This performs all of the autodetection and sets up the various paths. 22130b57cec5SDimitry Andric /// Once constructed, a GCCInstallationDetector is essentially immutable. 22140b57cec5SDimitry Andric /// 22150b57cec5SDimitry Andric /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and 22160b57cec5SDimitry Andric /// should instead pull the target out of the driver. This is currently 22170b57cec5SDimitry Andric /// necessary because the driver doesn't store the final version of the target 22180b57cec5SDimitry Andric /// triple. 22190b57cec5SDimitry Andric void Generic_GCC::GCCInstallationDetector::init( 22205f757f3fSDimitry Andric const llvm::Triple &TargetTriple, const ArgList &Args) { 22210b57cec5SDimitry Andric llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit() 22220b57cec5SDimitry Andric ? TargetTriple.get64BitArchVariant() 22230b57cec5SDimitry Andric : TargetTriple.get32BitArchVariant(); 22240b57cec5SDimitry Andric // The library directories which may contain GCC installations. 22250b57cec5SDimitry Andric SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; 22260b57cec5SDimitry Andric // The compatible GCC triples for this particular architecture. 22270b57cec5SDimitry Andric SmallVector<StringRef, 16> CandidateTripleAliases; 22280b57cec5SDimitry Andric SmallVector<StringRef, 16> CandidateBiarchTripleAliases; 22295f757f3fSDimitry Andric // Add some triples that we want to check first. 22305f757f3fSDimitry Andric CandidateTripleAliases.push_back(TargetTriple.str()); 22310fca6ea1SDimitry Andric std::string TripleNoVendor, BiarchTripleNoVendor; 22320fca6ea1SDimitry Andric if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) { 22330fca6ea1SDimitry Andric StringRef OSEnv = TargetTriple.getOSAndEnvironmentName(); 22340fca6ea1SDimitry Andric if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) 22350fca6ea1SDimitry Andric OSEnv = "linux-gnu"; 22360fca6ea1SDimitry Andric TripleNoVendor = (TargetTriple.getArchName().str() + '-' + OSEnv).str(); 22375f757f3fSDimitry Andric CandidateTripleAliases.push_back(TripleNoVendor); 22380fca6ea1SDimitry Andric if (BiarchVariantTriple.getArch() != llvm::Triple::UnknownArch) { 22390fca6ea1SDimitry Andric BiarchTripleNoVendor = 22400fca6ea1SDimitry Andric (BiarchVariantTriple.getArchName().str() + '-' + OSEnv).str(); 22410fca6ea1SDimitry Andric CandidateBiarchTripleAliases.push_back(BiarchTripleNoVendor); 22420fca6ea1SDimitry Andric } 22430fca6ea1SDimitry Andric } 22445f757f3fSDimitry Andric 22450b57cec5SDimitry Andric CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, 22460b57cec5SDimitry Andric CandidateTripleAliases, CandidateBiarchLibDirs, 22470b57cec5SDimitry Andric CandidateBiarchTripleAliases); 22480b57cec5SDimitry Andric 2249bdd1243dSDimitry Andric // If --gcc-install-dir= is specified, skip filesystem detection. 2250bdd1243dSDimitry Andric if (const Arg *A = 2251bdd1243dSDimitry Andric Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ); 2252bdd1243dSDimitry Andric A && A->getValue()[0]) { 2253bdd1243dSDimitry Andric StringRef InstallDir = A->getValue(); 2254bdd1243dSDimitry Andric if (!ScanGCCForMultilibs(TargetTriple, Args, InstallDir, false)) { 2255bdd1243dSDimitry Andric D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir; 2256bdd1243dSDimitry Andric } else { 2257bdd1243dSDimitry Andric (void)InstallDir.consume_back("/"); 2258bdd1243dSDimitry Andric StringRef VersionText = llvm::sys::path::filename(InstallDir); 2259bdd1243dSDimitry Andric StringRef TripleText = 2260bdd1243dSDimitry Andric llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir)); 2261bdd1243dSDimitry Andric 2262bdd1243dSDimitry Andric Version = GCCVersion::Parse(VersionText); 2263bdd1243dSDimitry Andric GCCTriple.setTriple(TripleText); 2264bdd1243dSDimitry Andric GCCInstallPath = std::string(InstallDir); 2265bdd1243dSDimitry Andric GCCParentLibPath = GCCInstallPath + "/../../.."; 2266bdd1243dSDimitry Andric IsValid = true; 2267bdd1243dSDimitry Andric } 2268bdd1243dSDimitry Andric return; 2269bdd1243dSDimitry Andric } 2270bdd1243dSDimitry Andric 22711db9f3b2SDimitry Andric // If --gcc-triple is specified use this instead of trying to 22721db9f3b2SDimitry Andric // auto-detect a triple. 22731db9f3b2SDimitry Andric if (const Arg *A = 22741db9f3b2SDimitry Andric Args.getLastArg(clang::driver::options::OPT_gcc_triple_EQ)) { 22751db9f3b2SDimitry Andric StringRef GCCTriple = A->getValue(); 22761db9f3b2SDimitry Andric CandidateTripleAliases.clear(); 22771db9f3b2SDimitry Andric CandidateTripleAliases.push_back(GCCTriple); 22781db9f3b2SDimitry Andric } 22791db9f3b2SDimitry Andric 22800b57cec5SDimitry Andric // Compute the set of prefixes for our search. 2281fe6060f1SDimitry Andric SmallVector<std::string, 8> Prefixes; 22820b57cec5SDimitry Andric StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot); 22830b57cec5SDimitry Andric if (GCCToolchainDir != "") { 22840b57cec5SDimitry Andric if (GCCToolchainDir.back() == '/') 22850b57cec5SDimitry Andric GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / 22860b57cec5SDimitry Andric 22875ffd83dbSDimitry Andric Prefixes.push_back(std::string(GCCToolchainDir)); 22880b57cec5SDimitry Andric } else { 22890b57cec5SDimitry Andric // If we have a SysRoot, try that first. 22900b57cec5SDimitry Andric if (!D.SysRoot.empty()) { 22910b57cec5SDimitry Andric Prefixes.push_back(D.SysRoot); 22920b57cec5SDimitry Andric AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); 22930b57cec5SDimitry Andric } 22940b57cec5SDimitry Andric 22950b57cec5SDimitry Andric // Then look for gcc installed alongside clang. 22960fca6ea1SDimitry Andric Prefixes.push_back(D.Dir + "/.."); 22970b57cec5SDimitry Andric 22980b57cec5SDimitry Andric // Next, look for prefix(es) that correspond to distribution-supplied gcc 22990b57cec5SDimitry Andric // installations. 23000b57cec5SDimitry Andric if (D.SysRoot.empty()) { 23010b57cec5SDimitry Andric // Typically /usr. 23020b57cec5SDimitry Andric AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); 23030b57cec5SDimitry Andric } 23040b57cec5SDimitry Andric 2305fe6060f1SDimitry Andric // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided. 2306fe6060f1SDimitry Andric // This avoids accidentally enforcing the system GCC version when using a 2307fe6060f1SDimitry Andric // custom toolchain. 23080b57cec5SDimitry Andric SmallVector<StringRef, 16> GentooTestTriples; 23090b57cec5SDimitry Andric // Try to match an exact triple as target triple first. 23100b57cec5SDimitry Andric // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for 23110b57cec5SDimitry Andric // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu" 23120b57cec5SDimitry Andric // may pick the libraries for x86_64-pc-linux-gnu even when exact matching 23130b57cec5SDimitry Andric // triple x86_64-gentoo-linux-gnu is present. 23140b57cec5SDimitry Andric GentooTestTriples.push_back(TargetTriple.str()); 23150b57cec5SDimitry Andric GentooTestTriples.append(CandidateTripleAliases.begin(), 23160b57cec5SDimitry Andric CandidateTripleAliases.end()); 23170b57cec5SDimitry Andric if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples, 23180b57cec5SDimitry Andric CandidateBiarchTripleAliases)) 23190b57cec5SDimitry Andric return; 23200b57cec5SDimitry Andric } 23210b57cec5SDimitry Andric 23220b57cec5SDimitry Andric // Loop over the various components which exist and select the best GCC 23230b57cec5SDimitry Andric // installation available. GCC installs are ranked by version number. 2324fe6060f1SDimitry Andric const GCCVersion VersionZero = GCCVersion::Parse("0.0.0"); 2325fe6060f1SDimitry Andric Version = VersionZero; 23260b57cec5SDimitry Andric for (const std::string &Prefix : Prefixes) { 2327e8d8bef9SDimitry Andric auto &VFS = D.getVFS(); 2328e8d8bef9SDimitry Andric if (!VFS.exists(Prefix)) 23290b57cec5SDimitry Andric continue; 23300b57cec5SDimitry Andric for (StringRef Suffix : CandidateLibDirs) { 233181ad6265SDimitry Andric const std::string LibDir = concat(Prefix, Suffix); 2332e8d8bef9SDimitry Andric if (!VFS.exists(LibDir)) 23330b57cec5SDimitry Andric continue; 2334e8d8bef9SDimitry Andric // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross. 2335e8d8bef9SDimitry Andric bool GCCDirExists = VFS.exists(LibDir + "/gcc"); 2336e8d8bef9SDimitry Andric bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); 23370b57cec5SDimitry Andric for (StringRef Candidate : CandidateTripleAliases) 2338e8d8bef9SDimitry Andric ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false, 2339e8d8bef9SDimitry Andric GCCDirExists, GCCCrossDirExists); 23400b57cec5SDimitry Andric } 23410b57cec5SDimitry Andric for (StringRef Suffix : CandidateBiarchLibDirs) { 23420b57cec5SDimitry Andric const std::string LibDir = Prefix + Suffix.str(); 2343e8d8bef9SDimitry Andric if (!VFS.exists(LibDir)) 23440b57cec5SDimitry Andric continue; 2345e8d8bef9SDimitry Andric bool GCCDirExists = VFS.exists(LibDir + "/gcc"); 2346e8d8bef9SDimitry Andric bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); 23470b57cec5SDimitry Andric for (StringRef Candidate : CandidateBiarchTripleAliases) 2348e8d8bef9SDimitry Andric ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true, 2349e8d8bef9SDimitry Andric GCCDirExists, GCCCrossDirExists); 23500b57cec5SDimitry Andric } 2351fe6060f1SDimitry Andric 2352fe6060f1SDimitry Andric // Skip other prefixes once a GCC installation is found. 2353fe6060f1SDimitry Andric if (Version > VersionZero) 2354fe6060f1SDimitry Andric break; 23550b57cec5SDimitry Andric } 23560b57cec5SDimitry Andric } 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { 23590b57cec5SDimitry Andric for (const auto &InstallPath : CandidateGCCInstallPaths) 23600b57cec5SDimitry Andric OS << "Found candidate GCC installation: " << InstallPath << "\n"; 23610b57cec5SDimitry Andric 23620b57cec5SDimitry Andric if (!GCCInstallPath.empty()) 23630b57cec5SDimitry Andric OS << "Selected GCC installation: " << GCCInstallPath << "\n"; 23640b57cec5SDimitry Andric 23650b57cec5SDimitry Andric for (const auto &Multilib : Multilibs) 23660b57cec5SDimitry Andric OS << "Candidate multilib: " << Multilib << "\n"; 23670b57cec5SDimitry Andric 23680b57cec5SDimitry Andric if (Multilibs.size() != 0 || !SelectedMultilib.isDefault()) 23690b57cec5SDimitry Andric OS << "Selected multilib: " << SelectedMultilib << "\n"; 23700b57cec5SDimitry Andric } 23710b57cec5SDimitry Andric 23720b57cec5SDimitry Andric bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { 237381ad6265SDimitry Andric if (BiarchSibling) { 2374bdd1243dSDimitry Andric M = *BiarchSibling; 23750b57cec5SDimitry Andric return true; 23760b57cec5SDimitry Andric } 23770b57cec5SDimitry Andric return false; 23780b57cec5SDimitry Andric } 23790b57cec5SDimitry Andric 23800b57cec5SDimitry Andric void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( 23810b57cec5SDimitry Andric const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes, 23820b57cec5SDimitry Andric StringRef SysRoot) { 23835f757f3fSDimitry Andric 23845f757f3fSDimitry Andric if (TargetTriple.isOSHaiku()) { 23855f757f3fSDimitry Andric Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools")); 23865f757f3fSDimitry Andric return; 23875f757f3fSDimitry Andric } 23885f757f3fSDimitry Andric 23895f757f3fSDimitry Andric if (TargetTriple.isOSSolaris()) { 23900b57cec5SDimitry Andric // Solaris is a special case. 23910b57cec5SDimitry Andric // The GCC installation is under 23920b57cec5SDimitry Andric // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/ 23930b57cec5SDimitry Andric // so we need to find those /usr/gcc/*/lib/gcc libdirs and go with 23940b57cec5SDimitry Andric // /usr/gcc/<version> as a prefix. 23950b57cec5SDimitry Andric 23968a4dda33SDimitry Andric SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes; 239781ad6265SDimitry Andric std::string PrefixDir = concat(SysRoot, "/usr/gcc"); 23980b57cec5SDimitry Andric std::error_code EC; 23990b57cec5SDimitry Andric for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC), 24000b57cec5SDimitry Andric LE; 24010b57cec5SDimitry Andric !EC && LI != LE; LI = LI.increment(EC)) { 24020b57cec5SDimitry Andric StringRef VersionText = llvm::sys::path::filename(LI->path()); 24030b57cec5SDimitry Andric GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 24040b57cec5SDimitry Andric 24050b57cec5SDimitry Andric // Filter out obviously bad entries. 24060b57cec5SDimitry Andric if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1)) 24070b57cec5SDimitry Andric continue; 24080b57cec5SDimitry Andric 24090b57cec5SDimitry Andric std::string CandidatePrefix = PrefixDir + "/" + VersionText.str(); 24100b57cec5SDimitry Andric std::string CandidateLibPath = CandidatePrefix + "/lib/gcc"; 24110b57cec5SDimitry Andric if (!D.getVFS().exists(CandidateLibPath)) 24120b57cec5SDimitry Andric continue; 24130b57cec5SDimitry Andric 24148a4dda33SDimitry Andric SolarisPrefixes.emplace_back( 24158a4dda33SDimitry Andric std::make_pair(CandidateVersion, CandidatePrefix)); 24160b57cec5SDimitry Andric } 24178a4dda33SDimitry Andric // Sort in reverse order so GCCInstallationDetector::init picks the latest. 24188a4dda33SDimitry Andric std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend()); 24198a4dda33SDimitry Andric for (auto p : SolarisPrefixes) 24208a4dda33SDimitry Andric Prefixes.emplace_back(p.second); 24210b57cec5SDimitry Andric return; 24220b57cec5SDimitry Andric } 24230b57cec5SDimitry Andric 242481ad6265SDimitry Andric // For Linux, if --sysroot is not specified, look for RHEL/CentOS devtoolsets 242581ad6265SDimitry Andric // and gcc-toolsets. 242681ad6265SDimitry Andric if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux && 242781ad6265SDimitry Andric D.getVFS().exists("/opt/rh")) { 2428f3fd488fSDimitry Andric // TODO: We may want to remove this, since the functionality 2429f3fd488fSDimitry Andric // can be achieved using config files. 2430f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr"); 2431f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr"); 2432f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr"); 2433f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-12/root/usr"); 2434f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-11/root/usr"); 2435f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-10/root/usr"); 2436f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-9/root/usr"); 2437f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); 2438f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); 2439f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); 2440f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-4/root/usr"); 2441f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-3/root/usr"); 2442f3fd488fSDimitry Andric Prefixes.push_back("/opt/rh/devtoolset-2/root/usr"); 244381ad6265SDimitry Andric } 244481ad6265SDimitry Andric 244581ad6265SDimitry Andric // Fall back to /usr which is used by most non-Solaris systems. 244681ad6265SDimitry Andric Prefixes.push_back(concat(SysRoot, "/usr")); 24470b57cec5SDimitry Andric } 24480b57cec5SDimitry Andric 24490b57cec5SDimitry Andric /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( 24500b57cec5SDimitry Andric const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, 24510b57cec5SDimitry Andric SmallVectorImpl<StringRef> &LibDirs, 24520b57cec5SDimitry Andric SmallVectorImpl<StringRef> &TripleAliases, 24530b57cec5SDimitry Andric SmallVectorImpl<StringRef> &BiarchLibDirs, 24540b57cec5SDimitry Andric SmallVectorImpl<StringRef> &BiarchTripleAliases) { 24550b57cec5SDimitry Andric // Declare a bunch of static data sets that we'll select between below. These 24560b57cec5SDimitry Andric // are specifically designed to always refer to string literals to avoid any 24570b57cec5SDimitry Andric // lifetime or initialization issues. 2458349cc55cSDimitry Andric // 2459349cc55cSDimitry Andric // The *Triples variables hard code some triples so that, for example, 2460349cc55cSDimitry Andric // --target=aarch64 (incomplete triple) can detect lib/aarch64-linux-gnu. 2461349cc55cSDimitry Andric // They are not needed when the user has correct LLVM_DEFAULT_TARGET_TRIPLE 2462349cc55cSDimitry Andric // and always uses the full --target (e.g. --target=aarch64-linux-gnu). The 2463349cc55cSDimitry Andric // lists should shrink over time. Please don't add more elements to *Triples. 24640b57cec5SDimitry Andric static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; 24650b57cec5SDimitry Andric static const char *const AArch64Triples[] = { 246662987288SDimitry Andric "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", 246762987288SDimitry Andric "aarch64-suse-linux"}; 24680b57cec5SDimitry Andric static const char *const AArch64beLibDirs[] = {"/lib"}; 24690fca6ea1SDimitry Andric static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu"}; 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric static const char *const ARMLibDirs[] = {"/lib"}; 2472349cc55cSDimitry Andric static const char *const ARMTriples[] = {"arm-linux-gnueabi"}; 24730b57cec5SDimitry Andric static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", 24740b57cec5SDimitry Andric "armv7hl-redhat-linux-gnueabi", 24750b57cec5SDimitry Andric "armv6hl-suse-linux-gnueabi", 24760b57cec5SDimitry Andric "armv7hl-suse-linux-gnueabi"}; 24770b57cec5SDimitry Andric static const char *const ARMebLibDirs[] = {"/lib"}; 2478349cc55cSDimitry Andric static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"}; 24790b57cec5SDimitry Andric static const char *const ARMebHFTriples[] = { 24800b57cec5SDimitry Andric "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric static const char *const AVRLibDirs[] = {"/lib"}; 24830b57cec5SDimitry Andric static const char *const AVRTriples[] = {"avr"}; 24840b57cec5SDimitry Andric 248581ad6265SDimitry Andric static const char *const CSKYLibDirs[] = {"/lib"}; 248681ad6265SDimitry Andric static const char *const CSKYTriples[] = { 248781ad6265SDimitry Andric "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"}; 248881ad6265SDimitry Andric 24890b57cec5SDimitry Andric static const char *const X86_64LibDirs[] = {"/lib64", "/lib"}; 24900b57cec5SDimitry Andric static const char *const X86_64Triples[] = { 24910b57cec5SDimitry Andric "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", 24920b57cec5SDimitry Andric "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", 24930b57cec5SDimitry Andric "x86_64-redhat-linux", "x86_64-suse-linux", 24940fca6ea1SDimitry Andric "x86_64-manbo-linux-gnu", "x86_64-slackware-linux", 24950fca6ea1SDimitry Andric "x86_64-unknown-linux", "x86_64-amazon-linux"}; 2496fe6060f1SDimitry Andric static const char *const X32Triples[] = {"x86_64-linux-gnux32", 2497fe6060f1SDimitry Andric "x86_64-pc-linux-gnux32"}; 2498fe6060f1SDimitry Andric static const char *const X32LibDirs[] = {"/libx32", "/lib"}; 24990b57cec5SDimitry Andric static const char *const X86LibDirs[] = {"/lib32", "/lib"}; 25000b57cec5SDimitry Andric static const char *const X86Triples[] = { 2501349cc55cSDimitry Andric "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu", 2502349cc55cSDimitry Andric "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux", 25037a6dacacSDimitry Andric "i586-suse-linux", "i686-montavista-linux", 2504fe6060f1SDimitry Andric }; 2505fe6060f1SDimitry Andric 2506bdd1243dSDimitry Andric static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"}; 2507bdd1243dSDimitry Andric static const char *const LoongArch64Triples[] = { 2508bdd1243dSDimitry Andric "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"}; 2509bdd1243dSDimitry Andric 2510fe6060f1SDimitry Andric static const char *const M68kLibDirs[] = {"/lib"}; 25110fca6ea1SDimitry Andric static const char *const M68kTriples[] = {"m68k-unknown-linux-gnu", 25120fca6ea1SDimitry Andric "m68k-suse-linux"}; 25130b57cec5SDimitry Andric 2514349cc55cSDimitry Andric static const char *const MIPSLibDirs[] = {"/libo32", "/lib"}; 25150b57cec5SDimitry Andric static const char *const MIPSTriples[] = { 25160b57cec5SDimitry Andric "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu", 25170b57cec5SDimitry Andric "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"}; 2518349cc55cSDimitry Andric static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"}; 25190fca6ea1SDimitry Andric static const char *const MIPSELTriples[] = {"mipsel-linux-gnu", 25200fca6ea1SDimitry Andric "mips-img-linux-gnu"}; 25210b57cec5SDimitry Andric 25220b57cec5SDimitry Andric static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; 25230b57cec5SDimitry Andric static const char *const MIPS64Triples[] = { 25240fca6ea1SDimitry Andric "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64-linux-gnuabi64", 25250b57cec5SDimitry Andric "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"}; 25260b57cec5SDimitry Andric static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"}; 25270b57cec5SDimitry Andric static const char *const MIPS64ELTriples[] = { 25280fca6ea1SDimitry Andric "mips-mti-linux-gnu", "mips-img-linux-gnu", "mips64el-linux-gnuabi64", 2529349cc55cSDimitry Andric "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"}; 25300b57cec5SDimitry Andric 25310b57cec5SDimitry Andric static const char *const MIPSN32LibDirs[] = {"/lib32"}; 25320b57cec5SDimitry Andric static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32", 25330b57cec5SDimitry Andric "mipsisa64r6-linux-gnuabin32"}; 25340b57cec5SDimitry Andric static const char *const MIPSN32ELLibDirs[] = {"/lib32"}; 25350b57cec5SDimitry Andric static const char *const MIPSN32ELTriples[] = { 25360b57cec5SDimitry Andric "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"}; 25370b57cec5SDimitry Andric 25380b57cec5SDimitry Andric static const char *const MSP430LibDirs[] = {"/lib"}; 25390b57cec5SDimitry Andric static const char *const MSP430Triples[] = {"msp430-elf"}; 25400b57cec5SDimitry Andric 25410b57cec5SDimitry Andric static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; 25420b57cec5SDimitry Andric static const char *const PPCTriples[] = { 25430fca6ea1SDimitry Andric "powerpc-unknown-linux-gnu", 2544480093f4SDimitry Andric // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a 2545480093f4SDimitry Andric // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux". 2546480093f4SDimitry Andric "powerpc64-suse-linux", "powerpc-montavista-linuxspe"}; 2547e8d8bef9SDimitry Andric static const char *const PPCLELibDirs[] = {"/lib32", "/lib"}; 25480fca6ea1SDimitry Andric static const char *const PPCLETriples[] = {"powerpcle-unknown-linux-gnu", 2549e8d8bef9SDimitry Andric "powerpcle-linux-musl"}; 2550e8d8bef9SDimitry Andric 25510b57cec5SDimitry Andric static const char *const PPC64LibDirs[] = {"/lib64", "/lib"}; 25520fca6ea1SDimitry Andric static const char *const PPC64Triples[] = {"powerpc64-unknown-linux-gnu", 25530fca6ea1SDimitry Andric "powerpc64-suse-linux", 25540fca6ea1SDimitry Andric "ppc64-redhat-linux"}; 25550b57cec5SDimitry Andric static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"}; 25560b57cec5SDimitry Andric static const char *const PPC64LETriples[] = { 25570fca6ea1SDimitry Andric "powerpc64le-unknown-linux-gnu", "powerpc64le-none-linux-gnu", 25580fca6ea1SDimitry Andric "powerpc64le-suse-linux", "ppc64le-redhat-linux"}; 25590b57cec5SDimitry Andric 25600b57cec5SDimitry Andric static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"}; 25610b57cec5SDimitry Andric static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu", 25620b57cec5SDimitry Andric "riscv32-unknown-elf"}; 25630b57cec5SDimitry Andric static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"}; 25640b57cec5SDimitry Andric static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu", 2565349cc55cSDimitry Andric "riscv64-unknown-elf"}; 25660b57cec5SDimitry Andric 25670b57cec5SDimitry Andric static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; 25680b57cec5SDimitry Andric static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", 25690b57cec5SDimitry Andric "sparcv8-linux-gnu"}; 25700b57cec5SDimitry Andric static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"}; 25710b57cec5SDimitry Andric static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu", 25720b57cec5SDimitry Andric "sparcv9-linux-gnu"}; 25730b57cec5SDimitry Andric 25740b57cec5SDimitry Andric static const char *const SystemZLibDirs[] = {"/lib64", "/lib"}; 25750b57cec5SDimitry Andric static const char *const SystemZTriples[] = { 25760fca6ea1SDimitry Andric "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", "s390x-suse-linux", 25770fca6ea1SDimitry Andric "s390x-redhat-linux"}; 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andric using std::begin; 25800b57cec5SDimitry Andric using std::end; 25810b57cec5SDimitry Andric 25825f757f3fSDimitry Andric if (TargetTriple.isOSSolaris()) { 25830b57cec5SDimitry Andric static const char *const SolarisLibDirs[] = {"/lib"}; 25840b57cec5SDimitry Andric static const char *const SolarisSparcV8Triples[] = { 25855f757f3fSDimitry Andric "sparc-sun-solaris2.11"}; 25860b57cec5SDimitry Andric static const char *const SolarisSparcV9Triples[] = { 25875f757f3fSDimitry Andric "sparcv9-sun-solaris2.11"}; 25885f757f3fSDimitry Andric static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"}; 25895f757f3fSDimitry Andric static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"}; 25900b57cec5SDimitry Andric LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs)); 25910b57cec5SDimitry Andric BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs)); 25920b57cec5SDimitry Andric switch (TargetTriple.getArch()) { 25930b57cec5SDimitry Andric case llvm::Triple::x86: 25940b57cec5SDimitry Andric TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples)); 25950b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SolarisX86_64Triples), 25960b57cec5SDimitry Andric end(SolarisX86_64Triples)); 25970b57cec5SDimitry Andric break; 25980b57cec5SDimitry Andric case llvm::Triple::x86_64: 25990b57cec5SDimitry Andric TripleAliases.append(begin(SolarisX86_64Triples), 26000b57cec5SDimitry Andric end(SolarisX86_64Triples)); 26010b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SolarisX86Triples), 26020b57cec5SDimitry Andric end(SolarisX86Triples)); 26030b57cec5SDimitry Andric break; 26040b57cec5SDimitry Andric case llvm::Triple::sparc: 26050b57cec5SDimitry Andric TripleAliases.append(begin(SolarisSparcV8Triples), 26060b57cec5SDimitry Andric end(SolarisSparcV8Triples)); 26070b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SolarisSparcV9Triples), 26080b57cec5SDimitry Andric end(SolarisSparcV9Triples)); 26090b57cec5SDimitry Andric break; 26100b57cec5SDimitry Andric case llvm::Triple::sparcv9: 26110b57cec5SDimitry Andric TripleAliases.append(begin(SolarisSparcV9Triples), 26120b57cec5SDimitry Andric end(SolarisSparcV9Triples)); 26130b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SolarisSparcV8Triples), 26140b57cec5SDimitry Andric end(SolarisSparcV8Triples)); 26150b57cec5SDimitry Andric break; 26160b57cec5SDimitry Andric default: 26170b57cec5SDimitry Andric break; 26180b57cec5SDimitry Andric } 26190b57cec5SDimitry Andric return; 26200b57cec5SDimitry Andric } 26210b57cec5SDimitry Andric 26220b57cec5SDimitry Andric // Android targets should not use GNU/Linux tools or libraries. 26230b57cec5SDimitry Andric if (TargetTriple.isAndroid()) { 26240b57cec5SDimitry Andric static const char *const AArch64AndroidTriples[] = { 26250b57cec5SDimitry Andric "aarch64-linux-android"}; 26260b57cec5SDimitry Andric static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"}; 26270b57cec5SDimitry Andric static const char *const X86AndroidTriples[] = {"i686-linux-android"}; 26280b57cec5SDimitry Andric static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"}; 26290b57cec5SDimitry Andric 26300b57cec5SDimitry Andric switch (TargetTriple.getArch()) { 26310b57cec5SDimitry Andric case llvm::Triple::aarch64: 26320b57cec5SDimitry Andric LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); 26330b57cec5SDimitry Andric TripleAliases.append(begin(AArch64AndroidTriples), 26340b57cec5SDimitry Andric end(AArch64AndroidTriples)); 26350b57cec5SDimitry Andric break; 26360b57cec5SDimitry Andric case llvm::Triple::arm: 26370b57cec5SDimitry Andric case llvm::Triple::thumb: 26380b57cec5SDimitry Andric LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs)); 26390b57cec5SDimitry Andric TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples)); 26400b57cec5SDimitry Andric break; 26410b57cec5SDimitry Andric case llvm::Triple::x86_64: 26420b57cec5SDimitry Andric LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 26430b57cec5SDimitry Andric TripleAliases.append(begin(X86_64AndroidTriples), 26440b57cec5SDimitry Andric end(X86_64AndroidTriples)); 26450b57cec5SDimitry Andric BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); 26460b57cec5SDimitry Andric BiarchTripleAliases.append(begin(X86AndroidTriples), 26470b57cec5SDimitry Andric end(X86AndroidTriples)); 26480b57cec5SDimitry Andric break; 26490b57cec5SDimitry Andric case llvm::Triple::x86: 26500b57cec5SDimitry Andric LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); 26510b57cec5SDimitry Andric TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples)); 26520b57cec5SDimitry Andric BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 26530b57cec5SDimitry Andric BiarchTripleAliases.append(begin(X86_64AndroidTriples), 26540b57cec5SDimitry Andric end(X86_64AndroidTriples)); 26550b57cec5SDimitry Andric break; 26560b57cec5SDimitry Andric default: 26570b57cec5SDimitry Andric break; 26580b57cec5SDimitry Andric } 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric return; 26610b57cec5SDimitry Andric } 26620b57cec5SDimitry Andric 26637a6dacacSDimitry Andric if (TargetTriple.isOSHurd()) { 26647a6dacacSDimitry Andric switch (TargetTriple.getArch()) { 26657a6dacacSDimitry Andric case llvm::Triple::x86_64: 26667a6dacacSDimitry Andric LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 26677a6dacacSDimitry Andric TripleAliases.push_back("x86_64-gnu"); 26687a6dacacSDimitry Andric break; 26697a6dacacSDimitry Andric case llvm::Triple::x86: 26707a6dacacSDimitry Andric LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); 26717a6dacacSDimitry Andric TripleAliases.push_back("i686-gnu"); 26727a6dacacSDimitry Andric break; 26737a6dacacSDimitry Andric default: 26747a6dacacSDimitry Andric break; 26757a6dacacSDimitry Andric } 26767a6dacacSDimitry Andric 26777a6dacacSDimitry Andric return; 26787a6dacacSDimitry Andric } 26797a6dacacSDimitry Andric 26800b57cec5SDimitry Andric switch (TargetTriple.getArch()) { 26810b57cec5SDimitry Andric case llvm::Triple::aarch64: 26820b57cec5SDimitry Andric LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); 26830b57cec5SDimitry Andric TripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); 26840b57cec5SDimitry Andric BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); 26850b57cec5SDimitry Andric BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); 26860b57cec5SDimitry Andric break; 26870b57cec5SDimitry Andric case llvm::Triple::aarch64_be: 26880b57cec5SDimitry Andric LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); 26890b57cec5SDimitry Andric TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); 26900b57cec5SDimitry Andric BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); 26910b57cec5SDimitry Andric BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); 26920b57cec5SDimitry Andric break; 26930b57cec5SDimitry Andric case llvm::Triple::arm: 26940b57cec5SDimitry Andric case llvm::Triple::thumb: 26950b57cec5SDimitry Andric LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs)); 2696297eecfbSDimitry Andric if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF || 2697*d686ce93SDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 || 2698297eecfbSDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF || 2699297eecfbSDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::EABIHF) { 27000b57cec5SDimitry Andric TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples)); 27010b57cec5SDimitry Andric } else { 27020b57cec5SDimitry Andric TripleAliases.append(begin(ARMTriples), end(ARMTriples)); 27030b57cec5SDimitry Andric } 27040b57cec5SDimitry Andric break; 27050b57cec5SDimitry Andric case llvm::Triple::armeb: 27060b57cec5SDimitry Andric case llvm::Triple::thumbeb: 27070b57cec5SDimitry Andric LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs)); 2708297eecfbSDimitry Andric if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF || 2709*d686ce93SDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHFT64 || 2710297eecfbSDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::MuslEABIHF || 2711297eecfbSDimitry Andric TargetTriple.getEnvironment() == llvm::Triple::EABIHF) { 27120b57cec5SDimitry Andric TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples)); 27130b57cec5SDimitry Andric } else { 27140b57cec5SDimitry Andric TripleAliases.append(begin(ARMebTriples), end(ARMebTriples)); 27150b57cec5SDimitry Andric } 27160b57cec5SDimitry Andric break; 27170b57cec5SDimitry Andric case llvm::Triple::avr: 27180b57cec5SDimitry Andric LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs)); 27190b57cec5SDimitry Andric TripleAliases.append(begin(AVRTriples), end(AVRTriples)); 27200b57cec5SDimitry Andric break; 272181ad6265SDimitry Andric case llvm::Triple::csky: 272281ad6265SDimitry Andric LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs)); 272381ad6265SDimitry Andric TripleAliases.append(begin(CSKYTriples), end(CSKYTriples)); 272481ad6265SDimitry Andric break; 27250b57cec5SDimitry Andric case llvm::Triple::x86_64: 2726fe6060f1SDimitry Andric if (TargetTriple.isX32()) { 2727fe6060f1SDimitry Andric LibDirs.append(begin(X32LibDirs), end(X32LibDirs)); 2728fe6060f1SDimitry Andric TripleAliases.append(begin(X32Triples), end(X32Triples)); 2729fe6060f1SDimitry Andric BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 27300b57cec5SDimitry Andric BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); 27310b57cec5SDimitry Andric } else { 2732fe6060f1SDimitry Andric LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 2733fe6060f1SDimitry Andric TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); 2734fe6060f1SDimitry Andric BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); 2735fe6060f1SDimitry Andric BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); 2736fe6060f1SDimitry Andric } 27370b57cec5SDimitry Andric BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); 27380b57cec5SDimitry Andric BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); 27390b57cec5SDimitry Andric break; 27400b57cec5SDimitry Andric case llvm::Triple::x86: 27410b57cec5SDimitry Andric LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); 27420b57cec5SDimitry Andric // MCU toolchain is 32 bit only and its triple alias is TargetTriple 27430b57cec5SDimitry Andric // itself, which will be appended below. 27440b57cec5SDimitry Andric if (!TargetTriple.isOSIAMCU()) { 27450b57cec5SDimitry Andric TripleAliases.append(begin(X86Triples), end(X86Triples)); 27460b57cec5SDimitry Andric BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); 27470b57cec5SDimitry Andric BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); 2748fe6060f1SDimitry Andric BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); 2749fe6060f1SDimitry Andric BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); 27500b57cec5SDimitry Andric } 27510b57cec5SDimitry Andric break; 2752bdd1243dSDimitry Andric // TODO: Handle loongarch32. 2753bdd1243dSDimitry Andric case llvm::Triple::loongarch64: 2754bdd1243dSDimitry Andric LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs)); 2755bdd1243dSDimitry Andric TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples)); 2756bdd1243dSDimitry Andric break; 2757fe6060f1SDimitry Andric case llvm::Triple::m68k: 2758fe6060f1SDimitry Andric LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs)); 2759fe6060f1SDimitry Andric TripleAliases.append(begin(M68kTriples), end(M68kTriples)); 2760fe6060f1SDimitry Andric break; 27610b57cec5SDimitry Andric case llvm::Triple::mips: 27620b57cec5SDimitry Andric LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); 27630b57cec5SDimitry Andric TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); 27640b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); 27650b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); 27660b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); 27670b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); 27680b57cec5SDimitry Andric break; 27690b57cec5SDimitry Andric case llvm::Triple::mipsel: 27700b57cec5SDimitry Andric LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); 27710b57cec5SDimitry Andric TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); 27720b57cec5SDimitry Andric TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); 27730b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); 27740b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); 27750b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); 27760b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); 27770b57cec5SDimitry Andric break; 27780b57cec5SDimitry Andric case llvm::Triple::mips64: 27790b57cec5SDimitry Andric LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); 27800b57cec5SDimitry Andric TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); 27810b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); 27820b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); 27830b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); 27840b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); 27850b57cec5SDimitry Andric break; 27860b57cec5SDimitry Andric case llvm::Triple::mips64el: 27870b57cec5SDimitry Andric LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); 27880b57cec5SDimitry Andric TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); 27890b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); 27900b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); 27910b57cec5SDimitry Andric BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); 27920b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); 27930b57cec5SDimitry Andric BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); 27940b57cec5SDimitry Andric break; 27950b57cec5SDimitry Andric case llvm::Triple::msp430: 27960b57cec5SDimitry Andric LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs)); 27970b57cec5SDimitry Andric TripleAliases.append(begin(MSP430Triples), end(MSP430Triples)); 27980b57cec5SDimitry Andric break; 27990b57cec5SDimitry Andric case llvm::Triple::ppc: 28000b57cec5SDimitry Andric LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); 28010b57cec5SDimitry Andric TripleAliases.append(begin(PPCTriples), end(PPCTriples)); 28020b57cec5SDimitry Andric BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); 28030b57cec5SDimitry Andric BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); 28040b57cec5SDimitry Andric break; 2805e8d8bef9SDimitry Andric case llvm::Triple::ppcle: 2806e8d8bef9SDimitry Andric LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); 2807e8d8bef9SDimitry Andric TripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); 2808e8d8bef9SDimitry Andric BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); 2809e8d8bef9SDimitry Andric BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); 2810e8d8bef9SDimitry Andric break; 28110b57cec5SDimitry Andric case llvm::Triple::ppc64: 28120b57cec5SDimitry Andric LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); 28130b57cec5SDimitry Andric TripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); 28140b57cec5SDimitry Andric BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); 28150b57cec5SDimitry Andric BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples)); 28160b57cec5SDimitry Andric break; 28170b57cec5SDimitry Andric case llvm::Triple::ppc64le: 28180b57cec5SDimitry Andric LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); 28190b57cec5SDimitry Andric TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); 2820e8d8bef9SDimitry Andric BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); 2821e8d8bef9SDimitry Andric BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); 28220b57cec5SDimitry Andric break; 28230b57cec5SDimitry Andric case llvm::Triple::riscv32: 28240b57cec5SDimitry Andric LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); 28250b57cec5SDimitry Andric TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); 28260b57cec5SDimitry Andric BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); 28270b57cec5SDimitry Andric BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); 28280b57cec5SDimitry Andric break; 28290b57cec5SDimitry Andric case llvm::Triple::riscv64: 28300b57cec5SDimitry Andric LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); 28310b57cec5SDimitry Andric TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); 28320b57cec5SDimitry Andric BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); 28330b57cec5SDimitry Andric BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); 28340b57cec5SDimitry Andric break; 28350b57cec5SDimitry Andric case llvm::Triple::sparc: 28360b57cec5SDimitry Andric case llvm::Triple::sparcel: 28370b57cec5SDimitry Andric LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); 28380b57cec5SDimitry Andric TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); 28390b57cec5SDimitry Andric BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); 28400b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); 28410b57cec5SDimitry Andric break; 28420b57cec5SDimitry Andric case llvm::Triple::sparcv9: 28430b57cec5SDimitry Andric LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); 28440b57cec5SDimitry Andric TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); 28450b57cec5SDimitry Andric BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); 28460b57cec5SDimitry Andric BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); 28470b57cec5SDimitry Andric break; 28480b57cec5SDimitry Andric case llvm::Triple::systemz: 28490b57cec5SDimitry Andric LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs)); 28500b57cec5SDimitry Andric TripleAliases.append(begin(SystemZTriples), end(SystemZTriples)); 28510b57cec5SDimitry Andric break; 28520b57cec5SDimitry Andric default: 28530b57cec5SDimitry Andric // By default, just rely on the standard lib directories and the original 28540b57cec5SDimitry Andric // triple. 28550b57cec5SDimitry Andric break; 28560b57cec5SDimitry Andric } 28570b57cec5SDimitry Andric 28580b57cec5SDimitry Andric // Also include the multiarch variant if it's different. 28590b57cec5SDimitry Andric if (TargetTriple.str() != BiarchTriple.str()) 28600b57cec5SDimitry Andric BiarchTripleAliases.push_back(BiarchTriple.str()); 28610b57cec5SDimitry Andric } 28620b57cec5SDimitry Andric 28630b57cec5SDimitry Andric bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( 28640b57cec5SDimitry Andric const llvm::Triple &TargetTriple, const ArgList &Args, 28650b57cec5SDimitry Andric StringRef Path, bool NeedsBiarchSuffix) { 28660b57cec5SDimitry Andric llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); 28670b57cec5SDimitry Andric DetectedMultilibs Detected; 28680b57cec5SDimitry Andric 28690b57cec5SDimitry Andric // Android standalone toolchain could have multilibs for ARM and Thumb. 28700b57cec5SDimitry Andric // Debian mips multilibs behave more like the rest of the biarch ones, 28710b57cec5SDimitry Andric // so handle them there 28720b57cec5SDimitry Andric if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) { 28730b57cec5SDimitry Andric // It should also work without multilibs in a simplified toolchain. 28740b57cec5SDimitry Andric findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected); 287581ad6265SDimitry Andric } else if (TargetTriple.isCSKY()) { 287681ad6265SDimitry Andric findCSKYMultilibs(D, TargetTriple, Path, Args, Detected); 28770b57cec5SDimitry Andric } else if (TargetTriple.isMIPS()) { 28780b57cec5SDimitry Andric if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) 28790b57cec5SDimitry Andric return false; 28800b57cec5SDimitry Andric } else if (TargetTriple.isRISCV()) { 28810b57cec5SDimitry Andric findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); 28820b57cec5SDimitry Andric } else if (isMSP430(TargetArch)) { 28830b57cec5SDimitry Andric findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); 28840b57cec5SDimitry Andric } else if (TargetArch == llvm::Triple::avr) { 28850b57cec5SDimitry Andric // AVR has no multilibs. 28860b57cec5SDimitry Andric } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, 28870b57cec5SDimitry Andric NeedsBiarchSuffix, Detected)) { 28880b57cec5SDimitry Andric return false; 28890b57cec5SDimitry Andric } 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric Multilibs = Detected.Multilibs; 289206c3fb27SDimitry Andric SelectedMultilib = Detected.SelectedMultilibs.empty() 289306c3fb27SDimitry Andric ? Multilib() 289406c3fb27SDimitry Andric : Detected.SelectedMultilibs.back(); 28950b57cec5SDimitry Andric BiarchSibling = Detected.BiarchSibling; 28960b57cec5SDimitry Andric 28970b57cec5SDimitry Andric return true; 28980b57cec5SDimitry Andric } 28990b57cec5SDimitry Andric 29000b57cec5SDimitry Andric void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( 29010b57cec5SDimitry Andric const llvm::Triple &TargetTriple, const ArgList &Args, 29020b57cec5SDimitry Andric const std::string &LibDir, StringRef CandidateTriple, 2903e8d8bef9SDimitry Andric bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) { 29040b57cec5SDimitry Andric // Locations relative to the system lib directory where GCC's triple-specific 29050b57cec5SDimitry Andric // directories might reside. 29060b57cec5SDimitry Andric struct GCCLibSuffix { 29070b57cec5SDimitry Andric // Path from system lib directory to GCC triple-specific directory. 29080b57cec5SDimitry Andric std::string LibSuffix; 29090b57cec5SDimitry Andric // Path from GCC triple-specific directory back to system lib directory. 29100b57cec5SDimitry Andric // This is one '..' component per component in LibSuffix. 29110b57cec5SDimitry Andric StringRef ReversePath; 29120b57cec5SDimitry Andric // Whether this library suffix is relevant for the triple. 29130b57cec5SDimitry Andric bool Active; 29140b57cec5SDimitry Andric } Suffixes[] = { 29150b57cec5SDimitry Andric // This is the normal place. 2916e8d8bef9SDimitry Andric {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists}, 29170b57cec5SDimitry Andric 29180b57cec5SDimitry Andric // Debian puts cross-compilers in gcc-cross. 2919e8d8bef9SDimitry Andric {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists}, 29200b57cec5SDimitry Andric 29210b57cec5SDimitry Andric // The Freescale PPC SDK has the gcc libraries in 29220b57cec5SDimitry Andric // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do 29230b57cec5SDimitry Andric // this on Freescale triples, though, since some systems put a *lot* of 29240b57cec5SDimitry Andric // files in that location, not just GCC installation data. 29250b57cec5SDimitry Andric {CandidateTriple.str(), "..", 29260b57cec5SDimitry Andric TargetTriple.getVendor() == llvm::Triple::Freescale || 2927fe6060f1SDimitry Andric TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}}; 29280b57cec5SDimitry Andric 29290b57cec5SDimitry Andric for (auto &Suffix : Suffixes) { 29300b57cec5SDimitry Andric if (!Suffix.Active) 29310b57cec5SDimitry Andric continue; 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric StringRef LibSuffix = Suffix.LibSuffix; 29340b57cec5SDimitry Andric std::error_code EC; 29350b57cec5SDimitry Andric for (llvm::vfs::directory_iterator 29360b57cec5SDimitry Andric LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC), 29370b57cec5SDimitry Andric LE; 29380b57cec5SDimitry Andric !EC && LI != LE; LI = LI.increment(EC)) { 29390b57cec5SDimitry Andric StringRef VersionText = llvm::sys::path::filename(LI->path()); 29400b57cec5SDimitry Andric GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); 29410b57cec5SDimitry Andric if (CandidateVersion.Major != -1) // Filter obviously bad entries. 29425ffd83dbSDimitry Andric if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second) 29430b57cec5SDimitry Andric continue; // Saw this path before; no need to look at it again. 29440b57cec5SDimitry Andric if (CandidateVersion.isOlderThan(4, 1, 1)) 29450b57cec5SDimitry Andric continue; 29460b57cec5SDimitry Andric if (CandidateVersion <= Version) 29470b57cec5SDimitry Andric continue; 29480b57cec5SDimitry Andric 29490b57cec5SDimitry Andric if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(), 29500b57cec5SDimitry Andric NeedsBiarchSuffix)) 29510b57cec5SDimitry Andric continue; 29520b57cec5SDimitry Andric 29530b57cec5SDimitry Andric Version = CandidateVersion; 29540b57cec5SDimitry Andric GCCTriple.setTriple(CandidateTriple); 29550b57cec5SDimitry Andric // FIXME: We hack together the directory name here instead of 29560b57cec5SDimitry Andric // using LI to ensure stable path separators across Windows and 29570b57cec5SDimitry Andric // Linux. 29580b57cec5SDimitry Andric GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str(); 29590b57cec5SDimitry Andric GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str(); 29600b57cec5SDimitry Andric IsValid = true; 29610b57cec5SDimitry Andric } 29620b57cec5SDimitry Andric } 29630b57cec5SDimitry Andric } 29640b57cec5SDimitry Andric 29650b57cec5SDimitry Andric bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs( 29660b57cec5SDimitry Andric const llvm::Triple &TargetTriple, const ArgList &Args, 29670b57cec5SDimitry Andric const SmallVectorImpl<StringRef> &CandidateTriples, 29680b57cec5SDimitry Andric const SmallVectorImpl<StringRef> &CandidateBiarchTriples) { 296981ad6265SDimitry Andric if (!D.getVFS().exists(concat(D.SysRoot, GentooConfigDir))) 2970e8d8bef9SDimitry Andric return false; 2971e8d8bef9SDimitry Andric 29720b57cec5SDimitry Andric for (StringRef CandidateTriple : CandidateTriples) { 29730b57cec5SDimitry Andric if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) 29740b57cec5SDimitry Andric return true; 29750b57cec5SDimitry Andric } 29760b57cec5SDimitry Andric 29770b57cec5SDimitry Andric for (StringRef CandidateTriple : CandidateBiarchTriples) { 29780b57cec5SDimitry Andric if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true)) 29790b57cec5SDimitry Andric return true; 29800b57cec5SDimitry Andric } 29810b57cec5SDimitry Andric return false; 29820b57cec5SDimitry Andric } 29830b57cec5SDimitry Andric 29840b57cec5SDimitry Andric bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( 29850b57cec5SDimitry Andric const llvm::Triple &TargetTriple, const ArgList &Args, 29860b57cec5SDimitry Andric StringRef CandidateTriple, bool NeedsBiarchSuffix) { 29870b57cec5SDimitry Andric llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = 298881ad6265SDimitry Andric D.getVFS().getBufferForFile(concat(D.SysRoot, GentooConfigDir, 298981ad6265SDimitry Andric "/config-" + CandidateTriple.str())); 29900b57cec5SDimitry Andric if (File) { 29910b57cec5SDimitry Andric SmallVector<StringRef, 2> Lines; 29920b57cec5SDimitry Andric File.get()->getBuffer().split(Lines, "\n"); 29930b57cec5SDimitry Andric for (StringRef Line : Lines) { 29940b57cec5SDimitry Andric Line = Line.trim(); 29950b57cec5SDimitry Andric // CURRENT=triple-version 29960b57cec5SDimitry Andric if (!Line.consume_front("CURRENT=")) 29970b57cec5SDimitry Andric continue; 29980b57cec5SDimitry Andric // Process the config file pointed to by CURRENT. 29990b57cec5SDimitry Andric llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile = 300081ad6265SDimitry Andric D.getVFS().getBufferForFile( 300181ad6265SDimitry Andric concat(D.SysRoot, GentooConfigDir, "/" + Line)); 30020b57cec5SDimitry Andric std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-'); 30030b57cec5SDimitry Andric // List of paths to scan for libraries. 30040b57cec5SDimitry Andric SmallVector<StringRef, 4> GentooScanPaths; 30050b57cec5SDimitry Andric // Scan the Config file to find installed GCC libraries path. 30060b57cec5SDimitry Andric // Typical content of the GCC config file: 30070b57cec5SDimitry Andric // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/ 30080b57cec5SDimitry Andric // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32" 30090b57cec5SDimitry Andric // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man" 30100b57cec5SDimitry Andric // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info" 30110b57cec5SDimitry Andric // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4" 30120b57cec5SDimitry Andric // We are looking for the paths listed in LDPATH=... . 30130b57cec5SDimitry Andric if (ConfigFile) { 30140b57cec5SDimitry Andric SmallVector<StringRef, 2> ConfigLines; 30150b57cec5SDimitry Andric ConfigFile.get()->getBuffer().split(ConfigLines, "\n"); 30160b57cec5SDimitry Andric for (StringRef ConfLine : ConfigLines) { 30170b57cec5SDimitry Andric ConfLine = ConfLine.trim(); 30180b57cec5SDimitry Andric if (ConfLine.consume_front("LDPATH=")) { 30190b57cec5SDimitry Andric // Drop '"' from front and back if present. 30200b57cec5SDimitry Andric ConfLine.consume_back("\""); 30210b57cec5SDimitry Andric ConfLine.consume_front("\""); 30220b57cec5SDimitry Andric // Get all paths sperated by ':' 30230b57cec5SDimitry Andric ConfLine.split(GentooScanPaths, ':', -1, /*AllowEmpty*/ false); 30240b57cec5SDimitry Andric } 30250b57cec5SDimitry Andric } 30260b57cec5SDimitry Andric } 30270b57cec5SDimitry Andric // Test the path based on the version in /etc/env.d/gcc/config-{tuple}. 30280b57cec5SDimitry Andric std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/" 30290b57cec5SDimitry Andric + ActiveVersion.second.str(); 30300b57cec5SDimitry Andric GentooScanPaths.push_back(StringRef(basePath)); 30310b57cec5SDimitry Andric 30320b57cec5SDimitry Andric // Scan all paths for GCC libraries. 30330b57cec5SDimitry Andric for (const auto &GentooScanPath : GentooScanPaths) { 303481ad6265SDimitry Andric std::string GentooPath = concat(D.SysRoot, GentooScanPath); 30350b57cec5SDimitry Andric if (D.getVFS().exists(GentooPath + "/crtbegin.o")) { 30360b57cec5SDimitry Andric if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath, 30370b57cec5SDimitry Andric NeedsBiarchSuffix)) 30380b57cec5SDimitry Andric continue; 30390b57cec5SDimitry Andric 30400b57cec5SDimitry Andric Version = GCCVersion::Parse(ActiveVersion.second); 30410b57cec5SDimitry Andric GCCInstallPath = GentooPath; 30420b57cec5SDimitry Andric GCCParentLibPath = GentooPath + std::string("/../../.."); 30430b57cec5SDimitry Andric GCCTriple.setTriple(ActiveVersion.first); 30440b57cec5SDimitry Andric IsValid = true; 30450b57cec5SDimitry Andric return true; 30460b57cec5SDimitry Andric } 30470b57cec5SDimitry Andric } 30480b57cec5SDimitry Andric } 30490b57cec5SDimitry Andric } 30500b57cec5SDimitry Andric 30510b57cec5SDimitry Andric return false; 30520b57cec5SDimitry Andric } 30530b57cec5SDimitry Andric 30540b57cec5SDimitry Andric Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple, 30550b57cec5SDimitry Andric const ArgList &Args) 30560b57cec5SDimitry Andric : ToolChain(D, Triple, Args), GCCInstallation(D), 30575ffd83dbSDimitry Andric CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) { 30580b57cec5SDimitry Andric getProgramPaths().push_back(getDriver().Dir); 30590b57cec5SDimitry Andric } 30600b57cec5SDimitry Andric 30610b57cec5SDimitry Andric Generic_GCC::~Generic_GCC() {} 30620b57cec5SDimitry Andric 30630b57cec5SDimitry Andric Tool *Generic_GCC::getTool(Action::ActionClass AC) const { 30640b57cec5SDimitry Andric switch (AC) { 30650b57cec5SDimitry Andric case Action::PreprocessJobClass: 30660b57cec5SDimitry Andric if (!Preprocess) 30670b57cec5SDimitry Andric Preprocess.reset(new clang::driver::tools::gcc::Preprocessor(*this)); 30680b57cec5SDimitry Andric return Preprocess.get(); 30690b57cec5SDimitry Andric case Action::CompileJobClass: 30700b57cec5SDimitry Andric if (!Compile) 30710b57cec5SDimitry Andric Compile.reset(new tools::gcc::Compiler(*this)); 30720b57cec5SDimitry Andric return Compile.get(); 30730b57cec5SDimitry Andric default: 30740b57cec5SDimitry Andric return ToolChain::getTool(AC); 30750b57cec5SDimitry Andric } 30760b57cec5SDimitry Andric } 30770b57cec5SDimitry Andric 30780b57cec5SDimitry Andric Tool *Generic_GCC::buildAssembler() const { 30790b57cec5SDimitry Andric return new tools::gnutools::Assembler(*this); 30800b57cec5SDimitry Andric } 30810b57cec5SDimitry Andric 30820b57cec5SDimitry Andric Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); } 30830b57cec5SDimitry Andric 30840b57cec5SDimitry Andric void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { 30850b57cec5SDimitry Andric // Print the information about how we detected the GCC installation. 30860b57cec5SDimitry Andric GCCInstallation.print(OS); 308706c3fb27SDimitry Andric CudaInstallation->print(OS); 308806c3fb27SDimitry Andric RocmInstallation->print(OS); 30890b57cec5SDimitry Andric } 30900b57cec5SDimitry Andric 3091bdd1243dSDimitry Andric ToolChain::UnwindTableLevel 3092bdd1243dSDimitry Andric Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const { 3093e8d8bef9SDimitry Andric switch (getArch()) { 3094e8d8bef9SDimitry Andric case llvm::Triple::aarch64: 30955f757f3fSDimitry Andric case llvm::Triple::aarch64_be: 3096e8d8bef9SDimitry Andric case llvm::Triple::ppc: 3097e8d8bef9SDimitry Andric case llvm::Triple::ppcle: 3098e8d8bef9SDimitry Andric case llvm::Triple::ppc64: 3099e8d8bef9SDimitry Andric case llvm::Triple::ppc64le: 310006c3fb27SDimitry Andric case llvm::Triple::riscv32: 310106c3fb27SDimitry Andric case llvm::Triple::riscv64: 3102349cc55cSDimitry Andric case llvm::Triple::x86: 3103e8d8bef9SDimitry Andric case llvm::Triple::x86_64: 3104bdd1243dSDimitry Andric return UnwindTableLevel::Asynchronous; 3105e8d8bef9SDimitry Andric default: 3106bdd1243dSDimitry Andric return UnwindTableLevel::None; 3107e8d8bef9SDimitry Andric } 31080b57cec5SDimitry Andric } 31090b57cec5SDimitry Andric 31100b57cec5SDimitry Andric bool Generic_GCC::isPICDefault() const { 31110b57cec5SDimitry Andric switch (getArch()) { 31120b57cec5SDimitry Andric case llvm::Triple::x86_64: 31130b57cec5SDimitry Andric return getTriple().isOSWindows(); 31140b57cec5SDimitry Andric case llvm::Triple::mips64: 31150b57cec5SDimitry Andric case llvm::Triple::mips64el: 31160b57cec5SDimitry Andric return true; 31170b57cec5SDimitry Andric default: 31180b57cec5SDimitry Andric return false; 31190b57cec5SDimitry Andric } 31200b57cec5SDimitry Andric } 31210b57cec5SDimitry Andric 3122349cc55cSDimitry Andric bool Generic_GCC::isPIEDefault(const llvm::opt::ArgList &Args) const { 3123349cc55cSDimitry Andric return false; 3124349cc55cSDimitry Andric } 31250b57cec5SDimitry Andric 31260b57cec5SDimitry Andric bool Generic_GCC::isPICDefaultForced() const { 31270b57cec5SDimitry Andric return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows(); 31280b57cec5SDimitry Andric } 31290b57cec5SDimitry Andric 31300b57cec5SDimitry Andric bool Generic_GCC::IsIntegratedAssemblerDefault() const { 31310b57cec5SDimitry Andric switch (getTriple().getArch()) { 313206c3fb27SDimitry Andric case llvm::Triple::nvptx: 313306c3fb27SDimitry Andric case llvm::Triple::nvptx64: 313406c3fb27SDimitry Andric case llvm::Triple::xcore: 31350b57cec5SDimitry Andric return false; 313606c3fb27SDimitry Andric default: 31375f757f3fSDimitry Andric return true; 31380b57cec5SDimitry Andric } 31390b57cec5SDimitry Andric } 31400b57cec5SDimitry Andric 31415ffd83dbSDimitry Andric void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) { 31425ffd83dbSDimitry Andric // Cross-compiling binutils and GCC installations (vanilla and openSUSE at 31435ffd83dbSDimitry Andric // least) put various tools in a triple-prefixed directory off of the parent 31445ffd83dbSDimitry Andric // of the GCC installation. We use the GCC triple here to ensure that we end 31455ffd83dbSDimitry Andric // up with tools that support the same amount of cross compiling as the 31465ffd83dbSDimitry Andric // detected GCC installation. For example, if we find a GCC installation 31475ffd83dbSDimitry Andric // targeting x86_64, but it is a bi-arch GCC installation, it can also be 31485ffd83dbSDimitry Andric // used to target i386. 31495ffd83dbSDimitry Andric if (GCCInstallation.isValid()) { 31505ffd83dbSDimitry Andric PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 31515ffd83dbSDimitry Andric GCCInstallation.getTriple().str() + "/bin") 31525ffd83dbSDimitry Andric .str()); 31535ffd83dbSDimitry Andric } 31545ffd83dbSDimitry Andric } 31555ffd83dbSDimitry Andric 31565ffd83dbSDimitry Andric void Generic_GCC::AddMultilibPaths(const Driver &D, 31575ffd83dbSDimitry Andric const std::string &SysRoot, 31585ffd83dbSDimitry Andric const std::string &OSLibDir, 31595ffd83dbSDimitry Andric const std::string &MultiarchTriple, 31605ffd83dbSDimitry Andric path_list &Paths) { 31615ffd83dbSDimitry Andric // Add the multilib suffixed paths where they are available. 31625ffd83dbSDimitry Andric if (GCCInstallation.isValid()) { 316306c3fb27SDimitry Andric assert(!SelectedMultilibs.empty()); 31645ffd83dbSDimitry Andric const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 31655ffd83dbSDimitry Andric const std::string &LibPath = 31665ffd83dbSDimitry Andric std::string(GCCInstallation.getParentLibPath()); 31675ffd83dbSDimitry Andric 31685ffd83dbSDimitry Andric // Sourcery CodeBench MIPS toolchain holds some libraries under 31695ffd83dbSDimitry Andric // a biarch-like suffix of the GCC installation. 3170fe6060f1SDimitry Andric if (const auto &PathsCallback = Multilibs.filePathsCallback()) 317106c3fb27SDimitry Andric for (const auto &Path : PathsCallback(SelectedMultilibs.back())) 3172fe6060f1SDimitry Andric addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths); 3173fe6060f1SDimitry Andric 3174fe6060f1SDimitry Andric // Add lib/gcc/$triple/$version, with an optional /multilib suffix. 317506c3fb27SDimitry Andric addPathIfExists(D, 317606c3fb27SDimitry Andric GCCInstallation.getInstallPath() + 317706c3fb27SDimitry Andric SelectedMultilibs.back().gccSuffix(), 31785ffd83dbSDimitry Andric Paths); 31795ffd83dbSDimitry Andric 318081ad6265SDimitry Andric // Add lib/gcc/$triple/$libdir 318181ad6265SDimitry Andric // For GCC built with --enable-version-specific-runtime-libs. 318281ad6265SDimitry Andric addPathIfExists(D, GCCInstallation.getInstallPath() + "/../" + OSLibDir, 318381ad6265SDimitry Andric Paths); 318481ad6265SDimitry Andric 31855ffd83dbSDimitry Andric // GCC cross compiling toolchains will install target libraries which ship 31865ffd83dbSDimitry Andric // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as 31875ffd83dbSDimitry Andric // any part of the GCC installation in 31885ffd83dbSDimitry Andric // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat 31895ffd83dbSDimitry Andric // debatable, but is the reality today. We need to search this tree even 31905ffd83dbSDimitry Andric // when we have a sysroot somewhere else. It is the responsibility of 31915ffd83dbSDimitry Andric // whomever is doing the cross build targeting a sysroot using a GCC 31925ffd83dbSDimitry Andric // installation that is *not* within the system root to ensure two things: 31935ffd83dbSDimitry Andric // 31945ffd83dbSDimitry Andric // 1) Any DSOs that are linked in from this tree or from the install path 31955ffd83dbSDimitry Andric // above must be present on the system root and found via an 31965ffd83dbSDimitry Andric // appropriate rpath. 31975ffd83dbSDimitry Andric // 2) There must not be libraries installed into 31985ffd83dbSDimitry Andric // <prefix>/<triple>/<libdir> unless they should be preferred over 31995ffd83dbSDimitry Andric // those within the system root. 32005ffd83dbSDimitry Andric // 32015ffd83dbSDimitry Andric // Note that this matches the GCC behavior. See the below comment for where 32025ffd83dbSDimitry Andric // Clang diverges from GCC's behavior. 32035ffd83dbSDimitry Andric addPathIfExists(D, 32045ffd83dbSDimitry Andric LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir + 320506c3fb27SDimitry Andric SelectedMultilibs.back().osSuffix(), 32065ffd83dbSDimitry Andric Paths); 32075ffd83dbSDimitry Andric 32085ffd83dbSDimitry Andric // If the GCC installation we found is inside of the sysroot, we want to 32095ffd83dbSDimitry Andric // prefer libraries installed in the parent prefix of the GCC installation. 32105ffd83dbSDimitry Andric // It is important to *not* use these paths when the GCC installation is 32115ffd83dbSDimitry Andric // outside of the system root as that can pick up unintended libraries. 32125ffd83dbSDimitry Andric // This usually happens when there is an external cross compiler on the 32135ffd83dbSDimitry Andric // host system, and a more minimal sysroot available that is the target of 32145ffd83dbSDimitry Andric // the cross. Note that GCC does include some of these directories in some 32155ffd83dbSDimitry Andric // configurations but this seems somewhere between questionable and simply 32165ffd83dbSDimitry Andric // a bug. 32175f757f3fSDimitry Andric if (StringRef(LibPath).starts_with(SysRoot)) 32185ffd83dbSDimitry Andric addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); 32195ffd83dbSDimitry Andric } 32205ffd83dbSDimitry Andric } 32215ffd83dbSDimitry Andric 32225ffd83dbSDimitry Andric void Generic_GCC::AddMultiarchPaths(const Driver &D, 32235ffd83dbSDimitry Andric const std::string &SysRoot, 32245ffd83dbSDimitry Andric const std::string &OSLibDir, 32255ffd83dbSDimitry Andric path_list &Paths) { 32265ffd83dbSDimitry Andric if (GCCInstallation.isValid()) { 32275ffd83dbSDimitry Andric const std::string &LibPath = 32285ffd83dbSDimitry Andric std::string(GCCInstallation.getParentLibPath()); 32295ffd83dbSDimitry Andric const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 32305ffd83dbSDimitry Andric const Multilib &Multilib = GCCInstallation.getMultilib(); 32315ffd83dbSDimitry Andric addPathIfExists( 32325ffd83dbSDimitry Andric D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(), 32335ffd83dbSDimitry Andric Paths); 32345ffd83dbSDimitry Andric } 32355ffd83dbSDimitry Andric } 32365ffd83dbSDimitry Andric 32375ffd83dbSDimitry Andric void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs, 32385ffd83dbSDimitry Andric ArgStringList &CC1Args) const { 32395ffd83dbSDimitry Andric // Add include directories specific to the selected multilib set and multilib. 3240fe6060f1SDimitry Andric if (!GCCInstallation.isValid()) 3241fe6060f1SDimitry Andric return; 3242fe6060f1SDimitry Andric // gcc TOOL_INCLUDE_DIR. 3243fe6060f1SDimitry Andric const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); 3244fe6060f1SDimitry Andric std::string LibPath(GCCInstallation.getParentLibPath()); 3245fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, 3246fe6060f1SDimitry Andric Twine(LibPath) + "/../" + GCCTriple.str() + "/include"); 3247fe6060f1SDimitry Andric 32485ffd83dbSDimitry Andric const auto &Callback = Multilibs.includeDirsCallback(); 32495ffd83dbSDimitry Andric if (Callback) { 32505ffd83dbSDimitry Andric for (const auto &Path : Callback(GCCInstallation.getMultilib())) 3251fe6060f1SDimitry Andric addExternCSystemIncludeIfExists(DriverArgs, CC1Args, 3252fe6060f1SDimitry Andric GCCInstallation.getInstallPath() + Path); 32535ffd83dbSDimitry Andric } 32545ffd83dbSDimitry Andric } 32555ffd83dbSDimitry Andric 32560b57cec5SDimitry Andric void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 32570b57cec5SDimitry Andric ArgStringList &CC1Args) const { 3258fe6060f1SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx, 3259fe6060f1SDimitry Andric options::OPT_nostdlibinc)) 32600b57cec5SDimitry Andric return; 32610b57cec5SDimitry Andric 32620b57cec5SDimitry Andric switch (GetCXXStdlibType(DriverArgs)) { 32630b57cec5SDimitry Andric case ToolChain::CST_Libcxx: 32640b57cec5SDimitry Andric addLibCxxIncludePaths(DriverArgs, CC1Args); 32650b57cec5SDimitry Andric break; 32660b57cec5SDimitry Andric 32670b57cec5SDimitry Andric case ToolChain::CST_Libstdcxx: 32680b57cec5SDimitry Andric addLibStdCxxIncludePaths(DriverArgs, CC1Args); 32690b57cec5SDimitry Andric break; 32700b57cec5SDimitry Andric } 32710b57cec5SDimitry Andric } 32720b57cec5SDimitry Andric 32730b57cec5SDimitry Andric void 3274480093f4SDimitry Andric Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 32750b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 3276fe6060f1SDimitry Andric const Driver &D = getDriver(); 3277fe6060f1SDimitry Andric std::string SysRoot = computeSysRoot(); 32785f757f3fSDimitry Andric if (SysRoot.empty()) 32795f757f3fSDimitry Andric SysRoot = llvm::sys::path::get_separator(); 3280fe6060f1SDimitry Andric 32815f757f3fSDimitry Andric auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) { 3282fe6060f1SDimitry Andric std::string Version = detectLibcxxVersion(Path); 3283fe6060f1SDimitry Andric if (Version.empty()) 3284480093f4SDimitry Andric return false; 3285fe6060f1SDimitry Andric 3286fe6060f1SDimitry Andric // First add the per-target include path if it exists. 32875f757f3fSDimitry Andric bool TargetDirExists = false; 32885f757f3fSDimitry Andric std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(Path); 32895f757f3fSDimitry Andric if (TargetIncludeDir) { 32905f757f3fSDimitry Andric SmallString<128> TargetDir(*TargetIncludeDir); 32915f757f3fSDimitry Andric llvm::sys::path::append(TargetDir, "c++", Version); 32925f757f3fSDimitry Andric if (D.getVFS().exists(TargetDir)) { 3293fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, TargetDir); 32945f757f3fSDimitry Andric TargetDirExists = true; 32955f757f3fSDimitry Andric } 32965f757f3fSDimitry Andric } 32975f757f3fSDimitry Andric if (TargetDirRequired && !TargetDirExists) 32985f757f3fSDimitry Andric return false; 3299fe6060f1SDimitry Andric 3300fe6060f1SDimitry Andric // Second add the generic one. 33015f757f3fSDimitry Andric SmallString<128> GenericDir(Path); 33025f757f3fSDimitry Andric llvm::sys::path::append(GenericDir, "c++", Version); 33035f757f3fSDimitry Andric addSystemInclude(DriverArgs, CC1Args, GenericDir); 3304480093f4SDimitry Andric return true; 3305480093f4SDimitry Andric }; 3306fe6060f1SDimitry Andric 33075f757f3fSDimitry Andric // Android only uses the libc++ headers installed alongside the toolchain if 33085f757f3fSDimitry Andric // they contain an Android-specific target include path, otherwise they're 33095f757f3fSDimitry Andric // incompatible with the NDK libraries. 33105f757f3fSDimitry Andric SmallString<128> DriverIncludeDir(getDriver().Dir); 33115f757f3fSDimitry Andric llvm::sys::path::append(DriverIncludeDir, "..", "include"); 33125f757f3fSDimitry Andric if (AddIncludePath(DriverIncludeDir, 33135f757f3fSDimitry Andric /*TargetDirRequired=*/getTriple().isAndroid())) 3314480093f4SDimitry Andric return; 3315480093f4SDimitry Andric // If this is a development, non-installed, clang, libcxx will 3316480093f4SDimitry Andric // not be found at ../include/c++ but it likely to be found at 3317480093f4SDimitry Andric // one of the following two locations: 33185f757f3fSDimitry Andric SmallString<128> UsrLocalIncludeDir(SysRoot); 33195f757f3fSDimitry Andric llvm::sys::path::append(UsrLocalIncludeDir, "usr", "local", "include"); 33205f757f3fSDimitry Andric if (AddIncludePath(UsrLocalIncludeDir)) 3321480093f4SDimitry Andric return; 33225f757f3fSDimitry Andric SmallString<128> UsrIncludeDir(SysRoot); 33235f757f3fSDimitry Andric llvm::sys::path::append(UsrIncludeDir, "usr", "include"); 33245f757f3fSDimitry Andric if (AddIncludePath(UsrIncludeDir)) 3325480093f4SDimitry Andric return; 33260b57cec5SDimitry Andric } 33270b57cec5SDimitry Andric 3328fe6060f1SDimitry Andric bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, 3329fe6060f1SDimitry Andric Twine IncludeSuffix, 3330fe6060f1SDimitry Andric const llvm::opt::ArgList &DriverArgs, 3331fe6060f1SDimitry Andric llvm::opt::ArgStringList &CC1Args, 3332fe6060f1SDimitry Andric bool DetectDebian) const { 3333fe6060f1SDimitry Andric if (!getVFS().exists(IncludeDir)) 33340b57cec5SDimitry Andric return false; 33350b57cec5SDimitry Andric 3336fe6060f1SDimitry Andric // Debian native gcc uses g++-multiarch-incdir.diff which uses 3337fe6060f1SDimitry Andric // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of 3338fe6060f1SDimitry Andric // include/c++/10/x86_64-linux-gnu$IncludeSuffix. 3339fe6060f1SDimitry Andric std::string Dir = IncludeDir.str(); 3340fe6060f1SDimitry Andric StringRef Include = 3341fe6060f1SDimitry Andric llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); 3342fe6060f1SDimitry Andric std::string Path = 3343fe6060f1SDimitry Andric (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) 3344fe6060f1SDimitry Andric .str(); 3345fe6060f1SDimitry Andric if (DetectDebian && !getVFS().exists(Path)) 3346fe6060f1SDimitry Andric return false; 33470b57cec5SDimitry Andric 3348fe6060f1SDimitry Andric // GPLUSPLUS_INCLUDE_DIR 3349fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, IncludeDir); 3350fe6060f1SDimitry Andric // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent 3351fe6060f1SDimitry Andric // include directory. 3352fe6060f1SDimitry Andric if (DetectDebian) 3353fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Path); 3354fe6060f1SDimitry Andric else if (!Triple.empty()) 33550b57cec5SDimitry Andric addSystemInclude(DriverArgs, CC1Args, 3356fe6060f1SDimitry Andric IncludeDir + "/" + Triple + IncludeSuffix); 3357fe6060f1SDimitry Andric // GPLUSPLUS_BACKWARD_INCLUDE_DIR 3358fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); 33590b57cec5SDimitry Andric return true; 33600b57cec5SDimitry Andric } 33610b57cec5SDimitry Andric 3362fe6060f1SDimitry Andric bool Generic_GCC::addGCCLibStdCxxIncludePaths( 3363fe6060f1SDimitry Andric const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, 3364fe6060f1SDimitry Andric StringRef DebianMultiarch) const { 3365fe6060f1SDimitry Andric assert(GCCInstallation.isValid()); 3366480093f4SDimitry Andric 3367480093f4SDimitry Andric // By default, look for the C++ headers in an include directory adjacent to 3368480093f4SDimitry Andric // the lib directory of the GCC installation. Note that this is expect to be 3369480093f4SDimitry Andric // equivalent to '/usr/include/c++/X.Y' in almost all cases. 3370480093f4SDimitry Andric StringRef LibDir = GCCInstallation.getParentLibPath(); 3371480093f4SDimitry Andric StringRef InstallDir = GCCInstallation.getInstallPath(); 3372480093f4SDimitry Andric StringRef TripleStr = GCCInstallation.getTriple().str(); 3373480093f4SDimitry Andric const Multilib &Multilib = GCCInstallation.getMultilib(); 3374480093f4SDimitry Andric const GCCVersion &Version = GCCInstallation.getVersion(); 3375480093f4SDimitry Andric 3376fe6060f1SDimitry Andric // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty). 3377fe6060f1SDimitry Andric if (addLibStdCXXIncludePaths( 3378fe6060f1SDimitry Andric LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, 3379fe6060f1SDimitry Andric TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) 3380fe6060f1SDimitry Andric return true; 3381fe6060f1SDimitry Andric 338281ad6265SDimitry Andric // Try /gcc/$triple/$version/include/c++/ (gcc --print-multiarch is not 338381ad6265SDimitry Andric // empty). Like above but for GCC built with 338481ad6265SDimitry Andric // --enable-version-specific-runtime-libs. 338581ad6265SDimitry Andric if (addLibStdCXXIncludePaths(LibDir.str() + "/gcc/" + TripleStr + "/" + 338681ad6265SDimitry Andric Version.Text + "/include/c++/", 338781ad6265SDimitry Andric TripleStr, Multilib.includeSuffix(), DriverArgs, 338881ad6265SDimitry Andric CC1Args)) 338981ad6265SDimitry Andric return true; 339081ad6265SDimitry Andric 3391fe6060f1SDimitry Andric // Detect Debian g++-multiarch-incdir.diff. 3392fe6060f1SDimitry Andric if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, 3393fe6060f1SDimitry Andric DebianMultiarch, Multilib.includeSuffix(), 3394fe6060f1SDimitry Andric DriverArgs, CC1Args, /*Debian=*/true)) 3395fe6060f1SDimitry Andric return true; 3396fe6060f1SDimitry Andric 3397fe6060f1SDimitry Andric // Try /../include/c++/$version (gcc --print-multiarch is empty). 3398fe6060f1SDimitry Andric if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, 3399fe6060f1SDimitry Andric TripleStr, Multilib.includeSuffix(), DriverArgs, 3400fe6060f1SDimitry Andric CC1Args)) 3401480093f4SDimitry Andric return true; 3402480093f4SDimitry Andric 3403480093f4SDimitry Andric // Otherwise, fall back on a bunch of options which don't use multiarch 3404480093f4SDimitry Andric // layouts for simplicity. 3405480093f4SDimitry Andric const std::string LibStdCXXIncludePathCandidates[] = { 3406480093f4SDimitry Andric // Gentoo is weird and places its headers inside the GCC install, 3407480093f4SDimitry Andric // so if the first attempt to find the headers fails, try these patterns. 3408480093f4SDimitry Andric InstallDir.str() + "/include/g++-v" + Version.Text, 3409480093f4SDimitry Andric InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + 3410480093f4SDimitry Andric Version.MinorStr, 3411480093f4SDimitry Andric InstallDir.str() + "/include/g++-v" + Version.MajorStr, 3412480093f4SDimitry Andric }; 3413480093f4SDimitry Andric 3414480093f4SDimitry Andric for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { 3415fe6060f1SDimitry Andric if (addLibStdCXXIncludePaths(IncludePath, TripleStr, 3416480093f4SDimitry Andric Multilib.includeSuffix(), DriverArgs, CC1Args)) 3417480093f4SDimitry Andric return true; 3418480093f4SDimitry Andric } 3419480093f4SDimitry Andric return false; 3420480093f4SDimitry Andric } 3421480093f4SDimitry Andric 3422480093f4SDimitry Andric void 3423480093f4SDimitry Andric Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 3424480093f4SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 3425fe6060f1SDimitry Andric if (GCCInstallation.isValid()) { 3426fe6060f1SDimitry Andric addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, 3427fe6060f1SDimitry Andric GCCInstallation.getTriple().str()); 3428fe6060f1SDimitry Andric } 3429480093f4SDimitry Andric } 3430480093f4SDimitry Andric 34310b57cec5SDimitry Andric llvm::opt::DerivedArgList * 34320b57cec5SDimitry Andric Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef, 34330b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const { 34340b57cec5SDimitry Andric 34350b57cec5SDimitry Andric // If this tool chain is used for an OpenMP offloading device we have to make 34360b57cec5SDimitry Andric // sure we always generate a shared library regardless of the commands the 34370b57cec5SDimitry Andric // user passed to the host. This is required because the runtime library 34380b57cec5SDimitry Andric // is required to load the device image dynamically at run time. 34390b57cec5SDimitry Andric if (DeviceOffloadKind == Action::OFK_OpenMP) { 34400b57cec5SDimitry Andric DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 34410b57cec5SDimitry Andric const OptTable &Opts = getDriver().getOpts(); 34420b57cec5SDimitry Andric 34430b57cec5SDimitry Andric // Request the shared library. Given that these options are decided 34440b57cec5SDimitry Andric // implicitly, they do not refer to any base argument. 34450b57cec5SDimitry Andric DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared)); 34460b57cec5SDimitry Andric DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC)); 34470b57cec5SDimitry Andric 34480b57cec5SDimitry Andric // Filter all the arguments we don't care passing to the offloading 34490b57cec5SDimitry Andric // toolchain as they can mess up with the creation of a shared library. 34500b57cec5SDimitry Andric for (auto *A : Args) { 34510b57cec5SDimitry Andric switch ((options::ID)A->getOption().getID()) { 34520b57cec5SDimitry Andric default: 34530b57cec5SDimitry Andric DAL->append(A); 34540b57cec5SDimitry Andric break; 34550b57cec5SDimitry Andric case options::OPT_shared: 34560b57cec5SDimitry Andric case options::OPT_dynamic: 34570b57cec5SDimitry Andric case options::OPT_static: 34580b57cec5SDimitry Andric case options::OPT_fPIC: 34590b57cec5SDimitry Andric case options::OPT_fno_PIC: 34600b57cec5SDimitry Andric case options::OPT_fpic: 34610b57cec5SDimitry Andric case options::OPT_fno_pic: 34620b57cec5SDimitry Andric case options::OPT_fPIE: 34630b57cec5SDimitry Andric case options::OPT_fno_PIE: 34640b57cec5SDimitry Andric case options::OPT_fpie: 34650b57cec5SDimitry Andric case options::OPT_fno_pie: 34660b57cec5SDimitry Andric break; 34670b57cec5SDimitry Andric } 34680b57cec5SDimitry Andric } 34690b57cec5SDimitry Andric return DAL; 34700b57cec5SDimitry Andric } 34710b57cec5SDimitry Andric return nullptr; 34720b57cec5SDimitry Andric } 34730b57cec5SDimitry Andric 34740b57cec5SDimitry Andric void Generic_ELF::anchor() {} 34750b57cec5SDimitry Andric 34760b57cec5SDimitry Andric void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, 34770b57cec5SDimitry Andric ArgStringList &CC1Args, 34780b57cec5SDimitry Andric Action::OffloadKind) const { 3479480093f4SDimitry Andric if (!DriverArgs.hasFlag(options::OPT_fuse_init_array, 3480480093f4SDimitry Andric options::OPT_fno_use_init_array, true)) 3481480093f4SDimitry Andric CC1Args.push_back("-fno-use-init-array"); 34820b57cec5SDimitry Andric } 3483