blob: e89ee377e7db6a536e1bbf230be5c504592f0834 [file] [log] [blame]
David L. Jonesf561aba2017-03-08 01:02:16 +00001//===--- 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"
Kamil Rytarowski2eef4752017-07-04 19:55:56 +000018#include "clang/Driver/SanitizerArgs.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000019#include "llvm/Option/ArgList.h"
20
21using namespace clang::driver;
22using namespace clang::driver::tools;
23using namespace clang::driver::toolchains;
24using namespace clang;
25using namespace llvm::opt;
26
27void 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
110void 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
Kamil Rytarowski2eef4752017-07-04 19:55:56 +0000250 bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000251 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 }
Kamil Rytarowski2eef4752017-07-04 19:55:56 +0000284 if (NeedsSanitizerDeps)
285 linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000286 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
325NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
326 : Generic_ELF(D, Triple, Args) {
Nico Webere0c3f902017-07-23 16:31:47 +0000327 if (!Args.hasArg(options::OPT_nostdlib)) {
David L. Jonesf561aba2017-03-08 01:02:16 +0000328 // 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
376Tool *NetBSD::buildAssembler() const {
377 return new tools::netbsd::Assembler(*this);
378}
379
380Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
381
382ToolChain::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
408std::string NetBSD::findLibCxxIncludePath() const {
409 return getDriver().SysRoot + "/usr/include/c++/";
410}
411
412void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
413 llvm::opt::ArgStringList &CC1Args) const {
414 addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "",
415 "", DriverArgs, CC1Args);
416}
Kamil Rytarowski2eef4752017-07-04 19:55:56 +0000417
418SanitizerMask 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}