[lld] r200175 - [ELF] Add Target specific Readers.

Shankar Easwaran shankare at codeaurora.org
Sun Jan 26 17:02:03 PST 2014


Author: shankare
Date: Sun Jan 26 19:02:03 2014
New Revision: 200175

URL: http://llvm.org/viewvc/llvm-project?rev=200175&view=rev
Log:
[ELF] Add Target specific Readers.

No change in functionality.

Added:
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h
      - copied, changed from r200173, lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/Reader.h
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
    lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
    lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -14,6 +14,7 @@
 #include "lld/Core/PassManager.h"
 #include "lld/Core/Pass.h"
 #include "lld/Core/range.h"
+#include "lld/Core/STDExtras.h"
 
 #include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/Writer.h"
@@ -37,6 +38,10 @@ class TargetHandlerBase {
 public:
   virtual ~TargetHandlerBase() {}
   virtual void registerRelocationNames(Registry &) = 0;
+
+  virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
+
+  virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
 };
 
 class ELFLinkingContext : public LinkingContext {

Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Sun Jan 26 19:02:03 2014
@@ -125,7 +125,8 @@ public:
   void addSupportWindowsResourceFiles();
   void addSupportMachOObjects(StringRef archName);
   void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler);
-  void addSupportELFDynamicSharedObjects(bool useShlibUndefines);
+  void addSupportELFDynamicSharedObjects(bool useShlibUndefines,
+                                         TargetHandlerBase *handler);
 
   /// To convert between kind values and names, the registry walks the list
   /// of registered kind tables. Each table is a zero terminated array of

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Sun Jan 26 19:02:03 2014
@@ -119,7 +119,7 @@ bool GnuLdDriver::linkELF(int argc, cons
   options->registry().addSupportNativeObjects();
   if (options->allowLinkWithDynamicLibraries())
     options->registry().addSupportELFDynamicSharedObjects(
-        options->useShlibUndefines());
+        options->useShlibUndefines(), options->targetHandler());
 
   return link(*options, diagnostics);
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Sun Jan 26 19:02:03 2014
@@ -25,7 +25,6 @@ namespace lld {
 namespace elf {
 template <class ELFT> class DynamicFile;
 template <typename ELFT> class ELFFile;
-template <typename ELFT> class TargetAtomHandler;
 
 /// \brief Relocation References: Defined Atoms may contain references that will
 /// need to be patched before the executable is written.
@@ -36,7 +35,7 @@ template <typename ELFT> class TargetAto
 /// (not target atom) about a relocation, so we store the index to
 /// ELFREference. In the second pass, ELFReferences are revisited to update
 /// target atoms by target symbol indexes.
-template <class ELFT> class ELFReference LLVM_FINAL : public Reference {
+template <class ELFT> class ELFReference : public Reference {
   typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 public:
@@ -88,8 +87,7 @@ private:
 /// \brief These atoms store symbols that are fixed to a particular address.
 /// This atom has no content its address will be used by the writer to fixup
 /// references that point to it.
-template<class ELFT>
-class ELFAbsoluteAtom LLVM_FINAL : public AbsoluteAtom {
+template <class ELFT> class ELFAbsoluteAtom : public AbsoluteAtom {
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
 
 public:
@@ -128,8 +126,7 @@ private:
 
 /// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
 /// holders that will be replaced by defined atoms later in the linking process.
-template<class ELFT>
-class ELFUndefinedAtom LLVM_FINAL : public lld::UndefinedAtom {
+template <class ELFT> class ELFUndefinedAtom : public lld::UndefinedAtom {
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
 
 public:
@@ -158,8 +155,7 @@ private:
 
 /// \brief This atom stores defined symbols and will contain either data or
 /// code.
-template<class ELFT>
-class ELFDefinedAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFDefinedAtom : public DefinedAtom {
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
   typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
 
@@ -172,8 +168,8 @@ public:
       : _owningFile(file), _symbolName(symbolName), _sectionName(sectionName),
         _symbol(symbol), _section(section), _contentData(contentData),
         _referenceStartIndex(referenceStart), _referenceEndIndex(referenceEnd),
-        _referenceList(referenceList), _targetAtomHandler(nullptr),
-        _contentType(typeUnknown), _permissions(permUnknown) {}
+        _referenceList(referenceList), _contentType(typeUnknown),
+        _permissions(permUnknown) {}
 
   ~ELFDefinedAtom() {}
 
@@ -196,15 +192,6 @@ public:
   virtual uint64_t size() const {
     // Common symbols are not allocated in object files,
     // so use st_size to tell how many bytes are required.
-
-    // Treat target defined common symbols
-    if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
-         _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler)
-        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
-      if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
-        return (uint64_t) _symbol->st_size;
-    }
     if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
         _symbol->st_shndx == llvm::ELF::SHN_COMMON)
       return (uint64_t) _symbol->st_size;
@@ -231,17 +218,6 @@ public:
     if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
       return mergeAsWeak;
 
-    // If the symbol is a target defined and if the target
-    // defines the symbol as a common symbol treat it as
-    // mergeTentative
-    if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
-         _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler)
-        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
-      if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
-        return mergeAsTentative;
-    }
-
     if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
         _symbol->st_shndx == llvm::ELF::SHN_COMMON)
       return mergeAsTentative;
@@ -256,15 +232,6 @@ public:
     ContentType ret = typeUnknown;
     uint64_t flags = _section->sh_flags;
 
-    // Treat target defined symbols
-    if ((_section->sh_flags & llvm::ELF::SHF_MASKPROC) ||
-        ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
-          _symbol->st_shndx < llvm::ELF::SHN_HIPROC))) {
-      if (!_targetAtomHandler)
-        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
-      return _contentType = _targetAtomHandler->contentType(this);
-    }
-
     if (!(flags & llvm::ELF::SHF_ALLOC))
       return _contentType = typeNoAlloc;
 
@@ -337,16 +304,6 @@ public:
   virtual Alignment alignment() const {
     // Unallocated common symbols specify their alignment constraints in
     // st_value.
-
-    // Treat target defined common symbols
-    if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
-         _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler)
-        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
-      if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
-        return Alignment(llvm::Log2_64(_symbol->st_value));
-    }
-
     if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
         _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
       return Alignment(llvm::Log2_64(_symbol->st_value));
@@ -396,13 +353,6 @@ public:
       return _permissions;
 
     uint64_t flags = _section->sh_flags;
-    // Treat target defined symbols
-    if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
-         _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler)
-        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
-      return _permissions = _targetAtomHandler->contentPermissions(this);
-    }
 
     if (!(flags & llvm::ELF::SHF_ALLOC))
       return _permissions = perm___;
