10b57cec5SDimitry Andric //===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "OpenBSD.h" 10349cc55cSDimitry Andric #include "Arch/ARM.h" 110b57cec5SDimitry Andric #include "Arch/Mips.h" 120b57cec5SDimitry Andric #include "Arch/Sparc.h" 130b57cec5SDimitry Andric #include "CommonArgs.h" 1416d6b3b3SDimitry Andric #include "clang/Config/config.h" 150b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 160b57cec5SDimitry Andric #include "clang/Driver/Options.h" 170b57cec5SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 180b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 1916d6b3b3SDimitry Andric #include "llvm/Support/Path.h" 2081ad6265SDimitry Andric #include "llvm/Support/VirtualFileSystem.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang::driver; 230b57cec5SDimitry Andric using namespace clang::driver::tools; 240b57cec5SDimitry Andric using namespace clang::driver::toolchains; 250b57cec5SDimitry Andric using namespace clang; 260b57cec5SDimitry Andric using namespace llvm::opt; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 290b57cec5SDimitry Andric const InputInfo &Output, 300b57cec5SDimitry Andric const InputInfoList &Inputs, 310b57cec5SDimitry Andric const ArgList &Args, 320b57cec5SDimitry Andric const char *LinkingOutput) const { 335f757f3fSDimitry Andric const auto &ToolChain = static_cast<const OpenBSD &>(getToolChain()); 34349cc55cSDimitry Andric const Driver &D = ToolChain.getDriver(); 35349cc55cSDimitry Andric const llvm::Triple &Triple = ToolChain.getTriple(); 365f757f3fSDimitry Andric ArgStringList CmdArgs; 37349cc55cSDimitry Andric 380b57cec5SDimitry Andric claimNoWarnArgs(Args); 390b57cec5SDimitry Andric 40349cc55cSDimitry Andric switch (ToolChain.getArch()) { 410b57cec5SDimitry Andric case llvm::Triple::x86: 420b57cec5SDimitry Andric // When building 32-bit code on OpenBSD/amd64, we have to explicitly 430b57cec5SDimitry Andric // instruct as in the base system to assemble 32-bit code. 440b57cec5SDimitry Andric CmdArgs.push_back("--32"); 450b57cec5SDimitry Andric break; 460b57cec5SDimitry Andric 475f757f3fSDimitry Andric case llvm::Triple::arm: { 48349cc55cSDimitry Andric StringRef MArch, MCPU; 49349cc55cSDimitry Andric arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true); 50349cc55cSDimitry Andric std::string Arch = arm::getARMTargetCPU(MCPU, MArch, Triple); 51349cc55cSDimitry Andric CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch)); 52349cc55cSDimitry Andric break; 53349cc55cSDimitry Andric } 54349cc55cSDimitry Andric 550b57cec5SDimitry Andric case llvm::Triple::ppc: 560b57cec5SDimitry Andric CmdArgs.push_back("-mppc"); 570b57cec5SDimitry Andric CmdArgs.push_back("-many"); 580b57cec5SDimitry Andric break; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric case llvm::Triple::sparcv9: { 610b57cec5SDimitry Andric CmdArgs.push_back("-64"); 62349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, Triple); 63349cc55cSDimitry Andric CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, Triple)); 64349cc55cSDimitry Andric AddAssemblerKPIC(ToolChain, Args, CmdArgs); 650b57cec5SDimitry Andric break; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric case llvm::Triple::mips64: 690b57cec5SDimitry Andric case llvm::Triple::mips64el: { 700b57cec5SDimitry Andric StringRef CPUName; 710b57cec5SDimitry Andric StringRef ABIName; 72349cc55cSDimitry Andric mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); 73349cc55cSDimitry Andric 74349cc55cSDimitry Andric CmdArgs.push_back("-march"); 75349cc55cSDimitry Andric CmdArgs.push_back(CPUName.data()); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric CmdArgs.push_back("-mabi"); 780b57cec5SDimitry Andric CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data()); 790b57cec5SDimitry Andric 80349cc55cSDimitry Andric if (Triple.isLittleEndian()) 810b57cec5SDimitry Andric CmdArgs.push_back("-EL"); 820b57cec5SDimitry Andric else 830b57cec5SDimitry Andric CmdArgs.push_back("-EB"); 840b57cec5SDimitry Andric 85349cc55cSDimitry Andric AddAssemblerKPIC(ToolChain, Args, CmdArgs); 860b57cec5SDimitry Andric break; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric default: 900b57cec5SDimitry Andric break; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric CmdArgs.push_back("-o"); 960b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric for (const auto &II : Inputs) 990b57cec5SDimitry Andric CmdArgs.push_back(II.getFilename()); 1000b57cec5SDimitry Andric 101349cc55cSDimitry Andric const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("as")); 102e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 103e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 104e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, 1080b57cec5SDimitry Andric const InputInfo &Output, 1090b57cec5SDimitry Andric const InputInfoList &Inputs, 1100b57cec5SDimitry Andric const ArgList &Args, 1110b57cec5SDimitry Andric const char *LinkingOutput) const { 1125f757f3fSDimitry Andric const auto &ToolChain = static_cast<const OpenBSD &>(getToolChain()); 113349cc55cSDimitry Andric const Driver &D = ToolChain.getDriver(); 114*0fca6ea1SDimitry Andric const llvm::Triple &Triple = ToolChain.getTriple(); 11581ad6265SDimitry Andric const llvm::Triple::ArchType Arch = ToolChain.getArch(); 1165f757f3fSDimitry Andric const bool Static = Args.hasArg(options::OPT_static); 1175f757f3fSDimitry Andric const bool Shared = Args.hasArg(options::OPT_shared); 1185f757f3fSDimitry Andric const bool Profiling = Args.hasArg(options::OPT_pg); 1195f757f3fSDimitry Andric const bool Pie = Args.hasArg(options::OPT_pie); 1205f757f3fSDimitry Andric const bool Nopie = Args.hasArg(options::OPT_no_pie, options::OPT_nopie); 1215f757f3fSDimitry Andric const bool Relocatable = Args.hasArg(options::OPT_r); 1220b57cec5SDimitry Andric ArgStringList CmdArgs; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // Silence warning for "clang -g foo.o -o foo" 1250b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_g_Group); 1260b57cec5SDimitry Andric // and "clang -emit-llvm foo.o -o foo" 1270b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_emit_llvm); 1280b57cec5SDimitry Andric // and for "clang -w foo.o -o foo". Other warning options are already 1290b57cec5SDimitry Andric // handled somewhere else. 1300b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_w); 1310b57cec5SDimitry Andric 13281ad6265SDimitry Andric if (!D.SysRoot.empty()) 13381ad6265SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 13481ad6265SDimitry Andric 13581ad6265SDimitry Andric if (Arch == llvm::Triple::mips64) 1360b57cec5SDimitry Andric CmdArgs.push_back("-EB"); 13781ad6265SDimitry Andric else if (Arch == llvm::Triple::mips64el) 1380b57cec5SDimitry Andric CmdArgs.push_back("-EL"); 1390b57cec5SDimitry Andric 1405f757f3fSDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && !Shared && !Relocatable) { 1410b57cec5SDimitry Andric CmdArgs.push_back("-e"); 1420b57cec5SDimitry Andric CmdArgs.push_back("__start"); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric CmdArgs.push_back("--eh-frame-hdr"); 14606c3fb27SDimitry Andric if (Static) { 1470b57cec5SDimitry Andric CmdArgs.push_back("-Bstatic"); 1480b57cec5SDimitry Andric } else { 1490b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 1500b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 15106c3fb27SDimitry Andric if (Shared) { 1520b57cec5SDimitry Andric CmdArgs.push_back("-shared"); 1535f757f3fSDimitry Andric } else if (!Relocatable) { 1540b57cec5SDimitry Andric CmdArgs.push_back("-dynamic-linker"); 1550b57cec5SDimitry Andric CmdArgs.push_back("/usr/libexec/ld.so"); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 15906c3fb27SDimitry Andric if (Pie) 1600b57cec5SDimitry Andric CmdArgs.push_back("-pie"); 16106c3fb27SDimitry Andric if (Nopie || Profiling) 1620b57cec5SDimitry Andric CmdArgs.push_back("-nopie"); 1630b57cec5SDimitry Andric 164*0fca6ea1SDimitry Andric if (Triple.isRISCV64()) { 16581ad6265SDimitry Andric CmdArgs.push_back("-X"); 166*0fca6ea1SDimitry Andric if (Args.hasArg(options::OPT_mno_relax)) 167*0fca6ea1SDimitry Andric CmdArgs.push_back("--no-relax"); 168*0fca6ea1SDimitry Andric } 16981ad6265SDimitry Andric 1705f757f3fSDimitry Andric assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); 1710b57cec5SDimitry Andric if (Output.isFilename()) { 1720b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1730b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 176d56accc7SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 177d56accc7SDimitry Andric options::OPT_r)) { 1780b57cec5SDimitry Andric const char *crt0 = nullptr; 1790b57cec5SDimitry Andric const char *crtbegin = nullptr; 18006c3fb27SDimitry Andric if (!Shared) { 18106c3fb27SDimitry Andric if (Profiling) 1820b57cec5SDimitry Andric crt0 = "gcrt0.o"; 18306c3fb27SDimitry Andric else if (Static && !Nopie) 1840b57cec5SDimitry Andric crt0 = "rcrt0.o"; 1850b57cec5SDimitry Andric else 1860b57cec5SDimitry Andric crt0 = "crt0.o"; 1870b57cec5SDimitry Andric crtbegin = "crtbegin.o"; 1880b57cec5SDimitry Andric } else { 1890b57cec5SDimitry Andric crtbegin = "crtbeginS.o"; 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric if (crt0) 1930b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt0))); 1940b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L); 1980b57cec5SDimitry Andric ToolChain.AddFilePathLibArgs(Args, CmdArgs); 199*0fca6ea1SDimitry Andric Args.addAllArgs(CmdArgs, 200*0fca6ea1SDimitry Andric {options::OPT_T_Group, options::OPT_s, options::OPT_t}); 2015f757f3fSDimitry Andric 2025f757f3fSDimitry Andric if (D.isUsingLTO()) { 2035f757f3fSDimitry Andric assert(!Inputs.empty() && "Must have at least one input."); 2045f757f3fSDimitry Andric // Find the first filename InputInfo object. 2055f757f3fSDimitry Andric auto Input = llvm::find_if( 2065f757f3fSDimitry Andric Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); }); 2075f757f3fSDimitry Andric if (Input == Inputs.end()) 2085f757f3fSDimitry Andric // For a very rare case, all of the inputs to the linker are 2095f757f3fSDimitry Andric // InputArg. If that happens, just use the first InputInfo. 2105f757f3fSDimitry Andric Input = Inputs.begin(); 2115f757f3fSDimitry Andric 2125f757f3fSDimitry Andric addLTOOptions(ToolChain, Args, CmdArgs, Output, *Input, 2135f757f3fSDimitry Andric D.getLTOMode() == LTOK_Thin); 2145f757f3fSDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); 2170b57cec5SDimitry Andric bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); 2180b57cec5SDimitry Andric AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 2190b57cec5SDimitry Andric 220d56accc7SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 221d56accc7SDimitry Andric options::OPT_r)) { 22269ade1e0SDimitry Andric // Use the static OpenMP runtime with -static-openmp 22306c3fb27SDimitry Andric bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; 224*0fca6ea1SDimitry Andric addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); 22569ade1e0SDimitry Andric 2260b57cec5SDimitry Andric if (D.CCCIsCXX()) { 2270b57cec5SDimitry Andric if (ToolChain.ShouldLinkCXXStdlib(Args)) 2280b57cec5SDimitry Andric ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 22906c3fb27SDimitry Andric if (Profiling) 2300b57cec5SDimitry Andric CmdArgs.push_back("-lm_p"); 2310b57cec5SDimitry Andric else 2320b57cec5SDimitry Andric CmdArgs.push_back("-lm"); 2330b57cec5SDimitry Andric } 2345f757f3fSDimitry Andric 2355f757f3fSDimitry Andric // Silence warnings when linking C code with a C++ '-stdlib' argument. 2365f757f3fSDimitry Andric Args.ClaimAllArgs(options::OPT_stdlib_EQ); 2375f757f3fSDimitry Andric 2385f757f3fSDimitry Andric // Additional linker set-up and flags for Fortran. This is required in order 2395f757f3fSDimitry Andric // to generate executables. As Fortran runtime depends on the C runtime, 2405f757f3fSDimitry Andric // these dependencies need to be listed before the C runtime below (i.e. 2415f757f3fSDimitry Andric // AddRunTimeLibs). 2425f757f3fSDimitry Andric if (D.IsFlangMode()) { 2435f757f3fSDimitry Andric addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); 2445f757f3fSDimitry Andric addFortranRuntimeLibs(ToolChain, Args, CmdArgs); 2455f757f3fSDimitry Andric if (Profiling) 2465f757f3fSDimitry Andric CmdArgs.push_back("-lm_p"); 2475f757f3fSDimitry Andric else 2485f757f3fSDimitry Andric CmdArgs.push_back("-lm"); 2495f757f3fSDimitry Andric } 2505f757f3fSDimitry Andric 2510b57cec5SDimitry Andric if (NeedsSanitizerDeps) { 2520b57cec5SDimitry Andric CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); 2535f757f3fSDimitry Andric linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric if (NeedsXRayDeps) { 2560b57cec5SDimitry Andric CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); 2575f757f3fSDimitry Andric linkXRayRuntimeDeps(ToolChain, Args, CmdArgs); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric // FIXME: For some reason GCC passes -lgcc before adding 2600b57cec5SDimitry Andric // the default system libraries. Just mimic this for now. 2610b57cec5SDimitry Andric CmdArgs.push_back("-lcompiler_rt"); 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) { 26406c3fb27SDimitry Andric if (!Shared && Profiling) 2650b57cec5SDimitry Andric CmdArgs.push_back("-lpthread_p"); 2660b57cec5SDimitry Andric else 2670b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 27006c3fb27SDimitry Andric if (!Shared) { 27106c3fb27SDimitry Andric if (Profiling) 2720b57cec5SDimitry Andric CmdArgs.push_back("-lc_p"); 2730b57cec5SDimitry Andric else 2740b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric CmdArgs.push_back("-lcompiler_rt"); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 280d56accc7SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 281d56accc7SDimitry Andric options::OPT_r)) { 2820b57cec5SDimitry Andric const char *crtend = nullptr; 28306c3fb27SDimitry Andric if (!Shared) 2840b57cec5SDimitry Andric crtend = "crtend.o"; 2850b57cec5SDimitry Andric else 2860b57cec5SDimitry Andric crtend = "crtendS.o"; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 29169ade1e0SDimitry Andric ToolChain.addProfileRTLibs(Args, CmdArgs); 29269ade1e0SDimitry Andric 2930b57cec5SDimitry Andric const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); 294e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 295e8d8bef9SDimitry Andric ResponseFileSupport::AtFileCurCP(), 296e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric SanitizerMask OpenBSD::getSupportedSanitizers() const { 3000b57cec5SDimitry Andric const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; 3010b57cec5SDimitry Andric const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; 3020b57cec5SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 3030b57cec5SDimitry Andric if (IsX86 || IsX86_64) { 3040b57cec5SDimitry Andric Res |= SanitizerKind::Vptr; 3050b57cec5SDimitry Andric Res |= SanitizerKind::Fuzzer; 3060b57cec5SDimitry Andric Res |= SanitizerKind::FuzzerNoLink; 3070b57cec5SDimitry Andric } 3085f757f3fSDimitry Andric if (IsX86_64) { 3095f757f3fSDimitry Andric Res |= SanitizerKind::KernelAddress; 3105f757f3fSDimitry Andric } 3110b57cec5SDimitry Andric return Res; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple, 3170b57cec5SDimitry Andric const ArgList &Args) 3180b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 319fcaf7f86SDimitry Andric getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib")); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 32216d6b3b3SDimitry Andric void OpenBSD::AddClangSystemIncludeArgs( 32316d6b3b3SDimitry Andric const llvm::opt::ArgList &DriverArgs, 32416d6b3b3SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 32516d6b3b3SDimitry Andric const Driver &D = getDriver(); 32616d6b3b3SDimitry Andric 32716d6b3b3SDimitry Andric if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) 32816d6b3b3SDimitry Andric return; 32916d6b3b3SDimitry Andric 33016d6b3b3SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 33116d6b3b3SDimitry Andric SmallString<128> Dir(D.ResourceDir); 33216d6b3b3SDimitry Andric llvm::sys::path::append(Dir, "include"); 33316d6b3b3SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str()); 33416d6b3b3SDimitry Andric } 33516d6b3b3SDimitry Andric 33616d6b3b3SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 33716d6b3b3SDimitry Andric return; 33816d6b3b3SDimitry Andric 33916d6b3b3SDimitry Andric // Check for configure-time C include directories. 34016d6b3b3SDimitry Andric StringRef CIncludeDirs(C_INCLUDE_DIRS); 34116d6b3b3SDimitry Andric if (CIncludeDirs != "") { 34216d6b3b3SDimitry Andric SmallVector<StringRef, 5> dirs; 34316d6b3b3SDimitry Andric CIncludeDirs.split(dirs, ":"); 34416d6b3b3SDimitry Andric for (StringRef dir : dirs) { 34516d6b3b3SDimitry Andric StringRef Prefix = 34616d6b3b3SDimitry Andric llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; 34716d6b3b3SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); 34816d6b3b3SDimitry Andric } 34916d6b3b3SDimitry Andric return; 35016d6b3b3SDimitry Andric } 35116d6b3b3SDimitry Andric 352fcaf7f86SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 353fcaf7f86SDimitry Andric concat(D.SysRoot, "/usr/include")); 35416d6b3b3SDimitry Andric } 35516d6b3b3SDimitry Andric 35616d6b3b3SDimitry Andric void OpenBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 35716d6b3b3SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 35816d6b3b3SDimitry Andric addSystemInclude(DriverArgs, CC1Args, 359fcaf7f86SDimitry Andric concat(getDriver().SysRoot, "/usr/include/c++/v1")); 36016d6b3b3SDimitry Andric } 36116d6b3b3SDimitry Andric 3620b57cec5SDimitry Andric void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args, 3630b57cec5SDimitry Andric ArgStringList &CmdArgs) const { 3640b57cec5SDimitry Andric bool Profiling = Args.hasArg(options::OPT_pg); 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); 367fcaf7f86SDimitry Andric if (Args.hasArg(options::OPT_fexperimental_library)) 368fcaf7f86SDimitry Andric CmdArgs.push_back("-lc++experimental"); 3690b57cec5SDimitry Andric CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi"); 370d409305fSDimitry Andric CmdArgs.push_back(Profiling ? "-lpthread_p" : "-lpthread"); 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 37381ad6265SDimitry Andric std::string OpenBSD::getCompilerRT(const ArgList &Args, StringRef Component, 37416d6b3b3SDimitry Andric FileType Type) const { 37581ad6265SDimitry Andric if (Component == "builtins") { 37616d6b3b3SDimitry Andric SmallString<128> Path(getDriver().SysRoot); 37716d6b3b3SDimitry Andric llvm::sys::path::append(Path, "/usr/lib/libcompiler_rt.a"); 3783a079333SDimitry Andric if (getVFS().exists(Path)) 3797a6dacacSDimitry Andric return std::string(Path); 38016d6b3b3SDimitry Andric } 38181ad6265SDimitry Andric SmallString<128> P(getDriver().ResourceDir); 38281ad6265SDimitry Andric std::string CRTBasename = 38381ad6265SDimitry Andric buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false); 38481ad6265SDimitry Andric llvm::sys::path::append(P, "lib", CRTBasename); 38581ad6265SDimitry Andric // Checks if this is the base system case which uses a different location. 38681ad6265SDimitry Andric if (getVFS().exists(P)) 3877a6dacacSDimitry Andric return std::string(P); 38881ad6265SDimitry Andric return ToolChain::getCompilerRT(Args, Component, Type); 38981ad6265SDimitry Andric } 39016d6b3b3SDimitry Andric 3910b57cec5SDimitry Andric Tool *OpenBSD::buildAssembler() const { 3920b57cec5SDimitry Andric return new tools::openbsd::Assembler(*this); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); } 396480093f4SDimitry Andric 39716d6b3b3SDimitry Andric bool OpenBSD::HasNativeLLVMSupport() const { return true; } 3983a9a9c0cSDimitry Andric 399bdd1243dSDimitry Andric ToolChain::UnwindTableLevel 400bdd1243dSDimitry Andric OpenBSD::getDefaultUnwindTableLevel(const ArgList &Args) const { 4013a9a9c0cSDimitry Andric switch (getArch()) { 4023a9a9c0cSDimitry Andric case llvm::Triple::arm: 403bdd1243dSDimitry Andric return UnwindTableLevel::None; 4043a9a9c0cSDimitry Andric default: 405bdd1243dSDimitry Andric return UnwindTableLevel::Asynchronous; 4063a9a9c0cSDimitry Andric } 4073a9a9c0cSDimitry Andric } 408