[Core] Move Resolver and SymbolTable over to TargetInfo.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 22 Jan 2013 20:49:42 +0000 (20:49 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Tue, 22 Jan 2013 20:49:42 +0000 (20:49 +0000)
No functionality change.

llvm-svn: 173192

lld/include/lld/Core/Resolver.h
lld/include/lld/Core/SymbolTable.h
lld/lib/Core/Resolver.cpp
lld/lib/Core/SymbolTable.cpp
lld/lib/Driver/LinkerInvocation.cpp
lld/tools/lld-core/lld-core.cpp

index c0cca09..4dafaf4 100644 (file)
 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<StringRef>& 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<StringRef> _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<const Atom *>     _atoms;
index e648f78..b78cce4 100644 (file)
 
 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;
index 7e0d2e2..f53152b 100644 (file)
@@ -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 <algorithm>
 #include <cassert>
@@ -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<const DefinedAtom*>& 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<DefinedAtom>(atom);
       if (defAtom == nullptr)
@@ -261,8 +262,7 @@ void Resolver::deadStripOptimize() {
   }
 
   // Or, use list of names that are dead stip roots.
-  const std::vector<StringRef> &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<const Atom *> 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 ) {
index 1c7ea99..7a35ed9 100644 (file)
@@ -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 <vector>
 
 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()
index be6d951..268a3ce 100644 (file)
@@ -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();
 
index 7fcebde..d50b9fc 100644 (file)
@@ -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<TestingStubsPass*>(&_stubsPass);
+    else
+      return nullptr;
   }
 
-};
+  virtual GOTPass *getGOTPass() const {
+     if (_doGOT)
+      return const_cast<TestingGOTPass*>(&_gotPass);
+    else
+      return nullptr;
+  }
 
+  virtual ErrorOr<uint32_t> 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<std::string> stringFromRelocKind(uint32_t kind) const {
+    for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
+      if (kind == static_cast<uint32_t>(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();