about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix4
-rw-r--r--pkgs/development/compilers/llvm/8/clang/default.nix8
-rw-r--r--pkgs/development/compilers/llvm/8/clang/static-pie.patch157
-rw-r--r--pkgs/development/compilers/llvm/8/clang/unwindlib.patch372
-rw-r--r--pkgs/development/compilers/llvm/8/compiler-rt.nix4
-rw-r--r--pkgs/development/compilers/llvm/8/default.nix74
-rw-r--r--pkgs/development/compilers/llvm/8/libc++/default.nix3
-rw-r--r--pkgs/development/compilers/llvm/8/libc++abi.nix7
-rw-r--r--pkgs/development/compilers/llvm/8/libunwind.nix22
-rw-r--r--pkgs/development/libraries/kerberos/krb5.nix3
-rw-r--r--pkgs/stdenv/cross/default.nix2
-rw-r--r--pkgs/top-level/all-packages.nix2
12 files changed, 633 insertions, 25 deletions
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index f05b9fb22555..9569c6e78c8a 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -45,9 +45,9 @@ let
   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
   coreutils_bin = if nativeTools then "" else getBin coreutils;
 
-  default_cxx_stdlib_compile = if (targetPlatform.isLinux && !(cc.isGNU or false) && !nativeTools && cc ? gcc) then
+  default_cxx_stdlib_compile = if (targetPlatform.isLinux && !(cc.isGNU or false) && !nativeTools && cc ? gcc) && !(targetPlatform.useLLVM or false) then
     "-isystem $(echo -n ${cc.gcc}/include/c++/*) -isystem $(echo -n ${cc.gcc}/include/c++/*)/$(${cc.gcc}/bin/gcc -dumpmachine)"
-  else if targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false) then
+  else if targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false) && !(targetPlatform.useLLVM or false) then
     "-isystem ${libcxx}/include/c++/v1"
   else "";
 
