diff options
| author | Shankar Easwaran <shankare@codeaurora.org> | 2013-10-07 02:47:09 +0000 |
|---|---|---|
| committer | Shankar Easwaran <shankare@codeaurora.org> | 2013-10-07 02:47:09 +0000 |
| commit | a96f3a3da45cf6f37998df918f3c90ec9e6e2fec (patch) | |
| tree | 8c69bcec8537cf344963c094feb68de6664f63de /lld/lib/Core/Resolver.cpp | |
| parent | 4f44079a2ca1467d0d6a0bb053a338a6b6e795d6 (diff) | |
| download | bcm5719-llvm-a96f3a3da45cf6f37998df918f3c90ec9e6e2fec.tar.gz bcm5719-llvm-a96f3a3da45cf6f37998df918f3c90ec9e6e2fec.zip | |
[lld][InputGraph] Change the Resolver to use inputGraph
Changes :-
a) Functionality in InputGraph to insert Input elements at any position
b) Functionality in the Resolver to use nextFile
c) Move the functionality of assigning file ordinals to InputGraph
d) Changes all inputs to MemoryBuffers
e) Remove LinkerInput, InputFiles, ReaderArchive
llvm-svn: 192081
Diffstat (limited to 'lld/lib/Core/Resolver.cpp')
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 216 |
1 files changed, 128 insertions, 88 deletions
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 2a763c555f9..f43368c7e91 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -8,8 +8,9 @@ //===----------------------------------------------------------------------===// #include "lld/Core/Atom.h" +#include "lld/Core/ArchiveLibraryFile.h" #include "lld/Core/File.h" -#include "lld/Core/InputFiles.h" +#include "lld/Core/SharedLibraryFile.h" #include "lld/Core/Instrumentation.h" #include "lld/Core/LLVM.h" #include "lld/Core/Resolver.h" @@ -69,24 +70,126 @@ private: } // namespace +// called before the first atom in any file is added with doAtom() +void Resolver::doFile(const File &file) {} + +void Resolver::handleFile(const File &file) { + int32_t resolverState = Resolver::StateNoChange; + doFile(file); + for (const DefinedAtom *atom : file.defined()) { + doDefinedAtom(*atom); + resolverState |= StateNewDefinedAtoms; + } + for (const UndefinedAtom *undefAtom : file.undefined()) { + doUndefinedAtom(*undefAtom); + resolverState |= StateNewUndefinedAtoms; + } + for (const SharedLibraryAtom *shlibAtom : file.sharedLibrary()) { + doSharedLibraryAtom(*shlibAtom); + resolverState |= StateNewSharedLibraryAtoms; + } + for (const AbsoluteAtom *absAtom : file.absolute()) { + doAbsoluteAtom(*absAtom); + resolverState |= StateNewAbsoluteAtoms; + } + _context.setResolverState(resolverState); +} -// add all atoms from all initial .o files -void Resolver::buildInitialAtomList() { - ScopedTask task(getDefaultDomain(), "buildInitialAtomList"); - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver initial atom list:\n"); - - // each input files contributes initial atoms - _atoms.reserve(1024); - _inputFiles.forEachInitialAtom(*this); +void Resolver::handleArchiveFile(const File &file) { + const ArchiveLibraryFile *archiveFile = dyn_cast<ArchiveLibraryFile>(&file); - _completedInitialObjectFiles = true; + // Handle normal archives + int64_t undefineGenCount = 0; + do { + undefineGenCount = _symbolTable.size(); + std::vector<const UndefinedAtom *> undefines; + _symbolTable.undefines(undefines); + for (const UndefinedAtom *undefAtom : undefines) { + StringRef undefName = undefAtom->name(); + // load for previous undefine may also have loaded this undefine + if (!_symbolTable.isDefined(undefName)) { + if (const File *member = archiveFile->find(undefName, false)) + handleFile(*member); + } + // 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 + // for COFF "weak external" symbol. + if (!_symbolTable.isDefined(undefName)) { + if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { + _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); + _symbolTable.add(*fallbackUndefAtom); + } + } + } + // search libraries for overrides of common symbols + if (_context.searchArchivesToOverrideTentativeDefinitions()) { + std::vector<StringRef> tentDefNames; + _symbolTable.tentativeDefinitions(tentDefNames); + for (StringRef tentDefName : tentDefNames) { + // Load for previous tentative may also have loaded + // something that overrode this tentative, so always check. + const Atom *curAtom = _symbolTable.findByName(tentDefName); + assert(curAtom != nullptr); + if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) { + if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) { + if (const File *member = archiveFile->find(tentDefName, true)) + handleFile(*member); + } + } + } + } + } while (undefineGenCount != _symbolTable.size()); } +void Resolver::handleSharedLibrary(const File &file) { + const SharedLibraryFile *sharedLibrary = dyn_cast<SharedLibraryFile>(&file); + int64_t undefineGenCount = 0; -// called before the first atom in any file is added with doAtom() -void Resolver::doFile(const File &file) { -} + // Add all the atoms from the shared library + handleFile(*sharedLibrary); + do { + undefineGenCount = _symbolTable.size(); + std::vector<const UndefinedAtom *> undefines; + _symbolTable.undefines(undefines); + for (const UndefinedAtom *undefAtom : undefines) { + StringRef undefName = undefAtom->name(); + // load for previous undefine may also have loaded this undefine + if (!_symbolTable.isDefined(undefName)) { + if (const SharedLibraryAtom *shAtom = + sharedLibrary->exports(undefName, false)) + doSharedLibraryAtom(*shAtom); + } + // 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 + // for COFF "weak external" symbol. + if (!_symbolTable.isDefined(undefName)) { + if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { + _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); + _symbolTable.add(*fallbackUndefAtom); + } + } + } + // search libraries for overrides of common symbols + if (_context.searchSharedLibrariesToOverrideTentativeDefinitions()) { + std::vector<StringRef> tentDefNames; + _symbolTable.tentativeDefinitions(tentDefNames); + for (StringRef tentDefName : tentDefNames) { + // Load for previous tentative may also have loaded + // something that overrode this tentative, so always check. + const Atom *curAtom = _symbolTable.findByName(tentDefName); + assert(curAtom != nullptr); + if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) { + if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) { + if (const SharedLibraryAtom *shAtom = + sharedLibrary->exports(tentDefName, true)) + doSharedLibraryAtom(*shAtom); + } + } + } + } + } while (undefineGenCount != _symbolTable.size()); +} void Resolver::doUndefinedAtom(const UndefinedAtom& atom) { DEBUG_WITH_TYPE("resolver", llvm::dbgs() @@ -187,62 +290,20 @@ void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) { // if so, keep searching libraries until no more atoms being added void Resolver::resolveUndefines() { ScopedTask task(getDefaultDomain(), "resolveUndefines"); - const bool searchArchives = - _context.searchArchivesToOverrideTentativeDefinitions(); - const bool searchSharedLibs = - _context.searchSharedLibrariesToOverrideTentativeDefinitions(); - - // keep looping until no more undefines were added in last loop - unsigned int undefineGenCount; - do { - undefineGenCount = _symbolTable.size(); - std::vector<const UndefinedAtom *> undefines; - _symbolTable.undefines(undefines); - for (const UndefinedAtom *undefAtom : undefines) { - StringRef undefName = undefAtom->name(); - // load for previous undefine may also have loaded this undefine - if (!_symbolTable.isDefined(undefName)) { - _inputFiles.searchLibraries(undefName, - true, // searchSharedLibs - true, // searchArchives - false, // dataSymbolOnly - *this); - } - // 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 - // for COFF "weak external" symbol. - if (!_symbolTable.isDefined(undefName)) { - if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { - _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); - _symbolTable.add(*fallbackUndefAtom); - } - } - } - // search libraries for overrides of common symbols - if (searchArchives || searchSharedLibs) { - std::vector<StringRef> tentDefNames; - _symbolTable.tentativeDefinitions(tentDefNames); - for ( StringRef tentDefName : tentDefNames ) { - // Load for previous tentative may also have loaded - // something that overrode this tentative, so always check. - const Atom *curAtom = _symbolTable.findByName(tentDefName); - assert(curAtom != nullptr); - if (const DefinedAtom* curDefAtom = dyn_cast<DefinedAtom>(curAtom)) { - if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) { - // Still tentative definition, so look for override. - _inputFiles.searchLibraries(tentDefName, - searchSharedLibs, - searchArchives, - true, // dataSymbolOnly - *this); - } - } - } - } - } while (undefineGenCount != _symbolTable.size()); + ErrorOr<File &> nextFile; + + while ((nextFile = _context.nextFile())) { + if (error_code(nextFile) == input_graph_error::no_more_files) + break; + if (nextFile->kind() == File::kindObject) + handleFile(*nextFile); + if (nextFile->kind() == File::kindArchiveLibrary) + handleArchiveFile(*nextFile); + if (nextFile->kind() == File::kindSharedLibrary) + handleSharedLibrary(*nextFile); + } } - // switch all references to undefined or coalesced away atoms // to the new defined atom void Resolver::updateReferences() { @@ -381,31 +442,11 @@ void Resolver::removeCoalescedAwayAtoms() { AtomCoalescedAway(_symbolTable)), _atoms.end()); } -// check for interactions between symbols defined in this linkage unit -// and same symbol name in linked dynamic shared libraries -void Resolver::checkDylibSymbolCollisions() { - ScopedTask task(getDefaultDomain(), "checkDylibSymbolCollisions"); - for ( const Atom *atom : _atoms ) { - const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom); - if (defAtom == nullptr) - continue; - if ( defAtom->merge() != DefinedAtom::mergeAsTentative ) - continue; - assert(defAtom->scope() != DefinedAtom::scopeTranslationUnit); - // See if any shared library also has symbol which - // collides with the tentative definition. - // SymbolTable will warn if needed. - _inputFiles.searchLibraries(defAtom->name(), true, false, false, *this); - } -} - - void Resolver::linkTimeOptimize() { // FIX ME } bool Resolver::resolve() { - this->buildInitialAtomList(); this->resolveUndefines(); this->updateReferences(); this->deadStripOptimize(); @@ -414,7 +455,6 @@ bool Resolver::resolve() { return true; } this->removeCoalescedAwayAtoms(); - this->checkDylibSymbolCollisions(); this->linkTimeOptimize(); this->_result.addAtoms(_atoms); return false; |

