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 "clang/Driver/SanitizerArgs.h"
19 #include "llvm/Option/ArgList.h"
21 using namespace clang::driver;
22 using namespace clang::driver::tools;
23 using namespace clang::driver::toolchains;
24 using namespace clang;
25 using namespace llvm::opt;
27 void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
28 const InputInfo &Output,
29 const InputInfoList &Inputs,
31 const char *LinkingOutput) const {
32 claimNoWarnArgs(Args);
33 ArgStringList CmdArgs;
35 // GNU as needs different flags for creating the correct output format
36 // on architectures with different ABIs or optional feature sets.
37 switch (getToolChain().getArch()) {
38 case llvm::Triple::x86:
39 CmdArgs.push_back("--32");
41 case llvm::Triple::arm:
42 case llvm::Triple::armeb:
43 case llvm::Triple::thumb:
44 case llvm::Triple::thumbeb: {
45 StringRef MArch, MCPU;
46 arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
48 arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
49 CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
53 case llvm::Triple::mips:
54 case llvm::Triple::mipsel:
55 case llvm::Triple::mips64:
56 case llvm::Triple::mips64el: {
59 mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
61 CmdArgs.push_back("-march");
62 CmdArgs.push_back(CPUName.data());
64 CmdArgs.push_back("-mabi");
65 CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
67 if (getToolChain().getArch() == llvm::Triple::mips ||
68 getToolChain().getArch() == llvm::Triple::mips64)
69 CmdArgs.push_back("-EB");
71 CmdArgs.push_back("-EL");
73 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
77 case llvm::Triple::sparc:
78 case llvm::Triple::sparcel: {
79 CmdArgs.push_back("-32");
80 std::string CPU = getCPUName(Args, getToolChain().getTriple());
81 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
82 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
86 case llvm::Triple::sparcv9: {
87 CmdArgs.push_back("-64");
88 std::string CPU = getCPUName(Args, getToolChain().getTriple());
89 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
90 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
98 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
100 CmdArgs.push_back("-o");
101 CmdArgs.push_back(Output.getFilename());
103 for (const auto &II : Inputs)
104 CmdArgs.push_back(II.getFilename());
106 const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
107 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
110 void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
111 const InputInfo &Output,
112 const InputInfoList &Inputs,
114 const char *LinkingOutput) const {
115 const Driver &D = getToolChain().getDriver();
116 ArgStringList CmdArgs;
118 if (!D.SysRoot.empty())
119 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
121 CmdArgs.push_back("--eh-frame-hdr");
122 if (Args.hasArg(options::OPT_static)) {
123 CmdArgs.push_back("-Bstatic");
125 if (Args.hasArg(options::OPT_rdynamic))
126 CmdArgs.push_back("-export-dynamic");
127 if (Args.hasArg(options::OPT_shared)) {
128 CmdArgs.push_back("-Bshareable");
130 Args.AddAllArgs(CmdArgs, options::OPT_pie);
131 CmdArgs.push_back("-dynamic-linker");
132 CmdArgs.push_back("/libexec/ld.elf_so");
136 // Many NetBSD architectures support more than one ABI.
137 // Determine the correct emulation for ld.
138 switch (getToolChain().getArch()) {
139 case llvm::Triple::x86:
140 CmdArgs.push_back("-m");
141 CmdArgs.push_back("elf_i386");
143 case llvm::Triple::arm:
144 case llvm::Triple::thumb:
145 CmdArgs.push_back("-m");
146 switch (getToolChain().getTriple().getEnvironment()) {
147 case llvm::Triple::EABI:
148 case llvm::Triple::GNUEABI:
149 CmdArgs.push_back("armelf_nbsd_eabi");
151 case llvm::Triple::EABIHF:
152 case llvm::Triple::GNUEABIHF:
153 CmdArgs.push_back("armelf_nbsd_eabihf");
156 CmdArgs.push_back("armelf_nbsd");
160 case llvm::Triple::armeb:
161 case llvm::Triple::thumbeb:
162 arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple());
163 CmdArgs.push_back("-m");
164 switch (getToolChain().getTriple().getEnvironment()) {
165 case llvm::Triple::EABI:
166 case llvm::Triple::GNUEABI:
167 CmdArgs.push_back("armelfb_nbsd_eabi");
169 case llvm::Triple::EABIHF:
170 case llvm::Triple::GNUEABIHF:
171 CmdArgs.push_back("armelfb_nbsd_eabihf");
174 CmdArgs.push_back("armelfb_nbsd");
178 case llvm::Triple::mips64:
179 case llvm::Triple::mips64el:
180 if (mips::hasMipsAbiArg(Args, "32")) {
181 CmdArgs.push_back("-m");
182 if (getToolChain().getArch() == llvm::Triple::mips64)
183 CmdArgs.push_back("elf32btsmip");
185 CmdArgs.push_back("elf32ltsmip");
186 } else if (mips::hasMipsAbiArg(Args, "64")) {
187 CmdArgs.push_back("-m");
188 if (getToolChain().getArch() == llvm::Triple::mips64)
189 CmdArgs.push_back("elf64btsmip");
191 CmdArgs.push_back("elf64ltsmip");
194 case llvm::Triple::ppc:
195 CmdArgs.push_back("-m");
196 CmdArgs.push_back("elf32ppc_nbsd");
199 case llvm::Triple::ppc64:
200 case llvm::Triple::ppc64le:
201 CmdArgs.push_back("-m");
202 CmdArgs.push_back("elf64ppc");
205 case llvm::Triple::sparc:
206 CmdArgs.push_back("-m");
207 CmdArgs.push_back("elf32_sparc");
210 case llvm::Triple::sparcv9:
211 CmdArgs.push_back("-m");
212 CmdArgs.push_back("elf64_sparc");
219 if (Output.isFilename()) {
220 CmdArgs.push_back("-o");
221 CmdArgs.push_back(Output.getFilename());
223 assert(Output.isNothing() && "Invalid output.");
226 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
227 if (!Args.hasArg(options::OPT_shared)) {
229 Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
232 Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
233 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
235 Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
238 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
242 Args.AddAllArgs(CmdArgs, options::OPT_L);
243 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
244 Args.AddAllArgs(CmdArgs, options::OPT_e);
245 Args.AddAllArgs(CmdArgs, options::OPT_s);
246 Args.AddAllArgs(CmdArgs, options::OPT_t);
247 Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
248 Args.AddAllArgs(CmdArgs, options::OPT_r);
250 bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
251 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
253 unsigned Major, Minor, Micro;
254 getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
255 bool useLibgcc = true;
256 if (Major >= 7 || Major == 0) {
257 switch (getToolChain().getArch()) {
258 case llvm::Triple::aarch64:
259 case llvm::Triple::aarch64_be:
260 case llvm::Triple::arm:
261 case llvm::Triple::armeb:
262 case llvm::Triple::thumb:
263 case llvm::Triple::thumbeb:
264 case llvm::Triple::ppc:
265 case llvm::Triple::ppc64:
266 case llvm::Triple::ppc64le:
267 case llvm::Triple::sparc:
268 case llvm::Triple::sparcv9:
269 case llvm::Triple::x86:
270 case llvm::Triple::x86_64:
278 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
279 addOpenMPRuntime(CmdArgs, getToolChain(), Args);
281 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
282 CmdArgs.push_back("-lm");
284 if (NeedsSanitizerDeps)
285 linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
286 if (Args.hasArg(options::OPT_pthread))
287 CmdArgs.push_back("-lpthread");
288 CmdArgs.push_back("-lc");
291 if (Args.hasArg(options::OPT_static)) {
292 // libgcc_eh depends on libc, so resolve as much as possible,
293 // pull in any new requirements from libc and then get the rest
295 CmdArgs.push_back("-lgcc_eh");
296 CmdArgs.push_back("-lc");
297 CmdArgs.push_back("-lgcc");
299 CmdArgs.push_back("-lgcc");
300 CmdArgs.push_back("--as-needed");
301 CmdArgs.push_back("-lgcc_s");
302 CmdArgs.push_back("--no-as-needed");
307 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
308 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
310 Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
313 Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
314 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
317 getToolChain().addProfileRTLibs(Args, CmdArgs);
319 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
320 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
323 /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
325 NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
326 : Generic_ELF(D, Triple, Args) {
327 if (getDriver().UseStdLib) {
328 // When targeting a 32-bit platform, try the special directory used on
329 // 64-bit hosts, and only fall back to the main library directory if that
331 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
332 // what all logic is needed to emulate the '=' prefix here.
333 switch (Triple.getArch()) {
334 case llvm::Triple::x86:
335 getFilePaths().push_back("=/usr/lib/i386");
337 case llvm::Triple::arm:
338 case llvm::Triple::armeb:
339 case llvm::Triple::thumb:
340 case llvm::Triple::thumbeb:
341 switch (Triple.getEnvironment()) {
342 case llvm::Triple::EABI:
343 case llvm::Triple::GNUEABI:
344 getFilePaths().push_back("=/usr/lib/eabi");
346 case llvm::Triple::EABIHF:
347 case llvm::Triple::GNUEABIHF:
348 getFilePaths().push_back("=/usr/lib/eabihf");
351 getFilePaths().push_back("=/usr/lib/oabi");
355 case llvm::Triple::mips64:
356 case llvm::Triple::mips64el:
357 if (tools::mips::hasMipsAbiArg(Args, "o32"))
358 getFilePaths().push_back("=/usr/lib/o32");
359 else if (tools::mips::hasMipsAbiArg(Args, "64"))
360 getFilePaths().push_back("=/usr/lib/64");
362 case llvm::Triple::ppc:
363 getFilePaths().push_back("=/usr/lib/powerpc");
365 case llvm::Triple::sparc:
366 getFilePaths().push_back("=/usr/lib/sparc");
372 getFilePaths().push_back("=/usr/lib");
376 Tool *NetBSD::buildAssembler() const {
377 return new tools::netbsd::Assembler(*this);
380 Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
382 ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
383 unsigned Major, Minor, Micro;
384 getTriple().getOSVersion(Major, Minor, Micro);
385 if (Major >= 7 || Major == 0) {
387 case llvm::Triple::aarch64:
388 case llvm::Triple::aarch64_be:
389 case llvm::Triple::arm:
390 case llvm::Triple::armeb:
391 case llvm::Triple::thumb:
392 case llvm::Triple::thumbeb:
393 case llvm::Triple::ppc:
394 case llvm::Triple::ppc64:
395 case llvm::Triple::ppc64le:
396 case llvm::Triple::sparc:
397 case llvm::Triple::sparcv9:
398 case llvm::Triple::x86:
399 case llvm::Triple::x86_64:
400 return ToolChain::CST_Libcxx;
405 return ToolChain::CST_Libstdcxx;
408 std::string NetBSD::findLibCxxIncludePath() const {
409 return getDriver().SysRoot + "/usr/include/c++/";
412 void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
413 llvm::opt::ArgStringList &CC1Args) const {
414 addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
415 "", DriverArgs, CC1Args);
418 SanitizerMask NetBSD::getSupportedSanitizers() const {
419 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
420 SanitizerMask Res = ToolChain::getSupportedSanitizers();
422 Res |= SanitizerKind::Address;