diff --git a/pkgs/development/compilers/llvm/8/clang/default.nix b/pkgs/development/compilers/llvm/8/clang/default.nix
index 353e113ddb9a..8709e47dd3aa 100644
--- a/pkgs/development/compilers/llvm/8/clang/default.nix
+++ b/pkgs/development/compilers/llvm/8/clang/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetch, cmake, libxml2, llvm, version, clang-tools-extra_src, python
+{ stdenv, fetch, fetchpatch, cmake, libxml2, llvm, version, clang-tools-extra_src, python
 , fixDarwinDylibNames
 , enableManpages ? false
 , enablePolly ? false # TODO: get this info from llvm (passthru?)
@@ -39,6 +39,12 @@ let
     patches = [
       ./purity.patch
       ./clang-xpc.patch
+      # Backport for -static-pie, which the latter touches, and which is nice in
+      # its own right.
+      ./static-pie.patch
+      # Backport for the `--unwindlib=[libgcc|complier-rt]` flag, which is
+      # needed for our bootstrapping to not interfere with C.
+      ./unwindlib.patch
     ];
 
     postPatch = ''
diff --git a/pkgs/development/compilers/llvm/8/clang/static-pie.patch b/pkgs/development/compilers/llvm/8/clang/static-pie.patch
new file mode 100644
index 000000000000..d1f86a162327
--- /dev/null
+++ b/pkgs/development/compilers/llvm/8/clang/static-pie.patch
@@ -0,0 +1,157 @@
+commit 7a9842bc92921e79b84630045276861be90b2d47
+Author: Siva Chandra <sivachandra@google.com>
+Date:   Wed Feb 20 19:07:04 2019 +0000
+
+    [Clang Driver] Add support for "-static-pie" argument to the Clang driver.
+    
+    Summary: This change mimics GCC's support for the "-static-pie" argument.
+    
+    Subscribers: cfe-commits
+    
+    Tags: #clang
+    
+    Differential Revision: https://reviews.llvm.org/D58307
+    
+    git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354502 91177308-0d34-0410-b5e6-96231b3b80d8
+    (cherry picked from commit 7d6cd7825e6883f8650e32b07f3750824c2cef62)
+
+diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
+index d02d9744d7..75a21e66c7 100644
+--- a/include/clang/Driver/Options.td
++++ b/include/clang/Driver/Options.td
+@@ -2502,6 +2502,7 @@ def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>,
+ def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>;
+ def p : Flag<["-"], "p">;
+ def pie : Flag<["-"], "pie">;
++def static_pie : Flag<["-"], "static-pie">;
+ def read__only__relocs : Separate<["-"], "read_only_relocs">;
+ def remap : Flag<["-"], "remap">;
+ def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>,
+diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
+index d7e316befa..85ffc1618d 100644
+--- a/lib/Driver/ToolChains/CommonArgs.cpp
++++ b/lib/Driver/ToolChains/CommonArgs.cpp
+@@ -1138,19 +1138,22 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
+   bool isCygMing = Triple.isOSCygMing();
+   bool IsIAMCU = Triple.isOSIAMCU();
+   bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
+-                      Args.hasArg(options::OPT_static);
++                      Args.hasArg(options::OPT_static) ||
++                      Args.hasArg(options::OPT_static_pie);
+ 
+   bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
+   bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
+ 
+   // Gcc adds libgcc arguments in various ways:
+   //
+-  // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
+-  // g++ <none>:                   -lgcc_s               -lgcc
+-  // gcc shared:                   -lgcc_s               -lgcc
+-  // g++ shared:                   -lgcc_s               -lgcc
+-  // gcc static: -lgcc             -lgcc_eh
+-  // g++ static: -lgcc             -lgcc_eh
++  // gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
++  // g++ <none>:                       -lgcc_s               -lgcc
++  // gcc shared:                       -lgcc_s               -lgcc
++  // g++ shared:                       -lgcc_s               -lgcc
++  // gcc static:     -lgcc             -lgcc_eh
++  // g++ static:     -lgcc             -lgcc_eh
++  // gcc static-pie: -lgcc             -lgcc_eh
++  // g++ static-pie: -lgcc             -lgcc_eh
+   //
+   // Also, certain targets need additional adjustments.
+ 
+diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
+index 69dba8fec8..0faa0bb473 100644
+--- a/lib/Driver/ToolChains/Gnu.cpp
++++ b/lib/Driver/ToolChains/Gnu.cpp
+@@ -334,6 +334,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+   const bool isAndroid = ToolChain.getTriple().isAndroid();
+   const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+   const bool IsPIE = getPIE(Args, ToolChain);
++  const bool IsStaticPIE = Args.hasArg(options::OPT_static_pie);
+   const bool HasCRTBeginEndFiles =
+       ToolChain.getTriple().hasEnvironment() ||
+       (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
+@@ -354,6 +355,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+   if (IsPIE)
+     CmdArgs.push_back("-pie");
+ 
++  if (IsStaticPIE) {
++    CmdArgs.push_back("-static");
++    CmdArgs.push_back("-pie");
++    CmdArgs.push_back("--no-dynamic-linker");
++  }
++
+   if (Args.hasArg(options::OPT_rdynamic))
+     CmdArgs.push_back("-export-dynamic");
+ 
+@@ -415,6 +422,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+           crt1 = "gcrt1.o";
+         else if (IsPIE)
+           crt1 = "Scrt1.o";
++        else if (IsStaticPIE)
++          crt1 = "rcrt1.o";
+         else
+           crt1 = "crt1.o";
+       }
+@@ -432,7 +441,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+         crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
+       else if (Args.hasArg(options::OPT_shared))
+         crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
+-      else if (IsPIE)
++      else if (IsPIE || IsStaticPIE)
+         crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
+       else
+         crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
+@@ -483,7 +492,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ 
+   if (!Args.hasArg(options::OPT_nostdlib)) {
+     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+-      if (Args.hasArg(options::OPT_static))
++      if (Args.hasArg(options::OPT_static) || IsStaticPIE)
+         CmdArgs.push_back("--start-group");
+ 
+       if (NeedsSanitizerDeps)
+@@ -518,7 +527,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+       if (IsIAMCU)
+         CmdArgs.push_back("-lgloss");
+ 
+-      if (Args.hasArg(options::OPT_static))
++      if (Args.hasArg(options::OPT_static) || IsStaticPIE)
+         CmdArgs.push_back("--end-group");
+       else
+         AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+@@ -535,7 +544,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+       const char *crtend;
+       if (Args.hasArg(options::OPT_shared))
+         crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
+-      else if (IsPIE)
++      else if (IsPIE || IsStaticPIE)
+         crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
+       else
+         crtend = isAndroid ? "crtend_android.o" : "crtend.o";
+diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
+index 3ab81be490..800f782523 100644
+--- a/test/Driver/linux-ld.c
++++ b/test/Driver/linux-ld.c
+@@ -176,6 +176,19 @@
+ // CHECK-CLANG-NO-LIBGCC-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+ // CHECK-CLANG-NO-LIBGCC-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+ //
++// RUN: %clang -static-pie -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux -rtlib=platform \
++// RUN:     --gcc-toolchain="" \
++// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
++// RUN:   | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE %s
++// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
++// CHECK-CLANG-LD-STATIC-PIE: "-static"
++// CHECK-CLANG-LD-STATIC-PIE: "-pie"
++// CHECK-CLANG-LD-STATIC-PIE: "--no-dynamic-linker"
++// CHECK-CLANG-LD-STATIC-PIE: "-m" "elf_x86_64"
++// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}rcrt1.o"
++// CHECK-CLANG-LD-STATIC-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
++//
+ // RUN: %clang -dynamic -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+ // RUN:     --target=x86_64-unknown-linux -rtlib=platform \
+ // RUN:     --gcc-toolchain="" \
diff --git a/pkgs/development/compilers/llvm/8/clang/unwindlib.patch b/pkgs/development/compilers/llvm/8/clang/unwindlib.patch
new file mode 100644
index 000000000000..6958fce60cef
--- /dev/null
+++ b/pkgs/development/compilers/llvm/8/clang/unwindlib.patch
@@ -0,0 +1,372 @@
+commit cd5603a4767277a29d3e67a9c3f2a5d2129cd973
+Author: Sterling Augustine <saugustine@google.com>
+Date:   Tue Mar 19 20:01:59 2019 +0000
+
+    Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]
+    
+    "clang++ hello.cc --rtlib=compiler-rt"
+    
+    now can works without specifying additional unwind or exception
+    handling libraries.
+    
+    This reworked version of the feature no longer modifies today's default
+    unwind library for compiler-rt: which is nothing. Rather, a user
+    can specify -DCLANG_DEFAULT_UNWINDLIB=libunwind when configuring
+    the compiler.
+    
+    This should address the issues from the previous version.
+    
+    Update tests for new --unwindlib semantics.
+    
+    Differential Revision: https://reviews.llvm.org/D59109
+    
+    git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356508 91177308-0d34-0410-b5e6-96231b3b80d8
+    (cherry picked from commit 344aa82a52f2fae527f58284567ae305a314f7a8)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index c2016a45ca..edeb2b66a1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -261,6 +261,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR
+     "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
+ endif()
+ 
++set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
++  "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
++if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
++  if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
++    set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
++  elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
++    set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
++  endif()
++endif()
++
++if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
++        CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
++        CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
++  message(WARNING "Resetting default unwindlib to use platform default")
++  set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
++    "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
++endif()
++
+ set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
+   "Default objcopy executable to use.")
+ 
+diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
+index 5475e28ed7..15971210e4 100644
+--- a/include/clang/Basic/DiagnosticDriverKinds.td
++++ b/include/clang/Basic/DiagnosticDriverKinds.td
+@@ -52,6 +52,10 @@ def err_drv_invalid_rtlib_name : Error<
+   "invalid runtime library name in argument '%0'">;
+ def err_drv_unsupported_rtlib_for_platform : Error<
+   "unsupported runtime library '%0' for platform '%1'">;
++def err_drv_invalid_unwindlib_name : Error<
++  "invalid unwind library name in argument '%0'">;
++def err_drv_incompatible_unwindlib : Error<
++  "--rtlib=libgcc requires --unwindlib=libgcc">;
+ def err_drv_invalid_stdlib_name : Error<
+   "invalid library name in argument '%0'">;
+ def err_drv_invalid_output_with_multiple_archs : Error<
+diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
+index 1d624450b9..2d4cb747e8 100644
+--- a/include/clang/Config/config.h.cmake
++++ b/include/clang/Config/config.h.cmake
+@@ -23,6 +23,9 @@
+ /* Default runtime library to use. */
+ #define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
+ 
++/* Default unwind library to use. */
++#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
++
+ /* Default objcopy to use */
+ #define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
+ 
+diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
+index 75a21e66c7..4da0e54965 100644
+--- a/include/clang/Driver/Options.td
++++ b/include/clang/Driver/Options.td
+@@ -2570,6 +2570,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
+   }]>;
+ def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
+   HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
++def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
++  HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
+ def sub__library : JoinedOrSeparate<["-"], "sub_library">;
+ def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
+ def system_header_prefix : Joined<["--"], "system-header-prefix=">,
+diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
+index d5f75b8271..4bedf760eb 100644
+--- a/include/clang/Driver/ToolChain.h
++++ b/include/clang/Driver/ToolChain.h
+@@ -100,6 +100,12 @@ public:
+     RLT_Libgcc
+   };
+ 
++  enum UnwindLibType {
++    UNW_None,
++    UNW_CompilerRT,
++    UNW_Libgcc
++  };
++
+   enum RTTIMode {
+     RM_Enabled,
+     RM_Disabled,
+@@ -368,6 +374,10 @@ public:
+     return ToolChain::CST_Libstdcxx;
+   }
+ 
++  virtual UnwindLibType GetDefaultUnwindLibType() const {
++    return ToolChain::UNW_None;
++  }
++
+   virtual std::string getCompilerRTPath() const;
+ 
+   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
+@@ -512,6 +522,10 @@ public:
+   // given compilation arguments.
+   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+ 
++  // GetUnwindLibType - Determine the unwind library type to use with the
++  // given compilation arguments.
++  virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
++
+   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
+   /// the include paths to use for the given C++ standard library type.
+   virtual void
+diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
+index 88a627eab6..d82423f4a8 100644
+--- a/lib/Driver/ToolChain.cpp
++++ b/lib/Driver/ToolChain.cpp
+@@ -680,6 +680,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
+   return GetDefaultRuntimeLibType();
+ }
+ 
++ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
++    const ArgList &Args) const {
++  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
++  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
++
++  if (LibName == "none")
++    return ToolChain::UNW_None;
++  else if (LibName == "platform" || LibName == "") {
++    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
++    if (RtLibType == ToolChain::RLT_CompilerRT)
++      return ToolChain::UNW_None;
++    else if (RtLibType == ToolChain::RLT_Libgcc)
++      return ToolChain::UNW_Libgcc;
++  } else if (LibName == "libunwind") {
++    if (GetRuntimeLibType(Args) == RLT_Libgcc)
++      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
++    return ToolChain::UNW_CompilerRT;
++  } else if (LibName == "libgcc")
++    return ToolChain::UNW_Libgcc;
++
++  if (A)
++    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
++        << A->getAsString(Args);
++
++  return GetDefaultUnwindLibType();
++}
++
+ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
+   const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+   StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
+diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
+index 85ffc1618d..9fd29726a4 100644
+--- a/lib/Driver/ToolChains/CommonArgs.cpp
++++ b/lib/Driver/ToolChains/CommonArgs.cpp
+@@ -1132,47 +1132,80 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
+   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
+ }
+ 
+-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
+-                      ArgStringList &CmdArgs, const ArgList &Args) {
+-  bool isAndroid = Triple.isAndroid();
+-  bool isCygMing = Triple.isOSCygMing();
+-  bool IsIAMCU = Triple.isOSIAMCU();
+-  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
+-                      Args.hasArg(options::OPT_static) ||
+-                      Args.hasArg(options::OPT_static_pie);
+-
+-  bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
+-  bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
+-
+-  // Gcc adds libgcc arguments in various ways:
+-  //
+-  // gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
+-  // g++ <none>:                       -lgcc_s               -lgcc
+-  // gcc shared:                       -lgcc_s               -lgcc
+-  // g++ shared:                       -lgcc_s               -lgcc
+-  // gcc static:     -lgcc             -lgcc_eh
+-  // g++ static:     -lgcc             -lgcc_eh
+-  // gcc static-pie: -lgcc             -lgcc_eh
+-  // g++ static-pie: -lgcc             -lgcc_eh
+-  //
+-  // Also, certain targets need additional adjustments.
++enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
++
++static LibGccType getLibGccType(const ArgList &Args) {
++  bool Static = Args.hasArg(options::OPT_static_libgcc) ||
++                Args.hasArg(options::OPT_static) ||
++                Args.hasArg(options::OPT_static_pie);
++
++  bool Shared = Args.hasArg(options::OPT_shared_libgcc);
++  if (Shared)
++    return LibGccType::SharedLibGcc;
++  if (Static)
++    return LibGccType::StaticLibGcc;
++  return LibGccType::UnspecifiedLibGcc;
++}
+ 
+-  bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc;
+-  if (LibGccFirst)
+-    CmdArgs.push_back("-lgcc");
++// Gcc adds libgcc arguments in various ways:
++//
++// gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
++// g++ <none>:                       -lgcc_s               -lgcc
++// gcc shared:                       -lgcc_s               -lgcc
++// g++ shared:                       -lgcc_s               -lgcc
++// gcc static:     -lgcc             -lgcc_eh
++// g++ static:     -lgcc             -lgcc_eh
++// gcc static-pie: -lgcc             -lgcc_eh
++// g++ static-pie: -lgcc             -lgcc_eh
++//
++// Also, certain targets need additional adjustments.
++
++static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
++                             ArgStringList &CmdArgs, const ArgList &Args) {
++  ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
++  // Targets that don't use unwind libraries.
++  if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
++      TC.getTriple().isOSBinFormatWasm() ||
++      UNW == ToolChain::UNW_None)
++    return;
+ 
+-  bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
++  LibGccType LGT = getLibGccType(Args);
++  bool AsNeeded = D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc &&
++                  !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
+   if (AsNeeded)
+     CmdArgs.push_back("--as-needed");
+ 
+-  if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid)
+-    CmdArgs.push_back("-lgcc_s");
+-
+-  else if (StaticLibgcc && !isAndroid && !IsIAMCU)
+-    CmdArgs.push_back("-lgcc_eh");
++  switch (UNW) {
++  case ToolChain::UNW_None:
++    return;
++  case ToolChain::UNW_Libgcc: {
++    LibGccType LGT = getLibGccType(Args);
++    if (LGT == LibGccType::UnspecifiedLibGcc || LGT == LibGccType::SharedLibGcc)
++      CmdArgs.push_back("-lgcc_s");
++    else if (LGT == LibGccType::StaticLibGcc)
++      CmdArgs.push_back("-lgcc_eh");
++    break;
++  }
++  case ToolChain::UNW_CompilerRT:
++    CmdArgs.push_back("-lunwind");
++    break;
++  }
+ 
+   if (AsNeeded)
+     CmdArgs.push_back("--no-as-needed");
++}
++
++static void AddLibgcc(const ToolChain &TC, const Driver &D,
++                      ArgStringList &CmdArgs, const ArgList &Args) {
++  bool isAndroid = TC.getTriple().isAndroid();
++
++  LibGccType LGT = getLibGccType(Args);
++  bool LibGccFirst = (D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc) ||
++                     LGT == LibGccType::StaticLibGcc;
++  if (LibGccFirst)
++    CmdArgs.push_back("-lgcc");
++
++  AddUnwindLibrary(TC, D, CmdArgs, Args);
+ 
+   if (!LibGccFirst)
+     CmdArgs.push_back("-lgcc");
+@@ -1182,7 +1215,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
+   //
+   // 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)
++  if (isAndroid && getLibGccType(Args) != LibGccType::StaticLibGcc)
+     CmdArgs.push_back("-ldl");
+ }
+ 
+@@ -1194,6 +1227,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
+   switch (RLT) {
+   case ToolChain::RLT_CompilerRT:
+     CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
++    AddUnwindLibrary(TC, D, CmdArgs, Args);
+     break;
+   case ToolChain::RLT_Libgcc:
+     // Make sure libgcc is not used under MSVC environment by default
+@@ -1205,7 +1239,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
+             << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
+       }
+     } else
+-      AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
++      AddLibgcc(TC, D, CmdArgs, Args);
+     break;
+   }
+ }
+diff --git a/test/Driver/compiler-rt-unwind.c b/test/Driver/compiler-rt-unwind.c
+new file mode 100644
+index 0000000000..00024dfa7e
+--- /dev/null
++++ b/test/Driver/compiler-rt-unwind.c
+@@ -0,0 +1,49 @@
++// General tests that the driver handles combinations of --rtlib=XXX and
++// --unwindlib=XXX properly.
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-EMPTY %s
++// RTLIB-EMPTY: "{{.*}}lgcc"
++// RTLIB-EMPTY: "{{.*}}-lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-GCC %s
++// RTLIB-GCC: "{{.*}}lgcc"
++// RTLIB-GCC: "{{.*}}lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
++// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
++// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
++// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
++// RUN:     --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
++//
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1              \
++// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
++// RUN:     -static --gcc-toolchain="" \
++// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
++// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
++//
++// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err              \
++// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
++// RUN:     --gcc-toolchain="" \
++// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
++// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"
diff --git a/pkgs/development/compilers/llvm/8/compiler-rt.nix b/pkgs/development/compilers/llvm/8/compiler-rt.nix
index 4965b57b0d73..47c8b7bd59f5 100644
--- a/pkgs/development/compilers/llvm/8/compiler-rt.nix
+++ b/pkgs/development/compilers/llvm/8/compiler-rt.nix
@@ -55,9 +55,9 @@ stdenv.mkDerivation rec {
   # Hack around weird upsream RPATH bug
   postInstall = stdenv.lib.optionalString stdenv.isDarwin ''
     ln -s "$out/lib"/*/* "$out/lib"
-  '' + stdenv.lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
+  '' + stdenv.lib.optionalString (stdenv.hostPlatform.useLLVM or false) ''
     ln -s $out/lib/*/clang_rt.crtbegin-*.o $out/lib/crtbegin.o
-    ln -s $out/lib/*/cclang_rt.crtend-*.o $out/lib/crtend.o
+    ln -s $out/lib/*/clang_rt.crtend-*.o $out/lib/crtend.o
     ln -s $out/lib/*/clang_rt.crtbegin_shared-*.o $out/lib/crtbeginS.o
     ln -s $out/lib/*/clang_rt.crtend_shared-*.o $out/lib/crtendS.o
   '';
diff --git a/pkgs/development/compilers/llvm/8/default.nix b/pkgs/development/compilers/llvm/8/default.nix
index c5f2163450fe..3503e6b83d2e 100644
--- a/pkgs/development/compilers/llvm/8/default.nix
+++ b/pkgs/development/compilers/llvm/8/default.nix
@@ -23,7 +23,7 @@ let
       ln -s "${cc}/lib/clang/${release_version}/include" "$rsrc"
       ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
       echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
-    '' + stdenv.lib.optionalString (stdenv.targetPlatform.isLinux && tools.clang-unwrapped ? gcc) ''
+    '' + stdenv.lib.optionalString (stdenv.targetPlatform.isLinux && tools.clang-unwrapped ? gcc && !(stdenv.targetPlatform.useLLVM or false)) ''
       echo "--gcc-toolchain=${tools.clang-unwrapped.gcc}" >> $out/nix-support/cc-cflags
     '';
   in {
@@ -78,48 +78,80 @@ let
 
     lldb = callPackage ./lldb.nix {};
 
+    # Below, is the LLVM bootstrapping logic. It handles building a
+    # fully LLVM toolchain from scratch. No GCC toolchain should be
+    # pulled in. As a consequence, it is very quick to build different
+    # targets provided by LLVM and we can also build for what GCC
+    # doesn’t support like LLVM. Probably we should move to some other
+    # file.
+
     bintools = callPackage ./bintools.nix {};
 
     lldClang = wrapCCWith rec {
       cc = tools.clang-unwrapped;
+      libcxx = targetLlvmLibraries.libcxx;
+      bintools = wrapBintoolsWith {
+        inherit (tools) bintools;
+      };
+      extraPackages = [
+        targetLlvmLibraries.libcxx
+        targetLlvmLibraries.libcxxabi
+        targetLlvmLibraries.compiler-rt
+        targetLlvmLibraries.libunwind
+      ];
+      extraBuildCommands = ''
+        echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
+        echo "-rtlib=compiler-rt -Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags
+        echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
+        echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags
+      '' + mkExtraBuildCommands cc;
+    };
+
+    lldClangNoLibcxx = wrapCCWith rec {
+      cc = tools.clang-unwrapped;
+      libcxx = null;
       bintools = wrapBintoolsWith {
         inherit (tools) bintools;
       };
       extraPackages = [
-        # targetLlvmLibraries.libcxx
-        # targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
       ];
       extraBuildCommands = ''
-        echo "-target ${stdenv.targetPlatform.config} -rtlib=compiler-rt" >> $out/nix-support/cc-cflags
+        echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
+        echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
+        echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
+        echo "-nostdlib++" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands cc;
     };
 
     lldClangNoLibc = wrapCCWith rec {
       cc = tools.clang-unwrapped;
+      libcxx = null;
       bintools = wrapBintoolsWith {
         inherit (tools) bintools;
         libc = null;
       };
       extraPackages = [
-        # targetLlvmLibraries.libcxx
-        # targetLlvmLibraries.libcxxabi
         targetLlvmLibraries.compiler-rt
       ];
       extraBuildCommands = ''
-        echo "-target ${stdenv.targetPlatform.config} -rtlib=compiler-rt" >> $out/nix-support/cc-cflags
+        echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
+        echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
+        echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
       '' + mkExtraBuildCommands cc;
     };
 
     lldClangNoCompilerRt = wrapCCWith rec {
       cc = tools.clang-unwrapped;
+      libcxx = null;
       bintools = wrapBintoolsWith {
         inherit (tools) bintools;
         libc = null;
       };
       extraPackages = [ ];
       extraBuildCommands = ''
-        echo "-nostartfiles -target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
+        echo "-nostartfiles" >> $out/nix-support/cc-cflags
+        echo "-target ${stdenv.targetPlatform.config}" >> $out/nix-support/cc-cflags
       '';
     };
 
@@ -129,21 +161,33 @@ let
     callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python isl release_version version fetch; });
   in {
 
-    compiler-rt = callPackage ./compiler-rt.nix {
-      stdenv = if stdenv.hostPlatform.useLLVM or false
-               then overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt
-               else stdenv;
-    };
+    compiler-rt = callPackage ./compiler-rt.nix ({} //
+      (stdenv.lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) {
+        stdenv = overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt;
+      }));
 
     stdenv = overrideCC stdenv buildLlvmTools.clang;
 
     libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang;
 
