[lld] [lld/ELF] Place .lrodata at the very end of the binary (PR #81202)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 14:47:07 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Arthur Eubanks (aeubanks)

<details>
<summary>Changes</summary>

`-fno-pic` compiles expect that small symbols are in the lower 2GB of the address space. However, we currently place .lrodata at the very beginning of the binary, which can cause large data to contriute to relocation pressure. LLD should put all large sections at the end of the binary, at least for `-no-pie` links. This patch places .lrodata after all other non-special sections at the end of the binary. For simplicity we do the same for `-shared`/`-pie` links, although this introduces a new PT_LOAD segment.

Fixes #<!-- -->78521

---
Full diff: https://github.com/llvm/llvm-project/pull/81202.diff


3 Files Affected:

- (modified) lld/ELF/Writer.cpp (+10-8) 
- (modified) lld/test/ELF/lto/codemodel.ll (+2-2) 
- (modified) lld/test/ELF/x86-64-section-layout.s (+50-48) 


``````````diff
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6df43a34be013..e844c64e56b7a 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -911,11 +911,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_RO = 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,
@@ -973,9 +974,10 @@ static unsigned getSectionRank(OutputSection &osec) {
     // .dynstr and .dynsym can be away from .text.
     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))
-      rank |= RF_LARGE;
+    // Place .lrodata at the end of the binary so it doesn't push small sections
+    // out of the low 2GB of the address space in -no-pie links.
+    if (osec.flags & SHF_X86_64_LARGE && config->emachine == EM_X86_64)
+      rank |= RF_LARGE_RO;
   } else if (isExec) {
     rank |= isWrite ? RF_EXEC_WRITE : RF_EXEC;
   } else {
diff --git a/lld/test/ELF/lto/codemodel.ll b/lld/test/ELF/lto/codemodel.ll
index a35f87729411d..9350e1335386e 100644
--- a/lld/test/ELF/lto/codemodel.ll
+++ b/lld/test/ELF/lto/codemodel.ll
@@ -13,8 +13,8 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
 define ptr @_start() nounwind readonly {
 entry:
 ; CHECK-SMALL-LABEL:  <_start>:
-; CHECK-SMALL: movl    $2097440, %eax
+; CHECK-SMALL: movl    ${{[0-9]+}}, %eax
 ; CHECK-LARGE-LABEL: <_start>:
-; CHECK-LARGE: movabsq $2097440, %rax
+; CHECK-LARGE: movabsq ${{[0-9]+}}, %rax
     ret ptr @data
 }
diff --git a/lld/test/ELF/x86-64-section-layout.s b/lld/test/ELF/x86-64-section-layout.s
index 37201279fa0a5..9759ba398a9fb 100644
--- a/lld/test/ELF/x86-64-section-layout.s
+++ b/lld/test/ELF/x86-64-section-layout.s
@@ -15,60 +15,62 @@
 # RUN: ld.lld -T b.lds -z norelro a.o -o b
 # RUN: llvm-readelf -S -l b | FileCheck %s --check-prefix=CHECK2
 
-# 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:      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: .rodata           PROGBITS        0000000000200301 000301 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
 ## 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        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: .lrodata          PROGBITS        0000000000206b0c 000b0c 000002 00  Al  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:      Program Headers:
+# CHECK-NEXT:   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# CHECK-NEXT:   PHDR           0x000040 0x0000000000200040 0x0000000000200040 0x000268 0x000268 R   0x8
+# CHECK-NEXT:   LOAD           0x000000 0x0000000000200000 0x0000000000200000 0x000302 0x000302 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           0x000b0c 0x0000000000206b0c 0x0000000000206b0c 0x000002 0x000002 R   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        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: .lrodata          PROGBITS        000000000020430a 00030a 000002 00  Al  0   0  1
+# CHECK1-NEXT: .comment          PROGBITS        0000000000000000 00030c {{.*}} 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:      .note             NOTE            0000000000200300 000300 000001 00   A  0   0  1
+# CHECK2-NEXT: .rodata           PROGBITS        0000000000200301 000301 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
 ## 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          PROGBITS        0000000000201b0c 001b0c 000001 00  Al  0   0  1
+# CHECK2-NEXT: .lrodata.1        PROGBITS        0000000000201b0d 001b0d 000001 00  Al  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:     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 0x000302 0x000302 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 0x000002 0x000002 R   0x1000
 
 #--- a.s
 .globl _start

``````````

</details>


https://github.com/llvm/llvm-project/pull/81202


More information about the llvm-commits mailing list