1//===-- BareMetal.cpp - Bare Metal ToolChain --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "BareMetal.h"
10
11#include "Gnu.h"
12#include "clang/Driver/CommonArgs.h"
13#include "clang/Driver/InputInfo.h"
14
15#include "Arch/ARM.h"
16#include "Arch/RISCV.h"
17#include "clang/Driver/Compilation.h"
18#include "clang/Driver/Driver.h"
19#include "clang/Driver/MultilibBuilder.h"
20#include "clang/Driver/Options.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/Option/ArgList.h"
23#include "llvm/Support/Path.h"
24#include "llvm/Support/VirtualFileSystem.h"
25
26#include <sstream>
27
28using namespace llvm::opt;
29using namespace clang;
30using namespace clang::driver;
31using namespace clang::driver::tools;
32using namespace clang::driver::toolchains;
33
34static bool findRISCVMultilibs(const Driver &D,
35 const llvm::Triple &TargetTriple,
36 const ArgList &Args, DetectedMultilibs &Result) {
37 Multilib::flags_list Flags;
38 std::string Arch = riscv::getRISCVArch(Args, Triple: TargetTriple);
39 StringRef Abi = tools::riscv::getRISCVABI(Args, Triple: TargetTriple);
40
41 if (TargetTriple.isRISCV64()) {
42 MultilibBuilder Imac =
43 MultilibBuilder().flag(Flag: "-march=rv64imac").flag(Flag: "-mabi=lp64");
44 MultilibBuilder Imafdc = MultilibBuilder("/rv64imafdc/lp64d")
45 .flag(Flag: "-march=rv64imafdc")
46 .flag(Flag: "-mabi=lp64d");
47
48 // Multilib reuse
49 bool UseImafdc =
50 (Arch == "rv64imafdc") || (Arch == "rv64gc"); // gc => imafdc
51
52 addMultilibFlag(Enabled: (Arch == "rv64imac"), Flag: "-march=rv64imac", Flags);
53 addMultilibFlag(Enabled: UseImafdc, Flag: "-march=rv64imafdc", Flags);
54 addMultilibFlag(Enabled: Abi == "lp64", Flag: "-mabi=lp64", Flags);
55 addMultilibFlag(Enabled: Abi == "lp64d", Flag: "-mabi=lp64d", Flags);
56
57 Result.Multilibs =
58 MultilibSetBuilder().Either(M1: Imac, M2: Imafdc).makeMultilibSet();
59 return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
60 }
61 if (TargetTriple.isRISCV32()) {
62 MultilibBuilder Imac =
63 MultilibBuilder().flag(Flag: "-march=rv32imac").flag(Flag: "-mabi=ilp32");
64 MultilibBuilder I = MultilibBuilder("/rv32i/ilp32")
65 .flag(Flag: "-march=rv32i")
66 .flag(Flag: "-mabi=ilp32");
67 MultilibBuilder Im = MultilibBuilder("/rv32im/ilp32")
68 .flag(Flag: "-march=rv32im")
69 .flag(Flag: "-mabi=ilp32");
70 MultilibBuilder Iac = MultilibBuilder("/rv32iac/ilp32")
71 .flag(Flag: "-march=rv32iac")
72 .flag(Flag: "-mabi=ilp32");
73 MultilibBuilder Imafc = MultilibBuilder("/rv32imafc/ilp32f")
74 .flag(Flag: "-march=rv32imafc")
75 .flag(Flag: "-mabi=ilp32f");
76
77 // Multilib reuse
78 bool UseI = (Arch == "rv32i") || (Arch == "rv32ic"); // ic => i
79 bool UseIm = (Arch == "rv32im") || (Arch == "rv32imc"); // imc => im
80 bool UseImafc = (Arch == "rv32imafc") || (Arch == "rv32imafdc") ||
81 (Arch == "rv32gc"); // imafdc,gc => imafc
82
83 addMultilibFlag(Enabled: UseI, Flag: "-march=rv32i", Flags);
84 addMultilibFlag(Enabled: UseIm, Flag: "-march=rv32im", Flags);
85 addMultilibFlag(Enabled: (Arch == "rv32iac"), Flag: "-march=rv32iac", Flags);
86 addMultilibFlag(Enabled: (Arch == "rv32imac"), Flag: "-march=rv32imac", Flags);
87 addMultilibFlag(Enabled: UseImafc, Flag: "-march=rv32imafc", Flags);
88 addMultilibFlag(Enabled: Abi == "ilp32", Flag: "-mabi=ilp32", Flags);
89 addMultilibFlag(Enabled: Abi == "ilp32f", Flag: "-mabi=ilp32f", Flags);
90
91 Result.Multilibs =
92 MultilibSetBuilder().Either(M1: I, M2: Im, M3: Iac, M4: Imac, M5: Imafc).makeMultilibSet();
93 return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
94 }
95 return false;
96}
97
98static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
99 if (!D.SysRoot.empty())
100 return D.SysRoot;
101
102 SmallString<128> SysRootDir(D.Dir);
103 llvm::sys::path::append(path&: SysRootDir, a: "..", b: "lib", c: "clang-runtimes");
104
105 if (IncludeTriple)
106 llvm::sys::path::append(path&: SysRootDir, a: D.getTargetTriple());
107
108 return std::string(SysRootDir);
109}
110
111BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
112 const ArgList &Args)
113 : ToolChain(D, Triple, Args),
114 SysRoot(computeBaseSysRoot(D, /*IncludeTriple=*/true)) {
115 getProgramPaths().push_back(Elt: getDriver().Dir);
116
117 findMultilibs(D, Triple, Args);
118 SmallString<128> SysRoot(computeSysRoot());
119 if (!SysRoot.empty()) {
120 for (const Multilib &M : getOrderedMultilibs()) {
121 SmallString<128> Dir(SysRoot);
122 llvm::sys::path::append(path&: Dir, a: M.osSuffix(), b: "lib");
123 getFilePaths().push_back(Elt: std::string(Dir));
124 getLibraryPaths().push_back(Elt: std::string(Dir));
125 }
126 }
127}
128
129/// Is the triple {aarch64.aarch64_be}-none-elf?
130static bool isAArch64BareMetal(const llvm::Triple &Triple) {
131 if (Triple.getArch() != llvm::Triple::aarch64 &&
132 Triple.getArch() != llvm::Triple::aarch64_be)
133 return false;
134
135 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
136 return false;
137
138 if (Triple.getOS() != llvm::Triple::UnknownOS)
139 return false;
140
141 return Triple.getEnvironmentName() == "elf";
142}
143
144static bool isRISCVBareMetal(const llvm::Triple &Triple) {
145 if (!Triple.isRISCV())
146 return false;
147
148 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
149 return false;
150
151 if (Triple.getOS() != llvm::Triple::UnknownOS)
152 return false;
153
154 return Triple.getEnvironmentName() == "elf";
155}
156
157/// Is the triple powerpc[64][le]-*-none-eabi?
158static bool isPPCBareMetal(const llvm::Triple &Triple) {
159 return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
160 Triple.getEnvironment() == llvm::Triple::EABI;
161}
162
163static void
164findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
165 StringRef MultilibPath, const ArgList &Args,
166 DetectedMultilibs &Result,
167 SmallVector<StringRef> &CustomFlagsMacroDefines) {
168 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
169 D.getVFS().getBufferForFile(Name: MultilibPath);
170 if (!MB)
171 return;
172 Multilib::flags_list Flags = TC.getMultilibFlags(Args);
173 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
174 MultilibSet::parseYaml(*MB.get());
175 if (ErrorOrMultilibSet.getError())
176 return;
177 Result.Multilibs = ErrorOrMultilibSet.get();
178 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs,
179 &CustomFlagsMacroDefines))
180 return;
181 D.Diag(clang::diag::DiagID: warn_drv_missing_multilib) << llvm::join(R&: Flags, Separator: " ");
182 std::stringstream ss;
183
184 // If multilib selection didn't complete successfully, report a list
185 // of all the configurations the user could have provided.
186 for (const Multilib &Multilib : Result.Multilibs)
187 if (!Multilib.isError())
188 ss << "\n" << llvm::join(R: Multilib.flags(), Separator: " ");
189 D.Diag(clang::diag::DiagID: note_drv_available_multilibs) << ss.str();
190
191 // Now report any custom error messages requested by the YAML. We do
192 // this after displaying the list of available multilibs, because
193 // that list is probably large, and (in interactive use) risks
194 // scrolling the useful error message off the top of the user's
195 // terminal.
196 for (const Multilib &Multilib : Result.SelectedMultilibs)
197 if (Multilib.isError())
198 D.Diag(clang::diag::DiagID: err_drv_multilib_custom_error)
199 << Multilib.getErrorMessage();
200
201 // If there was an error, clear the SelectedMultilibs vector, in
202 // case it contains partial data.
203 Result.SelectedMultilibs.clear();
204}
205
206static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";
207
208static std::optional<llvm::SmallString<128>>
209getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
210 const ArgList &Args) {
211 llvm::SmallString<128> MultilibPath;
212 if (Arg *ConfigFileArg = Args.getLastArg(options::OPT_multi_lib_config)) {
213 MultilibPath = ConfigFileArg->getValue();
214 if (!D.getVFS().exists(Path: MultilibPath)) {
215 D.Diag(clang::diag::DiagID: err_drv_no_such_file) << MultilibPath.str();
216 return {};
217 }
218 } else {
219 MultilibPath = computeBaseSysRoot(D, /*IncludeTriple=*/false);
220 llvm::sys::path::append(path&: MultilibPath, a: MultilibFilename);
221 }
222 return MultilibPath;
223}
224
225void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
226 const ArgList &Args) {
227 DetectedMultilibs Result;
228 // Look for a multilib.yaml before trying target-specific hardwired logic.
229 // If it exists, always do what it specifies.
230 std::optional<llvm::SmallString<128>> MultilibPath =
231 getMultilibConfigPath(D, Triple, Args);
232 if (!MultilibPath)
233 return;
234 if (D.getVFS().exists(Path: *MultilibPath)) {
235 // If multilib.yaml is found, update sysroot so it doesn't use a target
236 // specific suffix
237 SysRoot = computeBaseSysRoot(D, /*IncludeTriple=*/false);
238 SmallVector<StringRef> CustomFlagMacroDefines;
239 findMultilibsFromYAML(TC: *this, D, MultilibPath: *MultilibPath, Args, Result,
240 CustomFlagsMacroDefines&: CustomFlagMacroDefines);
241 SelectedMultilibs = Result.SelectedMultilibs;
242 Multilibs = Result.Multilibs;
243 MultilibMacroDefines.append(in_start: CustomFlagMacroDefines.begin(),
244 in_end: CustomFlagMacroDefines.end());
245 } else if (isRISCVBareMetal(Triple)) {
246 if (findRISCVMultilibs(D, TargetTriple: Triple, Args, Result)) {
247 SelectedMultilibs = Result.SelectedMultilibs;
248 Multilibs = Result.Multilibs;
249 }
250 }
251}
252
253bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
254 return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) ||
255 isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
256}
257
258Tool *BareMetal::buildLinker() const {
259 return new tools::baremetal::Linker(*this);
260}
261
262Tool *BareMetal::buildStaticLibTool() const {
263 return new tools::baremetal::StaticLibTool(*this);
264}
265
266std::string BareMetal::computeSysRoot() const { return SysRoot; }
267
268BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
269 // Get multilibs in reverse order because they're ordered most-specific last.
270 if (!SelectedMultilibs.empty())
271 return llvm::reverse(C: SelectedMultilibs);
272
273 // No multilibs selected so return a single default multilib.
274 static const llvm::SmallVector<Multilib> Default = {Multilib()};
275 return llvm::reverse(C: Default);
276}
277
278void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
279 ArgStringList &CC1Args) const {
280 if (DriverArgs.hasArg(options::OPT_nostdinc))
281 return;
282
283 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
284 SmallString<128> Dir(getDriver().ResourceDir);
285 llvm::sys::path::append(path&: Dir, a: "include");
286 addSystemInclude(DriverArgs, CC1Args, Path: Dir.str());
287 }
288
289 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
290 return;
291
292 if (std::optional<std::string> Path = getStdlibIncludePath())
293 addSystemInclude(DriverArgs, CC1Args, Path: *Path);
294
295 const SmallString<128> SysRoot(computeSysRoot());
296 if (!SysRoot.empty()) {
297 for (const Multilib &M : getOrderedMultilibs()) {
298 SmallString<128> Dir(SysRoot);
299 llvm::sys::path::append(path&: Dir, a: M.includeSuffix());
300 llvm::sys::path::append(path&: Dir, a: "include");
301 addSystemInclude(DriverArgs, CC1Args, Path: Dir.str());
302 }
303 }
304}
305
306void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
307 ArgStringList &CC1Args,
308 Action::OffloadKind) const {
309 CC1Args.push_back(Elt: "-nostdsysteminc");
310}
311
312void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
313 ArgStringList &CC1Args) const {
314 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
315 options::OPT_nostdincxx))
316 return;
317
318 const Driver &D = getDriver();
319 std::string Target = getTripleString();
320
321 auto AddCXXIncludePath = [&](StringRef Path) {
322 std::string Version = detectLibcxxVersion(IncludePath: Path);
323 if (Version.empty())
324 return;
325
326 {
327 // First the per-target include dir: include/<target>/c++/v1.
328 SmallString<128> TargetDir(Path);
329 llvm::sys::path::append(path&: TargetDir, a: Target, b: "c++", c: Version);
330 addSystemInclude(DriverArgs, CC1Args, Path: TargetDir);
331 }
332
333 {
334 // Then the generic dir: include/c++/v1.
335 SmallString<128> Dir(Path);
336 llvm::sys::path::append(path&: Dir, a: "c++", b: Version);
337 addSystemInclude(DriverArgs, CC1Args, Path: Dir);
338 }
339 };
340
341 switch (GetCXXStdlibType(Args: DriverArgs)) {
342 case ToolChain::CST_Libcxx: {
343 SmallString<128> P(D.Dir);
344 llvm::sys::path::append(path&: P, a: "..", b: "include");
345 AddCXXIncludePath(P);
346 break;
347 }
348 case ToolChain::CST_Libstdcxx:
349 // We only support libc++ toolchain installation.
350 break;
351 }
352
353 std::string SysRoot(computeSysRoot());
354 if (SysRoot.empty())
355 return;
356
357 for (const Multilib &M : getOrderedMultilibs()) {
358 SmallString<128> Dir(SysRoot);
359 llvm::sys::path::append(path&: Dir, a: M.gccSuffix());
360 switch (GetCXXStdlibType(Args: DriverArgs)) {
361 case ToolChain::CST_Libcxx: {
362 // First check sysroot/usr/include/c++/v1 if it exists.
363 SmallString<128> TargetDir(Dir);
364 llvm::sys::path::append(path&: TargetDir, a: "usr", b: "include", c: "c++", d: "v1");
365 if (D.getVFS().exists(Path: TargetDir)) {
366 addSystemInclude(DriverArgs, CC1Args, Path: TargetDir.str());
367 break;
368 }
369 // Add generic path if nothing else succeeded so far.
370 llvm::sys::path::append(path&: Dir, a: "include", b: "c++", c: "v1");
371 addSystemInclude(DriverArgs, CC1Args, Path: Dir.str());
372 break;
373 }
374 case ToolChain::CST_Libstdcxx: {
375 llvm::sys::path::append(path&: Dir, a: "include", b: "c++");
376 std::error_code EC;
377 Generic_GCC::GCCVersion Version = {.Text: "", .Major: -1, .Minor: -1, .Patch: -1, .MajorStr: "", .MinorStr: "", .PatchSuffix: ""};
378 // Walk the subdirs, and find the one with the newest gcc version:
379 for (llvm::vfs::directory_iterator
380 LI = D.getVFS().dir_begin(Dir: Dir.str(), EC),
381 LE;
382 !EC && LI != LE; LI = LI.increment(EC)) {
383 StringRef VersionText = llvm::sys::path::filename(path: LI->path());
384 auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText);
385 if (CandidateVersion.Major == -1)
386 continue;
387 if (CandidateVersion <= Version)
388 continue;
389 Version = CandidateVersion;
390 }
391 if (Version.Major != -1) {
392 llvm::sys::path::append(path&: Dir, a: Version.Text);
393 addSystemInclude(DriverArgs, CC1Args, Path: Dir.str());
394 }
395 break;
396 }
397 }
398 }
399}
400
401void baremetal::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA,
402 const InputInfo &Output,
403 const InputInfoList &Inputs,
404 const ArgList &Args,
405 const char *LinkingOutput) const {
406 const Driver &D = getToolChain().getDriver();
407
408 // Silence warning for "clang -g foo.o -o foo"
409 Args.ClaimAllArgs(options::OPT_g_Group);
410 // and "clang -emit-llvm foo.o -o foo"
411 Args.ClaimAllArgs(options::OPT_emit_llvm);
412 // and for "clang -w foo.o -o foo". Other warning options are already
413 // handled somewhere else.
414 Args.ClaimAllArgs(options::OPT_w);
415 // Silence warnings when linking C code with a C++ '-stdlib' argument.
416 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
417
418 // ar tool command "llvm-ar <options> <output_file> <input_files>".
419 ArgStringList CmdArgs;
420 // Create and insert file members with a deterministic index.
421 CmdArgs.push_back(Elt: "rcsD");
422 CmdArgs.push_back(Elt: Output.getFilename());
423
424 for (const auto &II : Inputs) {
425 if (II.isFilename()) {
426 CmdArgs.push_back(Elt: II.getFilename());
427 }
428 }
429
430 // Delete old output archive file if it already exists before generating a new
431 // archive file.
432 const char *OutputFileName = Output.getFilename();
433 if (Output.isFilename() && llvm::sys::fs::exists(Path: OutputFileName)) {
434 if (std::error_code EC = llvm::sys::fs::remove(path: OutputFileName)) {
435 D.Diag(diag::DiagID: err_drv_unable_to_remove_file) << EC.message();
436 return;
437 }
438 }
439
440 const char *Exec = Args.MakeArgString(Str: getToolChain().GetStaticLibToolPath());
441 C.addCommand(C: std::make_unique<Command>(args: JA, args: *this,
442 args: ResponseFileSupport::AtFileCurCP(),
443 args&: Exec, args&: CmdArgs, args: Inputs, args: Output));
444}
445
446void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
447 const InputInfo &Output,
448 const InputInfoList &Inputs,
449 const ArgList &Args,
450 const char *LinkingOutput) const {
451 ArgStringList CmdArgs;
452
453 auto &TC = static_cast<const toolchains::BareMetal &>(getToolChain());
454 const Driver &D = getToolChain().getDriver();
455 const llvm::Triple::ArchType Arch = TC.getArch();
456 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
457
458 AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
459
460 CmdArgs.push_back(Elt: "-Bstatic");
461
462 if (TC.getTriple().isRISCV() && Args.hasArg(options::OPT_mno_relax))
463 CmdArgs.push_back(Elt: "--no-relax");
464
465 if (Triple.isARM() || Triple.isThumb()) {
466 bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
467 if (IsBigEndian)
468 arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
469 CmdArgs.push_back(Elt: IsBigEndian ? "-EB" : "-EL");
470 } else if (Triple.isAArch64()) {
471 CmdArgs.push_back(Elt: Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
472 }
473
474 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
475 options::OPT_r)) {
476 CmdArgs.push_back(Elt: Args.MakeArgString(Str: TC.GetFilePath(Name: "crt0.o")));
477 }
478
479 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
480 options::OPT_s, options::OPT_t, options::OPT_r});
481
482 TC.AddFilePathLibArgs(Args, CmdArgs);
483
484 for (const auto &LibPath : TC.getLibraryPaths())
485 CmdArgs.push_back(Elt: Args.MakeArgString(Str: llvm::Twine("-L", LibPath)));
486
487 if (TC.ShouldLinkCXXStdlib(Args)) {
488 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
489 !Args.hasArg(options::OPT_static);
490 if (OnlyLibstdcxxStatic)
491 CmdArgs.push_back(Elt: "-Bstatic");
492 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
493 if (OnlyLibstdcxxStatic)
494 CmdArgs.push_back(Elt: "-Bdynamic");
495 CmdArgs.push_back(Elt: "-lm");
496 }
497
498 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
499 AddRunTimeLibs(TC, D, CmdArgs, Args);
500
501 CmdArgs.push_back(Elt: "-lc");
502 }
503
504 if (D.isUsingLTO())
505 addLTOOptions(ToolChain: TC, Args, CmdArgs, Output, Inputs,
506 IsThinLTO: D.getLTOMode() == LTOK_Thin);
507
508 if (TC.getTriple().isRISCV())
509 CmdArgs.push_back(Elt: "-X");
510
511 // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
512 // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
513 // arm*-*-*bsd).
514 if (arm::isARMEABIBareMetal(Triple: TC.getTriple()))
515 CmdArgs.push_back(Elt: "--target2=rel");
516
517 CmdArgs.push_back(Elt: "-o");
518 CmdArgs.push_back(Elt: Output.getFilename());
519
520 C.addCommand(C: std::make_unique<Command>(
521 args: JA, args: *this, args: ResponseFileSupport::AtFileCurCP(),
522 args: Args.MakeArgString(Str: TC.GetLinkerPath()), args&: CmdArgs, args: Inputs, args: Output));
523}
524
525// BareMetal toolchain allows all sanitizers where the compiler generates valid
526// code, ignoring all runtime library support issues on the assumption that
527// baremetal targets typically implement their own runtime support.
528SanitizerMask BareMetal::getSupportedSanitizers() const {
529 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
530 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
531 getTriple().getArch() == llvm::Triple::aarch64_be;
532 const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
533 SanitizerMask Res = ToolChain::getSupportedSanitizers();
534 Res |= SanitizerKind::Address;
535 Res |= SanitizerKind::KernelAddress;
536 Res |= SanitizerKind::PointerCompare;
537 Res |= SanitizerKind::PointerSubtract;
538 Res |= SanitizerKind::Fuzzer;
539 Res |= SanitizerKind::FuzzerNoLink;
540 Res |= SanitizerKind::Vptr;
541 Res |= SanitizerKind::SafeStack;
542 Res |= SanitizerKind::Thread;
543 Res |= SanitizerKind::Scudo;
544 if (IsX86_64 || IsAArch64 || IsRISCV64) {
545 Res |= SanitizerKind::HWAddress;
546 Res |= SanitizerKind::KernelHWAddress;
547 }
548 return Res;
549}
550
551SmallVector<std::string>
552BareMetal::getMultilibMacroDefinesStr(llvm::opt::ArgList &Args) const {
553 return MultilibMacroDefines;
554}
555

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Driver/ToolChains/BareMetal.cpp