@@ -492,7 +442,7 @@ public:
 
   virtual void setOrdinal(uint64_t ord) { _ordinal = ord; }
 
-private:
+protected:
   const ELFFile<ELFT> &_owningFile;
   StringRef _symbolName;
   StringRef _sectionName;
@@ -505,14 +455,12 @@ private:
   unsigned int _referenceStartIndex;
   unsigned int _referenceEndIndex;
   std::vector<ELFReference<ELFT> *> &_referenceList;
-  // Cached size of the TLS segment.
-  mutable TargetAtomHandler<ELFT> *_targetAtomHandler;
   mutable ContentType _contentType;
   mutable ContentPermissions _permissions;
 };
 
 /// \brief This atom stores mergeable Strings
-template <class ELFT> class ELFMergeAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFMergeAtom : public DefinedAtom {
   typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
 
 public:
@@ -596,8 +544,7 @@ private:
   uint64_t _offset;
 };
 
-template <class ELFT>
-class ELFCommonAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFCommonAtom : public DefinedAtom {
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
 public:
   ELFCommonAtom(const ELFFile<ELFT> &file,
@@ -643,10 +590,6 @@ public:
   }
 
   virtual ContentType contentType() const {
-    if (_symbol->st_shndx >= llvm::ELF::SHN_LORESERVE &&
-        _symbol->st_shndx <= llvm::ELF::SHN_HIOS)
-      return _owningFile.targetHandler()->targetAtomHandler().contentType(
-          nullptr, _symbol);
     return typeZeroFill;
   }
 
@@ -703,7 +646,6 @@ protected:
 
   virtual void incrementIterator(const void *&iter) const {}
 
-private:
   const ELFFile<ELFT> &_owningFile;
   StringRef _symbolName;
   const Elf_Sym *_symbol;
@@ -711,8 +653,7 @@ private:
 };
 
 /// \brief An atom from a shared library.
-template <class ELFT>
-class ELFDynamicAtom LLVM_FINAL : public SharedLibraryAtom {
+template <class ELFT> class ELFDynamicAtom : public SharedLibraryAtom {
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
 
 public:

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -12,6 +12,7 @@
 
 #include "DefaultLayout.h"
 #include "TargetHandler.h"
+#include "ELFReader.h"
 
 #include "lld/ReaderWriter/ELFLinkingContext.h"
 
@@ -32,11 +33,6 @@ public:
     llvm_unreachable("Target should provide implementation for function ");
   }
 
-  /// TargetAtomHandler
-  TargetAtomHandler<ELFT> &targetAtomHandler() {
-    llvm_unreachable("Target should provide implementation for function ");
-  }
-
   const TargetRelocationHandler<ELFT> &getRelocationHandler() const {
     llvm_unreachable("Target should provide implementation for function ");
   }
@@ -74,7 +70,15 @@ public:
             DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
   }
 
-private:
+  virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
+    return std::unique_ptr<Reader>(new ELFObjectReader(atomizeStrings));
+  }
+
+  virtual std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) {
+    return std::unique_ptr<Reader>(new ELFDSOReader(useShlibUndefines));
+  }
+
+protected:
   llvm::BumpPtrAllocator _alloc;
 };
 } // end namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Sun Jan 26 19:02:03 2014
@@ -22,7 +22,7 @@
 
 namespace lld {
 namespace elf {
-template <class ELFT> class DynamicFile LLVM_FINAL : public SharedLibraryFile {
+template <class ELFT> class DynamicFile : public SharedLibraryFile {
 public:
   static ErrorOr<std::unique_ptr<DynamicFile>>
   create(std::unique_ptr<llvm::MemoryBuffer> mb, bool useShlibUndefines);

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFFile.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFFile.h Sun Jan 26 19:02:03 2014
@@ -118,12 +118,10 @@ template <class ELFT> class ELFFile : pu
 
 public:
   ELFFile(StringRef name, bool atomizeStrings = false)
-      : File(name, kindObject), _ordinal(0), _doStringsMerge(atomizeStrings),
-        _targetHandler(nullptr) {}
+      : File(name, kindObject), _ordinal(0), _doStringsMerge(atomizeStrings) {}
 
   static ErrorOr<std::unique_ptr<ELFFile>>
-  create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
-         TargetHandlerBase *handler);
+  create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings);
 
   virtual Reference::KindArch kindArch();
 
@@ -159,8 +157,6 @@ public:
     return _absoluteAtoms;
   }
 
-  TargetHandler<ELFT> *targetHandler() const { return _targetHandler; }
-
   Atom *findAtom(const Elf_Sym *symbol) {
     return _symbolToAtomMapping.lookup(symbol);
   }
@@ -195,12 +191,8 @@ protected:
                                                   StringRef sectionName,
                                                   StringRef sectionContents);
 
-  /// Returns true if the symbol is common symbol. A common symbol represents a
-  /// tentive definition in C. It has name, size and alignment constraint, but
-  /// actual storage has not yet been allocated. (The linker will allocate
-  /// storage for them in the later pass after coalescing tentative symbols by
-  /// name.)
-  virtual bool isCommonSymbol(const Elf_Sym *symbol);
+  /// Return the default reloc addend for references.
+  virtual int64_t defaultRelocAddend(const Reference &) const;
 
   /// Returns the symbol's content size. The nextSymbol should be null if the
   /// symbol is the last one in the section.
@@ -211,8 +203,113 @@ protected:
   virtual void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
                           uint32_t edgeKind);
 
