[lld] [LLD] Add support for two special openbsd-sections (PR #97122)
John Ericson via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 28 15:58:19 PDT 2024
https://github.com/Ericson2314 created https://github.com/llvm/llvm-project/pull/97122
> (rebaser's note) adapted from:
> https://github.com/openbsd/src/commit/bd249b5664da50f0178adea78250a7a0d8ea6566
>
> In the linkers, collect objects in section "openbsd.mutable" and place them into a page-aligned region in the bss, with the right markers for kernel/ld.so to identify the region and skip making it immutable. While here, fix readelf/objdump versions to show all of this. ok miod kettenis
> (rebaser's note) adapted from:
> https://github.com/openbsd/src/commit/42a61acefa8b3288ff2163fb55e934a3fee39974
>
> Collect .openbsd.syscalls sections into a new PT_OPENBSD_SYSCALLS segment. This will be used soon to pin system calls to designated call sites.
>
> ok deraadt@
Note that I think it would seem better if all this OpenBSD stuff was conditioned on `config->osabi == ELFOSABI_FREEBSD`, but the `-m` flag for `ld.llld` is quite underpowered compared to `--target`.
>From a70d51eae28eaad4b4ef8c55dd0c4672a5c0e979 Mon Sep 17 00:00:00 2001
From: deraadt <deraadt at openbsd.org>
Date: Fri, 7 Oct 2022 15:04:51 +0000
Subject: [PATCH 1/2] [LLD] Add support for `.openbsd.mutable`
(rebaser's note) adapted from:
https://github.com/openbsd/src/commit/bd249b5664da50f0178adea78250a7a0d8ea6566
In the linkers, collect objects in section "openbsd.mutable" and place them into a page-aligned region in the bss, with the right markers for kernel/ld.so to identify the region and skip making it immutable. While here, fix readelf/objdump versions to show all of this. ok miod kettenis
---
lld/ELF/LinkerScript.cpp | 3 ++-
lld/ELF/ScriptParser.cpp | 1 +
lld/ELF/Writer.cpp | 6 ++++++
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1ec796a3bdd99..e1f38eccb1518 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -107,7 +107,8 @@ static StringRef getOutputSectionName(const InputSectionBase *s) {
for (StringRef v :
{".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", ".ldata",
".lrodata", ".lbss", ".gcc_except_table", ".init_array", ".fini_array",
- ".tbss", ".tdata", ".ARM.exidx", ".ARM.extab", ".ctors", ".dtors"})
+ ".tbss", ".tdata", ".ARM.exidx", ".ARM.extab", ".ctors", ".dtors",
+ ".openbsd.randomdata", ".openbsd.mutable"})
if (isSectionPrefix(v, s->name))
return v;
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index db46263115242..b8d18f516f461 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1628,6 +1628,7 @@ unsigned ScriptParser::readPhdrType() {
.Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
.Case("PT_GNU_STACK", PT_GNU_STACK)
.Case("PT_GNU_RELRO", PT_GNU_RELRO)
+ .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
.Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
.Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 640cb2a445f7d..99e13ee89b6dd 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2245,6 +2245,12 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
->add(part.ehFrameHdr->getParent());
+ // PT_OPENBSD_MUTABLE is an OpenBSD-specific feature. That makes
+ // the dynamic linker fill the segment with zero data, like bss, but
+ // it can be treated differently.
+ if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
+ addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
+
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
>From 05716a80240edda6091e48ff6d425b8bb2ef4c1b Mon Sep 17 00:00:00 2001
From: kettenis <kettenis at openbsd.org>
Date: Sun, 3 Dec 2023 21:15:11 +0000
Subject: [PATCH 2/2] [LLD] Add support for `.openbsd.syscalls`
(rebaser's note) adapted from:
https://github.com/openbsd/src/commit/42a61acefa8b3288ff2163fb55e934a3fee39974
Collect .openbsd.syscalls sections into a new PT_OPENBSD_SYSCALLS segment. This will be used soon to pin system calls to designated call sites.
ok deraadt@
---
lld/ELF/ScriptParser.cpp | 1 +
lld/ELF/Writer.cpp | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index b8d18f516f461..41bd9a95053f7 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1630,6 +1630,7 @@ unsigned ScriptParser::readPhdrType() {
.Case("PT_GNU_RELRO", PT_GNU_RELRO)
.Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
.Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
+ .Case("PT_OPENBSD_SYSCALLS", PT_OPENBSD_SYSCALLS)
.Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
.Default(-1);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 99e13ee89b6dd..917ed48bf0ec4 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2256,6 +2256,11 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
+ // PT_OPENBSD_SYSCALLS is an OpenBSD-specific feature. That makes
+ // the kernel and dynamic linker register system call sites.
+ if (OutputSection *cmd = findSection(".openbsd.syscalls", partNo))
+ addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd);
+
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
More information about the llvm-commits
mailing list