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,
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,
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);
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");
CmdArgs.push_back("-shared");
}
- if (!Args.hasArg(options::OPT_static)) {
+ if (!IsStatic) {
if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
}
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";
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)
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);
// 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="" \