summaryrefslogtreecommitdiffstats
path: root/lld/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib')
-rw-r--r--lld/lib/Core/Resolver.cpp21
-rw-r--r--lld/lib/Core/SymbolTable.cpp28
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) {
OpenPOWER on IntegriCloud