[llvm] d39a9e3 - [Driver] Support GNU ld on Solaris
Rainer Orth via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 1 12:42:56 PDT 2023
Author: Rainer Orth
Date: 2023-09-01T21:42:05+02:00
New Revision: d39a9e3b4d4afc0321fea72b9d6b8a3908c45fc1
URL: https://github.com/llvm/llvm-project/commit/d39a9e3b4d4afc0321fea72b9d6b8a3908c45fc1
DIFF: https://github.com/llvm/llvm-project/commit/d39a9e3b4d4afc0321fea72b9d6b8a3908c45fc1.diff
LOG: [Driver] Support GNU ld on Solaris
This patch supports GNU ld on Solaris in addition to Solaris ld, the
default.
- Linker selection is dynamic: one can switch between Solaris ld and GNU ld
at runtime, with the default selectable with `-DCLANG_DEFAULT_LINKER`.
- Testcases have been adjusted to test both variants in case there are
differences.
- The `compiler-rt/cmake/config-ix.cmake` and
`llvm/cmake/modules/AddLLVM.cmake` changes to restrict the tests to
Solaris ld are necessary because GNU accepts unknown `-z` options, but
warns every time they are used, creating a lot of noise. Since there
seems to be no way to check for those warnings in
`llvm_check_compiler_linker_flag` or `llvm_check_compiler_linker_flag`, I
restrict the cmake tests to Solaris ld in the first place.
- The changes to `clang/test/Driver/hip-link-bundle-archive.hip` and
`flang/test/Driver/linker-flags.f90` are required when LLVM is built with
`-DCLANG_DEFAULT_LINKER=gld` on Solaris: `MSVC.cpp`
`visualstudio::Linker::ConstructJob` ultimately calls
`GetProgramPath("gld")`, resulting in a search for `gld`, which exists in
`/usr/bin/gld` on Solaris. With `-fuse-ld=`, this doesn't happen and the
expected `link` is returned.
- `compiler-rt/test/asan/TestCases/global-location-nodebug.cpp` needs to
enforce the Solaris ld, otherwise the test would `XPASS` with GNU ld
which has the `-S` semantics expected by the test.
Tested on `amd64-pc-solaris2.11` and `sparcv9-sun-solaris2.11` with both
`-DCLANG_DEFAULT_LINKER=gld` and the default, and `x86_64-pc-linux-gnu`.
No regressions in either case.
Differential Revision: https://reviews.llvm.org/D85309
Added:
Modified:
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/Solaris.cpp
clang/lib/Driver/ToolChains/Solaris.h
clang/test/Driver/hip-link-bundle-archive.hip
clang/test/Driver/solaris-ld-sanitizer.c
clang/test/Driver/solaris-ld.c
compiler-rt/cmake/config-ix.cmake
compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
flang/test/Driver/linker-flags.f90
llvm/cmake/modules/AddLLVM.cmake
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 4daca7ba5fc9544..37db5a2740011d4 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -22,6 +22,7 @@
#include "HIPAMD.h"
#include "Hexagon.h"
#include "MSP430.h"
+#include "Solaris.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
@@ -993,9 +994,11 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs,
StringRef Sanitizer) {
+ bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
+
// Solaris ld defaults to --export-dynamic behaviour but doesn't support
// the option, so don't try to pass it.
- if (TC.getTriple().getOS() == llvm::Triple::Solaris)
+ if (TC.getTriple().getOS() == llvm::Triple::Solaris && !LinkerIsGnuLd)
return true;
SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
if (llvm::sys::fs::exists(SanRT + ".syms")) {
@@ -1011,11 +1014,14 @@ void tools::addAsNeededOption(const ToolChain &TC,
bool as_needed) {
assert(!TC.getTriple().isOSAIX() &&
"AIX linker does not support any form of --as-needed option yet.");
+ bool LinkerIsGnuLd = solaris::isLinkerGnuLd(TC, Args);
// While the Solaris 11.2 ld added --as-needed/--no-as-needed as aliases
// for the native forms -z ignore/-z record, they are missing in Illumos,
// so always use the native form.
- if (TC.getTriple().isOSSolaris()) {
+ // GNU ld doesn't support -z ignore/-z record, so don't use them even on
+ // Solaris.
+ if (TC.getTriple().isOSSolaris() && !LinkerIsGnuLd) {
CmdArgs.push_back("-z");
CmdArgs.push_back(as_needed ? "ignore" : "record");
} else {
diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp
index 1a7839d739655d7..a22e4c2e47b87e6 100644
--- a/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -16,6 +16,7 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -47,6 +48,13 @@ void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
Exec, CmdArgs, Inputs, Output));
}
+bool solaris::isLinkerGnuLd(const ToolChain &TC, const ArgList &Args) {
+ // Only used if targetting Solaris.
+ const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
+ StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
+ return UseLinker == "bfd" || UseLinker == "gld";
+}
+
static bool getPIE(const ArgList &Args, const ToolChain &TC) {
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_r))
@@ -59,6 +67,32 @@ static bool getPIE(const ArgList &Args, const ToolChain &TC) {
return A->getOption().matches(options::OPT_pie);
}
+// FIXME: Need to handle CLANG_DEFAULT_LINKER here?
+std::string solaris::Linker::getLinkerPath(const ArgList &Args) const {
+ const ToolChain &ToolChain = getToolChain();
+ if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+ StringRef UseLinker = A->getValue();
+ if (!UseLinker.empty()) {
+ if (llvm::sys::path::is_absolute(UseLinker) &&
+ llvm::sys::fs::can_execute(UseLinker))
+ return std::string(UseLinker);
+
+ // Accept 'bfd' and 'gld' as aliases for the GNU linker.
+ if (UseLinker == "bfd" || UseLinker == "gld")
+ // FIXME: Could also use /usr/bin/gld here.
+ return "/usr/gnu/bin/ld";
+
+ // Accept 'ld' as alias for the default linker
+ if (UseLinker != "ld")
+ ToolChain.getDriver().Diag(diag::err_drv_invalid_linker_name)
+ << A->getAsString(Args);
+ }
+ }
+
+ // getDefaultLinker() always returns an absolute path.
+ return ToolChain.getDefaultLinker();
+}
+
void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -66,9 +100,11 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const char *LinkingOutput) const {
const bool IsPIE = getPIE(Args, getToolChain());
ArgStringList CmdArgs;
+ bool LinkerIsGnuLd = isLinkerGnuLd(getToolChain(), Args);
- // Demangle C++ names in errors
- CmdArgs.push_back("-C");
+ // Demangle C++ names in errors. GNU ld already defaults to --demangle.
+ if (!LinkerIsGnuLd)
+ CmdArgs.push_back("-C");
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
CmdArgs.push_back("-e");
@@ -76,8 +112,12 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
if (IsPIE) {
- CmdArgs.push_back("-z");
- CmdArgs.push_back("type=pie");
+ if (LinkerIsGnuLd) {
+ CmdArgs.push_back("-pie");
+ } else {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("type=pie");
+ }
}
if (Args.hasArg(options::OPT_static)) {
@@ -95,6 +135,42 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Args.ClaimAllArgs(options::OPT_pthreads);
}
+ if (LinkerIsGnuLd) {
+ // Set the correct linker emulation for 32- and 64-bit Solaris.
+ const toolchains::Solaris &ToolChain =
+ static_cast<const toolchains::Solaris &>(getToolChain());
+ const llvm::Triple::ArchType Arch = ToolChain.getArch();
+
+ switch (Arch) {
+ case llvm::Triple::x86:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf_i386_sol2");
+ break;
+ case llvm::Triple::x86_64:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf_x86_64_sol2");
+ break;
+ case llvm::Triple::sparc:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf32_sparc_sol2");
+ break;
+ case llvm::Triple::sparcv9:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf64_sparc_sol2");
+ break;
+ default:
+ break;
+ }
+
+ if (Args.hasArg(options::OPT_rdynamic))
+ CmdArgs.push_back("-export-dynamic");
+
+ CmdArgs.push_back("--eh-frame-hdr");
+ } else {
+ // -rdynamic is a no-op with Solaris ld. Claim argument to avoid warning.
+ Args.ClaimAllArgs(options::OPT_rdynamic);
+ }
+
if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
@@ -183,7 +259,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// in Illumos.
if (getToolChain().getTriple().getArch() == llvm::Triple::x86_64 &&
(SA.needsAsanRt() || SA.needsStatsRt() ||
- (SA.needsUbsanRt() && !SA.requiresMinimalRuntime()))) {
+ (SA.needsUbsanRt() && !SA.requiresMinimalRuntime())) &&
+ !LinkerIsGnuLd) {
CmdArgs.push_back("-z");
CmdArgs.push_back("relax=transtls");
}
@@ -210,7 +287,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().addProfileRTLibs(Args, CmdArgs);
- const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
+ const char *Exec = Args.MakeArgString(getLinkerPath(Args));
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
Exec, CmdArgs, Inputs, Output));
}
@@ -271,6 +348,13 @@ SanitizerMask Solaris::getSupportedSanitizers() const {
return Res;
}
+const char *Solaris::getDefaultLinker() const {
+ // FIXME: Only handle Solaris ld and GNU ld here.
+ return llvm::StringSwitch<const char *>(CLANG_DEFAULT_LINKER)
+ .Cases("bfd", "gld", "/usr/gnu/bin/ld")
+ .Default("/usr/bin/ld");
+}
+
Tool *Solaris::buildAssembler() const {
return new tools::solaris::Assembler(*this);
}
diff --git a/clang/lib/Driver/ToolChains/Solaris.h b/clang/lib/Driver/ToolChains/Solaris.h
index 9023bf7c37c522e..fe3e7f3a1f1b994 100644
--- a/clang/lib/Driver/ToolChains/Solaris.h
+++ b/clang/lib/Driver/ToolChains/Solaris.h
@@ -32,12 +32,15 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
const char *LinkingOutput) const override;
};
+bool isLinkerGnuLd(const ToolChain &TC, const llvm::opt::ArgList &Args);
+
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
public:
Linker(const ToolChain &TC) : Tool("solaris::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
+ std::string getLinkerPath(const llvm::opt::ArgList &Args) const;
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
@@ -64,10 +67,7 @@ class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_ELF {
SanitizerMask getSupportedSanitizers() const override;
- const char *getDefaultLinker() const override {
- // clang currently uses Solaris ld-only options.
- return "/usr/bin/ld";
- }
+ const char *getDefaultLinker() const override;
protected:
Tool *buildAssembler() const override;
diff --git a/clang/test/Driver/hip-link-bundle-archive.hip b/clang/test/Driver/hip-link-bundle-archive.hip
index 7da7b91d1e62510..dd1d779fe19a876 100644
--- a/clang/test/Driver/hip-link-bundle-archive.hip
+++ b/clang/test/Driver/hip-link-bundle-archive.hip
@@ -56,17 +56,17 @@
// RUN: llvm-ar cr %t/hipBundled2.lib %t/dummy.bc
// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \
-// RUN: --target=x86_64-pc-windows-msvc \
+// RUN: --target=x86_64-pc-windows-msvc -fuse-ld= \
// RUN: -nogpuinc -nogpulib %s -fgpu-rdc -L%t -lhipBundled2 \
// RUN: 2>&1 | FileCheck -check-prefix=MSVC %s
// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \
-// RUN: --target=x86_64-pc-windows-msvc \
+// RUN: --target=x86_64-pc-windows-msvc -fuse-ld= \
// RUN: -nogpuinc -nogpulib %s -fgpu-rdc -L%t -l:hipBundled2.lib \
// RUN: 2>&1 | FileCheck -check-prefix=MSVC %s
// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \
-// RUN: --target=x86_64-pc-windows-msvc \
+// RUN: --target=x86_64-pc-windows-msvc -fuse-ld= \
// RUN: -nogpuinc -nogpulib %s -fgpu-rdc %t/hipBundled2.lib \
// RUN: 2>&1 | FileCheck -check-prefix=MSVC %s
diff --git a/clang/test/Driver/solaris-ld-sanitizer.c b/clang/test/Driver/solaris-ld-sanitizer.c
index af98f94b0de10ac..a59164787cada13 100644
--- a/clang/test/Driver/solaris-ld-sanitizer.c
+++ b/clang/test/Driver/solaris-ld-sanitizer.c
@@ -3,55 +3,55 @@
/// independent of the host system.
/// Check sparc-sun-solaris2.11, 32bit
-// RUN: %clang --target=sparc-sun-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32 %s
-// CHECK-LD-SPARC32-NOT: "-z" "relax=transtls"
+// RUN: %clang --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check sparc-sun-solaris2.11, 32bit
-// RUN: %clang -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32 %s
-// CHECK-LD-SPARC32-NOT: "-z" "relax=transtls"
+// RUN: %clang -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check sparc-sun-solaris2.11, 64bit
-// RUN: %clang -m64 --target=sparc-sun-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-SPARC64 %s
-// CHECK-LD-SPARC64-NOT: "-z" "relax=transtls"
+// RUN: %clang -m64 --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check sparc-sun-solaris2.11, 64bit
-// RUN: %clang -m64 -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-SPARC64 %s
-// CHECK-LD-SPARC64-NOT: "-z" "relax=transtls"
+// RUN: %clang -m64 -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check i386-pc-solaris2.11, 32bit
-// RUN: %clang --target=i386-pc-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-X32 %s
-// CHECK-LD-X32-NOT: "-z" "relax=transtls"
+// RUN: %clang --target=i386-pc-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check i386-pc-solaris2.11, 32bit
-// RUN: %clang -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-X32 %s
-// CHECK-LD-X32-NOT: "-z" "relax=transtls"
+// RUN: %clang -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
/// Check i386-pc-solaris2.11, 64bit
-// RUN: %clang -m64 --target=i386-pc-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-X64 %s
-// CHECK-LD-X64-NOT: "-z" "relax=transtls"
+// RUN: %clang -m64 --target=i386-pc-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LD %s
+
+// CHECK-LD-NOT: "-z" "relax=transtls"
/// Check i386-pc-solaris2.11, 64bit
-// RUN: %clang -m64 -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### 2>&1 \
-// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \
+// RUN: %clang -m64 -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld= \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-LD-X64-UBSAN %s
+// RUN: %clang -m64 -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld=gld \
+// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-GLD-X64-UBSAN %s
+
// CHECK-LD-X64-UBSAN: "-z" "relax=transtls"
+// CHECK-GLD-X64-UBSAN-NOT: "-z" "relax=transtls"
/// General tests that the ld -z now workaround is only applied on
-/// Solaris/i386 with shared libclang_rt.asan.. Note that we use sysroot to
+/// Solaris/i386 with shared libclang_rt.asan. Note that we use sysroot to
/// make these tests independent of the host system.
/// Check i386-pc-solaris2.11, 32bit, shared libclang_rt.asan
diff --git a/clang/test/Driver/solaris-ld.c b/clang/test/Driver/solaris-ld.c
index 3c1de12b16d1cd0..096ecadbbd60a6d 100644
--- a/clang/test/Driver/solaris-ld.c
+++ b/clang/test/Driver/solaris-ld.c
@@ -2,10 +2,14 @@
// sysroot to make these tests independent of the host system.
// Check sparc-sun-solaris2.11, 32bit
-// RUN: %clang -### %s 2>&1 --target=sparc-sun-solaris2.11 \
+// RUN: %clang -### %s --target=sparc-sun-solaris2.11 -fuse-ld= \
// RUN: --gcc-toolchain="" \
-// RUN: --sysroot=%S/Inputs/solaris_sparc_tree \
-// RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32 %s
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefixes=CHECK-LD-SPARC32,CHECK-LD %s
+// RUN: %clang -### %s --target=sparc-sun-solaris2.11 -fuse-ld=gld \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefixes=CHECK-LD-SPARC32,CHECK-GLD %s
// CHECK-LD-SPARC32-NOT: warning:
// CHECK-LD-SPARC32: "-cc1" "-triple" "sparc-sun-solaris2.11"
// CHECK-LD-SPARC32-SAME: "-isysroot" "[[SYSROOT:[^"]+]]"
@@ -16,7 +20,8 @@
// CHECK-LD-SPARC32-SAME: "-L[[SYSROOT]]/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2"
// CHECK-LD-SPARC32-SAME: "-L[[SYSROOT]]/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2/../../.."
// CHECK-LD-SPARC32-SAME: "-L[[SYSROOT]]/usr/lib"
-// CHECK-LD-SPARC32-SAME: "-z" "ignore" "-latomic" "-z" "record"
+// CHECK-LD: "-z" "ignore" "-latomic" "-z" "record"
+// CHECK-GLD: "--as-needed" "-latomic" "--no-as-needed"
// CHECK-LD-SPARC32-SAME: "-lgcc_s"
// CHECK-LD-SPARC32-SAME: "-lc"
// CHECK-LD-SPARC32-SAME: "-lgcc"
@@ -107,31 +112,53 @@
// CHECK-SPARC32-SHARED-NOT: "-lm"
// Check the right ld flags are present with -pie.
-// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie \
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie -fuse-ld= \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-PIE %s
-// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -nopie \
+// RUN: | FileCheck --check-prefix=CHECK-PIE-LD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie -fuse-ld=gld \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-PIE-GLD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -nopie -fuse-ld= \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -nopie -fuse-ld=gld \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s
// Check that -shared/-r/-static disable PIE.
-// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie \
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie -fuse-ld= \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie -fuse-ld=gld \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie -fuse-ld= \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie -fuse-ld=gld \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s
-// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie -fuse-ld= \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s
-// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie \
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s
+// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie -fuse-ld=gld \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s
+// RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s
-// CHECK-PIE: "-z" "type=pie"
-// CHECK-NOPIE-NOT: "-z" "type=pie"
+// CHECK-PIE-LD: "-z" "type=pie"
+// CHECK-PIE-GLD: "-pie"
+// CHECK-NOPIE-LD-NOT: "-z" "type=pie"
+// CHECK-NOPIE-GLD-NOT: "-pie"
// -r suppresses default -l and crt*.o, values-*.o like -nostdlib.
// RUN: %clang -### %s --target=sparc-sun-solaris2.11 -r 2>&1 \
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 8d3dc8d208b25d1..09a9b62ce4cd37b 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -1,4 +1,5 @@
include(CMakePushCheckState)
+include(AddLLVM)
include(LLVMCheckCompilerLinkerFlag)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
@@ -196,7 +197,7 @@ check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX)
llvm_check_compiler_linker_flag(C "-Wl,-z,text" COMPILER_RT_HAS_Z_TEXT)
llvm_check_compiler_linker_flag(C "-fuse-ld=lld" COMPILER_RT_HAS_FUSE_LD_LLD_FLAG)
-if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
+if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND LLVM_LINKER_IS_SOLARISLD)
set(VERS_COMPAT_OPTION "-Wl,-z,gnu-version-script-compat")
llvm_check_compiler_linker_flag(C "${VERS_COMPAT_OPTION}" COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
endif()
diff --git a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
index edbff7c303107aa..07c8e63f439da47 100644
--- a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
+++ b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
@@ -2,13 +2,14 @@
/// allow this test to also run on Windows (which can't be done for the
/// debuginfo variant).
-// RUN: %clangxx_asan -O2 %S/global-location.cpp -o %t %if target={{.*-windows-msvc.*}} %{ -Wl,/DEBUG:NONE %} %else %{ -Wl,-S %}
+// RUN: %clangxx_asan -O2 %S/global-location.cpp -o %t %if target={{.*-windows-msvc.*}} %{ -Wl,/DEBUG:NONE %} %else %{ -Wl,-S %} %if target={{.*-solaris.*}} %{ -fuse-ld= %}
// RUN: not %run %t g 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=GLOB-NO-G
// RUN: not %run %t c 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CLASS_STATIC-NO-G
// RUN: not %run %t f 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=FUNC_STATIC-NO-G
// RUN: not %run %t l 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=LITERAL-NO-G
-/// Solaris ld -S has
diff erent semantics.
+/// Solaris ld -S has
diff erent semantics, so enforce -fuse-ld= for
+/// configurations that default to GNU ld.
// XFAIL: target={{.*solaris.*}}
// CHECK: AddressSanitizer: global-buffer-overflow
diff --git a/flang/test/Driver/linker-flags.f90 b/flang/test/Driver/linker-flags.f90
index 910d246237f7984..09b8a224df13828 100644
--- a/flang/test/Driver/linker-flags.f90
+++ b/flang/test/Driver/linker-flags.f90
@@ -10,7 +10,7 @@
! 'oldnames' on Windows, but they are not needed when compiling
! Fortran code and they might bring in additional dependencies.
! Make sure they're not added.
-! RUN: %flang -### -target aarch64-windows-msvc %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not libcmt --implicit-check-not oldnames
+! RUN: %flang -### -target aarch64-windows-msvc -fuse-ld= %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MSVC --implicit-check-not libcmt --implicit-check-not oldnames
! Compiler invocation to generate the object file
! CHECK-LABEL: {{.*}} "-emit-obj"
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index a9aed212e5678fa..77b4a51b13b8ca9 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -282,9 +282,9 @@ function(add_link_opts target_name)
# ld64's implementation of -dead_strip breaks tools that use plugins.
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-dead_strip")
- elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND LLVM_LINKER_IS_SOLARISLD)
# Support for ld -z discard-unused=sections was only added in
- # Solaris 11.4.
+ # Solaris 11.4. GNU ld ignores it, but warns every time.
include(LLVMCheckLinkerFlag)
llvm_check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED)
if (LINKER_SUPPORTS_Z_DISCARD_UNUSED)
@@ -1281,7 +1281,10 @@ function(export_executable_symbols target)
# the size of the exported symbol table, but on other platforms we can do
# it without any trouble.
set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
- if (APPLE)
+ # CMake doesn't set CMAKE_EXE_EXPORTS_${lang}_FLAG on Solaris, so
+ # ENABLE_EXPORTS has no effect. While Solaris ld defaults to -rdynamic
+ # behaviour, GNU ld needs it.
+ if (APPLE OR ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
set_property(TARGET ${target} APPEND_STRING PROPERTY
LINK_FLAGS " -rdynamic")
endif()
More information about the llvm-commits
mailing list