[lld] [ELF] Orphan placement: prefer the last similar section when its rank <= orphan's rank (PR #94099)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 3 11:24:39 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/94099
>From 899c740415b165a2606596546929e9bfabc1ff86 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Fri, 31 May 2024 23:36:02 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
lld/ELF/Writer.cpp | 10 ++++--
lld/test/ELF/linkerscript/orphan.s | 22 +++++++++++++
lld/test/ELF/linkerscript/sections-nonalloc.s | 33 ++++++++++---------
lld/test/ELF/linkerscript/sections.s | 8 ++---
4 files changed, 50 insertions(+), 23 deletions(-)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 58ae20720a177..685ac0352f1fb 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -935,14 +935,18 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
return i;
}
- // Find the first element that has as close a rank as possible.
if (b == e)
return e;
+ // Select the most similar output section. In case of ties, select the first
+ // section with a rank > the orphan's rank, or the last one with a rank <= the
+ // orphan's rank.
int proximity = getRankProximity(sec, *b);
auto i = b;
for (auto j = b; ++j != e;) {
- int p = getRankProximity(sec, *j);
- if (p > proximity) {
+ auto p = getRankProximity(sec, *j);
+ if (p > proximity ||
+ (p == proximity && proximity >= 0 &&
+ cast<OutputDesc>(*j)->osec.sortRank <= sec->sortRank)) {
proximity = p;
i = j;
}
diff --git a/lld/test/ELF/linkerscript/orphan.s b/lld/test/ELF/linkerscript/orphan.s
index 4f01b181d0416..dc1b49042a987 100644
--- a/lld/test/ELF/linkerscript/orphan.s
+++ b/lld/test/ELF/linkerscript/orphan.s
@@ -65,6 +65,18 @@
# RW-TEXT-NEXT: .text PROGBITS 0000000000001{{...}} 0
# RW-TEXT-NEXT: .mytext PROGBITS 0000000000001{{...}} 0
+# RUN: ld.lld a.o -T rw-text-rw.lds -o rw-text-rw
+# RUN: llvm-readelf -S rw-text-rw | FileCheck %s --check-prefix=RW-TEXT-RW
+# RW-TEXT-RW: .jcr PROGBITS 00000000000002{{..}} 0
+# RW-TEXT-RW-NEXT: .rw1 PROGBITS 00000000000002{{..}} 0
+# RW-TEXT-RW-NEXT: .interp PROGBITS 00000000000002{{..}} 0
+# RW-TEXT-RW-NEXT: .note.my NOTE 00000000000002{{..}} 0
+# RW-TEXT-RW-NEXT: .text PROGBITS 0000000000001{{...}} 0
+# RW-TEXT-RW-NEXT: .mytext PROGBITS 0000000000001{{...}} 0
+# RW-TEXT-RW-NEXT: .rw2 PROGBITS 0000000000002{{...}} 0
+# RW-TEXT-RW-NEXT: .rw3 PROGBITS 0000000000002{{...}} 0
+# RW-TEXT-RW-NEXT: .bss NOBITS 0000000000002{{...}} 0
+
#--- a.s
.section .rw1, "aw"; .byte 0
.section .rw2, "aw"; .byte 0
@@ -112,3 +124,13 @@ SECTIONS {
. = ALIGN(CONSTANT(MAXPAGESIZE));
.text : { *(.text) }
}
+
+#--- rw-text-rw.lds
+SECTIONS {
+ . = SIZEOF_HEADERS;
+ .rw1 : { *(.rw1) }
+ . = ALIGN(CONSTANT(MAXPAGESIZE));
+ .text : { *(.text) }
+ . = ALIGN(CONSTANT(MAXPAGESIZE));
+ .rw2 : { *(.rw2) }
+}
diff --git a/lld/test/ELF/linkerscript/sections-nonalloc.s b/lld/test/ELF/linkerscript/sections-nonalloc.s
index a0669f701d8c9..79765d32dfffe 100644
--- a/lld/test/ELF/linkerscript/sections-nonalloc.s
+++ b/lld/test/ELF/linkerscript/sections-nonalloc.s
@@ -14,15 +14,16 @@
# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0
# CHECK-NEXT: [ 1] .bss NOBITS 0000000000000000 001000 000001 00 WA 0
# CHECK-NEXT: [ 2] data1 PROGBITS 0000000000000001 001001 000001 00 WA 0
-# CHECK-NEXT: [ 3] data3 PROGBITS 0000000000000002 001002 000001 00 WA 0
-# CHECK-NEXT: [ 4] other1 PROGBITS 0000000000000000 001008 000001 00 0
-# CHECK-NEXT: [ 5] other2 PROGBITS 0000000000000000 001010 000001 00 0
+# CHECK-NEXT: [ 3] other1 PROGBITS 0000000000000000 001008 000001 00 0
+# CHECK-NEXT: [ 4] other2 PROGBITS 0000000000000000 001010 000001 00 0
## Orphan placement places other3, .symtab, .shstrtab and .strtab after other2.
-# CHECK-NEXT: [ 6] other3 PROGBITS 0000000000000000 001020 000001 00 0
-# CHECK-NEXT: [ 7] .symtab SYMTAB 0000000000000000 001028 000030 18 9
-# CHECK-NEXT: [ 8] .shstrtab STRTAB 0000000000000000 001058 00004d 00 0
-# CHECK-NEXT: [ 9] .strtab STRTAB 0000000000000000 0010a5 000008 00 0
-# CHECK-NEXT: [10] data2 PROGBITS 0000000000000003 001003 000001 00 WA 0
+# CHECK-NEXT: [ 5] other3 PROGBITS 0000000000000000 001020 000001 00 0
+# CHECK-NEXT: [ 6] .symtab SYMTAB 0000000000000000 001028 000030 18 8
+# CHECK-NEXT: [ 7] .shstrtab STRTAB 0000000000000000 001058 00004d 00 0
+# CHECK-NEXT: [ 8] .strtab STRTAB 0000000000000000 0010a5 000008 00 0
+# CHECK-NEXT: [ 9] data2 PROGBITS 0000000000000002 001002 000001 00 WA 0
+## max{sortRank(data1),sortRank(data2)} <= sortRank(data3). data3 is placed after the latter.
+# CHECK-NEXT: [10] data3 PROGBITS 0000000000000003 001003 000001 00 WA 0
# CHECK-NEXT: [11] .text PROGBITS 0000000000000004 001004 000001 00 AX 0
# CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
@@ -38,14 +39,14 @@
# CHECK1-NEXT: [ 1] .text PROGBITS 00000000000000b0 0000b0 000001 00 AX 0
# CHECK1-NEXT: [ 2] .bss NOBITS 00000000000000b1 0000b1 000001 00 WA 0
# CHECK1-NEXT: [ 3] data1 PROGBITS 00000000000000b2 0000b2 000001 00 WA 0
-# CHECK1-NEXT: [ 4] data3 PROGBITS 00000000000000b3 0000b3 000001 00 WA 0
-# CHECK1-NEXT: [ 5] other1 PROGBITS 0000000000000000 0000b8 000001 00 0
-# CHECK1-NEXT: [ 6] other2 PROGBITS 0000000000000000 0000c0 000001 00 0
-# CHECK1-NEXT: [ 7] other3 PROGBITS 0000000000000000 0000d0 000001 00 0
-# CHECK1-NEXT: [ 8] .symtab SYMTAB 0000000000000000 0000d8 000030 18 10
-# CHECK1-NEXT: [ 9] .shstrtab STRTAB 0000000000000000 000108 00004d 00 0
-# CHECK1-NEXT: [10] .strtab STRTAB 0000000000000000 000155 000008 00 0
-# CHECK1-NEXT: [11] data2 PROGBITS 00000000000000b4 0000b4 000001 00 WA 0
+# CHECK1-NEXT: [ 4] other1 PROGBITS 0000000000000000 0000b8 000001 00 0
+# CHECK1-NEXT: [ 5] other2 PROGBITS 0000000000000000 0000c0 000001 00 0
+# CHECK1-NEXT: [ 6] other3 PROGBITS 0000000000000000 0000d0 000001 00 0
+# CHECK1-NEXT: [ 7] .symtab SYMTAB 0000000000000000 0000d8 000030 18 9
+# CHECK1-NEXT: [ 8] .shstrtab STRTAB 0000000000000000 000108 00004d 00 0
+# CHECK1-NEXT: [ 9] .strtab STRTAB 0000000000000000 000155 000008 00 0
+# CHECK1-NEXT: [10] data2 PROGBITS 00000000000000b3 0000b3 000001 00 WA 0
+# CHECK1-NEXT: [11] data3 PROGBITS 00000000000000b4 0000b4 000001 00 WA 0
# CHECK1: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# CHECK1-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0000b5 0x0000b5 RWE 0x1000
# CHECK1-NEXT: 0x60000000 0x0000b8 0x0000000000000000 0x0000000000000000 0x000009 0x000001 0x8
diff --git a/lld/test/ELF/linkerscript/sections.s b/lld/test/ELF/linkerscript/sections.s
index 539aa9c170588..5d6cc1f3bd0df 100644
--- a/lld/test/ELF/linkerscript/sections.s
+++ b/lld/test/ELF/linkerscript/sections.s
@@ -78,13 +78,13 @@
# SEP-BY-NONALLOC: [Nr] Name Type Address Off Size ES Flg
# SEP-BY-NONALLOC: [ 1] .text PROGBITS 0000000000000000 001000 00000e 00 AX
# SEP-BY-NONALLOC-NEXT: [ 2] .data PROGBITS 000000000000000e 00100e 000020 00 WA
-# SEP-BY-NONALLOC-NEXT: [ 3] .bss NOBITS 000000000000002e 00102e 000002 00 WA
-# SEP-BY-NONALLOC-NEXT: [ 4] .comment PROGBITS 0000000000000000 001033 000008 01 MS
-# SEP-BY-NONALLOC: [ 8] other PROGBITS 0000000000000030 001030 000003 00 WA
+# SEP-BY-NONALLOC-NEXT: [ 3] .comment PROGBITS 0000000000000000 001031 000008 01 MS
+# SEP-BY-NONALLOC: [ 7] other PROGBITS 000000000000002e 00102e 000003 00 WA
+# SEP-BY-NONALLOC-NEXT: [ 8] .bss NOBITS 0000000000000031 001031 000002 00 WA
# SEP-BY-NONALLOC: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# SEP-BY-NONALLOC-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x00000e 0x00000e R E 0x1000
-# SEP-BY-NONALLOC-NEXT: LOAD 0x00100e 0x000000000000000e 0x000000000000000e 0x000025 0x000025 RW 0x1000
+# SEP-BY-NONALLOC-NEXT: LOAD 0x00100e 0x000000000000000e 0x000000000000000e 0x000023 0x000025 RW 0x1000
# SEP-BY-NONALLOC-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
# Input section pattern contains additional semicolon.
>From 9d4111682cc900191a4133294b9caeb5d4642ec6 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 3 Jun 2024 11:24:30 -0700
Subject: [PATCH 2/2] simplify
Created using spr 1.3.5-bogner
---
lld/ELF/Writer.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index e777d486f44a9..0295a656b0705 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -941,18 +941,17 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
//
// In the event of proximity ties, we select the first or last section
// depending on whether the orphan's rank is smaller.
- int maxP = -1;
+ int maxP = 0;
auto i = e;
for (auto j = b; j != e; ++j) {
int p = getRankProximity(sec, *j);
if (p > maxP ||
- (p == maxP && maxP >= 0 &&
- cast<OutputDesc>(*j)->osec.sortRank <= sec->sortRank)) {
+ (p == maxP && cast<OutputDesc>(*j)->osec.sortRank <= sec->sortRank)) {
maxP = p;
i = j;
}
}
- if (maxP == -1)
+ if (i == e)
return e;
auto isOutputSecWithInputSections = [](SectionCommand *cmd) {
More information about the llvm-commits
mailing list