diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -291,6 +291,10 @@ // GOT, which means that the ifunc must be available when the main partition is // loaded) and TLS symbols (because we only know how to correctly process TLS // relocations for the main partition). +// +// We also need to move sections whose names are C identifiers that are referred +// to from __start_/__stop_ symbols because there will only be one set of +// symbols for the whole program. template void MarkLive::moveToMain() { for (InputFile *file : objectFiles) for (Symbol *s : file->getSymbols()) @@ -299,6 +303,14 @@ d->section->isLive()) markSymbol(s); + for (InputSectionBase *sec : inputSections) { + if (!sec->isLive() || !isValidCIdentifier(sec->name)) + continue; + if (symtab->find(("__start_" + sec->name).str()) || + symtab->find(("__stop_" + sec->name).str())) + enqueue(sec, 0); + } + mark(); } diff --git a/lld/test/ELF/partition-move-to-main-startstop.s b/lld/test/ELF/partition-move-to-main-startstop.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/partition-move-to-main-startstop.s @@ -0,0 +1,43 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux +// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections +// RUN: llvm-readelf -S %t | FileCheck --implicit-check-not=has_startstop %s + +// We can't let the has_startstop section be split by partition because it is +// referenced by __start_ and __stop_ symbols, so the split could result in +// some sections being moved out of the __start_/__stop_ range. Make sure that +// that didn't happen by checking that there is only one section. +// +// It's fine for us to split no_startstop because of the lack of +// __start_/__stop_ symbols. + +// CHECK: has_startstop +// CHECK: no_startstop + +// CHECK: no_startstop + +.section .llvm_sympart.f1,"",@llvm_sympart +.asciz "part1" +.quad f1 + +.section .text._start,"ax",@progbits +.globl _start +_start: +call __start_has_startstop +call __stop_has_startstop + +.section .text.f1,"ax",@progbits +.globl f1 +f1: + +.section has_startstop,"ao",@progbits,.text._start,unique,1 +.quad 1 + +.section has_startstop,"ao",@progbits,.text.f1,unique,2 +.quad 2 + +.section no_startstop,"ao",@progbits,.text._start,unique,1 +.quad 3 + +.section no_startstop,"ao",@progbits,.text.f1,unique,2 +.quad 4