diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-03-02 01:50:34 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-03-02 01:50:34 +0000 |
commit | f32828a9870f0e6e346c79ea2277e4cef6fa1372 (patch) | |
tree | 5909350c30a3dbf02f721f9e89971008015e0d32 /lld/ELF/MarkLive.cpp | |
parent | 4a32770b93b9b0a0002ebfc794c96b649696715f (diff) |
Make gc a bit more aggressive.
We were not gcing any section whose name was a C identifier. Both gold
and bfd only keep those if they are used.
To avoid having to create the __start/__stop symbols early or doing
string lookups in resolvedReloc, this patch just looks for undefined
symbols __start/__stop to decide if a section is needed or not.
Diffstat (limited to 'lld/ELF/MarkLive.cpp')
-rw-r--r-- | lld/ELF/MarkLive.cpp | 23 |
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}); } |