-  virtual void setTargetHandler(TargetHandlerBase *handler) {
-    _targetHandler = reinterpret_cast<TargetHandler<ELFT> *>(handler);
+  /// Determines if the reader needs to create atoms for the section.
+  virtual bool ignoreCreateAtomsForSection(const Elf_Shdr *shdr) {
+    return false;
+  }
+
+  /// Get the section name for a section.
+  virtual ErrorOr<StringRef> getSectionName(const Elf_Shdr *shdr) const {
+    if (!shdr)
+      return StringRef();
+    return _objFile->getSectionName(shdr);
+  }
+
+  /// Determines if the section occupy memory space.
+  virtual bool sectionOccupiesMemorySpace(const Elf_Shdr *shdr) const {
+    return (shdr->sh_type != llvm::ELF::SHT_NOBITS);
+  }
+
+  /// Return the section contents.
+  virtual ErrorOr<ArrayRef<uint8_t>>
+  getSectionContents(const Elf_Shdr *shdr) const {
+    if (!shdr || !sectionOccupiesMemorySpace(shdr))
+      return ArrayRef<uint8_t>();
+    return _objFile->getSectionContents(shdr);
+  }
+
+  /// Returns true if the symbol is a undefined symbol.
+  virtual bool isUndefinedSymbol(const Elf_Sym *sym) const {
+    return (sym->st_shndx == llvm::ELF::SHN_UNDEF);
+  }
+
+  /// Determines if the target wants to create an atom for a section that has no
+  /// symbol references.
+  virtual bool
+  handleSectionWithNoSymbols(const Elf_Shdr *shdr,
+                             std::vector<Elf_Sym_Iter> &symbols) const {
+    if (shdr && shdr->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty())
+      return true;
+    return false;
+  }
+
+  /// Process the Undefined symbol and create an atom for it.
+  virtual ErrorOr<ELFUndefinedAtom<ELFT> *>
+  handleUndefinedSymbol(StringRef symName, const Elf_Sym *sym) {
+    return new (_readerStorage) ELFUndefinedAtom<ELFT>(*this, symName, sym);
+  }
+
+  /// Returns true if the symbol is a absolute symbol.
+  virtual bool isAbsoluteSymbol(const Elf_Sym *sym) const {
+    return (sym->st_shndx == llvm::ELF::SHN_ABS);
+  }
+
+  /// Process the Absolute symbol and create an atom for it.
+  virtual ErrorOr<ELFAbsoluteAtom<ELFT> *>
+  handleAbsoluteSymbol(StringRef symName, const Elf_Sym *sym, int64_t value) {
+    return new (_readerStorage)
+        ELFAbsoluteAtom<ELFT>(*this, symName, sym, value);
+  }
+
+  /// Returns true if the symbol is common symbol. A common symbol represents a
+  /// tentive definition in C. It has name, size and alignment constraint, but
+  /// actual storage has not yet been allocated. (The linker will allocate
+  /// storage for them in the later pass after coalescing tentative symbols by
+  /// name.)
+  virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
+    return symbol->getType() == llvm::ELF::STT_COMMON ||
+           symbol->st_shndx == llvm::ELF::SHN_COMMON;
+  }
+
+  /// Process the common symbol and create an atom for it.
+  virtual ErrorOr<ELFCommonAtom<ELFT> *>
+  handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
+    return new (_readerStorage) ELFCommonAtom<ELFT>(*this, symName, sym);
+  }
+
+  /// Returns true if the symbol is a defined symbol.
+  virtual bool isDefinedSymbol(const Elf_Sym *sym) const {
+    return (sym->getType() == llvm::ELF::STT_NOTYPE ||
+            sym->getType() == llvm::ELF::STT_OBJECT ||
+            sym->getType() == llvm::ELF::STT_FUNC ||
+            sym->getType() == llvm::ELF::STT_GNU_IFUNC ||
+            sym->getType() == llvm::ELF::STT_SECTION ||
+            sym->getType() == llvm::ELF::STT_FILE ||
+            sym->getType() == llvm::ELF::STT_TLS);
+  }
+
+  /// Process the Defined symbol and create an atom for it.
+  virtual ErrorOr<ELFDefinedAtom<ELFT> *>
+  handleDefinedSymbol(StringRef symName, StringRef sectionName,
+                      const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
+                      ArrayRef<uint8_t> contentData,
+                      unsigned int referenceStart, unsigned int referenceEnd,
+                      std::vector<ELFReference<ELFT> *> &referenceList) {
+    return new (_readerStorage) ELFDefinedAtom<ELFT>(
+        *this, symName, sectionName, sym, sectionHdr, contentData,
+        referenceStart, referenceEnd, referenceList);
+  }
+
+  /// Process the Merge string and create an atom for it.
+  virtual ErrorOr<ELFMergeAtom<ELFT> *>
+  handleMergeString(StringRef sectionName, const Elf_Shdr *sectionHdr,
+                    ArrayRef<uint8_t> contentData, unsigned int offset) {
+    ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage)
+        ELFMergeAtom<ELFT>(*this, sectionName, sectionHdr, contentData, offset);
+    const MergeSectionKey mergedSectionKey(sectionHdr, offset);
+    if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
+      _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
+    return mergeAtom;
   }
 
   llvm::BumpPtrAllocator _readerStorage;
@@ -225,8 +322,7 @@ protected:
   /// \brief _relocationAddendReferences and _relocationReferences contain the
   /// list of relocations references.  In ELF, if a section named, ".text" has
   /// relocations will also have a section named ".rel.text" or ".rela.text"
-  /// which will hold the entries. -- .rel or .rela is prepended to create
-  /// the SHT_REL(A) section name.
+  /// which will hold the entries.
   std::unordered_map<
       StringRef,
       range<typename llvm::object::ELFFile<ELFT>::Elf_Rela_Iter> >
@@ -254,7 +350,6 @@ protected:
 
   /// \brief the cached options relevant while reading the ELF File
   bool _doStringsMerge;
-  TargetHandler<ELFT> *_targetHandler;
 };
 
 /// \brief All atoms are owned by a File. To add linker specific atoms
@@ -271,53 +366,45 @@ public:
   /// \brief add a global absolute atom
   virtual Atom *addAbsoluteAtom(StringRef symbolName) {
     assert(!symbolName.empty() && "AbsoluteAtoms must have a name");
-    Elf_Sym *symbol = new (_allocator) Elf_Sym;
+    Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
     symbol->st_name = 0;
     symbol->st_value = 0;
     symbol->st_shndx = llvm::ELF::SHN_ABS;
     symbol->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT);
     symbol->st_other = llvm::ELF::STV_DEFAULT;
     symbol->st_size = 0;
-    auto *newAtom =
-        new (_allocator) ELFAbsoluteAtom<ELFT>(*this, symbolName, symbol, -1);
-    this->_absoluteAtoms._atoms.push_back(newAtom);
-    return newAtom;
+    auto newAtom = this->handleAbsoluteSymbol(symbolName, symbol, -1);
+    this->_absoluteAtoms._atoms.push_back(*newAtom);
+    return *newAtom;
   }
 
   /// \brief add an undefined atom
   virtual Atom *addUndefinedAtom(StringRef symbolName) {
     assert(!symbolName.empty() && "UndefinedAtoms must have a name");
-    Elf_Sym *symbol = new (_allocator) Elf_Sym;
+    Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
     symbol->st_name = 0;
     symbol->st_value = 0;
     symbol->st_shndx = llvm::ELF::SHN_UNDEF;
     symbol->st_other = llvm::ELF::STV_DEFAULT;
     symbol->st_size = 0;
-    auto *newAtom =
-        new (_allocator) ELFUndefinedAtom<ELFT>(*this, symbolName, symbol);
-    this->_undefinedAtoms._atoms.push_back(newAtom);
-    return newAtom;
+    auto newAtom = this->handleUndefinedSymbol(symbolName, symbol);
+    this->_undefinedAtoms._atoms.push_back(*newAtom);
+    return *newAtom;
   }
 
   // cannot add atoms to C Runtime file
   virtual void addAtom(const Atom &) {
     llvm_unreachable("cannot add atoms to Runtime files");
   }
