summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-01-28 09:31:12 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-01-28 09:31:12 +0000
commit9707d88efadcdb547df32453ab9c60297f444296 (patch)
treee963f28134ae251830cff28772610178288b6259
parent6fcd795046e4ceb652faa82b2447ccf96b8146a0 (diff)
On i386, produce binaries that are compatible with our W^X implementation.
Note that this will still produce binaries that have the read-only segment placed before the executable segment. This means that on machines without the NX bit, the read-only segment is now executable. However on machines with an NX bit, the ordering used by lld means the program headers are no longer executable since they are now part of the read-only segment. ok deraadt@, naddy@
-rw-r--r--gnu/llvm/tools/lld/ELF/Writer.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/gnu/llvm/tools/lld/ELF/Writer.cpp b/gnu/llvm/tools/lld/ELF/Writer.cpp
index ccff0c58333..2829559e28e 100644
--- a/gnu/llvm/tools/lld/ELF/Writer.cpp
+++ b/gnu/llvm/tools/lld/ELF/Writer.cpp
@@ -1947,6 +1947,23 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
};
};
+#ifdef __OpenBSD__
+ auto NXAlign = [](OutputSection *Cmd) {
+ if (Cmd && !Cmd->AddrExpr)
+ Cmd->AddrExpr = [=] {
+ return alignTo(Script->getDot(), 0x20000000);
+ };
+ };
+
+ PhdrEntry *firstRW = nullptr;
+ for (PhdrEntry *P : Phdrs)
+ if (P->p_type == PT_LOAD && (P->p_flags & PF_W))
+ firstRW = P;
+
+ if (Config->EMachine == EM_386 && firstRW)
+ NXAlign(firstRW->FirstSec);
+#endif
+
for (const PhdrEntry *P : Phdrs)
if (P->p_type == PT_LOAD && P->FirstSec)
PageAlign(P->FirstSec);