xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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