-
-protected:
-  llvm::BumpPtrAllocator _allocator;
 };
 
 template <class ELFT>
 ErrorOr<std::unique_ptr<ELFFile<ELFT>>>
-ELFFile<ELFT>::create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
-                      TargetHandlerBase *handler) {
+ELFFile<ELFT>::create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings) {
   error_code ec;
   std::unique_ptr<ELFFile<ELFT>> file(
       new ELFFile<ELFT>(mb->getBufferIdentifier(), atomizeStrings));
 
-  file->setTargetHandler(handler);
-
   file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
 
   if (ec)
@@ -426,11 +513,11 @@ template <class ELFT> error_code ELFFile
   // b) Create a separate section chunk to write mergeable atoms
   std::vector<MergeString *> tokens;
   for (const Elf_Shdr *msi : _mergeStringSections) {
-    auto sectionName = _objFile->getSectionName(msi);
+    auto sectionName = getSectionName(msi);
     if (error_code ec = sectionName.getError())
       return ec;
 
-    auto sectionContents = _objFile->getSectionContents(msi);
+    auto sectionContents = getSectionContents(msi);
     if (error_code ec = sectionContents.getError())
       return ec;
 
@@ -451,14 +538,11 @@ template <class ELFT> error_code ELFFile
   for (const MergeString *tai : tokens) {
     ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
                               tai->_string.size());
-    ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage) ELFMergeAtom<ELFT>(
-        *this, tai->_sectionName, tai->_shdr, content, tai->_offset);
-    const MergeSectionKey mergedSectionKey(tai->_shdr, tai->_offset);
-    if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
-      _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
-    mergeAtom->setOrdinal(++_ordinal);
-    _definedAtoms._atoms.push_back(mergeAtom);
-    _mergeAtoms.push_back(mergeAtom);
+    ErrorOr<ELFMergeAtom<ELFT> *> mergeAtom =
+        handleMergeString(tai->_sectionName, tai->_shdr, content, tai->_offset);
+    (*mergeAtom)->setOrdinal(++_ordinal);
+    _definedAtoms._atoms.push_back(*mergeAtom);
+    _mergeAtoms.push_back(*mergeAtom);
   }
   return error_code::success();
 }
@@ -480,50 +564,41 @@ error_code ELFFile<ELFT>::createSymbolsF
     if (error_code ec = symbolName.getError())
       return ec;
 
-    if (SymI->st_shndx == llvm::ELF::SHN_ABS) {
-      // Create an absolute atom.
-      auto *newAtom = new (_readerStorage)
-          ELFAbsoluteAtom<ELFT>(*this, *symbolName, &*SymI, SymI->st_value);
-
-      _absoluteAtoms._atoms.push_back(newAtom);
-      _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
-    } else if (SymI->st_shndx == llvm::ELF::SHN_UNDEF) {
-      // Create an undefined atom.
-      auto *newAtom = new (_readerStorage)
-          ELFUndefinedAtom<ELFT>(*this, *symbolName, &*SymI);
-
-      _undefinedAtoms._atoms.push_back(newAtom);
-      _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
+    if (isAbsoluteSymbol(&*SymI)) {
+      ErrorOr<ELFAbsoluteAtom<ELFT> *> absAtom =
+          handleAbsoluteSymbol(*symbolName, &*SymI, SymI->st_value);
+      _absoluteAtoms._atoms.push_back(*absAtom);
+      _symbolToAtomMapping.insert(std::make_pair(&*SymI, *absAtom));
+    } else if (isUndefinedSymbol(&*SymI)) {
+      ErrorOr<ELFUndefinedAtom<ELFT> *> undefAtom =
+          handleUndefinedSymbol(*symbolName, &*SymI);
+      _undefinedAtoms._atoms.push_back(*undefAtom);
+      _symbolToAtomMapping.insert(std::make_pair(&*SymI, *undefAtom));
     } else if (isCommonSymbol(&*SymI)) {
-      auto *newAtom =
-          new (_readerStorage) ELFCommonAtom<ELFT>(*this, *symbolName, &*SymI);
-      newAtom->setOrdinal(++_ordinal);
-      _definedAtoms._atoms.push_back(newAtom);
-      _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
+      ErrorOr<ELFCommonAtom<ELFT> *> commonAtom =
+          handleCommonSymbol(*symbolName, &*SymI);
+      (*commonAtom)->setOrdinal(++_ordinal);
+      _definedAtoms._atoms.push_back(*commonAtom);
+      _symbolToAtomMapping.insert(std::make_pair(&*SymI, *commonAtom));
+    } else if (isDefinedSymbol(&*SymI)) {
+      _sectionSymbols[section].push_back(SymI);
     } else {
-      assert(section && "Symbol not defined in a section!");
-      // This is actually a defined symbol. Add it to its section's list of
-      // symbols.
-      if (SymI->getType() == llvm::ELF::STT_NOTYPE ||
-          SymI->getType() == llvm::ELF::STT_OBJECT ||
-          SymI->getType() == llvm::ELF::STT_FUNC ||
-          SymI->getType() == llvm::ELF::STT_GNU_IFUNC ||
-          SymI->getType() == llvm::ELF::STT_SECTION ||
-          SymI->getType() == llvm::ELF::STT_FILE ||
-          SymI->getType() == llvm::ELF::STT_TLS) {
-        _sectionSymbols[section].push_back(SymI);
-      } else {
-        llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
-        return llvm::object::object_error::parse_failed;
-      }
+      llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
+      return llvm::object::object_error::parse_failed;
     }
   }
