[lld] [LLD][ELF] Fix SHF_MERGE misalignment when spilled (PR #119289)
Daniel Thornburgh via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 10 11:24:23 PST 2024
https://github.com/mysterymath updated https://github.com/llvm/llvm-project/pull/119289
>From 2f4b8f5d5b5ff66bb1bcec1d0fa5417abc354ba7 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Thu, 5 Dec 2024 16:24:28 -0800
Subject: [PATCH 1/3] [LLD][ELF] Fix SHF_MERGE misalignment when spilled
Section merging can increase section alignment after potential spill
sections are created. Since this operation is never performed on spill
sections, they can keep their earlier, smaller, alignment, which
produces a misalignment if a spill occurs.
This change propagates alignment increases forward after merging.
---
lld/ELF/OutputSections.cpp | 17 ++++++++++++++++-
lld/test/ELF/linkerscript/section-class.test | 10 ++++++----
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 546dc58b4bc843..5e77eeb1ed5988 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -249,12 +249,27 @@ void OutputSection::finalizeInputSections() {
// catch misuses.
isd->sectionBases.clear();
+
// Some input sections may be removed from the list after ICF.
for (InputSection *s : isd->sections)
commitSection(s);
}
- for (auto *ms : mergeSections)
+ for (auto *ms : mergeSections) {
+ // Merging may have increased the alignment of a spillable section. Update
+ // the alignment of potential spill sections and their containing output
+ // sections.
+ if (!script->potentialSpillLists.empty()) {
+ if (auto it = script->potentialSpillLists.find(ms);
+ it != script->potentialSpillLists.end()) {
+ for (PotentialSpillSection *s = it->second.head; s; s = s->next) {
+ s->addralign = std::max(s->addralign, ms->addralign);
+ s->parent->addralign = std::max(s->parent->addralign, s->addralign);
+ }
+ }
+ }
+
ms->finalizeContents();
+ }
}
static void sortByOrder(MutableArrayRef<InputSection *> in,
diff --git a/lld/test/ELF/linkerscript/section-class.test b/lld/test/ELF/linkerscript/section-class.test
index 7fce13bfe3e025..ae1a5026ef0490 100644
--- a/lld/test/ELF/linkerscript/section-class.test
+++ b/lld/test/ELF/linkerscript/section-class.test
@@ -310,6 +310,7 @@ SECTIONS {
.byte 0x12, 0x34
.section .b,"aM", at progbits,1
+.p2align 1
.byte 0x12
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 merge.s -o merge.o
@@ -317,10 +318,11 @@ SECTIONS {
#--- spill-merge.lds
## SHF_MERGE sections are spilled according to the class refs of the first
## merged input section (the one giving the resulting section its name).
+## Spills take into account increases in section alignment due to merging.
MEMORY {
a : ORIGIN = 0, LENGTH = 1
- b : ORIGIN = 1, LENGTH = 2
- c : ORIGIN = 3, LENGTH = 2
+ b : ORIGIN = 1, LENGTH = 4
+ c : ORIGIN = 5, LENGTH = 4
}
SECTIONS {
@@ -336,8 +338,8 @@ SECTIONS {
# SPILL-MERGE: Name Type Address Off Size
# SPILL-MERGE: .first PROGBITS 0000000000000000 000190 000000
-# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000001 001001 000002
-# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000003 001003 000000
+# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000002 001002 000003
+# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000006 001006 000000
#--- link-order.s
.section .a,"a", at progbits
>From a8e632cb70fac69f529d5f68082d3a8eb08619c9 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Mon, 9 Dec 2024 15:57:59 -0800
Subject: [PATCH 2/3] clang-format
---
lld/ELF/OutputSections.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 5e77eeb1ed5988..8d63ba54968440 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -249,7 +249,6 @@ void OutputSection::finalizeInputSections() {
// catch misuses.
isd->sectionBases.clear();
-
// Some input sections may be removed from the list after ICF.
for (InputSection *s : isd->sections)
commitSection(s);
>From 87dae3826eaa1520eedeace5767d400be032e02a Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 10 Dec 2024 11:05:08 -0800
Subject: [PATCH 3/3] Address review feedback
---
lld/ELF/OutputSections.cpp | 12 +++++-------
lld/test/ELF/linkerscript/section-class.test | 16 +++++++++-------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 8d63ba54968440..a2da5543d58670 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -257,13 +257,11 @@ void OutputSection::finalizeInputSections() {
// Merging may have increased the alignment of a spillable section. Update
// the alignment of potential spill sections and their containing output
// sections.
- if (!script->potentialSpillLists.empty()) {
- if (auto it = script->potentialSpillLists.find(ms);
- it != script->potentialSpillLists.end()) {
- for (PotentialSpillSection *s = it->second.head; s; s = s->next) {
- s->addralign = std::max(s->addralign, ms->addralign);
- s->parent->addralign = std::max(s->parent->addralign, s->addralign);
- }
+ if (auto it = script->potentialSpillLists.find(ms);
+ it != script->potentialSpillLists.end()) {
+ for (PotentialSpillSection *s = it->second.head; s; s = s->next) {
+ s->addralign = std::max(s->addralign, ms->addralign);
+ s->parent->addralign = std::max(s->parent->addralign, s->addralign);
}
}
diff --git a/lld/test/ELF/linkerscript/section-class.test b/lld/test/ELF/linkerscript/section-class.test
index ae1a5026ef0490..5c30b6343653e5 100644
--- a/lld/test/ELF/linkerscript/section-class.test
+++ b/lld/test/ELF/linkerscript/section-class.test
@@ -310,7 +310,7 @@ SECTIONS {
.byte 0x12, 0x34
.section .b,"aM", at progbits,1
-.p2align 1
+.p2align 3
.byte 0x12
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 merge.s -o merge.o
@@ -321,8 +321,8 @@ SECTIONS {
## Spills take into account increases in section alignment due to merging.
MEMORY {
a : ORIGIN = 0, LENGTH = 1
- b : ORIGIN = 1, LENGTH = 4
- c : ORIGIN = 5, LENGTH = 4
+ b : ORIGIN = 1, LENGTH = 16
+ c : ORIGIN = 17, LENGTH = 16
}
SECTIONS {
@@ -334,12 +334,14 @@ SECTIONS {
}
# RUN: ld.lld -T spill-merge.lds merge.o -o spill-merge
-# RUN: llvm-readelf -S spill-merge | FileCheck %s --check-prefix=SPILL-MERGE
+# RUN: llvm-readelf -S -x .second spill-merge | FileCheck %s --check-prefix=SPILL-MERGE
-# SPILL-MERGE: Name Type Address Off Size
+# SPILL-MERGE: Name Type Address Off Size
# SPILL-MERGE: .first PROGBITS 0000000000000000 000190 000000
-# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000002 001002 000003
-# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000006 001006 000000
+# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000008 001008 000009
+# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000018 001018 000000
+# SPILL-MERGE: Hex dump of section '.second':
+# SPILL-MERGE-NEXT: 0x00000008 12000000 00000000 34 .
#--- link-order.s
.section .a,"a", at progbits
More information about the llvm-commits
mailing list