Skip to content

Commit 381599f

Browse files
authored
[ELF] Allow KEEP within OVERLAY (#130661)
When attempting to add KEEP within an OVERLAY description, which the Linux kernel would like to do for ARCH=arm to avoid dropping the .vectors sections with '--gc-sections' [1], ld.lld errors with: ld.lld: error: ./arch/arm/kernel/vmlinux.lds:37: section pattern is expected >>> __vectors_lma = .; OVERLAY 0xffff0000 : AT(__vectors_lma) { .vectors { KEEP(*(.vectors)) } ... >>> ^ readOverlaySectionDescription() does not handle all input section description keywords, despite GNU ld's documentation stating that "The section definitions within the OVERLAY construct are identical to those within the general SECTIONS construct, except that no addresses and no memory regions may be defined for sections within an OVERLAY." Reuse the existing parsing in readInputSectionDescription(), which handles KEEP, allowing the Linux kernel's use case to work properly. [1]: https://lore.kernel.org/[email protected]/
1 parent 14176d1 commit 381599f

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

lld/ELF/ScriptParser.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -988,20 +988,8 @@ OutputDesc *ScriptParser::readOverlaySectionDescription() {
988988
ctx.script->createOutputSection(readName(), getCurrentLocation());
989989
osd->osec.inOverlay = true;
990990
expect("{");
991-
while (auto tok = till("}")) {
992-
uint64_t withFlags = 0;
993-
uint64_t withoutFlags = 0;
994-
if (tok == "INPUT_SECTION_FLAGS") {
995-
std::tie(withFlags, withoutFlags) = readInputSectionFlags();
996-
tok = till("");
997-
}
998-
if (tok == "CLASS")
999-
osd->osec.commands.push_back(make<InputSectionDescription>(
1000-
StringRef{}, withFlags, withoutFlags, readSectionClassName()));
1001-
else
1002-
osd->osec.commands.push_back(
1003-
readInputSectionRules(tok, withFlags, withoutFlags));
1004-
}
991+
while (auto tok = till("}"))
992+
osd->osec.commands.push_back(readInputSectionDescription(tok));
1005993
osd->osec.phdrs = readOutputSectionPhdrs();
1006994
return osd;
1007995
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# REQUIRES: x86
2+
# RUN: rm -rf %t && split-file %s %t && cd %t
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
4+
# RUN: ld.lld a.o --gc-sections --script nokeep.t -o a
5+
# RUN: llvm-objdump --section-headers a | FileCheck --check-prefix=NOKEEP %s
6+
# RUN: ld.lld a.o --gc-sections --script keep.t -o a
7+
# RUN: llvm-objdump --section-headers a | FileCheck --check-prefix=KEEP %s
8+
9+
# NOKEEP: Sections:
10+
# NOKEEP-NEXT: Idx Name Size
11+
# NOKEEP-NEXT: 0 00000000
12+
# NOKEEP-NEXT: 1 .text 00000004
13+
# NOKEEP-NEXT: 2 .keep1 00000000
14+
15+
# KEEP: Sections:
16+
# KEEP-NEXT: Idx Name Size
17+
# KEEP-NEXT: 0 00000000
18+
# KEEP-NEXT: 1 .text 00000004
19+
# KEEP-NEXT: 2 .keep1 00000004
20+
# KEEP-NEXT: 3 .keep2 00000004
21+
22+
#--- a.s
23+
.global _start
24+
_start:
25+
.long 1
26+
27+
.section .keep1, "a"
28+
keep1:
29+
.long 2
30+
31+
.section .keep2, "a"
32+
keep2:
33+
.long 3
34+
35+
#--- nokeep.t
36+
SECTIONS {
37+
.text : { *(.text) }
38+
OVERLAY 0x1000 : AT ( 0x4000 ) {
39+
.keep1 { *(.keep1) }
40+
.keep2 { *(.keep2) }
41+
}
42+
}
43+
44+
#--- keep.t
45+
SECTIONS {
46+
.text : { *(.text) }
47+
OVERLAY 0x1000 : AT ( 0x4000 ) {
48+
.keep1 { KEEP(*(.keep1)) }
49+
.keep2 { KEEP(*(.keep2)) }
50+
}
51+
}

0 commit comments

Comments
 (0)