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 if (getToolChain().ShouldLinkCXXStdlib(Args))
282 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
283 CmdArgs.push_back("-lm");
285 if (NeedsSanitizerDeps)
286 linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
287 if (Args.hasArg(options::OPT_pthread))
288 CmdArgs.push_back("-lpthread");
289 CmdArgs.push_back("-lc");
292 if (Args.hasArg(options::OPT_static)) {
293 // libgcc_eh depends on libc, so resolve as much as possible,
294 // pull in any new requirements from libc and then get the rest
296 CmdArgs.push_back("-lgcc_eh");
297 CmdArgs.push_back("-lc");
298 CmdArgs.push_back("-lgcc");
300 CmdArgs.push_back("-lgcc");
301 CmdArgs.push_back("--as-needed");
302 CmdArgs.push_back("-lgcc_s");
303 CmdArgs.push_back("--no-as-needed");
308 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
309 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
311 Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
314 Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
315 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
318 getToolChain().addProfileRTLibs(Args, CmdArgs);
320 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
321 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
324 /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
326 NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
327 : Generic_ELF(D, Triple, Args) {
328 if (!Args.hasArg(options::OPT_nostdlib)) {
329 // When targeting a 32-bit platform, try the special directory used on
330 // 64-bit hosts, and only fall back to the main library directory if that
332 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
333 // what all logic is needed to emulate the '=' prefix here.
334 switch (Triple.getArch()) {
335 case llvm::Triple::x86:
336 getFilePaths().push_back("=/usr/lib/i386");
338 case llvm::Triple::arm:
339 case llvm::Triple::armeb:
340 case llvm::Triple::thumb:
341 case llvm::Triple::thumbeb:
342 switch (Triple.getEnvironment()) {
343 case llvm::Triple::EABI:
344 case llvm::Triple::GNUEABI:
345 getFilePaths().push_back("=/usr/lib/eabi");
347 case llvm::Triple::EABIHF:
348 case llvm::Triple::GNUEABIHF:
349 getFilePaths().push_back("=/usr/lib/eabihf");
352 getFilePaths().push_back("=/usr/lib/oabi");
356 case llvm::Triple::mips64:
357 case llvm::Triple::mips64el:
358 if (tools::mips::hasMipsAbiArg(Args, "o32"))
359 getFilePaths().push_back("=/usr/lib/o32");
360 else if (tools::mips::hasMipsAbiArg(Args, "64"))
361 getFilePaths().push_back("=/usr/lib/64");
363 case llvm::Triple::ppc:
364 getFilePaths().push_back("=/usr/lib/powerpc");
366 case llvm::Triple::sparc:
367 getFilePaths().push_back("=/usr/lib/sparc");
373 getFilePaths().push_back("=/usr/lib");
377 Tool *NetBSD::buildAssembler() const {
378 return new tools::netbsd::Assembler(*this);
381 Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
383 ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
384 unsigned Major, Minor, Micro;
385 getTriple().getOSVersion(Major, Minor, Micro);
386 if (Major >= 7 || Major == 0) {
388 case llvm::Triple::aarch64:
389 case llvm::Triple::aarch64_be:
390 case llvm::Triple::arm:
391 case llvm::Triple::armeb:
392 case llvm::Triple::thumb:
393 case llvm::Triple::thumbeb:
394 case llvm::Triple::ppc:
395 case llvm::Triple::ppc64:
396 case llvm::Triple::ppc64le:
397 case llvm::Triple::sparc:
398 case llvm::Triple::sparcv9:
399 case llvm::Triple::x86:
400 case llvm::Triple::x86_64:
401 return ToolChain::CST_Libcxx;
406 return ToolChain::CST_Libstdcxx;
409 std::string NetBSD::findLibCxxIncludePath() const {
410 return getDriver().SysRoot + "/usr/include/c++/";
413 void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
414 llvm::opt::ArgStringList &CC1Args) const {
415 addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
416 "", DriverArgs, CC1Args);
419 llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const {
420 // NetBSD uses Dwarf exceptions on ARM.
421 llvm::Triple::ArchType TArch = getTriple().getArch();
422 if (TArch == llvm::Triple::arm || TArch == llvm::Triple::armeb ||
423 TArch == llvm::Triple::thumb || TArch == llvm::Triple::thumbeb)
424 return llvm::ExceptionHandling::DwarfCFI;
425 return llvm::ExceptionHandling::None;
428 SanitizerMask NetBSD::getSupportedSanitizers() const {
429 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
430 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
431 SanitizerMask Res = ToolChain::getSupportedSanitizers();
432 if (IsX86 || IsX86_64) {
433 Res |= SanitizerKind::Address;
434 Res |= SanitizerKind::Function;
435 Res |= SanitizerKind::Leak;
436 Res |= SanitizerKind::SafeStack;
437 Res |= SanitizerKind::Scudo;
438 Res |= SanitizerKind::Vptr;
441 Res |= SanitizerKind::Efficiency;
442 Res |= SanitizerKind::Fuzzer;
443 Res |= SanitizerKind::FuzzerNoLink;
444 Res |= SanitizerKind::KernelAddress;
445 Res |= SanitizerKind::Memory;
446 Res |= SanitizerKind::Thread;