diff options
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 21 | ||||
| -rw-r--r-- | lld/lib/Core/SymbolTable.cpp | 28 |
2 files changed, 28 insertions, 21 deletions
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index d139f8a4625..6ed35598d60 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -48,15 +48,12 @@ private: } // namespace void Resolver::handleFile(const File &file) { - bool isEmpty = file.defined().empty() && file.undefined().empty() && - file.sharedLibrary().empty() && file.absolute().empty(); - if (isEmpty) - return; - + bool undefAdded = false; for (const DefinedAtom *atom : file.defined()) doDefinedAtom(*atom); for (const UndefinedAtom *atom : file.undefined()) - doUndefinedAtom(*atom); + if (doUndefinedAtom(*atom)) + undefAdded = true; for (const SharedLibraryAtom *atom : file.sharedLibrary()) doSharedLibraryAtom(*atom); for (const AbsoluteAtom *atom : file.absolute()) @@ -65,7 +62,9 @@ void Resolver::handleFile(const File &file) { // Notify the input file manager of the fact that we have made some progress // on linking using the current input file. It may want to know the fact for // --start-group/--end-group. - _context.getInputGraph().notifyProgress(); + if (undefAdded) { + _context.getInputGraph().notifyProgress(); + } } void Resolver::forEachUndefines(bool searchForOverrides, @@ -124,7 +123,7 @@ void Resolver::handleSharedLibrary(const File &file) { }); } -void Resolver::doUndefinedAtom(const UndefinedAtom &atom) { +bool Resolver::doUndefinedAtom(const UndefinedAtom &atom) { DEBUG_WITH_TYPE("resolver", llvm::dbgs() << " UndefinedAtom: " << llvm::format("0x%09lX", &atom) @@ -134,7 +133,7 @@ void Resolver::doUndefinedAtom(const UndefinedAtom &atom) { _atoms.push_back(&atom); // tell symbol table - _symbolTable.add(atom); + bool newUndefAdded = _symbolTable.add(atom); // If the undefined symbol has an alternative name, try to resolve the // symbol with the name to give it a second chance. This feature is used @@ -145,6 +144,7 @@ void Resolver::doUndefinedAtom(const UndefinedAtom &atom) { _symbolTable.addReplacement(&atom, fallbackAtom); } } + return newUndefAdded; } /// \brief Add the section group and the group-child reference members. @@ -178,7 +178,8 @@ bool Resolver::maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom) { return true; } -// called on each atom when a file is added +// Called on each atom when a file is added. Returns true if a given +// atom is added to the symbol table. void Resolver::doDefinedAtom(const DefinedAtom &atom) { DEBUG_WITH_TYPE("resolver", llvm::dbgs() << " DefinedAtom: " diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp index a6620753424..81ed9bb0b5e 100644 --- a/lld/lib/Core/SymbolTable.cpp +++ b/lld/lib/Core/SymbolTable.cpp @@ -32,26 +32,26 @@ namespace lld { SymbolTable::SymbolTable(const LinkingContext &context) : _context(context) {} -void SymbolTable::add(const UndefinedAtom &atom) { addByName(atom); } +bool SymbolTable::add(const UndefinedAtom &atom) { return addByName(atom); } -void SymbolTable::add(const SharedLibraryAtom &atom) { addByName(atom); } +bool SymbolTable::add(const SharedLibraryAtom &atom) { return addByName(atom); } -void SymbolTable::add(const AbsoluteAtom &atom) { addByName(atom); } +bool SymbolTable::add(const AbsoluteAtom &atom) { return addByName(atom); } -void SymbolTable::add(const DefinedAtom &atom) { +bool SymbolTable::add(const DefinedAtom &atom) { if (!atom.name().empty() && atom.scope() != DefinedAtom::scopeTranslationUnit) { // Named atoms cannot be merged by content. assert(atom.merge() != DefinedAtom::mergeByContent); // Track named atoms that are not scoped to file (static). - addByName(atom); - return; + return addByName(atom); } if (atom.merge() == DefinedAtom::mergeByContent) { // Named atoms cannot be merged by content. assert(atom.name().empty()); - addByContent(atom); + return addByContent(atom); } + return false; } const Atom *SymbolTable::findGroup(StringRef sym) { @@ -162,16 +162,20 @@ static uint64_t sectionSize(const DefinedAtom *atom) { + getSizeFollowReferences(atom, lld::Reference::kindLayoutAfter); } -void SymbolTable::addByName(const Atom &newAtom) { +bool SymbolTable::addByName(const Atom &newAtom) { StringRef name = newAtom.name(); assert(!name.empty()); const Atom *existing = findByName(name); if (existing == nullptr) { // Name is not in symbol table yet, add it associate with this atom. _nameTable[name] = &newAtom; - return; + return true; } + // Do nothing if the same object is added more than once. + if (existing == &newAtom) + return false; + // Name is already in symbol table and associated with another atom. bool useNew = true; switch (collide(existing->definition(), newAtom.definition())) { @@ -301,6 +305,7 @@ void SymbolTable::addByName(const Atom &newAtom) { // New atom is not being used. Add it to replacement table. _replacedAtoms[&newAtom] = existing; } + return false; } unsigned SymbolTable::AtomMappingInfo::getHashValue(const DefinedAtom *atom) { @@ -332,17 +337,18 @@ bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l, return memcmp(lc.data(), rc.data(), lc.size()) == 0; } -void SymbolTable::addByContent(const DefinedAtom & newAtom) { +bool SymbolTable::addByContent(const DefinedAtom &newAtom) { // Currently only read-only constants can be merged. assert(newAtom.permissions() == DefinedAtom::permR__); AtomContentSet::iterator pos = _contentTable.find(&newAtom); if (pos == _contentTable.end()) { _contentTable.insert(&newAtom); - return; + return true; } const Atom* existing = *pos; // New atom is not being used. Add it to replacement table. _replacedAtoms[&newAtom] = existing; + return false; } const Atom *SymbolTable::findByName(StringRef sym) { |

