]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/ToolChains/NetBSD.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r307894, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Driver / ToolChains / NetBSD.cpp
1 //===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "NetBSD.h"
11 #include "Arch/ARM.h"
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"
20
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;
26
27 void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
28                                      const InputInfo &Output,
29                                      const InputInfoList &Inputs,
30                                      const ArgList &Args,
31                                      const char *LinkingOutput) const {
32   claimNoWarnArgs(Args);
33   ArgStringList CmdArgs;
34
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");
40     break;
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);
47     std::string Arch =
48         arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
49     CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
50     break;
51   }
52
53   case llvm::Triple::mips:
54   case llvm::Triple::mipsel:
55   case llvm::Triple::mips64:
56   case llvm::Triple::mips64el: {
57     StringRef CPUName;
58     StringRef ABIName;
59     mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
60
61     CmdArgs.push_back("-march");
62     CmdArgs.push_back(CPUName.data());
63
64     CmdArgs.push_back("-mabi");
65     CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
66
67     if (getToolChain().getArch() == llvm::Triple::mips ||
68         getToolChain().getArch() == llvm::Triple::mips64)
69       CmdArgs.push_back("-EB");
70     else
71       CmdArgs.push_back("-EL");
72
73     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
74     break;
75   }
76
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);
83     break;
84   }
85
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);
91     break;
92   }
93
94   default:
95     break;
96   }
97
98   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
99
100   CmdArgs.push_back("-o");
101   CmdArgs.push_back(Output.getFilename());
102
103   for (const auto &II : Inputs)
104     CmdArgs.push_back(II.getFilename());
105
106   const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
107   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
108 }
109
110 void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
111                                   const InputInfo &Output,
112                                   const InputInfoList &Inputs,
113                                   const ArgList &Args,
114                                   const char *LinkingOutput) const {
115   const Driver &D = getToolChain().getDriver();
116   ArgStringList CmdArgs;
117
118   if (!D.SysRoot.empty())
119     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
120
121   CmdArgs.push_back("--eh-frame-hdr");
122   if (Args.hasArg(options::OPT_static)) {
123     CmdArgs.push_back("-Bstatic");
124   } else {
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");
129     } else {
130       Args.AddAllArgs(CmdArgs, options::OPT_pie);
131       CmdArgs.push_back("-dynamic-linker");
132       CmdArgs.push_back("/libexec/ld.elf_so");
133     }
134   }
135
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");
142     break;
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");
150       break;
151     case llvm::Triple::EABIHF:
152     case llvm::Triple::GNUEABIHF:
153       CmdArgs.push_back("armelf_nbsd_eabihf");
154       break;
155     default:
156       CmdArgs.push_back("armelf_nbsd");
157       break;
158     }
159     break;
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");
168       break;
169     case llvm::Triple::EABIHF:
170     case llvm::Triple::GNUEABIHF:
171       CmdArgs.push_back("armelfb_nbsd_eabihf");
172       break;
173     default:
174       CmdArgs.push_back("armelfb_nbsd");
175       break;
176     }
177     break;
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");
184       else
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");
190       else
191         CmdArgs.push_back("elf64ltsmip");
192     }
193     break;
194   case llvm::Triple::ppc:
195     CmdArgs.push_back("-m");
196     CmdArgs.push_back("elf32ppc_nbsd");
197     break;
198
199   case llvm::Triple::ppc64:
200   case llvm::Triple::ppc64le:
201     CmdArgs.push_back("-m");
202     CmdArgs.push_back("elf64ppc");
203     break;
204
205   case llvm::Triple::sparc:
206     CmdArgs.push_back("-m");
207     CmdArgs.push_back("elf32_sparc");
208     break;
209
210   case llvm::Triple::sparcv9:
211     CmdArgs.push_back("-m");
212     CmdArgs.push_back("elf64_sparc");
213     break;
214
215   default:
216     break;
217   }
218
219   if (Output.isFilename()) {
220     CmdArgs.push_back("-o");
221     CmdArgs.push_back(Output.getFilename());
222   } else {
223     assert(Output.isNothing() && "Invalid output.");
224   }
225
226   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
227     if (!Args.hasArg(options::OPT_shared)) {
228       CmdArgs.push_back(
229           Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
230     }
231     CmdArgs.push_back(
232         Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
233     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
234       CmdArgs.push_back(
235           Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
236     } else {
237       CmdArgs.push_back(
238           Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
239     }
240   }
241
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);
249
250   bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
251   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
252
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:
271       useLibgcc = false;
272       break;
273     default:
274       break;
275     }
276   }
277
278   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
279     addOpenMPRuntime(CmdArgs, getToolChain(), Args);
280     if (D.CCCIsCXX()) {
281       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
282       CmdArgs.push_back("-lm");
283     }
284     if (NeedsSanitizerDeps)
285       linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
286     if (Args.hasArg(options::OPT_pthread))
287       CmdArgs.push_back("-lpthread");
288     CmdArgs.push_back("-lc");
289
290     if (useLibgcc) {
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
294         // of libgcc.
295         CmdArgs.push_back("-lgcc_eh");
296         CmdArgs.push_back("-lc");
297         CmdArgs.push_back("-lgcc");
298       } else {
299         CmdArgs.push_back("-lgcc");
300         CmdArgs.push_back("--as-needed");
301         CmdArgs.push_back("-lgcc_s");
302         CmdArgs.push_back("--no-as-needed");
303       }
304     }
305   }
306
307   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
308     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
309       CmdArgs.push_back(
310           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
311     else
312       CmdArgs.push_back(
313           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
314     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
315   }
316
317   getToolChain().addProfileRTLibs(Args, CmdArgs);
318
319   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
320   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
321 }
322
323 /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
324
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
330     // doesn't work.
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");
336       break;
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");
345         break;
346       case llvm::Triple::EABIHF:
347       case llvm::Triple::GNUEABIHF:
348         getFilePaths().push_back("=/usr/lib/eabihf");
349         break;
350       default:
351         getFilePaths().push_back("=/usr/lib/oabi");
352         break;
353       }
354       break;
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");
361       break;
362     case llvm::Triple::ppc:
363       getFilePaths().push_back("=/usr/lib/powerpc");
364       break;
365     case llvm::Triple::sparc:
366       getFilePaths().push_back("=/usr/lib/sparc");
367       break;
368     default:
369       break;
370     }
371
372     getFilePaths().push_back("=/usr/lib");
373   }
374 }
375
376 Tool *NetBSD::buildAssembler() const {
377   return new tools::netbsd::Assembler(*this);
378 }
379
380 Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
381
382 ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
383   unsigned Major, Minor, Micro;
384   getTriple().getOSVersion(Major, Minor, Micro);
385   if (Major >= 7 || Major == 0) {
386     switch (getArch()) {
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;
401     default:
402       break;
403     }
404   }
405   return ToolChain::CST_Libstdcxx;
406 }
407
408 std::string NetBSD::findLibCxxIncludePath() const {
409   return getDriver().SysRoot + "/usr/include/c++/";
410 }
411
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);
416 }
417
418 SanitizerMask NetBSD::getSupportedSanitizers() const {
419   const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
420   SanitizerMask Res = ToolChain::getSupportedSanitizers();
421   if (IsX86_64) {
422     Res |= SanitizerKind::Address;
423   }
424   return Res;
425 }