mgorny updated this revision to Diff 183729.
mgorny added a comment.
Ok, here's my proposition of using trinary enum.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D56554/new/
https://reviews.llvm.org/D56554
Files:
ELF/Config.h
ELF/Driver.cpp
ELF/Writer.cpp
docs/ld.lld.1
test/ELF/gnustack.s
Index: test/ELF/gnustack.s
===================================================================
--- test/ELF/gnustack.s
+++ test/ELF/gnustack.s
@@ -10,6 +10,9 @@
# RUN: ld.lld %t1 -o %t -z noexecstack
# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
+# RUN: ld.lld %t1 -o %t -z nognustack
+# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=NOGNUSTACK %s
+
# RW: Type: PT_GNU_STACK
# RW-NEXT: Offset: 0x0
# RW-NEXT: VirtualAddress: 0x0
@@ -35,5 +38,7 @@
# RWX-NEXT: ]
# RWX-NEXT: Alignment: 0
+# NOGNUSTACK-NOT: Type: PT_GNU_STACK
+
.globl _start
_start:
Index: docs/ld.lld.1
===================================================================
--- docs/ld.lld.1
+++ docs/ld.lld.1
@@ -509,6 +509,10 @@
.Dv DF_1_NOOPEN
flag to indicate that the object may not be opened by
.Xr dlopen 3 .
+.It Cm nognustack
+Do not emit the
+.Dv PT_GNU_STACK
+segment.
.It Cm norelro
Do not indicate that portions of the object shold be mapped read-only
after initial relocation processing.
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1976,14 +1976,16 @@
if (OutputSection *Cmd = findSection(".openbsd.randomdata"))
AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd);
- // PT_GNU_STACK is a special section to tell the loader to make the
- // pages for the stack non-executable. If you really want an executable
- // stack, you can pass -z execstack, but that's not recommended for
- // security reasons.
- unsigned Perm = PF_R | PF_W;
- if (Config->ZExecstack)
- Perm |= PF_X;
- AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
+ if (Config->ZGnustack != GnuStackKind::None) {
+ // PT_GNU_STACK is a special section to tell the loader to make the
+ // pages for the stack non-executable. If you really want an executable
+ // stack, you can pass -z execstack, but that's not recommended for
+ // security reasons.
+ unsigned Perm = PF_R | PF_W;
+ if (Config->ZGnustack == GnuStackKind::Exec)
+ Perm |= PF_X;
+ AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
+ }
// PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
// is expected to perform W^X violations, such as calling mprotect(2) or
Index: ELF/Driver.cpp
===================================================================
--- ELF/Driver.cpp
+++ ELF/Driver.cpp
@@ -345,6 +345,20 @@
return Default;
}
+static GnuStackKind getZGnuStack(opt::InputArgList &Args) {
+ for (auto *Arg : Args.filtered_reverse(OPT_z)) {
+ if (StringRef("execstack") == Arg->getValue())
+ return GnuStackKind::Exec;
+ else if (StringRef("noexecstack") == Arg->getValue())
+ return GnuStackKind::NoExec;
+ else if (StringRef("nognustack") == Arg->getValue())
+ return GnuStackKind::None;
+ }
+
+ // default
+ return GnuStackKind::NoExec;
+}
+
static bool isKnownZFlag(StringRef S) {
return S == "combreloc" || S == "copyreloc" || S == "defs" ||
S == "execstack" || S == "global" || S == "hazardplt" ||
@@ -352,6 +366,7 @@
S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
+ S == "nognustack" ||
S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
S == "rodynamic" || S == "text" || S == "wxneeded" ||
@@ -868,8 +883,8 @@
Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
- Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
Config->ZGlobal = hasZOption(Args, "global");
+ Config->ZGnustack = getZGnuStack(Args);
Config->ZHazardplt = hasZOption(Args, "hazardplt");
Config->ZInitfirst = hasZOption(Args, "initfirst");
Config->ZInterpose = hasZOption(Args, "interpose");
Index: ELF/Config.h
===================================================================
--- ELF/Config.h
+++ ELF/Config.h
@@ -61,6 +61,9 @@
// For tracking ARM Float Argument PCS
enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
+// For -z *stack
+enum class GnuStackKind { None, Exec, NoExec };
+
struct SymbolVersion {
llvm::StringRef Name;
bool IsExternCpp;
@@ -184,8 +187,8 @@
bool WriteAddends;
bool ZCombreloc;
bool ZCopyreloc;
- bool ZExecstack;
bool ZGlobal;
+ GnuStackKind ZGnustack;
bool ZHazardplt;
bool ZInitfirst;
bool ZInterpose;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits