diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -47,11 +47,24 @@ Exec, CmdArgs, Inputs, Output)); } +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)) + return false; + + Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, + options::OPT_nopie); + if (!A) + return TC.isPIEDefault(Args); + return A->getOption().matches(options::OPT_pie); +} + void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + const bool IsPIE = getPIE(Args, getToolChain()); ArgStringList CmdArgs; // Demangle C++ names in errors @@ -62,6 +75,11 @@ CmdArgs.push_back("_start"); } + if (IsPIE) { + CmdArgs.push_back("-z"); + CmdArgs.push_back("type=pie"); + } + if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-Bstatic"); CmdArgs.push_back("-dn"); @@ -113,8 +131,13 @@ values_xpg = "values-xpg4.o"; CmdArgs.push_back( Args.MakeArgString(getToolChain().GetFilePath(values_xpg))); - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); + + const char *crtbegin = nullptr; + if (Args.hasArg(options::OPT_shared) || IsPIE) + crtbegin = "crtbeginS.o"; + else + crtbegin = "crtbegin.o"; + CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(crtbegin))); // Add crtfastmath.o if available and fast math is enabled. getToolChain().addFastMathRuntimeIfAvailable(Args, CmdArgs); } @@ -171,8 +194,12 @@ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, options::OPT_r)) { - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); + if (Args.hasArg(options::OPT_shared) || IsPIE) + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); + else + CmdArgs.push_back( + Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); CmdArgs.push_back( Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); } diff --git a/clang/test/Driver/Inputs/solaris_sparc_tree/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2/crtbeginS.o b/clang/test/Driver/Inputs/solaris_sparc_tree/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2/crtbeginS.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/solaris_sparc_tree/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2/sparcv9/crtbeginS.o b/clang/test/Driver/Inputs/solaris_sparc_tree/usr/gcc/4.8/lib/gcc/sparc-sun-solaris2.11/4.8.2/sparcv9/crtbeginS.o new file mode 100644 diff --git a/clang/test/Driver/solaris-ld.c b/clang/test/Driver/solaris-ld.c --- a/clang/test/Driver/solaris-ld.c +++ b/clang/test/Driver/solaris-ld.c @@ -106,6 +106,33 @@ // CHECK-SPARC32-SHARED-NOT: "-lgcc" // CHECK-SPARC32-SHARED-NOT: "-lm" +// Check the right ld flags are present with -pie. +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie \ +// 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: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s + +// Check that -shared/-r/-static disable PIE. +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie \ +// 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: --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: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOPIE %s + +// CHECK-PIE: "-z" "type=pie" +// CHECK-NOPIE-NOT: "-z" "type=pie" + // -r suppresses default -l and crt*.o, values-*.o like -nostdlib. // RUN: %clang -### %s --target=sparc-sun-solaris2.11 -r 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-RELOCATABLE @@ -115,6 +142,28 @@ // CHECK-RELOCATABLE-NOT: /crt{{[^.]+}}.o // CHECK-RELOCATABLE-NOT: /values-{{[^.]+}}.o +// Check that crt{begin,end}S.o is linked with -shared/-pie. +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTS %s +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTS %s +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -nopie \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOCRTS %s +// RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CRTS %s +// CHECK-CRTS: crtbeginS.o +// CHECK-CRTS: crtendS.o +// CHECK-NOCRTS-NOT: crtbeginS.o +// CHECK-NOCRTS-NOT: crtendS.o + // Check that crtfastmath.o is linked with -ffast-math. // Check sparc-sun-solaris2.11, 32bit