[lld] [LLD] Add support for two special openbsd-sections (PR #97122)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 28 15:58:49 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-elf

Author: John Ericson (Ericson2314)

<details>
<summary>Changes</summary>


> (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`.

---
Full diff: https://github.com/llvm/llvm-project/pull/97122.diff


3 Files Affected:

- (modified) lld/ELF/LinkerScript.cpp (+2-1) 
- (modified) lld/ELF/ScriptParser.cpp (+2) 
- (modified) lld/ELF/Writer.cpp (+11) 


``````````diff
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..41bd9a95053f7 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1628,7 +1628,9 @@ 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_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 640cb2a445f7d..917ed48bf0ec4 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2245,11 +2245,22 @@ 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))
     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

``````````

</details>


https://github.com/llvm/llvm-project/pull/97122


More information about the llvm-commits mailing list