blob: 3a33432f3dc06d4de053c81cb4bc3429ddf91598 [file] [log] [blame]
David L. Jonesf561aba2017-03-08 01:02:16 +00001//===--- OpenBSD.cpp - OpenBSD 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 "OpenBSD.h"
11#include "Arch/Mips.h"
12#include "Arch/Sparc.h"
13#include "CommonArgs.h"
14#include "clang/Driver/Compilation.h"
15#include "clang/Driver/Options.h"
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +000016#include "clang/Driver/SanitizerArgs.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000017#include "llvm/Option/ArgList.h"
18
19using namespace clang::driver;
20using namespace clang::driver::tools;
21using namespace clang::driver::toolchains;
22using namespace clang;
23using namespace llvm::opt;
24
Dean Michael Berris9b592332018-04-04 12:47:49 +000025static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args,
26 ArgStringList &CmdArgs) {
27 if (Args.hasArg(options::OPT_shared))
28 return false;
29
30 if (Args.hasFlag(options::OPT_fxray_instrument,
31 options::OPT_fnoxray_instrument, false)) {
32 CmdArgs.push_back("-whole-archive");
33 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false));
34 CmdArgs.push_back("-no-whole-archive");
35 return true;
36 }
37
38 return false;
39}
40
41static void linkXRayRuntimeDeps(const ToolChain &TC, const ArgList &Args,
42 ArgStringList &CmdArgs) {
43 CmdArgs.push_back("--no-as-needed");
44 CmdArgs.push_back("-lm");
45 CmdArgs.push_back("-lpthread");
46}
47
David L. Jonesf561aba2017-03-08 01:02:16 +000048void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
49 const InputInfo &Output,
50 const InputInfoList &Inputs,
51 const ArgList &Args,
52 const char *LinkingOutput) const {
53 claimNoWarnArgs(Args);
54 ArgStringList CmdArgs;
55
56 switch (getToolChain().getArch()) {
57 case llvm::Triple::x86:
58 // When building 32-bit code on OpenBSD/amd64, we have to explicitly
59 // instruct as in the base system to assemble 32-bit code.
60 CmdArgs.push_back("--32");
61 break;
62
63 case llvm::Triple::ppc:
64 CmdArgs.push_back("-mppc");
65 CmdArgs.push_back("-many");
66 break;
67
68 case llvm::Triple::sparc:
69 case llvm::Triple::sparcel: {
70 CmdArgs.push_back("-32");
71 std::string CPU = getCPUName(Args, getToolChain().getTriple());
72 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
73 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
74 break;
75 }
76
77 case llvm::Triple::sparcv9: {
78 CmdArgs.push_back("-64");
79 std::string CPU = getCPUName(Args, getToolChain().getTriple());
80 CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
81 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
82 break;
83 }
84
85 case llvm::Triple::mips64:
86 case llvm::Triple::mips64el: {
87 StringRef CPUName;
88 StringRef ABIName;
89 mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
90
91 CmdArgs.push_back("-mabi");
92 CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
93
94 if (getToolChain().getArch() == llvm::Triple::mips64)
95 CmdArgs.push_back("-EB");
96 else
97 CmdArgs.push_back("-EL");
98
99 AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
100 break;
101 }
102
103 default:
104 break;
105 }
106
107 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
108
109 CmdArgs.push_back("-o");
110 CmdArgs.push_back(Output.getFilename());
111
112 for (const auto &II : Inputs)
113 CmdArgs.push_back(II.getFilename());
114
115 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
116 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
117}
118
119void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
120 const InputInfo &Output,
121 const InputInfoList &Inputs,
122 const ArgList &Args,
123 const char *LinkingOutput) const {
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +0000124 const toolchains::OpenBSD &ToolChain =
125 static_cast<const toolchains::OpenBSD &>(getToolChain());
David L. Jonesf561aba2017-03-08 01:02:16 +0000126 const Driver &D = getToolChain().getDriver();
127 ArgStringList CmdArgs;
128
129 // Silence warning for "clang -g foo.o -o foo"
130 Args.ClaimAllArgs(options::OPT_g_Group);
131 // and "clang -emit-llvm foo.o -o foo"
132 Args.ClaimAllArgs(options::OPT_emit_llvm);
133 // and for "clang -w foo.o -o foo". Other warning options are already
134 // handled somewhere else.
135 Args.ClaimAllArgs(options::OPT_w);
136
137 if (getToolChain().getArch() == llvm::Triple::mips64)
138 CmdArgs.push_back("-EB");
139 else if (getToolChain().getArch() == llvm::Triple::mips64el)
140 CmdArgs.push_back("-EL");
141
142 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
143 CmdArgs.push_back("-e");
144 CmdArgs.push_back("__start");
145 }
146
147 CmdArgs.push_back("--eh-frame-hdr");
148 if (Args.hasArg(options::OPT_static)) {
149 CmdArgs.push_back("-Bstatic");
150 } else {
151 if (Args.hasArg(options::OPT_rdynamic))
152 CmdArgs.push_back("-export-dynamic");
153 CmdArgs.push_back("-Bdynamic");
154 if (Args.hasArg(options::OPT_shared)) {
155 CmdArgs.push_back("-shared");
156 } else {
157 CmdArgs.push_back("-dynamic-linker");
158 CmdArgs.push_back("/usr/libexec/ld.so");
159 }
160 }
161
Brad Smith580f8e62017-07-30 21:13:59 +0000162 if (Args.hasArg(options::OPT_pie))
163 CmdArgs.push_back("-pie");
David L. Jonesf561aba2017-03-08 01:02:16 +0000164 if (Args.hasArg(options::OPT_nopie))
165 CmdArgs.push_back("-nopie");
166
167 if (Output.isFilename()) {
168 CmdArgs.push_back("-o");
169 CmdArgs.push_back(Output.getFilename());
170 } else {
171 assert(Output.isNothing() && "Invalid output.");
172 }
173
174 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
175 if (!Args.hasArg(options::OPT_shared)) {
176 if (Args.hasArg(options::OPT_pg))
177 CmdArgs.push_back(
178 Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
179 else if (Args.hasArg(options::OPT_static) &&
180 !Args.hasArg(options::OPT_nopie))
181 CmdArgs.push_back(
182 Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
183 else
184 CmdArgs.push_back(
185 Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
186 CmdArgs.push_back(
187 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
188 } else {
189 CmdArgs.push_back(
190 Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
191 }
192 }
193
194 std::string Triple = getToolChain().getTripleString();
195 if (Triple.substr(0, 6) == "x86_64")
196 Triple.replace(0, 6, "amd64");
197 CmdArgs.push_back(
198 Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +0000199 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib"));
David L. Jonesf561aba2017-03-08 01:02:16 +0000200
201 Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
202 options::OPT_e, options::OPT_s, options::OPT_t,
203 options::OPT_Z_Flag, options::OPT_r});
204
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +0000205 bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
Dean Michael Berris9b592332018-04-04 12:47:49 +0000206 bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000207 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
208
209 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
210 if (D.CCCIsCXX()) {
Nico Weber0ee47d92017-07-25 18:02:57 +0000211 if (getToolChain().ShouldLinkCXXStdlib(Args))
212 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000213 if (Args.hasArg(options::OPT_pg))
214 CmdArgs.push_back("-lm_p");
215 else
216 CmdArgs.push_back("-lm");
217 }
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +0000218 if (NeedsSanitizerDeps) {
219 CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
220 linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
221 }
Dean Michael Berris9b592332018-04-04 12:47:49 +0000222 if (NeedsXRayDeps) {
223 CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
224 linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);
225 }
David L. Jonesf561aba2017-03-08 01:02:16 +0000226 // FIXME: For some reason GCC passes -lgcc before adding
227 // the default system libraries. Just mimic this for now.
228 CmdArgs.push_back("-lgcc");
229
230 if (Args.hasArg(options::OPT_pthread)) {
231 if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
232 CmdArgs.push_back("-lpthread_p");
233 else
234 CmdArgs.push_back("-lpthread");
235 }
236
237 if (!Args.hasArg(options::OPT_shared)) {
238 if (Args.hasArg(options::OPT_pg))
239 CmdArgs.push_back("-lc_p");
240 else
241 CmdArgs.push_back("-lc");
242 }
243
244 CmdArgs.push_back("-lgcc");
245 }
246
247 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
248 if (!Args.hasArg(options::OPT_shared))
249 CmdArgs.push_back(
250 Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
251 else
252 CmdArgs.push_back(
253 Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
254 }
255
256 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
257 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
258}
259
Kamil Rytarowski3f7f9602018-03-03 11:52:52 +0000260SanitizerMask OpenBSD::getSupportedSanitizers() const {
261 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
262 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
263
264 // For future use, only UBsan at the moment
265 SanitizerMask Res = ToolChain::getSupportedSanitizers();
266
267 if (IsX86 || IsX86_64)
268 Res |= SanitizerKind::Vptr;
269
270 return Res;
271}
272
David L. Jonesf561aba2017-03-08 01:02:16 +0000273/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
274
275OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
276 const ArgList &Args)
277 : Generic_ELF(D, Triple, Args) {
278 getFilePaths().push_back(getDriver().Dir + "/../lib");
279 getFilePaths().push_back("/usr/lib");
280}
281
282Tool *OpenBSD::buildAssembler() const {
283 return new tools::openbsd::Assembler(*this);
284}
285
286Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }