From 4586fbcbadbb7b4240de056aacc659c4aea2e861 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Tue, 22 Jan 2013 20:49:42 +0000 Subject: [PATCH] [Core] Move Resolver and SymbolTable over to TargetInfo. No functionality change. llvm-svn: 173192 --- lld/include/lld/Core/Resolver.h | 101 +++--------------------------------- lld/include/lld/Core/SymbolTable.h | 13 ++--- lld/lib/Core/Resolver.cpp | 28 +++++----- lld/lib/Core/SymbolTable.cpp | 17 +++--- lld/lib/Driver/LinkerInvocation.cpp | 15 +++--- lld/tools/lld-core/lld-core.cpp | 80 +++++++++++++++++++++++----- 6 files changed, 114 insertions(+), 140 deletions(-) diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h index c0cca09..4dafaf4 100644 --- a/lld/include/lld/Core/Resolver.h +++ b/lld/include/lld/Core/Resolver.h @@ -22,105 +22,16 @@ namespace lld { class Atom; -class InputFiles; -class SymbolTable; - -/// -/// The ResolverOptions class encapsulates options needed during core linking. -/// To use, create a subclass whose constructor sets up the ivars. -/// -class ResolverOptions { -public: - ResolverOptions() - : _deadCodeStrip(false) - , _globalsAreDeadStripRoots(false) - , _searchArchivesToOverrideTentativeDefinitions(false) - , _searchSharedLibrariesToOverrideTentativeDefinitions(false) - , _warnSharedLibrariesOverridesTentativeDefinitions(false) - , _undefinesAreErrors(false) - , _warnIfCoalesableAtomsHaveDifferentCanBeNull(false) - , _warnIfCoalesableAtomsHaveDifferentLoadName(false) { - } - - /// Whether the resolver should removed unreferenced atoms. - bool deadCodeStripping() const { - return _deadCodeStrip; - } - - /// If dead stripping, whether all global symbols are kept. - bool allGlobalsAreDeadStripRoots() const { - return _globalsAreDeadStripRoots; - } - - /// If dead stripping, names of atoms that must be kept. - const std::vector& deadStripRootNames() const { - return _deadStripRootNames; - } - - /// Whether resolver should look in archives for a definition to - /// replace a tentative defintion. - bool searchArchivesToOverrideTentativeDefinitions() const { - return _searchArchivesToOverrideTentativeDefinitions; - } - - /// Whether resolver should look in shared libraries for a definition to - /// replace a tentative defintion. - bool searchSharedLibrariesToOverrideTentativeDefinitions() const { - return _searchSharedLibrariesToOverrideTentativeDefinitions; - } - - /// Whether resolver should look warn if shared library definition replaced - /// a tentative defintion. - bool warnSharedLibrariesOverridesTentativeDefinitions() const { - return _warnSharedLibrariesOverridesTentativeDefinitions; - } - - /// Whether resolver should error if there are any UndefinedAtoms - /// left when resolving is done. - bool undefinesAreErrors() const { - return _undefinesAreErrors; - } - - /// Whether resolver should warn if it discovers two UndefinedAtoms - /// or two SharedLibraryAtoms with the same name, but different - /// canBeNull attributes. - bool warnIfCoalesableAtomsHaveDifferentCanBeNull() const { - return _warnIfCoalesableAtomsHaveDifferentCanBeNull; - } - - /// Whether resolver should warn if it discovers two SharedLibraryAtoms - /// with the same name, but different loadNames. - bool warnIfCoalesableAtomsHaveDifferentLoadName() const { - return _warnIfCoalesableAtomsHaveDifferentLoadName; - } - -protected: - bool _deadCodeStrip; - bool _globalsAreDeadStripRoots; - bool _searchArchivesToOverrideTentativeDefinitions; - bool _searchSharedLibrariesToOverrideTentativeDefinitions; - bool _warnSharedLibrariesOverridesTentativeDefinitions; - bool _undefinesAreErrors; - bool _warnIfCoalesableAtomsHaveDifferentCanBeNull; - bool _warnIfCoalesableAtomsHaveDifferentLoadName; - std::vector _deadStripRootNames; -}; - - +class TargetInfo; -/// -/// The Resolver is responsible for merging all input object files +/// \brief The Resolver is responsible for merging all input object files /// and producing a merged graph. -/// -/// All variations in resolving are controlled by the -/// ResolverOptions object specified. -/// class Resolver : public InputFiles::Handler { public: - Resolver(ResolverOptions &opts, const InputFiles &inputs) - : _options(opts) + Resolver(const TargetInfo &ti, const InputFiles &inputs) + : _targetInfo(ti) , _inputFiles(inputs) - , _symbolTable(opts) + , _symbolTable(ti) , _haveLLVMObjs(false) , _addToFinalSection(false) , _completedInitialObjectFiles(false) {} @@ -185,7 +96,7 @@ private: }; - ResolverOptions &_options; + const TargetInfo &_targetInfo; const InputFiles &_inputFiles; SymbolTable _symbolTable; std::vector _atoms; diff --git a/lld/include/lld/Core/SymbolTable.h b/lld/include/lld/Core/SymbolTable.h index e648f78..b78cce4 100644 --- a/lld/include/lld/Core/SymbolTable.h +++ b/lld/include/lld/Core/SymbolTable.h @@ -22,21 +22,22 @@ namespace lld { +class AbsoluteAtom; class Atom; class DefinedAtom; -class UndefinedAtom; -class SharedLibraryAtom; -class AbsoluteAtom; class ResolverOptions; +class SharedLibraryAtom; +class TargetInfo; +class UndefinedAtom; -/// The SymbolTable class is responsible for coalescing atoms. +/// \brief The SymbolTable class is responsible for coalescing atoms. /// /// All atoms coalescable by-name or by-content should be added. /// The method replacement() can be used to find the replacement atom /// if an atom has been coalesced away. class SymbolTable { public: - SymbolTable(ResolverOptions&); + SymbolTable(const TargetInfo &); /// @brief add atom to symbol table void add(const DefinedAtom &); @@ -95,7 +96,7 @@ private: void addByName(const Atom &); void addByContent(const DefinedAtom &); - ResolverOptions &_options; + const TargetInfo &_targetInfo; AtomToAtom _replacedAtoms; NameToAtom _nameTable; AtomContentSet _contentTable; diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 7e0d2e2..f53152b 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -9,17 +9,18 @@ #include "lld/Core/Atom.h" #include "lld/Core/File.h" -#include "lld/Core/LLVM.h" #include "lld/Core/InputFiles.h" +#include "lld/Core/LinkerOptions.h" #include "lld/Core/LLVM.h" #include "lld/Core/Resolver.h" #include "lld/Core/SymbolTable.h" +#include "lld/Core/TargetInfo.h" #include "lld/Core/UndefinedAtom.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/ErrorHandling.h" #include #include @@ -113,7 +114,7 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) { // tell symbol table _symbolTable.add(atom); - if (_options.deadCodeStripping()) { + if (_targetInfo.getLinkerOptions()._deadStrip) { // add to set of dead-strip-roots, all symbols that // the compiler marks as don't strip if (atom.deadStrip() == DefinedAtom::deadStripNever) @@ -166,10 +167,10 @@ void Resolver::addAtoms(const std::vector& newAtoms) { // ask symbol table if any definitionUndefined atoms still exist // if so, keep searching libraries until no more atoms being added void Resolver::resolveUndefines() { - const bool searchArchives = - _options.searchArchivesToOverrideTentativeDefinitions(); - const bool searchSharedLibs = - _options.searchSharedLibrariesToOverrideTentativeDefinitions(); + const bool searchArchives = _targetInfo.getLinkerOptions(). + _searchArchivesToOverrideTentativeDefinitions; + const bool searchSharedLibs = _targetInfo.getLinkerOptions(). + _searchSharedLibrariesToOverrideTentativeDefinitions; // keep looping until no more undefines were added in last loop unsigned int undefineGenCount = 0xFFFFFFFF; @@ -243,14 +244,14 @@ void Resolver::markLive(const Atom &atom) { // remove all atoms not actually used void Resolver::deadStripOptimize() { // only do this optimization with -dead_strip - if (!_options.deadCodeStripping()) + if (!_targetInfo.getLinkerOptions()._deadStrip) return; // clear liveness on all atoms _liveAtoms.clear(); // By default, shared libraries are built with all globals as dead strip roots - if ( _options.allGlobalsAreDeadStripRoots() ) { + if (_targetInfo.getLinkerOptions()._globalsAreDeadStripRoots) { for ( const Atom *atom : _atoms ) { const DefinedAtom *defAtom = dyn_cast(atom); if (defAtom == nullptr) @@ -261,8 +262,7 @@ void Resolver::deadStripOptimize() { } // Or, use list of names that are dead stip roots. - const std::vector &names = _options.deadStripRootNames(); - for ( const StringRef &name : names ) { + for (const StringRef &name : _targetInfo.getLinkerOptions()._deadStripRoots) { const Atom *symAtom = _symbolTable.findByName(name); assert(symAtom->definition() != Atom::definitionUndefined); _deadStripRoots.insert(symAtom); @@ -288,7 +288,7 @@ void Resolver::checkUndefines(bool final) { // build vector of remaining undefined symbols std::vector undefinedAtoms; _symbolTable.undefines(undefinedAtoms); - if (_options.deadCodeStripping()) { + if (_targetInfo.getLinkerOptions()._deadStrip) { // When dead code stripping, we don't care if dead atoms are undefined. undefinedAtoms.erase(std::remove_if( undefinedAtoms.begin(), undefinedAtoms.end(), @@ -296,7 +296,9 @@ void Resolver::checkUndefines(bool final) { } // error message about missing symbols - if ( (undefinedAtoms.size() != 0) && _options.undefinesAreErrors() ) { + if (!undefinedAtoms.empty() && + (!_targetInfo.getLinkerOptions()._noInhibitExec || + _targetInfo.getLinkerOptions()._outputKind == OutputKind::Relocatable)) { // FIXME: need diagonstics interface for writing error messages llvm::errs() << "Undefined symbols:\n"; for ( const Atom *undefAtom : undefinedAtoms ) { diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp index 1c7ea99f..7a35ed9 100644 --- a/lld/lib/Core/SymbolTable.cpp +++ b/lld/lib/Core/SymbolTable.cpp @@ -8,14 +8,16 @@ //===----------------------------------------------------------------------===// #include "lld/Core/SymbolTable.h" -#include "lld/Core/Atom.h" #include "lld/Core/AbsoluteAtom.h" +#include "lld/Core/Atom.h" #include "lld/Core/DefinedAtom.h" #include "lld/Core/File.h" #include "lld/Core/InputFiles.h" +#include "lld/Core/LinkerOptions.h" #include "lld/Core/LLVM.h" #include "lld/Core/Resolver.h" #include "lld/Core/SharedLibraryAtom.h" +#include "lld/Core/TargetInfo.h" #include "lld/Core/UndefinedAtom.h" #include "llvm/ADT/ArrayRef.h" @@ -29,9 +31,7 @@ #include namespace lld { -SymbolTable::SymbolTable(ResolverOptions &opts) - : _options(opts) { -} +SymbolTable::SymbolTable(const TargetInfo &ti) : _targetInfo(ti) {} void SymbolTable::add(const UndefinedAtom &atom) { this->addByName(atom); @@ -183,7 +183,8 @@ void SymbolTable::addByName(const Atom & newAtom) { useNew = false; } else { - if ( _options.warnIfCoalesableAtomsHaveDifferentCanBeNull() ) { + if (_targetInfo.getLinkerOptions(). + _warnIfCoalesableAtomsHaveDifferentCanBeNull) { // FIXME: need diagonstics interface for writing warning messages llvm::errs() << "lld warning: undefined symbol " << existingUndef->name() @@ -208,7 +209,8 @@ void SymbolTable::addByName(const Atom & newAtom) { bool sameName = curShLib->loadName().equals(newShLib->loadName()); if ( !sameName ) { useNew = false; - if ( _options.warnIfCoalesableAtomsHaveDifferentLoadName() ) { + if (_targetInfo.getLinkerOptions(). + _warnIfCoalesableAtomsHaveDifferentLoadName) { // FIXME: need diagonstics interface for writing warning messages llvm::errs() << "lld warning: shared library symbol " << curShLib->name() @@ -220,7 +222,8 @@ void SymbolTable::addByName(const Atom & newAtom) { } else if ( ! sameNullness ) { useNew = false; - if ( _options.warnIfCoalesableAtomsHaveDifferentCanBeNull() ) { + if (_targetInfo.getLinkerOptions(). + _warnIfCoalesableAtomsHaveDifferentCanBeNull) { // FIXME: need diagonstics interface for writing warning messages llvm::errs() << "lld warning: shared library symbol " << curShLib->name() diff --git a/lld/lib/Driver/LinkerInvocation.cpp b/lld/lib/Driver/LinkerInvocation.cpp index be6d951..268a3ce 100644 --- a/lld/lib/Driver/LinkerInvocation.cpp +++ b/lld/lib/Driver/LinkerInvocation.cpp @@ -11,6 +11,7 @@ #include "lld/Core/InputFiles.h" #include "lld/Core/Resolver.h" +#include "lld/Core/TargetInfo.h" #include "lld/Driver/Target.h" #include "llvm/Support/CommandLine.h" @@ -66,19 +67,19 @@ void LinkerInvocation::operator()() { inputs.appendFiles(files); } - struct Blah : ResolverOptions { - Blah(const LinkerOptions &options) - : ResolverOptions() { - _undefinesAreErrors = !options._noInhibitExec; - } - } ro(_options); + class TestingTargetInfo LLVM_FINAL : public TargetInfo { + public: + TestingTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {} + + virtual uint64_t getPageSize() const { return 0x1000; } + } tti(_options); auto writer = target->getWriter(); // Give writer a chance to add files writer->addFiles(inputs); - Resolver resolver(ro, inputs); + Resolver resolver(tti, inputs); resolver.resolve(); File &merged = resolver.resultFile(); diff --git a/lld/tools/lld-core/lld-core.cpp b/lld/tools/lld-core/lld-core.cpp index 7fcebde..d50b9fc 100644 --- a/lld/tools/lld-core/lld-core.cpp +++ b/lld/tools/lld-core/lld-core.cpp @@ -8,9 +8,11 @@ //===----------------------------------------------------------------------===// #include "lld/Core/Atom.h" +#include "lld/Core/LinkerOptions.h" #include "lld/Core/LLVM.h" #include "lld/Core/Pass.h" #include "lld/Core/Resolver.h" +#include "lld/Core/TargetInfo.h" #include "lld/ReaderWriter/Reader.h" #include "lld/ReaderWriter/ReaderArchive.h" #include "lld/ReaderWriter/ReaderNative.h" @@ -154,19 +156,50 @@ endianSelected("endian", "output little endian format"), clEnumValEnd)); - -class TestingResolverOptions : public ResolverOptions { +class TestingTargetInfo LLVM_FINAL : public TargetInfo { public: - TestingResolverOptions() { - _undefinesAreErrors = cmdLineUndefinesIsError; - _searchArchivesToOverrideTentativeDefinitions = cmdLineCommonsSearchArchives; - _deadCodeStrip = cmdLineDeadStrip; - _globalsAreDeadStripRoots = cmdLineGlobalsNotDeadStrip; + TestingTargetInfo(const LinkerOptions &lo, bool stubs, bool got) + : TargetInfo(lo), _doStubs(stubs), _doGOT(got) {} + + virtual uint64_t getPageSize() const { return 0x1000; } + + virtual StubsPass *getStubPass() const { + if (_doStubs) + return const_cast(&_stubsPass); + else + return nullptr; } -}; + virtual GOTPass *getGOTPass() const { + if (_doGOT) + return const_cast(&_gotPass); + else + return nullptr; + } + virtual ErrorOr relocKindFromString(StringRef str) const { + // Try parsing as a number. + if (auto kind = TargetInfo::relocKindFromString(str)) + return kind; + for (const auto *kinds = sKinds; kinds->string; ++kinds) + if (str == kinds->string) + return kinds->value; + return llvm::make_error_code(llvm::errc::invalid_argument); + } + virtual ErrorOr stringFromRelocKind(uint32_t kind) const { + for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) { + if (kind == static_cast(p->value)) + return std::string(p->string); + } + return llvm::make_error_code(llvm::errc::invalid_argument); + } +private: + bool _doStubs; + bool _doGOT; + TestingStubsPass _stubsPass; + TestingGOTPass _gotPass; +}; int main(int argc, char *argv[]) { // Print a stack trace if we signal out. @@ -185,6 +218,32 @@ int main(int argc, char *argv[]) { if (cmdLineOutputFilePath.empty()) cmdLineOutputFilePath.assign("-"); + LinkerOptions lo; + lo._noInhibitExec = !cmdLineUndefinesIsError; + lo._searchArchivesToOverrideTentativeDefinitions = + cmdLineCommonsSearchArchives; + lo._deadStrip = cmdLineDeadStrip; + lo._globalsAreDeadStripRoots = cmdLineGlobalsNotDeadStrip; + lo._forceLoadArchives = cmdLineForceLoad; + lo._outputKind = OutputKind::Executable; + + switch (archSelected) { + case i386: + lo._target = "i386"; + break; + case x86_64: + lo._target = "x86_64"; + break; + case hexagon: + lo._target = "hexagon"; + break; + case ppc: + lo._target = "powerpc"; + break; + } + + TestingTargetInfo tti(lo, cmdLineDoStubsPass, cmdLineDoGotPass); + // create writer for final output, default to i386 if none selected WriterOptionsELF writerOptionsELF(false, endianSelected == big @@ -257,11 +316,8 @@ int main(int argc, char *argv[]) { // given writer a chance to add files writer->addFiles(inputFiles); - // create options for resolving - TestingResolverOptions options; - // merge all atom graphs - Resolver resolver(options, inputFiles); + Resolver resolver(tti, inputFiles); resolver.resolve(); MutableFile &mergedMasterFile = resolver.resultFile(); -- 2.7.4