Skip to content

Commit 7f1f90c

Browse files
deraadtEricson2314
deraadt
authored andcommitted
[LLD] Extend special OpenBSD support, but scope under ELFOSABI
- Add support for `.openbsd.mutable` (rebaser's note) adapted from: openbsd/src@bd249b5 New auto-coalescing sections removed 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 - Add support for `.openbsd.syscalls` (rebaser's note) adapted from: openbsd/src@42a61ac 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@ - Scope OpenBSD special section handling under that ELFOSABI As a preexisting comment in `ELF/Writer.cpp` says: > section names shouldn't be significant in ELF in spirit. so scoping OSABI-specific magic name hacks to just the OSABI in question limits the degree to which we deviate from that "spirit" for all other OSABIs. OpenBSD in particular is very fast moving, having added a number of special sections, etc. in recent years. It is unclear how possible / reasonable it is for upstream to implement all these features in any event, but scoping like this at least mitigates the fallout for other OSABIs systems which wish to be more slow-moving.
1 parent 9da46ac commit 7f1f90c

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

lld/ELF/ScriptParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,7 +1628,9 @@ unsigned ScriptParser::readPhdrType() {
16281628
.Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
16291629
.Case("PT_GNU_STACK", PT_GNU_STACK)
16301630
.Case("PT_GNU_RELRO", PT_GNU_RELRO)
1631+
.Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
16311632
.Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1633+
.Case("PT_OPENBSD_SYSCALLS", PT_OPENBSD_SYSCALLS)
16321634
.Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
16331635
.Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
16341636
.Default(-1);

lld/ELF/Writer.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -601,10 +601,16 @@ static bool isRelroSection(const OutputSection *sec) {
601601
// ELF in spirit. But in reality many linker features depend on
602602
// magic section names.
603603
StringRef s = sec->name;
604-
return s == ".data.rel.ro" || s == ".bss.rel.ro" || s == ".ctors" ||
605-
s == ".dtors" || s == ".jcr" || s == ".eh_frame" ||
606-
s == ".fini_array" || s == ".init_array" ||
607-
s == ".openbsd.randomdata" || s == ".preinit_array";
604+
605+
bool abiAgnostic = s == ".data.rel.ro" || s == ".bss.rel.ro" ||
606+
s == ".ctors" || s == ".dtors" || s == ".jcr" ||
607+
s == ".eh_frame" || s == ".fini_array" ||
608+
s == ".init_array" || s == ".preinit_array";
609+
610+
bool abiSpecific =
611+
config->osabi == ELFOSABI_OPENBSD && s == ".openbsd.randomdata";
612+
613+
return abiAgnostic || abiSpecific;
608614
}
609615

610616
// We compute a rank for each section. The rank indicates where the
@@ -2273,10 +2279,23 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22732279
addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
22742280
->add(part.ehFrameHdr->getParent());
22752281

2276-
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
2277-
// the dynamic linker fill the segment with random data.
2278-
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
2279-
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
2282+
// Handle OpenBSD-specific section types for OpenBSD "OS ABI".
2283+
if (config->osabi == ELFOSABI_OPENBSD) {
2284+
// PT_OPENBSD_MUTABLE makes the dynamic linker fill the segment with
2285+
// zero data, like bss, but it can be treated differently.
2286+
if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
2287+
addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
2288+
2289+
// PT_OPENBSD_RANDOMIZE makes the dynamic linker fill the segment
2290+
// with random data.
2291+
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
2292+
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
2293+
2294+
// PT_OPENBSD_SYSCALLS makes the kernel and dynamic linker register
2295+
// system call sites.
2296+
if (OutputSection *cmd = findSection(".openbsd.syscalls", partNo))
2297+
addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd);
2298+
}
22802299

22812300
if (config->zGnustack != GnuStackKind::None) {
22822301
// PT_GNU_STACK is a special section to tell the loader to make the

lld/test/ELF/openbsd-phdr.s

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# REQUIRES: x86
22
# RUN: rm -rf %t && split-file %s %t && cd %t
3-
# RUN: llvm-mc -filetype=obj -triple=x86_64 randomdata.s -o randomdata.o
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-openbsd randomdata.s -o randomdata.o
44
# RUN: ld.lld randomdata.o -o randomdata
55
# RUN: llvm-readelf -S -l randomdata | FileCheck %s --check-prefix=RANDOMDATA
66

7-
# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o wxneeded.o
7+
# RUN: llvm-mc -filetype=obj -triple=x86_64-openbsd /dev/null -o wxneeded.o
88
# RUN: ld.lld -z wxneeded wxneeded.o -o wxneeded
99
# RUN: llvm-readelf -l wxneeded | FileCheck %s --check-prefix=WXNEEDED
1010

@@ -20,6 +20,8 @@
2020
# RANDOMDATA: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
2121
# RANDOMDATA: OPENBSD_RANDOMIZE 0x[[O]] 0x[[ADDR]] 0x[[ADDR]] 0x000008 0x000008 R 0x1
2222
# CHECK-NEXT: OPENBSD_BOOTDATA 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 R 0
23+
# CHECK-NEXT: OPENBSD_MUTABLE 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 R 0
24+
# CHECK-NEXT: OPENBSD_SYSCALLS 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 R 0
2325
# CHECK-NEXT: OPENBSD_WXNEEDED 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 R 0
2426

2527
#--- randomdata.s
@@ -31,6 +33,8 @@ PHDRS {
3133
text PT_LOAD FILEHDR PHDRS;
3234
rand PT_OPENBSD_RANDOMIZE;
3335
boot PT_OPENBSD_BOOTDATA;
36+
mutable PT_OPENBSD_MUTABLE;
37+
syscalls PT_OPENBSD_SYSCALLS;
3438
wxneeded PT_OPENBSD_WXNEEDED;
3539
}
3640
SECTIONS {

0 commit comments

Comments
 (0)