1*0b57cec5SDimitry Andric //===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "DragonFly.h" 10*0b57cec5SDimitry Andric #include "CommonArgs.h" 11*0b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 12*0b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 13*0b57cec5SDimitry Andric #include "clang/Driver/Options.h" 14*0b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric using namespace clang::driver; 17*0b57cec5SDimitry Andric using namespace clang::driver::tools; 18*0b57cec5SDimitry Andric using namespace clang::driver::toolchains; 19*0b57cec5SDimitry Andric using namespace clang; 20*0b57cec5SDimitry Andric using namespace llvm::opt; 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric /// DragonFly Tools 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric // For now, DragonFly Assemble does just about the same as for 25*0b57cec5SDimitry Andric // FreeBSD, but this may change soon. 26*0b57cec5SDimitry Andric void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 27*0b57cec5SDimitry Andric const InputInfo &Output, 28*0b57cec5SDimitry Andric const InputInfoList &Inputs, 29*0b57cec5SDimitry Andric const ArgList &Args, 30*0b57cec5SDimitry Andric const char *LinkingOutput) const { 31*0b57cec5SDimitry Andric claimNoWarnArgs(Args); 32*0b57cec5SDimitry Andric ArgStringList CmdArgs; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric // When building 32-bit code on DragonFly/pc64, we have to explicitly 35*0b57cec5SDimitry Andric // instruct as in the base system to assemble 32-bit code. 36*0b57cec5SDimitry Andric if (getToolChain().getArch() == llvm::Triple::x86) 37*0b57cec5SDimitry Andric CmdArgs.push_back("--32"); 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric CmdArgs.push_back("-o"); 42*0b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric for (const auto &II : Inputs) 45*0b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename()); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 48*0b57cec5SDimitry Andric C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 49*0b57cec5SDimitry Andric } 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, 52*0b57cec5SDimitry Andric const InputInfo &Output, 53*0b57cec5SDimitry Andric const InputInfoList &Inputs, 54*0b57cec5SDimitry Andric const ArgList &Args, 55*0b57cec5SDimitry Andric const char *LinkingOutput) const { 56*0b57cec5SDimitry Andric const Driver &D = getToolChain().getDriver(); 57*0b57cec5SDimitry Andric ArgStringList CmdArgs; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric if (!D.SysRoot.empty()) 60*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric CmdArgs.push_back("--eh-frame-hdr"); 63*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_static)) { 64*0b57cec5SDimitry Andric CmdArgs.push_back("-Bstatic"); 65*0b57cec5SDimitry Andric } else { 66*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 67*0b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 68*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared)) 69*0b57cec5SDimitry Andric CmdArgs.push_back("-Bshareable"); 70*0b57cec5SDimitry Andric else { 71*0b57cec5SDimitry Andric CmdArgs.push_back("-dynamic-linker"); 72*0b57cec5SDimitry Andric CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); 73*0b57cec5SDimitry Andric } 74*0b57cec5SDimitry Andric CmdArgs.push_back("--hash-style=gnu"); 75*0b57cec5SDimitry Andric CmdArgs.push_back("--enable-new-dtags"); 76*0b57cec5SDimitry Andric } 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric // When building 32-bit code on DragonFly/pc64, we have to explicitly 79*0b57cec5SDimitry Andric // instruct ld in the base system to link 32-bit code. 80*0b57cec5SDimitry Andric if (getToolChain().getArch() == llvm::Triple::x86) { 81*0b57cec5SDimitry Andric CmdArgs.push_back("-m"); 82*0b57cec5SDimitry Andric CmdArgs.push_back("elf_i386"); 83*0b57cec5SDimitry Andric } 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric if (Output.isFilename()) { 86*0b57cec5SDimitry Andric CmdArgs.push_back("-o"); 87*0b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 88*0b57cec5SDimitry Andric } else { 89*0b57cec5SDimitry Andric assert(Output.isNothing() && "Invalid output."); 90*0b57cec5SDimitry Andric } 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 93*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_shared)) { 94*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pg)) 95*0b57cec5SDimitry Andric CmdArgs.push_back( 96*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o"))); 97*0b57cec5SDimitry Andric else { 98*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pie)) 99*0b57cec5SDimitry Andric CmdArgs.push_back( 100*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o"))); 101*0b57cec5SDimitry Andric else 102*0b57cec5SDimitry Andric CmdArgs.push_back( 103*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); 104*0b57cec5SDimitry Andric } 105*0b57cec5SDimitry Andric } 106*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); 107*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 108*0b57cec5SDimitry Andric CmdArgs.push_back( 109*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); 110*0b57cec5SDimitry Andric else 111*0b57cec5SDimitry Andric CmdArgs.push_back( 112*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, 116*0b57cec5SDimitry Andric {options::OPT_L, options::OPT_T_Group, options::OPT_e}); 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 121*0b57cec5SDimitry Andric CmdArgs.push_back("-L/usr/lib/gcc50"); 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_static)) { 124*0b57cec5SDimitry Andric CmdArgs.push_back("-rpath"); 125*0b57cec5SDimitry Andric CmdArgs.push_back("/usr/lib/gcc50"); 126*0b57cec5SDimitry Andric } 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric if (D.CCCIsCXX()) { 129*0b57cec5SDimitry Andric if (getToolChain().ShouldLinkCXXStdlib(Args)) 130*0b57cec5SDimitry Andric getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 131*0b57cec5SDimitry Andric CmdArgs.push_back("-lm"); 132*0b57cec5SDimitry Andric } 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) 135*0b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nolibc)) { 138*0b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_static) || 142*0b57cec5SDimitry Andric Args.hasArg(options::OPT_static_libgcc)) { 143*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 144*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc_eh"); 145*0b57cec5SDimitry Andric } else { 146*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared_libgcc)) { 147*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc_pic"); 148*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_shared)) 149*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 150*0b57cec5SDimitry Andric } else { 151*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 152*0b57cec5SDimitry Andric CmdArgs.push_back("--as-needed"); 153*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc_pic"); 154*0b57cec5SDimitry Andric CmdArgs.push_back("--no-as-needed"); 155*0b57cec5SDimitry Andric } 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric } 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 160*0b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 161*0b57cec5SDimitry Andric CmdArgs.push_back( 162*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); 163*0b57cec5SDimitry Andric else 164*0b57cec5SDimitry Andric CmdArgs.push_back( 165*0b57cec5SDimitry Andric Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); 166*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); 167*0b57cec5SDimitry Andric } 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric getToolChain().addProfileRTLibs(Args, CmdArgs); 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); 172*0b57cec5SDimitry Andric C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, 178*0b57cec5SDimitry Andric const ArgList &Args) 179*0b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric // Path mangling to find libexec 182*0b57cec5SDimitry Andric getProgramPaths().push_back(getDriver().getInstalledDir()); 183*0b57cec5SDimitry Andric if (getDriver().getInstalledDir() != getDriver().Dir) 184*0b57cec5SDimitry Andric getProgramPaths().push_back(getDriver().Dir); 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric getFilePaths().push_back(getDriver().Dir + "/../lib"); 187*0b57cec5SDimitry Andric getFilePaths().push_back("/usr/lib"); 188*0b57cec5SDimitry Andric getFilePaths().push_back("/usr/lib/gcc50"); 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric Tool *DragonFly::buildAssembler() const { 192*0b57cec5SDimitry Andric return new tools::dragonfly::Assembler(*this); 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric Tool *DragonFly::buildLinker() const { 196*0b57cec5SDimitry Andric return new tools::dragonfly::Linker(*this); 197*0b57cec5SDimitry Andric } 198