[lld] [lld/ELF] Place large executable sections at the end (PR #70358)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 10 13:28:29 PST 2023
https://github.com/aeubanks updated https://github.com/llvm/llvm-project/pull/70358
>From bf4472ca95ba14242b073b246ccc3fde224a8196 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Thu, 26 Oct 2023 10:36:23 -0700
Subject: [PATCH] [lld/ELF] Place large executable sections at the beginning
So that when mixing small and large text, large text stays out of the way of the rest of the binary.
---
lld/ELF/Writer.cpp | 21 ++++---
lld/test/ELF/x86-64-section-layout.s | 83 +++++++++++++++-------------
2 files changed, 59 insertions(+), 45 deletions(-)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a84e4864ab0e5a5..ffa77713a53b792 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -902,11 +902,12 @@ enum RankFlags {
RF_NOT_ALLOC = 1 << 26,
RF_PARTITION = 1 << 18, // Partition number (8 bits)
RF_NOT_SPECIAL = 1 << 17,
- RF_WRITE = 1 << 16,
- RF_EXEC_WRITE = 1 << 15,
- RF_EXEC = 1 << 14,
- RF_RODATA = 1 << 13,
- RF_LARGE = 1 << 12,
+ RF_NOT_LARGE_TEXT = 1 << 16,
+ RF_WRITE = 1 << 15,
+ RF_EXEC_WRITE = 1 << 14,
+ RF_EXEC = 1 << 13,
+ RF_RODATA = 1 << 12,
+ RF_LARGE = 1 << 11,
RF_NOT_RELRO = 1 << 9,
RF_NOT_TLS = 1 << 8,
RF_BSS = 1 << 7,
@@ -957,6 +958,9 @@ static unsigned getSectionRank(OutputSection &osec) {
// places.
bool isExec = osec.flags & SHF_EXECINSTR;
bool isWrite = osec.flags & SHF_WRITE;
+ bool isLarge = osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64;
+
+ rank |= RF_NOT_LARGE_TEXT;
if (!isWrite && !isExec) {
// Make PROGBITS sections (e.g .rodata .eh_frame) closer to .text to
@@ -965,10 +969,13 @@ static unsigned getSectionRank(OutputSection &osec) {
if (osec.type == SHT_PROGBITS)
rank |= RF_RODATA;
// Among PROGBITS sections, place .lrodata further from .text.
- if (!(osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64))
+ if (!isLarge)
rank |= RF_LARGE;
} else if (isExec) {
rank |= isWrite ? RF_EXEC_WRITE : RF_EXEC;
+ // Place .ltext before .(l)rodata.
+ if (isLarge)
+ rank &= ~RF_NOT_LARGE_TEXT;
} else {
rank |= RF_WRITE;
// The TLS initialization block needs to be a single contiguous block. Place
@@ -981,7 +988,7 @@ static unsigned getSectionRank(OutputSection &osec) {
rank |= RF_NOT_RELRO;
// Place .ldata and .lbss after .bss. Making .bss closer to .text alleviates
// relocation overflow pressure.
- if (osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64)
+ if (isLarge)
rank |= RF_LARGE;
}
diff --git a/lld/test/ELF/x86-64-section-layout.s b/lld/test/ELF/x86-64-section-layout.s
index 37201279fa0a5d0..b0f61cac7dad66c 100644
--- a/lld/test/ELF/x86-64-section-layout.s
+++ b/lld/test/ELF/x86-64-section-layout.s
@@ -18,63 +18,70 @@
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
# CHECK-NEXT: NULL 0000000000000000 000000 000000 00 0 0 0
# CHECK-NEXT: .note NOTE 0000000000200300 000300 000001 00 A 0 0 1
-# CHECK-NEXT: .lrodata PROGBITS 0000000000200301 000301 000002 00 Al 0 0 1
-# CHECK-NEXT: .rodata PROGBITS 0000000000200303 000303 000001 00 A 0 0 1
-# CHECK-NEXT: .text PROGBITS 0000000000201304 000304 000001 00 AX 0 0 4
-# CHECK-NEXT: .tdata PROGBITS 0000000000202305 000305 000001 00 WAT 0 0 1
-# CHECK-NEXT: .tbss NOBITS 0000000000202306 000306 000002 00 WAT 0 0 1
-# CHECK-NEXT: .relro_padding NOBITS 0000000000202306 000306 000cfa 00 WA 0 0 1
-# CHECK-NEXT: .data PROGBITS 0000000000203306 000306 000001 00 WA 0 0 1
-# CHECK-NEXT: .bss NOBITS 0000000000203307 000307 001800 00 WA 0 0 1
+# CHECK-NEXT: .ltext PROGBITS 0000000000201301 000301 000001 00 AXl 0 0 1
+# CHECK-NEXT: .lrodata PROGBITS 0000000000202302 000302 000002 00 Al 0 0 1
+# CHECK-NEXT: .rodata PROGBITS 0000000000202304 000304 000001 00 A 0 0 1
+# CHECK-NEXT: .text PROGBITS 0000000000203308 000308 000001 00 AX 0 0 4
+# CHECK-NEXT: .tdata PROGBITS 0000000000204309 000309 000001 00 WAT 0 0 1
+# CHECK-NEXT: .tbss NOBITS 000000000020430a 00030a 000002 00 WAT 0 0 1
+# CHECK-NEXT: .relro_padding NOBITS 000000000020430a 00030a 000cf6 00 WA 0 0 1
+# CHECK-NEXT: .data PROGBITS 000000000020530a 00030a 000001 00 WA 0 0 1
+# CHECK-NEXT: .bss NOBITS 000000000020530b 00030b 001800 00 WA 0 0 1
## We spend size(.bss) % MAXPAGESIZE bytes for .bss.
-# CHECK-NEXT: .ldata PROGBITS 0000000000205b07 000b07 000002 00 WAl 0 0 1
-# CHECK-NEXT: .ldata2 PROGBITS 0000000000205b09 000b09 000001 00 WAl 0 0 1
-# CHECK-NEXT: .lbss NOBITS 0000000000205b0a 000b0a 000002 00 WAl 0 0 1
-# CHECK-NEXT: .comment PROGBITS 0000000000000000 000b0a {{.*}} 01 MS 0 0 1
+# CHECK-NEXT: .ldata PROGBITS 0000000000207b0b 000b0b 000002 00 WAl 0 0 1
+# CHECK-NEXT: .ldata2 PROGBITS 0000000000207b0d 000b0d 000001 00 WAl 0 0 1
+# CHECK-NEXT: .lbss NOBITS 0000000000207b0e 000b0e 000002 00 WAl 0 0 1
+# CHECK-NEXT: .comment PROGBITS 0000000000000000 000b0e {{.*}} 01 MS 0 0 1
# CHECK: Program Headers:
# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# CHECK-NEXT: PHDR 0x000040 0x0000000000200040 0x0000000000200040 {{.*}} {{.*}} R 0x8
-# CHECK-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000304 0x000304 R 0x1000
-# CHECK-NEXT: LOAD 0x000304 0x0000000000201304 0x0000000000201304 0x000001 0x000001 R E 0x1000
-# CHECK-NEXT: LOAD 0x000305 0x0000000000202305 0x0000000000202305 0x000001 0x000cfb RW 0x1000
-# CHECK-NEXT: LOAD 0x000306 0x0000000000203306 0x0000000000203306 0x000001 0x001801 RW 0x1000
-# CHECK-NEXT: LOAD 0x000b07 0x0000000000205b07 0x0000000000205b07 0x000003 0x000005 RW 0x1000
+# CHECK-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000301 0x000301 R 0x1000
+# CHECK-NEXT: LOAD 0x000301 0x0000000000201301 0x0000000000201301 0x000001 0x000001 R E 0x1000
+# CHECK-NEXT: LOAD 0x000302 0x0000000000202302 0x0000000000202302 0x000003 0x000003 R 0x1000
+# CHECK-NEXT: LOAD 0x000308 0x0000000000203308 0x0000000000203308 0x000001 0x000001 R E 0x1000
+# CHECK-NEXT: LOAD 0x000309 0x0000000000204309 0x0000000000204309 0x000001 0x000cf7 RW 0x1000
+# CHECK-NEXT: LOAD 0x00030a 0x000000000020530a 0x000000000020530a 0x000001 0x001801 RW 0x1000
+# CHECK-NEXT: LOAD 0x000b0b 0x0000000000207b0b 0x0000000000207b0b 0x000003 0x000005 RW 0x1000
-# CHECK1: .data PROGBITS 0000000000203306 000306 000001 00 WA 0 0 1
-# CHECK1-NEXT: .ldata PROGBITS 0000000000203307 000307 000002 00 WAl 0 0 1
-# CHECK1-NEXT: .ldata2 PROGBITS 0000000000203309 000309 000001 00 WAl 0 0 1
-# CHECK1-NEXT: .comment PROGBITS 0000000000000000 00030a {{.*}} 01 MS 0 0 1
+# CHECK1: .data PROGBITS 000000000020530a 00030a 000001 00 WA 0 0 1
+# CHECK1-NEXT: .ldata PROGBITS 000000000020530b 00030b 000002 00 WAl 0 0 1
+# CHECK1-NEXT: .ldata2 PROGBITS 000000000020530d 00030d 000001 00 WAl 0 0 1
+# CHECK1-NEXT: .comment PROGBITS 0000000000000000 00030e {{.*}} 01 MS 0 0 1
# CHECK2: .note NOTE 0000000000200300 000300 000001 00 A 0 0 1
-# CHECK2-NEXT: .lrodata PROGBITS 0000000000200301 000301 000001 00 Al 0 0 1
+# CHECK2-NEXT: .ltext PROGBITS 0000000000200301 000301 000001 00 AXl 0 0 1
+# CHECK2-NEXT: .lrodata PROGBITS 0000000000200302 000302 000001 00 Al 0 0 1
## With a SECTIONS command, we suppress the default rule placing .lrodata.* into .lrodata.
-# CHECK2-NEXT: .lrodata.1 PROGBITS 0000000000200302 000302 000001 00 Al 0 0 1
-# CHECK2-NEXT: .rodata PROGBITS 0000000000200303 000303 000001 00 A 0 0 1
-# CHECK2-NEXT: .text PROGBITS 0000000000200304 000304 000001 00 AX 0 0 4
-# CHECK2-NEXT: .tdata PROGBITS 0000000000200305 000305 000001 00 WAT 0 0 1
-# CHECK2-NEXT: .tbss NOBITS 0000000000200306 000306 000001 00 WAT 0 0 1
-# CHECK2-NEXT: .tbss.1 NOBITS 0000000000200307 000306 000001 00 WAT 0 0 1
-# CHECK2-NEXT: .data PROGBITS 0000000000200306 000306 000001 00 WA 0 0 1
-# CHECK2-NEXT: .bss NOBITS 0000000000200307 000307 001800 00 WA 0 0 1
-# CHECK2-NEXT: .ldata PROGBITS 0000000000201b07 001b07 000002 00 WAl 0 0 1
-# CHECK2-NEXT: .ldata2 PROGBITS 0000000000201b09 001b09 000001 00 WAl 0 0 1
-# CHECK2-NEXT: .lbss NOBITS 0000000000201b0a 001b0a 000002 00 WAl 0 0 1
-# CHECK2-NEXT: .comment PROGBITS 0000000000000000 001b0a {{.*}} 01 MS 0 0 1
+# CHECK2-NEXT: .lrodata.1 PROGBITS 0000000000200303 000303 000001 00 Al 0 0 1
+# CHECK2-NEXT: .rodata PROGBITS 0000000000200304 000304 000001 00 A 0 0 1
+# CHECK2-NEXT: .text PROGBITS 0000000000200308 000308 000001 00 AX 0 0 4
+# CHECK2-NEXT: .tdata PROGBITS 0000000000200309 000309 000001 00 WAT 0 0 1
+# CHECK2-NEXT: .tbss NOBITS 000000000020030a 00030a 000001 00 WAT 0 0 1
+# CHECK2-NEXT: .tbss.1 NOBITS 000000000020030b 00030a 000001 00 WAT 0 0 1
+# CHECK2-NEXT: .data PROGBITS 000000000020030a 00030a 000001 00 WA 0 0 1
+# CHECK2-NEXT: .bss NOBITS 000000000020030b 00030b 001800 00 WA 0 0 1
+# CHECK2-NEXT: .ldata PROGBITS 0000000000201b0b 001b0b 000002 00 WAl 0 0 1
+# CHECK2-NEXT: .ldata2 PROGBITS 0000000000201b0d 001b0d 000001 00 WAl 0 0 1
+# CHECK2-NEXT: .lbss NOBITS 0000000000201b0e 001b0e 000002 00 WAl 0 0 1
+# CHECK2-NEXT: .comment PROGBITS 0000000000000000 001b0e {{.*}} 01 MS 0 0 1
# CHECK2: Program Headers:
# CHECK2-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# CHECK2-NEXT: PHDR 0x000040 0x0000000000200040 0x0000000000200040 {{.*}} {{.*}} R 0x8
-# CHECK2-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000304 0x000304 R 0x1000
-# CHECK2-NEXT: LOAD 0x000304 0x0000000000200304 0x0000000000200304 0x000001 0x000001 R E 0x1000
-# CHECK2-NEXT: LOAD 0x000305 0x0000000000200305 0x0000000000200305 0x001805 0x001807 RW 0x1000
-# CHECK2-NEXT: TLS 0x000305 0x0000000000200305 0x0000000000200305 0x000001 0x000003 R 0x1
+# CHECK2-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000301 0x000301 R 0x1000
+# CHECK2-NEXT: LOAD 0x000301 0x0000000000200301 0x0000000000200301 0x000001 0x000001 R E 0x1000
+# CHECK2-NEXT: LOAD 0x000302 0x0000000000200302 0x0000000000200302 0x000003 0x000003 R 0x1000
+# CHECK2-NEXT: LOAD 0x000308 0x0000000000200308 0x0000000000200308 0x000001 0x000001 R E 0x1000
+# CHECK2-NEXT: LOAD 0x000309 0x0000000000200309 0x0000000000200309 0x001805 0x001807 RW 0x1000
+# CHECK2-NEXT: TLS 0x000309 0x0000000000200309 0x0000000000200309 0x000001 0x000003 R 0x1
#--- a.s
.globl _start
_start:
ret
+.section .ltext,"axl", at progbits; .space 1
.section .note,"a", at note; .space 1
.section .rodata,"a", at progbits; .space 1
.section .data,"aw", at progbits; .space 1
More information about the llvm-commits
mailing list