diff options
| author | Nick Kledzik <kledzik@apple.com> | 2012-04-18 21:55:06 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2012-04-18 21:55:06 +0000 |
| commit | bb963dfb7ebeab75764e962734c88aca44422dbf (patch) | |
| tree | cc27be9a8272806d858158c0cdb1104235c6e855 /lld/lib/Core/Resolver.cpp | |
| parent | eb1c2bdc1f55fbc5d1e7bb86e9f0e038b0f5adb7 (diff) | |
| download | bcm5719-llvm-bb963dfb7ebeab75764e962734c88aca44422dbf.tar.gz bcm5719-llvm-bb963dfb7ebeab75764e962734c88aca44422dbf.zip | |
Factor out core linking options from Platform in a new ResolverOptions
class. Change Resolver to no longer use Platform. Core linking
now issues errors directly. We need to factor that out later.
Rework how Darwin executable writer finds "main" atom. It now
adds to core linking an Atom which has a Reference to "main".
llvm-svn: 155060
Diffstat (limited to 'lld/lib/Core/Resolver.cpp')
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 146 |
1 files changed, 42 insertions, 104 deletions
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 0cf5838bb1f..a758a8628ab 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -13,11 +13,11 @@ #include "lld/Core/File.h" #include "lld/Core/InputFiles.h" #include "lld/Core/LLVM.h" -#include "lld/Core/Platform.h" #include "lld/Core/SymbolTable.h" #include "lld/Core/UndefinedAtom.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <cassert> @@ -63,17 +63,6 @@ private: }; - - -void Resolver::initializeState() { - _platform.initialize(); -} - -// add initial undefines from -u option -void Resolver::addInitialUndefines() { - -} - // add all atoms from all initial .o files void Resolver::buildInitialAtomList() { // each input files contributes initial atoms @@ -86,8 +75,6 @@ void Resolver::buildInitialAtomList() { // called before the first atom in any file is added with doAtom() void Resolver::doFile(const File &file) { - // notify platform - _platform.fileAdded(file); } @@ -102,35 +89,19 @@ void Resolver::doUndefinedAtom(const class UndefinedAtom& atom) { // called on each atom when a file is added void Resolver::doDefinedAtom(const DefinedAtom &atom) { - // notify platform - _platform.atomAdded(atom); - // add to list of known atoms _atoms.push_back(&atom); - // adjust scope (e.g. force some globals to be hidden) - _platform.adjustScope(atom); - // non-static atoms need extra handling if (atom.scope() != DefinedAtom::scopeTranslationUnit) { // tell symbol table about non-static atoms _symbolTable.add(atom); - - // platform can add aliases for any symbol - std::vector<const DefinedAtom *> aliases; - if (_platform.getAliasAtoms(atom, aliases)) - this->addAtoms(aliases); } - - if (_platform.deadCodeStripping()) { + + if (_options.deadCodeStripping()) { // add to set of dead-strip-roots, all symbols that // the compiler marks as don't strip - if (!atom.deadStrip()) - _deadStripRoots.insert(&atom); - - // add to set of dead-strip-roots, all symbols that - // the platform decided must remain - if (_platform.isDeadStripRoot(atom)) + if (atom.deadStrip() == DefinedAtom::deadStripNever) _deadStripRoots.insert(&atom); } } @@ -165,9 +136,9 @@ void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) { // if so, keep searching libraries until no more atoms being added void Resolver::resolveUndefines() { const bool searchArchives = - _platform.searchArchivesToOverrideTentativeDefinitions(); + _options.searchArchivesToOverrideTentativeDefinitions(); const bool searchDylibs = - _platform.searchSharedLibrariesToOverrideTentativeDefinitions(); + _options.searchSharedLibrariesToOverrideTentativeDefinitions(); // keep looping until no more undefines were added in last loop unsigned int undefineGenCount = 0xFFFFFFFF; @@ -180,14 +151,6 @@ void Resolver::resolveUndefines() { // load for previous undefine may also have loaded this undefine if (!_symbolTable.isDefined(undefName)) { _inputFiles.searchLibraries(undefName, true, true, false, *this); - - // give platform a chance to instantiate platform - // specific atoms (e.g. section boundary) - if (!_symbolTable.isDefined(undefName)) { - std::vector<const DefinedAtom *> platAtoms; - if (_platform.getPlatformAtoms(undefName, platAtoms)) - this->addAtoms(platAtoms); - } } } // search libraries for overrides of common symbols @@ -230,21 +193,8 @@ void Resolver::updateReferences() { } -// for dead code stripping, recursively mark atom "live" -void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) { - // if -why_live cares about this symbol, then dump chain - if ((previous->referer != nullptr) && _platform.printWhyLive(atom.name())) { - llvm::errs() << atom.name() << " from " << atom.file().path() << "\n"; - int depth = 1; - for (WhyLiveBackChain *p = previous; p != nullptr; - p = p->previous, ++depth) { - for (int i = depth; i > 0; --i) - llvm::errs() << " "; - llvm::errs() << p->referer->name() << " from " - << p->referer->file().path() << "\n"; - } - } - +// for dead code stripping, recursively mark atoms "live" +void Resolver::markLive(const Atom &atom) { // if already marked live, then done (stop recursion) if ( _liveAtoms.count(&atom) ) return; @@ -253,50 +203,47 @@ void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) { _liveAtoms.insert(&atom); // mark all atoms it references as live - WhyLiveBackChain thisChain; - thisChain.previous = previous; - thisChain.referer = &atom; if ( const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(&atom)) { for (const Reference *ref : *defAtom) { - this->markLive(*ref->target(), &thisChain); + const Atom *target = ref->target(); + if ( target != nullptr ) + this->markLive(*target); } } } + // remove all atoms not actually used void Resolver::deadStripOptimize() { // only do this optimization with -dead_strip - if (!_platform.deadCodeStripping()) + if (!_options.deadCodeStripping()) return; // clear liveness on all atoms _liveAtoms.clear(); - // add entry point (main) to live roots - const Atom *entry = this->entryPoint(); - if (entry != nullptr) - _deadStripRoots.insert(entry); - - // add -exported_symbols_list, -init, and -u entries to live roots - for (Platform::UndefinesIterator uit = _platform.initialUndefinesBegin(); - uit != _platform.initialUndefinesEnd(); ++uit) { - StringRef sym = *uit; - const Atom *symAtom = _symbolTable.findByName(sym); + // By default, shared libraries are built with all globals as dead strip roots + if ( _options.allGlobalsAreDeadStripRoots() ) { + for ( const Atom *atom : _atoms ) { + const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom); + if (defAtom == nullptr) + continue; + if ( defAtom->scope() == DefinedAtom::scopeGlobal ) + _deadStripRoots.insert(defAtom); + } + } + + // Or, use list of names that are dead stip roots. + const std::vector<StringRef> &names = _options.deadStripRootNames(); + for ( const StringRef &name : names ) { + const Atom *symAtom = _symbolTable.findByName(name); assert(symAtom->definition() != Atom::definitionUndefined); _deadStripRoots.insert(symAtom); } - // add platform specific helper atoms - std::vector<const DefinedAtom *> platRootAtoms; - if (_platform.getImplicitDeadStripRoots(platRootAtoms)) - this->addAtoms(platRootAtoms); - // mark all roots as live, and recursively all atoms they reference for ( const Atom *dsrAtom : _deadStripRoots) { - WhyLiveBackChain rootChain; - rootChain.previous = nullptr; - rootChain.referer = dsrAtom; - this->markLive(*dsrAtom, &rootChain); + this->markLive(*dsrAtom); } // now remove all non-live atoms from _atoms @@ -304,6 +251,7 @@ void Resolver::deadStripOptimize() { NotLive(_liveAtoms)), _atoms.end()); } + // error out if some undefines remain void Resolver::checkUndefines(bool final) { // when using LTO, undefines are checked after bitcode is optimized @@ -313,18 +261,25 @@ void Resolver::checkUndefines(bool final) { // build vector of remaining undefined symbols std::vector<const Atom *> undefinedAtoms; _symbolTable.undefines(undefinedAtoms); - if (_platform.deadCodeStripping()) { - // when dead code stripping we don't care if dead atoms are undefined + if (_options.deadCodeStripping()) { + // When dead code stripping, we don't care if dead atoms are undefined. undefinedAtoms.erase(std::remove_if( undefinedAtoms.begin(), undefinedAtoms.end(), NotLive(_liveAtoms)), undefinedAtoms.end()); } - // let platform make error message about missing symbols - if (undefinedAtoms.size() != 0) - _platform.errorWithUndefines(undefinedAtoms, _atoms); + // error message about missing symbols + if ( (undefinedAtoms.size() != 0) && _options.undefinesAreErrors() ) { + // FIXME: need diagonstics interface for writing error messages + llvm::errs() << "Undefined symbols:\n"; + for ( const Atom *undefAtom : undefinedAtoms ) { + llvm::errs() << " " << undefAtom->name() << "\n"; + } + llvm::report_fatal_error("symbol(s) not found"); + } } + // remove from _atoms all coaleseced away atoms void Resolver::removeCoalescedAwayAtoms() { _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), @@ -348,27 +303,12 @@ void Resolver::checkDylibSymbolCollisions() { } } -// get "main" atom for linkage unit -const Atom *Resolver::entryPoint() { - StringRef symbolName = _platform.entryPointName(); - if ( !symbolName.empty() ) - return _symbolTable.findByName(symbolName); - - return nullptr; -} - -// give platform a chance to tweak the set of atoms -void Resolver::tweakAtoms() { - _platform.postResolveTweaks(_atoms); -} void Resolver::linkTimeOptimize() { // FIX ME } void Resolver::resolve() { - this->initializeState(); - this->addInitialUndefines(); this->buildInitialAtomList(); this->resolveUndefines(); this->updateReferences(); @@ -377,9 +317,7 @@ void Resolver::resolve() { this->removeCoalescedAwayAtoms(); this->checkDylibSymbolCollisions(); this->linkTimeOptimize(); - this->tweakAtoms(); this->_result.addAtoms(_atoms); - this->_result._mainAtom = this->entryPoint(); } void Resolver::MergedFile::addAtom(const Atom& atom) { |

