summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r--lld/ELF/Writer.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 540516ba80e..a616fdc51a9 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -385,6 +385,34 @@ static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
error(Msg);
}
+template <class ELFT>
+static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
+ const typename ELFFile<ELFT>::Elf_Sym &Sym) {
+ if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
+ return false;
+
+ InputSectionBase<ELFT> *Sec = File.getSection(Sym);
+ // If sym references a section in a discarded group, don't keep it.
+ if (Sec == &InputSection<ELFT>::Discarded)
+ return false;
+
+ if (Config->DiscardNone)
+ return true;
+
+ // In ELF assembly .L symbols are normally discarded by the assembler.
+ // If the assembler fails to do so, the linker discards them if
+ // * --discard-locals is used.
+ // * The symbol is in a SHF_MERGE section, which is normally the reason for
+ // the assembler keeping the .L symbol.
+ if (!SymName.startswith(".L") && !SymName.empty())
+ return true;
+
+ if (Config->DiscardLocals)
+ return false;
+
+ return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
+}
+
// Local symbols are not in the linker's symbol table. This function scans
// each object file's symbol table to copy local symbols to the output.
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
@@ -403,6 +431,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
continue;
}
Out<ELFT>::SymTab->addLocalSymbol(SymName);
+ F->KeptLocalSyms.push_back(&Sym);
}
}
}
OpenPOWER on IntegriCloud