summaryrefslogtreecommitdiffstats
path: root/lld/ELF/MarkLive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/MarkLive.cpp')
-rw-r--r--lld/ELF/MarkLive.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 8f75de6dc30..9528708b584 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -170,12 +170,7 @@ template <class ELFT> static bool isReserved(InputSectionBase *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
return true;
- // We do not want to reclaim sections if they can be referred
- // by __start_* and __stop_* symbols.
StringRef S = Sec->Name;
- if (isValidCIdentifier(S))
- return true;
-
return S.startswith(".ctors") || S.startswith(".dtors") ||
S.startswith(".init") || S.startswith(".fini") ||
S.startswith(".jcr");
@@ -226,11 +221,22 @@ template <class ELFT> void elf::markLive() {
for (StringRef S : Config->Undefined)
MarkSymbol(Symtab<ELFT>::X->find(S));
+ // Remember which __start_* or __stop_* symbols are used so that we don't gc
+ // those sections.
+ DenseSet<StringRef> UsedStartStopNames;
+
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
- for (const Symbol *S : Symtab<ELFT>::X->getSymbols())
- if (S->includeInDynsym())
+ for (const Symbol *S : Symtab<ELFT>::X->getSymbols()) {
+ if (auto *U = dyn_cast_or_null<Undefined>(S->body())) {
+ StringRef Name = U->getName();
+ for (StringRef Prefix : {"__start_", "__stop_"})
+ if (Name.startswith(Prefix))
+ UsedStartStopNames.insert(Name.substr(Prefix.size()));
+ } else if (S->includeInDynsym()) {
MarkSymbol(S->body());
+ }
+ }
// Preserve special sections and those which are specified in linker
// script KEEP command.
@@ -240,7 +246,8 @@ template <class ELFT> void elf::markLive() {
// referred by .eh_frame here.
if (auto *EH = dyn_cast_or_null<EhInputSection<ELFT>>(Sec))
scanEhFrameSection<ELFT>(*EH, Enqueue);
- if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec))
+ if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec) ||
+ UsedStartStopNames.count(Sec->Name))
Enqueue({Sec, 0});
}
OpenPOWER on IntegriCloud