Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -412,6 +412,9 @@ /// Test whether this toolchain defaults to PIE. virtual bool isPIEDefault() const = 0; + /// Test whether this toolchaind defaults to non-executable stacks. + virtual bool isNoExecStackDefault() const; + /// Tests whether this toolchain forces its default for PIC, PIE or /// non-PIC. If this returns true, any PIC related flags should be ignored /// and instead the results of \c isPICDefault() and \c isPIEDefault() are Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -112,6 +112,10 @@ return ENABLE_X86_RELAX_RELOCATIONS; } +bool ToolChain::isNoExecStackDefault() const { + return false; +} + const SanitizerArgs& ToolChain::getSanitizerArgs() const { if (!SanitizerArguments.get()) SanitizerArguments.reset(new SanitizerArgs(*this, Args)); Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -2053,6 +2053,7 @@ bool TakeNextArg = false; bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations(); + bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault(); const char *MipsTargetFeature = nullptr; for (const Arg *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { @@ -2134,7 +2135,7 @@ } else if (Value == "--fatal-warnings") { CmdArgs.push_back("-massembler-fatal-warnings"); } else if (Value == "--noexecstack") { - CmdArgs.push_back("-mnoexecstack"); + UseNoExecStack = true; } else if (Value.startswith("-compress-debug-sections") || Value.startswith("--compress-debug-sections") || Value == "-nocompress-debug-sections" || @@ -2197,6 +2198,8 @@ } if (UseRelaxRelocations) CmdArgs.push_back("--mrelax-relocations"); + if (UseNoExecStack) + CmdArgs.push_back("-mnoexecstack"); if (MipsTargetFeature != nullptr) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back(MipsTargetFeature); Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -360,6 +360,11 @@ CmdArgs.push_back("--no-dynamic-linker"); } + if (ToolChain.isNoExecStackDefault()) { + CmdArgs.push_back("-z"); + CmdArgs.push_back("noexecstack"); + } + if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); @@ -609,6 +614,10 @@ } } + if (getToolChain().isNoExecStackDefault()) { + CmdArgs.push_back("--noexecstack"); + } + switch (getToolChain().getArch()) { default: break; Index: lib/Driver/ToolChains/Linux.h =================================================================== --- lib/Driver/ToolChains/Linux.h +++ lib/Driver/ToolChains/Linux.h @@ -38,6 +38,7 @@ llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetDefaultCXXStdlibType() const override; bool isPIEDefault() const override; + bool isNoExecStackDefault() const override; bool IsMathErrnoDefault() const override; SanitizerMask getSupportedSanitizers() const override; void addProfileRTLibs(const llvm::opt::ArgList &Args, Index: lib/Driver/ToolChains/Linux.cpp =================================================================== --- lib/Driver/ToolChains/Linux.cpp +++ lib/Driver/ToolChains/Linux.cpp @@ -971,6 +971,10 @@ getTriple().isMusl() || getSanitizerArgs().requiresPIE(); } +bool Linux::isNoExecStackDefault() const { + return getTriple().isAndroid(); +} + bool Linux::IsMathErrnoDefault() const { if (getTriple().isAndroid()) return false; Index: test/Driver/integrated-as.c =================================================================== --- test/Driver/integrated-as.c +++ test/Driver/integrated-as.c @@ -13,3 +13,8 @@ // NOFIAS-NOT: cc1as // NOFIAS: -cc1 // NOFIAS: -no-integrated-as + +// RUN: %clang -target arm-linux-androideabi -### \ +// RUN: -integrated-as -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID %s +// CHECK-ARM-ANDROID: "-mnoexecstack" Index: test/Driver/linux-as.c =================================================================== --- test/Driver/linux-as.c +++ test/Driver/linux-as.c @@ -108,12 +108,12 @@ // RUN: %clang -target arm-linux-androideabi -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID %s -// CHECK-ARM-ANDROID: as{{(.exe)?}}" "-EL" "-mfloat-abi=soft" +// CHECK-ARM-ANDROID: as{{(.exe)?}}" "--noexecstack" "-EL" "-mfloat-abi=soft" // // RUN: %clang -target arm-linux-androideabi -march=armv7-a -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID-SOFTFP %s -// CHECK-ARM-ANDROID-SOFTFP: as{{(.exe)?}}" "-EL" "-mfloat-abi=softfp" "-march=armv7-a" +// CHECK-ARM-ANDROID-SOFTFP: as{{(.exe)?}}" "--noexecstack" "-EL" "-mfloat-abi=softfp" "-march=armv7-a" // // RUN: %clang -target arm-linux-eabi -mhard-float -### \ // RUN: -no-integrated-as -c %s 2>&1 \ Index: test/Driver/linux-ld.c =================================================================== --- test/Driver/linux-ld.c +++ test/Driver/linux-ld.c @@ -997,6 +997,15 @@ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-HASH-STYLE-M %s // CHECK-ANDROID-HASH-STYLE-M: "{{.*}}ld{{(.exe)?}}" // CHECK-ANDROID-HASH-STYLE-M: "--hash-style=gnu" + +// RUN: %clang %s -### -o %t.o 2>&1 \ +// RUN: --target=armv7-linux-android21 \ +// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NOEXECSTACK %s +// CHECK-ANDROID-NOEXECSTACK: "{{.*}}ld{{(.exe)?}}" +// CHECK-ANDROID-NOEXECSTACK: "-z" "noexecstack" +// CHECK-ANDROID-NOEXECSTACK-NOT: "-z" "execstack" +// CHECK-ANDROID-NOEXECSTACK-NOT: "-z,execstack" +// CHECK-ANDROID-NOEXECSTACK-NOT: "-zexecstack" // // RUN: %clang %s -### -o %t.o 2>&1 --target=mips64-linux-gnuabin32 \ // RUN: | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABIN32 %s