[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
This commit is contained in:
Rainer Orth 2023-09-01 21:42:05 +02:00
parent f9f2fdcf03
commit d39a9e3b4d
10 changed files with 191 additions and 69 deletions

View File

@ -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 {

View File

@ -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);
}

View File

@ -32,12 +32,15 @@ public:
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 @@ public:
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;

View File

@ -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

View File

@ -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

View File

@ -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-NOPIE %s
// 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-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 %s
// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie \
// 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 %s
// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie \
// 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 %s
// 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-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-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-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 \

View File

@ -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()

View File

@ -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 different semantics.
/// Solaris ld -S has different semantics, so enforce -fuse-ld= for
/// configurations that default to GNU ld.
// XFAIL: target={{.*solaris.*}}
// CHECK: AddressSanitizer: global-buffer-overflow

View File

@ -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"

View File

@ -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()