diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index 40f14bb5f037..7a3fedb51001 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -58,7 +58,7 @@ protected: // Build the atom to address map, this has to be called // before applying relocations - virtual void buildAtomToAddressMap(); + virtual void buildAtomToAddressMap(const File &file); // Build the symbol table for static linking virtual void buildStaticSymbolTable(const File &file); @@ -167,14 +167,25 @@ void OutputELFWriter::buildDynamicSymbolTable(const File &file) { _dynamicSymbolTable->addSymbolsToHashTable(); } -template void OutputELFWriter::buildAtomToAddressMap() { +template +void OutputELFWriter::buildAtomToAddressMap(const File &file) { + int64_t totalAbsAtoms = _layout->absoluteAtoms().size(); + int64_t totalUndefinedAtoms = file.undefined().size(); + int64_t totalDefinedAtoms = 0; for (auto sec : _layout->sections()) - if (auto section = dyn_cast>(sec)) + if (auto section = dyn_cast >(sec)) { + totalDefinedAtoms += section->atoms().size(); for (const auto &atom : section->atoms()) _atomToAddressMap[atom->_atom] = atom->_virtualAddr; + } // build the atomToAddressMap that contains absolute symbols too for (auto &atom : _layout->absoluteAtoms()) _atomToAddressMap[atom->_atom] = atom->_virtualAddr; + + // Set the total number of atoms in the symbol table, so that appropriate + // resizing of the string table can be done + _symtab->setNumEntries(totalDefinedAtoms + totalAbsAtoms + + totalUndefinedAtoms); } template @@ -287,7 +298,7 @@ error_code OutputELFWriter::buildOutput(const File &file) { finalizeDefaultAtomValues(); // Build the Atom To Address map for applying relocations - buildAtomToAddressMap(); + buildAtomToAddressMap(file); // Create symbol table and section string table buildStaticSymbolTable(file); diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index 8237529629f0..89d313fa9022 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -510,6 +510,10 @@ public: virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer); + inline void setNumEntries(int64_t numEntries) { + _stringMap.resize(numEntries); + } + private: std::vector _strings; @@ -597,8 +601,15 @@ class SymbolTable : public Section { public: SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order); - void addSymbol(const Atom *atom, int32_t sectionIndex, - uint64_t addr = 0, const AtomLayout *layout=nullptr); + /// \brief set the number of entries that would exist in the symbol + /// table for the current link + void setNumEntries(int64_t numEntries) const { + if (_stringSection) + _stringSection->setNumEntries(numEntries); + } + + void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0, + const AtomLayout *layout = nullptr); /// \brief Get the symbol table index for an Atom. If it's not in the symbol /// table, return STN_UNDEF.