From: Benjamin Kramer Date: Wed, 2 Feb 2011 18:59:27 +0000 (+0000) Subject: Add NetBSD target support. Patch by Joerg Sonnenberger. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e50a96b387dca7525caa8a6add31420dd82a2cd;p=clang Add NetBSD target support. Patch by Joerg Sonnenberger. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124736 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h index 04e72992d6..7285a48b1c 100644 --- a/include/clang/Driver/HostInfo.h +++ b/include/clang/Driver/HostInfo.h @@ -71,6 +71,8 @@ const HostInfo *createOpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple); const HostInfo *createFreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple); +const HostInfo *createNetBSDHostInfo(const Driver &D, + const llvm::Triple& Triple); const HostInfo *createMinixHostInfo(const Driver &D, const llvm::Triple& Triple); const HostInfo *createDragonFlyHostInfo(const Driver &D, diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index a1fdb87c18..c12e540a7a 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -2817,6 +2817,7 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::DragonFly: case llvm::Triple::FreeBSD: case llvm::Triple::OpenBSD: + case llvm::Triple::NetBSD: return *(TheTargetCodeGenInfo = new X86_32TargetCodeGenInfo(Types, false, true)); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index d588dc3772..df32eb3a4d 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1327,6 +1327,8 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const { return createDragonFlyHostInfo(*this, Triple); case llvm::Triple::OpenBSD: return createOpenBSDHostInfo(*this, Triple); + case llvm::Triple::NetBSD: + return createNetBSDHostInfo(*this, Triple); case llvm::Triple::FreeBSD: return createFreeBSDHostInfo(*this, Triple); case llvm::Triple::Minix: diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index cce18fbc0d..cd413180f7 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -372,6 +372,65 @@ ToolChain *FreeBSDHostInfo::CreateToolChain(const ArgList &Args, return TC; } +// NetBSD Host Info + +/// NetBSDHostInfo - NetBSD host information implementation. +class NetBSDHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap ToolChains; + +public: + NetBSDHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) {} + ~NetBSDHostInfo(); + + virtual bool useDriverDriver() const; + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +NetBSDHostInfo::~NetBSDHostInfo() { + for (llvm::StringMap::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool NetBSDHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *NetBSDHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + // Automatically handle some instances of -m32/-m64 we know about. + std::string Arch = getArchName(); + ArchName = Arch.c_str(); + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } else if (Triple.getArch() == llvm::Triple::ppc || + Triple.getArch() == llvm::Triple::ppc64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::NetBSD(*this, TCTriple); + } + + return TC; +} + // Minix Host Info /// MinixHostInfo - Minix host information implementation. @@ -623,6 +682,12 @@ clang::driver::createFreeBSDHostInfo(const Driver &D, return new FreeBSDHostInfo(D, Triple); } +const HostInfo * +clang::driver::createNetBSDHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new NetBSDHostInfo(D, Triple); +} + const HostInfo * clang::driver::createMinixHostInfo(const Driver &D, const llvm::Triple& Triple) { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 64c9ccb8c3..236a1549eb 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1130,6 +1130,57 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { return *T; } +/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. + +NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple) + : Generic_ELF(Host, Triple) { + + // Determine if we are compiling 32-bit code on an x86_64 platform. + bool Lib32 = false; + if (Triple.getArch() == llvm::Triple::x86 && + llvm::Triple(getDriver().DefaultHostTriple).getArch() == + llvm::Triple::x86_64) + Lib32 = true; + + getProgramPaths().push_back(getDriver().Dir + "/../libexec"); + getProgramPaths().push_back("/usr/libexec"); + if (Lib32) { + getFilePaths().push_back("/usr/lib/i386"); + } else { + getFilePaths().push_back("/usr/lib"); + } +} + +Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA) const { + Action::ActionClass Key; + if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) + Key = Action::AnalyzeJobClass; + else + Key = JA.getKind(); + + bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, + options::OPT_no_integrated_as, + IsIntegratedAssemblerDefault()); + + Tool *&T = Tools[Key]; + if (!T) { + switch (Key) { + case Action::AssembleJobClass: + if (UseIntegratedAs) + T = new tools::ClangAs(*this); + else + T = new tools::netbsd::Assemble(*this); + break; + case Action::LinkJobClass: + T = new tools::netbsd::Link(*this); break; + default: + T = &Generic_GCC::SelectTool(C, JA); + } + } + + return *T; +} + /// Minix - Minix tool chain which can call as(1) and ld(1) directly. Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple) diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 33b8053453..005597dccc 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -305,6 +305,13 @@ public: virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; +class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF { +public: + NetBSD(const HostInfo &Host, const llvm::Triple& Triple); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; +}; + class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC { public: Minix(const HostInfo &Host, const llvm::Triple& Triple); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index a2536381c3..61d1bbe48e 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -710,6 +710,11 @@ void Clang::AddX86TargetArgs(const ArgList &Args, CPUName = "x86-64"; else if (getToolChain().getArchName() == "i386") CPUName = "i486"; + } else if (getToolChain().getOS().startswith("netbsd")) { + if (getToolChain().getArchName() == "x86_64") + CPUName = "x86-64"; + else if (getToolChain().getArchName() == "i386") + CPUName = "i486"; } else { if (getToolChain().getArchName() == "x86_64") CPUName = "x86-64"; @@ -3227,6 +3232,153 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } +void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + ArgStringList CmdArgs; + + // When building 32-bit code on NetBSD/amd64, we have to explicitly + // instruct as in the base system to assemble 32-bit code. + if (getToolChain().getArchName() == "i386") + CmdArgs.push_back("--32"); + + + // Set byte order explicitly + if (getToolChain().getArchName() == "mips") + CmdArgs.push_back("-EB"); + else if (getToolChain().getArchName() == "mipsel") + CmdArgs.push_back("-EL"); + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, + options::OPT_Xassembler); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + for (InputInfoList::const_iterator + it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { + const InputInfo &II = *it; + CmdArgs.push_back(II.getFilename()); + } + + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath("as")); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} + +void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + ArgStringList CmdArgs; + + if (Args.hasArg(options::OPT_static)) { + CmdArgs.push_back("-Bstatic"); + } else { + if (Args.hasArg(options::OPT_rdynamic)) + CmdArgs.push_back("-export-dynamic"); + CmdArgs.push_back("--eh-frame-hdr"); + if (Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-Bshareable"); + } else { + CmdArgs.push_back("-dynamic-linker"); + CmdArgs.push_back("/libexec/ld.elf_so"); + } + } + + // When building 32-bit code on NetBSD/amd64, we have to explicitly + // instruct ld in the base system to link 32-bit code. + if (getToolChain().getArchName() == "i386") { + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf_i386"); + } + + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crt0.o"))); + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crtbegin.o"))); + } else { + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crti.o"))); + CmdArgs.push_back(Args.MakeArgString( + getToolChain().GetFilePath("crtbeginS.o"))); + } + } + + Args.AddAllArgs(CmdArgs, options::OPT_L); + Args.AddAllArgs(CmdArgs, options::OPT_T_Group); + Args.AddAllArgs(CmdArgs, options::OPT_e); + Args.AddAllArgs(CmdArgs, options::OPT_s); + Args.AddAllArgs(CmdArgs, options::OPT_t); + Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); + Args.AddAllArgs(CmdArgs, options::OPT_r); + + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nodefaultlibs)) { + if (D.CCCIsCXX) { + getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); + CmdArgs.push_back("-lm"); + } + // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding + // the default system libraries. Just mimic this for now. + CmdArgs.push_back("-lgcc"); + if (Args.hasArg(options::OPT_static)) { + CmdArgs.push_back("-lgcc_eh"); + } else { + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back("-lgcc_s"); + CmdArgs.push_back("--no-as-needed"); + } + + if (Args.hasArg(options::OPT_pthread)) + CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("-lc"); + + CmdArgs.push_back("-lgcc"); + if (Args.hasArg(options::OPT_static)) { + CmdArgs.push_back("-lgcc_eh"); + } else { + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back("-lgcc_s"); + CmdArgs.push_back("--no-as-needed"); + } + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_shared)) + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( + "crtend.o"))); + else + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( + "crtendS.o"))); + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath( + "crtn.o"))); + } + + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath("ld")); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} + void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 782aa4867c..10c8839009 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -334,6 +334,35 @@ namespace freebsd { }; } // end namespace freebsd + /// netbsd -- Directly call GNU Binutils assembler and linker +namespace netbsd { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { + public: + Assemble(const ToolChain &TC) : Tool("netbsd::Assemble", "assembler", + TC) {} + + virtual bool hasIntegratedCPP() const { return false; } + + virtual void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; + class LLVM_LIBRARY_VISIBILITY Link : public Tool { + public: + Link(const ToolChain &TC) : Tool("netbsd::Link", "linker", TC) {} + + virtual bool hasIntegratedCPP() const { return false; } + + virtual void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; +} // end namespace netbsd + /// linux -- Directly call GNU Binutils assembler and linker namespace linuxtools { class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 23b46d23d6..7fa7d0162f 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -418,8 +418,16 @@ static bool getWindowsSDKDir(std::string &path) { void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { - // FIXME: temporary hack: hard-coded paths. - AddPath("/usr/local/include", System, true, false, false); + llvm::Triple::OSType os = triple.getOS(); + + switch (os) { + case llvm::Triple::NetBSD: + break; + default: + // FIXME: temporary hack: hard-coded paths. + AddPath("/usr/local/include", System, true, false, false); + break; + } // Builtin includes use #include_next directives and should be positioned // just prior C include dirs. @@ -442,7 +450,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, AddPath(*i, System, false, false, false); return; } - llvm::Triple::OSType os = triple.getOS(); + switch (os) { case llvm::Triple::Win32: { std::string VSDir;