diff options
Diffstat (limited to 'lld/lib/Core')
| -rw-r--r-- | lld/lib/Core/File.cpp | 4 | ||||
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 146 | ||||
| -rw-r--r-- | lld/lib/Core/SymbolTable.cpp | 55 | ||||
| -rw-r--r-- | lld/lib/Core/YamlKeyValues.cpp | 2 | ||||
| -rw-r--r-- | lld/lib/Core/YamlWriter.cpp | 5 |
5 files changed, 88 insertions, 124 deletions
diff --git a/lld/lib/Core/File.cpp b/lld/lib/Core/File.cpp index 70ce886919a..768f1d26282 100644 --- a/lld/lib/Core/File.cpp +++ b/lld/lib/Core/File.cpp @@ -18,8 +18,4 @@ StringRef File::translationUnitSource() const { return StringRef(); } -const Atom *File::entryPoint() const { - return nullptr; -} - } 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) { diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp index 96b1e51752d..e2269749062 100644 --- a/lld/lib/Core/SymbolTable.cpp +++ b/lld/lib/Core/SymbolTable.cpp @@ -14,7 +14,6 @@ #include "lld/Core/File.h" #include "lld/Core/InputFiles.h" #include "lld/Core/LLVM.h" -#include "lld/Core/Platform.h" #include "lld/Core/Resolver.h" #include "lld/Core/SharedLibraryAtom.h" #include "lld/Core/UndefinedAtom.h" @@ -22,6 +21,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -30,8 +30,8 @@ namespace lld { -SymbolTable::SymbolTable(Platform& plat) - : _platform(plat) { +SymbolTable::SymbolTable(ResolverOptions &opts) + : _options(opts) { } void SymbolTable::add(const UndefinedAtom &atom) { @@ -171,29 +171,56 @@ void SymbolTable::addByName(const Atom & newAtom) { useNew = false; } else { + if ( _options.warnIfCoalesableAtomsHaveDifferentCanBeNull() ) { + // FIXME: need diagonstics interface for writing warning messages + llvm::errs() << "lld warning: undefined symbol " + << existingUndef->name() + << " has different weakness in " + << existingUndef->file().path() + << " and in " + << newUndef->file().path(); + } useNew = (newUndef->canBeNull() < existingUndef->canBeNull()); - // give platform a change to override which to use - _platform.undefineCanBeNullMismatch(*existingUndef, - *newUndef, useNew); } } break; case NCR_DupShLib: { - const SharedLibraryAtom* existingShLib = + const SharedLibraryAtom* curShLib = dyn_cast<SharedLibraryAtom>(existing); const SharedLibraryAtom* newShLib = dyn_cast<SharedLibraryAtom>(&newAtom); - assert(existingShLib != nullptr); + assert(curShLib != nullptr); assert(newShLib != nullptr); - if ( (existingShLib->canBeNullAtRuntime() - == newShLib->canBeNullAtRuntime()) && - existingShLib->loadName().equals(newShLib->loadName()) ) { + bool sameNullness = (curShLib->canBeNullAtRuntime() + == newShLib->canBeNullAtRuntime()); + bool sameName = curShLib->loadName().equals(newShLib->loadName()); + if ( !sameName ) { useNew = false; + if ( _options.warnIfCoalesableAtomsHaveDifferentLoadName() ) { + // FIXME: need diagonstics interface for writing warning messages + llvm::errs() << "lld warning: shared library symbol " + << curShLib->name() + << " has different load path in " + << curShLib->file().path() + << " and in " + << newShLib->file().path(); + } + } + else if ( ! sameNullness ) { + useNew = false; + if ( _options.warnIfCoalesableAtomsHaveDifferentCanBeNull() ) { + // FIXME: need diagonstics interface for writing warning messages + llvm::errs() << "lld warning: shared library symbol " + << curShLib->name() + << " has different weakness in " + << curShLib->file().path() + << " and in " + << newShLib->file().path(); + } } else { - useNew = false; // use existing shared library by default - // give platform a change to override which to use - _platform.sharedLibrarylMismatch(*existingShLib, *newShLib, useNew); + // Both shlib atoms are identical and can be coalesced. + useNew = false; } } break; diff --git a/lld/lib/Core/YamlKeyValues.cpp b/lld/lib/Core/YamlKeyValues.cpp index 548cafa261f..abf6f16f8c6 100644 --- a/lld/lib/Core/YamlKeyValues.cpp +++ b/lld/lib/Core/YamlKeyValues.cpp @@ -138,6 +138,7 @@ static const ContentTypeMapping typeMappings[] = { { "unknown", DefinedAtom::typeUnknown }, { "code", DefinedAtom::typeCode }, { "stub", DefinedAtom::typeStub }, + { "stub-helper", DefinedAtom::typeStubHelper }, { "resolver", DefinedAtom::typeResolver }, { "constant", DefinedAtom::typeConstant }, { "c-string", DefinedAtom::typeCString }, @@ -151,6 +152,7 @@ static const ContentTypeMapping typeMappings[] = { { "zero-fill", DefinedAtom::typeZeroFill }, { "cf-string", DefinedAtom::typeCFString }, { "got", DefinedAtom::typeGOT }, + { "lazy-pointer", DefinedAtom::typeLazyPointer }, { "initializer-ptr",DefinedAtom::typeInitializerPtr }, { "terminator-ptr", DefinedAtom::typeTerminatorPtr }, { "c-string-ptr", DefinedAtom::typeCStringPtr }, diff --git a/lld/lib/Core/YamlWriter.cpp b/lld/lib/Core/YamlWriter.cpp index c5f45c9025f..e056eb898c9 100644 --- a/lld/lib/Core/YamlWriter.cpp +++ b/lld/lib/Core/YamlWriter.cpp @@ -56,11 +56,12 @@ public: // Find references to unnamed atoms and create ref-names for them. for (const Reference *ref : *atom) { // create refname for any unnamed reference target - if ( ref->target()->name().empty() ) { + const Atom *target = ref->target(); + if ( (target != nullptr) && target->name().empty() ) { std::string Storage; llvm::raw_string_ostream Buffer(Storage); Buffer << llvm::format("L%03d", _unnamedCounter++); - _refNames[ref->target()] = Buffer.str(); + _refNames[target] = Buffer.str(); } } } |

