Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -170,6 +170,8 @@ std::string GetFilePath(const char *Name) const; std::string GetProgramPath(const char *Name) const; + std::string GetRuntimeLibPath(enum RuntimeLibType Type, const char *Component, + bool Shared = false) const; /// Returns the linker path, respecting the -fuse-ld= argument to determine /// the linker suffix or name. Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -187,6 +187,38 @@ return D.GetProgramPath(Name, *this); } +std::string ToolChain::GetRuntimeLibPath(enum RuntimeLibType Type, + const char *Component, bool Shared) const { + bool IsOSWindows = Triple.isOSWindows(); + StringRef Suffix = + Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a"); + llvm::SmallString<128> Path; + + switch (Type) { + case RLT_CompilerRT: { + StringRef Prefix = IsOSWindows ? "" : "lib"; + StringRef Arch = Triple.getArchName(); + // FIXME: Handle 64-bit. + if (IsOSWindows && !Triple.isWindowsItaniumEnvironment()) + Arch = "i386"; + // All ARM runtimes are in one library. + if (Triple.getArch() == llvm::Triple::arm || Triple.getArch() == llvm::Triple::armeb) + Arch = "arm"; + StringRef Env = Triple.getEnvironment() == llvm::Triple::Android + ? "-android" + : ""; + + (Prefix + Twine("clang_rt.") + Component + "-" + Arch + Env + Suffix).toVector(Path); + break; + } + case RLT_Libgcc: { + (Twine("libgcc") + Component + Suffix).toVector(Path); + break; + } + } + return GetFilePath(Path.c_str()); +} + std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { StringRef Suffix = A->getValue(); Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2208,53 +2208,13 @@ } } -// Until ARM libraries are build separately, we have them all in one library -static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) { - // FIXME: handle 64-bit - if (TC.getTriple().isOSWindows() && - !TC.getTriple().isWindowsItaniumEnvironment()) - return "i386"; - if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) - return "arm"; - return TC.getArchName(); -} - -static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) { - // The runtimes are located in the OS-specific resource directory. - SmallString<128> Res(TC.getDriver().ResourceDir); - const llvm::Triple &Triple = TC.getTriple(); - // TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected. - StringRef OSLibName = - (Triple.getOS() == llvm::Triple::FreeBSD) ? "freebsd" : TC.getOS(); - llvm::sys::path::append(Res, "lib", OSLibName); - return Res; -} - -static SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, - bool Shared = false) { - const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android - ? "-android" - : ""; - - bool IsOSWindows = TC.getTriple().isOSWindows(); - StringRef Arch = getArchNameForCompilerRTLib(TC); - const char *Prefix = IsOSWindows ? "" : "lib"; - const char *Suffix = - Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a"); - - SmallString<128> Path = getCompilerRTLibDir(TC); - llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" + - Arch + Env + Suffix); - - return Path; -} - // This adds the static libclang_rt.builtins-arch.a directly to the command line // FIXME: Make sure we can also emit shared objects if they're requested // and available, check for possible errors, etc. static void addClangRT(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins"))); + CmdArgs.push_back(Args.MakeArgString( + TC.GetRuntimeLibPath(ToolChain::RLT_CompilerRT, "builtins"))); if (!TC.getTriple().isOSWindows()) { // FIXME: why do we link against gcc when we are using compiler-rt? @@ -2275,7 +2235,8 @@ Args.hasArg(options::OPT_coverage))) return; - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "profile"))); + CmdArgs.push_back(Args.MakeArgString( + TC.GetRuntimeLibPath(ToolChain::RLT_CompilerRT, "profile"))); } static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, @@ -2285,7 +2246,8 @@ // whole-archive. if (!IsShared) CmdArgs.push_back("-whole-archive"); - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Sanitizer, IsShared))); + CmdArgs.push_back(Args.MakeArgString(TC.GetRuntimeLibPath( + ToolChain::RLT_CompilerRT, Sanitizer.data(), IsShared))); if (!IsShared) CmdArgs.push_back("-no-whole-archive"); } @@ -2295,7 +2257,8 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer) { - SmallString<128> SanRT = getCompilerRT(TC, Sanitizer); + std::string SanRT = TC.GetRuntimeLibPath(ToolChain::RLT_CompilerRT, + Sanitizer.data()); if (llvm::sys::fs::exists(SanRT + ".syms")) { CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms")); return true; @@ -8611,19 +8574,22 @@ "asan_dynamic_runtime_thunk", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); + CmdArgs.push_back(Args.MakeArgString(TC.GetRuntimeLibPath( + ToolChain::RLT_CompilerRT, Component))); // Make sure the dynamic runtime thunk is not optimized out at link time // to ensure proper SEH handling. CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor")); } else if (DLL) { - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk"))); + CmdArgs.push_back(Args.MakeArgString(TC.GetRuntimeLibPath( + ToolChain::RLT_CompilerRT, "asan_dll_thunk"))); } else { static const char *CompilerRTComponents[] = { "asan", "asan_cxx", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); + CmdArgs.push_back(Args.MakeArgString(TC.GetRuntimeLibPath( + ToolChain::RLT_CompilerRT, Component))); } }