Skip to content

Commit 76deb33

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 280d82e commit 76deb33

File tree

5 files changed

+83
-13
lines changed

5 files changed

+83
-13
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: 26 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,22 @@ 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+
if (config->osabi == ELFOSABI_OPENBSD) {
2283+
// PT_OPENBSD_MUTABLE makes the dynamic linker fill the segment with
2284+
// zero data, like bss, but it can be treated differently.
2285+
if (OutputSection *cmd = findSection(".openbsd.mutable", partNo))
2286+
addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd);
2287+
2288+
// PT_OPENBSD_RANDOMIZE makes the dynamic linker fill the segment
2289+
// with random data.
2290+
if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
2291+
addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
2292+
2293+
// PT_OPENBSD_SYSCALLS makes the kernel and dynamic linker register
2294+
// system call sites.
2295+
if (OutputSection *cmd = findSection(".openbsd.syscalls", partNo))
2296+
addHdr(PT_OPENBSD_SYSCALLS, cmd->getPhdrFlags())->add(cmd);
2297+
}
22802298

22812299
if (config->zGnustack != GnuStackKind::None) {
22822300
// 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-unknown-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-unknown-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 {

lld/test/ELF/relro-openbsd.s

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// REQUIRES: x86
2+
3+
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-openbsd %s -o %t.o
4+
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-openbsd %p/Inputs/shared.s -o %t2.o
5+
// RUN: ld.lld -shared %t2.o -o %t2.so
6+
7+
// RUN: ld.lld %t.o %t2.so -z now -z norelro -z relro -o %t
8+
// RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s
9+
10+
// RUN: ld.lld %t.o %t2.so -z norelro -z relro -o %t
11+
// RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s
12+
13+
// RUN: ld.lld %t.o %t2.so -z norelro -o %t
14+
// RUN: llvm-readelf -l %t | FileCheck --check-prefix=NORELRO %s
15+
16+
// CHECK: Program Headers:
17+
// CHECK-NEXT: Type
18+
// CHECK-NEXT: PHDR
19+
// CHECK-NEXT: LOAD
20+
// CHECK-NEXT: LOAD
21+
// CHECK-NEXT: LOAD
22+
// CHECK-NEXT: LOAD
23+
// CHECK-NEXT: DYNAMIC
24+
// CHECK-NEXT: GNU_RELRO
25+
// CHECK: Section to Segment mapping:
26+
27+
// FULLRELRO: 03 .openbsd.randomdata .dynamic .got .got.plt .relro_padding {{$}}
28+
// PARTRELRO: 03 .openbsd.randomdata .dynamic .got .relro_padding {{$}}
29+
30+
31+
// NORELRO-NOT: GNU_RELRO
32+
33+
.global _start
34+
_start:
35+
.long bar
36+
jmp *bar2@GOTPCREL(%rip)
37+
38+
.section .data,"aw"
39+
.quad 0
40+
41+
.zero 4
42+
.section .foo,"aw"
43+
.section .bss,"",@nobits
44+
45+
.section .openbsd.randomdata, "aw"
46+
.quad 0

lld/test/ELF/relro.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
// CHECK-NEXT: GNU_RELRO
2525
// CHECK: Section to Segment mapping:
2626

27-
// FULLRELRO: 03 .openbsd.randomdata .dynamic .got .got.plt .relro_padding {{$}}
28-
// PARTRELRO: 03 .openbsd.randomdata .dynamic .got .relro_padding {{$}}
27+
// FULLRELRO: 03 .data.rel.ro .dynamic .got .got.plt .relro_padding {{$}}
28+
// PARTRELRO: 03 .data.rel.ro .dynamic .got .relro_padding {{$}}
2929

3030

3131
// NORELRO-NOT: GNU_RELRO
@@ -42,5 +42,5 @@ _start:
4242
.section .foo,"aw"
4343
.section .bss,"",@nobits
4444

45-
.section .openbsd.randomdata, "aw"
45+
.section .data.rel.ro, "aw"
4646
.quad 0

0 commit comments

Comments
 (0)