Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -2508,6 +2508,7 @@ def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; def p : Flag<["-"], "p">; def pie : Flag<["-"], "pie">; +def static_pie : Flag<["-"], "static-pie">; def read__only__relocs : Separate<["-"], "read_only_relocs">; def remap : Flag<["-"], "remap">; def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>, Index: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp +++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp @@ -1137,19 +1137,22 @@ bool isCygMing = Triple.isOSCygMing(); bool IsIAMCU = Triple.isOSIAMCU(); bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) || - Args.hasArg(options::OPT_static); + Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_static_pie); bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc); bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc; // Gcc adds libgcc arguments in various ways: // - // gcc : -lgcc --as-needed -lgcc_s --no-as-needed - // g++ : -lgcc_s -lgcc - // gcc shared: -lgcc_s -lgcc - // g++ shared: -lgcc_s -lgcc - // gcc static: -lgcc -lgcc_eh - // g++ static: -lgcc -lgcc_eh + // gcc : -lgcc --as-needed -lgcc_s --no-as-needed + // g++ : -lgcc_s -lgcc + // gcc shared: -lgcc_s -lgcc + // g++ shared: -lgcc_s -lgcc + // gcc static: -lgcc -lgcc_eh + // g++ static: -lgcc -lgcc_eh + // gcc static-pie: -lgcc -lgcc_eh + // g++ static-pie: -lgcc -lgcc_eh // // Also, certain targets need additional adjustments. Index: cfe/trunk/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/Gnu.cpp +++ cfe/trunk/lib/Driver/ToolChains/Gnu.cpp @@ -333,6 +333,7 @@ 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 HasCRTBeginEndFiles = ToolChain.getTriple().hasEnvironment() || (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); @@ -353,6 +354,12 @@ if (IsPIE) CmdArgs.push_back("-pie"); + if (IsStaticPIE) { + CmdArgs.push_back("-static"); + CmdArgs.push_back("-pie"); + CmdArgs.push_back("--no-dynamic-linker"); + } + if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); @@ -402,7 +409,7 @@ if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); - if (!Args.hasArg(options::OPT_shared)) { + if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE) { const std::string Loader = D.DyldPrefix + ToolChain.getDynamicLinker(Args); CmdArgs.push_back("-dynamic-linker"); @@ -421,6 +428,8 @@ crt1 = "gcrt1.o"; else if (IsPIE) crt1 = "Scrt1.o"; + else if (IsStaticPIE) + crt1 = "rcrt1.o"; else crt1 = "crt1.o"; } @@ -438,14 +447,14 @@ crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; else if (Args.hasArg(options::OPT_shared)) crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; - else if (IsPIE) + else if (IsPIE || IsStaticPIE) crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; else crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; if (HasCRTBeginEndFiles) CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); - } + } // Add crtfastmath.o if available and fast math is enabled. ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs); @@ -489,7 +498,7 @@ if (!Args.hasArg(options::OPT_nostdlib)) { if (!Args.hasArg(options::OPT_nodefaultlibs)) { - if (Args.hasArg(options::OPT_static)) + if (Args.hasArg(options::OPT_static) || IsStaticPIE) CmdArgs.push_back("--start-group"); if (NeedsSanitizerDeps) @@ -525,7 +534,7 @@ if (IsIAMCU) CmdArgs.push_back("-lgloss"); - if (Args.hasArg(options::OPT_static)) + if (Args.hasArg(options::OPT_static) || IsStaticPIE) CmdArgs.push_back("--end-group"); else AddRunTimeLibs(ToolChain, D, CmdArgs, Args); @@ -542,7 +551,7 @@ const char *crtend; if (Args.hasArg(options::OPT_shared)) crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; - else if (IsPIE) + else if (IsPIE || IsStaticPIE) crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; else crtend = isAndroid ? "crtend_android.o" : "crtend.o"; Index: cfe/trunk/test/Driver/linux-ld.c =================================================================== --- cfe/trunk/test/Driver/linux-ld.c +++ cfe/trunk/test/Driver/linux-ld.c @@ -176,6 +176,19 @@ // CHECK-CLANG-NO-LIBGCC-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-CLANG-NO-LIBGCC-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" // +// RUN: %clang -static-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 %s +// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-CLANG-LD-STATIC-PIE: "-static" +// CHECK-CLANG-LD-STATIC-PIE: "-pie" +// CHECK-CLANG-LD-STATIC-PIE: "--no-dynamic-linker" +// CHECK-CLANG-LD-STATIC-PIE: "-m" "elf_x86_64" +// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}rcrt1.o" +// CHECK-CLANG-LD-STATIC-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" +// // RUN: %clang -dynamic -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform \ // RUN: --gcc-toolchain="" \