From 8692af253c93c2f32b419a832e1cc2caf63669fb Mon Sep 17 00:00:00 2001 From: Siva Chandra Date: Tue, 21 May 2019 21:09:05 +0000 Subject: [PATCH] Let -static-pie win if it is specified along with -pie or -static. Also, disallow specifying -no-pie/-nopie along with -static-pie. Differential Revision: https://reviews.llvm.org/D59841 llvm-svn: 361312 --- .../clang/Basic/DiagnosticDriverKinds.td | 1 + clang/lib/Driver/ToolChains/Gnu.cpp | 35 +++++++++++++++---- clang/test/Driver/linux-ld.c | 33 +++++++++++++++++ 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 404650f688c6..9ce7def88e52 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -458,4 +458,5 @@ def warn_drv_libstdcxx_not_found : Warning< "command line to use the libc++ standard library instead">, InGroup>; +def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">; } diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index d233d443ba8a..30a61d5ad120 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -311,7 +311,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_r)) + Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) return false; Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, @@ -321,6 +321,26 @@ static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { return A->getOption().matches(options::OPT_pie); } +static bool getStaticPIE(const ArgList &Args, + const toolchains::Linux &ToolChain) { + bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); + // -no-pie is an alias for -nopie. So, handling -nopie takes care of + // -no-pie as well. + if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { + const Driver &D = ToolChain.getDriver(); + const llvm::opt::OptTable &Opts = D.getOpts(); + const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie); + const char *NoPIEName = Opts.getOptionName(options::OPT_nopie); + D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; + } + return HasStaticPIE; +} + +static bool getStatic(const ArgList &Args) { + return Args.hasArg(options::OPT_static) && + !Args.hasArg(options::OPT_static_pie); +} + void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -336,7 +356,8 @@ 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 IsStaticPIE = getStaticPIE(Args, ToolChain); + const bool IsStatic = getStatic(Args); const bool HasCRTBeginEndFiles = ToolChain.getTriple().hasEnvironment() || (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); @@ -408,7 +429,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, return; } - if (Args.hasArg(options::OPT_static)) { + if (IsStatic) { if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb) CmdArgs.push_back("-Bstatic"); @@ -418,7 +439,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-shared"); } - if (!Args.hasArg(options::OPT_static)) { + if (!IsStatic) { if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); @@ -465,7 +486,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, } if (P.empty()) { const char *crtbegin; - if (Args.hasArg(options::OPT_static)) + if (IsStatic) crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; else if (Args.hasArg(options::OPT_shared)) crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; @@ -520,7 +541,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) || IsStaticPIE) + if (IsStatic || IsStaticPIE) CmdArgs.push_back("--start-group"); if (NeedsSanitizerDeps) @@ -556,7 +577,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (IsIAMCU) CmdArgs.push_back("-lgloss"); - if (Args.hasArg(options::OPT_static) || IsStaticPIE) + if (IsStatic || IsStaticPIE) CmdArgs.push_back("--end-group"); else AddRunTimeLibs(ToolChain, D, CmdArgs, Args); diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index d592a1ccd212..e602c6c32373 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -194,6 +194,39 @@ // CHECK-CLANG-LD-STATIC-PIE: "{{.*}}rcrt1.o" // CHECK-CLANG-LD-STATIC-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" // +// RUN: %clang -static-pie -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-PIE %s +// CHECK-CLANG-LD-STATIC-PIE-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "-static" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "-pie" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "--no-dynamic-linker" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "-m" "elf_x86_64" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "{{.*}}rcrt1.o" +// CHECK-CLANG-LD-STATIC-PIE-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" +// +// RUN: %clang -static-pie -static -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-STATIC %s +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "-static" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "-pie" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "--no-dynamic-linker" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "-m" "elf_x86_64" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "{{.*}}rcrt1.o" +// CHECK-CLANG-LD-STATIC-PIE-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" +// +// RUN: %clang -static-pie -nopie -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-NOPIE %s +// CHECK-CLANG-LD-STATIC-PIE-NOPIE: error: cannot specify 'nopie' along with 'static-pie' +// // RUN: %clang -dynamic -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform \ // RUN: --gcc-toolchain="" \