mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 04:36:31 +00:00
[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/20250221125520.14035-1-ceggers@arri.de/
This commit is contained in:
parent
14176d1084
commit
381599f1fe
@ -988,20 +988,8 @@ OutputDesc *ScriptParser::readOverlaySectionDescription() {
|
||||
ctx.script->createOutputSection(readName(), getCurrentLocation());
|
||||
osd->osec.inOverlay = true;
|
||||
expect("{");
|
||||
while (auto tok = till("}")) {
|
||||
uint64_t withFlags = 0;
|
||||
uint64_t withoutFlags = 0;
|
||||
if (tok == "INPUT_SECTION_FLAGS") {
|
||||
std::tie(withFlags, withoutFlags) = readInputSectionFlags();
|
||||
tok = till("");
|
||||
}
|
||||
if (tok == "CLASS")
|
||||
osd->osec.commands.push_back(make<InputSectionDescription>(
|
||||
StringRef{}, withFlags, withoutFlags, readSectionClassName()));
|
||||
else
|
||||
osd->osec.commands.push_back(
|
||||
readInputSectionRules(tok, withFlags, withoutFlags));
|
||||
}
|
||||
while (auto tok = till("}"))
|
||||
osd->osec.commands.push_back(readInputSectionDescription(tok));
|
||||
osd->osec.phdrs = readOutputSectionPhdrs();
|
||||
return osd;
|
||||
}
|
||||
|
51
lld/test/ELF/linkerscript/overlay-keep.test
Normal file
51
lld/test/ELF/linkerscript/overlay-keep.test
Normal file
@ -0,0 +1,51 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: rm -rf %t && split-file %s %t && cd %t
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
|
||||
# RUN: ld.lld a.o --gc-sections --script nokeep.t -o a
|
||||
# RUN: llvm-objdump --section-headers a | FileCheck --check-prefix=NOKEEP %s
|
||||
# RUN: ld.lld a.o --gc-sections --script keep.t -o a
|
||||
# RUN: llvm-objdump --section-headers a | FileCheck --check-prefix=KEEP %s
|
||||
|
||||
# NOKEEP: Sections:
|
||||
# NOKEEP-NEXT: Idx Name Size
|
||||
# NOKEEP-NEXT: 0 00000000
|
||||
# NOKEEP-NEXT: 1 .text 00000004
|
||||
# NOKEEP-NEXT: 2 .keep1 00000000
|
||||
|
||||
# KEEP: Sections:
|
||||
# KEEP-NEXT: Idx Name Size
|
||||
# KEEP-NEXT: 0 00000000
|
||||
# KEEP-NEXT: 1 .text 00000004
|
||||
# KEEP-NEXT: 2 .keep1 00000004
|
||||
# KEEP-NEXT: 3 .keep2 00000004
|
||||
|
||||
#--- a.s
|
||||
.global _start
|
||||
_start:
|
||||
.long 1
|
||||
|
||||
.section .keep1, "a"
|
||||
keep1:
|
||||
.long 2
|
||||
|
||||
.section .keep2, "a"
|
||||
keep2:
|
||||
.long 3
|
||||
|
||||
#--- nokeep.t
|
||||
SECTIONS {
|
||||
.text : { *(.text) }
|
||||
OVERLAY 0x1000 : AT ( 0x4000 ) {
|
||||
.keep1 { *(.keep1) }
|
||||
.keep2 { *(.keep2) }
|
||||
}
|
||||
}
|
||||
|
||||
#--- keep.t
|
||||
SECTIONS {
|
||||
.text : { *(.text) }
|
||||
OVERLAY 0x1000 : AT ( 0x4000 ) {
|
||||
.keep1 { KEEP(*(.keep1)) }
|
||||
.keep2 { KEEP(*(.keep2)) }
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user