summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2016-12-31 13:15:55 +0300
committerIgor Pashev <pashev.igor@gmail.com>2016-12-31 13:29:50 +0300
commit7a7e5d5ad4abc0010ed81bec0a04b672d7aed74c (patch)
tree85180d2880d8d14b12ecc4b5ce547c13b57a1f4e
parentaf9bc6048f75920d7916539e1c95e53a317840bb (diff)
downloadllvm-toolchain-3.8-7a7e5d5ad4abc0010ed81bec0a04b672d7aed74c.tar.gz
Very dirty patch for Dyson toolchain
-rw-r--r--debian/patches/dyson-toolchain.patch920
-rw-r--r--debian/patches/series1
2 files changed, 921 insertions, 0 deletions
diff --git a/debian/patches/dyson-toolchain.patch b/debian/patches/dyson-toolchain.patch
new file mode 100644
index 0000000..0d6c2c0
--- /dev/null
+++ b/debian/patches/dyson-toolchain.patch
@@ -0,0 +1,920 @@
+Index: llvm-toolchain-3.8-3.8.1/clang/lib/Driver/ToolChains.cpp
+===================================================================
+--- llvm-toolchain-3.8-3.8.1.orig/clang/lib/Driver/ToolChains.cpp
++++ llvm-toolchain-3.8-3.8.1/clang/lib/Driver/ToolChains.cpp
+@@ -1493,20 +1493,9 @@ bool Generic_GCC::GCCInstallationDetecto
+ "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
+ "s390x-suse-linux", "s390x-redhat-linux"};
+
+- // Solaris.
+- static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
+- static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
+- "i386-pc-solaris2.11"};
+-
+ using std::begin;
+ using std::end;
+
+- if (TargetTriple.getOS() == llvm::Triple::Solaris) {
+- LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
+- TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
+- return;
+- }
+-
+ switch (TargetTriple.getArch()) {
+ case llvm::Triple::aarch64:
+ LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
+@@ -2178,56 +2167,6 @@ static bool findBiarchMultilibs(const Dr
+ return true;
+ }
+
+-void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
+- const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
+- const std::string &LibDir, StringRef CandidateTriple,
+- bool NeedsBiarchSuffix) {
+- // Solaris is a special case. The GCC installation is under
+- // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
+- // need to iterate twice.
+- std::error_code EC;
+- for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
+- !EC && LI != LE; LI = LI.increment(EC)) {
+- StringRef VersionText = llvm::sys::path::filename(LI->getName());
+- GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
+-
+- if (CandidateVersion.Major != -1) // Filter obviously bad entries.
+- if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
+- continue; // Saw this path before; no need to look at it again.
+- if (CandidateVersion.isOlderThan(4, 1, 1))
+- continue;
+- if (CandidateVersion <= Version)
+- continue;
+-
+- GCCInstallPath =
+- LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
+- if (!D.getVFS().exists(GCCInstallPath))
+- continue;
+-
+- // If we make it here there has to be at least one GCC version, let's just
+- // use the latest one.
+- std::error_code EEC;
+- for (vfs::directory_iterator
+- LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
+- LLE;
+- !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
+-
+- StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
+- GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
+-
+- if (CandidateSubVersion > Version)
+- Version = CandidateSubVersion;
+- }
+-
+- GCCTriple.setTriple(CandidateTriple);
+-
+- GCCInstallPath += "/" + Version.Text;
+- GCCParentLibPath = GCCInstallPath + "/../../../../";
+-
+- IsValid = true;
+- }
+-}
+-
+ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
+ const llvm::Triple &TargetTriple, const ArgList &Args,
+ const std::string &LibDir, StringRef CandidateTriple,
+@@ -2257,12 +2196,6 @@ void Generic_GCC::GCCInstallationDetecto
+ // triple.
+ {"/i386-linux-gnu/gcc/" + CandidateTriple.str(), "/../../../.."}};
+
+- if (TargetTriple.getOS() == llvm::Triple::Solaris) {
+- scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
+- NeedsBiarchSuffix);
+- return;
+- }
+-
+ // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
+ const unsigned NumLibSuffixes = (llvm::array_lengthof(LibAndInstallSuffixes) -
+ (TargetArch != llvm::Triple::x86));
+@@ -3307,66 +3240,224 @@ static void addPathIfExists(const Driver
+
+ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+- : Generic_GCC(D, Triple, Args) {
++ : Linux(D, Triple, Args) {
++}
+
+- GCCInstallation.init(Triple, Args);
++Tool *Solaris::buildAssembler() const {
++ return new tools::gnutools::Assembler(*this);
++}
+
+- path_list &Paths = getFilePaths();
+- if (GCCInstallation.isValid())
+- addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
++Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
+
+- addPathIfExists(D, getDriver().getInstalledDir(), Paths);
+- if (getDriver().getInstalledDir() != getDriver().Dir)
+- addPathIfExists(D, getDriver().Dir, Paths);
++static std::string DetectLibcxxIncludePath(StringRef base) {
++ std::error_code EC;
++ int MaxVersion = 0;
++ std::string MaxVersionString = "";
++ for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
++ LI = LI.increment(EC)) {
++ StringRef VersionText = llvm::sys::path::filename(LI->path());
++ int Version;
++ if (VersionText[0] == 'v' &&
++ !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
++ if (Version > MaxVersion) {
++ MaxVersion = Version;
++ MaxVersionString = VersionText;
++ }
++ }
++ }
++ return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
++}
+
+- addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
++/// \brief Get our best guess at the multiarch triple for a target.
++///
++/// Debian-based systems are starting to use a multiarch setup where they use
++/// a target-triple directory in the library and header search paths.
++/// Unfortunately, this triple does not align with the vanilla target triple,
++/// so we provide a rough mapping here.
++static std::string getMultiarchTriple(const Driver &D,
++ const llvm::Triple &TargetTriple,
++ StringRef SysRoot) {
++ llvm::Triple::EnvironmentType TargetEnvironment =
++ TargetTriple.getEnvironment();
+
+- std::string LibPath = "/usr/lib/";
+- switch (Triple.getArch()) {
++ // For most architectures, just use whatever we have rather than trying to be
++ // clever.
++ switch (TargetTriple.getArch()) {
++ default:
++ break;
++
++ // We use the existence of '/lib/<triple>' as a directory to detect some
++ // common linux triples that don't quite match the Clang triple for both
++ // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
++ // regardless of what the actual target triple is.
++ case llvm::Triple::arm:
++ case llvm::Triple::thumb:
++ if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
++ if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
++ return "arm-linux-gnueabihf";
++ } else {
++ if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
++ return "arm-linux-gnueabi";
++ }
++ break;
++ case llvm::Triple::armeb:
++ case llvm::Triple::thumbeb:
++ if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
++ if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
++ return "armeb-linux-gnueabihf";
++ } else {
++ if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
++ return "armeb-linux-gnueabi";
++ }
++ break;
+ case llvm::Triple::x86:
+- case llvm::Triple::sparc:
++ if (TargetTriple.getOS() == llvm::Triple::Solaris) {
++ if (D.getVFS().exists(SysRoot + "/lib/i386-illumos"))
++ return "i386-illumos";
++ }
++ if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
++ return "i386-linux-gnu";
+ break;
+ case llvm::Triple::x86_64:
+- LibPath += "amd64/";
++ if (TargetTriple.getOS() == llvm::Triple::Solaris) {
++ if (D.getVFS().exists(SysRoot + "/lib/x86_64-illumos"))
++ return "x86_64-illumos";
++ }
++ // We don't want this for x32, otherwise it will match x86_64 libs
++ if (TargetEnvironment != llvm::Triple::GNUX32 &&
++ D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
++ return "x86_64-linux-gnu";
++ break;
++ case llvm::Triple::aarch64:
++ if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
++ return "aarch64-linux-gnu";
++ break;
++ case llvm::Triple::aarch64_be:
++ if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
++ return "aarch64_be-linux-gnu";
++ break;
++ case llvm::Triple::mips:
++ if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
++ return "mips-linux-gnu";
++ break;
++ case llvm::Triple::mipsel:
++ if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
++ return "mipsel-linux-gnu";
++ break;
++ case llvm::Triple::mips64:
++ if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
++ return "mips64-linux-gnu";
++ if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
++ return "mips64-linux-gnuabi64";
++ break;
++ case llvm::Triple::mips64el:
++ if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
++ return "mips64el-linux-gnu";
++ if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
++ return "mips64el-linux-gnuabi64";
++ break;
++ case llvm::Triple::ppc:
++ if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
++ return "powerpc-linux-gnuspe";
++ if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
++ return "powerpc-linux-gnu";
++ break;
++ case llvm::Triple::ppc64:
++ if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
++ return "powerpc64-linux-gnu";
++ break;
++ case llvm::Triple::ppc64le:
++ if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
++ return "powerpc64le-linux-gnu";
++ break;
++ case llvm::Triple::sparc:
++ if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
++ return "sparc-linux-gnu";
+ break;
+ case llvm::Triple::sparcv9:
+- LibPath += "sparcv9/";
++ if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
++ return "sparc64-linux-gnu";
++ break;
++ case llvm::Triple::systemz:
++ if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
++ return "s390x-linux-gnu";
+ break;
+- default:
+- llvm_unreachable("Unsupported architecture");
+ }
+-
+- addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
+-}
+-
+-Tool *Solaris::buildAssembler() const {
+- return new tools::solaris::Assembler(*this);
++ return TargetTriple.str();
+ }
+
+-Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
+-
+ void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
++ // See Linux::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+ DriverArgs.hasArg(options::OPT_nostdincxx))
+ return;
+
+- // Include the support directory for things like xlocale and fudged system
+- // headers.
+- addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
++ // Check if libc++ has been enabled and provide its include paths if so.
++ if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
++ const std::string LibCXXIncludePathCandidates[] = {
++ DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
++
++ // We also check the system as for a long time this is the only place
++ // Clang looked.
++ // FIXME: We should really remove this. It doesn't make any sense.
++ DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++")};
++ for (const auto &IncludePath : LibCXXIncludePathCandidates) {
++ if (IncludePath.empty() || !getVFS().exists(IncludePath))
++ continue;
++ // Add the first candidate that exists.
++ addSystemInclude(DriverArgs, CC1Args, IncludePath);
++ break;
++ }
++ return;
++ }
++
++ // We need a detected GCC installation on Linux to provide libstdc++'s
++ // headers. We handled the libc++ case above.
++ if (!GCCInstallation.isValid())
++ return;
+
+- if (GCCInstallation.isValid()) {
+- GCCVersion Version = GCCInstallation.getVersion();
+- addSystemInclude(DriverArgs, CC1Args,
+- getDriver().SysRoot + "/usr/gcc/" +
+- Version.MajorStr + "." +
+- Version.MinorStr +
+- "/include/c++/" + Version.Text);
+- addSystemInclude(DriverArgs, CC1Args,
+- getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
+- "." + Version.MinorStr + "/include/c++/" +
+- Version.Text + "/" +
+- GCCInstallation.getTriple().str());
++ // By default, look for the C++ headers in an include directory adjacent to
++ // the lib directory of the GCC installation. Note that this is expect to be
++ // equivalent to '/usr/include/c++/X.Y' in almost all cases.
++ StringRef LibDir = GCCInstallation.getParentLibPath();
++ StringRef InstallDir = GCCInstallation.getInstallPath();
++ StringRef TripleStr = GCCInstallation.getTriple().str();
++ const Multilib &Multilib = GCCInstallation.getMultilib();
++ const std::string GCCMultiarchTriple = getMultiarchTriple(
++ getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
++ const std::string TargetMultiarchTriple =
++ getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
++ const GCCVersion &Version = GCCInstallation.getVersion();
++
++ // The primary search for libstdc++ supports multiarch variants.
++ if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
++ "/c++/" + Version.Text, TripleStr,
++ GCCMultiarchTriple, TargetMultiarchTriple,
++ Multilib.includeSuffix(), DriverArgs, CC1Args))
++ return;
++
++ // Otherwise, fall back on a bunch of options which don't use multiarch
++ // layouts for simplicity.
++ const std::string LibStdCXXIncludePathCandidates[] = {
++ // Gentoo is weird and places its headers inside the GCC install,
++ // so if the first attempt to find the headers fails, try these patterns.
++ InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
++ Version.MinorStr,
++ InstallDir.str() + "/include/g++-v" + Version.MajorStr,
++ // Android standalone toolchain has C++ headers in yet another place.
++ LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
++ // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
++ // without a subdirectory corresponding to the gcc version.
++ LibDir.str() + "/../include/c++",
++ };
++
++ for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
++ if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
++ /*GCCMultiarchTriple*/ "",
++ /*TargetMultiarchTriple*/ "",
++ Multilib.includeSuffix(), DriverArgs, CC1Args))
++ break;
+ }
+ }
+
+@@ -3377,11 +3468,7 @@ enum Distro {
+ // in this enum, because some tests are done by integer comparison against
+ // the first and last known member in the family, e.g. IsRedHat().
+ ArchLinux,
+- DebianLenny,
+- DebianSqueeze,
+- DebianWheezy,
+- DebianJessie,
+- DebianStretch,
++ Debian,
+ Exherbo,
+ RHEL4,
+ RHEL5,
+@@ -3415,10 +3502,6 @@ static bool IsRedhat(enum Distro Distro)
+
+ static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; }
+
+-static bool IsDebian(enum Distro Distro) {
+- return Distro >= DebianLenny && Distro <= DebianStretch;
+-}
+-
+ static bool IsUbuntu(enum Distro Distro) {
+ return Distro >= UbuntuHardy && Distro <= UbuntuXenial;
+ }
+@@ -3476,18 +3559,7 @@ static Distro DetectDistro(const Driver
+
+ File = llvm::MemoryBuffer::getFile("/etc/debian_version");
+ if (File) {
+- StringRef Data = File.get()->getBuffer();
+- if (Data[0] == '5')
+- return DebianLenny;
+- else if (Data.startswith("squeeze/sid") || Data[0] == '6')
+- return DebianSqueeze;
+- else if (Data.startswith("wheezy/sid") || Data[0] == '7')
+- return DebianWheezy;
+- else if (Data.startswith("jessie/sid") || Data[0] == '8')
+- return DebianJessie;
+- else if (Data.startswith("stretch/sid") || Data[0] == '9')
+- return DebianStretch;
+- return UnknownDistro;
++ return Debian;
+ }
+
+ if (D.getVFS().exists("/etc/SuSE-release"))
+@@ -3502,116 +3574,6 @@ static Distro DetectDistro(const Driver
+ return UnknownDistro;
+ }
+
+-/// \brief Get our best guess at the multiarch triple for a target.
+-///
+-/// Debian-based systems are starting to use a multiarch setup where they use
+-/// a target-triple directory in the library and header search paths.
+-/// Unfortunately, this triple does not align with the vanilla target triple,
+-/// so we provide a rough mapping here.
+-static std::string getMultiarchTriple(const Driver &D,
+- const llvm::Triple &TargetTriple,
+- StringRef SysRoot) {
+- llvm::Triple::EnvironmentType TargetEnvironment =
+- TargetTriple.getEnvironment();
+-
+- // For most architectures, just use whatever we have rather than trying to be
+- // clever.
+- switch (TargetTriple.getArch()) {
+- default:
+- break;
+-
+- // We use the existence of '/lib/<triple>' as a directory to detect some
+- // common linux triples that don't quite match the Clang triple for both
+- // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
+- // regardless of what the actual target triple is.
+- case llvm::Triple::arm:
+- case llvm::Triple::thumb:
+- if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
+- if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+- return "arm-linux-gnueabihf";
+- } else {
+- if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
+- return "arm-linux-gnueabi";
+- }
+- break;
+- case llvm::Triple::armeb:
+- case llvm::Triple::thumbeb:
+- if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
+- if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
+- return "armeb-linux-gnueabihf";
+- } else {
+- if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
+- return "armeb-linux-gnueabi";
+- }
+- break;
+- case llvm::Triple::x86:
+- if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
+- return "i386-linux-gnu";
+- break;
+- case llvm::Triple::x86_64:
+- // We don't want this for x32, otherwise it will match x86_64 libs
+- if (TargetEnvironment != llvm::Triple::GNUX32 &&
+- D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
+- return "x86_64-linux-gnu";
+- break;
+- case llvm::Triple::aarch64:
+- if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
+- return "aarch64-linux-gnu";
+- break;
+- case llvm::Triple::aarch64_be:
+- if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
+- return "aarch64_be-linux-gnu";
+- break;
+- case llvm::Triple::mips:
+- if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
+- return "mips-linux-gnu";
+- break;
+- case llvm::Triple::mipsel:
+- if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
+- return "mipsel-linux-gnu";
+- break;
+- case llvm::Triple::mips64:
+- if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
+- return "mips64-linux-gnu";
+- if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
+- return "mips64-linux-gnuabi64";
+- break;
+- case llvm::Triple::mips64el:
+- if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
+- return "mips64el-linux-gnu";
+- if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
+- return "mips64el-linux-gnuabi64";
+- break;
+- case llvm::Triple::ppc:
+- if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
+- return "powerpc-linux-gnuspe";
+- if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
+- return "powerpc-linux-gnu";
+- break;
+- case llvm::Triple::ppc64:
+- if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
+- return "powerpc64-linux-gnu";
+- break;
+- case llvm::Triple::ppc64le:
+- if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
+- return "powerpc64le-linux-gnu";
+- break;
+- case llvm::Triple::sparc:
+- if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
+- return "sparc-linux-gnu";
+- break;
+- case llvm::Triple::sparcv9:
+- if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
+- return "sparc64-linux-gnu";
+- break;
+- case llvm::Triple::systemz:
+- if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
+- return "s390x-linux-gnu";
+- break;
+- }
+- return TargetTriple.str();
+-}
+-
+ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
+ if (isMipsArch(Triple.getArch())) {
+ // lib32 directory has a special meaning on MIPS targets.
+@@ -3689,7 +3651,7 @@ Linux::Linux(const Driver &D, const llvm
+ (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
+ ExtraOpts.push_back("--hash-style=gnu");
+
+- if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
++ if (Distro == Debian || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
+ Distro == UbuntuJaunty || Distro == UbuntuKarmic)
+ ExtraOpts.push_back("--hash-style=both");
+ }
+@@ -3697,7 +3659,7 @@ Linux::Linux(const Driver &D, const llvm
+ if (IsRedhat(Distro))
+ ExtraOpts.push_back("--no-add-needed");
+
+- if ((IsDebian(Distro) && Distro >= DebianSqueeze) || IsOpenSUSE(Distro) ||
++ if ((Distro == Debian) || IsOpenSUSE(Distro) ||
+ (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) ||
+ (IsUbuntu(Distro) && Distro >= UbuntuKarmic))
+ ExtraOpts.push_back("--build-id");
+@@ -4030,26 +3992,6 @@ void Linux::AddClangSystemIncludeArgs(co
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
+ }
+
+-
+-static std::string DetectLibcxxIncludePath(StringRef base) {
+- std::error_code EC;
+- int MaxVersion = 0;
+- std::string MaxVersionString = "";
+- for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
+- LI = LI.increment(EC)) {
+- StringRef VersionText = llvm::sys::path::filename(LI->path());
+- int Version;
+- if (VersionText[0] == 'v' &&
+- !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
+- if (Version > MaxVersion) {
+- MaxVersion = Version;
+- MaxVersionString = VersionText;
+- }
+- }
+- }
+- return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
+-}
+-
+ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+Index: llvm-toolchain-3.8-3.8.1/clang/lib/Driver/Tools.cpp
+===================================================================
+--- llvm-toolchain-3.8-3.8.1.orig/clang/lib/Driver/Tools.cpp
++++ llvm-toolchain-3.8-3.8.1/clang/lib/Driver/Tools.cpp
+@@ -7391,35 +7391,108 @@ void solaris::Assembler::ConstructJob(Co
+ C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
+ }
+
++static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
++ ArgStringList &CmdArgs, const ArgList &Args) {
++ bool isAndroid = Triple.isAndroid();
++ bool isCygMing = Triple.isOSCygMing();
++ bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
++ Args.hasArg(options::OPT_static);
++ if (!D.CCCIsCXX())
++ CmdArgs.push_back("-lgcc");
++
++ if (StaticLibgcc || isAndroid) {
++ if (D.CCCIsCXX())
++ CmdArgs.push_back("-lgcc");
++ } else {
++ if (!D.CCCIsCXX() && !isCygMing)
++ CmdArgs.push_back("--as-needed");
++ CmdArgs.push_back("-lgcc_s");
++ if (!D.CCCIsCXX() && !isCygMing)
++ CmdArgs.push_back("--no-as-needed");
++ }
++
++ if (StaticLibgcc && !isAndroid)
++ CmdArgs.push_back("-lgcc_eh");
++ else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
++ CmdArgs.push_back("-lgcc");
++
++ // According to Android ABI, we have to link with libdl if we are
++ // linking with non-static libgcc.
++ //
++ // NOTE: This fixes a link error on Android MIPS as well. The non-static
++ // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
++ if (isAndroid && !StaticLibgcc)
++ CmdArgs.push_back("-ldl");
++}
++
++static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
++ ArgStringList &CmdArgs, const ArgList &Args) {
++ // Make use of compiler-rt if --rtlib option is used
++ ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
++
++ switch (RLT) {
++ case ToolChain::RLT_CompilerRT:
++ switch (TC.getTriple().getOS()) {
++ default:
++ llvm_unreachable("unsupported OS");
++ case llvm::Triple::Win32:
++ case llvm::Triple::Linux:
++ addClangRT(TC, Args, CmdArgs);
++ break;
++ }
++ break;
++ case ToolChain::RLT_Libgcc:
++ AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
++ break;
++ }
++}
++
+ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
++ const toolchains::Linux &ToolChain =
++ static_cast<const toolchains::Linux &>(getToolChain());
++ const Driver &D = ToolChain.getDriver();
++
+ ArgStringList CmdArgs;
+
+- // Demangle C++ names in errors
+- CmdArgs.push_back("-C");
++ if (Args.hasArg(options::OPT_static)) {
++ CmdArgs.push_back("-static");
++ } else if (Args.hasArg(options::OPT_shared)) {
++ CmdArgs.push_back("-shared");
++ }
+
+- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
+- CmdArgs.push_back("-e");
+- CmdArgs.push_back("_start");
++ if (!D.SysRoot.empty())
++ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
++
++ if (Args.hasArg(options::OPT_rdynamic))
++ CmdArgs.push_back("-export-dynamic");
++
++ if (Args.hasArg(options::OPT_s))
++ CmdArgs.push_back("-s");
++
++ for (const auto &Opt : ToolChain.ExtraOpts)
++ CmdArgs.push_back(Opt.c_str());
++
++ if (!Args.hasArg(options::OPT_static)) {
++ CmdArgs.push_back("--eh-frame-hdr");
+ }
+
+- if (Args.hasArg(options::OPT_static)) {
+- CmdArgs.push_back("-Bstatic");
+- CmdArgs.push_back("-dn");
+- } else {
+- CmdArgs.push_back("-Bdynamic");
+- if (Args.hasArg(options::OPT_shared)) {
+- CmdArgs.push_back("-shared");
+- } else {
+- CmdArgs.push_back("--dynamic-linker");
+- CmdArgs.push_back(
+- Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
+- }
++ CmdArgs.push_back("-m");
++ switch (ToolChain.getTriple().getArch()) {
++ case llvm::Triple::x86:
++ CmdArgs.push_back("elf_i386_sol2");
++ break;
++ case llvm::Triple::x86_64:
++ CmdArgs.push_back("elf_x86_64_sol2");
++ break;
++ default:
++ llvm_unreachable("Unsupported architecture");
+ }
+
++
+ if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+@@ -7447,7 +7520,7 @@ void solaris::Linker::ConstructJob(Compi
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+- if (getToolChain().getDriver().CCCIsCXX())
++ if (D.CCCIsCXX())
+ getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+ CmdArgs.push_back("-lgcc_s");
+ CmdArgs.push_back("-lc");
+@@ -7457,11 +7530,73 @@ void solaris::Linker::ConstructJob(Compi
+ }
+ }
+
+- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+- CmdArgs.push_back(
+- Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
++ bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
++ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
++ // The profile runtime also needs access to system libraries.
++ getToolChain().addProfileRTLibs(Args, CmdArgs);
++
++ if (D.CCCIsCXX() &&
++ !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
++ bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
++ !Args.hasArg(options::OPT_static);
++ if (OnlyLibstdcxxStatic)
++ CmdArgs.push_back("-Bstatic");
++ ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
++ if (OnlyLibstdcxxStatic)
++ CmdArgs.push_back("-Bdynamic");
++ CmdArgs.push_back("-lm");
++ }
++ // Silence warnings when linking C code with a C++ '-stdlib' argument.
++ Args.ClaimAllArgs(options::OPT_stdlib_EQ);
++
++ if (!Args.hasArg(options::OPT_nostdlib)) {
++ if (!Args.hasArg(options::OPT_nodefaultlibs)) {
++ if (Args.hasArg(options::OPT_static))
++ CmdArgs.push_back("--start-group");
++
++ if (NeedsSanitizerDeps)
++ linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
++
++ if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
++ options::OPT_fno_openmp, false)) {
++
++ // Also link the particular OpenMP runtimes.
++ switch (getOpenMPRuntime(ToolChain, Args)) {
++ case OMPRT_OMP:
++ CmdArgs.push_back("-lomp");
++ break;
++ case OMPRT_GOMP:
++ CmdArgs.push_back("-lgomp");
++ break;
++ case OMPRT_IOMP5:
++ CmdArgs.push_back("-liomp5");
++ break;
++ case OMPRT_Unknown:
++ // Already diagnosed.
++ break;
++ }
++ }
++
++ AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
++
++ CmdArgs.push_back("-lc");
++
++ if (Args.hasArg(options::OPT_static))
++ CmdArgs.push_back("--end-group");
++ else
++ AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
++ }
++
++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
++ CmdArgs.push_back(
++ Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
++ }
++ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
++
+ }
+- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
++
++ if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
++ CmdArgs.push_back("--no-demangle");
+
+ getToolChain().addProfileRTLibs(Args, CmdArgs);
+
+@@ -8585,40 +8720,6 @@ void gnutools::Assembler::ConstructJob(C
+ SplitDebugName(Args, Inputs[0]));
+ }
+
+-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
+- ArgStringList &CmdArgs, const ArgList &Args) {
+- bool isAndroid = Triple.isAndroid();
+- bool isCygMing = Triple.isOSCygMing();
+- bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
+- Args.hasArg(options::OPT_static);
+- if (!D.CCCIsCXX())
+- CmdArgs.push_back("-lgcc");
+-
+- if (StaticLibgcc || isAndroid) {
+- if (D.CCCIsCXX())
+- CmdArgs.push_back("-lgcc");
+- } else {
+- if (!D.CCCIsCXX() && !isCygMing)
+- CmdArgs.push_back("--as-needed");
+- CmdArgs.push_back("-lgcc_s");
+- if (!D.CCCIsCXX() && !isCygMing)
+- CmdArgs.push_back("--no-as-needed");
+- }
+-
+- if (StaticLibgcc && !isAndroid)
+- CmdArgs.push_back("-lgcc_eh");
+- else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
+- CmdArgs.push_back("-lgcc");
+-
+- // According to Android ABI, we have to link with libdl if we are
+- // linking with non-static libgcc.
+- //
+- // NOTE: This fixes a link error on Android MIPS as well. The non-static
+- // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
+- if (isAndroid && !StaticLibgcc)
+- CmdArgs.push_back("-ldl");
+-}
+-
+ static std::string getLinuxDynamicLinker(const ArgList &Args,
+ const toolchains::Linux &ToolChain) {
+ const llvm::Triple::ArchType Arch = ToolChain.getArch();
+@@ -8685,28 +8786,6 @@ static std::string getLinuxDynamicLinker
+ return "/lib64/ld-linux-x86-64.so.2";
+ }
+
+-static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
+- ArgStringList &CmdArgs, const ArgList &Args) {
+- // Make use of compiler-rt if --rtlib option is used
+- ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
+-
+- switch (RLT) {
+- case ToolChain::RLT_CompilerRT:
+- switch (TC.getTriple().getOS()) {
+- default:
+- llvm_unreachable("unsupported OS");
+- case llvm::Triple::Win32:
+- case llvm::Triple::Linux:
+- addClangRT(TC, Args, CmdArgs);
+- break;
+- }
+- break;
+- case ToolChain::RLT_Libgcc:
+- AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+- break;
+- }
+-}
+-
+ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
+ switch (T.getArch()) {
+ case llvm::Triple::x86:
+Index: llvm-toolchain-3.8-3.8.1/clang/lib/Driver/Tools.h
+===================================================================
+--- llvm-toolchain-3.8-3.8.1.orig/clang/lib/Driver/Tools.h
++++ llvm-toolchain-3.8-3.8.1/clang/lib/Driver/Tools.h
+@@ -620,7 +620,6 @@ public:
+ };
+ } // end namespace minix
+
+-/// solaris -- Directly call Solaris assembler and linker
+ namespace solaris {
+ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
+ public:
+Index: llvm-toolchain-3.8-3.8.1/clang/lib/Driver/ToolChains.h
+===================================================================
+--- llvm-toolchain-3.8-3.8.1.orig/clang/lib/Driver/ToolChains.h
++++ llvm-toolchain-3.8-3.8.1/clang/lib/Driver/ToolChains.h
+@@ -615,24 +615,6 @@ protected:
+ Tool *buildLinker() const override;
+ };
+
+-class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
+-public:
+- Solaris(const Driver &D, const llvm::Triple &Triple,
+- const llvm::opt::ArgList &Args);
+-
+- bool IsIntegratedAssemblerDefault() const override { return true; }
+-
+- void AddClangCXXStdlibIncludeArgs(
+- const llvm::opt::ArgList &DriverArgs,
+- llvm::opt::ArgStringList &CC1Args) const override;
+-
+- unsigned GetDefaultDwarfVersion() const override { return 2; }
+-
+-protected:
+- Tool *buildAssembler() const override;
+- Tool *buildLinker() const override;
+-};
+-
+ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
+ public:
+ MinGW(const Driver &D, const llvm::Triple &Triple,
+@@ -805,6 +787,26 @@ public:
+
+ protected:
+ Tool *buildAssembler() const override;
++ Tool *buildLinker() const override;
++};
++
++class LLVM_LIBRARY_VISIBILITY Solaris : public Linux {
++public:
++ Solaris(const Driver &D, const llvm::Triple &Triple,
++ const llvm::opt::ArgList &Args);
++
++ bool IsIntegratedAssemblerDefault() const override { return true; }
++
++ void AddClangCXXStdlibIncludeArgs(
++ const llvm::opt::ArgList &DriverArgs,
++ llvm::opt::ArgStringList &CC1Args) const override;
++
++ unsigned GetDefaultDwarfVersion() const override { return 2; }
++ // At Dyson PIE is not supported:
++ bool isPIEDefault() const override { return false; }
++
++protected:
++ Tool *buildAssembler() const override;
+ Tool *buildLinker() const override;
+ };
+
diff --git a/debian/patches/series b/debian/patches/series
index 9ba49d1..858faf8 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -55,3 +55,4 @@ upstream-asan-msan-fix-reallocation-logic.diff
lit-force-lang.diff
dyson-coreutils.patch
dyson-gnu-ld.patch
+dyson-toolchain.patch