1 //===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "Arch/Mips.h"
13 #include "Arch/Sparc.h"
14 #include "CommonArgs.h"
15 #include "clang/Driver/Compilation.h"
16 #include "clang/Driver/Driver.h"
17 #include "clang/Driver/Options.h"
18 #include "llvm/Option/ArgList.h"
20 using namespace clang::driver;
21 using namespace clang::driver::tools;
22 using namespace clang::driver::toolchains;
23 using namespace clang;
24 using namespace llvm::opt;
26 void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
27 const InputInfo &Output,
28 const InputInfoList &Inputs,
30 const char *LinkingOutput) const {
31 claimNoWarnArgs(Args);
32 ArgStringList CmdArgs;
34 // GNU as needs different flags for creating the correct output format
35 // on architectures with different ABIs or optional feature sets.
36 switch (getToolChain().getArch()) {
37 case llvm::Triple::x86:
38 CmdArgs.push_back("--32");
40 case llvm::Triple::arm:
41 case llvm::Triple::armeb:
42 case llvm::Triple::thumb:
43 case llvm::Triple::thumbeb: {
44 StringRef MArch, MCPU;
45 arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
47 arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
48 CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
52 case llvm::Triple::mips:
53 case llvm::Triple::mipsel:
54 case llvm::Triple::mips64:
55 case llvm::Triple::mips64el: {
58 mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
60 CmdArgs.push_back("-march");
61 CmdArgs.push_back(CPUName.data());
63 CmdArgs.push_back("-mabi");
64 CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
66 if (getToolChain().getArch() == llvm::Triple::mips ||
67 getToolChain().getArch() == llvm::Triple::mips64)
68 CmdArgs.push_back("-EB");
70 CmdArgs.push_back("-EL");
72 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
76 case llvm::Triple::sparc:
77 case llvm::Triple::sparcel: {
78 CmdArgs.push_back("-32");
79 std::string CPU = getCPUName(Args, getToolChain().getTriple());
80 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
81 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
85 case llvm::Triple::sparcv9: {
86 CmdArgs.push_back("-64");
87 std::string CPU = getCPUName(Args, getToolChain().getTriple());
88 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
89 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
97 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
99 CmdArgs.push_back("-o");
100 CmdArgs.push_back(Output.getFilename());
102 for (const auto &II : Inputs)
103 CmdArgs.push_back(II.getFilename());
105 const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
106 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
109 void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
110 const InputInfo &Output,
111 const InputInfoList &Inputs,
113 const char *LinkingOutput) const {
114 const Driver &D = getToolChain().getDriver();
115 ArgStringList CmdArgs;
117 if (!D.SysRoot.empty())
118 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
120 CmdArgs.push_back("--eh-frame-hdr");
121 if (Args.hasArg(options::OPT_static)) {
122 CmdArgs.push_back("-Bstatic");
124 if (Args.hasArg(options::OPT_rdynamic))
125 CmdArgs.push_back("-export-dynamic");
126 if (Args.hasArg(options::OPT_shared)) {
127 CmdArgs.push_back("-Bshareable");
129 Args.AddAllArgs(CmdArgs, options::OPT_pie);
130 CmdArgs.push_back("-dynamic-linker");
131 CmdArgs.push_back("/libexec/ld.elf_so");
135 // Many NetBSD architectures support more than one ABI.
136 // Determine the correct emulation for ld.
137 switch (getToolChain().getArch()) {
138 case llvm::Triple::x86:
139 CmdArgs.push_back("-m");
140 CmdArgs.push_back("elf_i386");
142 case llvm::Triple::arm:
143 case llvm::Triple::thumb:
144 CmdArgs.push_back("-m");
145 switch (getToolChain().getTriple().getEnvironment()) {
146 case llvm::Triple::EABI:
147 case llvm::Triple::GNUEABI:
148 CmdArgs.push_back("armelf_nbsd_eabi");
150 case llvm::Triple::EABIHF:
151 case llvm::Triple::GNUEABIHF:
152 CmdArgs.push_back("armelf_nbsd_eabihf");
155 CmdArgs.push_back("armelf_nbsd");
159 case llvm::Triple::armeb:
160 case llvm::Triple::thumbeb:
161 arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple());
162 CmdArgs.push_back("-m");
163 switch (getToolChain().getTriple().getEnvironment()) {
164 case llvm::Triple::EABI:
165 case llvm::Triple::GNUEABI:
166 CmdArgs.push_back("armelfb_nbsd_eabi");
168 case llvm::Triple::EABIHF:
169 case llvm::Triple::GNUEABIHF:
170 CmdArgs.push_back("armelfb_nbsd_eabihf");
173 CmdArgs.push_back("armelfb_nbsd");
177 case llvm::Triple::mips64:
178 case llvm::Triple::mips64el:
179 if (mips::hasMipsAbiArg(Args, "32")) {
180 CmdArgs.push_back("-m");
181 if (getToolChain().getArch() == llvm::Triple::mips64)
182 CmdArgs.push_back("elf32btsmip");
184 CmdArgs.push_back("elf32ltsmip");
185 } else if (mips::hasMipsAbiArg(Args, "64")) {
186 CmdArgs.push_back("-m");
187 if (getToolChain().getArch() == llvm::Triple::mips64)
188 CmdArgs.push_back("elf64btsmip");
190 CmdArgs.push_back("elf64ltsmip");
193 case llvm::Triple::ppc:
194 CmdArgs.push_back("-m");
195 CmdArgs.push_back("elf32ppc_nbsd");
198 case llvm::Triple::ppc64:
199 case llvm::Triple::ppc64le:
200 CmdArgs.push_back("-m");
201 CmdArgs.push_back("elf64ppc");
204 case llvm::Triple::sparc:
205 CmdArgs.push_back("-m");
206 CmdArgs.push_back("elf32_sparc");
209 case llvm::Triple::sparcv9:
210 CmdArgs.push_back("-m");
211 CmdArgs.push_back("elf64_sparc");
218 if (Output.isFilename()) {
219 CmdArgs.push_back("-o");
220 CmdArgs.push_back(Output.getFilename());
222 assert(Output.isNothing() && "Invalid output.");
225 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
226 if (!Args.hasArg(options::OPT_shared)) {
228 Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
231 Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
232 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
234 Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
237 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
241 Args.AddAllArgs(CmdArgs, options::OPT_L);
242 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
243 Args.AddAllArgs(CmdArgs, options::OPT_e);
244 Args.AddAllArgs(CmdArgs, options::OPT_s);
245 Args.AddAllArgs(CmdArgs, options::OPT_t);
246 Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
247 Args.AddAllArgs(CmdArgs, options::OPT_r);
249 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
251 unsigned Major, Minor, Micro;
252 getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
253 bool useLibgcc = true;
254 if (Major >= 7 || Major == 0) {
255 switch (getToolChain().getArch()) {
256 case llvm::Triple::aarch64:
257 case llvm::Triple::aarch64_be:
258 case llvm::Triple::arm:
259 case llvm::Triple::armeb:
260 case llvm::Triple::thumb:
261 case llvm::Triple::thumbeb:
262 case llvm::Triple::ppc:
263 case llvm::Triple::ppc64:
264 case llvm::Triple::ppc64le:
265 case llvm::Triple::sparc:
266 case llvm::Triple::sparcv9:
267 case llvm::Triple::x86:
268 case llvm::Triple::x86_64:
276 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
277 addOpenMPRuntime(CmdArgs, getToolChain(), Args);
279 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
280 CmdArgs.push_back("-lm");
282 if (Args.hasArg(options::OPT_pthread))
283 CmdArgs.push_back("-lpthread");
284 CmdArgs.push_back("-lc");
287 if (Args.hasArg(options::OPT_static)) {
288 // libgcc_eh depends on libc, so resolve as much as possible,
289 // pull in any new requirements from libc and then get the rest
291 CmdArgs.push_back("-lgcc_eh");
292 CmdArgs.push_back("-lc");
293 CmdArgs.push_back("-lgcc");
295 CmdArgs.push_back("-lgcc");
296 CmdArgs.push_back("--as-needed");
297 CmdArgs.push_back("-lgcc_s");
298 CmdArgs.push_back("--no-as-needed");
303 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
304 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
306 Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
309 Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
310 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
313 getToolChain().addProfileRTLibs(Args, CmdArgs);
315 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
316 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
319 /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
321 NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
322 : Generic_ELF(D, Triple, Args) {
323 if (getDriver().UseStdLib) {
324 // When targeting a 32-bit platform, try the special directory used on
325 // 64-bit hosts, and only fall back to the main library directory if that
327 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
328 // what all logic is needed to emulate the '=' prefix here.
329 switch (Triple.getArch()) {
330 case llvm::Triple::x86:
331 getFilePaths().push_back("=/usr/lib/i386");
333 case llvm::Triple::arm:
334 case llvm::Triple::armeb:
335 case llvm::Triple::thumb:
336 case llvm::Triple::thumbeb:
337 switch (Triple.getEnvironment()) {
338 case llvm::Triple::EABI:
339 case llvm::Triple::GNUEABI:
340 getFilePaths().push_back("=/usr/lib/eabi");
342 case llvm::Triple::EABIHF:
343 case llvm::Triple::GNUEABIHF:
344 getFilePaths().push_back("=/usr/lib/eabihf");
347 getFilePaths().push_back("=/usr/lib/oabi");
351 case llvm::Triple::mips64:
352 case llvm::Triple::mips64el:
353 if (tools::mips::hasMipsAbiArg(Args, "o32"))
354 getFilePaths().push_back("=/usr/lib/o32");
355 else if (tools::mips::hasMipsAbiArg(Args, "64"))
356 getFilePaths().push_back("=/usr/lib/64");
358 case llvm::Triple::ppc:
359 getFilePaths().push_back("=/usr/lib/powerpc");
361 case llvm::Triple::sparc:
362 getFilePaths().push_back("=/usr/lib/sparc");
368 getFilePaths().push_back("=/usr/lib");
372 Tool *NetBSD::buildAssembler() const {
373 return new tools::netbsd::Assembler(*this);
376 Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
378 ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
379 unsigned Major, Minor, Micro;
380 getTriple().getOSVersion(Major, Minor, Micro);
381 if (Major >= 7 || Major == 0) {
383 case llvm::Triple::aarch64:
384 case llvm::Triple::aarch64_be:
385 case llvm::Triple::arm:
386 case llvm::Triple::armeb:
387 case llvm::Triple::thumb:
388 case llvm::Triple::thumbeb:
389 case llvm::Triple::ppc:
390 case llvm::Triple::ppc64:
391 case llvm::Triple::ppc64le:
392 case llvm::Triple::sparc:
393 case llvm::Triple::sparcv9:
394 case llvm::Triple::x86:
395 case llvm::Triple::x86_64:
396 return ToolChain::CST_Libcxx;
401 return ToolChain::CST_Libstdcxx;
404 std::string NetBSD::findLibCxxIncludePath() const {
405 return getDriver().SysRoot + "/usr/include/c++/";
408 void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
409 llvm::opt::ArgStringList &CC1Args) const {
410 addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
411 "", DriverArgs, CC1Args);