Skip to content

Commit 278f80c

Browse files
MaskRaytstellar
authored andcommitted
[ELF] Fix compareSections assertion failure when OutputDescs in sectionCommands are non-contiguous
In a `--defsym y0=0 -T a.lds` link where a.lds contains only INSERT commands, the `script->sectionCommands` layout may be: ``` orphan sections SymbolAssignment due to --defsym sections created by INSERT commands ``` The `OutputDesc` objects are not contiguous in sortInputSections, and `compareSections` will be called with a SymbolAssignment argument, leading to an assertion failure. (cherry picked from commit dee8786)
1 parent eeaf41b commit 278f80c

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

lld/ELF/Writer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,12 +1518,12 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
15181518
if (auto *osd = dyn_cast<OutputDesc>(cmd))
15191519
osd->osec.sortRank = getSectionRank(osd->osec);
15201520
if (!script->hasSectionsCommand) {
1521-
// We know that all the OutputSections are contiguous in this case.
1522-
auto isSection = [](SectionCommand *cmd) { return isa<OutputDesc>(cmd); };
1523-
std::stable_sort(
1524-
llvm::find_if(script->sectionCommands, isSection),
1525-
llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(),
1526-
compareSections);
1521+
// OutputDescs are mostly contiguous, but may be interleaved with
1522+
// SymbolAssignments in the presence of INSERT commands.
1523+
auto mid = std::stable_partition(
1524+
script->sectionCommands.begin(), script->sectionCommands.end(),
1525+
[](SectionCommand *cmd) { return isa<OutputDesc>(cmd); });
1526+
std::stable_sort(script->sectionCommands.begin(), mid, compareSections);
15271527
}
15281528

15291529
// Process INSERT commands and update output section attributes. From this

lld/test/ELF/linkerscript/insert-before.test

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
## without making more layout changes. Address/offset assignments are different
2525
## with a main linker script.
2626

27-
# RUN: ld.lld --script %s %t1.o -o %t2
28-
# RUN: llvm-readelf -S -l %t2 | FileCheck --check-prefix=CHECK2 %s
27+
## Test non-contiguous OutputDescs in script->sectionCommands.
28+
# RUN: ld.lld --defsym y0=1 %s --defsym y1=1 %t1.o -o %t2
29+
# RUN: llvm-readelf -S -l -sX %t2 | FileCheck --check-prefix=CHECK2 %s
2930
# CHECK2: Name Type Address Off Size ES Flg
3031
# CHECK2-NEXT: NULL
3132
# CHECK2-NEXT: .foo.text PROGBITS 000000000020{{.*}} [[#%x,]] 000008 00 AX
@@ -40,9 +41,13 @@
4041
# CHECK2-NEXT: LOAD {{.*}} RW 0x1000
4142
# CHECK2-NEXT: GNU_STACK {{.*}} RW 0
4243

44+
# CHECK2: NOTYPE GLOBAL DEFAULT ABS y0
45+
# CHECK2: NOTYPE GLOBAL DEFAULT [[#]] (.foo.text) x0
46+
# CHECK2: NOTYPE GLOBAL DEFAULT ABS y1
47+
4348
SECTIONS { .byte : { BYTE(0) } } INSERT BEFORE .data;
4449

4550
SECTIONS { .foo.data : { *(.foo.data) } } INSERT BEFORE .data;
4651

4752
## The input section .foo.text is an orphan. It will be placed in .foo.text
48-
SECTIONS { .foo.text : {} } INSERT BEFORE .text;
53+
SECTIONS { .foo.text : { x0 = .; } } INSERT BEFORE .text;

0 commit comments

Comments
 (0)