Skip to content

Commit 1e1b68f

Browse files
committed
[LLD][AArch64] Mark .plt with PURECODE flag if all input sections also have it
Mark the synthetic `.plt` section with the `SHF_AARCH64_PURECODE` section flag if all executable input sections also have that flag. Without this change, if we were to compile a binary with `-mexecute-only`, the final executable will only have `.plt` not marked with the section flag, causing it to be placed in a different load segment. This leads to an extra page's worth of memory usage unnecessarily when running the executable. A similar issue happens if we always set the section flag on `.plt` and compile a binary without `-mexecute-only`, so the solution should match the `SHF_AARCH64_PURECODE` section flags between `.plt` and all other executable sections.
1 parent f5ee105 commit 1e1b68f

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

lld/ELF/SyntheticSections.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,18 @@ PltSection::PltSection(Ctx &ctx)
26102610
// modify the instructions in the PLT entries.
26112611
if (ctx.arg.emachine == EM_SPARCV9)
26122612
this->flags |= SHF_WRITE;
2613+
2614+
// On AArch64, PLT entries only do loads from the .got.plt section, so the
2615+
// .plt section can be marked with the SHF_AARCH64_PURECODE section flag. We
2616+
// only do this if all other executable sections also have the same section
2617+
// flag set, because otherwise .plt can't be allocated in the same segment as
2618+
// the other executable sections.
2619+
if (ctx.arg.emachine == EM_AARCH64 &&
2620+
all_of(ctx.inputSections, [](InputSectionBase *sec) {
2621+
return !(sec->flags & SHF_EXECINSTR) ||
2622+
(sec->flags & SHF_AARCH64_PURECODE);
2623+
}))
2624+
this->flags |= SHF_AARCH64_PURECODE;
26132625
}
26142626

