1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "OpenBSD.h" |
10 | #include "Arch/Mips.h" |
11 | #include "Arch/Sparc.h" |
12 | #include "CommonArgs.h" |
13 | #include "clang/Driver/Compilation.h" |
14 | #include "clang/Driver/Options.h" |
15 | #include "clang/Driver/SanitizerArgs.h" |
16 | #include "llvm/Option/ArgList.h" |
17 | |
18 | using namespace clang::driver; |
19 | using namespace clang::driver::tools; |
20 | using namespace clang::driver::toolchains; |
21 | using namespace clang; |
22 | using namespace llvm::opt; |
23 | |
24 | void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
25 | const InputInfo &Output, |
26 | const InputInfoList &Inputs, |
27 | const ArgList &Args, |
28 | const char *LinkingOutput) const { |
29 | claimNoWarnArgs(Args); |
30 | ArgStringList CmdArgs; |
31 | |
32 | switch (getToolChain().getArch()) { |
33 | case llvm::Triple::x86: |
34 | |
35 | |
36 | CmdArgs.push_back("--32"); |
37 | break; |
38 | |
39 | case llvm::Triple::ppc: |
40 | CmdArgs.push_back("-mppc"); |
41 | CmdArgs.push_back("-many"); |
42 | break; |
43 | |
44 | case llvm::Triple::sparc: |
45 | case llvm::Triple::sparcel: { |
46 | CmdArgs.push_back("-32"); |
47 | std::string CPU = getCPUName(Args, getToolChain().getTriple()); |
48 | CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); |
49 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
50 | break; |
51 | } |
52 | |
53 | case llvm::Triple::sparcv9: { |
54 | CmdArgs.push_back("-64"); |
55 | std::string CPU = getCPUName(Args, getToolChain().getTriple()); |
56 | CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); |
57 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
58 | break; |
59 | } |
60 | |
61 | case llvm::Triple::mips64: |
62 | case llvm::Triple::mips64el: { |
63 | StringRef CPUName; |
64 | StringRef ABIName; |
65 | mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); |
66 | |
67 | CmdArgs.push_back("-mabi"); |
68 | CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data()); |
69 | |
70 | if (getToolChain().getTriple().isLittleEndian()) |
71 | CmdArgs.push_back("-EL"); |
72 | else |
73 | CmdArgs.push_back("-EB"); |
74 | |
75 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
76 | break; |
77 | } |
78 | |
79 | default: |
80 | break; |
81 | } |
82 | |
83 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
84 | |
85 | CmdArgs.push_back("-o"); |
86 | CmdArgs.push_back(Output.getFilename()); |
87 | |
88 | for (const auto &II : Inputs) |
89 | CmdArgs.push_back(II.getFilename()); |
90 | |
91 | const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); |
92 | C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); |
93 | } |
94 | |
95 | void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
96 | const InputInfo &Output, |
97 | const InputInfoList &Inputs, |
98 | const ArgList &Args, |
99 | const char *LinkingOutput) const { |
100 | const toolchains::OpenBSD &ToolChain = |
101 | static_cast<const toolchains::OpenBSD &>(getToolChain()); |
102 | const Driver &D = getToolChain().getDriver(); |
103 | ArgStringList CmdArgs; |
104 | |
105 | |
106 | Args.ClaimAllArgs(options::OPT_g_Group); |
107 | |
108 | Args.ClaimAllArgs(options::OPT_emit_llvm); |
109 | |
110 | |
111 | Args.ClaimAllArgs(options::OPT_w); |
112 | |
113 | if (ToolChain.getArch() == llvm::Triple::mips64) |
114 | CmdArgs.push_back("-EB"); |
115 | else if (ToolChain.getArch() == llvm::Triple::mips64el) |
116 | CmdArgs.push_back("-EL"); |
117 | |
118 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) { |
119 | CmdArgs.push_back("-e"); |
120 | CmdArgs.push_back("__start"); |
121 | } |
122 | |
123 | CmdArgs.push_back("--eh-frame-hdr"); |
124 | if (Args.hasArg(options::OPT_static)) { |
125 | CmdArgs.push_back("-Bstatic"); |
126 | } else { |
127 | if (Args.hasArg(options::OPT_rdynamic)) |
128 | CmdArgs.push_back("-export-dynamic"); |
129 | CmdArgs.push_back("-Bdynamic"); |
130 | if (Args.hasArg(options::OPT_shared)) { |
131 | CmdArgs.push_back("-shared"); |
132 | } else { |
133 | CmdArgs.push_back("-dynamic-linker"); |
134 | CmdArgs.push_back("/usr/libexec/ld.so"); |
135 | } |
136 | } |
137 | |
138 | if (Args.hasArg(options::OPT_pie)) |
139 | CmdArgs.push_back("-pie"); |
140 | if (Args.hasArg(options::OPT_nopie) || Args.hasArg(options::OPT_pg)) |
141 | CmdArgs.push_back("-nopie"); |
142 | |
143 | if (Output.isFilename()) { |
144 | CmdArgs.push_back("-o"); |
145 | CmdArgs.push_back(Output.getFilename()); |
146 | } else { |
147 | (0) . __assert_fail ("Output.isNothing() && \"Invalid output.\"", "/home/seafit/code_projects/clang_source/clang/lib/Driver/ToolChains/OpenBSD.cpp", 147, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Output.isNothing() && "Invalid output."); |
148 | } |
149 | |
150 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
151 | const char *crt0 = nullptr; |
152 | const char *crtbegin = nullptr; |
153 | if (!Args.hasArg(options::OPT_shared)) { |
154 | if (Args.hasArg(options::OPT_pg)) |
155 | crt0 = "gcrt0.o"; |
156 | else if (Args.hasArg(options::OPT_static) && |
157 | !Args.hasArg(options::OPT_nopie)) |
158 | crt0 = "rcrt0.o"; |
159 | else |
160 | crt0 = "crt0.o"; |
161 | crtbegin = "crtbegin.o"; |
162 | } else { |
163 | crtbegin = "crtbeginS.o"; |
164 | } |
165 | |
166 | if (crt0) |
167 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt0))); |
168 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); |
169 | } |
170 | |
171 | Args.AddAllArgs(CmdArgs, options::OPT_L); |
172 | ToolChain.AddFilePathLibArgs(Args, CmdArgs); |
173 | Args.AddAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_e, |
174 | options::OPT_s, options::OPT_t, |
175 | options::OPT_Z_Flag, options::OPT_r}); |
176 | |
177 | bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); |
178 | bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); |
179 | AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); |
180 | |
181 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { |
182 | if (D.CCCIsCXX()) { |
183 | if (ToolChain.ShouldLinkCXXStdlib(Args)) |
184 | ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); |
185 | if (Args.hasArg(options::OPT_pg)) |
186 | CmdArgs.push_back("-lm_p"); |
187 | else |
188 | CmdArgs.push_back("-lm"); |
189 | } |
190 | if (NeedsSanitizerDeps) { |
191 | CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); |
192 | linkSanitizerRuntimeDeps(ToolChain, CmdArgs); |
193 | } |
194 | if (NeedsXRayDeps) { |
195 | CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); |
196 | linkXRayRuntimeDeps(ToolChain, CmdArgs); |
197 | } |
198 | |
199 | |
200 | CmdArgs.push_back("-lcompiler_rt"); |
201 | |
202 | if (Args.hasArg(options::OPT_pthread)) { |
203 | if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg)) |
204 | CmdArgs.push_back("-lpthread_p"); |
205 | else |
206 | CmdArgs.push_back("-lpthread"); |
207 | } |
208 | |
209 | if (!Args.hasArg(options::OPT_shared)) { |
210 | if (Args.hasArg(options::OPT_pg)) |
211 | CmdArgs.push_back("-lc_p"); |
212 | else |
213 | CmdArgs.push_back("-lc"); |
214 | } |
215 | |
216 | CmdArgs.push_back("-lcompiler_rt"); |
217 | } |
218 | |
219 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
220 | const char *crtend = nullptr; |
221 | if (!Args.hasArg(options::OPT_shared)) |
222 | crtend = "crtend.o"; |
223 | else |
224 | crtend = "crtendS.o"; |
225 | |
226 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); |
227 | } |
228 | |
229 | const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); |
230 | C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); |
231 | } |
232 | |
233 | SanitizerMask OpenBSD::getSupportedSanitizers() const { |
234 | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
235 | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
236 | |
237 | |
238 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
239 | |
240 | if (IsX86 || IsX86_64) { |
241 | Res |= SanitizerKind::Vptr; |
242 | Res |= SanitizerKind::Fuzzer; |
243 | Res |= SanitizerKind::FuzzerNoLink; |
244 | } |
245 | |
246 | return Res; |
247 | } |
248 | |
249 | |
250 | |
251 | OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple, |
252 | const ArgList &Args) |
253 | : Generic_ELF(D, Triple, Args) { |
254 | getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); |
255 | } |
256 | |
257 | void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args, |
258 | ArgStringList &CmdArgs) const { |
259 | bool Profiling = Args.hasArg(options::OPT_pg); |
260 | |
261 | CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); |
262 | CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi"); |
263 | } |
264 | |
265 | Tool *OpenBSD::buildAssembler() const { |
266 | return new tools::openbsd::Assembler(*this); |
267 | } |
268 | |
269 | Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); } |
270 | |