diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 6583d7d8e5627e36bab4f7f58f28ce9a742fa152..1ea2f4dbe39fac9adab9b8545a81181c91f9e3c6 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -399,6 +399,9 @@ struct Ctx { // A tuple of (reference, extractedFile, sym). Used by --why-extract=. SmallVector, 0> whyExtractRecords; + // Store duplicate symbols (only defined). + typedef llvm::DenseMap eSymsCntMap; + llvm::DenseSet eSymsHist; // A mapping from a symbol to an InputFile referencing it backward. Used by // --warn-backrefs. llvm::DenseMapundefined) addUnusedUndefined(name)->referenced = true; + // Fill eSymsHist for defined syms. This will help to find duplicates. + if (config->adlt) { + Ctx::eSymsCntMap eSymsHist; + for (auto *file : files) + buildSymsHist(file, eSymsHist); + for (auto eSym : eSymsHist) + if (eSym.second > 1) + ctx->eSymsHist.insert(eSym.first); + eSymsHist.clear(); + } + // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. This process might // add files to the link, via autolinking, these files are always diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 0c9a7e00682255692e123e1f2f48c6455e4f0362..aa908ea4c55083debc4a918847f105c3285ba1ed 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -158,6 +158,18 @@ static bool isCompatible(InputFile *file) { return false; } +template +static void doBuildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist) { + if (!isCompatible(file)) + return; + if (auto *f = dyn_cast>(file)) + f->buildSymsHist(eSymsHist); +} + +void elf::buildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist) { + invokeELFT(doBuildSymsHist, file, eSymsHist); +} + template static void doParseFile(InputFile *file) { if (!isCompatible(file)) return; @@ -1034,6 +1046,17 @@ InputSectionBase *ObjFile::createInputSection(uint32_t idx, return make(*this, sec, name); } +template +void ObjFile::buildSymsHist(Ctx::eSymsCntMap &eSymsHist) { + ArrayRef eSyms = this->getELFSyms(); + for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { + if (!eSyms[i].isDefined()) + continue; + StringRef name = CHECK(eSyms[i].getName(stringTable), this); + eSymsHist[CachedHashStringRef(name)]++; + } +} + // Initialize this->Symbols. this->Symbols is a parallel array as // its corresponding ELF symbol table. template @@ -1047,10 +1070,11 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) if (!symbols[i]) { StringRef name = CHECK(eSyms[i].getName(stringTable), this); - if (config->adlt && name == "__cfi_check") { - name = this->getUniqueName(name); - if (!ctx->adltWithCfi) + if (config->adlt && eSyms[i].isDefined() && + ctx->eSymsHist.count(CachedHashStringRef(name)) != 0) { + if (!ctx->adltWithCfi && name == "__cfi_check") ctx->adltWithCfi = true; + name = this->getUniqueName(name); } symbols[i] = symtab.insert(name); } diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 1db53c987f94ae0b383afa3affbd3fc491bd68ba..65152c33727952018484e56c456d731edfe508f5 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -47,6 +47,7 @@ extern std::unique_ptr tar; llvm::Optional readFile(StringRef path); // Add symbols in File to the symbol table. +void buildSymsHist(InputFile *file, Ctx::eSymsCntMap &eSymsHist); void parseFile(InputFile *file); // The root class of input files. @@ -292,6 +293,7 @@ public: // Get cached DWARF information. DWARFCache *getDwarf(); + void buildSymsHist(Ctx::eSymsCntMap &eSymsHist); void initializeLocalSymbols(); void postParse();