-    libcxx = callPackage ./libc++ {};
+    libcxx = callPackage ./libc++ ({} //
+      (stdenv.lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) {
+        stdenv = overrideCC stdenv buildLlvmTools.lldClangNoLibcxx;
+      }));
 
-    libcxxabi = callPackage ./libc++abi.nix {};
+    libcxxabi = callPackage ./libc++abi.nix ({} //
+      (stdenv.lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) {
+        stdenv = overrideCC stdenv buildLlvmTools.lldClangNoLibcxx;
+        libunwind = libraries.libunwind;
+      }));
 
     openmp = callPackage ./openmp.nix {};
+
+    libunwind = callPackage ./libunwind.nix ({} //
+      (stdenv.lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) {
+        stdenv = overrideCC stdenv buildLlvmTools.lldClangNoLibcxx;
+      }));
+
   });
 
 in { inherit tools libraries; } // libraries // tools
diff --git a/pkgs/development/compilers/llvm/8/libc++/default.nix b/pkgs/development/compilers/llvm/8/libc++/default.nix
index 84db33209ebd..d0a5c37c4148 100644
--- a/pkgs/development/compilers/llvm/8/libc++/default.nix
+++ b/pkgs/development/compilers/llvm/8/libc++/default.nix
@@ -30,7 +30,8 @@ stdenv.mkDerivation rec {
     "-DLIBCXX_LIBCXXABI_LIB_PATH=${libcxxabi}/lib"
     "-DLIBCXX_LIBCPPABI_VERSION=2"
     "-DLIBCXX_CXX_ABI=libcxxabi"
-  ] ++ stdenv.lib.optional stdenv.hostPlatform.isMusl "-DLIBCXX_HAS_MUSL_LIBC=1";
+  ] ++ stdenv.lib.optional stdenv.hostPlatform.isMusl "-DLIBCXX_HAS_MUSL_LIBC=1"
+    ++ stdenv.lib.optional (stdenv.hostPlatform.useLLVM or false) "-DLIBCXX_USE_COMPILER_RT=ON";
 
   enableParallelBuilding = true;
 
