diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 7adc35f20984a..1570adf137093 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1744,8 +1744,10 @@ createBitcodeSymbol(Symbol *&sym, const std::vector &keptComdats, uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE; uint8_t visibility = mapVisibility(objSym.getVisibility()); + // Symbols can be duplicated in bitcode files because of '#include' and + // linkonce_odr. Use unique_saver to save symbol names for de-duplication. if (!sym) - sym = symtab.insert(saver().save(objSym.getName())); + sym = symtab.insert(unique_saver().save(objSym.getName())); int c = objSym.getComdatIndex(); if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) { @@ -1797,7 +1799,9 @@ void BitcodeFile::parseLazy() { symbols = std::make_unique(numSymbols); for (auto [i, irSym] : llvm::enumerate(obj->symbols())) if (!irSym.isUndefined()) { - auto *sym = symtab.insert(saver().save(irSym.getName())); + // Symbols can be duplicated in bitcode files because of '#include' and + // linkonce_odr. Use unique_saver to save symbol names for de-duplication. + auto *sym = symtab.insert(unique_saver().save(irSym.getName())); sym->resolve(LazySymbol{*this}); symbols[i] = sym; } diff --git a/lld/include/lld/Common/CommonLinkerContext.h b/lld/include/lld/Common/CommonLinkerContext.h index 0627bbdc8bd87..9970dfcb713f8 100644 --- a/lld/include/lld/Common/CommonLinkerContext.h +++ b/lld/include/lld/Common/CommonLinkerContext.h @@ -38,6 +38,7 @@ class CommonLinkerContext { llvm::BumpPtrAllocator bAlloc; llvm::StringSaver saver{bAlloc}; + llvm::UniqueStringSaver unique_saver{bAlloc}; llvm::DenseMap instances; ErrorHandler e; @@ -54,8 +55,13 @@ template T &context() { bool hasContext(); -inline llvm::StringSaver &saver() { return context().saver; } inline llvm::BumpPtrAllocator &bAlloc() { return context().bAlloc; } +inline llvm::StringSaver &saver() { return context().saver; } +inline llvm::UniqueStringSaver &unique_saver() { + // FIXME: Look into other places where duplications are common in saved + // strings and unique saver make sense. + return context().unique_saver; +} } // namespace lld #endif