+
   return error_code::success();
 }
 
 template <class ELFT> error_code ELFFile<ELFT>::createAtoms() {
   for (auto &i : _sectionSymbols) {
     const Elf_Shdr *section = i.first;
+
+    // Check if need to create atoms for this section ?
+    if ((ignoreCreateAtomsForSection(section)))
+      continue;
+
     std::vector<Elf_Sym_Iter> &symbols = i.second;
 
     // Sort symbols by position.
@@ -531,25 +606,18 @@ template <class ELFT> error_code ELFFile
                      [](Elf_Sym_Iter A,
                         Elf_Sym_Iter B) { return A->st_value < B->st_value; });
 
-    auto sectionName =
-        section ? _objFile->getSectionName(section) : StringRef();
+    ErrorOr<StringRef> sectionName = this->getSectionName(section);
     if (error_code ec = sectionName.getError())
       return ec;
 
-    auto sectionContents =
-        (section && section->sh_type != llvm::ELF::SHT_NOBITS)
-            ? _objFile->getSectionContents(section)
-            : ArrayRef<uint8_t>();
-
+    auto sectionContents = getSectionContents(section);
     if (error_code ec = sectionContents.getError())
       return ec;
 
     StringRef secCont(reinterpret_cast<const char *>(sectionContents->begin()),
                       sectionContents->size());
 
-    // If the section has no symbols, create a custom atom for it.
-    if (section && section->sh_type == llvm::ELF::SHT_PROGBITS &&
-        symbols.empty()) {
+    if (handleSectionWithNoSymbols(section, symbols)) {
       ELFDefinedAtom<ELFT> *newAtom =
           createSectionAtom(section, *sectionName, secCont);
       _definedAtoms._atoms.push_back(newAtom);
@@ -597,11 +665,11 @@ template <class ELFT> error_code ELFFile
       // resolution
       if (isMergeableStringSection(section)) {
         if (symbol->getBinding() == llvm::ELF::STB_GLOBAL) {
-          auto definedMergeAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
-              *this, symbolName, *sectionName, &**si, section, symbolData,
+          auto definedMergeAtom = handleDefinedSymbol(
+              symbolName, *sectionName, &**si, section, symbolData,
               _references.size(), _references.size(), _references);
-          _definedAtoms._atoms.push_back(definedMergeAtom);
-          definedMergeAtom->setOrdinal(++_ordinal);
+          _definedAtoms._atoms.push_back(*definedMergeAtom);
+          (*definedMergeAtom)->setOrdinal(++_ordinal);
         }
         continue;
       }
@@ -711,17 +779,16 @@ ELFDefinedAtom<ELFT> *ELFFile<ELFT>::cre
   }
 
   // Create the DefinedAtom and add it to the list of DefinedAtoms.
-  return new (_readerStorage) ELFDefinedAtom<ELFT>(
-      *this, symbolName, sectionName, symbol, section, content, referenceStart,
-      _references.size(), _references);
+  return *handleDefinedSymbol(symbolName, sectionName, symbol, section, content,
+                              referenceStart, _references.size(), _references);
 }
 
-template <class ELFT> void ELFFile<ELFT>::updateReferences() {
-  /// cached value of target relocation handler
-  assert(_targetHandler);
-  const TargetRelocationHandler<ELFT> &targetRelocationHandler =
-      _targetHandler->getRelocationHandler();
+template <class ELFT>
+int64_t ELFFile<ELFT>::defaultRelocAddend(const Reference &) const {
+  return 0;
+}
 
+template <class ELFT> void ELFFile<ELFT>::updateReferences() {
   for (auto &ri : _references) {
     if (ri->kindNamespace() == lld::Reference::KindNamespace::ELF) {
       const Elf_Sym *symbol = _objFile->getSymbol(ri->targetSymbolIndex());
@@ -737,8 +804,7 @@ template <class ELFT> void ELFFile<ELFT>
       // If the target atom is mergeable string atom, the atom might have been
       // merged with other atom having the same contents. Try to find the
       // merged one if that's the case.
-      int64_t relocAddend = targetRelocationHandler.relocAddend(*ri);
-      uint64_t addend = ri->addend() + relocAddend;
+      uint64_t addend = ri->addend() + defaultRelocAddend(*ri);
       const MergeSectionKey ms(shdr, addend);
       auto msec = _mergedSectionMap.find(ms);
       if (msec != _mergedSectionMap.end()) {
@@ -816,20 +882,6 @@ ELFFile<ELFT>::createSectionAtom(const E
 }
 
 template <class ELFT>
-bool ELFFile<ELFT>::isCommonSymbol(const Elf_Sym *symbol) {
-  // This method handles only architecture independent stuffs, and don't know
-  // whether an architecture dependent section is for common symbols or
-  // not. Let the TargetHandler to make a decision if that's the case.
-  if (isTargetSpecificAtom(nullptr, symbol)) {
-    assert(_targetHandler);
-    TargetAtomHandler<ELFT> &atomHandler = _targetHandler->targetAtomHandler();
-    return atomHandler.getType(symbol) == llvm::ELF::STT_COMMON;
-  }
-  return symbol->getType() == llvm::ELF::STT_COMMON ||
-         symbol->st_shndx == llvm::ELF::SHN_COMMON;
-}
-
-template <class ELFT>
 uint64_t ELFFile<ELFT>::symbolContentSize(const Elf_Shdr *section,
                                           const Elf_Sym *symbol,
                                           const Elf_Sym *nextSymbol) {

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFReader.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFReader.h Sun Jan 26 19:02:03 2014
@@ -34,16 +34,14 @@ struct ELFFileCreateELFTraits {
 
   template <class ELFT>
   static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
-                            bool atomizeStrings, TargetHandlerBase *handler) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
-                                           handler);
+                            bool atomizeStrings) {
+    return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings);
   }
 };
 
 class ELFObjectReader : public Reader {
 public:
-  ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
-      : _atomizeStrings(atomizeStrings), _handler(handler) {}
+  ELFObjectReader(bool atomizeStrings) : _atomizeStrings(atomizeStrings) {}
 
   virtual bool canParse(file_magic magic, StringRef,
                         const MemoryBuffer &) const {
@@ -57,16 +55,15 @@ public:
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
     auto f = createELF<ELFFileCreateELFTraits>(
         llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
-        _atomizeStrings, _handler);
+        _atomizeStrings);
     if (error_code ec = f.getError())
       return ec;
     result.push_back(std::move(*f));
     return error_code::success();
   }
 
-private:
+protected:
   bool _atomizeStrings;
-  TargetHandlerBase *_handler;
 };
 
 class ELFDSOReader : public Reader {
@@ -92,7 +89,7 @@ public:
     return error_code::success();
   }
 
-private:
+protected:
   bool _useUndefines;
 };
 

Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h?rev=200175&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h Sun Jan 26 19:02:03 2014
@@ -0,0 +1,203 @@
+//===- lib/ReaderWriter/ELF/HexagonELFFile.h
+//-------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+#define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+
+#include "ELFReader.h"
+#include "HexagonLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonELFFile;
+
+template <class ELFT>
+class HexagonELFDefinedAtom : public ELFDefinedAtom<ELFT> {
+  typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+  HexagonELFDefinedAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+                        StringRef sectionName, const Elf_Sym *symbol,
+                        const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
+                        unsigned int referenceStart, unsigned int referenceEnd,
+                        std::vector<ELFReference<ELFT> *> &referenceList)
+      : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
+                             contentData, referenceStart, referenceEnd,
+                             referenceList) {}
+
+  virtual DefinedAtom::ContentType contentType() const {
+    if (this->_contentType != DefinedAtom::typeUnknown)
+      return this->_contentType;
+    else if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) {
+      if (this->_section->sh_type == llvm::ELF::SHT_NOBITS)
+        return (this->_contentType = DefinedAtom::typeZeroFillFast);
+      else
+        return (this->_contentType = DefinedAtom::typeDataFast);
+    }
+    return ELFDefinedAtom<ELFT>::contentType();
+  }
+
+  virtual DefinedAtom::ContentPermissions permissions() const {
+    if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
+      return DefinedAtom::permRW_;
+    return ELFDefinedAtom<ELFT>::permissions();
+  }
+};
+
+template <class ELFT> class HexagonELFCommonAtom : public ELFCommonAtom<ELFT> {
+  typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+  HexagonELFCommonAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+                       const Elf_Sym *symbol)
+      : ELFCommonAtom<ELFT>(file, symbolName, symbol) {}
+
+  virtual bool isSmallCommonSymbol() const {
+    switch (this->_symbol->st_shndx) {
+    // Common symbols
+    case llvm::ELF::SHN_HEXAGON_SCOMMON:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+      return true;
+    default:
+      break;
+    }
+    return false;
+  }
+
+  virtual uint64_t size() const {
+    if (isSmallCommonSymbol())
+      return this->_symbol->st_size;
+    return ELFCommonAtom<ELFT>::size();
+  }
+
+  virtual DefinedAtom::Merge merge() const {
+    if (this->_symbol->getBinding() == llvm::ELF::STB_WEAK)
+      return DefinedAtom::mergeAsWeak;
+    if (isSmallCommonSymbol())
+      return DefinedAtom::mergeAsTentative;
+    return ELFCommonAtom<ELFT>::merge();
+  }
+
+  virtual DefinedAtom::ContentType contentType() const {
+    if (isSmallCommonSymbol())
+      return DefinedAtom::typeZeroFillFast;
+    return ELFCommonAtom<ELFT>::contentType();
+  }
+
+  virtual DefinedAtom::Alignment alignment() const {
+    if (isSmallCommonSymbol())
+      return DefinedAtom::Alignment(llvm::Log2_64(this->_symbol->st_value));
+    return ELFCommonAtom<ELFT>::alignment();
+  }
+
+  virtual DefinedAtom::ContentPermissions permissions() const {
+    if (isSmallCommonSymbol())
+      return DefinedAtom::permRW_;
+    return ELFCommonAtom<ELFT>::permissions();
+  }
+};
+
+template <class ELFT> class HexagonELFFile : public ELFFile<ELFT> {
+  typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+  HexagonELFFile(StringRef name, bool atomizeStrings)
+      : ELFFile<ELFT>(name, atomizeStrings) {}
+
+  HexagonELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
+                 error_code &ec)
+      : ELFFile<ELFT>(std::move(mb), atomizeStrings, ec) {}
+
+  static ErrorOr<std::unique_ptr<HexagonELFFile>>
+  create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings) {
+    error_code ec;
+    std::unique_ptr<HexagonELFFile<ELFT>> file(
+        new HexagonELFFile<ELFT>(mb->getBufferIdentifier(), atomizeStrings));
+
+    file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
+
+    if (ec)
+      return ec;
+
+    // Read input sections from the input file that need to be converted to
+    // atoms
+    if ((ec = file->createAtomizableSections()))
+      return ec;
+
+    // For mergeable strings, we would need to split the section into various
+    // atoms
+    if ((ec = file->createMergeableAtoms()))
+      return ec;
+
+    // Create the necessary symbols that are part of the section that we
+    // created in createAtomizableSections function
+    if ((ec = file->createSymbolsFromAtomizableSections()))
+      return ec;
+
+    // Create the appropriate atoms from the file
+    if ((ec = file->createAtoms()))
+      return ec;
+
+    return std::move(file);
+  }
+
+  virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
+    switch (symbol->st_shndx) {
+    // Common symbols
+    case llvm::ELF::SHN_HEXAGON_SCOMMON:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+    case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+      return llvm::ELF::STT_COMMON;
+
+    default:
+      break;
+    }
+    return ELFFile<ELFT>::isCommonSymbol(symbol);
+  }
+
+  /// Process the Defined symbol and create an atom for it.
+  virtual ErrorOr<ELFDefinedAtom<ELFT> *>
+  handleDefinedSymbol(StringRef symName, StringRef sectionName,
+                      const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
+                      ArrayRef<uint8_t> contentData,
+                      unsigned int referenceStart, unsigned int referenceEnd,
+                      std::vector<ELFReference<ELFT> *> &referenceList) {
+    return new (this->_readerStorage) HexagonELFDefinedAtom<ELFT>(
+        *this, symName, sectionName, sym, sectionHdr, contentData,
+        referenceStart, referenceEnd, referenceList);
+  }
+
+  /// Process the Common symbol and create an atom for it.
+  virtual ErrorOr<ELFCommonAtom<ELFT> *>
+  handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
+    return new (this->_readerStorage)
+        HexagonELFCommonAtom<ELFT>(*this, symName, sym);
+  }
+};
+
+template <class ELFT> class HexagonDynamicFile : public DynamicFile<ELFT> {
+public:
+  HexagonDynamicFile(const HexagonLinkingContext &context, StringRef name)
+      : DynamicFile<ELFT>(context, name) {}
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H

Copied: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h (from r200173, lld/trunk/lib/ReaderWriter/ELF/ELFReader.h)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h?p2=lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h&p1=lld/trunk/lib/ReaderWriter/ELF/ELFReader.h&r1=200173&r2=200175&rev=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h Sun Jan 26 19:02:03 2014
@@ -1,4 +1,5 @@
-//===- lib/ReaderWriter/ELF/ELFReader.h -----------------------------------===//
+//===- lib/ReaderWriter/ELF/HexagonELFReader.h
+//------------------------------===//
 //
 //                             The LLVM Linker
 //
@@ -7,83 +8,67 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLD_READER_WRITER_ELF_READER_H
-#define LLD_READER_WRITER_ELF_READER_H
+#ifndef LLD_READER_WRITER_HEXAGON_ELF_READER_H
+#define LLD_READER_WRITER_HEXAGON_ELF_READER_H
 
-#include "CreateELF.h"
-#include "DynamicFile.h"
-#include "ELFFile.h"
-
-#include "lld/ReaderWriter/Reader.h"
+#include "ELFReader.h"
+#include "HexagonELFFile.h"
 
 namespace lld {
 namespace elf {
 
-struct DynamicFileCreateELFTraits {
+struct HexagonDynamicFileCreateELFTraits {
   typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
 
   template <class ELFT>
   static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
                             bool useUndefines) {
-    return lld::elf::DynamicFile<ELFT>::create(std::move(mb), useUndefines);
+    return lld::elf::HexagonDynamicFile<ELFT>::create(std::move(mb),
+                                                      useUndefines);
   }
 };
 
-struct ELFFileCreateELFTraits {
+struct HexagonELFFileCreateELFTraits {
   typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
 
   template <class ELFT>
   static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
-                            bool atomizeStrings, TargetHandlerBase *handler) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
-                                           handler);
+                            bool atomizeStrings) {
+    return lld::elf::HexagonELFFile<ELFT>::create(std::move(mb),
+                                                  atomizeStrings);
   }
 };
 
-class ELFObjectReader : public Reader {
+class HexagonELFObjectReader : public ELFObjectReader {
 public:
-  ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
-      : _atomizeStrings(atomizeStrings), _handler(handler) {}
-
-  virtual bool canParse(file_magic magic, StringRef,
-                        const MemoryBuffer &) const {
-    return (magic == llvm::sys::fs::file_magic::elf_relocatable);
-  }
+  HexagonELFObjectReader(bool atomizeStrings)
+      : ELFObjectReader(atomizeStrings) {}
 
   virtual error_code
   parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
             std::vector<std::unique_ptr<File>> &result) const {
     std::size_t maxAlignment =
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
-    auto f = createELF<ELFFileCreateELFTraits>(
+    auto f = createELF<HexagonELFFileCreateELFTraits>(
         llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
-        _atomizeStrings, _handler);
+        _atomizeStrings);
     if (error_code ec = f.getError())
       return ec;
     result.push_back(std::move(*f));
     return error_code::success();
   }
-
-private:
-  bool _atomizeStrings;
-  TargetHandlerBase *_handler;
 };
 
-class ELFDSOReader : public Reader {
+class HexagonELFDSOReader : public ELFDSOReader {
 public:
-  ELFDSOReader(bool useUndefines) : _useUndefines(useUndefines) {}
-
-  virtual bool canParse(file_magic magic, StringRef,
-                        const MemoryBuffer &) const {
-    return (magic == llvm::sys::fs::file_magic::elf_shared_object);
-  }
+  HexagonELFDSOReader(bool useUndefines) : ELFDSOReader(useUndefines) {}
 
   virtual error_code
   parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
             std::vector<std::unique_ptr<File>> &result) const {
     std::size_t maxAlignment =
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
-    auto f = createELF<DynamicFileCreateELFTraits>(
+    auto f = createELF<HexagonDynamicFileCreateELFTraits>(
         llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
         _useUndefines);
     if (error_code ec = f.getError())
@@ -91,9 +76,6 @@ public:
     result.push_back(std::move(*f));
     return error_code::success();
   }
-
-private:
-  bool _useUndefines;
 };
 
 } // namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp Sun Jan 26 19:02:03 2014
@@ -9,6 +9,7 @@
 
 #include "Atoms.h"
 #include "HexagonLinkingContext.h"
+#include "HexagonTargetHandler.h"
 
 #include "lld/Core/File.h"
 #include "lld/Core/Pass.h"
@@ -101,3 +102,7 @@ void elf::HexagonLinkingContext::createI
     initFiniFile->addFiniFunction(ai);
   result.push_back(std::move(initFiniFile));
 }