26152627
void PltSection::writeTo(uint8_t *buf) {
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// REQUIRES: aarch64
2+
// RUN: rm -rf %t && split-file %s %t && cd %t
3+
4+
// RUN: llvm-mc -filetype=obj -triple=aarch64 start.s -o start.o
5+
// RUN: llvm-mc -filetype=obj -triple=aarch64 foo-xo-same-section.s -o foo-xo-same-section.o
6+
// RUN: llvm-mc -filetype=obj -triple=aarch64 foo-rx-same-section.s -o foo-rx-same-section.o
7+
// RUN: llvm-mc -filetype=obj -triple=aarch64 foo-xo-different-section.s -o foo-xo-different-section.o
8+
// RUN: llvm-mc -filetype=obj -triple=aarch64 foo-rx-different-section.s -o foo-rx-different-section.o
9+
// RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/plt-aarch64.s -o plt.o
10+
// RUN: ld.lld -shared plt.o -soname=t2.so -o plt.so
11+
// RUN: ld.lld start.o foo-xo-same-section.o plt.so -o xo-same-section
12+
// RUN: ld.lld start.o foo-rx-same-section.o plt.so -o rx-same-section
13+
// RUN: ld.lld start.o foo-xo-different-section.o plt.so -o xo-different-section
14+
// RUN: ld.lld start.o foo-rx-different-section.o plt.so -o rx-different-section
15+
// RUN: llvm-readobj -S -l xo-same-section | FileCheck --check-prefix=CHECK-XO %s
16+
// RUN: llvm-readobj -S -l rx-same-section | FileCheck --check-prefix=CHECK-RX %s
17+
// RUN: llvm-readobj -S -l xo-different-section | FileCheck --check-prefix=CHECK-XO %s
18+
// RUN: llvm-readobj -S -l rx-different-section | FileCheck --check-prefix=CHECK-RX %s
19+
// RUN: llvm-objdump -d --no-show-raw-insn xo-same-section | FileCheck --check-prefix=DISASM %s
20+
// RUN: llvm-objdump -d --no-show-raw-insn rx-same-section | FileCheck --check-prefix=DISASM %s
21+
// RUN: llvm-objdump -d --no-show-raw-insn xo-different-section | FileCheck --check-prefix=DISASM %s
22+
// RUN: llvm-objdump -d --no-show-raw-insn rx-different-section | FileCheck --check-prefix=DISASM %s
23+
24+
// CHECK-XO: Name: .plt
25+
// CHECK-XO-NEXT: Type: SHT_PROGBITS
26+
// CHECK-XO-NEXT: Flags [
27+
// CHECK-XO-NEXT: SHF_AARCH64_PURECODE
28+
// CHECK-XO-NEXT: SHF_ALLOC
29+
// CHECK-XO-NEXT: SHF_EXECINSTR
30+
// CHECK-XO-NEXT: ]
31+
// CHECK-XO-NEXT: Address: 0x2102E0
32+
33+
/// The address of .plt above should be within this program header.
34+
// CHECK-XO: VirtualAddress: 0x2102C8
35+
// CHECK-XO-NEXT: PhysicalAddress: 0x2102C8
36+
// CHECK-XO-NEXT: FileSize: 88
37+
// CHECK-XO-NEXT: MemSize: 88
38+
// CHECK-XO-NEXT: Flags [
39+
// CHECK-XO-NEXT: PF_X
40+
// CHECK-XO-NEXT: ]
41+
42+
// CHECK-RX: Name: .plt
43+
// CHECK-RX-NEXT: Type: SHT_PROGBITS
44+
// CHECK-RX-NEXT: Flags [
45+
// CHECK-RX-NEXT: SHF_ALLOC
46+
// CHECK-RX-NEXT: SHF_EXECINSTR
47+
// CHECK-RX-NEXT: ]
48+
// CHECK-RX-NEXT: Address: 0x2102E0
49+
50+
/// The address of .plt above should be within this program header.
51+
// CHECK-RX: VirtualAddress: 0x2102C8
52+
// CHECK-RX-NEXT: PhysicalAddress: 0x2102C8
53+
// CHECK-RX-NEXT: FileSize: 88
54+
// CHECK-RX-NEXT: MemSize: 88
55+
// CHECK-RX-NEXT: Flags [
56+
// CHECK-RX-NEXT: PF_R
57+
// CHECK-RX-NEXT: PF_X
58+
// CHECK-RX-NEXT: ]
59+
60+
// DISASM-LABEL: Disassembly of section .plt:
61+
// DISASM-LABEL: <.plt>:
62+
// DISASM-NEXT: 2102e0: stp x16, x30, [sp, #-0x10]!
63+
// DISASM-NEXT: adrp x16, 0x230000 <weak+0x230000>
64+
// DISASM-NEXT: ldr x17, [x16, #0x400]
65+
// DISASM-NEXT: add x16, x16, #0x400
66+
// DISASM-NEXT: br x17
67+
// DISASM-NEXT: nop
68+
// DISASM-NEXT: nop
69+
// DISASM-NEXT: nop
70+
71+
// DISASM-LABEL: <bar@plt>:
72+
// DISASM-NEXT: 210300: adrp x16, 0x230000 <weak+0x230000>
73+
// DISASM-NEXT: ldr x17, [x16, #0x408]
74+
// DISASM-NEXT: add x16, x16, #0x408
75+
// DISASM-NEXT: br x17
76+
77+
// DISASM-LABEL: <weak@plt>:
78+
// DISASM-NEXT: 210310: adrp x16, 0x230000 <weak+0x230000>
79+
// DISASM-NEXT: ldr x17, [x16, #0x410]
80+
// DISASM-NEXT: add x16, x16, #0x410
81+
// DISASM-NEXT: br x17
82+
83+
//--- start.s
84+
.section .text,"axy",@progbits,unique,0
85+
.global _start, foo, bar
86+
.weak weak
87+
_start:
88+
bl foo
89+
bl bar
90+
bl weak
91+
ret
92+
93+
//--- foo-xo-same-section.s
94+
.section .text,"axy",@progbits,unique,0
95+
.global foo
96+
foo:
97+
ret
98+
99+
//--- foo-rx-same-section.s
100+
.section .text,"ax",@progbits,unique,0
101+
.global foo
102+
foo:
103+
ret
104+
105+
//--- foo-xo-different-section.s
106+
.section .foo,"axy",@progbits,unique,0
107+
.global foo
108+
foo:
109+
ret
110+
111+
//--- foo-rx-different-section.s
112+
.section .foo,"ax",@progbits,unique,0
113+
.global foo
114+
foo:
115+
ret

0 commit comments

Comments
 (0)