Skip to content

Commit bf4472c

Browse files
committed
[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.
1 parent 5425925 commit bf4472c

File tree

2 files changed

+59
-45
lines changed

2 files changed

+59
-45
lines changed

lld/ELF/Writer.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -902,11 +902,12 @@ enum RankFlags {
902902
RF_NOT_ALLOC = 1 << 26,
903903
RF_PARTITION = 1 << 18, // Partition number (8 bits)
904904
RF_NOT_SPECIAL = 1 << 17,
905-
RF_WRITE = 1 << 16,
906-
RF_EXEC_WRITE = 1 << 15,
907-
RF_EXEC = 1 << 14,
908-
RF_RODATA = 1 << 13,
909-
RF_LARGE = 1 << 12,
905+
RF_NOT_LARGE_TEXT = 1 << 16,
906+
RF_WRITE = 1 << 15,
907+
RF_EXEC_WRITE = 1 << 14,
908+
RF_EXEC = 1 << 13,
909+
RF_RODATA = 1 << 12,
910+
RF_LARGE = 1 << 11,
910911
RF_NOT_RELRO = 1 << 9,
911912
RF_NOT_TLS = 1 << 8,
912913
RF_BSS = 1 << 7,
@@ -957,6 +958,9 @@ static unsigned getSectionRank(OutputSection &osec) {
957958
// places.
958959
bool isExec = osec.flags & SHF_EXECINSTR;
959960
bool isWrite = osec.flags & SHF_WRITE;
961+
bool isLarge = osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64;
962+
963+
rank |= RF_NOT_LARGE_TEXT;
960964

961965
if (!isWrite && !isExec) {
962966
// Make PROGBITS sections (e.g .rodata .eh_frame) closer to .text to
@@ -965,10 +969,13 @@ static unsigned getSectionRank(OutputSection &osec) {
965969
if (osec.type == SHT_PROGBITS)
966970
rank |= RF_RODATA;
967971
// Among PROGBITS sections, place .lrodata further from .text.
968-
if (!(osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64))
972+
if (!isLarge)
969973
rank |= RF_LARGE;
970974
} else if (isExec) {
971975
rank |= isWrite ? RF_EXEC_WRITE : RF_EXEC;
976+
// Place .ltext before .(l)rodata.
977+
if (isLarge)
978+
rank &= ~RF_NOT_LARGE_TEXT;
972979
} else {
973980
rank |= RF_WRITE;
974981
// The TLS initialization block needs to be a single contiguous block. Place
@@ -981,7 +988,7 @@ static unsigned getSectionRank(OutputSection &osec) {
981988
rank |= RF_NOT_RELRO;
982989
// Place .ldata and .lbss after .bss. Making .bss closer to .text alleviates
983990
// relocation overflow pressure.
984-
if (osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64)
991+
if (isLarge)
985992
rank |= RF_LARGE;
986993
}
987994

lld/test/ELF/x86-64-section-layout.s

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,63 +18,70 @@
1818
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
1919
# CHECK-NEXT: NULL 0000000000000000 000000 000000 00 0 0 0
2020
# CHECK-NEXT: .note NOTE 0000000000200300 000300 000001 00 A 0 0 1
21-
# CHECK-NEXT: .lrodata PROGBITS 0000000000200301 000301 000002 00 Al 0 0 1
22-
# CHECK-NEXT: .rodata PROGBITS 0000000000200303 000303 000001 00 A 0 0 1
23-
# CHECK-NEXT: .text PROGBITS 0000000000201304 000304 000001 00 AX 0 0 4
24-
# CHECK-NEXT: .tdata PROGBITS 0000000000202305 000305 000001 00 WAT 0 0 1
25-
# CHECK-NEXT: .tbss NOBITS 0000000000202306 000306 000002 00 WAT 0 0 1
26-
# CHECK-NEXT: .relro_padding NOBITS 0000000000202306 000306 000cfa 00 WA 0 0 1
27-
# CHECK-NEXT: .data PROGBITS 0000000000203306 000306 000001 00 WA 0 0 1
28-
# CHECK-NEXT: .bss NOBITS 0000000000203307 000307 001800 00 WA 0 0 1
21+
# CHECK-NEXT: .ltext PROGBITS 0000000000201301 000301 000001 00 AXl 0 0 1
22+
# CHECK-NEXT: .lrodata PROGBITS 0000000000202302 000302 000002 00 Al 0 0 1
23+
# CHECK-NEXT: .rodata PROGBITS 0000000000202304 000304 000001 00 A 0 0 1
24+
# CHECK-NEXT: .text PROGBITS 0000000000203308 000308 000001 00 AX 0 0 4
25+
# CHECK-NEXT: .tdata PROGBITS 0000000000204309 000309 000001 00 WAT 0 0 1
26+
# CHECK-NEXT: .tbss NOBITS 000000000020430a 00030a 000002 00 WAT 0 0 1
27+
# CHECK-NEXT: .relro_padding NOBITS 000000000020430a 00030a 000cf6 00 WA 0 0 1
28+
# CHECK-NEXT: .data PROGBITS 000000000020530a 00030a 000001 00 WA 0 0 1
29+
# CHECK-NEXT: .bss NOBITS 000000000020530b 00030b 001800 00 WA 0 0 1
2930
## We spend size(.bss) % MAXPAGESIZE bytes for .bss.
30-
# CHECK-NEXT: .ldata PROGBITS 0000000000205b07 000b07 000002 00 WAl 0 0 1
31-
# CHECK-NEXT: .ldata2 PROGBITS 0000000000205b09 000b09 000001 00 WAl 0 0 1
32-
# CHECK-NEXT: .lbss NOBITS 0000000000205b0a 000b0a 000002 00 WAl 0 0 1
33-
# CHECK-NEXT: .comment PROGBITS 0000000000000000 000b0a {{.*}} 01 MS 0 0 1
31+
# CHECK-NEXT: .ldata PROGBITS 0000000000207b0b 000b0b 000002 00 WAl 0 0 1
32+
# CHECK-NEXT: .ldata2 PROGBITS 0000000000207b0d 000b0d 000001 00 WAl 0 0 1
33+
# CHECK-NEXT: .lbss NOBITS 0000000000207b0e 000b0e 000002 00 WAl 0 0 1
34+
# CHECK-NEXT: .comment PROGBITS 0000000000000000 000b0e {{.*}} 01 MS 0 0 1
3435

3536
# CHECK: Program Headers:
3637
# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
3738
# CHECK-NEXT: PHDR 0x000040 0x0000000000200040 0x0000000000200040 {{.*}} {{.*}} R 0x8
38-
# CHECK-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000304 0x000304 R 0x1000
39-
# CHECK-NEXT: LOAD 0x000304 0x0000000000201304 0x0000000000201304 0x000001 0x000001 R E 0x1000
40-
# CHECK-NEXT: LOAD 0x000305 0x0000000000202305 0x0000000000202305 0x000001 0x000cfb RW 0x1000
41-
# CHECK-NEXT: LOAD 0x000306 0x0000000000203306 0x0000000000203306 0x000001 0x001801 RW 0x1000
42-
# CHECK-NEXT: LOAD 0x000b07 0x0000000000205b07 0x0000000000205b07 0x000003 0x000005 RW 0x1000
39+
# CHECK-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000301 0x000301 R 0x1000
40+
# CHECK-NEXT: LOAD 0x000301 0x0000000000201301 0x0000000000201301 0x000001 0x000001 R E 0x1000
41+
# CHECK-NEXT: LOAD 0x000302 0x0000000000202302 0x0000000000202302 0x000003 0x000003 R 0x1000
42+
# CHECK-NEXT: LOAD 0x000308 0x0000000000203308 0x0000000000203308 0x000001 0x000001 R E 0x1000
43+
# CHECK-NEXT: LOAD 0x000309 0x0000000000204309 0x0000000000204309 0x000001 0x000cf7 RW 0x1000
44+
# CHECK-NEXT: LOAD 0x00030a 0x000000000020530a 0x000000000020530a 0x000001 0x001801 RW 0x1000
45+
# CHECK-NEXT: LOAD 0x000b0b 0x0000000000207b0b 0x0000000000207b0b 0x000003 0x000005 RW 0x1000
4346

44-
# CHECK1: .data PROGBITS 0000000000203306 000306 000001 00 WA 0 0 1
45-
# CHECK1-NEXT: .ldata PROGBITS 0000000000203307 000307 000002 00 WAl 0 0 1
46-
# CHECK1-NEXT: .ldata2 PROGBITS 0000000000203309 000309 000001 00 WAl 0 0 1
47-
# CHECK1-NEXT: .comment PROGBITS 0000000000000000 00030a {{.*}} 01 MS 0 0 1
47+
# CHECK1: .data PROGBITS 000000000020530a 00030a 000001 00 WA 0 0 1
48+
# CHECK1-NEXT: .ldata PROGBITS 000000000020530b 00030b 000002 00 WAl 0 0 1
49+
# CHECK1-NEXT: .ldata2 PROGBITS 000000000020530d 00030d 000001 00 WAl 0 0 1
50+
# CHECK1-NEXT: .comment PROGBITS 0000000000000000 00030e {{.*}} 01 MS 0 0 1
4851

4952
# CHECK2: .note NOTE 0000000000200300 000300 000001 00 A 0 0 1
50-
# CHECK2-NEXT: .lrodata PROGBITS 0000000000200301 000301 000001 00 Al 0 0 1
53+
# CHECK2-NEXT: .ltext PROGBITS 0000000000200301 000301 000001 00 AXl 0 0 1
54+
# CHECK2-NEXT: .lrodata PROGBITS 0000000000200302 000302 000001 00 Al 0 0 1
5155
## With a SECTIONS command, we suppress the default rule placing .lrodata.* into .lrodata.
52-
# CHECK2-NEXT: .lrodata.1 PROGBITS 0000000000200302 000302 000001 00 Al 0 0 1
53-
# CHECK2-NEXT: .rodata PROGBITS 0000000000200303 000303 000001 00 A 0 0 1
54-
# CHECK2-NEXT: .text PROGBITS 0000000000200304 000304 000001 00 AX 0 0 4
55-
# CHECK2-NEXT: .tdata PROGBITS 0000000000200305 000305 000001 00 WAT 0 0 1
56-
# CHECK2-NEXT: .tbss NOBITS 0000000000200306 000306 000001 00 WAT 0 0 1
57-
# CHECK2-NEXT: .tbss.1 NOBITS 0000000000200307 000306 000001 00 WAT 0 0 1
58-
# CHECK2-NEXT: .data PROGBITS 0000000000200306 000306 000001 00 WA 0 0 1
59-
# CHECK2-NEXT: .bss NOBITS 0000000000200307 000307 001800 00 WA 0 0 1
60-
# CHECK2-NEXT: .ldata PROGBITS 0000000000201b07 001b07 000002 00 WAl 0 0 1
61-
# CHECK2-NEXT: .ldata2 PROGBITS 0000000000201b09 001b09 000001 00 WAl 0 0 1
62-
# CHECK2-NEXT: .lbss NOBITS 0000000000201b0a 001b0a 000002 00 WAl 0 0 1
63-
# CHECK2-NEXT: .comment PROGBITS 0000000000000000 001b0a {{.*}} 01 MS 0 0 1
56+
# CHECK2-NEXT: .lrodata.1 PROGBITS 0000000000200303 000303 000001 00 Al 0 0 1
57+
# CHECK2-NEXT: .rodata PROGBITS 0000000000200304 000304 000001 00 A 0 0 1
58+
# CHECK2-NEXT: .text PROGBITS 0000000000200308 000308 000001 00 AX 0 0 4
59+
# CHECK2-NEXT: .tdata PROGBITS 0000000000200309 000309 000001 00 WAT 0 0 1
60+
# CHECK2-NEXT: .tbss NOBITS 000000000020030a 00030a 000001 00 WAT 0 0 1
61+
# CHECK2-NEXT: .tbss.1 NOBITS 000000000020030b 00030a 000001 00 WAT 0 0 1
62+
# CHECK2-NEXT: .data PROGBITS 000000000020030a 00030a 000001 00 WA 0 0 1
63+
# CHECK2-NEXT: .bss NOBITS 000000000020030b 00030b 001800 00 WA 0 0 1
64+
# CHECK2-NEXT: .ldata PROGBITS 0000000000201b0b 001b0b 000002 00 WAl 0 0 1
65+
# CHECK2-NEXT: .ldata2 PROGBITS 0000000000201b0d 001b0d 000001 00 WAl 0 0 1
66+
# CHECK2-NEXT: .lbss NOBITS 0000000000201b0e 001b0e 000002 00 WAl 0 0 1
67+
# CHECK2-NEXT: .comment PROGBITS 0000000000000000 001b0e {{.*}} 01 MS 0 0 1
6468

6569
# CHECK2: Program Headers:
6670
# CHECK2-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
6771
# CHECK2-NEXT: PHDR 0x000040 0x0000000000200040 0x0000000000200040 {{.*}} {{.*}} R 0x8
68-
# CHECK2-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000304 0x000304 R 0x1000
69-
# CHECK2-NEXT: LOAD 0x000304 0x0000000000200304 0x0000000000200304 0x000001 0x000001 R E 0x1000
70-
# CHECK2-NEXT: LOAD 0x000305 0x0000000000200305 0x0000000000200305 0x001805 0x001807 RW 0x1000
71-
# CHECK2-NEXT: TLS 0x000305 0x0000000000200305 0x0000000000200305 0x000001 0x000003 R 0x1
72+
# CHECK2-NEXT: LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x000301 0x000301 R 0x1000
73+
# CHECK2-NEXT: LOAD 0x000301 0x0000000000200301 0x0000000000200301 0x000001 0x000001 R E 0x1000
74+
# CHECK2-NEXT: LOAD 0x000302 0x0000000000200302 0x0000000000200302 0x000003 0x000003 R 0x1000
75+
# CHECK2-NEXT: LOAD 0x000308 0x0000000000200308 0x0000000000200308 0x000001 0x000001 R E 0x1000
76+
# CHECK2-NEXT: LOAD 0x000309 0x0000000000200309 0x0000000000200309 0x001805 0x001807 RW 0x1000
77+
# CHECK2-NEXT: TLS 0x000309 0x0000000000200309 0x0000000000200309 0x000001 0x000003 R 0x1
7278

7379
#--- a.s
7480
.globl _start
7581
_start:
7682
ret
7783

84+
.section .ltext,"axl",@progbits; .space 1
7885
.section .note,"a",@note; .space 1
7986
.section .rodata,"a",@progbits; .space 1
8087
.section .data,"aw",@progbits; .space 1

0 commit comments

Comments
 (0)