diff --git a/pkgs/development/compilers/llvm/8/libc++abi.nix b/pkgs/development/compilers/llvm/8/libc++abi.nix
index 976c289e5bc5..0eb5ebca5159 100644
--- a/pkgs/development/compilers/llvm/8/libc++abi.nix
+++ b/pkgs/development/compilers/llvm/8/libc++abi.nix
@@ -8,10 +8,15 @@ stdenv.mkDerivation {
   nativeBuildInputs = [ cmake ];
   buildInputs = stdenv.lib.optional (!stdenv.isDarwin && !stdenv.isFreeBSD) libunwind;
 
+  cmakeFlags = stdenv.lib.optionals (stdenv.hostPlatform.useLLVM or false) [
+    "-DLLVM_ENABLE_LIBCXX=ON"
+    "-DLIBCXXABI_USE_LLVM_UNWINDER=ON"
+  ];
+
   postUnpack = ''
     unpackFile ${libcxx.src}
     unpackFile ${llvm.src}
-    export cmakeFlags="-DLLVM_PATH=$PWD/$(ls -d llvm-*) -DLIBCXXABI_LIBCXX_PATH=$PWD/$(ls -d libcxx-*)"
+    cmakeFlags+=" -DLLVM_PATH=$PWD/$(ls -d llvm-*) -DLIBCXXABI_LIBCXX_PATH=$PWD/$(ls -d libcxx-*)"
   '' + stdenv.lib.optionalString stdenv.isDarwin ''
     export TRIPLE=x86_64-apple-darwin
   '' + stdenv.lib.optionalString stdenv.hostPlatform.isMusl ''
diff --git a/pkgs/development/compilers/llvm/8/libunwind.nix b/pkgs/development/compilers/llvm/8/libunwind.nix
new file mode 100644
index 000000000000..a187d0adc994
--- /dev/null
+++ b/pkgs/development/compilers/llvm/8/libunwind.nix
@@ -0,0 +1,22 @@
+{ stdenv, version, fetch, cmake, libcxx, fetchpatch }:
+
+stdenv.mkDerivation {
+  name = "libunwind-${version}";
+
+  src = fetch "libunwind" "0q7ndlldid9wchnny0a936llwxj7zgb9gxp46wjjxvwwkik3l97z";
+
+  nativeBuildInputs = [ cmake ];
+
+  patches = [
+    (fetchpatch {
+      url = "https://github.com/llvm-mirror/libunwind/commit/34a45c630d4c79af403661d267db42fbe7de1178.patch";
+      sha256 = "0n0pv6jvcky8pn3srhrf9x5kbnd0d2kia9xlx2g590f5q0bgwfhv";
+    })
+    (fetchpatch {
+      url = "https://github.com/llvm-mirror/libunwind/commit/e050272d2eb57eb4e56a37b429a61df2ebb8aa3e.patch";
+      sha256 = "1sxyx5xnax8k713jjcxgq3jq3cpnxygs2rcdf5vfja0f2k9jzldl";
+    })
+  ];
+
+  enableParallelBuilding = true;
+}
diff --git a/pkgs/development/libraries/kerberos/krb5.nix b/pkgs/development/libraries/kerberos/krb5.nix
index a2b78231f745..208f294aef7e 100644
--- a/pkgs/development/libraries/kerberos/krb5.nix
+++ b/pkgs/development/libraries/kerberos/krb5.nix
@@ -39,8 +39,9 @@ stdenv.mkDerivation rec {
     ++ optional (!libOnly) yacc
     # Provides the mig command used by the build scripts
     ++ optional stdenv.isDarwin bootstrap_cmds;
+
   buildInputs = [ openssl ]
-    ++ optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.libc != "bionic") [ keyutils ]
+    ++ optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.libc != "bionic" && !(stdenv.hostPlatform.useLLVM or false)) [ keyutils ]
     ++ optionals (!libOnly) [ openldap libedit ];
 
   preConfigure = "cd ./src";
diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix
index 43198f4e913a..fc9a585cf4d6 100644
--- a/pkgs/stdenv/cross/default.nix
+++ b/pkgs/stdenv/cross/default.nix
@@ -55,7 +55,7 @@ in lib.init bootStages ++ [
            else if crossSystem.useAndroidPrebuilt or false
              then buildPackages."androidndkPkgs_${crossSystem.ndkVer}".clang
            else if crossSystem.useLLVM or false
-             then buildPackages.llvmPackages_7.lldClang
+             then buildPackages.llvmPackages_8.lldClang
            else buildPackages.gcc;
 
       extraNativeBuildInputs = old.extraNativeBuildInputs
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index d0f27ff6f614..237902c9ce4d 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -6989,7 +6989,7 @@ in
 
   crossLibcStdenv = overrideCC stdenv
     (if stdenv.targetPlatform.useLLVM or false
-     then buildPackages.llvmPackages_7.lldClangNoLibc
+     then buildPackages.llvmPackages_8.lldClangNoLibc
      else buildPackages.gccCrossStageStatic);
 
   # The GCC used to build libc for the target platform. Normal gccs will be