| 1 | //===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- 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 "NetBSD.h" |
| 10 | #include "Arch/ARM.h" |
| 11 | #include "Arch/Mips.h" |
| 12 | #include "Arch/Sparc.h" |
| 13 | #include "clang/Config/config.h" |
| 14 | #include "clang/Driver/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 | #include "llvm/Support/VirtualFileSystem.h" |
| 21 | |
| 22 | using namespace clang::driver; |
| 23 | using namespace clang::driver::tools; |
| 24 | using namespace clang::driver::toolchains; |
| 25 | using namespace clang; |
| 26 | using namespace llvm::opt; |
| 27 | |
| 28 | void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
| 29 | const InputInfo &Output, |
| 30 | const InputInfoList &Inputs, |
| 31 | const ArgList &Args, |
| 32 | const char *LinkingOutput) const { |
| 33 | const auto &ToolChain = static_cast<const NetBSD &>(getToolChain()); |
| 34 | const Driver &D = ToolChain.getDriver(); |
| 35 | const llvm::Triple &Triple = ToolChain.getTriple(); |
| 36 | ArgStringList CmdArgs; |
| 37 | |
| 38 | claimNoWarnArgs(Args); |
| 39 | |
| 40 | // GNU as needs different flags for creating the correct output format |
| 41 | // on architectures with different ABIs or optional feature sets. |
| 42 | switch (ToolChain.getArch()) { |
| 43 | case llvm::Triple::x86: |
| 44 | CmdArgs.push_back(Elt: "--32" ); |
| 45 | break; |
| 46 | case llvm::Triple::arm: |
| 47 | case llvm::Triple::armeb: |
| 48 | case llvm::Triple::thumb: |
| 49 | case llvm::Triple::thumbeb: { |
| 50 | StringRef MArch, MCPU; |
| 51 | arm::getARMArchCPUFromArgs(Args, Arch&: MArch, CPU&: MCPU, /*FromAs*/ true); |
| 52 | std::string Arch = arm::getARMTargetCPU(CPU: MCPU, Arch: MArch, Triple); |
| 53 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-mcpu=" + Arch)); |
| 54 | break; |
| 55 | } |
| 56 | |
| 57 | case llvm::Triple::mips: |
| 58 | case llvm::Triple::mipsel: |
| 59 | case llvm::Triple::mips64: |
| 60 | case llvm::Triple::mips64el: { |
| 61 | StringRef CPUName; |
| 62 | StringRef ABIName; |
| 63 | mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); |
| 64 | |
| 65 | CmdArgs.push_back(Elt: "-march" ); |
| 66 | CmdArgs.push_back(Elt: CPUName.data()); |
| 67 | |
| 68 | CmdArgs.push_back(Elt: "-mabi" ); |
| 69 | CmdArgs.push_back(Elt: mips::getGnuCompatibleMipsABIName(ABI: ABIName).data()); |
| 70 | |
| 71 | if (Triple.isLittleEndian()) |
| 72 | CmdArgs.push_back(Elt: "-EL" ); |
| 73 | else |
| 74 | CmdArgs.push_back(Elt: "-EB" ); |
| 75 | |
| 76 | AddAssemblerKPIC(ToolChain, Args, CmdArgs); |
| 77 | break; |
| 78 | } |
| 79 | |
| 80 | case llvm::Triple::sparc: { |
| 81 | CmdArgs.push_back(Elt: "-32" ); |
| 82 | std::string CPU = getCPUName(D, Args, T: Triple); |
| 83 | CmdArgs.push_back(Elt: sparc::getSparcAsmModeForCPU(Name: CPU, Triple)); |
| 84 | AddAssemblerKPIC(ToolChain, Args, CmdArgs); |
| 85 | break; |
| 86 | } |
| 87 | |
| 88 | case llvm::Triple::sparcv9: { |
| 89 | CmdArgs.push_back(Elt: "-64" ); |
| 90 | std::string CPU = getCPUName(D, Args, T: Triple); |
| 91 | CmdArgs.push_back(Elt: sparc::getSparcAsmModeForCPU(Name: CPU, Triple)); |
| 92 | AddAssemblerKPIC(ToolChain, Args, CmdArgs); |
| 93 | break; |
| 94 | } |
| 95 | |
| 96 | default: |
| 97 | break; |
| 98 | } |
| 99 | |
| 100 | Args.AddAllArgValues(Output&: CmdArgs, Id0: options::OPT_Wa_COMMA, Id1: options::OPT_Xassembler); |
| 101 | |
| 102 | CmdArgs.push_back(Elt: "-o" ); |
| 103 | CmdArgs.push_back(Elt: Output.getFilename()); |
| 104 | |
| 105 | for (const auto &II : Inputs) |
| 106 | CmdArgs.push_back(Elt: II.getFilename()); |
| 107 | |
| 108 | const char *Exec = Args.MakeArgString(Str: (ToolChain.GetProgramPath(Name: "as" ))); |
| 109 | C.addCommand(C: std::make_unique<Command>(args: JA, args: *this, |
| 110 | args: ResponseFileSupport::AtFileCurCP(), |
| 111 | args&: Exec, args&: CmdArgs, args: Inputs, args: Output)); |
| 112 | } |
| 113 | |
| 114 | void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
| 115 | const InputInfo &Output, |
| 116 | const InputInfoList &Inputs, |
| 117 | const ArgList &Args, |
| 118 | const char *LinkingOutput) const { |
| 119 | const auto &ToolChain = static_cast<const NetBSD &>(getToolChain()); |
| 120 | const Driver &D = ToolChain.getDriver(); |
| 121 | const llvm::Triple &Triple = ToolChain.getTriple(); |
| 122 | const llvm::Triple::ArchType Arch = ToolChain.getArch(); |
| 123 | const bool Static = Args.hasArg(Ids: options::OPT_static); |
| 124 | const bool Shared = Args.hasArg(Ids: options::OPT_shared); |
| 125 | const bool Pie = Args.hasArg(Ids: options::OPT_pie); |
| 126 | ArgStringList CmdArgs; |
| 127 | |
| 128 | if (!D.SysRoot.empty()) |
| 129 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: "--sysroot=" + D.SysRoot)); |
| 130 | |
| 131 | CmdArgs.push_back(Elt: "--eh-frame-hdr" ); |
| 132 | if (Static) { |
| 133 | CmdArgs.push_back(Elt: "-Bstatic" ); |
| 134 | if (Pie) { |
| 135 | Args.AddAllArgs(Output&: CmdArgs, Id0: options::OPT_pie); |
| 136 | CmdArgs.push_back(Elt: "--no-dynamic-linker" ); |
| 137 | } |
| 138 | } else { |
| 139 | if (Args.hasArg(Ids: options::OPT_rdynamic)) |
| 140 | CmdArgs.push_back(Elt: "-export-dynamic" ); |
| 141 | if (Shared) { |
| 142 | CmdArgs.push_back(Elt: "-shared" ); |
| 143 | } else if (!Args.hasArg(Ids: options::OPT_r)) { |
| 144 | Args.AddAllArgs(Output&: CmdArgs, Id0: options::OPT_pie); |
| 145 | CmdArgs.push_back(Elt: "-dynamic-linker" ); |
| 146 | CmdArgs.push_back(Elt: "/libexec/ld.elf_so" ); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // Many NetBSD architectures support more than one ABI. |
| 151 | // Determine the correct emulation for ld. |
| 152 | switch (Arch) { |
| 153 | case llvm::Triple::x86: |
| 154 | CmdArgs.push_back(Elt: "-m" ); |
| 155 | CmdArgs.push_back(Elt: "elf_i386" ); |
| 156 | break; |
| 157 | case llvm::Triple::arm: |
| 158 | case llvm::Triple::thumb: |
| 159 | CmdArgs.push_back(Elt: "-m" ); |
| 160 | switch (Triple.getEnvironment()) { |
| 161 | case llvm::Triple::EABI: |
| 162 | case llvm::Triple::GNUEABI: |
| 163 | CmdArgs.push_back(Elt: "armelf_nbsd_eabi" ); |
| 164 | break; |
| 165 | case llvm::Triple::EABIHF: |
| 166 | case llvm::Triple::GNUEABIHF: |
| 167 | CmdArgs.push_back(Elt: "armelf_nbsd_eabihf" ); |
| 168 | break; |
| 169 | default: |
| 170 | CmdArgs.push_back(Elt: "armelf_nbsd" ); |
| 171 | break; |
| 172 | } |
| 173 | break; |
| 174 | case llvm::Triple::armeb: |
| 175 | case llvm::Triple::thumbeb: |
| 176 | arm::appendBE8LinkFlag(Args, CmdArgs, Triple: ToolChain.getEffectiveTriple()); |
| 177 | CmdArgs.push_back(Elt: "-m" ); |
| 178 | switch (Triple.getEnvironment()) { |
| 179 | case llvm::Triple::EABI: |
| 180 | case llvm::Triple::GNUEABI: |
| 181 | CmdArgs.push_back(Elt: "armelfb_nbsd_eabi" ); |
| 182 | break; |
| 183 | case llvm::Triple::EABIHF: |
| 184 | case llvm::Triple::GNUEABIHF: |
| 185 | CmdArgs.push_back(Elt: "armelfb_nbsd_eabihf" ); |
| 186 | break; |
| 187 | default: |
| 188 | CmdArgs.push_back(Elt: "armelfb_nbsd" ); |
| 189 | break; |
| 190 | } |
| 191 | break; |
| 192 | case llvm::Triple::mips64: |
| 193 | case llvm::Triple::mips64el: |
| 194 | if (mips::hasMipsAbiArg(Args, Value: "32" )) { |
| 195 | CmdArgs.push_back(Elt: "-m" ); |
| 196 | if (Arch == llvm::Triple::mips64) |
| 197 | CmdArgs.push_back(Elt: "elf32btsmip" ); |
| 198 | else |
| 199 | CmdArgs.push_back(Elt: "elf32ltsmip" ); |
| 200 | } else if (mips::hasMipsAbiArg(Args, Value: "64" )) { |
| 201 | CmdArgs.push_back(Elt: "-m" ); |
| 202 | if (Arch == llvm::Triple::mips64) |
| 203 | CmdArgs.push_back(Elt: "elf64btsmip" ); |
| 204 | else |
| 205 | CmdArgs.push_back(Elt: "elf64ltsmip" ); |
| 206 | } |
| 207 | break; |
| 208 | case llvm::Triple::ppc: |
| 209 | CmdArgs.push_back(Elt: "-m" ); |
| 210 | CmdArgs.push_back(Elt: "elf32ppc_nbsd" ); |
| 211 | break; |
| 212 | |
| 213 | case llvm::Triple::ppc64: |
| 214 | case llvm::Triple::ppc64le: |
| 215 | CmdArgs.push_back(Elt: "-m" ); |
| 216 | CmdArgs.push_back(Elt: "elf64ppc" ); |
| 217 | break; |
| 218 | |
| 219 | case llvm::Triple::riscv32: |
| 220 | CmdArgs.push_back(Elt: "-m" ); |
| 221 | CmdArgs.push_back(Elt: "elf32lriscv" ); |
| 222 | break; |
| 223 | |
| 224 | case llvm::Triple::riscv64: |
| 225 | CmdArgs.push_back(Elt: "-m" ); |
| 226 | CmdArgs.push_back(Elt: "elf64lriscv" ); |
| 227 | break; |
| 228 | |
| 229 | case llvm::Triple::sparc: |
| 230 | CmdArgs.push_back(Elt: "-m" ); |
| 231 | CmdArgs.push_back(Elt: "elf32_sparc" ); |
| 232 | break; |
| 233 | |
| 234 | case llvm::Triple::sparcv9: |
| 235 | CmdArgs.push_back(Elt: "-m" ); |
| 236 | CmdArgs.push_back(Elt: "elf64_sparc" ); |
| 237 | break; |
| 238 | |
| 239 | default: |
| 240 | break; |
| 241 | } |
| 242 | |
| 243 | if (Triple.isRISCV()) { |
| 244 | CmdArgs.push_back(Elt: "-X" ); |
| 245 | if (Args.hasArg(Ids: options::OPT_mno_relax)) |
| 246 | CmdArgs.push_back(Elt: "--no-relax" ); |
| 247 | } |
| 248 | |
| 249 | assert((Output.isFilename() || Output.isNothing()) && "Invalid output." ); |
| 250 | if (Output.isFilename()) { |
| 251 | CmdArgs.push_back(Elt: "-o" ); |
| 252 | CmdArgs.push_back(Elt: Output.getFilename()); |
| 253 | } |
| 254 | |
| 255 | if (!Args.hasArg(Ids: options::OPT_nostdlib, Ids: options::OPT_nostartfiles, |
| 256 | Ids: options::OPT_r)) { |
| 257 | const char *crt0 = nullptr; |
| 258 | const char *crtbegin = nullptr; |
| 259 | if (!Shared) |
| 260 | crt0 = "crt0.o" ; |
| 261 | |
| 262 | if (Shared || Pie) |
| 263 | crtbegin = "crtbeginS.o" ; |
| 264 | else |
| 265 | crtbegin = "crtbegin.o" ; |
| 266 | |
| 267 | if (crt0) |
| 268 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: crt0))); |
| 269 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crti.o" ))); |
| 270 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: crtbegin))); |
| 271 | } |
| 272 | |
| 273 | Args.addAllArgs(Output&: CmdArgs, Ids: {options::OPT_L, options::OPT_T_Group, |
| 274 | options::OPT_s, options::OPT_t}); |
| 275 | ToolChain.AddFilePathLibArgs(Args, CmdArgs); |
| 276 | |
| 277 | bool NeedsSanitizerDeps = addSanitizerRuntimes(TC: ToolChain, Args, CmdArgs); |
| 278 | bool NeedsXRayDeps = addXRayRuntime(TC: ToolChain, Args, CmdArgs); |
| 279 | AddLinkerInputs(TC: ToolChain, Inputs, Args, CmdArgs, JA); |
| 280 | |
| 281 | const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(JobArgs: Args); |
| 282 | if (SanArgs.needsSharedRt()) { |
| 283 | CmdArgs.push_back(Elt: "-rpath" ); |
| 284 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.getCompilerRTPath())); |
| 285 | } |
| 286 | |
| 287 | bool useLibgcc = true; |
| 288 | switch (ToolChain.getArch()) { |
| 289 | case llvm::Triple::aarch64: |
| 290 | case llvm::Triple::aarch64_be: |
| 291 | case llvm::Triple::arm: |
| 292 | case llvm::Triple::armeb: |
| 293 | case llvm::Triple::thumb: |
| 294 | case llvm::Triple::thumbeb: |
| 295 | case llvm::Triple::ppc: |
| 296 | case llvm::Triple::ppc64: |
| 297 | case llvm::Triple::ppc64le: |
| 298 | case llvm::Triple::riscv32: |
| 299 | case llvm::Triple::riscv64: |
| 300 | case llvm::Triple::sparc: |
| 301 | case llvm::Triple::sparcv9: |
| 302 | case llvm::Triple::x86: |
| 303 | case llvm::Triple::x86_64: |
| 304 | useLibgcc = false; |
| 305 | break; |
| 306 | default: |
| 307 | break; |
| 308 | } |
| 309 | |
| 310 | if (!Args.hasArg(Ids: options::OPT_nostdlib, Ids: options::OPT_nodefaultlibs, |
| 311 | Ids: options::OPT_r)) { |
| 312 | // Use the static OpenMP runtime with -static-openmp |
| 313 | bool StaticOpenMP = Args.hasArg(Ids: options::OPT_static_openmp) && !Static; |
| 314 | addOpenMPRuntime(C, CmdArgs, TC: ToolChain, Args, ForceStaticHostRuntime: StaticOpenMP); |
| 315 | |
| 316 | if (D.CCCIsCXX()) { |
| 317 | if (ToolChain.ShouldLinkCXXStdlib(Args)) |
| 318 | ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); |
| 319 | CmdArgs.push_back(Elt: "-lm" ); |
| 320 | } |
| 321 | |
| 322 | // Silence warnings when linking C code with a C++ '-stdlib' argument. |
| 323 | Args.ClaimAllArgs(Id0: options::OPT_stdlib_EQ); |
| 324 | |
| 325 | // Additional linker set-up and flags for Fortran. This is required in order |
| 326 | // to generate executables. As Fortran runtime depends on the C runtime, |
| 327 | // these dependencies need to be listed before the C runtime below (i.e. |
| 328 | // AddRunTimeLibs). |
| 329 | if (D.IsFlangMode() && |
| 330 | !Args.hasArg(Ids: options::OPT_nostdlib, Ids: options::OPT_nodefaultlibs)) { |
| 331 | ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs); |
| 332 | ToolChain.addFortranRuntimeLibs(Args, CmdArgs); |
| 333 | CmdArgs.push_back(Elt: "-lm" ); |
| 334 | } |
| 335 | |
| 336 | if (NeedsSanitizerDeps) |
| 337 | linkSanitizerRuntimeDeps(TC: ToolChain, Args, CmdArgs); |
| 338 | if (NeedsXRayDeps) |
| 339 | linkXRayRuntimeDeps(TC: ToolChain, Args, CmdArgs); |
| 340 | if (Args.hasArg(Ids: options::OPT_pthread)) |
| 341 | CmdArgs.push_back(Elt: "-lpthread" ); |
| 342 | CmdArgs.push_back(Elt: "-lc" ); |
| 343 | |
| 344 | if (useLibgcc) { |
| 345 | if (Static) { |
| 346 | // libgcc_eh depends on libc, so resolve as much as possible, |
| 347 | // pull in any new requirements from libc and then get the rest |
| 348 | // of libgcc. |
| 349 | CmdArgs.push_back(Elt: "-lgcc_eh" ); |
| 350 | CmdArgs.push_back(Elt: "-lc" ); |
| 351 | CmdArgs.push_back(Elt: "-lgcc" ); |
| 352 | } else { |
| 353 | CmdArgs.push_back(Elt: "-lgcc" ); |
| 354 | CmdArgs.push_back(Elt: "--as-needed" ); |
| 355 | CmdArgs.push_back(Elt: "-lgcc_s" ); |
| 356 | CmdArgs.push_back(Elt: "--no-as-needed" ); |
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | if (!Args.hasArg(Ids: options::OPT_nostdlib, Ids: options::OPT_nostartfiles, |
| 362 | Ids: options::OPT_r)) { |
| 363 | const char *crtend = nullptr; |
| 364 | if (Shared || Pie) |
| 365 | crtend = "crtendS.o" ; |
| 366 | else |
| 367 | crtend = "crtend.o" ; |
| 368 | |
| 369 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: crtend))); |
| 370 | CmdArgs.push_back(Elt: Args.MakeArgString(Str: ToolChain.GetFilePath(Name: "crtn.o" ))); |
| 371 | } |
| 372 | |
| 373 | ToolChain.addProfileRTLibs(Args, CmdArgs); |
| 374 | |
| 375 | const char *Exec = Args.MakeArgString(Str: ToolChain.GetLinkerPath()); |
| 376 | C.addCommand(C: std::make_unique<Command>(args: JA, args: *this, |
| 377 | args: ResponseFileSupport::AtFileCurCP(), |
| 378 | args&: Exec, args&: CmdArgs, args: Inputs, args: Output)); |
| 379 | } |
| 380 | |
| 381 | /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. |
| 382 | |
| 383 | NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
| 384 | : Generic_ELF(D, Triple, Args) { |
| 385 | if (!Args.hasArg(Ids: options::OPT_nostdlib)) { |
| 386 | // When targeting a 32-bit platform, try the special directory used on |
| 387 | // 64-bit hosts, and only fall back to the main library directory if that |
| 388 | // doesn't work. |
| 389 | // FIXME: It'd be nicer to test if this directory exists, but I'm not sure |
| 390 | // what all logic is needed to emulate the '=' prefix here. |
| 391 | switch (Triple.getArch()) { |
| 392 | case llvm::Triple::x86: |
| 393 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/i386" )); |
| 394 | break; |
| 395 | case llvm::Triple::arm: |
| 396 | case llvm::Triple::armeb: |
| 397 | case llvm::Triple::thumb: |
| 398 | case llvm::Triple::thumbeb: |
| 399 | switch (Triple.getEnvironment()) { |
| 400 | case llvm::Triple::EABI: |
| 401 | case llvm::Triple::GNUEABI: |
| 402 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/eabi" )); |
| 403 | break; |
| 404 | case llvm::Triple::EABIHF: |
| 405 | case llvm::Triple::GNUEABIHF: |
| 406 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/eabihf" )); |
| 407 | break; |
| 408 | default: |
| 409 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/oabi" )); |
| 410 | break; |
| 411 | } |
| 412 | break; |
| 413 | case llvm::Triple::mips64: |
| 414 | case llvm::Triple::mips64el: |
| 415 | if (tools::mips::hasMipsAbiArg(Args, Value: "o32" )) |
| 416 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/o32" )); |
| 417 | else if (tools::mips::hasMipsAbiArg(Args, Value: "64" )) |
| 418 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/64" )); |
| 419 | break; |
| 420 | case llvm::Triple::ppc: |
| 421 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/powerpc" )); |
| 422 | break; |
| 423 | case llvm::Triple::sparc: |
| 424 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib/sparc" )); |
| 425 | break; |
| 426 | default: |
| 427 | break; |
| 428 | } |
| 429 | |
| 430 | getFilePaths().push_back(Elt: concat(Path: getDriver().SysRoot, A: "/usr/lib" )); |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | Tool *NetBSD::buildAssembler() const { |
| 435 | return new tools::netbsd::Assembler(*this); |
| 436 | } |
| 437 | |
| 438 | Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); } |
| 439 | |
| 440 | ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const { |
| 441 | switch (getArch()) { |
| 442 | case llvm::Triple::aarch64: |
| 443 | case llvm::Triple::aarch64_be: |
| 444 | case llvm::Triple::arm: |
| 445 | case llvm::Triple::armeb: |
| 446 | case llvm::Triple::thumb: |
| 447 | case llvm::Triple::thumbeb: |
| 448 | case llvm::Triple::ppc: |
| 449 | case llvm::Triple::ppc64: |
| 450 | case llvm::Triple::ppc64le: |
| 451 | case llvm::Triple::riscv32: |
| 452 | case llvm::Triple::riscv64: |
| 453 | case llvm::Triple::sparc: |
| 454 | case llvm::Triple::sparcv9: |
| 455 | case llvm::Triple::x86: |
| 456 | case llvm::Triple::x86_64: |
| 457 | return ToolChain::CST_Libcxx; |
| 458 | default: |
| 459 | break; |
| 460 | } |
| 461 | return ToolChain::CST_Libstdcxx; |
| 462 | } |
| 463 | |
| 464 | void NetBSD::AddClangSystemIncludeArgs( |
| 465 | const llvm::opt::ArgList &DriverArgs, |
| 466 | llvm::opt::ArgStringList &CC1Args) const { |
| 467 | const Driver &D = getDriver(); |
| 468 | |
| 469 | if (DriverArgs.hasArg(Ids: clang::driver::options::OPT_nostdinc)) |
| 470 | return; |
| 471 | |
| 472 | if (!DriverArgs.hasArg(Ids: options::OPT_nobuiltininc)) { |
| 473 | SmallString<128> Dir(D.ResourceDir); |
| 474 | llvm::sys::path::append(path&: Dir, a: "include" ); |
| 475 | addSystemInclude(DriverArgs, CC1Args, Path: Dir.str()); |
| 476 | } |
| 477 | |
| 478 | if (DriverArgs.hasArg(Ids: options::OPT_nostdlibinc)) |
| 479 | return; |
| 480 | |
| 481 | // Check for configure-time C include directories. |
| 482 | StringRef CIncludeDirs(C_INCLUDE_DIRS); |
| 483 | if (CIncludeDirs != "" ) { |
| 484 | SmallVector<StringRef, 5> dirs; |
| 485 | CIncludeDirs.split(A&: dirs, Separator: ":" ); |
| 486 | for (StringRef dir : dirs) { |
| 487 | StringRef Prefix = |
| 488 | llvm::sys::path::is_absolute(path: dir) ? StringRef(D.SysRoot) : "" ; |
| 489 | addExternCSystemInclude(DriverArgs, CC1Args, Path: Prefix + dir); |
| 490 | } |
| 491 | return; |
| 492 | } |
| 493 | |
| 494 | addExternCSystemInclude(DriverArgs, CC1Args, |
| 495 | Path: concat(Path: D.SysRoot, A: "/usr/include" )); |
| 496 | } |
| 497 | |
| 498 | void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
| 499 | llvm::opt::ArgStringList &CC1Args) const { |
| 500 | const std::string Candidates[] = { |
| 501 | // directory relative to build tree |
| 502 | concat(Path: getDriver().Dir, A: "/../include/c++/v1" ), |
| 503 | // system install with full upstream path |
| 504 | concat(Path: getDriver().SysRoot, A: "/usr/include/c++/v1" ), |
| 505 | // system install from src |
| 506 | concat(Path: getDriver().SysRoot, A: "/usr/include/c++" ), |
| 507 | }; |
| 508 | |
| 509 | for (const auto &IncludePath : Candidates) { |
| 510 | if (!getVFS().exists(Path: IncludePath + "/__config" )) |
| 511 | continue; |
| 512 | |
| 513 | // Use the first candidate that looks valid. |
| 514 | addSystemInclude(DriverArgs, CC1Args, Path: IncludePath); |
| 515 | return; |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
| 520 | llvm::opt::ArgStringList &CC1Args) const { |
| 521 | addLibStdCXXIncludePaths(IncludeDir: concat(Path: getDriver().SysRoot, A: "/usr/include/g++" ), Triple: "" , IncludeSuffix: "" , |
| 522 | DriverArgs, CC1Args); |
| 523 | } |
| 524 | |
| 525 | llvm::ExceptionHandling NetBSD::GetExceptionModel(const ArgList &Args) const { |
| 526 | // NetBSD uses Dwarf exceptions on ARM. |
| 527 | llvm::Triple::ArchType TArch = getTriple().getArch(); |
| 528 | if (TArch == llvm::Triple::arm || TArch == llvm::Triple::armeb || |
| 529 | TArch == llvm::Triple::thumb || TArch == llvm::Triple::thumbeb) |
| 530 | return llvm::ExceptionHandling::DwarfCFI; |
| 531 | return llvm::ExceptionHandling::None; |
| 532 | } |
| 533 | |
| 534 | SanitizerMask NetBSD::getSupportedSanitizers() const { |
| 535 | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
| 536 | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
| 537 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
| 538 | if (IsX86 || IsX86_64) { |
| 539 | Res |= SanitizerKind::Address; |
| 540 | Res |= SanitizerKind::PointerCompare; |
| 541 | Res |= SanitizerKind::PointerSubtract; |
| 542 | Res |= SanitizerKind::Leak; |
| 543 | Res |= SanitizerKind::SafeStack; |
| 544 | Res |= SanitizerKind::Scudo; |
| 545 | Res |= SanitizerKind::Vptr; |
| 546 | } |
| 547 | if (IsX86_64) { |
| 548 | Res |= SanitizerKind::DataFlow; |
| 549 | Res |= SanitizerKind::Fuzzer; |
| 550 | Res |= SanitizerKind::FuzzerNoLink; |
| 551 | Res |= SanitizerKind::HWAddress; |
| 552 | Res |= SanitizerKind::KernelAddress; |
| 553 | Res |= SanitizerKind::KernelHWAddress; |
| 554 | Res |= SanitizerKind::KernelMemory; |
| 555 | Res |= SanitizerKind::Memory; |
| 556 | Res |= SanitizerKind::Thread; |
| 557 | } |
| 558 | return Res; |
| 559 | } |
| 560 | |
| 561 | void NetBSD::addClangTargetOptions(const ArgList &DriverArgs, |
| 562 | ArgStringList &CC1Args, |
| 563 | Action::OffloadKind) const { |
| 564 | const SanitizerArgs &SanArgs = getSanitizerArgs(JobArgs: DriverArgs); |
| 565 | if (SanArgs.hasAnySanitizer()) |
| 566 | CC1Args.push_back(Elt: "-D_REENTRANT" ); |
| 567 | } |
| 568 | |