+
+HexagonLinkingContext::HexagonLinkingContext(llvm::Triple triple)
+    : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
+                                    new HexagonTargetHandler(*this))) {}

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -10,8 +10,6 @@
 #ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
 #define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
 
-#include "HexagonTargetHandler.h"
-
 #include "lld/ReaderWriter/ELFLinkingContext.h"
 
 #include "llvm/Object/ELF.h"
@@ -22,9 +20,7 @@ namespace elf {
 
 class HexagonLinkingContext LLVM_FINAL : public ELFLinkingContext {
 public:
-  HexagonLinkingContext(llvm::Triple triple)
-      : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
-                                      new HexagonTargetHandler(*this))) {}
+  HexagonLinkingContext(llvm::Triple triple);
 
   virtual void addPasses(PassManager &);
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -15,68 +15,13 @@
 #include "HexagonRelocationHandler.h"
 #include "HexagonSectionChunks.h"
 #include "TargetLayout.h"
+#include "HexagonELFReader.h"
 
 namespace lld {
 namespace elf {
 typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
 class HexagonLinkingContext;
 
-/// \brief Handle Hexagon specific Atoms
-template <class HexagonELFType>
-class HexagonTargetAtomHandler LLVM_FINAL :
-    public TargetAtomHandler<HexagonELFType> {
-  typedef llvm::object::Elf_Sym_Impl<HexagonELFType> Elf_Sym;
-  typedef llvm::object::Elf_Shdr_Impl<HexagonELFType> Elf_Shdr;
-public:
-
-  virtual DefinedAtom::ContentType
-  contentType(const ELFDefinedAtom<HexagonELFType> *atom) const {
-    return contentType(atom->section(), atom->symbol());
-  }
-
-  virtual DefinedAtom::ContentType
-  contentType(const Elf_Shdr *section, const Elf_Sym *sym) const {
-    switch (sym->st_shndx) {
-    // Common symbols
-    case llvm::ELF::SHN_HEXAGON_SCOMMON:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
-      return DefinedAtom::typeZeroFillFast;
-
-    default:
-      if (section->sh_type == llvm::ELF::SHT_NOBITS)
-        return DefinedAtom::typeZeroFillFast;
-      else if (section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
-        return DefinedAtom::typeDataFast;
-      else
-        llvm_unreachable("unknown symbol type");
-    }
-  }
-
-  virtual DefinedAtom::ContentPermissions
-  contentPermissions(const ELFDefinedAtom<HexagonELFType> *atom) const {
-    // All of the hexagon specific symbols belong in the data segment
-    return DefinedAtom::permRW_;
-  }
-
-  virtual int64_t getType(const Elf_Sym *sym) const {
-    switch (sym->st_shndx) {
-    // Common symbols
-    case llvm::ELF::SHN_HEXAGON_SCOMMON:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
-    case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
-      return llvm::ELF::STT_COMMON;
-
-    default:
-      return sym->getType();
-    }
-  }
-};
-
 /// \brief TargetLayout for Hexagon
 template <class HexagonELFType>
 class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
@@ -165,10 +110,6 @@ public:
     return _targetLayout;
   }
 
-  virtual HexagonTargetAtomHandler<HexagonELFType> &targetAtomHandler() {
-    return _targetAtomHandler;
-  }
-
   virtual const HexagonTargetRelocationHandler &getRelocationHandler() const {
     return _relocationHandler;
   }
@@ -216,12 +157,19 @@ public:
     return _gotSymAtom->_virtualAddr;
   }
 
+  virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
+    return std::unique_ptr<Reader>(new HexagonELFObjectReader(atomizeStrings));
+  }
+
+  virtual std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) {
+    return std::unique_ptr<Reader>(new HexagonELFDSOReader(useShlibUndefines));
+  }
+
 private:
   static const Registry::KindStrings kindStrings[];
 
   HexagonTargetLayout<HexagonELFType> _targetLayout;
   HexagonTargetRelocationHandler _relocationHandler;
