Skip to content

Commit 4dac0df

Browse files
authored
[LLD][ELF] Fix SHF_MERGE misalignment when spilled (llvm#119289)
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.
1 parent 951a284 commit 4dac0df

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

lld/ELF/OutputSections.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,20 @@ void OutputSection::finalizeInputSections() {
253253
for (InputSection *s : isd->sections)
254254
commitSection(s);
255255
}
256-
for (auto *ms : mergeSections)
256+
for (auto *ms : mergeSections) {
257+
// Merging may have increased the alignment of a spillable section. Update
258+
// the alignment of potential spill sections and their containing output
259+
// sections.
260+
if (auto it = script->potentialSpillLists.find(ms);
261+
it != script->potentialSpillLists.end()) {
262+
for (PotentialSpillSection *s = it->second.head; s; s = s->next) {
263+
s->addralign = std::max(s->addralign, ms->addralign);
264+
s->parent->addralign = std::max(s->parent->addralign, s->addralign);
265+
}
266+
}
267+
257268
ms->finalizeContents();
269+
}
258270
}
259271

260272
static void sortByOrder(MutableArrayRef<InputSection *> in,

lld/test/ELF/linkerscript/section-class.test

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,19 @@ SECTIONS {
310310
.byte 0x12, 0x34
311311

312312
.section .b,"aM",@progbits,1
313+
.p2align 3
313314
.byte 0x12
314315

315316
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 merge.s -o merge.o
316317

317318
#--- spill-merge.lds
318319
## SHF_MERGE sections are spilled according to the class refs of the first
319320
## merged input section (the one giving the resulting section its name).
321+
## Spills take into account increases in section alignment due to merging.
320322
MEMORY {
321323
a : ORIGIN = 0, LENGTH = 1
322-
b : ORIGIN = 1, LENGTH = 2
323-
c : ORIGIN = 3, LENGTH = 2
324+
b : ORIGIN = 1, LENGTH = 16
325+
c : ORIGIN = 17, LENGTH = 16
324326
}
325327

326328
SECTIONS {
@@ -332,12 +334,14 @@ SECTIONS {
332334
}
333335

334336
# RUN: ld.lld -T spill-merge.lds merge.o -o spill-merge
335-
# RUN: llvm-readelf -S spill-merge | FileCheck %s --check-prefix=SPILL-MERGE
337+
# RUN: llvm-readelf -S -x .second spill-merge | FileCheck %s --check-prefix=SPILL-MERGE
336338

337-
# SPILL-MERGE: Name Type Address Off Size
339+
# SPILL-MERGE: Name Type Address Off Size
338340
# SPILL-MERGE: .first PROGBITS 0000000000000000 000190 000000
339-
# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000001 001001 000002
340-
# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000003 001003 000000
341+
# SPILL-MERGE-NEXT: .second PROGBITS 0000000000000008 001008 000009
342+
# SPILL-MERGE-NEXT: .third PROGBITS 0000000000000018 001018 000000
343+
# SPILL-MERGE: Hex dump of section '.second':
344+
# SPILL-MERGE-NEXT: 0x00000008 12000000 00000000 34 .
341345

342346
#--- link-order.s
343347
.section .a,"a",@progbits

0 commit comments

Comments
 (0)