diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index dc14e7782c79a..6f85e245a002e 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -184,6 +184,17 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, #else Arguments.push_back(context.Args.MakeArgString("-fuse-ld=" + Linker)); #endif + // Starting with lld 13, Swift stopped working with the lld --gc-sections + // implementation for ELF, unless -z nostart-stop-gc is also passed to lld: + // + // https://reviews.llvm.org/D96914 + if (Linker == "lld" || (Linker.length() > 5 && + Linker.substr(Linker.length() - 6) == "ld.lld")) { + Arguments.push_back("-Xlinker"); + Arguments.push_back("-z"); + Arguments.push_back("-Xlinker"); + Arguments.push_back("nostart-stop-gc"); + } } // Configure the toolchain. diff --git a/test/Driver/link-time-opt.swift b/test/Driver/link-time-opt.swift index b0684b2425a9d..10d6fc8ca1b45 100644 --- a/test/Driver/link-time-opt.swift +++ b/test/Driver/link-time-opt.swift @@ -16,6 +16,7 @@ // CHECK-SIMPLE-THIN-linux-gnu: clang // CHECK-SIMPLE-THIN-linux-gnu-DAG: -flto=thin // CHECK-SIMPLE-THIN-linux-gnu-DAG: -fuse-ld=lld +// CHECK-SIMPLE-THIN-linux-gnu-DAG: -Xlinker -z -Xlinker nostart-stop-gc // CHECK-SIMPLE-THIN-linux-gnu-DAG: [[BITCODEFILE]] // CHECK-SIMPLE-THIN-linux-gnu-NOT: swift-autolink-extract @@ -37,6 +38,7 @@ // CHECK-SIMPLE-FULL-linux-gnu: clang // CHECK-SIMPLE-FULL-linux-gnu-DAG: -flto=full // CHECK-SIMPLE-FULL-linux-gnu-DAG: -fuse-ld=lld +// CHECK-SIMPLE-FULL-linux-gnu-DAG: -Xlinker -z -Xlinker nostart-stop-gc // CHECK-SIMPLE-FULL-linux-gnu-DAG: [[BITCODEFILE]] // CHECK-SIMPLE-FULL-linux-gnu-NOT: swift-autolink-extract