-  HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
   std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
   AtomLayout *_gotSymAtom;
 };

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -19,6 +19,7 @@
 
 namespace lld {
 namespace elf {
+
 class PPCLinkingContext LLVM_FINAL : public ELFLinkingContext {
 public:
   PPCLinkingContext(llvm::Triple triple)

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -44,7 +44,7 @@ public:
 
 private:
   static const Registry::KindStrings kindStrings[];
-  
+
   PPCTargetRelocationHandler _relocationHandler;
   TargetLayout<PPCELFType> _targetLayout;
 };

Modified: lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Reader.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp Sun Jan 26 19:02:03 2014
@@ -39,16 +39,14 @@ struct ELFFileCreateELFTraits {
 
   template <class ELFT>
   static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
-                            bool atomizeStrings, TargetHandlerBase *handler) {
-    return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
-                                           handler);
+                            bool atomizeStrings) {
+    return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings);
   }
 };
 
 class ELFObjectReader : public Reader {
 public:
-  ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
-      : _atomizeStrings(atomizeStrings), _handler(handler) {}
+  ELFObjectReader(bool atomizeStrings) : _atomizeStrings(atomizeStrings) {}
 
   virtual bool canParse(file_magic magic, StringRef,
                         const MemoryBuffer &) const {
@@ -61,9 +59,8 @@ public:
     error_code ec;
     std::size_t maxAlignment =
         1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
-    auto f = createELF<ELFFileCreateELFTraits>(getElfArchType(&*mb),
-                                               maxAlignment, std::move(mb),
-                                               _atomizeStrings, _handler);
+    auto f = createELF<ELFFileCreateELFTraits>(
+        getElfArchType(&*mb), maxAlignment, std::move(mb), _atomizeStrings);
     if (error_code ec = f.getError())
       return ec;
     result.push_back(std::move(*f));
@@ -72,7 +69,6 @@ public:
 
 private:
   bool _atomizeStrings;
-  TargetHandlerBase *_handler;
 };
 
 class ELFDSOReader : public Reader {
@@ -111,15 +107,16 @@ void Registry::addSupportELFObjects(bool
                                     TargetHandlerBase *handler) {
 
   // Tell registry about the ELF object file parser.
-  add(std::unique_ptr<Reader>(
-      new elf::ELFObjectReader(atomizeStrings, handler)));
+  add(std::move(handler->getObjReader(atomizeStrings)));
 
   // Tell registry about the relocation name to number mapping for this arch.
   handler->registerRelocationNames(*this);
 }
 
-void Registry::addSupportELFDynamicSharedObjects(bool useShlibUndefines) {
-  add(std::unique_ptr<Reader>(new elf::ELFDSOReader(useShlibUndefines)));
+void Registry::addSupportELFDynamicSharedObjects(bool useShlibUndefines,
+                                                 TargetHandlerBase *handler) {
+  // Tell registry about the ELF dynamic shared library file parser.
+  add(handler->getDSOReader(useShlibUndefines));
 }
 
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Sun Jan 26 19:02:03 2014
@@ -40,44 +40,12 @@ template <class ELFT> class ELFHeader;
 template <class ELFT> class Section;
 template <class ELFT> class TargetLayout;
 
-/// \brief The target registers a set of handlers for overriding target specific
-/// attributes for a DefinedAtom. The Reader uses this class to query for the
-/// type of atom and its permissions
-template <class ELFT> class TargetAtomHandler {
-public:
-  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-  typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-  virtual DefinedAtom::ContentType
-  contentType(const ELFDefinedAtom<ELFT> *atom) const {
-    return atom->contentType();
-  }
-
-  virtual DefinedAtom::ContentType
-  contentType(const Elf_Shdr *shdr, const Elf_Sym *sym) const {
-    return DefinedAtom::typeZeroFill;
-  }
-
-  virtual DefinedAtom::ContentPermissions
-  contentPermissions(const ELFDefinedAtom<ELFT> *atom) const {
-    return atom->permissions();
-  }
-
-  virtual int64_t getType(const Elf_Sym *sym) const {
-    return llvm::ELF::STT_NOTYPE;
-  }
-
-  virtual ~TargetAtomHandler() {}
-};
-
 template <class ELFT> class TargetRelocationHandler {
 public:
   virtual error_code
   applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                   const lld::AtomLayout &, const Reference &) const = 0;
 
-  virtual int64_t relocAddend(const Reference &)const { return 0; }
-
   virtual ~TargetRelocationHandler() {}
 };
 
@@ -99,9 +67,6 @@ public:
   /// TargetLayout
   virtual TargetLayout<ELFT> &targetLayout() = 0;
 
-  /// TargetAtomHandler
-  virtual TargetAtomHandler<ELFT> &targetAtomHandler() = 0;
-
   virtual const TargetRelocationHandler<ELFT> &getRelocationHandler() const = 0;
 
   /// Create a set of Default target sections that a target might needj
@@ -127,6 +92,10 @@ public:
   virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
   createDynamicSymbolTable() = 0;
 
+  virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
+
+  virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
+
 protected:
   ELFLinkingContext &_context;
 };





More information about the llvm-commits mailing list