diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2019-04-11 22:52:30 -0400 |
---|---|---|
committer | Matthew Bauer <mjbauer95@gmail.com> | 2019-04-12 13:19:48 -0400 |
commit | 6794b0165846373f07d5254354a1b86709e66daf (patch) | |
tree | 37317d7be38f2281f766fa5e15908598185a9146 /pkgs/development/compilers/llvm | |
parent | d453273fbf86ff1526094a84b01ef8fb9fad98e3 (diff) | |
download | nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar.gz nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar.bz2 nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar.lz nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar.xz nixlib-6794b0165846373f07d5254354a1b86709e66daf.tar.zst nixlib-6794b0165846373f07d5254354a1b86709e66daf.zip |
clang 8, lldClangStdenv: Get LLVM's unwind working properly
Backport the `--unwindlib` flag, so it don't try to use libgcc on Linux for hysterical reasons. The alternative of passing `-lunwind` always would mess up C.
Diffstat (limited to 'pkgs/development/compilers/llvm')
4 files changed, 538 insertions, 1 deletions
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/default.nix b/pkgs/development/compilers/llvm/8/default.nix index 5cd3bdfbe7b6..3503e6b83d2e 100644 --- a/pkgs/development/compilers/llvm/8/default.nix +++ b/pkgs/development/compilers/llvm/8/default.nix @@ -97,11 +97,13 @@ let 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; }; |