[lld] [lld/ELF] Place large executable sections at the end (PR #70358)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 26 10:37:59 PDT 2023
https://github.com/aeubanks created https://github.com/llvm/llvm-project/pull/70358
So that when mixing small and large text, large text stays out of the way of the rest of the binary.
>From b1c068a3d8687aaae0ca2ac362f84e0663a7a091 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 end
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 | 19 ++++++++++++-------
lld/test/ELF/x86-64-section-layout.s | 11 ++++++++---
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 57e1aa06c6aa873..313ff0f872e9440 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_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,7 @@ 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;
if (!isWrite && !isExec) {
// Make PROGBITS sections (e.g .rodata .eh_frame) closer to .text to
@@ -965,10 +967,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 after all other not special sections.
+ if (isLarge)
+ rank |= RF_LARGE_TEXT;
} else {
rank |= RF_WRITE;
// The TLS initialization block needs to be a single contiguous block. Place
@@ -981,7 +986,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..5ae24f132f9f7b9 100644
--- a/lld/test/ELF/x86-64-section-layout.s
+++ b/lld/test/ELF/x86-64-section-layout.s
@@ -30,7 +30,8 @@
# 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: .ltext PROGBITS 0000000000206b0c 000b0c 000001 00 AXl 0 0 1
+# CHECK-NEXT: .comment PROGBITS 0000000000000000 000b0d {{.*}} 01 MS 0 0 1
# CHECK: Program Headers:
# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
@@ -44,7 +45,8 @@
# 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-NEXT: .ltext PROGBITS 000000000020430a 00030a 000001 00 AXl 0 0 1
+# CHECK1-NEXT: .comment PROGBITS 0000000000000000 00030b {{.*}} 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
@@ -60,7 +62,8 @@
# 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: .ltext PROGBITS 0000000000201b0c 001b0c 000001 00 AXl 0 0 1
+# CHECK2-NEXT: .comment PROGBITS 0000000000000000 001b0d {{.*}} 01 MS 0 0 1
# CHECK2: Program Headers:
# CHECK2-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
@@ -68,6 +71,7 @@
# 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: LOAD 0x001b0c 0x0000000000201b0c 0x0000000000201b0c 0x000001 0x000001 R E 0x1000
# CHECK2-NEXT: TLS 0x000305 0x0000000000200305 0x0000000000200305 0x000001 0x000003 R 0x1
#--- a.s
@@ -75,6 +79,7 @@
_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