[lld] r197727 - [lld] Introduce registry and Reference kind tuple

Nick Kledzik kledzik at apple.com
Thu Dec 19 13:58:02 PST 2013


Author: kledzik
Date: Thu Dec 19 15:58:00 2013
New Revision: 197727

URL: http://llvm.org/viewvc/llvm-project?rev=197727&view=rev
Log:
[lld] Introduce registry and Reference kind tuple

The main changes are in:
  include/lld/Core/Reference.h
  include/lld/ReaderWriter/Reader.h
Everything else is details to support the main change.

1) Registration based Readers
Previously, lld had a tangled interdependency with all the Readers.  It would
have been impossible to make a streamlined linker (say for a JIT) which
just supported one file format and one architecture (no yaml, no archives, etc).
The old model also required a LinkingContext to read an object file, which
would have made .o inspection tools awkward.

The new model is that there is a global Registry object. You programmatically 
register the Readers you want with the registry object. Whenever you need to 
read/parse a file, you ask the registry to do it, and the registry tries each 
registered reader.

For ease of use with the existing lld code base, there is one Registry
object inside the LinkingContext object. 


2) Changing kind value to be a tuple
Beside Readers, the registry also keeps track of the mapping for Reference
Kind values to and from strings.  Along with that, this patch also fixes
an ambiguity with the previous Reference::Kind values.  The problem was that
we wanted to reuse existing relocation type values as Reference::Kind values.
But then how can the YAML write know how to convert a value to a string? The
fix is to change the 32-bit Reference::Kind into a tuple with an 8-bit namespace
(e.g. ELF, COFFF, etc), an 8-bit architecture (e.g. x86_64, PowerPC, etc), and
a 16-bit value.  This tuple system allows conversion to and from strings with 
no ambiguities.



Added:
    lld/trunk/include/lld/ReaderWriter/YamlContext.h
Removed:
    lld/trunk/include/lld/ReaderWriter/FileArchive.h
Modified:
    lld/trunk/include/lld/Core/ArchiveLibraryFile.h
    lld/trunk/include/lld/Core/File.h
    lld/trunk/include/lld/Core/LinkingContext.h
    lld/trunk/include/lld/Core/Pass.h
    lld/trunk/include/lld/Core/Reference.h
    lld/trunk/include/lld/Core/Resolver.h
    lld/trunk/include/lld/Driver/CoreInputGraph.h
    lld/trunk/include/lld/Driver/DarwinInputGraph.h
    lld/trunk/include/lld/Driver/GnuLdInputGraph.h
    lld/trunk/include/lld/Driver/WinLinkInputGraph.h
    lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/Reader.h
    lld/trunk/include/lld/ReaderWriter/Simple.h
    lld/trunk/lib/Core/LinkingContext.cpp
    lld/trunk/lib/Driver/CoreDriver.cpp
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/GnuLdInputGraph.cpp
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkInputGraph.cpp
    lld/trunk/lib/Passes/GOTPass.cpp
    lld/trunk/lib/Passes/LayoutPass.cpp
    lld/trunk/lib/Passes/RoundTripNativePass.cpp
    lld/trunk/lib/Passes/RoundTripYAMLPass.cpp
    lld/trunk/lib/Passes/StubsPass.cpp
    lld/trunk/lib/ReaderWriter/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
    lld/trunk/lib/ReaderWriter/FileArchive.cpp
    lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
    lld/trunk/lib/ReaderWriter/MachO/GOTPass.hpp
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
    lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
    lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
    lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp
    lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp
    lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp
    lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
    lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
    lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/lib/ReaderWriter/Reader.cpp
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
    lld/trunk/test/darwin/hello-world.objtxt
    lld/trunk/test/elf/reloc.test
    lld/trunk/unittests/DriverTests/InputGraphTest.cpp

Modified: lld/trunk/include/lld/Core/ArchiveLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/ArchiveLibraryFile.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/ArchiveLibraryFile.h (original)
+++ lld/trunk/include/lld/Core/ArchiveLibraryFile.h Thu Dec 19 15:58:00 2013
@@ -33,14 +33,14 @@ public:
   /// specified name and return the File object for that member, or nullptr.
   virtual const File *find(StringRef name, bool dataSymbolOnly) const = 0;
 
-  virtual const LinkingContext &getLinkingContext() const { return _context; }
+  virtual error_code parseAllMembers(
+                          std::vector<std::unique_ptr<File>> &result) const = 0;
 
 protected:
   /// only subclasses of ArchiveLibraryFile can be instantiated
-  ArchiveLibraryFile(const LinkingContext &context, StringRef path)
-      : File(path, kindArchiveLibrary), _context(context) {}
+  ArchiveLibraryFile(StringRef path)
+      : File(path, kindArchiveLibrary) {}
 
-  const LinkingContext &_context;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Thu Dec 19 15:58:00 2013
@@ -155,8 +155,6 @@ public:
   /// all AbsoluteAtoms in this File.
   virtual const atom_collection<AbsoluteAtom> &absolute() const = 0;
 
-  virtual const LinkingContext &getLinkingContext() const = 0;
-
 protected:
   /// \brief only subclasses of File can be instantiated
   File(StringRef p, Kind kind) : _path(p), _kind(kind), _ordinal(UINT64_MAX) {}
@@ -234,15 +232,10 @@ public:
   typedef range<std::vector<const DefinedAtom *>::iterator> DefinedAtomRange;
   virtual DefinedAtomRange definedAtoms() = 0;
 
-  virtual const LinkingContext &getLinkingContext() const { return _context; }
-
 protected:
   /// \brief only subclasses of MutableFile can be instantiated
-  MutableFile(const LinkingContext &ctx, StringRef p)
-      : File(p, kindObject), _context(ctx) {}
-
-private:
-  const LinkingContext &_context;
+  MutableFile(StringRef p)
+      : File(p, kindObject){}
 };
 } // end namespace lld
 

Modified: lld/trunk/include/lld/Core/LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LinkingContext.h (original)
+++ lld/trunk/include/lld/Core/LinkingContext.h Thu Dec 19 15:58:00 2013
@@ -36,8 +36,8 @@ class SharedLibraryFile;
 ///
 /// The base class LinkingContext contains the options needed by core linking.
 /// Subclasses of LinkingContext have additional options needed by specific
-/// Readers and Writers. For example, ELFLinkingContext has methods that
-/// supplies options to the ELF Reader and Writer.
+/// Writers. For example, ELFLinkingContext has methods that supplies
+/// options to the ELF Writer and ELF Passes.
 class LinkingContext {
 public:
   /// \brief The types of output file that the linker creates.
@@ -277,14 +277,9 @@ public:
   /// Returns the output file type that that the linker needs to create.
   OutputFileType outputFileType() const { return _outputFileType; }
 
-  /// Returns the YAML reader.
-  virtual Reader &getYAMLReader() const { return *_yamlReader; }
-
-  /// Returns the LLD Native file format reader.
-  virtual Reader &getNativeReader() const { return *_nativeReader; }
-
-  /// Return the default reader for the target.
-  virtual Reader &getDefaultReader() const = 0;
+  /// Accessor for Register object embedded in LinkingContext.
+  const Registry &registry() const { return _registry; }
+  Registry &registry() { return _registry; }
 
   /// This method is called by core linking to give the Writer a chance
   /// to add file format specific "files" to set of files to be linked. This is
@@ -317,23 +312,9 @@ public:
 
   /// Return the next ordinal and Increment it.
   virtual uint64_t getNextOrdinalAndIncrement() const { return _nextOrdinal++; }
-
-  /// @}
-
-  /// \name Methods needed by YAML I/O and error messages to convert Kind values
-  /// to and from strings.
-  /// @{
-
-  /// Abstract method to parse a kind name string into an integral
-  /// Reference::Kind
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const = 0;
-
-  /// Abstract method to return the name for a given integral
-  /// Reference::Kind.
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind k) const = 0;
-
+  
   /// @}
-
+  
 protected:
   LinkingContext(); // Must be subclassed
 
@@ -361,18 +342,18 @@ protected:
   OutputFileType _outputFileType;
   std::vector<StringRef> _deadStripRoots;
   std::vector<const char *> _llvmOptions;
-  std::unique_ptr<Reader> _yamlReader;
-  std::unique_ptr<Reader> _nativeReader;
   StringRefVector _initialUndefinedSymbols;
   std::unique_ptr<InputGraph> _inputGraph;
   mutable llvm::BumpPtrAllocator _allocator;
   InputElement *_currentInputElement;
   mutable uint64_t _nextOrdinal;
+  Registry  _registry;
 
 private:
   /// Validate the subclass bits. Only called by validate.
   virtual bool validateImpl(raw_ostream &diagnostics) = 0;
 };
+
 } // end namespace lld
 
 #endif

Modified: lld/trunk/include/lld/Core/Pass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Pass.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Pass.h (original)
+++ lld/trunk/include/lld/Core/Pass.h Thu Dec 19 15:58:00 2013
@@ -63,7 +63,7 @@ public:
 
   /// Returns whether the Reference kind is for a call site.  The pass
   /// uses this to find calls that need to be indirected through a stub.
-  virtual bool isCallSite(int32_t) = 0;
+  virtual bool isCallSite(const Reference &) = 0;
 
   /// Returns a file format specific atom for a stub/PLT entry which contains
   /// instructions which jump to the specified atom.  May be called multiple
@@ -101,7 +101,7 @@ public:
   /// Returns whether the Reference kind is a pre-instantiated GOT access.
   /// The default implementation of perform() uses this to figure out
   /// what GOT entries to instantiate.
-  virtual bool isGOTAccess(int32_t, bool &canBypassGOT) = 0;
+  virtual bool isGOTAccess(const Reference &, bool &canBypassGOT) = 0;
 
   /// The file format Writer needs to alter the reference kind from a
   /// pre-instantiated GOT access to an actual access.  If targetIsNowGOT is

Modified: lld/trunk/include/lld/Core/Reference.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reference.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Reference.h (original)
+++ lld/trunk/include/lld/Core/Reference.h Thu Dec 19 15:58:00 2013
@@ -30,53 +30,58 @@ class Atom;
 /// grouping atoms (group comdat), forcing layout (one atom must follow
 /// another), marking data-in-code (jump tables or ARM constants), etc.
 ///
+/// The "kind" of a reference is a tuple of <namespace, arch, value>.  This
+/// enable us to re-use existing relocation types definded for various 
+/// file formats and architectures.  For instance, in ELF the relocation type 10
+/// means R_X86_64_32 for x86_64, and R_386_GOTPC for i386. For PE/COFF 
+/// relocation 10 means IMAGE_REL_AMD64_SECTION. 
+///
 class Reference {
 public:
-  /// The meaning of positive kind values is architecture specific.
-  /// Negative kind values are architecture independent.
-  typedef int32_t Kind;
+  /// Which universe defines the kindValue(). 
+  enum class KindNamespace { 
+    all     = 0,
+    testing = 1,
+    ELF     = 2,
+    COFF    = 3,
+    mach_o  = 4,
+  };
 
+  KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; }
+  void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
+
+  // Which architecture the kind value is for.  
+  enum class KindArch { 
+    all      = 0,
+    x86_64   = 1,
+    x86      = 2,
+    ARM      = 3,
+    PowerPC  = 4,
+    Hexagon  = 5,
+    Mips     = 6
+  };
+  
+  KindArch kindArch() const { return (KindArch)_kindArch; }
+  void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
+
+  typedef uint16_t KindValue;
+  
+  KindValue kindValue() const { return _kindValue; }
+  
+  /// setKindValue() is needed because during linking, some optimizations may 
+  /// change the codegen and hence the reference kind.
+  void setKindValue(KindValue value) { _kindValue = value; };
+
+  /// KindValues used with KindNamespace::all and KindArch::all.
   enum {
-    kindInGroup = -3,
-    kindLayoutAfter = -2,
-    kindLayoutBefore = -1,
-    kindTargetLow = 0
+    kindInGroup       = 1,
+    kindLayoutAfter   = 2,
+    kindLayoutBefore  = 3
   };
 
   // A value to be added to the value of a target
   typedef int64_t Addend;
 
-  /// What sort of reference this is.
-  Kind kind() const { return _kind; }
-
-  /// During linking, some optimizations may change the code gen and
-  /// hence the reference kind.
-  void setKind(Kind kind) { _kind = kind; };
-
-  virtual StringRef kindToString() const {
-    switch (kind()) {
-    case kindLayoutBefore:
-      return "layout-before";
-    case kindLayoutAfter:
-      return "layout-after";
-    case kindInGroup:
-      return "in-group";
-    default:
-      return "unknown";
-    }
-  }
-
-  virtual int32_t stringToKind(StringRef kindString) const {
-    if (kindString == "in-group")
-      return kindInGroup;
-    else if (kindString == "layout-before")
-      return kindLayoutBefore;
-    else if (kindString == "layout-after")
-      return kindLayoutAfter;
-    assert(0 && "unknown relocation kind");
-    return -1;
-  }
-
   /// If the reference is a fixup in the Atom, then this returns the
   /// byte offset into the Atom's content to do the fix up.
   virtual uint64_t offsetInAtom() const = 0;
@@ -96,8 +101,9 @@ public:
   virtual void setAddend(Addend) = 0;
 
 protected:
-  /// Atom is an abstract base class.  Only subclasses can access constructor.
-  Reference() {}
+  /// Reference is an abstract base class.  Only subclasses can use constructor.
+  Reference(KindNamespace ns, KindArch a, KindValue value) 
+    : _kindValue(value), _kindNamespace((uint8_t)ns), _kindArch((uint8_t)a) {}
 
   /// The memory for Reference objects is always managed by the owning File
   /// object.  Therefore, no one but the owning File object should call
@@ -105,7 +111,9 @@ protected:
   /// an array of References, so they cannot be individually deleted by anyone.
   virtual ~Reference() {}
 
-  Kind _kind;
+  KindValue _kindValue;
+  uint8_t  _kindNamespace;
+  uint8_t  _kindArch;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Thu Dec 19 15:58:00 2013
@@ -38,7 +38,7 @@ public:
 
   Resolver(LinkingContext &context)
       : _context(context), _symbolTable(context),
-        _result(new MergedFile(context)), _haveLLVMObjs(false),
+        _result(new MergedFile()), _haveLLVMObjs(false),
         _addToFinalSection(false) {}
 
   virtual ~Resolver() {}
@@ -84,9 +84,9 @@ private:
 
   class MergedFile : public MutableFile {
   public:
-    MergedFile(const LinkingContext &context)
-        : MutableFile(context, "<linker-internal>") {}
-
+    MergedFile()
+        : MutableFile("<linker-internal>") {}
+    
     virtual const atom_collection<DefinedAtom> &defined() const {
       return _definedAtoms;
     }

Modified: lld/trunk/include/lld/Driver/CoreInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/CoreInputGraph.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/CoreInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/CoreInputGraph.h Thu Dec 19 15:58:00 2013
@@ -18,6 +18,7 @@
 #define LLD_DRIVER_CORE_INPUT_GRAPH_H
 
 #include "lld/Core/InputGraph.h"
+#include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/CoreLinkingContext.h"
 
 #include <map>
@@ -50,7 +51,7 @@ public:
 
     std::unique_ptr<MemoryBuffer> mb(opmb.take());
     _buffer = std::move(mb);
-    return _ctx.getDefaultReader().parseFile(_buffer, _files);
+    return ctx.registry().parseFile(_buffer, _files);
   }
 
   /// \brief Return the file that has to be processed by the resolver

Modified: lld/trunk/include/lld/Driver/DarwinInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/DarwinInputGraph.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/DarwinInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/DarwinInputGraph.h Thu Dec 19 15:58:00 2013
@@ -18,6 +18,7 @@
 #define LLD_DRIVER_DARWIN_INPUT_GRAPH_H
 
 #include "lld/Core/InputGraph.h"
+#include "lld/Core/ArchiveLibraryFile.h"
 #include "lld/ReaderWriter/MachOLinkingContext.h"
 
 #include <map>
@@ -48,11 +49,24 @@ public:
     if (ctx.logInputFiles())
       diagnostics << *filePath << "\n";
 
-    if (filePath->endswith(".objtxt"))
-      return ctx.getYAMLReader().parseFile(_buffer, _files);
-
-    (void) (_isWholeArchive);
-    return error_code::success();
+    if (_isWholeArchive) {
+      std::vector<std::unique_ptr<File>> parsedFiles;
+      error_code ec = ctx.registry().parseFile(_buffer, parsedFiles);
+      if (ec)
+        return ec;
+      assert(parsedFiles.size() == 1);
+      std::unique_ptr<File> f(parsedFiles[0].release());
+      if (auto archive = reinterpret_cast<const ArchiveLibraryFile*>(f.get())) {
+        // FIXME: something needs to own archive File
+        //_files.push_back(std::move(archive));
+        return archive->parseAllMembers(_files);
+      } else {
+        // if --whole-archive is around non-archive, just use it as normal.
+        _files.push_back(std::move(f));
+        return error_code::success();
+      }
+    }
+    return ctx.registry().parseFile(_buffer, _files);
   }
 
   /// \brief Return the file that has to be processed by the resolver

Modified: lld/trunk/include/lld/Driver/GnuLdInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/GnuLdInputGraph.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/GnuLdInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/GnuLdInputGraph.h Thu Dec 19 15:58:00 2013
@@ -17,10 +17,10 @@
 #ifndef LLD_DRIVER_GNU_LD_INPUT_GRAPH_H
 #define LLD_DRIVER_GNU_LD_INPUT_GRAPH_H
 
+#include "lld/Core/ArchiveLibraryFile.h"
 #include "lld/Core/InputGraph.h"
 #include "lld/Core/Resolver.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/FileArchive.h"
 #include "lld/ReaderWriter/LinkerScript.h"
 
 namespace lld {
@@ -91,7 +91,7 @@ private:
   bool _isWholeArchive;
   bool _asNeeded;
   bool _isDashlPrefix;
-  std::unique_ptr<FileArchive> _archiveFile;
+  std::unique_ptr<const ArchiveLibraryFile> _archiveFile;
 };
 
 /// \brief Represents a ELF control node

Modified: lld/trunk/include/lld/Driver/WinLinkInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkInputGraph.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkInputGraph.h Thu Dec 19 15:58:00 2013
@@ -19,7 +19,6 @@
 
 #include "lld/Core/InputGraph.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
-#include "lld/ReaderWriter/FileArchive.h"
 
 #include <map>
 

Modified: lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -18,24 +18,28 @@
 
 namespace lld {
 
+
 class CoreLinkingContext : public LinkingContext {
 public:
   CoreLinkingContext();
 
+  enum {
+    TEST_RELOC_CALL32        = 1,
+    TEST_RELOC_PCREL32       = 2,
+    TEST_RELOC_GOT_LOAD32    = 3,
+    TEST_RELOC_GOT_USE32     = 4,
+    TEST_RELOC_LEA32_WAS_GOT = 5,
+  };
+  
   virtual bool validateImpl(raw_ostream &diagnostics);
   virtual void addPasses(PassManager &pm);
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
   void addPassNamed(StringRef name) { _passNames.push_back(name); }
 
-  virtual Reader &getDefaultReader() const { return *_reader; }
-
 protected:
   virtual Writer &writer() const;
 
 private:
-  std::unique_ptr<Reader> _reader;
   std::unique_ptr<Writer> _writer;
   std::vector<StringRef> _passNames;
 };

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -36,8 +36,11 @@ template <typename ELFT> class TargetHan
 class TargetHandlerBase {
 public:
   virtual ~TargetHandlerBase() {}
+  virtual void registerRelocationNames(Registry &) = 0;
 };
 
+
+
 class ELFLinkingContext : public LinkingContext {
 public:
 
@@ -115,8 +118,6 @@ public:
     return getDefaultInterpreter();
   }
 
-  virtual Reader &getDefaultReader() const { return *_elfReader; }
-
   /// \brief Does the output have dynamic sections.
   virtual bool isDynamic() const;
 
@@ -129,6 +130,9 @@ public:
     return static_cast<lld::elf::TargetHandler<ELFT> &>(*_targetHandler.get());
   }
 
+  TargetHandlerBase *targetHandler() const {
+    return _targetHandler.get();
+  }
   virtual void addPasses(PassManager &pm);
 
   void setTriple(llvm::Triple trip) { _triple = trip; }
@@ -248,7 +252,6 @@ protected:
   bool _noAllowDynamicLibraries;
   OutputMagic _outputMagic;
   StringRefVector _inputSearchPaths;
-  std::unique_ptr<Reader> _elfReader;
   std::unique_ptr<Writer> _writer;
   StringRef _dynamicLinkerPath;
   StringRefVector _initFunctions;

Removed: lld/trunk/include/lld/ReaderWriter/FileArchive.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/FileArchive.h?rev=197726&view=auto
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/FileArchive.h (original)
+++ lld/trunk/include/lld/ReaderWriter/FileArchive.h (removed)
@@ -1,59 +0,0 @@
-//===- lld/ReaderWriter/FileArchive.h - Archive Library File -----------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_FILE_ARCHIVE_H
-#define LLD_READER_WRITER_FILE_ARCHIVE_H
-
-#include "lld/Core/ArchiveLibraryFile.h"
-
-#include "llvm/Object/Archive.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-#include <unordered_map>
-
-namespace lld {
-
-/// \brief The FileArchive class represents an Archive Library file
-class FileArchive : public ArchiveLibraryFile {
-public:
-  FileArchive(const LinkingContext &context, std::unique_ptr<MemoryBuffer> mb,
-              error_code &ec, bool isWholeArchive);
-  virtual ~FileArchive() {}
-
-  virtual const File *find(StringRef name, bool dataSymbolOnly) const;
-
-  /// \brief Load all members of the archive?
-  virtual bool isWholeArchive() const { return _isWholeArchive; }
-
-  /// \brief parse each member
-  virtual error_code
-  parseAllMembers(std::vector<std::unique_ptr<File> > &result) const;
-
-  virtual const atom_collection<DefinedAtom> &defined() const;
-  virtual const atom_collection<UndefinedAtom> &undefined() const;
-  virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const;
-  virtual const atom_collection<AbsoluteAtom> &absolute() const;
-
-protected:
-  error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const;
-
-private:
-  std::unique_ptr<llvm::object::Archive>    _archive;
-  atom_collection_vector<DefinedAtom>       _definedAtoms;
-  atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
-  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
-  atom_collection_vector<AbsoluteAtom>      _absoluteAtoms;
-  const bool _isWholeArchive;
-  std::unordered_map<StringRef, llvm::object::Archive::child_iterator>
-  _symbolMemberMap;
-};
-
-} // end namespace lld
-
-#endif // LLD_READER_WRITER_FILE_ARCHIVE_H

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -31,8 +31,6 @@ public:
   ~MachOLinkingContext();
 
   virtual void addPasses(PassManager &pm);
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
   virtual bool validateImpl(raw_ostream &diagnostics);
 
   uint32_t getCPUType() const;
@@ -65,6 +63,7 @@ public:
   };
 
   Arch arch() const { return _arch; }
+  StringRef archName() const { return nameFromArch(_arch); }
   OS os() const { return _os; }
 
   void setOutputFileType(HeaderFileType type) { _outputFileType = type; }
@@ -74,8 +73,6 @@ public:
   void setDoNothing(bool value) { _doNothing = value; }
   bool doNothing() const { return _doNothing; }
 
-  virtual Reader &getDefaultReader() const { return *_machoReader; }
-
   /// \brief The dylib's binary compatibility version, in the raw uint32 format.
   ///
   /// When building a dynamic library, this is the compatibility version that
@@ -125,6 +122,7 @@ public:
 
   static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
   static Arch archFromName(StringRef archName);
+  static StringRef nameFromArch(Arch arch);
   static uint32_t cpuTypeFromArch(Arch arch);
   static uint32_t cpuSubtypeFromArch(Arch arch);
   static bool is64Bit(Arch arch);
@@ -163,7 +161,6 @@ private:
   bool _deadStrippableDylib;
   StringRef _bundleLoader;
   mutable std::unique_ptr<mach_o::KindHandler> _kindHandler;
-  mutable std::unique_ptr<Reader> _machoReader;
   mutable std::unique_ptr<Writer> _writer;
 };
 

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -73,8 +73,6 @@ public:
     IMAGE_DLL
   };
 
-  virtual Reader &getDefaultReader() const { return *_reader; }
-
   virtual Writer &writer() const;
   virtual bool validateImpl(raw_ostream &diagnostics);
 
@@ -198,6 +196,9 @@ public:
                           StringRef from, StringRef to);
 
   StringRef getAlternateName(StringRef def) const;
+  const std::map<std::string, std::string> &alternateNames() {
+    return _alternateNames;
+  }
   void setAlternateName(StringRef def, StringRef weak);
 
   void addNoDefaultLib(StringRef path) { _noDefaultLibs.insert(path); }
@@ -208,9 +209,6 @@ public:
   void setNoDefaultLibAll(bool val) { _noDefaultLibAll = val; }
   bool getNoDefaultLibAll() const { return _noDefaultLibAll; }
 
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
-
   void setSectionSetMask(StringRef sectionName, uint32_t flags);
   void setSectionClearMask(StringRef sectionName, uint32_t flags);
   uint32_t getSectionAttributes(StringRef sectionName, uint32_t flags) const;
@@ -284,7 +282,6 @@ private:
   std::set<std::string> _noDefaultLibs;
 
   std::vector<StringRef> _inputSearchPaths;
-  std::unique_ptr<Reader> _reader;
   std::unique_ptr<Writer> _writer;
 
   // A map for weak aliases.

Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Thu Dec 19 15:58:00 2013
@@ -11,16 +11,23 @@
 #define LLD_READER_WRITER_READER_H
 
 #include "lld/Core/LLVM.h"
+#include "lld/Core/Reference.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/YAMLTraits.h"
 
 #include <functional>
 #include <memory>
 #include <vector>
 
+using llvm::sys::fs::file_magic;
+
 namespace lld {
 class ELFLinkingContext;
 class File;
 class LinkingContext;
 class PECOFFLinkingContext;
+class TargetHandlerBase;
+
 
 /// \brief An abstract class for reading object files, library files, and
 /// executable files.
@@ -31,26 +38,98 @@ class Reader {
 public:
   virtual ~Reader();
 
+  /// Sniffs the file to determine if this Reader can parse it.
+  /// The method is called with:
+  /// 1) the file_magic enumeration returned by identify_magic()
+  /// 2) the file extenstion (e.g. ".obj")
+  /// 3) the whole file content buffer if the above is not enough. 
+  virtual bool canParse(file_magic magic, StringRef fileExtention, 
+                        const MemoryBuffer &mb) const = 0;
+
   /// \brief Parse a supplied buffer (already filled with the contents of a
   /// file) and create a File object.
   ///
-  /// On success, the resulting File object takes ownership of the MemoryBuffer.
+  /// The resulting File object may take ownership of the MemoryBuffer.
   virtual error_code
-  parseFile(std::unique_ptr<MemoryBuffer> &mb,
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
             std::vector<std::unique_ptr<File> > &result) const = 0;
+};
 
-protected:
-  // only concrete subclasses can be instantiated
-  Reader(const LinkingContext &context) : _context(context) {}
 
-  const LinkingContext &_context;
+/// A registry to hold the list of currently registered Readers and
+/// tables which map Reference kind values to strings.
+/// The linker does not directly invoke Readers.  Instead, it registers
+/// Readers based on it configuration and command line options, then calls
+/// the Registry object to parse files. 
+class Registry {
+public:
+  Registry();
+  
+  /// Walk the list of registered Readers and find one that can parse the
+  /// supplied file and parse it.
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File>> &result) const;
+  
+  /// Walk the list of registered kind tables to convert a Reference Kind
+  /// name to a value.
+  bool referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns,
+                               Reference::KindArch &a, 
+                               Reference::KindValue &value) const;
+                                 
+  /// Walk the list of registered kind tables to convert a Reference Kind
+  /// value to a string.
+  bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a, 
+                             Reference::KindValue value, StringRef &) const;
+  
+  // These methods are called to dynamically add support for various file 
+  // formats. The methods are also implemented in the appropriate lib*.a
+  // library, so that the code for handling a format is only linked in, if this
+  // method is used.  Any options that a Reader might need must be passed
+  // as parameters to the addSupport*() method.
+  void addSupportArchives(bool logLoading);
+  void addSupportYamlFiles();
+  void addSupportNativeObjects();
+  void addSupportCOFFObjects(PECOFFLinkingContext &);
+  void addSupportCOFFImportLibraries();
+  void addSupportWindowsResourceFiles();
+  void addSupportMachOObjects(StringRef archName);
+  void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler);
+  void addSupportELFDynamicSharedObjects(bool useShlibUndefines);
+
+  /// To convert between kind values and names, the registry walks the list
+  /// of registered kind tables. Each table is a zero terminated array of
+  /// KindStrings elements.  
+  struct KindStrings { Reference::KindValue value; StringRef name; };
+
+  /// A Reference Kind value is a tuple of <namespace, arch, value>.  All 
+  /// entries in a conversion table have the same <namespace, arch>.  The
+  /// array then contains the value/name pairs.
+  void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch,
+                    const KindStrings array[]);
+
+private:
+  struct KindEntry {  
+    Reference::KindNamespace  ns;
+    Reference::KindArch       arch;
+    const KindStrings        *array;
+  };
+  
+  void add(std::unique_ptr<Reader>);
+                                   
+  std::vector<std::unique_ptr<Reader>>    _readers;
+  std::vector<KindEntry>                  _kindEntries;
 };
 
-std::unique_ptr<Reader> createReaderELF(const ELFLinkingContext &);
-std::unique_ptr<Reader> createReaderMachO(const LinkingContext &);
-std::unique_ptr<Reader> createReaderNative(const LinkingContext &);
-std::unique_ptr<Reader> createReaderPECOFF(PECOFFLinkingContext &);
-std::unique_ptr<Reader> createReaderYAML(const LinkingContext &);
+// Utilities for building a KindString table.  For instance:
+//   static const Registry::KindStrings table[] = {
+//      LLD_KIND_STRING_ENTRY(R_VAX_ADDR16),
+//      LLD_KIND_STRING_ENTRY(R_VAX_DATA16),
+//      LLD_KIND_STRING_END
+//   };
+#define LLD_KIND_STRING_ENTRY(name) { name, #name }
+#define LLD_KIND_STRING_END {0, ""}
+
+
 } // end namespace lld
 
 #endif

Modified: lld/trunk/include/lld/ReaderWriter/Simple.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Simple.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Simple.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Simple.h Thu Dec 19 15:58:00 2013
@@ -23,8 +23,8 @@
 namespace lld {
 class SimpleFile : public MutableFile {
 public:
-  SimpleFile(const LinkingContext &context, StringRef path)
-      : MutableFile(context, path) {}
+  SimpleFile(StringRef path)
+      : MutableFile(path) {}
 
   virtual void addAtom(const Atom &atom) {
     if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom)) {
@@ -63,16 +63,16 @@ public:
   }
 
 protected:
-  atom_collection_vector<DefinedAtom> _definedAtoms;
-  atom_collection_vector<UndefinedAtom> _undefinedAtoms;
+  atom_collection_vector<DefinedAtom>       _definedAtoms;
+  atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
   atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
-  atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
+  atom_collection_vector<AbsoluteAtom>      _absoluteAtoms;
 };
 
 class FileToMutable : public SimpleFile {
 public:
-  FileToMutable(const LinkingContext &context, File &file)
-      : SimpleFile(context, file.path()) {
+  FileToMutable(const LinkingContext &context, const File &file)
+      : SimpleFile(file.path()) {
     for (auto definedAtom : file.defined())
       _definedAtoms._atoms.push_back(std::move(definedAtom));
     for (auto undefAtom : file.undefined())
@@ -86,10 +86,10 @@ public:
 
 class SimpleReference : public Reference {
 public:
-  SimpleReference(Reference::Kind k, uint64_t off, const Atom *t,
+  SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch, 
+                  Reference::KindValue value, uint64_t off, const Atom *t,
                   Reference::Addend a)
-      : _target(t), _offsetInAtom(off), _addend(a) {
-    _kind = k;
+      : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) {
   }
 
   virtual uint64_t offsetInAtom() const { return _offsetInAtom; }
@@ -167,9 +167,10 @@ public:
     it = reinterpret_cast<const void *>(index);
   }
 
-  void addReference(Reference::Kind kind, uint64_t offset, const Atom *target,
-                    Reference::Addend addend) {
-    _references.push_back(SimpleReference(kind, offset, target, addend));
+  void addReference(Reference::KindNamespace ns, Reference::KindArch arch, 
+                    Reference::KindValue kindValue, uint64_t off, 
+                    const Atom *target, Reference::Addend a) {
+    _references.push_back(SimpleReference(ns, arch, kindValue, off, target, a));
   }
 
   void setOrdinal(uint64_t ord) { _ordinal = ord; }

Added: lld/trunk/include/lld/ReaderWriter/YamlContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/YamlContext.h?rev=197727&view=auto
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/YamlContext.h (added)
+++ lld/trunk/include/lld/ReaderWriter/YamlContext.h Thu Dec 19 15:58:00 2013
@@ -0,0 +1,48 @@
+//===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_YAML_CONTEXT_H
+#define LLD_READER_WRITER_YAML_CONTEXT_H
+
+#include "lld/Core/LLVM.h"
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+namespace lld {
+  class File;
+  class LinkingContext;
+  namespace mach_o {
+    namespace normalized {
+      struct NormalizedFile;
+    }
+  }
+  
+using lld::mach_o::normalized::NormalizedFile;
+
+/// When YAML I/O is used in lld, the yaml context always holds a YamlContext
+/// object.  We need to support hetergenous yaml documents which each require
+/// different context info.  This struct supports all clients.
+struct YamlContext {
+  YamlContext()
+      : _linkingContext(nullptr), _registry(nullptr), _file(nullptr), 
+        _normalizeMachOFile(nullptr){}
+
+  const LinkingContext  *_linkingContext;
+  const Registry        *_registry;
+  File                  *_file;
+  NormalizedFile        *_normalizeMachOFile;
+};
+
+} // end namespace lld
+
+#endif // LLD_READER_WRITER_YAML_CONTEXT_H
+
+

Modified: lld/trunk/lib/Core/LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/LinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Core/LinkingContext.cpp (original)
+++ lld/trunk/lib/Core/LinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -30,8 +30,6 @@ LinkingContext::LinkingContext()
 LinkingContext::~LinkingContext() {}
 
 bool LinkingContext::validate(raw_ostream &diagnostics) {
-  _yamlReader = createReaderYAML(*this);
-  _nativeReader = createReaderNative(*this);
   return validateImpl(diagnostics);
 }
 
@@ -48,7 +46,7 @@ std::unique_ptr<File> LinkingContext::cr
   if (entrySymbolName().empty())
     return nullptr;
   std::unique_ptr<SimpleFile> entryFile(
-      new SimpleFile(*this, "command line option -entry"));
+      new SimpleFile("command line option -entry"));
   entryFile->addAtom(
       *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
   return std::move(entryFile);
@@ -58,7 +56,7 @@ std::unique_ptr<File> LinkingContext::cr
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(
-      new SimpleFile(*this, "command line option -u"));
+      new SimpleFile("command line option -u"));
   for (auto undefSymStr : _initialUndefinedSymbols)
     undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
                                    *undefinedSymFile, undefSymStr)));

Modified: lld/trunk/lib/Driver/CoreDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CoreDriver.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CoreDriver.cpp (original)
+++ lld/trunk/lib/Driver/CoreDriver.cpp Thu Dec 19 15:58:00 2013
@@ -66,11 +66,31 @@ public:
 
 namespace lld {
 
+static const Registry::KindStrings coreKindStrings[] = {
+  { CoreLinkingContext::TEST_RELOC_CALL32,        "call32" },
+  { CoreLinkingContext::TEST_RELOC_PCREL32,       "pcrel32" },
+  { CoreLinkingContext::TEST_RELOC_GOT_LOAD32,    "gotLoad32" },
+  { CoreLinkingContext::TEST_RELOC_GOT_USE32,     "gotUse32" },
+  { CoreLinkingContext::TEST_RELOC_LEA32_WAS_GOT, "lea32wasGot" },
+  LLD_KIND_STRING_END
+};
+
+
 bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
-  CoreLinkingContext info;
-  if (!parse(argc, argv, info))
+  CoreLinkingContext ctx;
+  if (!parse(argc, argv, ctx))
     return false;
-  return Driver::link(info);
+  
+  // Register possible input file parsers.
+  ctx.registry().addSupportNativeObjects();
+  ctx.registry().addSupportYamlFiles();
+  
+  ctx.registry().addKindTable(Reference::KindNamespace::testing, 
+                              Reference::KindArch::all, 
+                              coreKindStrings);
+
+
+  return Driver::link(ctx);
 }
 
 bool CoreDriver::parse(int argc, const char *argv[], CoreLinkingContext &ctx,

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Thu Dec 19 15:58:00 2013
@@ -77,6 +77,13 @@ bool DarwinLdDriver::linkMachO(int argc,
     return false;
   if (ctx.doNothing())
     return true;
+    
+  // Register possible input file parsers.
+  ctx.registry().addSupportMachOObjects(ctx.archName());
+  ctx.registry().addSupportArchives(ctx.logInputFiles());
+  ctx.registry().addSupportNativeObjects();
+  ctx.registry().addSupportYamlFiles();
+
   return link(ctx, diagnostics);
 }
 

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Thu Dec 19 15:58:00 2013
@@ -110,6 +110,16 @@ bool GnuLdDriver::linkELF(int argc, cons
   if (!options)
     return true;
 
+  // Register possible input file parsers.
+  options->registry().addSupportELFObjects(options->mergeCommonStrings(), 
+                                           options->targetHandler());
+  options->registry().addSupportArchives(options->logInputFiles());
+  options->registry().addSupportYamlFiles();
+  options->registry().addSupportNativeObjects();
+  if (options->allowLinkWithDynamicLibraries())
+    options->registry().addSupportELFDynamicSharedObjects(
+                                                options->useShlibUndefines());
+
   return link(*options, diagnostics);
 }
 
@@ -326,6 +336,8 @@ bool GnuLdDriver::parse(int argc, const
         }
         resolvedInputPath = resolvedPath->str();
       }
+      // FIXME: Calling getFileMagic() is expensive.  It would be better to
+      // wire up the LdScript parser into the registry.
       llvm::sys::fs::file_magic magic = llvm::sys::fs::file_magic::unknown;
       error_code ec = getFileMagic(*ctx, resolvedInputPath, magic);
       if (ec) {
@@ -336,7 +348,6 @@ bool GnuLdDriver::parse(int argc, const
       if ((!userPath.endswith(".objtxt")) &&
           (magic == llvm::sys::fs::file_magic::unknown))
         isELFFileNode = false;
-
       FileNode *inputNode = nullptr;
       if (isELFFileNode)
         inputNode = new ELFFileNode(*ctx, userPath, index++, isWholeArchive,

Modified: lld/trunk/lib/Driver/GnuLdInputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdInputGraph.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdInputGraph.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdInputGraph.cpp Thu Dec 19 15:58:00 2013
@@ -25,38 +25,27 @@ error_code ELFFileNode::parse(const Link
   if (ctx.logInputFiles())
     diagnostics << *filePath << "\n";
 
-  if (filePath->endswith(".objtxt"))
-    return ctx.getYAMLReader().parseFile(_buffer, _files);
-
-  // Identify File type
-  llvm::sys::fs::file_magic FileType =
-      llvm::sys::fs::identify_magic(_buffer->getBuffer());
-
-  switch (FileType) {
-  case llvm::sys::fs::file_magic::elf_relocatable:
-  case llvm::sys::fs::file_magic::elf_shared_object:
-    // Call the default reader to read object files and shared objects
-    return _elfLinkingContext.getDefaultReader().parseFile(_buffer, _files);
-
-  case llvm::sys::fs::file_magic::archive: {
-    // Process archive files. If Whole Archive option is set,
-    // parse all members of the archive.
-    error_code ec;
-    std::unique_ptr<FileArchive> fileArchive(
-        new FileArchive(ctx, std::move(_buffer), ec, _isWholeArchive));
-    if (_isWholeArchive) {
-      fileArchive->parseAllMembers(_files);
-      _archiveFile = std::move(fileArchive);
-    } else {
-      _files.push_back(std::move(fileArchive));
+  if (_isWholeArchive) {
+    std::vector<std::unique_ptr<File>> parsedFiles;
+    error_code ec = ctx.registry().parseFile(_buffer, parsedFiles);
+    if (ec)
+      return ec;
+    assert(parsedFiles.size() == 1);
+    std::unique_ptr<File> f(parsedFiles[0].release());
+    if (auto archive = reinterpret_cast<const ArchiveLibraryFile*>(f.get())) {
+      // Have this node own the FileArchive object.
+      _archiveFile.reset(archive);
+      f.release();
+      // Add all members to _files vector
+      return archive->parseAllMembers(_files);
+    }
+    else {
+      // if --whole-archive is around non-archive, just use it as normal.
+      _files.push_back(std::move(f));
+      return error_code::success();
     }
-    return ec;
-  }
-
-  default:
-    break;
   }
-  return error_code::success();
+  return ctx.registry().parseFile(_buffer, _files);
 }
 
 /// \brief Parse the GnuLD Script

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Thu Dec 19 15:58:00 2013
@@ -645,6 +645,14 @@ bool WinLinkDriver::linkPECOFF(int argc,
     if (!createManifest(context, diagnostics))
       return false;
 
+  // Register possible input file parsers.
+  context.registry().addSupportCOFFObjects(context);
+  context.registry().addSupportCOFFImportLibraries();
+  context.registry().addSupportWindowsResourceFiles();
+  context.registry().addSupportArchives(context.logInputFiles());
+  context.registry().addSupportNativeObjects();
+  context.registry().addSupportYamlFiles();
+
   return link(context, diagnostics);
 }
 

Modified: lld/trunk/lib/Driver/WinLinkInputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkInputGraph.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkInputGraph.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkInputGraph.cpp Thu Dec 19 15:58:00 2013
@@ -9,9 +9,6 @@
 
 #include "lld/Driver/WinLinkInputGraph.h"
 
-using llvm::sys::fs::file_magic;
-using llvm::sys::fs::identify_magic;
-
 namespace lld {
 
 /// \brief Parse the input file to lld::File.
@@ -31,16 +28,7 @@ error_code PECOFFFileNode::parse(const L
   if (ctx.logInputFiles())
     diagnostics << *filePath << "\n";
 
-  if (filePath->endswith(".objtxt"))
-    return ctx.getYAMLReader().parseFile(_buffer, _files);
-  if (identify_magic(_buffer->getBuffer()) == file_magic::archive) {
-    // Archive File
-    error_code ec;
-    _files.push_back(std::unique_ptr<File>(
-                       new FileArchive(ctx, std::move(_buffer), ec, false)));
-    return ec;
-  }
-  return _ctx.getDefaultReader().parseFile(_buffer, _files);
+  return ctx.registry().parseFile(_buffer, _files);
 }
 
 ErrorOr<File &> PECOFFFileNode::getNextFile() {

Modified: lld/trunk/lib/Passes/GOTPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/GOTPass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Passes/GOTPass.cpp (original)
+++ lld/trunk/lib/Passes/GOTPass.cpp Thu Dec 19 15:58:00 2013
@@ -75,7 +75,7 @@ void GOTPass::perform(std::unique_ptr<Mu
     for (const Reference *ref : *atom) {
       // Look at instructions accessing the GOT.
       bool canBypassGOT;
-      if (!isGOTAccess(ref->kind(), canBypassGOT))
+      if (!isGOTAccess(*ref, canBypassGOT))
         continue;
       const Atom *target = ref->target();
       assert(target != nullptr);

Modified: lld/trunk/lib/Passes/LayoutPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/LayoutPass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Passes/LayoutPass.cpp (original)
+++ lld/trunk/lib/Passes/LayoutPass.cpp Thu Dec 19 15:58:00 2013
@@ -70,8 +70,7 @@ static void showCycleDetectedError(AtomT
   do {
     llvm::dbgs() << "  " << atomToDebugString(atom) << "\n";
     for (const Reference *ref : *atom) {
-      llvm::dbgs() << "    " << ref->kindToString()
-                   << ": " << atomToDebugString(ref->target()) << "\n";
+      llvm::dbgs() << "  "  << atomToDebugString(ref->target()) << "\n";
     }
     atom = followOnNexts[atom];
   } while (atom != start);
@@ -324,7 +323,9 @@ void LayoutPass::buildFollowOnTable(Muta
   _followOnNexts.resize(range.size());
   for (const DefinedAtom *ai : range) {
     for (const Reference *r : *ai) {
-      if (r->kind() != lld::Reference::kindLayoutAfter)
+      if (r->kindNamespace() != lld::Reference::KindNamespace::all)
+        continue;
+      if (r->kindValue() != lld::Reference::kindLayoutAfter)
         continue;
       const DefinedAtom *targetAtom = dyn_cast<DefinedAtom>(r->target());
       _followOnNexts[ai] = targetAtom;
@@ -385,7 +386,9 @@ void LayoutPass::buildInGroupTable(Mutab
   // references so that we have only one table
   for (const DefinedAtom *ai : range) {
     for (const Reference *r : *ai) {
-      if (r->kind() == lld::Reference::kindInGroup) {
+      if (r->kindNamespace() != lld::Reference::KindNamespace::all)
+        continue;
+      if (r->kindValue() == lld::Reference::kindInGroup) {
         const DefinedAtom *rootAtom = dyn_cast<DefinedAtom>(r->target());
         // If the root atom is not part of any root
         // create a new root
@@ -455,7 +458,9 @@ void LayoutPass::buildPrecededByTable(Mu
   // references so that we have only one table
   for (const DefinedAtom *ai : range) {
     for (const Reference *r : *ai) {
-      if (r->kind() == lld::Reference::kindLayoutBefore) {
+      if (r->kindNamespace() != lld::Reference::KindNamespace::all)
+        continue;
+      if (r->kindValue() == lld::Reference::kindLayoutBefore) {
         const DefinedAtom *targetAtom = dyn_cast<DefinedAtom>(r->target());
         // Is the targetAtom not chained
         if (_followOnRoots.count(targetAtom) == 0) {

Modified: lld/trunk/lib/Passes/RoundTripNativePass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/RoundTripNativePass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Passes/RoundTripNativePass.cpp (original)
+++ lld/trunk/lib/Passes/RoundTripNativePass.cpp Thu Dec 19 15:58:00 2013
@@ -40,9 +40,10 @@ void RoundTripNativePass::perform(std::u
     return;
 
   std::unique_ptr<MemoryBuffer> mb(buff.take());
-  _context.getNativeReader().parseFile(mb, _nativeFile);
-
-  mergedFile.reset(new FileToMutable(_context, *_nativeFile[0].get()));
+  error_code ec = _context.registry().parseFile(mb, _nativeFile);
+  assert(!ec && "native reader not registered");
+  File *objFile =  _nativeFile[0].get();
+  mergedFile.reset(new FileToMutable(_context, *objFile));
 
   llvm::sys::fs::remove(tmpNativeFile.str());
 }

Modified: lld/trunk/lib/Passes/RoundTripYAMLPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/RoundTripYAMLPass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Passes/RoundTripYAMLPass.cpp (original)
+++ lld/trunk/lib/Passes/RoundTripYAMLPass.cpp Thu Dec 19 15:58:00 2013
@@ -45,8 +45,12 @@ void RoundTripYAMLPass::perform(std::uni
 
   if (buff->getBufferSize() < MAX_YAML_FILE_SIZE) {
     std::unique_ptr<MemoryBuffer> mb(buff.take());
-    _context.getYAMLReader().parseFile(mb, _yamlFile);
-    mergedFile.reset(new FileToMutable(_context, *_yamlFile[0].get()));
+    error_code ec = _context.registry().parseFile(mb, _yamlFile);
+    assert(!ec && "yaml reader not registered");
+    File *objFile =  _yamlFile[0].get();
+    const File *obj = dyn_cast<const File>(objFile);
+    assert(obj && "yaml generated file is not an relocatable file");
+    mergedFile.reset(new FileToMutable(_context, *obj));
   }
 
   llvm::sys::fs::remove(tmpYAMLFile.str());

Modified: lld/trunk/lib/Passes/StubsPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/StubsPass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/Passes/StubsPass.cpp (original)
+++ lld/trunk/lib/Passes/StubsPass.cpp Thu Dec 19 15:58:00 2013
@@ -32,7 +32,7 @@ void StubsPass::perform(std::unique_ptr<
   for (const DefinedAtom *atom : mergedFile->defined()) {
     for (const Reference *ref : *atom) {
       // Look at call-sites.
-      if (!this->isCallSite(ref->kind()))
+      if (!this->isCallSite(*ref))
         continue;
       const Atom *target = ref->target();
       assert(target != nullptr);

Modified: lld/trunk/lib/ReaderWriter/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CMakeLists.txt?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/CMakeLists.txt Thu Dec 19 15:58:00 2013
@@ -11,6 +11,7 @@ add_lld_library(lldReaderWriter
   LinkerScript.cpp
   Reader.cpp
   Writer.cpp
+  FileArchive.cpp
   )
 
 target_link_libraries(lldReaderWriter

Modified: lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -12,7 +12,6 @@
 #include "lld/Core/Pass.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Passes/LayoutPass.h"
-#include "lld/Passes/RoundTripNativePass.h"
 #include "lld/Passes/RoundTripYAMLPass.h"
 #include "lld/ReaderWriter/Simple.h"
 
@@ -155,7 +154,7 @@ private:
 class TestingPassFile : public SimpleFile {
 public:
   TestingPassFile(const LinkingContext &ctx)
-      : SimpleFile(ctx, "Testing pass") {}
+      : SimpleFile("Testing pass") {}
 
   virtual void addAtom(const Atom &atom) {
     if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom))
@@ -189,25 +188,6 @@ private:
   atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
 };
 
-struct TestingKindMapping {
-  const char *string;
-  int32_t value;
-  bool isBranch;
-  bool isGotLoad;
-  bool isGotUse;
-};
-
-//
-// Table of fixup kinds in YAML documents used for testing
-//
-const TestingKindMapping sKinds[] = {
-  { "in-group", -3, false, false, false },
-  { "layout-after", -2, false, false, false },
-  { "layout-before", -1, false, false, false },
-  { "call32", 2, true, false, false }, { "pcrel32", 3, false, false, false },
-  { "gotLoad32", 7, false, true, true }, { "gotUse32", 9, false, false, true },
-  { "lea32wasGot", 8, false, false, false }, { nullptr, 0, false, false, false }
-};
 
 class TestingStubsPass : public StubsPass {
 public:
@@ -215,12 +195,10 @@ public:
 
   virtual bool noTextRelocs() { return true; }
 
-  virtual bool isCallSite(int32_t kind) {
-    for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
-      if (kind == p->value)
-        return p->isBranch;
-    }
-    return false;
+  virtual bool isCallSite(const Reference &ref) {
+    if (ref.kindNamespace() != Reference::KindNamespace::testing)
+      return false;
+    return (ref.kindValue() == CoreLinkingContext::TEST_RELOC_CALL32);
   }
 
   virtual const DefinedAtom *getStub(const Atom &target) {
@@ -245,22 +223,25 @@ public:
 
   virtual bool noTextRelocs() { return true; }
 
-  virtual bool isGOTAccess(int32_t kind, bool &canBypassGOT) {
-    for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
-      if (kind == p->value) {
-        canBypassGOT = p->isGotLoad;
-        return p->isGotUse || p->isGotLoad;
-      }
+  virtual bool isGOTAccess(const Reference &ref, bool &canBypassGOT) {
+    if (ref.kindNamespace() != Reference::KindNamespace::testing)
+      return false;
+    switch (ref.kindValue()) {
+    case CoreLinkingContext::TEST_RELOC_GOT_LOAD32:
+      canBypassGOT = true;
+      return true;
+    case CoreLinkingContext::TEST_RELOC_GOT_USE32:
+      canBypassGOT = false;
+      return true;
     }
     return false;
   }
 
   virtual void updateReferenceToGOT(const Reference *ref, bool targetIsNowGOT) {
-    if (targetIsNowGOT)
-      const_cast<Reference *>(ref)->setKind(3); // pcrel32
-    else
-      const_cast<Reference *>(ref)->setKind(8); // lea32wasGot
-  }
+    const_cast<Reference *>(ref)->setKindValue(targetIsNowGOT ?
+                                  CoreLinkingContext::TEST_RELOC_PCREL32 : 
+                                  CoreLinkingContext::TEST_RELOC_LEA32_WAS_GOT);
+   }
 
   virtual const DefinedAtom *makeGOTEntry(const Atom &target) {
     return new TestingGOTAtom(_file, target);
@@ -275,7 +256,6 @@ private:
 CoreLinkingContext::CoreLinkingContext() {}
 
 bool CoreLinkingContext::validateImpl(raw_ostream &) {
-  _reader = createReaderYAML(*this);
   _writer = createWriterYAML(*this);
   return true;
 }
@@ -295,20 +275,3 @@ void CoreLinkingContext::addPasses(PassM
 
 Writer &CoreLinkingContext::writer() const { return *_writer; }
 
-ErrorOr<Reference::Kind>
-CoreLinkingContext::relocKindFromString(StringRef str) const {
-  for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
-    if (str.equals(p->string))
-      return p->value;
-  }
-  return make_error_code(YamlReaderError::illegal_value);
-}
-
-ErrorOr<std::string>
-CoreLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  for (const TestingKindMapping *p = sKinds; p->string != nullptr; ++p) {
-    if (kind == p->value)
-      return std::string(p->string);
-  }
-  return make_error_code(YamlReaderError::illegal_value);
-}

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Thu Dec 19 15:58:00 2013
@@ -41,21 +41,25 @@ template <class ELFT> class ELFReference
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 public:
 
-  ELFReference(const Elf_Rela *rela, uint64_t off, Kind kind, uint32_t idx)
-      : _target(nullptr), _targetSymbolIndex(idx),
+  ELFReference(const Elf_Rela *rela, uint64_t off, Reference::KindArch arch, 
+                                              uint16_t relocType, uint32_t idx)
+      : Reference(Reference::KindNamespace::ELF, arch, relocType), 
+        _target(nullptr), _targetSymbolIndex(idx),
         _offsetInAtom(off), _addend(rela->r_addend) {
-    _kind = kind;
   }
 
-  ELFReference(const Elf_Rel *rel, uint64_t off, Kind kind, uint32_t idx)
-      : _target(nullptr), _targetSymbolIndex(idx),
+  ELFReference(const Elf_Rel *rel, uint64_t off, Reference::KindArch arch, 
+                                              uint16_t relocType, uint32_t idx)
+      : Reference(Reference::KindNamespace::ELF, arch, relocType), 
+        _target(nullptr), _targetSymbolIndex(idx),
         _offsetInAtom(off), _addend(0) {
-    _kind = kind;
   }
 
-  ELFReference(Kind kind)
-      : _target(nullptr), _targetSymbolIndex(0), _offsetInAtom(0), _addend(0) {
-    _kind = kind;
+  ELFReference(uint32_t edgeKind)
+      : Reference(Reference::KindNamespace::all, 
+                  Reference::KindArch::all, edgeKind), 
+        _target(nullptr), _targetSymbolIndex(0), 
+        _offsetInAtom(0), _addend(0) {
   }
 
   virtual uint64_t offsetInAtom() const { return _offsetInAtom; }
@@ -186,8 +190,12 @@ public:
     , _referenceList(referenceList)
     , _targetAtomHandler(nullptr)
     , _contentType(typeUnknown)
-    , _permissions(permUnknown) {}
+    , _permissions(permUnknown) {
+    }
 
+  ~ELFDefinedAtom() {
+  }
+  
   virtual const ELFFile<ELFT> &file() const {
     return _owningFile;
   }
@@ -211,11 +219,8 @@ public:
     // Treat target defined common symbols
     if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
          _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler) {
-        const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
-        TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
-        _targetAtomHandler = &TargetHandler.targetAtomHandler();
-      }
+      if (!_targetAtomHandler) 
+        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
       if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
         return (uint64_t) _symbol->st_size;
     }
@@ -250,11 +255,8 @@ public:
     // mergeTentative
     if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
          _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler) {
-        const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
-        TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
-        _targetAtomHandler = &TargetHandler.targetAtomHandler();
-      }
+      if (!_targetAtomHandler) 
+        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
       if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
         return mergeAsTentative;
     }
@@ -277,11 +279,8 @@ public:
     if ((_section->sh_flags & llvm::ELF::SHF_MASKPROC) ||
         ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
           _symbol->st_shndx < llvm::ELF::SHN_HIPROC))) {
-      if (!_targetAtomHandler) {
-        const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
-        TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
-        _targetAtomHandler = &TargetHandler.targetAtomHandler();
-      }
+      if (!_targetAtomHandler)
+        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
       return _contentType = _targetAtomHandler->contentType(this);
     }
 
@@ -361,11 +360,8 @@ public:
     // Treat target defined common symbols
     if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
          _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler) {
-        const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
-        TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
-        _targetAtomHandler = &TargetHandler.targetAtomHandler();
-      }
+      if (!_targetAtomHandler)
+        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
       if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
         return Alignment(llvm::Log2_64(_symbol->st_value));
     }
@@ -422,11 +418,8 @@ public:
     // Treat target defined symbols
     if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
          _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
-      if (!_targetAtomHandler) {
-        const ELFLinkingContext &eti = (_owningFile.getLinkingContext());
-        TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
-        _targetAtomHandler = &TargetHandler.targetAtomHandler();
-      }
+      if (!_targetAtomHandler)
+        _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
       return _permissions = _targetAtomHandler->contentPermissions(this);
     }
 
@@ -671,8 +664,8 @@ public:
   virtual ContentType contentType() const {
     if (_symbol->st_shndx >= llvm::ELF::SHN_LORESERVE &&
         _symbol->st_shndx <= llvm::ELF::SHN_HIOS)
-      return _owningFile.getLinkingContext().template getTargetHandler<ELFT>().
-                 targetAtomHandler().contentType(nullptr, _symbol);
+      return _owningFile.targetHandler()->targetAtomHandler().
+                                                  contentType(nullptr, _symbol);
     return typeZeroFill;
   }
 
@@ -795,11 +788,46 @@ private:
   const Elf_Sym *_symbol;
 };
 
+
+class SimpleELFDefinedAtom : public SimpleDefinedAtom {
+public:
+  SimpleELFDefinedAtom(const File &f) : SimpleDefinedAtom(f) { } 
+
+  void addReferenceELF(Reference::KindArch arch, 
+                    uint16_t kindValue, uint64_t off, const Atom *target,
+                    Reference::Addend addend) {
+    this->addReference(Reference::KindNamespace::ELF, arch, kindValue,
+                       off, target, addend);
+  }
+  
+  void addReferenceELF_Hexagon(uint16_t relocType, uint64_t off, const Atom *t,
+                                Reference::Addend a) {
+    this->addReferenceELF(Reference::KindArch::Hexagon, relocType, off, t, a);
+  }
+  
+  void addReferenceELF_x86_64(uint16_t relocType, uint64_t off, const Atom *t,
+                              Reference::Addend a) {
+    this->addReferenceELF(Reference::KindArch::x86_64, relocType, off, t, a);
+  }
+  
+  void addReferenceELF_PowerPC(uint16_t relocType, uint64_t off, const Atom *t,
+                               Reference::Addend a) {
+    this->addReferenceELF(Reference::KindArch::PowerPC, relocType, off, t, a);
+  }
+  
+  void addReferenceELF_Mips(uint16_t relocType, uint64_t off, const Atom *t,
+                               Reference::Addend a) {
+    this->addReferenceELF(Reference::KindArch::Mips, relocType, off, t, a);
+  }
+};
+
+
+
 /// \brief Atom which represents an object for which a COPY relocation will be
 ///   generated.
-class ObjectAtom : public SimpleDefinedAtom {
+class ObjectAtom : public SimpleELFDefinedAtom {
 public:
-  ObjectAtom(const File &f) : SimpleDefinedAtom(f) {}
+  ObjectAtom(const File &f) : SimpleELFDefinedAtom(f) {}
 
   virtual Scope scope() const { return scopeGlobal; }
 
@@ -828,12 +856,12 @@ public:
   uint64_t _size;
 };
 
-class GOTAtom : public SimpleDefinedAtom {
+class GOTAtom : public SimpleELFDefinedAtom {
   StringRef _section;
 
 public:
   GOTAtom(const File &f, StringRef secName)
-      : SimpleDefinedAtom(f), _section(secName) {
+      : SimpleELFDefinedAtom(f), _section(secName) {
   }
 
   virtual Scope scope() const { return scopeTranslationUnit; }
@@ -864,12 +892,12 @@ public:
 #endif
 };
 
-class PLTAtom : public SimpleDefinedAtom {
+class PLTAtom : public SimpleELFDefinedAtom {
   StringRef _section;
 
 public:
   PLTAtom(const File &f, StringRef secName)
-      : SimpleDefinedAtom(f), _section(secName) {
+      : SimpleELFDefinedAtom(f), _section(secName) {
   }
 
   virtual Scope scope() const { return scopeTranslationUnit; }
@@ -909,9 +937,9 @@ public:
   }
 };
 
-class GLOBAL_OFFSET_TABLEAtom : public SimpleDefinedAtom {
+class GLOBAL_OFFSET_TABLEAtom : public SimpleELFDefinedAtom {
 public:
-  GLOBAL_OFFSET_TABLEAtom(const File &f) : SimpleDefinedAtom(f) {}
+  GLOBAL_OFFSET_TABLEAtom(const File &f) : SimpleELFDefinedAtom(f) {}
 
   virtual StringRef name() const { return "_GLOBAL_OFFSET_TABLE_"; }
 
@@ -937,9 +965,9 @@ public:
   }
 };
 
-class TLSGETADDRAtom : public SimpleDefinedAtom {
+class TLSGETADDRAtom : public SimpleELFDefinedAtom {
 public:
-  TLSGETADDRAtom(const File &f) : SimpleDefinedAtom(f) {}
+  TLSGETADDRAtom(const File &f) : SimpleELFDefinedAtom(f) {}
 
   virtual StringRef name() const { return "__tls_get_addr"; }
 
@@ -962,9 +990,9 @@ public:
   virtual ArrayRef<uint8_t> rawContent() const { return ArrayRef<uint8_t>(); }
 };
 
-class DYNAMICAtom : public SimpleDefinedAtom {
+class DYNAMICAtom : public SimpleELFDefinedAtom {
 public:
-  DYNAMICAtom(const File &f) : SimpleDefinedAtom(f) {}
+  DYNAMICAtom(const File &f) : SimpleELFDefinedAtom(f) {}
 
   virtual StringRef name() const { return "_DYNAMIC"; }
 
@@ -987,12 +1015,12 @@ public:
   virtual ArrayRef<uint8_t> rawContent() const { return ArrayRef<uint8_t>(); }
 };
 
-class InitFiniAtom : public SimpleDefinedAtom {
+class InitFiniAtom : public SimpleELFDefinedAtom {
   StringRef _section;
 
 public:
   InitFiniAtom(const File &f, StringRef secName)
-      : SimpleDefinedAtom(f), _section(secName) {
+      : SimpleELFDefinedAtom(f), _section(secName) {
   }
 
   virtual Scope scope() const { return scopeGlobal; }

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Dec 19 15:58:00 2013
@@ -331,7 +331,7 @@ Layout::SectionOrder DefaultLayout<ELFT>
   switch (contentType) {
   case DefinedAtom::typeResolver:
   case DefinedAtom::typeCode:
-    return llvm::StringSwitch<Reference::Kind>(name)
+    return llvm::StringSwitch<Layout::SectionOrder>(name)
       .StartsWith(".eh_frame_hdr", ORDER_EH_FRAMEHDR)
       .StartsWith(".eh_frame", ORDER_EH_FRAME)
       .StartsWith(".init", ORDER_INIT)
@@ -344,7 +344,7 @@ Layout::SectionOrder DefaultLayout<ELFT>
 
   case DefinedAtom::typeData:
   case DefinedAtom::typeDataFast:
-    return llvm::StringSwitch<Reference::Kind>(name)
+    return llvm::StringSwitch<Layout::SectionOrder>(name)
         .StartsWith(".init_array", ORDER_INIT_ARRAY)
         .StartsWith(".fini_array", ORDER_FINI_ARRAY)
         .Default(ORDER_DATA);
@@ -354,7 +354,7 @@ Layout::SectionOrder DefaultLayout<ELFT>
     return ORDER_BSS;
 
   case DefinedAtom::typeGOT:
-    return llvm::StringSwitch<Reference::Kind>(name)
+    return llvm::StringSwitch<Layout::SectionOrder>(name)
       .StartsWith(".got.plt", ORDER_GOT_PLT)
       .Default(ORDER_GOT);
 

Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Thu Dec 19 15:58:00 2013
@@ -25,11 +25,9 @@ namespace elf {
 template <class ELFT> class DynamicFile LLVM_FINAL : public SharedLibraryFile {
 public:
   static ErrorOr<std::unique_ptr<DynamicFile> >
-  create(const ELFLinkingContext &ctx, std::unique_ptr<llvm::MemoryBuffer> mb) {
+  create(std::unique_ptr<llvm::MemoryBuffer> mb, bool useShlibUndefines) {
     std::unique_ptr<DynamicFile> file(
-        new DynamicFile(ctx, mb->getBufferIdentifier()));
-
-    bool useShlibUndefines = ctx.useShlibUndefines();
+        new DynamicFile(mb->getBufferIdentifier()));
 
     error_code ec;
     file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
@@ -105,16 +103,11 @@ public:
         *this, name, _soname, sym->second._symbol);
   }
 
-  virtual const ELFLinkingContext &getLinkingContext() const {
-    return _context;
-  }
-
 private:
-  DynamicFile(const ELFLinkingContext &context, StringRef name)
-      : SharedLibraryFile(name), _context(context) {}
+  DynamicFile(StringRef name)
+      : SharedLibraryFile(name) {}
 
   mutable llvm::BumpPtrAllocator _alloc;
-  const ELFLinkingContext &_context;
   std::unique_ptr<llvm::object::ELFFile<ELFT>> _objFile;
   atom_collection_vector<DefinedAtom> _definedAtoms;
   atom_collection_vector<UndefinedAtom> _undefinedAtoms;

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -16,7 +16,6 @@
 
 #include "lld/Core/Instrumentation.h"
 #include "lld/Passes/LayoutPass.h"
-#include "lld/Passes/RoundTripNativePass.h"
 #include "lld/Passes/RoundTripYAMLPass.h"
 
 #include "llvm/ADT/Triple.h"
@@ -36,8 +35,8 @@ public:
   }
 };
 
-ELFLinkingContext::ELFLinkingContext(
-    llvm::Triple triple, std::unique_ptr<TargetHandlerBase> targetHandler)
+ELFLinkingContext::ELFLinkingContext(llvm::Triple triple, 
+                               std::unique_ptr<TargetHandlerBase> targetHandler)
     : _outputELFType(elf::ET_EXEC), _triple(triple),
       _targetHandler(std::move(targetHandler)), _baseAddress(0),
       _isStaticExecutable(false), _noInhibitExec(false),
@@ -83,7 +82,6 @@ StringRef ELFLinkingContext::entrySymbol
 }
 
 bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
-  _elfReader = createReaderELF(*this);
   switch (outputFileType()) {
   case LinkingContext::OutputFileType::YAML:
     _writer = createWriterYAML(*this);
@@ -185,7 +183,7 @@ std::unique_ptr<File> ELFLinkingContext:
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(
-      new SimpleFile(*this, "command line option -u"));
+      new SimpleFile("command line option -u"));
   for (auto undefSymStr : _initialUndefinedSymbols)
     undefinedSymFile->addAtom(*(new (_allocator) CommandLineUndefinedAtom(
                                    *undefinedSymFile, undefSymStr)));

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Thu Dec 19 15:58:00 2013
@@ -14,8 +14,8 @@
 
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
+
 #include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/FileArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
@@ -118,48 +118,67 @@ template <class ELFT> class ELFFile : pu
   typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
 
 public:
-  ELFFile(const ELFLinkingContext &context, StringRef name)
-      : File(name, kindObject), _elfLinkingContext(context) {}
-
-  ELFFile(const ELFLinkingContext &context,
-          std::unique_ptr<MemoryBuffer> MB, error_code &EC)
-      : File(MB->getBufferIdentifier(), kindObject),
-        _elfLinkingContext(context), _ordinal(0), _doStringsMerge(false) {
-    _objFile.reset(new llvm::object::ELFFile<ELFT>(MB.release(), EC));
+  ELFFile(StringRef name)
+      : File(name, kindObject), _ordinal(0), 
+          _doStringsMerge(false), _targetHandler(nullptr) {}
+
+  ELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
+          TargetHandlerBase *handler, error_code &ec)
+      : File(mb->getBufferIdentifier(), kindObject),
+        _ordinal(0), _doStringsMerge(atomizeStrings), 
+        _targetHandler(reinterpret_cast<TargetHandler<ELFT>*>(handler)) {
+    _objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
 
-    if (EC)
+    if (ec)
       return;
 
-    _doStringsMerge = _elfLinkingContext.mergeCommonStrings();
-
     // Read input sections from the input file that need to be converted to
     // atoms
     if (auto err = createAtomizableSections()) {
-      EC = err;
+      ec = err;
       return;
     }
 
     // For mergeable strings, we would need to split the section into various
     // atoms
     if (auto err = createMergeableAtoms()) {
-      EC = err;
+      ec = err;
       return;
     }
 
     // Create the necessary symbols that are part of the section that we
     // created in createAtomizableSections function
     if (auto err = createSymbolsFromAtomizableSections()) {
-      EC = err;
+      ec = err;
       return;
     }
 
     // Create the appropriate atoms from the file
     if (auto err = createAtoms()) {
-      EC = err;
+      ec = err;
       return;
     }
   }
 
+  Reference::KindArch kindArch() {
+    switch (_objFile->getHeader()->e_machine) {
+      case llvm::ELF::EM_X86_64:
+        return Reference::KindArch::x86_64;
+      case llvm::ELF::EM_386:
+        return Reference::KindArch::x86;
+      case llvm::ELF::EM_ARM:
+        return Reference::KindArch::ARM;
+      case llvm::ELF::EM_PPC:
+        return Reference::KindArch::PowerPC;
+      case llvm::ELF::EM_HEXAGON:
+        return Reference::KindArch::Hexagon;
+      case llvm::ELF::EM_MIPS:
+        return Reference::KindArch::Mips;
+    }
+    llvm_unreachable("unsupported e_machine value");
+  }
+
+
   /// \brief Read input sections and populate necessary data structures
   /// to read them later and create atoms
   error_code createAtomizableSections() {
@@ -446,7 +465,7 @@ public:
         // If the atom was a weak symbol, let's create a followon reference to
         // the anonymous atom that we created.
         if (anonAtom)
-          createEdge(newAtom, anonAtom, lld::Reference::kindLayoutAfter);
+          createEdge(newAtom, anonAtom, Reference::kindLayoutAfter);
 
         if (previousAtom) {
           // Set the followon atom to the weak atom that we have created, so
@@ -491,8 +510,8 @@ public:
     return _absoluteAtoms;
   }
 
-  virtual const ELFLinkingContext &getLinkingContext() const {
-    return _elfLinkingContext;
+  TargetHandler<ELFT> *targetHandler() const {
+    return _targetHandler;
   }
 
   Atom *findAtom(const Elf_Sym *symbol) {
@@ -516,11 +535,10 @@ private:
             symbol->st_value + content.size() <= rai.r_offset)
           continue;
         bool isMips64EL = _objFile->isMips64EL();
-        Reference::Kind kind = (Reference::Kind) rai.getType(isMips64EL);
         uint32_t symbolIndex = rai.getSymbol(isMips64EL);
         auto *ERef = new (_readerStorage)
             ELFReference<ELFT>(&rai, rai.r_offset - symbol->st_value,
-                               kind, symbolIndex);
+                              kindArch(), rai.getType(isMips64EL), symbolIndex);
         _references.push_back(ERef);
       }
     }
@@ -533,11 +551,10 @@ private:
             symbol->st_value + content.size() <= ri.r_offset)
           continue;
         bool isMips64EL = _objFile->isMips64EL();
-        Reference::Kind kind = (Reference::Kind) ri.getType(isMips64EL);
         uint32_t symbolIndex = ri.getSymbol(isMips64EL);
         auto *ERef = new (_readerStorage)
             ELFReference<ELFT>(&ri, ri.r_offset - symbol->st_value,
-                               kind, symbolIndex);
+                               kindArch(), ri.getType(isMips64EL), symbolIndex);
         // Read the addend from the section contents
         // TODO : We should move the way lld reads relocations totally from
         // ELFFile
@@ -557,12 +574,12 @@ private:
   /// Reference's target with the Atom pointer it refers to.
   void updateReferences() {
     /// cached value of target relocation handler
-    const TargetRelocationHandler<ELFT> &_targetRelocationHandler =
-        _elfLinkingContext.template getTargetHandler<ELFT>()
-            .getRelocationHandler();
+    assert(_targetHandler);
+    const TargetRelocationHandler<ELFT> &targetRelocationHandler =
+                                        _targetHandler->getRelocationHandler();
 
     for (auto &ri : _references) {
-      if (ri->kind() >= lld::Reference::kindTargetLow) {
+      if (ri->kindNamespace() == lld::Reference::KindNamespace::ELF) {
         const Elf_Sym *symbol = _objFile->getSymbol(ri->targetSymbolIndex());
         const Elf_Shdr *shdr = _objFile->getSection(symbol);
 
@@ -576,7 +593,7 @@ private:
         // 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);
+        int64_t relocAddend = targetRelocationHandler.relocAddend(*ri);
         uint64_t addend = ri->addend() + relocAddend;
         const MergeSectionKey ms(shdr, addend);
         auto msec = _mergedSectionMap.find(ms);
@@ -671,11 +688,9 @@ private:
     // 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)) {
-      TargetHandler<ELFT> &targetHandler =
-          _elfLinkingContext.template getTargetHandler<ELFT>();
-      TargetAtomHandler<ELFT> &targetAtomHandler =
-          targetHandler.targetAtomHandler();
-      return targetAtomHandler.getType(symbol) == llvm::ELF::STT_COMMON;
+      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;
@@ -692,8 +707,8 @@ private:
   }
 
   void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
-                  lld::Reference::Kind kind) {
-    auto reference = new (_readerStorage) ELFReference<ELFT>(kind);
+                  uint32_t edgeKind) {
+    auto reference = new (_readerStorage) ELFReference<ELFT>(edgeKind);
     reference->setTarget(to);
     from->addReference(reference);
   }
@@ -721,7 +736,6 @@ private:
   _relocationReferences;
   std::vector<ELFReference<ELFT> *> _references;
   llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
-  const ELFLinkingContext &_elfLinkingContext;
 
   /// \brief Atoms that are created for a section that has the merge property
   /// set
@@ -738,6 +752,7 @@ private:
 
   /// \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
@@ -749,7 +764,7 @@ template <class ELFT> class CRuntimeFile
 public:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
   CRuntimeFile(const ELFLinkingContext &context, StringRef name = "C runtime")
-      : ELFFile<ELFT>(context, name) {}
+      : ELFFile<ELFT>(name) {}
 
   /// \brief add a global absolute atom
   virtual Atom *addAbsoluteAtom(StringRef symbolName) {

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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -22,8 +22,6 @@
 using namespace lld;
 using namespace lld::elf;
 
-#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-
 namespace {
 
 const uint8_t hexagonInitFiniAtomContent[4] = { 0 };
@@ -63,15 +61,15 @@ public:
 class HexagonInitFiniFile : public SimpleFile {
 public:
   HexagonInitFiniFile(const ELFLinkingContext &context)
-      : SimpleFile(context, "command line option -init/-fini"), _ordinal(0) {}
+      : SimpleFile("command line option -init/-fini"), _ordinal(0) {}
 
   void addInitFunction(StringRef name) {
-    Atom *initFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
+    Atom *initFuncAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
     HexagonInitAtom *initAtom =
            (new (_allocator) HexagonInitAtom(*this, name));
-    initAtom->addReference(llvm::ELF::R_HEX_32, 0, initFunctionAtom, 0);
+    initAtom->addReferenceELF_Hexagon(llvm::ELF::R_HEX_32, 0, initFuncAtom, 0);
     initAtom->setOrdinal(_ordinal++);
-    addAtom(*initFunctionAtom);
+    addAtom(*initFuncAtom);
     addAtom(*initAtom);
   }
 
@@ -79,7 +77,7 @@ public:
     Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
     HexagonFiniAtom *finiAtom =
            (new (_allocator) HexagonFiniAtom(*this, name));
-    finiAtom->addReference(llvm::ELF::R_HEX_32, 0, finiFunctionAtom, 0);
+    finiAtom->addReferenceELF_Hexagon(llvm::ELF::R_HEX_32, 0, finiFunctionAtom, 0);
     finiAtom->setOrdinal(_ordinal++);
     addAtom(*finiFunctionAtom);
     addAtom(*finiAtom);
@@ -103,150 +101,3 @@ bool elf::HexagonLinkingContext::createI
   result.push_back(std::move(initFiniFile));
   return true;
 }
-
-ErrorOr<Reference::Kind>
-elf::HexagonLinkingContext::relocKindFromString(StringRef str) const {
-  int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_HEX_NONE)
-      LLD_CASE(R_HEX_B22_PCREL) LLD_CASE(R_HEX_B15_PCREL)
-      LLD_CASE(R_HEX_B7_PCREL) LLD_CASE(R_HEX_LO16) LLD_CASE(R_HEX_HI16)
-      LLD_CASE(R_HEX_32) LLD_CASE(R_HEX_16) LLD_CASE(R_HEX_8)
-      LLD_CASE(R_HEX_GPREL16_0) LLD_CASE(R_HEX_GPREL16_1)
-      LLD_CASE(R_HEX_GPREL16_2) LLD_CASE(R_HEX_GPREL16_3) LLD_CASE(R_HEX_HL16)
-      LLD_CASE(R_HEX_B13_PCREL) LLD_CASE(R_HEX_B9_PCREL)
-      LLD_CASE(R_HEX_B32_PCREL_X) LLD_CASE(R_HEX_32_6_X)
-      LLD_CASE(R_HEX_B22_PCREL_X) LLD_CASE(R_HEX_B15_PCREL_X)
-      LLD_CASE(R_HEX_B13_PCREL_X) LLD_CASE(R_HEX_B9_PCREL_X)
-      LLD_CASE(R_HEX_B7_PCREL_X) LLD_CASE(R_HEX_16_X) LLD_CASE(R_HEX_12_X)
-      LLD_CASE(R_HEX_11_X) LLD_CASE(R_HEX_10_X) LLD_CASE(R_HEX_9_X)
-      LLD_CASE(R_HEX_8_X) LLD_CASE(R_HEX_7_X) LLD_CASE(R_HEX_6_X)
-      LLD_CASE(R_HEX_32_PCREL) LLD_CASE(R_HEX_COPY) LLD_CASE(R_HEX_GLOB_DAT)
-      LLD_CASE(R_HEX_JMP_SLOT) LLD_CASE(R_HEX_RELATIVE)
-      LLD_CASE(R_HEX_PLT_B22_PCREL) LLD_CASE(R_HEX_GOTREL_LO16)
-      LLD_CASE(R_HEX_GOTREL_HI16) LLD_CASE(R_HEX_GOTREL_32)
-      LLD_CASE(R_HEX_GOT_LO16) LLD_CASE(R_HEX_GOT_HI16) LLD_CASE(R_HEX_GOT_32)
-      LLD_CASE(R_HEX_GOT_16) LLD_CASE(R_HEX_DTPMOD_32)
-      LLD_CASE(R_HEX_DTPREL_LO16) LLD_CASE(R_HEX_DTPREL_HI16)
-      LLD_CASE(R_HEX_DTPREL_32) LLD_CASE(R_HEX_DTPREL_16)
-      LLD_CASE(R_HEX_GD_PLT_B22_PCREL) LLD_CASE(R_HEX_GD_GOT_LO16)
-      LLD_CASE(R_HEX_GD_GOT_HI16) LLD_CASE(R_HEX_GD_GOT_32)
-      LLD_CASE(R_HEX_GD_GOT_16) LLD_CASE(R_HEX_IE_LO16) LLD_CASE(R_HEX_IE_HI16)
-      LLD_CASE(R_HEX_IE_32) LLD_CASE(R_HEX_IE_GOT_LO16)
-      LLD_CASE(R_HEX_IE_GOT_HI16) LLD_CASE(R_HEX_IE_GOT_32)
-      LLD_CASE(R_HEX_IE_GOT_16) LLD_CASE(R_HEX_TPREL_LO16)
-      LLD_CASE(R_HEX_TPREL_HI16) LLD_CASE(R_HEX_TPREL_32)
-      LLD_CASE(R_HEX_TPREL_16) LLD_CASE(R_HEX_6_PCREL_X)
-      LLD_CASE(R_HEX_GOTREL_32_6_X) LLD_CASE(R_HEX_GOTREL_16_X)
-      LLD_CASE(R_HEX_GOTREL_11_X) LLD_CASE(R_HEX_GOT_32_6_X)
-      LLD_CASE(R_HEX_GOT_16_X) LLD_CASE(R_HEX_GOT_11_X)
-      LLD_CASE(R_HEX_DTPREL_32_6_X) LLD_CASE(R_HEX_DTPREL_16_X)
-      LLD_CASE(R_HEX_DTPREL_11_X) LLD_CASE(R_HEX_GD_GOT_32_6_X)
-      LLD_CASE(R_HEX_GD_GOT_16_X) LLD_CASE(R_HEX_GD_GOT_11_X)
-      LLD_CASE(R_HEX_IE_32_6_X) LLD_CASE(R_HEX_IE_16_X)
-      LLD_CASE(R_HEX_IE_GOT_32_6_X) LLD_CASE(R_HEX_IE_GOT_16_X)
-      LLD_CASE(R_HEX_IE_GOT_11_X) LLD_CASE(R_HEX_TPREL_32_6_X)
-      LLD_CASE(R_HEX_TPREL_16_X) LLD_CASE(R_HEX_TPREL_11_X).Default(-1);
-
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-#undef LLD_CASE
-
-#define LLD_CASE(name)                                                         \
-  case llvm::ELF::name:                                                        \
-  return std::string(#name);
-
-ErrorOr<std::string>
-elf::HexagonLinkingContext::stringFromRelocKind(int32_t kind) const {
-  switch (kind) {
-    LLD_CASE(R_HEX_NONE)
-    LLD_CASE(R_HEX_B22_PCREL)
-    LLD_CASE(R_HEX_B15_PCREL)
-    LLD_CASE(R_HEX_B7_PCREL)
-    LLD_CASE(R_HEX_LO16)
-    LLD_CASE(R_HEX_HI16)
-    LLD_CASE(R_HEX_32)
-    LLD_CASE(R_HEX_16)
-    LLD_CASE(R_HEX_8)
-    LLD_CASE(R_HEX_GPREL16_0)
-    LLD_CASE(R_HEX_GPREL16_1)
-    LLD_CASE(R_HEX_GPREL16_2)
-    LLD_CASE(R_HEX_GPREL16_3)
-    LLD_CASE(R_HEX_HL16)
-    LLD_CASE(R_HEX_B13_PCREL)
-    LLD_CASE(R_HEX_B9_PCREL)
-    LLD_CASE(R_HEX_B32_PCREL_X)
-    LLD_CASE(R_HEX_32_6_X)
-    LLD_CASE(R_HEX_B22_PCREL_X)
-    LLD_CASE(R_HEX_B15_PCREL_X)
-    LLD_CASE(R_HEX_B13_PCREL_X)
-    LLD_CASE(R_HEX_B9_PCREL_X)
-    LLD_CASE(R_HEX_B7_PCREL_X)
-    LLD_CASE(R_HEX_16_X)
-    LLD_CASE(R_HEX_12_X)
-    LLD_CASE(R_HEX_11_X)
-    LLD_CASE(R_HEX_10_X)
-    LLD_CASE(R_HEX_9_X)
-    LLD_CASE(R_HEX_8_X)
-    LLD_CASE(R_HEX_7_X)
-    LLD_CASE(R_HEX_6_X)
-    LLD_CASE(R_HEX_32_PCREL)
-    LLD_CASE(R_HEX_COPY)
-    LLD_CASE(R_HEX_GLOB_DAT)
-    LLD_CASE(R_HEX_JMP_SLOT)
-    LLD_CASE(R_HEX_RELATIVE)
-    LLD_CASE(R_HEX_PLT_B22_PCREL)
-    LLD_CASE(R_HEX_GOTREL_LO16)
-    LLD_CASE(R_HEX_GOTREL_HI16)
-    LLD_CASE(R_HEX_GOTREL_32)
-    LLD_CASE(R_HEX_GOT_LO16)
-    LLD_CASE(R_HEX_GOT_HI16)
-    LLD_CASE(R_HEX_GOT_32)
-    LLD_CASE(R_HEX_GOT_16)
-    LLD_CASE(R_HEX_DTPMOD_32)
-    LLD_CASE(R_HEX_DTPREL_LO16)
-    LLD_CASE(R_HEX_DTPREL_HI16)
-    LLD_CASE(R_HEX_DTPREL_32)
-    LLD_CASE(R_HEX_DTPREL_16)
-    LLD_CASE(R_HEX_GD_PLT_B22_PCREL)
-    LLD_CASE(R_HEX_GD_GOT_LO16)
-    LLD_CASE(R_HEX_GD_GOT_HI16)
-    LLD_CASE(R_HEX_GD_GOT_32)
-    LLD_CASE(R_HEX_GD_GOT_16)
-    LLD_CASE(R_HEX_IE_LO16)
-    LLD_CASE(R_HEX_IE_HI16)
-    LLD_CASE(R_HEX_IE_32)
-    LLD_CASE(R_HEX_IE_GOT_LO16)
-    LLD_CASE(R_HEX_IE_GOT_HI16)
-    LLD_CASE(R_HEX_IE_GOT_32)
-    LLD_CASE(R_HEX_IE_GOT_16)
-    LLD_CASE(R_HEX_TPREL_LO16)
-    LLD_CASE(R_HEX_TPREL_HI16)
-    LLD_CASE(R_HEX_TPREL_32)
-    LLD_CASE(R_HEX_TPREL_16)
-    LLD_CASE(R_HEX_6_PCREL_X)
-    LLD_CASE(R_HEX_GOTREL_32_6_X)
-    LLD_CASE(R_HEX_GOTREL_16_X)
-    LLD_CASE(R_HEX_GOTREL_11_X)
-    LLD_CASE(R_HEX_GOT_32_6_X)
-    LLD_CASE(R_HEX_GOT_16_X)
-    LLD_CASE(R_HEX_GOT_11_X)
-    LLD_CASE(R_HEX_DTPREL_32_6_X)
-    LLD_CASE(R_HEX_DTPREL_16_X)
-    LLD_CASE(R_HEX_DTPREL_11_X)
-    LLD_CASE(R_HEX_GD_GOT_32_6_X)
-    LLD_CASE(R_HEX_GD_GOT_16_X)
-    LLD_CASE(R_HEX_GD_GOT_11_X)
-    LLD_CASE(R_HEX_IE_32_6_X)
-    LLD_CASE(R_HEX_IE_16_X)
-    LLD_CASE(R_HEX_IE_GOT_32_6_X)
-    LLD_CASE(R_HEX_IE_GOT_16_X)
-    LLD_CASE(R_HEX_IE_GOT_11_X)
-    LLD_CASE(R_HEX_TPREL_32_6_X)
-    LLD_CASE(R_HEX_TPREL_16_X)
-    LLD_CASE(R_HEX_TPREL_11_X)
-  }
-
-  return make_error_code(YamlReaderError::illegal_value);
-}

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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -26,14 +26,13 @@ public:
       : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
                                       new HexagonTargetHandler(*this))) {}
 
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
-
   virtual void addPasses(PassManager &);
 
   virtual bool isDynamicRelocation(const DefinedAtom &,
                                    const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    switch (r.kindValue()) {
     case llvm::ELF::R_HEX_RELATIVE:
     case llvm::ELF::R_HEX_GLOB_DAT:
       return true;
@@ -43,7 +42,9 @@ public:
   }
 
   virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    switch (r.kindValue()) {
     case llvm::ELF::R_HEX_JMP_SLOT:
       return true;
     default:
@@ -54,7 +55,9 @@ public:
   /// \brief Hexagon has only one relative relocation
   /// a) for supporting relative relocs - R_HEX_RELATIVE
   virtual bool isRelativeReloc(const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    switch (r.kindValue()) {
     case llvm::ELF::R_HEX_RELATIVE:
       return true;
     default:

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp Thu Dec 19 15:58:00 2013
@@ -219,7 +219,10 @@ error_code HexagonTargetRelocationHandle
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+    return error_code::success();
+  assert(ref.kindArch() == Reference::KindArch::Hexagon);
+  switch (ref.kindValue()) {
   case R_HEX_B22_PCREL:
     relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 21);
     break;
@@ -334,16 +337,10 @@ error_code HexagonTargetRelocationHandle
                    _targetHandler.getGOTSymAddr());
     break;
 
-  case lld::Reference::kindLayoutAfter:
-  case lld::Reference::kindLayoutBefore:
-  case lld::Reference::kindInGroup:
-    break;
   default : {
     std::string str;
     llvm::raw_string_ostream s(str);
-    auto name = _context.stringFromRelocKind(ref.kind());
-    s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
-      << ref.kind() << ")";
+    s << "Unhandled Hexagon relocation: #" << ref.kindValue();
     s.flush();
     llvm_unreachable(str.c_str());
   }
@@ -351,3 +348,5 @@ error_code HexagonTargetRelocationHandle
 
   return error_code::success();
 }
+
+ 
\ No newline at end of file

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h Thu Dec 19 15:58:00 2013
@@ -31,7 +31,8 @@ public:
   virtual error_code
   applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                   const lld::AtomLayout &, const Reference &) const;
-private:
+                  
+ private:
   const HexagonLinkingContext &_context;
   const HexagonTargetHandler &_targetHandler;
   const HexagonTargetLayout<HexagonELFType> &_targetLayout;

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp Thu Dec 19 15:58:00 2013
@@ -108,7 +108,8 @@ public:
 
 class ELFPassFile : public SimpleFile {
 public:
-  ELFPassFile(const ELFLinkingContext &eti) : SimpleFile(eti, "ELFPassFile") {
+  ELFPassFile(const ELFLinkingContext &eti) 
+    : SimpleFile("ELFPassFile") {
     setOrdinal(eti.getNextOrdinalAndIncrement());
   }
 
@@ -119,7 +120,10 @@ public:
 template <class Derived> class GOTPLTPass : public Pass {
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
-    switch (ref.kind()) {
+    if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+      return;
+    assert(ref.kindArch() == Reference::KindArch::Hexagon);
+    switch (ref.kindValue()) {
     case R_HEX_PLT_B22_PCREL:
     case R_HEX_B22_PCREL:
       static_cast<Derived *>(this)->handlePLT32(ref);
@@ -226,8 +230,8 @@ public:
     if (_PLT0)
       return _PLT0;
     _PLT0 = new (_file._alloc) HexagonPLT0Atom(_file);
-    _PLT0->addReference(R_HEX_B32_PCREL_X, 0, _got0, 0);
-    _PLT0->addReference(R_HEX_6_PCREL_X, 4, _got0, 4);
+    _PLT0->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, _got0, 0);
+    _PLT0->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, _got0, 4);
     DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[ PLT0/GOT0 ] "
                                         << "Adding plt0/got0 \n");
     return _PLT0;
@@ -238,13 +242,13 @@ public:
     if (plt != _pltMap.end())
       return plt->second;
     auto ga = new (_file._alloc) HexagonGOTPLTAtom(_file);
-    ga->addReference(R_HEX_JMP_SLOT, 0, a, 0);
+    ga->addReferenceELF_Hexagon(R_HEX_JMP_SLOT, 0, a, 0);
     auto pa = new (_file._alloc) HexagonPLTAtom(_file, ".plt");
-    pa->addReference(R_HEX_B32_PCREL_X, 0, ga, 0);
-    pa->addReference(R_HEX_6_PCREL_X, 4, ga, 4);
+    pa->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, ga, 0);
+    pa->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, ga, 4);
 
     // Point the got entry to the PLT0 atom initially
-    ga->addReference(R_HEX_32, 0, getPLT0(), 0);
+    ga->addReferenceELF_Hexagon(R_HEX_32, 0, getPLT0(), 0);
 #ifndef NDEBUG
     ga->_name = "__got_";
     ga->_name += a->name();
@@ -266,7 +270,7 @@ public:
     if (got != _gotMap.end())
       return got->second;
     auto ga = new (_file._alloc) HexagonGOTAtom(_file);
-    ga->addReference(R_HEX_GLOB_DAT, 0, a, 0);
+    ga->addReferenceELF_Hexagon(R_HEX_GLOB_DAT, 0, a, 0);
 
 #ifndef NDEBUG
     ga->_name = "__got_";
@@ -287,7 +291,9 @@ public:
 
   error_code handlePLT32(const Reference &ref) {
     // Turn this into a PC32 to the PLT entry.
-    const_cast<Reference &>(ref).setKind(R_HEX_B22_PCREL);
+    assert(ref.kindNamespace() ==  Reference::KindNamespace::ELF);
+    assert(ref.kindArch() ==  Reference::KindArch::Hexagon);
+    const_cast<Reference &>(ref).setKindValue(R_HEX_B22_PCREL);
     const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
     return error_code::success();
   }
@@ -299,3 +305,106 @@ void elf::HexagonLinkingContext::addPass
     pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
   ELFLinkingContext::addPasses(pm);
 }
+
+void HexagonTargetHandler::registerRelocationNames(Registry &registry) {
+  registry.addKindTable(Reference::KindNamespace::ELF, 
+                        Reference::KindArch::Hexagon, 
+                        kindStrings);
+}
+
+const Registry::KindStrings HexagonTargetHandler::kindStrings[] = {
+  LLD_KIND_STRING_ENTRY(R_HEX_NONE),
+  LLD_KIND_STRING_ENTRY(R_HEX_B22_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_B15_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_B7_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_8),
+  LLD_KIND_STRING_ENTRY(R_HEX_GPREL16_0),
+  LLD_KIND_STRING_ENTRY(R_HEX_GPREL16_1),
+  LLD_KIND_STRING_ENTRY(R_HEX_GPREL16_2),
+  LLD_KIND_STRING_ENTRY(R_HEX_GPREL16_3),
+  LLD_KIND_STRING_ENTRY(R_HEX_HL16),
+  LLD_KIND_STRING_ENTRY(R_HEX_B13_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_B9_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_B32_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_B22_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_B15_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_B13_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_B9_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_B7_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_12_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_10_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_9_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_8_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_7_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_32_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_COPY),
+  LLD_KIND_STRING_ENTRY(R_HEX_GLOB_DAT),
+  LLD_KIND_STRING_ENTRY(R_HEX_JMP_SLOT),
+  LLD_KIND_STRING_ENTRY(R_HEX_RELATIVE),
+  LLD_KIND_STRING_ENTRY(R_HEX_PLT_B22_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPMOD_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_PLT_B22_PCREL),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_LO16),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_HI16),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_32),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_16),
+  LLD_KIND_STRING_ENTRY(R_HEX_6_PCREL_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOTREL_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GOT_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_DTPREL_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_GD_GOT_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_IE_GOT_11_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_32_6_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_16_X),
+  LLD_KIND_STRING_ENTRY(R_HEX_TPREL_11_X),
+  LLD_KIND_STRING_END
+};
+

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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Thu Dec 19 15:58:00 2013
@@ -150,6 +150,8 @@ class HexagonTargetHandler LLVM_FINAL :
 public:
   HexagonTargetHandler(HexagonLinkingContext &targetInfo);
 
+  virtual void registerRelocationNames(Registry &registry);
+
   bool doesOverrideELFHeader() { return true; }
 
   void setELFHeader(ELFHeader<HexagonELFType> *elfHeader) {
@@ -215,6 +217,8 @@ public:
   }
 
 private:
+  static const Registry::KindStrings kindStrings[];
+
   HexagonTargetLayout<HexagonELFType> _targetLayout;
   HexagonTargetRelocationHandler _relocationHandler;
   HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -55,7 +55,7 @@ public:
 class MipsGOTPassFile : public SimpleFile {
 public:
   MipsGOTPassFile(const ELFLinkingContext &ctx)
-      : SimpleFile(ctx, "MipsGOTPassFile") {
+      : SimpleFile("MipsGOTPassFile") {
     setOrdinal(ctx.getNextOrdinalAndIncrement());
   }
 
@@ -113,7 +113,10 @@ private:
 
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
-    switch (ref.kind()) {
+    if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
+      return;
+    assert(ref.kindArch() == Reference::KindArch::Mips);
+    switch (ref.kindValue()) {
     case R_MIPS_GOT16:
     case R_MIPS_CALL16:
       handleGOT(ref);
@@ -139,9 +142,9 @@ private:
       _localGotVector.push_back(ga);
     else {
       if (da)
-        ga->addReference(R_MIPS_32, 0, a, 0);
+        ga->addReferenceELF_Mips(R_MIPS_32, 0, a, 0);
       else
-        ga->addReference(R_MIPS_NONE, 0, a, 0);
+        ga->addReferenceELF_Mips(R_MIPS_NONE, 0, a, 0);
       _globalGotVector.push_back(ga);
     }
 
@@ -177,46 +180,6 @@ bool MipsLinkingContext::isLittleEndian(
   return Mips32ElELFType::TargetEndianness == llvm::support::little;
 }
 
-#undef LLD_CASE
-#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-
-ErrorOr<Reference::Kind>
-MipsLinkingContext::relocKindFromString(StringRef str) const {
-  int32_t ret = llvm::StringSwitch<int32_t>(str)
-    LLD_CASE(R_MIPS_NONE)
-    LLD_CASE(R_MIPS_32)
-    LLD_CASE(R_MIPS_HI16)
-    LLD_CASE(R_MIPS_LO16)
-    LLD_CASE(R_MIPS_GOT16)
-    LLD_CASE(R_MIPS_CALL16)
-    LLD_CASE(R_MIPS_JALR)
-    .Default(-1);
-
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-#undef LLD_CASE
-#define LLD_CASE(name)                                                         \
-  case llvm::ELF::name:                                                        \
-    return std::string(#name);
-
-ErrorOr<std::string>
-MipsLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  switch (kind) {
-    LLD_CASE(R_MIPS_NONE)
-    LLD_CASE(R_MIPS_32)
-    LLD_CASE(R_MIPS_HI16)
-    LLD_CASE(R_MIPS_LO16)
-    LLD_CASE(R_MIPS_GOT16)
-    LLD_CASE(R_MIPS_CALL16)
-    LLD_CASE(R_MIPS_JALR)
-  }
-
-  return make_error_code(YamlReaderError::illegal_value);
-}
-
 void MipsLinkingContext::addPasses(PassManager &pm) {
   switch (getOutputELFType()) {
   case llvm::ELF::ET_DYN:

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -27,8 +27,6 @@ public:
 
   // ELFLinkingContext
   virtual bool isLittleEndian() const;
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
   virtual void addPasses(PassManager &pm);
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Thu Dec 19 15:58:00 2013
@@ -120,7 +120,10 @@ void MipsTargetRelocationHandler::applyP
 
     int64_t ahl = calcAHL(ri->addend(), loAddend);
 
-    switch (ri->kind()) {
+    if (ri->kindNamespace() != lld::Reference::KindNamespace::ELF)
+      continue;
+    assert(ri->kindArch() == Reference::KindArch::Mips);
+    switch (ri->kindValue()) {
     case R_MIPS_HI16:
       relocHi16(location, relocVAddress, targetVAddress, ahl,
                 _targetHandler.getGPDispSymAddr(),
@@ -146,7 +149,10 @@ error_code MipsTargetRelocationHandler::
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
+    return error_code::success();
+  assert(ref.kindArch() == Reference::KindArch::Mips);
+  switch (ref.kindValue()) {
   case R_MIPS_NONE:
     break;
   case R_MIPS_32:
@@ -171,16 +177,10 @@ error_code MipsTargetRelocationHandler::
   case R_MIPS_JALR:
     // We do not do JALR optimization now.
     break;
-  case lld::Reference::kindLayoutAfter:
-  case lld::Reference::kindLayoutBefore:
-  case lld::Reference::kindInGroup:
-    break;
   default: {
     std::string str;
     llvm::raw_string_ostream s(str);
-    auto name = _context.stringFromRelocKind(ref.kind());
-    s << "Unhandled relocation: "
-      << (name ? *name : "<unknown>") << " (" << ref.kind() << ")";
+    s << "Unhandled Mips relocation: " << ref.kindValue();
     llvm_unreachable(s.str().c_str());
   }
   }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Thu Dec 19 15:58:00 2013
@@ -51,8 +51,11 @@ public:
 
     const Atom *ta = nullptr;
     for (const auto &r : *da) {
-      if (r->kind() == llvm::ELF::R_MIPS_32 ||
-          r->kind() == llvm::ELF::R_MIPS_NONE) {
+      if (r->kindNamespace() != lld::Reference::KindNamespace::ELF)
+        continue;
+      assert(r->kindArch() == Reference::KindArch::Mips);
+      if (r->kindValue() == llvm::ELF::R_MIPS_32 ||
+          r->kindValue() == llvm::ELF::R_MIPS_NONE) {
         ta = r->target();
         break;
       }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Thu Dec 19 15:58:00 2013
@@ -173,3 +173,22 @@ void MipsTargetHandler::finalizeSymbolVa
         gotSection ? gotSection->virtualAddr() + 0x7FF0 : 0;
   }
 }
+
+void MipsTargetHandler::registerRelocationNames(Registry &registry) {
+  registry.addKindTable(Reference::KindNamespace::ELF, 
+                        Reference::KindArch::Mips, 
+                        kindStrings);
+}
+
+
+const Registry::KindStrings MipsTargetHandler::kindStrings[] = {
+  LLD_KIND_STRING_ENTRY(R_MIPS_NONE),
+  LLD_KIND_STRING_ENTRY(R_MIPS_32),
+  LLD_KIND_STRING_ENTRY(R_MIPS_HI16),
+  LLD_KIND_STRING_ENTRY(R_MIPS_LO16),
+  LLD_KIND_STRING_ENTRY(R_MIPS_GOT16),
+  LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
+  LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
+  LLD_KIND_STRING_END
+};
+ 
\ No newline at end of file

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Thu Dec 19 15:58:00 2013
@@ -59,8 +59,10 @@ public:
   createDynamicSymbolTable();
   virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &result);
   virtual void finalizeSymbolValues();
+  virtual void registerRelocationNames(Registry &registry);
 
 private:
+  static const Registry::KindStrings kindStrings[];
   llvm::BumpPtrAllocator _alloc;
   MipsTargetLayout<Mips32ElELFType> _targetLayout;
   MipsTargetRelocationHandler _relocationHandler;

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -16,31 +16,3 @@
 
 using namespace lld;
 
-#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-
-ErrorOr<Reference::Kind>
-elf::PPCLinkingContext::relocKindFromString(StringRef str) const {
-  int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_PPC_NONE)
-                LLD_CASE(R_PPC_ADDR32) LLD_CASE(R_PPC_REL24).Default(-1);
-
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-#undef LLD_CASE
-
-#define LLD_CASE(name)                                                         \
-  case llvm::ELF::name:                                                        \
-  return std::string(#name);
-
-ErrorOr<std::string>
-elf::PPCLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  switch (kind) {
-    LLD_CASE(R_PPC_NONE)
-    LLD_CASE(R_PPC_ADDR32)
-    LLD_CASE(R_PPC_REL24)
-  }
-
-  return make_error_code(YamlReaderError::illegal_value);
-}

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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h Thu Dec 19 15:58:00 2013
@@ -29,9 +29,6 @@ public:
 
   /// \brief PPC has no relative relocations defined
   virtual bool isRelativeReloc(const Reference &) const { return false; }
-
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 };
 
 } // elf

Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.cpp Thu Dec 19 15:58:00 2013
@@ -43,22 +43,18 @@ error_code PPCTargetRelocationHandler::a
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+    return error_code::success();
+  assert(ref.kindArch() == Reference::KindArch::PowerPC);
+  switch (ref.kindValue()) {
   case R_PPC_REL24:
     relocB24PCREL(location, relocVAddress, targetVAddress, ref.addend());
     break;
 
-  case lld::Reference::kindLayoutAfter:
-  case lld::Reference::kindLayoutBefore:
-  case lld::Reference::kindInGroup:
-    break;
-
   default : {
     std::string str;
     llvm::raw_string_ostream s(str);
-    auto name = _context.stringFromRelocKind(ref.kind());
-    s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
-      << ref.kind() << ")";
+    s << "Unhandled PowerPC relocation: #" << ref.kindValue();
     s.flush();
     llvm_unreachable(str.c_str());
   }
@@ -70,3 +66,70 @@ error_code PPCTargetRelocationHandler::a
 PPCTargetHandler::PPCTargetHandler(PPCLinkingContext &targetInfo)
     : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo),
       _targetLayout(targetInfo) {}
+
+
+void PPCTargetHandler::registerRelocationNames(Registry &registry) {
+  registry.addKindTable(Reference::KindNamespace::ELF, 
+                        Reference::KindArch::PowerPC, 
+                        kindStrings);
+}
+
+const Registry::KindStrings PPCTargetHandler::kindStrings[] = {
+  LLD_KIND_STRING_ENTRY(R_PPC_NONE),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR32),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR24),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR16),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR14),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR14_BRTAKEN),
+  LLD_KIND_STRING_ENTRY(R_PPC_ADDR14_BRNTAKEN),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL24),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL14),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL14_BRTAKEN),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL14_BRNTAKEN),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT16),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL32),
+  LLD_KIND_STRING_ENTRY(R_PPC_TLS),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPMOD32),
+  LLD_KIND_STRING_ENTRY(R_PPC_TPREL16),
+  LLD_KIND_STRING_ENTRY(R_PPC_TPREL16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_TPREL16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_TPREL16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_TPREL32),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPREL16),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPREL16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPREL16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPREL16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_DTPREL32),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSGD16),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSGD16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSGD16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSGD16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSLD16),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSLD16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSLD16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TLSLD16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TPREL16),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TPREL16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TPREL16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_TPREL16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_DTPREL16),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_DTPREL16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_DTPREL16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_GOT_DTPREL16_HA),
+  LLD_KIND_STRING_ENTRY(R_PPC_TLSGD),
+  LLD_KIND_STRING_ENTRY(R_PPC_TLSLD),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL16),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL16_LO),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL16_HI),
+  LLD_KIND_STRING_ENTRY(R_PPC_REL16_HA),
+  LLD_KIND_STRING_END
+};
+
+
+

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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h Thu Dec 19 15:58:00 2013
@@ -37,6 +37,8 @@ class PPCTargetHandler LLVM_FINAL
 public:
   PPCTargetHandler(PPCLinkingContext &targetInfo);
 
+  virtual void registerRelocationNames(Registry &registry);
+  
   virtual TargetLayout<PPCELFType> &targetLayout() {
     return _targetLayout;
   }
@@ -46,6 +48,8 @@ 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=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp Thu Dec 19 15:58:00 2013
@@ -19,13 +19,14 @@
 #include "CreateELF.h"
 #include "DynamicFile.h"
 #include "File.h"
+#include "X86/X86TargetHandler.h"
+#include "X86_64/X86_64TargetHandler.h"
+#include "Hexagon/HexagonTargetHandler.h"
 
 #include "lld/Core/Reference.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/FileArchive.h"
+#include "lld/ReaderWriter/Reader.h"
 
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Object/ELF.h"
 #include "llvm/Object/ObjectFile.h"
@@ -48,14 +49,16 @@
 using llvm::support::endianness;
 using namespace llvm::object;
 
+namespace lld {
 namespace {
+
 struct DynamicFileCreateELFTraits {
   typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
 
   template <class ELFT>
-  static result_type create(const lld::ELFLinkingContext &ctx,
-                            std::unique_ptr<llvm::MemoryBuffer> mb) {
-    return lld::elf::DynamicFile<ELFT>::create(ctx, std::move(mb));
+  static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb, 
+                                                            bool useUndefines) {
+    return lld::elf::DynamicFile<ELFT>::create(std::move(mb), useUndefines);
   }
 };
 
@@ -63,74 +66,89 @@ struct ELFFileCreateELFTraits {
   typedef std::unique_ptr<lld::File> result_type;
 
   template <class ELFT>
-  static result_type create(const lld::ELFLinkingContext &ctx,
-                            std::unique_ptr<llvm::MemoryBuffer> mb,
+  static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+                            bool atomizeStrings,
+                            TargetHandlerBase *handler,
                             lld::error_code &ec) {
     return std::unique_ptr<lld::File>(
-        new lld::elf::ELFFile<ELFT>(ctx, std::move(mb), ec));
+        new lld::elf::ELFFile<ELFT>(std::move(mb), atomizeStrings, handler,ec));
   }
 };
-}
 
-namespace lld {
-namespace elf {
-/// \brief A reader object that will instantiate correct File by examining the
-/// memory buffer for ELF class and bit width
-class ELFReader : public Reader {
+class ELFObjectReader : public Reader {
 public:
-  ELFReader(const ELFLinkingContext &ctx)
-      : lld::Reader(ctx), _elfLinkingContext(ctx) {}
-
-  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
-                       std::vector<std::unique_ptr<File> > &result) const {
-    using llvm::object::ELFType;
-    llvm::sys::fs::file_magic FileType =
-        llvm::sys::fs::identify_magic(mb->getBuffer());
-
-    std::size_t MaxAlignment =
-        1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+  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);
+  }
+  
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File>> &result) const {
     error_code ec;
-    switch (FileType) {
-    case llvm::sys::fs::file_magic::elf_relocatable: {
-      std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
-          getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, std::move(mb),
-          ec));
-      if (ec)
-        return ec;
-      result.push_back(std::move(f));
-      break;
-    }
-    case llvm::sys::fs::file_magic::elf_shared_object: {
-      // If the link doesn't allow dynamic libraries to be present during the
-      // link, let's not parse the file and just return
-      if (!_elfLinkingContext.allowLinkWithDynamicLibraries())
-        return llvm::make_error_code(llvm::errc::executable_format_error);
-      auto f = createELF<DynamicFileCreateELFTraits>(
-          getElfArchType(&*mb), MaxAlignment, _elfLinkingContext,
-          std::move(mb));
-      if (!f)
-        return f;
-      result.push_back(std::move(*f));
-      break;
-    }
-    default:
-      return llvm::make_error_code(llvm::errc::executable_format_error);
-      break;
-    }
-
+    std::size_t maxAlignment =
+              1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
+    std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
+                       getElfArchType(&*mb), maxAlignment, std::move(mb), 
+                       _atomizeStrings, _handler, ec));
     if (ec)
       return ec;
-
+    result.push_back(std::move(f));
     return error_code::success();
   }
+private:
+  bool               _atomizeStrings;
+  TargetHandlerBase *_handler;
+};
+
 
+class ELFDSOReader : public Reader {
+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);
+  }
+  
+  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>( 
+                                            getElfArchType(&*mb), maxAlignment, 
+                                            std::move(mb), _useUndefines);
+    if (!f)
+      return f;   
+    result.push_back(std::move(*f));
+    return error_code::success();
+  }
 private:
-  const ELFLinkingContext &_elfLinkingContext;
+  bool _useUndefines;
 };
-} // end namespace elf
 
-std::unique_ptr<Reader> createReaderELF(const ELFLinkingContext &context) {
-  return std::unique_ptr<Reader>(new elf::ELFReader(context));
+} // anonymous
+
+
+// This dynamic registration of a handler causes support for all ELF 
+// architectures to be pulled into the linker.  If we want to support making a 
+// linker that only supports one ELF architecture, we'd need to change this
+// to have a different registration method for each architecture.
+void Registry::addSupportELFObjects(bool atomizeStrings, 
+                                                 TargetHandlerBase *handler) {
+
+  // Tell registry about the ELF object file parser.
+  add(std::unique_ptr<Reader>(new ELFObjectReader(atomizeStrings, handler)));
+  
+  // 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 ELFDSOReader(useShlibUndefines)));
 }
+
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Dec 19 15:58:00 2013
@@ -31,13 +31,6 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileOutputBuffer.h"
 
-static LLVM_ATTRIBUTE_UNUSED std::string
-kindOrUnknown(llvm::ErrorOr<std::string> k) {
-  if (k)
-    return *k;
-  return "<unknown>";
-}
-
 namespace lld {
 namespace elf {
 template <class> class MergedSections;
@@ -49,7 +42,7 @@ template <class ELFT> class Section : pu
 public:
   Section(const ELFLinkingContext &context, StringRef name,
           typename Chunk<ELFT>::Kind k = Chunk<ELFT>::Kind::ELFSection)
-      : Chunk<ELFT>(name, k, context), _parent(nullptr), _flags(0), _entSize(0),
+      : Chunk<ELFT>(name, k, context), _parent(nullptr), _flags(0), _entSize(0), 
         _type(0), _link(0), _info(0), _segmentType(SHT_NULL) {}
 
   /// \brief Modify the section contents before assigning virtual addresses
@@ -959,7 +952,7 @@ public:
       uint32_t index =
           _symbolTable ? _symbolTable->getSymbolTableIndex(rel.second->target())
                        : (uint32_t) STN_UNDEF;
-      r->setSymbolAndType(index, rel.second->kind());
+      r->setSymbolAndType(index, rel.second->kindValue());
       r->r_offset =
           writer->addressOfAtom(rel.first) + rel.second->offsetInAtom();
       r->r_addend = 0;
@@ -969,12 +962,11 @@ public:
             writer->addressOfAtom(rel.second->target()) + rel.second->addend();
       dest += sizeof(Elf_Rela);
       DEBUG_WITH_TYPE(
-          "ELFRelocationTable",
-          llvm::dbgs() << kindOrUnknown(this->_context.stringFromRelocKind(
-                              rel.second->kind())) << " relocation at "
+          "ELFRelocationTable", 
+          llvm::dbgs() << rel.second->kindValue() << " relocation at "
                        << rel.first->name() << "@" << r->r_offset << " to "
                        << rel.second->target()->name() << "@" << r->r_addend
-                       << "\n");
+                       << "\n";);
     }
   }
 

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -16,33 +16,3 @@
 
 using namespace lld;
 
-#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-
-ErrorOr<Reference::Kind>
-elf::X86LinkingContext::relocKindFromString(StringRef str) const {
-  int32_t ret = llvm::StringSwitch<int32_t>(str)
-      LLD_CASE(R_386_NONE)
-      LLD_CASE(R_386_PC32)
-      LLD_CASE(R_386_32)
-      .Default(-1);
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-#undef LLD_CASE
-
-#define LLD_CASE(name)                                                         \
-  case llvm::ELF::name:                                                        \
-  return std::string(#name);
-
-ErrorOr<std::string>
-elf::X86LinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  switch (kind) {
-    LLD_CASE(R_386_NONE)
-    LLD_CASE(R_386_PC32)
-    LLD_CASE(R_386_32)
-  }
-
-  return make_error_code(YamlReaderError::illegal_value);
-}

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86LinkingContext.h Thu Dec 19 15:58:00 2013
@@ -29,7 +29,10 @@ public:
   /// a) for supporting IFUNC relocs - R_386_IRELATIVE
   /// b) for supporting relative relocs - R_386_RELATIVE
   virtual bool isRelativeReloc(const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::x86);
+    switch (r.kindValue()) {
     case llvm::ELF::R_386_IRELATIVE:
     case llvm::ELF::R_386_RELATIVE:
       return true;
@@ -37,8 +40,6 @@ public:
       return false;
     }
   }
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 };
 } // end namespace elf
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.cpp Thu Dec 19 15:58:00 2013
@@ -31,6 +31,59 @@ static int relocPC32(uint8_t *location,
   return 0;
 }
 
+
+
+const Registry::KindStrings X86TargetHandler::kindStrings[] = {
+  LLD_KIND_STRING_ENTRY(R_386_NONE),
+  LLD_KIND_STRING_ENTRY(R_386_32),
+  LLD_KIND_STRING_ENTRY(R_386_PC32),
+  LLD_KIND_STRING_ENTRY(R_386_GOT32),
+  LLD_KIND_STRING_ENTRY(R_386_PLT32),
+  LLD_KIND_STRING_ENTRY(R_386_COPY),
+  LLD_KIND_STRING_ENTRY(R_386_GLOB_DAT),
+  LLD_KIND_STRING_ENTRY(R_386_JUMP_SLOT),
+  LLD_KIND_STRING_ENTRY(R_386_RELATIVE),
+  LLD_KIND_STRING_ENTRY(R_386_GOTOFF),
+  LLD_KIND_STRING_ENTRY(R_386_GOTPC),
+  LLD_KIND_STRING_ENTRY(R_386_32PLT),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_TPOFF),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_IE),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GOTIE),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LE),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GD),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDM),
+  LLD_KIND_STRING_ENTRY(R_386_16),
+  LLD_KIND_STRING_ENTRY(R_386_PC16),
+  LLD_KIND_STRING_ENTRY(R_386_8),
+  LLD_KIND_STRING_ENTRY(R_386_PC8),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GD_32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GD_PUSH),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GD_CALL),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GD_POP),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDM_32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDM_PUSH),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDM_CALL),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDM_POP),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LDO_32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_IE_32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_LE_32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_DTPMOD32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_DTPOFF32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_TPOFF32),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_GOTDESC),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_DESC_CALL),
+  LLD_KIND_STRING_ENTRY(R_386_TLS_DESC),
+  LLD_KIND_STRING_ENTRY(R_386_IRELATIVE),
+  LLD_KIND_STRING_ENTRY(R_386_NUM),
+  LLD_KIND_STRING_END
+};
+
+void X86TargetHandler::registerRelocationNames(Registry &registry) {
+  registry.addKindTable(Reference::KindNamespace::ELF, 
+                        Reference::KindArch::x86, 
+                        kindStrings);
+}
+
 error_code X86TargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
     const Reference &ref) const {
@@ -39,23 +92,20 @@ error_code X86TargetRelocationHandler::a
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+    return error_code::success();
+  assert(ref.kindArch() == Reference::KindArch::x86);
+  switch (ref.kindValue()) {
   case R_386_32:
     reloc32(location, relocVAddress, targetVAddress, ref.addend());
     break;
   case R_386_PC32:
     relocPC32(location, relocVAddress, targetVAddress, ref.addend());
     break;
-  case lld::Reference::kindLayoutAfter:
-  case lld::Reference::kindLayoutBefore:
-  case lld::Reference::kindInGroup:
-    break;
   default : {
     std::string str;
     llvm::raw_string_ostream s(str);
-    auto name = _context.stringFromRelocKind(ref.kind());
-    s << "Unhandled relocation: " << (name ? *name : "<unknown>") << " ("
-      << ref.kind() << ")";
+    s << "Unhandled I386 relocation # " << ref.kindValue();
     s.flush();
     llvm_unreachable(str.c_str());
   }

Modified: lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86/X86TargetHandler.h Thu Dec 19 15:58:00 2013
@@ -13,8 +13,11 @@
 #include "DefaultTargetHandler.h"
 #include "TargetLayout.h"
 
+#include "lld/ReaderWriter/Reader.h"
+
 namespace lld {
 namespace elf {
+
 typedef llvm::object::ELFType<llvm::support::little, 2, false> X86ELFType;
 class X86LinkingContext;
 
@@ -27,6 +30,8 @@ public:
   virtual error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
                                      const lld::AtomLayout &,
                                      const Reference &) const;
+                                     
+  static const Registry::KindStrings kindStrings[];
 
 private:
   const X86LinkingContext &_context;
@@ -37,6 +42,8 @@ class X86TargetHandler LLVM_FINAL
 public:
   X86TargetHandler(X86LinkingContext &context);
 
+  virtual void registerRelocationNames(Registry &registry);
+
   virtual TargetLayout<X86ELFType> &targetLayout() {
     return _targetLayout;
   }
@@ -46,6 +53,8 @@ public:
   }
 
 private:
+  static const Registry::KindStrings kindStrings[];
+
   X86TargetRelocationHandler _relocationHandler;
   TargetLayout<X86ELFType> _targetLayout;
 };

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -63,13 +63,14 @@ public:
 class X86_64InitFiniFile : public SimpleFile {
 public:
   X86_64InitFiniFile(const ELFLinkingContext &context)
-      : SimpleFile(context, "command line option -init/-fini"), _ordinal(0) {}
+      : SimpleFile("command line option -init/-fini"), _ordinal(0) {}
 
   void addInitFunction(StringRef name) {
     Atom *initFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
     X86_64InitAtom *initAtom =
            (new (_allocator) X86_64InitAtom(*this, name));
-    initAtom->addReference(llvm::ELF::R_X86_64_64, 0, initFunctionAtom, 0);
+    initAtom->addReferenceELF_x86_64(llvm::ELF::R_X86_64_64, 0, 
+                                     initFunctionAtom, 0);
     initAtom->setOrdinal(_ordinal++);
     addAtom(*initFunctionAtom);
     addAtom(*initAtom);
@@ -79,7 +80,8 @@ public:
     Atom *finiFunctionAtom = new (_allocator) SimpleUndefinedAtom(*this, name);
     X86_64FiniAtom *finiAtom =
            (new (_allocator) X86_64FiniAtom(*this, name));
-    finiAtom->addReference(llvm::ELF::R_X86_64_64, 0, finiFunctionAtom, 0);
+    finiAtom->addReferenceELF_x86_64(llvm::ELF::R_X86_64_64, 0, 
+                                    finiFunctionAtom, 0);
     finiAtom->setOrdinal(_ordinal++);
     addAtom(*finiFunctionAtom);
     addAtom(*finiAtom);
@@ -112,87 +114,3 @@ bool elf::X86_64LinkingContext::createIn
   return true;
 }
 
-#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-
-ErrorOr<Reference::Kind>
-elf::X86_64LinkingContext::relocKindFromString(StringRef str) const {
-  int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_X86_64_NONE)
-      LLD_CASE(R_X86_64_64) LLD_CASE(R_X86_64_PC32) LLD_CASE(R_X86_64_GOT32)
-      LLD_CASE(R_X86_64_PLT32) LLD_CASE(R_X86_64_COPY)
-      LLD_CASE(R_X86_64_GLOB_DAT) LLD_CASE(R_X86_64_JUMP_SLOT)
-      LLD_CASE(R_X86_64_RELATIVE) LLD_CASE(R_X86_64_GOTPCREL)
-      LLD_CASE(R_X86_64_32) LLD_CASE(R_X86_64_32S) LLD_CASE(R_X86_64_16)
-      LLD_CASE(R_X86_64_PC16) LLD_CASE(R_X86_64_8) LLD_CASE(R_X86_64_PC8)
-      LLD_CASE(R_X86_64_DTPMOD64) LLD_CASE(R_X86_64_DTPOFF64)
-      LLD_CASE(R_X86_64_TPOFF64) LLD_CASE(R_X86_64_TLSGD)
-      LLD_CASE(R_X86_64_TLSLD) LLD_CASE(R_X86_64_DTPOFF32)
-      LLD_CASE(R_X86_64_GOTTPOFF) LLD_CASE(R_X86_64_TPOFF32)
-      LLD_CASE(R_X86_64_PC64) LLD_CASE(R_X86_64_GOTOFF64)
-      LLD_CASE(R_X86_64_GOTPC32) LLD_CASE(R_X86_64_GOT64)
-      LLD_CASE(R_X86_64_GOTPCREL64) LLD_CASE(R_X86_64_GOTPC64)
-      LLD_CASE(R_X86_64_GOTPLT64) LLD_CASE(R_X86_64_PLTOFF64)
-      LLD_CASE(R_X86_64_SIZE32) LLD_CASE(R_X86_64_SIZE64)
-      LLD_CASE(R_X86_64_GOTPC32_TLSDESC) LLD_CASE(R_X86_64_TLSDESC_CALL)
-      LLD_CASE(R_X86_64_TLSDESC) LLD_CASE(R_X86_64_IRELATIVE)
-          .Case("LLD_R_X86_64_GOTRELINDEX", LLD_R_X86_64_GOTRELINDEX)
-          .Default(-1);
-
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-#undef LLD_CASE
-
-#define LLD_CASE(name)                                                         \
-  case llvm::ELF::name:                                                        \
-  return std::string(#name);
-
-ErrorOr<std::string>
-elf::X86_64LinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  switch (kind) {
-    LLD_CASE(R_X86_64_NONE)
-    LLD_CASE(R_X86_64_64)
-    LLD_CASE(R_X86_64_PC32)
-    LLD_CASE(R_X86_64_GOT32)
-    LLD_CASE(R_X86_64_PLT32)
-    LLD_CASE(R_X86_64_COPY)
-    LLD_CASE(R_X86_64_GLOB_DAT)
-    LLD_CASE(R_X86_64_JUMP_SLOT)
-    LLD_CASE(R_X86_64_RELATIVE)
-    LLD_CASE(R_X86_64_GOTPCREL)
-    LLD_CASE(R_X86_64_32)
-    LLD_CASE(R_X86_64_32S)
-    LLD_CASE(R_X86_64_16)
-    LLD_CASE(R_X86_64_PC16)
-    LLD_CASE(R_X86_64_8)
-    LLD_CASE(R_X86_64_PC8)
-    LLD_CASE(R_X86_64_DTPMOD64)
-    LLD_CASE(R_X86_64_DTPOFF64)
-    LLD_CASE(R_X86_64_TPOFF64)
-    LLD_CASE(R_X86_64_TLSGD)
-    LLD_CASE(R_X86_64_TLSLD)
-    LLD_CASE(R_X86_64_DTPOFF32)
-    LLD_CASE(R_X86_64_GOTTPOFF)
-    LLD_CASE(R_X86_64_TPOFF32)
-    LLD_CASE(R_X86_64_PC64)
-    LLD_CASE(R_X86_64_GOTOFF64)
-    LLD_CASE(R_X86_64_GOTPC32)
-    LLD_CASE(R_X86_64_GOT64)
-    LLD_CASE(R_X86_64_GOTPCREL64)
-    LLD_CASE(R_X86_64_GOTPC64)
-    LLD_CASE(R_X86_64_GOTPLT64)
-    LLD_CASE(R_X86_64_PLTOFF64)
-    LLD_CASE(R_X86_64_SIZE32)
-    LLD_CASE(R_X86_64_SIZE64)
-    LLD_CASE(R_X86_64_GOTPC32_TLSDESC)
-    LLD_CASE(R_X86_64_TLSDESC_CALL)
-    LLD_CASE(R_X86_64_TLSDESC)
-    LLD_CASE(R_X86_64_IRELATIVE)
-  case LLD_R_X86_64_GOTRELINDEX:
-    return std::string("LLD_R_X86_64_GOTRELINDEX");
-  }
-
-  return make_error_code(YamlReaderError::illegal_value);
-}
-

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h Thu Dec 19 15:58:00 2013
@@ -43,7 +43,10 @@ public:
 
   virtual bool isDynamicRelocation(const DefinedAtom &,
                                    const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::x86_64);
+    switch (r.kindValue()) {
     case llvm::ELF::R_X86_64_RELATIVE:
     case llvm::ELF::R_X86_64_GLOB_DAT:
     case llvm::ELF::R_X86_64_COPY:
@@ -54,7 +57,10 @@ public:
   }
 
   virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::x86_64);
+    switch (r.kindValue()) {
     case llvm::ELF::R_X86_64_JUMP_SLOT:
     case llvm::ELF::R_X86_64_IRELATIVE:
       return true;
@@ -67,7 +73,10 @@ public:
   /// a) for supporting IFUNC - R_X86_64_IRELATIVE
   /// b) for supporting relative relocs - R_X86_64_RELATIVE
   virtual bool isRelativeReloc(const Reference &r) const {
-    switch (r.kind()) {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::x86_64);
+    switch (r.kindValue()) {
     case llvm::ELF::R_X86_64_IRELATIVE:
     case llvm::ELF::R_X86_64_RELATIVE:
       return true;
@@ -79,8 +88,6 @@ public:
   /// \brief Create Internal files for Init/Fini
   bool createInternalFiles(std::vector<std::unique_ptr<File> > &) const;
 
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 };
 } // end namespace elf
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp Thu Dec 19 15:58:00 2013
@@ -47,8 +47,13 @@ static void reloc32S(uint8_t *location,
   // TODO: Make sure that the result sign extends to the 64bit value.
 }
 
+
+
 int64_t X86_64TargetRelocationHandler::relocAddend(const Reference &ref) const {
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+    return false;
+  assert(ref.kindArch() == Reference::KindArch::x86_64);
+  switch (ref.kindValue()) {
   case R_X86_64_PC32:
     return 4;
   default:
@@ -65,7 +70,10 @@ error_code X86_64TargetRelocationHandler
   uint64_t targetVAddress = writer.addressOfAtom(ref.target());
   uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
 
-  switch (ref.kind()) {
+  if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+    return error_code::success();
+  assert(ref.kindArch() == Reference::KindArch::x86_64);
+  switch (ref.kindValue()) {
   case R_X86_64_NONE:
     break;
   case R_X86_64_64:
@@ -86,7 +94,8 @@ error_code X86_64TargetRelocationHandler
   case R_X86_64_TPOFF32: {
     _tlsSize =
         _context.getTargetHandler<X86_64ELFType>().targetLayout().getTLSSize();
-    if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) {
+    if (ref.kindValue() == R_X86_64_TPOFF32 || 
+        ref.kindValue() == R_X86_64_DTPOFF32) {
       int32_t result = (int32_t)(targetVAddress - _tlsSize);
       *reinterpret_cast<llvm::support::little32_t *>(location) = result;
     } else {
@@ -106,7 +115,7 @@ error_code X86_64TargetRelocationHandler
   case LLD_R_X86_64_GOTRELINDEX: {
     const DefinedAtom *target = cast<const DefinedAtom>(ref.target());
     for (const Reference *r : *target) {
-      if (r->kind() == R_X86_64_JUMP_SLOT) {
+      if (r->kindValue() == R_X86_64_JUMP_SLOT) {
         uint32_t index;
         if (!_context.getTargetHandler<X86_64ELFType>().targetLayout()
                 .getPLTRelocationTable()->getRelocationIndex(*r, index))
@@ -123,19 +132,12 @@ error_code X86_64TargetRelocationHandler
   case R_X86_64_JUMP_SLOT:
   case R_X86_64_GLOB_DAT:
     break;
-
-  case lld::Reference::kindLayoutAfter:
-  case lld::Reference::kindLayoutBefore:
-  case lld::Reference::kindInGroup:
-    break;
-
   default: {
     std::string str;
     llvm::raw_string_ostream s(str);
-    auto name = _context.stringFromRelocKind(ref.kind());
     s << "Unhandled relocation: " << atom._atom->file().path() << ":"
       << atom._atom->name() << "@" << ref.offsetInAtom() << " "
-      << (name ? *name : "<unknown>") << " (" << ref.kind() << ")";
+      << "#" << ref.kindValue();
     s.flush();
     llvm_unreachable(str.c_str());
   }

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h Thu Dec 19 15:58:00 2013
@@ -30,6 +30,8 @@ public:
 
   virtual int64_t relocAddend(const Reference &) const;
 
+  static const Registry::KindStrings kindStrings[];
+
 private:
   // Cached size of the TLS segment.
   mutable uint64_t _tlsSize;

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp Thu Dec 19 15:58:00 2013
@@ -83,7 +83,7 @@ public:
 
 class ELFPassFile : public SimpleFile {
 public:
-  ELFPassFile(const ELFLinkingContext &eti) : SimpleFile(eti, "ELFPassFile") {
+  ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") {
     setOrdinal(eti.getNextOrdinalAndIncrement());
   }
 
@@ -94,7 +94,10 @@ public:
 template <class Derived> class RelocationPass : public Pass {
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
-    switch (ref.kind()) {
+    if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+      return;
+    assert(ref.kindArch() == Reference::KindArch::x86_64);
+    switch (ref.kindValue()) {
     case R_X86_64_32:
     case R_X86_64_32S:
     case R_X86_64_64:
@@ -126,9 +129,9 @@ protected:
     if (plt != _pltMap.end())
       return plt->second;
     auto ga = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
-    ga->addReference(R_X86_64_IRELATIVE, 0, da, 0);
+    ga->addReferenceELF_x86_64(R_X86_64_IRELATIVE, 0, da, 0);
     auto pa = new (_file._alloc) X86_64PLTAtom(_file, ".plt");
-    pa->addReference(R_X86_64_PC32, 2, ga, -4);
+    pa->addReferenceELF_x86_64(R_X86_64_PC32, 2, ga, -4);
 #ifndef NDEBUG
     ga->_name = "__got_ifunc_";
     ga->_name += da->name();
@@ -158,7 +161,7 @@ protected:
     auto got = _gotMap.find(atom);
     if (got == _gotMap.end()) {
       auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got");
-      g->addReference(R_X86_64_TPOFF64, 0, atom, 0);
+      g->addReferenceELF_x86_64(R_X86_64_TPOFF64, 0, atom, 0);
 #ifndef NDEBUG
       g->_name = "__got_tls_";
       g->_name += atom->name();
@@ -174,7 +177,7 @@ protected:
   /// the GOT.
   void handleGOTTPOFF(const Reference &ref) {
     const_cast<Reference &>(ref).setTarget(getGOTTPOFF(ref.target()));
-    const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
+    const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
   }
 
   /// \brief Create a GOT entry containing 0.
@@ -192,7 +195,7 @@ protected:
     auto got = _gotMap.find(da);
     if (got == _gotMap.end()) {
       auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got");
-      g->addReference(R_X86_64_64, 0, da, 0);
+      g->addReferenceELF_x86_64(R_X86_64_64, 0, da, 0);
 #ifndef NDEBUG
       g->_name = "__got_";
       g->_name += da->name();
@@ -302,11 +305,11 @@ public:
   error_code handlePLT32(const Reference &ref) {
     // __tls_get_addr is handled elsewhere.
     if (ref.target() && ref.target()->name() == "__tls_get_addr") {
-      const_cast<Reference &>(ref).setKind(R_X86_64_NONE);
+      const_cast<Reference &>(ref).setKindValue(R_X86_64_NONE);
       return error_code::success();
     } else
       // Static code doesn't need PLTs.
-      const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
+      const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
     // Handle IFUNC.
     if (const DefinedAtom *da =
             dyn_cast_or_null<const DefinedAtom>(ref.target()))
@@ -338,8 +341,8 @@ public:
     _PLT0 = new (_file._alloc) X86_64PLT0Atom(_file);
     _got0 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
     _got1 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
-    _PLT0->addReference(R_X86_64_PC32, 2, _got0, -4);
-    _PLT0->addReference(R_X86_64_PC32, 8, _got1, -4);
+    _PLT0->addReferenceELF_x86_64(R_X86_64_PC32, 2, _got0, -4);
+    _PLT0->addReferenceELF_x86_64(R_X86_64_PC32, 8, _got1, -4);
 #ifndef NDEBUG
     _got0->_name = "__got0";
     _got1->_name = "__got1";
@@ -352,14 +355,14 @@ public:
     if (plt != _pltMap.end())
       return plt->second;
     auto ga = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
-    ga->addReference(R_X86_64_JUMP_SLOT, 0, a, 0);
+    ga->addReferenceELF_x86_64(R_X86_64_JUMP_SLOT, 0, a, 0);
     auto pa = new (_file._alloc) X86_64PLTAtom(_file, ".plt");
-    pa->addReference(R_X86_64_PC32, 2, ga, -4);
-    pa->addReference(LLD_R_X86_64_GOTRELINDEX, 7, ga, 0);
-    pa->addReference(R_X86_64_PC32, 12, getPLT0(), -4);
+    pa->addReferenceELF_x86_64(R_X86_64_PC32, 2, ga, -4);
+    pa->addReferenceELF_x86_64(LLD_R_X86_64_GOTRELINDEX, 7, ga, 0);
+    pa->addReferenceELF_x86_64(R_X86_64_PC32, 12, getPLT0(), -4);
     // Set the starting address of the got entry to the second instruction in
     // the plt entry.
-    ga->addReference(R_X86_64_64, 0, pa, 6);
+    ga->addReferenceELF_x86_64(R_X86_64_64, 0, pa, 6);
 #ifndef NDEBUG
     ga->_name = "__got_";
     ga->_name += a->name();
@@ -380,7 +383,7 @@ public:
 
     auto oa = new (_file._alloc) ObjectAtom(_file);
     // This needs to point to the atom that we just created.
-    oa->addReference(R_X86_64_COPY, 0, oa, 0);
+    oa->addReferenceELF_x86_64(R_X86_64_COPY, 0, oa, 0);
 
     oa->_name = a->name();
     oa->_size = a->size();
@@ -405,7 +408,7 @@ public:
 
   error_code handlePLT32(const Reference &ref) {
     // Turn this into a PC32 to the PLT entry.
-    const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
+    const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
     // Handle IFUNC.
     if (const DefinedAtom *da =
             dyn_cast_or_null<const DefinedAtom>(ref.target()))
@@ -420,7 +423,7 @@ public:
     auto got = _gotMap.find(sla);
     if (got == _gotMap.end()) {
       auto g = new (_file._alloc) X86_64GOTAtom(_file, ".got.dyn");
-      g->addReference(R_X86_64_GLOB_DAT, 0, sla, 0);
+      g->addReferenceELF_x86_64(R_X86_64_GLOB_DAT, 0, sla, 0);
 #ifndef NDEBUG
       g->_name = "__got_";
       g->_name += sla->name();

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Thu Dec 19 15:58:00 2013
@@ -27,3 +27,53 @@ bool X86_64TargetHandler::createImplicit
   result.push_back(std::move(_gotFile));
   return true;
 }
+
+void X86_64TargetHandler::registerRelocationNames(Registry &registry) {
+  registry.addKindTable(Reference::KindNamespace::ELF, 
+                        Reference::KindArch::x86_64, 
+                        kindStrings);
+}
+
+const Registry::KindStrings X86_64TargetHandler::kindStrings[] = {
+  LLD_KIND_STRING_ENTRY(R_X86_64_NONE),
+  LLD_KIND_STRING_ENTRY(R_X86_64_64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PC32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOT32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PLT32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_COPY),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GLOB_DAT),
+  LLD_KIND_STRING_ENTRY(R_X86_64_JUMP_SLOT),
+  LLD_KIND_STRING_ENTRY(R_X86_64_RELATIVE),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPCREL),
+  LLD_KIND_STRING_ENTRY(R_X86_64_32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_32S),
+  LLD_KIND_STRING_ENTRY(R_X86_64_16),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PC16),
+  LLD_KIND_STRING_ENTRY(R_X86_64_8),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PC8),
+  LLD_KIND_STRING_ENTRY(R_X86_64_DTPMOD64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_DTPOFF64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TPOFF64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TLSGD),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TLSLD),
+  LLD_KIND_STRING_ENTRY(R_X86_64_DTPOFF32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TPOFF32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PC64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTOFF64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPC32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOT64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOT64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPCREL64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPC64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPLT64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_PLTOFF64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_SIZE32),
+  LLD_KIND_STRING_ENTRY(R_X86_64_SIZE64),
+  LLD_KIND_STRING_ENTRY(R_X86_64_GOTPC32_TLSDESC),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TLSDESC_CALL),
+  LLD_KIND_STRING_ENTRY(R_X86_64_TLSDESC),
+  LLD_KIND_STRING_ENTRY(R_X86_64_IRELATIVE),
+  LLD_KIND_STRING_ENTRY(LLD_R_X86_64_GOTRELINDEX),
+  LLD_KIND_STRING_END
+};
+

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Thu Dec 19 15:58:00 2013
@@ -27,6 +27,8 @@ class X86_64TargetHandler LLVM_FINAL
 public:
   X86_64TargetHandler(X86_64LinkingContext &targetInfo);
 
+  virtual void registerRelocationNames(Registry &registry);
+
   virtual TargetLayout<X86_64ELFType> &targetLayout() {
     return _targetLayout;
   }
@@ -40,10 +42,11 @@ public:
 private:
   class GOTFile : public SimpleFile {
   public:
-    GOTFile(const ELFLinkingContext &eti) : SimpleFile(eti, "GOTFile") {}
+    GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
     llvm::BumpPtrAllocator _alloc;
   };
 
+  static const Registry::KindStrings kindStrings[];
   std::unique_ptr<GOTFile> _gotFile;
   X86_64TargetRelocationHandler _relocationHandler;
   TargetLayout<X86_64ELFType> _targetLayout;

Modified: lld/trunk/lib/ReaderWriter/FileArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/FileArchive.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/FileArchive.cpp (original)
+++ lld/trunk/lib/ReaderWriter/FileArchive.cpp Thu Dec 19 15:58:00 2013
@@ -1,155 +1,249 @@
-//===- lld/ReaderWriter/FileArchive.cpp - Archive Library File -----------===//
+//===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/FileArchive.h"
+#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/LLVM.h"
 
 #include "llvm/ADT/Hashing.h"
-#include "llvm/Object/ObjectFile.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Object/Archive.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 #include <unordered_map>
+#include <set>
+
+using llvm::object::Archive;
+using llvm::object::ObjectFile;
+using llvm::object::SymbolRef;
+using llvm::object::symbol_iterator;
+using llvm::object::object_error;
 
 namespace lld {
 
-/// \brief Check if any member of the archive contains an Atom with the
-/// specified name and return the File object for that member, or nullptr.
-const File *FileArchive::find(StringRef name, bool dataSymbolOnly) const {
-  auto member = _symbolMemberMap.find(name);
-  if (member == _symbolMemberMap.end())
-    return nullptr;
+namespace {
 
-  llvm::object::Archive::child_iterator ci = member->second;
+/// \brief The FileArchive class represents an Archive Library file
+class FileArchive : public lld::ArchiveLibraryFile {
+public:
+
+  virtual ~FileArchive() { }
+
+  /// \brief Check if any member of the archive contains an Atom with the
+  /// specified name and return the File object for that member, or nullptr.
+  virtual const File *find(StringRef name, bool dataSymbolOnly) const {
+    auto member = _symbolMemberMap.find(name);
+    if (member == _symbolMemberMap.end()) 
+      return nullptr;
+    Archive::child_iterator ci = member->second;
 
-  if (dataSymbolOnly) {
-    OwningPtr<MemoryBuffer> buff;
-    if (ci->getMemoryBuffer(buff, true))
+   // Don't return a member already returned
+    const char *memberStart = ci->getBuffer().data();
+    if (_membersInstantiated.count(memberStart)) 
       return nullptr;
-    if (isDataSymbol(buff.take(), name))
+
+    if (dataSymbolOnly) {
+      OwningPtr<MemoryBuffer> buff;
+      if (ci->getMemoryBuffer(buff, true))
+        return nullptr;
+      if (isDataSymbol(buff.take(), name))
+        return nullptr;
+    }
+
+    std::vector<std::unique_ptr<File>> result;
+    if (instantiateMember(ci, result))
       return nullptr;
+    assert(result.size() == 1);
+
+    // give up the pointer so that this object no longer manages it
+    return result[0].release();
   }
 
-  std::vector<std::unique_ptr<File> > result;
+  /// \brief Load all members of the archive ?
+  virtual bool isWholeArchive() const { return _isWholeArchive; }
 
-  OwningPtr<MemoryBuffer> buff;
-  if (ci->getMemoryBuffer(buff, true))
-    return nullptr;
-  if (_context.logInputFiles())
-    llvm::outs() << buff->getBufferIdentifier() << "\n";
-  std::unique_ptr<MemoryBuffer> mb(buff.take());
-  if (_context.getDefaultReader().parseFile(mb, result))
-    return nullptr;
+  /// \brief parse each member
+  virtual error_code
+    parseAllMembers(std::vector<std::unique_ptr<File>> &result) const {
+    for (auto mf = _archive->begin_children(),
+              me = _archive->end_children(); mf != me; ++mf) {
+      if (error_code ec=instantiateMember(mf, result))
+        return ec;
+    }
+    return error_code::success();
+  }
 
-  assert(result.size() == 1);
+  virtual const atom_collection<DefinedAtom> &defined() const {
+    return _definedAtoms;
+  }
 
-  // give up the pointer so that this object no longer manages it
-  return result[0].release();
-}
+  virtual const atom_collection<UndefinedAtom> &undefined() const {
+    return _undefinedAtoms;
+  }
+
+  virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
+    return _sharedLibraryAtoms;
+  }
+
+  virtual const atom_collection<AbsoluteAtom> &absolute() const {
+    return _absoluteAtoms;
+  }
 
-/// \brief parse each member
-error_code FileArchive::parseAllMembers(
-    std::vector<std::unique_ptr<File> > &result) const {
-  for (auto mf = _archive->begin_children(), me = _archive->end_children();
-       mf != me; ++mf) {
+protected:
+  error_code instantiateMember(Archive::child_iterator member,
+                             std::vector<std::unique_ptr<File>> &result) const {
     OwningPtr<MemoryBuffer> buff;
-    if (error_code ec = mf->getMemoryBuffer(buff, true))
+    if (error_code ec=member->getMemoryBuffer(buff, true))
       return ec;
-    if (_context.logInputFiles())
+    if (_logLoading)
       llvm::outs() << buff->getBufferIdentifier() << "\n";
-    std::unique_ptr<MemoryBuffer> mbc(buff.take());
-    if (error_code ec = _context.getDefaultReader().parseFile(mbc, result))
-      return ec;
+    std::unique_ptr<MemoryBuffer> mb(buff.take());
+    _registry.parseFile(mb, result);
+    const char *memberStart = member->getBuffer().data();
+    _membersInstantiated.insert(memberStart);
+    return error_code::success();
   }
-  return error_code::success();
-}
 
-const ArchiveLibraryFile::atom_collection<DefinedAtom> &
-FileArchive::defined() const {
-  return _definedAtoms;
-}
-
-const ArchiveLibraryFile::atom_collection<UndefinedAtom> &
-FileArchive::undefined() const {
-  return _undefinedAtoms;
-}
 
-const ArchiveLibraryFile::atom_collection<SharedLibraryAtom> &
-FileArchive::sharedLibrary() const {
-  return _sharedLibraryAtoms;
-}
+  error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
+    std::unique_ptr<ObjectFile>
+                    obj(ObjectFile::createObjectFile(mb));
+    error_code ec;
+    SymbolRef::Type symtype;
+    uint32_t symflags;
+    symbol_iterator ibegin = obj->begin_symbols();
+    symbol_iterator iend = obj->end_symbols();
+    StringRef symbolname;
+
+    for (symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
+      if (ec) return ec;
+
+      // Get symbol name
+      if ((ec = (i->getName(symbolname)))) return ec;
+
+      if (symbolname != symbol)
+          continue;
+
+      // Get symbol flags
+      if ((ec = (i->getFlags(symflags)))) return ec;
+
+      if (symflags <= SymbolRef::SF_Undefined)
+          continue;
+
+      // Get Symbol Type
+      if ((ec = (i->getType(symtype)))) return ec;
+
+      if (symtype == SymbolRef::ST_Data) {
+        return error_code::success();
+      }
+    }
+    return object_error::parse_failed;
+  }
 
-const ArchiveLibraryFile::atom_collection<AbsoluteAtom> &
-FileArchive::absolute() const {
-  return _absoluteAtoms;
-}
+private:
+  typedef std::unordered_map<StringRef,Archive::child_iterator> MemberMap;
+  typedef std::set<const char*> InstantiatedSet;
+
+  const Registry                           &_registry;
+  std::unique_ptr<Archive>                  _archive;
+  mutable MemberMap                         _symbolMemberMap;
+  mutable InstantiatedSet                   _membersInstantiated;
+  atom_collection_vector<DefinedAtom>       _definedAtoms;
+  atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
+  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+  atom_collection_vector<AbsoluteAtom>      _absoluteAtoms;
+  bool                                      _isWholeArchive;
+  bool                                      _logLoading;
+
+public:
+  /// only subclasses of ArchiveLibraryFile can be instantiated
+  FileArchive(const Registry &registry,
+              Archive* archive,
+              StringRef path,
+              bool isWholeArchive,
+              bool logLoading)
+      : ArchiveLibraryFile(path),
+        _registry(registry),
+        _archive(std::move(archive)),
+        _isWholeArchive(isWholeArchive),
+        _logLoading(logLoading) {
+  }
 
-error_code FileArchive::isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
-  std::unique_ptr<llvm::object::ObjectFile> obj(
-      llvm::object::ObjectFile::createObjectFile(mb));
-  error_code ec;
-  llvm::object::SymbolRef::Type symtype;
-  uint32_t symflags;
-  llvm::object::symbol_iterator ibegin = obj->begin_symbols();
-  llvm::object::symbol_iterator iend = obj->end_symbols();
-  StringRef symbolname;
+  error_code buildTableOfContents() {
+    DEBUG_WITH_TYPE("FileArchive",
+                    llvm::dbgs() << "Table of contents for archive '"
+                                 << _archive->getFileName() << "':\n");
+    for (auto i = _archive->begin_symbols(), e = _archive->end_symbols();
+              i != e; ++i) {
+      StringRef name;
+      error_code ec;
+      Archive::child_iterator member;
+      if ((ec = i->getName(name)))
+        return ec;
+      if ((ec = i->getMember(member)))
+        return ec;
+      DEBUG_WITH_TYPE("FileArchive",
+           llvm::dbgs() << llvm::format("0x%08llX ", member->getBuffer().data())
+                        << "'" << name << "'\n");
+      _symbolMemberMap[name] = member;
+    }
+    return error_code::success();  
+  }
 
-  for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
-    if (ec)
-      return ec;
+}; // class FileArchive
 
-    // Get symbol name
-    if (error_code ec = i->getName(symbolname))
-      return ec;
 
-    if (symbolname != symbol)
-      continue;
 
-    // Get symbol flags
-    if (error_code ec = i->getFlags(symflags))
+class ArchiveReader : public Reader {
+public:
+  ArchiveReader(bool logLoading) : _logLoading(logLoading) { }
+  
+  virtual bool canParse(file_magic magic, StringRef, const MemoryBuffer&) const{
+    return (magic == llvm::sys::fs::file_magic::archive);
+  }
+  
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry &reg,
+            std::vector<std::unique_ptr<File>> &result) const {
+    // Make Archive object which will be owned by FileArchive object.
+    error_code ec;
+    Archive* archive = new Archive(mb.get(), ec);
+    if (ec)
+      return ec;
+    StringRef path = mb->getBufferIdentifier();
+    // Construct FileArchive object.
+    std::unique_ptr<FileArchive> file(new FileArchive(reg, archive, 
+                                                     path, false, _logLoading));
+    ec = file->buildTableOfContents();
+    if (ec)
       return ec;
+      
+    // Transfer ownership of memory buffer to Archive object.
+    mb.release();
+    
+    result.push_back(std::move(file));
+    return error_code::success();     
+  }
+private:
+  bool  _logLoading;
+};
 
-    if (symflags <= llvm::object::SymbolRef::SF_Undefined)
-      continue;
 
-    // Get Symbol Type
-    if (error_code ec = i->getType(symtype))
-      return ec;
+} // anonymous namespace
 
-    if (symtype == llvm::object::SymbolRef::ST_Data) {
-      return error_code::success();
-    }
-  }
-  return llvm::object::object_error::parse_failed;
-}
 
-FileArchive::FileArchive(const LinkingContext &context,
-                         std::unique_ptr<MemoryBuffer> mb, error_code &ec,
-                         bool isWholeArchive)
-    : ArchiveLibraryFile(context, mb->getBufferIdentifier()),
-      _isWholeArchive(isWholeArchive) {
-  std::unique_ptr<llvm::object::Archive> archive_obj(
-      new llvm::object::Archive(mb.release(), ec));
-  if (ec)
-    return;
-  _archive.swap(archive_obj);
-
-  // Cache symbols.
-  for (auto i = _archive->begin_symbols(), e = _archive->end_symbols(); i != e;
-       ++i) {
-    StringRef name;
-    llvm::object::Archive::child_iterator member;
-    if ((ec = i->getName(name)))
-      return;
-    if ((ec = i->getMember(member)))
-      return;
-    _symbolMemberMap[name] = member;
-  }
+void Registry::addSupportArchives(bool logLoading) {
+  add(std::unique_ptr<Reader>(new ArchiveReader(logLoading)));
 }
 
 } // end namespace lld
+
+

Modified: lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.hpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.hpp Thu Dec 19 15:58:00 2013
@@ -30,7 +30,7 @@ namespace mach_o {
 class CRuntimeFile : public SimpleFile {
 public:
     CRuntimeFile(const MachOLinkingContext &context)
-      : SimpleFile(context, "C runtime"),
+      : SimpleFile("C runtime"),
         _undefMain(*this, context.entrySymbolName()) {
       // only main executables need _main
       if (context.outputFileType() == llvm::MachO::MH_EXECUTE) {

Modified: lld/trunk/lib/ReaderWriter/MachO/GOTPass.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/GOTPass.hpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/GOTPass.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/GOTPass.hpp Thu Dec 19 15:58:00 2013
@@ -29,7 +29,7 @@ public:
     return true;
   }
 
-  virtual bool isGOTAccess(int32_t, bool& canBypassGOT) {
+  virtual bool isGOTAccess(const Reference&, bool& canBypassGOT) {
     return false;
   }
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -16,7 +16,6 @@
 #include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/Writer.h"
 #include "lld/Passes/LayoutPass.h"
-#include "lld/Passes/RoundTripNativePass.h"
 #include "lld/Passes/RoundTripYAMLPass.h"
 
 #include "llvm/ADT/StringExtras.h"
@@ -93,6 +92,15 @@ MachOLinkingContext::archFromName(String
   return arch_unknown;
 }
 
+StringRef MachOLinkingContext::nameFromArch(Arch arch) {
+  for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
+    if (info->arch == arch)
+      return info->archName;
+  }
+  return "<unknown>";
+}
+
+
 uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
   assert(arch != arch_unknown);
   for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
@@ -293,14 +301,5 @@ KindHandler &MachOLinkingContext::kindHa
   return *_kindHandler;
 }
 
-ErrorOr<Reference::Kind>
-MachOLinkingContext::relocKindFromString(StringRef str) const {
-  return kindHandler().stringToKind(str);
-}
-
-ErrorOr<std::string>
-MachOLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  return std::string(kindHandler().kindToString(kind));
-}
 
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Thu Dec 19 15:58:00 2013
@@ -260,7 +260,7 @@ writeYaml(const NormalizedFile &file, ra
 
 /// Takes in-memory normalized dylib or object and parses it into lld::File
 ErrorOr<std::unique_ptr<lld::File>> 
-normalizedToAtoms(const NormalizedFile &normalizedFile);
+normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path);
 
 /// Takes atoms and generates a normalized macho-o view.
 ErrorOr<std::unique_ptr<NormalizedFile>> 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Thu Dec 19 15:58:00 2013
@@ -23,6 +23,7 @@
 
 #include "MachONormalizedFile.h"
 #include "MachONormalizedFileBinaryUtils.h"
+#include "ReferenceKinds.h"
 
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
@@ -306,5 +307,31 @@ readBinary(std::unique_ptr<MemoryBuffer>
 
 } // namespace normalized
 } // namespace mach_o
+
+void Registry::addSupportMachOObjects(StringRef archName) {
+  MachOLinkingContext::Arch arch = MachOLinkingContext::archFromName(archName);
+  switch (arch) {
+  case MachOLinkingContext::arch_x86_64:
+    addKindTable(Reference::KindNamespace::mach_o, 
+                 Reference::KindArch::x86_64, 
+                 mach_o::KindHandler_x86_64::kindStrings);
+    break;
+  case MachOLinkingContext::arch_x86:
+    addKindTable(Reference::KindNamespace::mach_o, 
+                 Reference::KindArch::x86, 
+                 mach_o::KindHandler_x86::kindStrings);
+    break;
+  case MachOLinkingContext::arch_armv6:
+  case MachOLinkingContext::arch_armv7:
+  case MachOLinkingContext::arch_armv7s:
+    addKindTable(Reference::KindNamespace::mach_o, 
+                 Reference::KindArch::ARM, 
+                 mach_o::KindHandler_arm::kindStrings);
+    break;
+  default:
+    llvm_unreachable("mach-o arch not supported");
+  }
+}
+
 } // namespace lld
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Thu Dec 19 15:58:00 2013
@@ -436,7 +436,8 @@ void Util::appendSection(SectionInfo *si
       if ( ref->target() != nullptr )
         targetAddress = _atomToAddress[ref->target()];
       uint64_t fixupAddress = _atomToAddress[ai.atom] + offset;
-      _context.kindHandler().applyFixup(ref->kind(), ref->addend(),
+      _context.kindHandler().applyFixup(ref->kindNamespace(), ref->kindArch(), 
+                                       ref->kindValue(), ref->addend(),
                                        &atomContent[offset], fixupAddress,
                                        targetAddress);
     }
@@ -578,7 +579,7 @@ void Util::addSymbols(const lld::File &a
 
 const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
   for (const Reference *ref : *lpAtom) {
-    if (_context.kindHandler().isLazyTarget(ref->kind())) {
+    if (_context.kindHandler().isLazyTarget(*ref)) {
       return ref->target();
     }
   }
@@ -736,7 +737,7 @@ void Util::addRebaseAndBindingInfo(const
         uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom() 
                                 - segmentStartAddr;
         const Atom* targ = ref->target();
-        if (_context.kindHandler().isPointer(ref->kind())) {
+        if (_context.kindHandler().isPointer(*ref)) {
           // A pointer to a DefinedAtom requires rebasing.
           if (dyn_cast<DefinedAtom>(targ)) {
             RebaseLocation rebase;
@@ -758,7 +759,7 @@ void Util::addRebaseAndBindingInfo(const
             nFile.bindingInfo.push_back(bind);
           }
         }
-        if (_context.kindHandler().isLazyTarget(ref->kind())) {
+        if (_context.kindHandler().isLazyTarget(*ref)) {
             BindLocation bind;
             bind.segIndex = segmentIndex;
             bind.segOffset = segmentOffset;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Thu Dec 19 15:58:00 2013
@@ -19,6 +19,7 @@
 
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
+#include "lld/ReaderWriter/YamlContext.h"
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
@@ -40,7 +41,7 @@ using llvm::dyn_cast;
 using namespace llvm::yaml;
 using namespace llvm::MachO;
 using namespace lld::mach_o::normalized;
-
+using lld::YamlContext;
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(Segment);
 LLVM_YAML_IS_SEQUENCE_VECTOR(DependentDylib);
@@ -303,7 +304,9 @@ struct MappingTraits<Relocation> {
 template <>
 struct ScalarEnumerationTraits<RelocationInfoType> {
   static void enumeration(IO &io, RelocationInfoType &value) {
-    NormalizedFile *file = reinterpret_cast<NormalizedFile*>(io.getContext());
+    YamlContext *info = reinterpret_cast<YamlContext*>(io.getContext());
+    assert(info != nullptr);
+    NormalizedFile *file = info->_normalizeMachOFile;
     assert(file != nullptr);
     switch (file->arch) {
     case lld::MachOLinkingContext::arch_x86_64:
@@ -574,6 +577,9 @@ struct MappingTraits<NormalizedFile> {
     io.mapOptional("lazy-bindings",    file.lazyBindingInfo);
     io.mapOptional("exports",          file.exportInfo);
   }
+  static StringRef validate(IO &io, NormalizedFile &file) {
+    return StringRef();
+  }
 };
 
 } // namespace llvm
@@ -591,7 +597,9 @@ readYaml(std::unique_ptr<MemoryBuffer> &
   std::unique_ptr<NormalizedFile> f(new NormalizedFile());
 
   // Create YAML Input parser.
-  llvm::yaml::Input yin(mb->getBuffer(), f.get());
+  YamlContext yamlContext;
+  yamlContext._normalizeMachOFile = f.get();
+  llvm::yaml::Input yin(mb->getBuffer(), &yamlContext);
 
   // Fill NormalizedFile by parsing yaml.
   yin >> *f;
@@ -612,7 +620,9 @@ writeYaml(const NormalizedFile &file, ra
   NormalizedFile *f = const_cast<NormalizedFile*>(&file);
 
   // Create yaml Output writer, using yaml options for context.
-  llvm::yaml::Output yout(out, f);
+  YamlContext yamlContext;
+  yamlContext._normalizeMachOFile = f;
+  llvm::yaml::Output yout(out, &yamlContext);
 
   // Stream out yaml.
   yout << *f;

Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp Thu Dec 19 15:58:00 2013
@@ -17,6 +17,8 @@
 
 #include "llvm/Support/ErrorHandling.h"
 
+using namespace llvm::MachO;
+
 namespace lld {
 namespace mach_o {
 
@@ -46,7 +48,6 @@ KindHandler::create(MachOLinkingContext:
   }
 }
 
-
 //===----------------------------------------------------------------------===//
 //  KindHandler_x86_64
 //===----------------------------------------------------------------------===//
@@ -54,133 +55,88 @@ KindHandler::create(MachOLinkingContext:
 KindHandler_x86_64::~KindHandler_x86_64() {
 }
 
-Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) {
-  return llvm::StringSwitch<Reference::Kind>(str)
-    .Case("none",                  none)
-    .Case("branch32",              branch32)
-    .Case("ripRel32",              ripRel32)
-    .Case("ripRel32_1",            ripRel32_1)
-    .Case("ripRel32_2",            ripRel32_2)
-    .Case("ripRel32_4",            ripRel32_4)
-    .Case("gotLoadRipRel32",       gotLoadRipRel32)
-    .Case("gotLoadRipRel32NowLea", gotLoadRipRel32NowLea)
-    .Case("gotUseRipRel32",        gotUseRipRel32)
-    .Case("tlvLoadRipRel32",       tlvLoadRipRel32)
-    .Case("tlvLoadRipRel32NowLea", tlvLoadRipRel32NowLea)
-    .Case("pointer64",             pointer64)
-    .Case("pointerRel32",          pointerRel32)
-    .Case("lazyTarget",            lazyTarget)
-    .Case("lazyImmediate",         lazyImmediate)
-    .Case("subordinateFDE",        subordinateFDE)
-    .Case("subordinateLSDA",       subordinateLSDA)
-    .Default(invalid);
-
-  llvm_unreachable("invalid x86_64 Reference kind");
-}
-
-StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
-  switch ( (Kinds)kind ) {
-    case invalid:
-      return StringRef("invalid");
-    case none:
-      return StringRef("none");
-    case branch32:
-      return StringRef("branch32");
-    case ripRel32:
-      return StringRef("ripRel32");
-    case ripRel32_1:
-      return StringRef("ripRel32_1");
-    case ripRel32_2:
-      return StringRef("ripRel32_2");
-    case ripRel32_4:
-      return StringRef("ripRel32_4");
-    case gotLoadRipRel32:
-      return StringRef("gotLoadRipRel32");
-    case gotLoadRipRel32NowLea:
-      return StringRef("gotLoadRipRel32NowLea");
-    case gotUseRipRel32:
-      return StringRef("gotUseRipRel32");
-    case tlvLoadRipRel32:
-      return StringRef("tlvLoadRipRel32");
-    case tlvLoadRipRel32NowLea:
-      return StringRef("tlvLoadRipRel32NowLea");
-    case pointer64:
-      return StringRef("pointer64");
-    case pointerRel32:
-      return StringRef("pointerRel32");
-    case lazyTarget:
-      return StringRef("lazyTarget");
-    case lazyImmediate:
-      return StringRef("lazyImmediate");
-    case subordinateFDE:
-      return StringRef("subordinateFDE");
-    case subordinateLSDA:
-      return StringRef("subordinateLSDA");
-  }
-  llvm_unreachable("invalid x86_64 Reference kind");
-}
 
-bool KindHandler_x86_64::isCallSite(Kind kind) {
-  return (kind == branch32);
+const Registry::KindStrings KindHandler_x86_64::kindStrings[] = {
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_UNSIGNED),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_BRANCH),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_SIGNED),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_SIGNED_1),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_SIGNED_2),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_SIGNED_4),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_GOT_LOAD),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_GOT),
+    LLD_KIND_STRING_ENTRY(X86_64_RELOC_TLV),
+    LLD_KIND_STRING_ENTRY(LLD_X86_64_RELOC_GOT_LOAD_NOW_LEA),
+    LLD_KIND_STRING_ENTRY(LLD_X86_64_RELOC_TLV_NOW_LEA),
+    LLD_KIND_STRING_ENTRY(LLD_X86_64_RELOC_LAZY_TARGET),
+    LLD_KIND_STRING_ENTRY(LLD_X86_64_RELOC_LAZY_IMMEDIATE),
+    LLD_KIND_STRING_END
+};
+
+bool KindHandler_x86_64::isCallSite(const Reference &ref) {
+  return (ref.kindValue() == X86_64_RELOC_BRANCH);
 }
 
-bool KindHandler_x86_64::isPointer(Kind kind) {
-  return (kind == pointer64);
+bool KindHandler_x86_64::isPointer(const Reference &ref) {
+  return (ref.kindValue() == X86_64_RELOC_UNSIGNED);
 }
 
-bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
-  return (kind == lazyImmediate);
+bool KindHandler_x86_64::isLazyImmediate(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_64_RELOC_LAZY_IMMEDIATE);
 }
 
-bool KindHandler_x86_64::isLazyTarget(Kind kind) {
-  return (kind == lazyTarget);
+bool KindHandler_x86_64::isLazyTarget(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_64_RELOC_LAZY_TARGET);
 }
 
 
-void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
+void KindHandler_x86_64::applyFixup(Reference::KindNamespace ns, 
+                                    Reference::KindArch arch, 
+                                    Reference::KindValue kindValue, 
+                                    uint64_t addend,
                                     uint8_t *location, uint64_t fixupAddress,
                                     uint64_t targetAddress) {
+  if (ns != Reference::KindNamespace::mach_o)
+    return;
+  assert(arch == Reference::KindArch::x86_64);
   int32_t *loc32 = reinterpret_cast<int32_t*>(location);
   uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
-  switch ( (Kinds)kind ) {
-    case branch32:
-    case ripRel32:
-    case gotLoadRipRel32:
-    case gotUseRipRel32:
-    case tlvLoadRipRel32:
+  switch ( kindValue ) {
+    case X86_64_RELOC_BRANCH:
+    case X86_64_RELOC_SIGNED:
+    case X86_64_RELOC_GOT_LOAD:
+    case X86_64_RELOC_GOT:
+    case X86_64_RELOC_TLV:
       *loc32 = (targetAddress - (fixupAddress+4)) + addend;
       break;
-    case pointer64:
+    case X86_64_RELOC_UNSIGNED:
       *loc64 = targetAddress + addend;
       break;
-    case ripRel32_1:
+    case X86_64_RELOC_SIGNED_1:
       *loc32 = (targetAddress - (fixupAddress+5)) + addend;
       break;
-    case ripRel32_2:
+    case X86_64_RELOC_SIGNED_2:
       *loc32 = (targetAddress - (fixupAddress+6)) + addend;
       break;
-    case ripRel32_4:
+    case X86_64_RELOC_SIGNED_4:
       *loc32 = (targetAddress - (fixupAddress+8)) + addend;
       break;
-    case pointerRel32:
+    case LLD_X86_64_RELOC_SIGNED_32:
       *loc32 = (targetAddress - fixupAddress) + addend;
       break;
-    case gotLoadRipRel32NowLea:
-    case tlvLoadRipRel32NowLea:
+    case LLD_X86_64_RELOC_GOT_LOAD_NOW_LEA:
+    case LLD_X86_64_RELOC_TLV_NOW_LEA:
       // Change MOVQ to LEA
       assert(location[-2] == 0x8B);
       location[-2] = 0x8D;
       *loc32 = (targetAddress - (fixupAddress+4)) + addend;
       break;
-    case none:
-    case lazyTarget:
-    case lazyImmediate:
-    case subordinateFDE:
-    case subordinateLSDA:
+    case LLD_X86_64_RELOC_LAZY_TARGET:
+    case LLD_X86_64_RELOC_LAZY_IMMEDIATE:
       // do nothing
       break;
-    case invalid:
-      assert(0 && "invalid Reference Kind");
+    default:
+      llvm_unreachable("invalid x86_64 Reference Kind");
       break;
   }
 }
@@ -193,88 +149,62 @@ void KindHandler_x86_64::applyFixup(Kind
 KindHandler_x86::~KindHandler_x86() {
 }
 
-Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
-  return llvm::StringSwitch<Reference::Kind>(str)
-    .Case("none",                  none)
-    .Case("branch32",              branch32)
-    .Case("abs32",                 abs32)
-    .Case("funcRel32",             funcRel32)
-    .Case("pointer32",             pointer32)
-    .Case("lazyTarget",            lazyTarget)
-    .Case("lazyImmediate",         lazyImmediate)
-    .Default(invalid);
-
-  llvm_unreachable("invalid x86 Reference kind");
-}
-
-StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
-  switch ( (Kinds)kind ) {
-    case invalid:
-      return StringRef("invalid");
-    case none:
-      return StringRef("none");
-    case branch32:
-      return StringRef("branch32");
-    case abs32:
-      return StringRef("abs32");
-    case funcRel32:
-      return StringRef("funcRel32");
-    case pointer32:
-      return StringRef("pointer32");
-    case lazyTarget:
-      return StringRef("lazyTarget");
-    case lazyImmediate:
-      return StringRef("lazyImmediate");
-    case subordinateFDE:
-      return StringRef("subordinateFDE");
-    case subordinateLSDA:
-      return StringRef("subordinateLSDA");
-  }
-  llvm_unreachable("invalid x86 Reference kind");
-}
+const Registry::KindStrings KindHandler_x86::kindStrings[] = {
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_BRANCH32),
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_ABS32),
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_FUNC_REL32),
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_POINTER32),
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_TARGET),
+    LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_IMMEDIATE),
+    LLD_KIND_STRING_END
+};
 
-bool KindHandler_x86::isCallSite(Kind kind) {
-  return (kind == branch32);
+bool KindHandler_x86::isCallSite(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_RELOC_BRANCH32);
 }
 
-bool KindHandler_x86::isPointer(Kind kind) {
-  return (kind == pointer32);
+bool KindHandler_x86::isPointer(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_RELOC_POINTER32);
 }
 
 
-bool KindHandler_x86::isLazyImmediate(Kind kind) {
-  return (kind == lazyImmediate);
+bool KindHandler_x86::isLazyImmediate(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET);
 }
 
 
-bool KindHandler_x86::isLazyTarget(Kind kind) {
-  return (kind == lazyTarget);
+bool KindHandler_x86::isLazyTarget(const Reference &ref) {
+  return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET);
 }
 
 
-void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                  uint64_t fixupAddress, uint64_t targetAddress) {
+void KindHandler_x86::applyFixup(Reference::KindNamespace ns, 
+                                 Reference::KindArch arch, 
+                                 Reference::KindValue kindValue, 
+                                 uint64_t addend, uint8_t *location,
+                                 uint64_t fixupAddress, 
+                                 uint64_t targetAddress) {
+  if (ns != Reference::KindNamespace::mach_o)
+    return;
+  assert(arch == Reference::KindArch::x86);
   int32_t *loc32 = reinterpret_cast<int32_t*>(location);
-  switch ( (Kinds)kind ) {
-    case branch32:
+  switch (kindValue) {
+    case LLD_X86_RELOC_BRANCH32:
       *loc32 = (targetAddress - (fixupAddress+4)) + addend;
       break;
-    case pointer32:
-    case abs32:
+    case LLD_X86_RELOC_POINTER32:
+    case LLD_X86_RELOC_ABS32:
       *loc32 = targetAddress + addend;
       break;
-    case funcRel32:
+    case LLD_X86_RELOC_FUNC_REL32:
       *loc32 = targetAddress + addend;
       break;
-    case none:
-    case lazyTarget:
-    case lazyImmediate:
-    case subordinateFDE:
-    case subordinateLSDA:
+    case LLD_X86_RELOC_LAZY_TARGET:
+    case LLD_X86_RELOC_LAZY_IMMEDIATE:
       // do nothing
       break;
-    case invalid:
-      assert(0 && "invalid Reference Kind");
+    default:
+      llvm_unreachable("invalid x86 Reference Kind");
       break;
   }
 }
@@ -287,112 +217,81 @@ void KindHandler_x86::applyFixup(Kind ki
 KindHandler_arm::~KindHandler_arm() {
 }
 
-Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
- return llvm::StringSwitch<Reference::Kind>(str)
-    .Case("none",               none)
-    .Case("thumbBranch22",      thumbBranch22)
-    .Case("armBranch24",        armBranch24)
-    .Case("thumbAbsLow16",      thumbAbsLow16)
-    .Case("thumbAbsHigh16",     thumbAbsHigh16)
-    .Case("thumbPcRelLow16",    thumbPcRelLow16)
-    .Case("thumbPcRelHigh16",   thumbPcRelHigh16)
-    .Case("abs32",              abs32)
-    .Case("pointer32",          pointer32)
-    .Case("lazyTarget",         lazyTarget)
-    .Case("lazyImmediate",      lazyImmediate)
-    .Case("subordinateLSDA",    subordinateLSDA)
-    .Default(invalid);
-
-  llvm_unreachable("invalid ARM Reference kind");
-}
-
-StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
-  switch ( (Kinds)kind ) {
-    case invalid:
-      return StringRef("invalid");
-    case none:
-      return StringRef("none");
-    case thumbBranch22:
-      return StringRef("thumbBranch22");
-    case armBranch24:
-      return StringRef("armBranch24");
-    case thumbAbsLow16:
-      return StringRef("thumbAbsLow16");
-    case thumbAbsHigh16:
-      return StringRef("thumbAbsHigh16");
-    case thumbPcRelLow16:
-      return StringRef("thumbPcRelLow16");
-    case thumbPcRelHigh16:
-      return StringRef("thumbPcRelHigh16");
-    case abs32:
-      return StringRef("abs32");
-    case pointer32:
-      return StringRef("pointer32");
-    case lazyTarget:
-      return StringRef("lazyTarget");
-    case lazyImmediate:
-      return StringRef("lazyImmediate");
-    case subordinateLSDA:
-      return StringRef("subordinateLSDA");
-  }
-  llvm_unreachable("invalid ARM Reference kind");
-}
+const Registry::KindStrings KindHandler_arm::kindStrings[] = {
+    LLD_KIND_STRING_ENTRY(ARM_RELOC_BR24),
+    LLD_KIND_STRING_ENTRY(ARM_THUMB_RELOC_BR22),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_THUMB_ABS_LO16),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_THUMB_ABS_HI16),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_THUMB_REL_LO16),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_THUMB_REL_HI16),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_ABS32),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_POINTER32),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_LAZY_TARGET),
+    LLD_KIND_STRING_ENTRY(LLD_ARM_RELOC_LAZY_IMMEDIATE),
+    LLD_KIND_STRING_END
+};
 
-bool KindHandler_arm::isCallSite(Kind kind) {
-  return (kind == thumbBranch22) || (kind == armBranch24);
+bool KindHandler_arm::isCallSite(const Reference &ref) {
+  return (ref.kindValue() == ARM_THUMB_RELOC_BR22) || 
+         (ref.kindValue() == ARM_RELOC_BR24);
 }
 
-bool KindHandler_arm::isPointer(Kind kind) {
-  return (kind == pointer32);
+bool KindHandler_arm::isPointer(const Reference &ref) {
+  return (ref.kindValue() == LLD_ARM_RELOC_POINTER32);
 }
 
 
-bool KindHandler_arm::isLazyImmediate(Kind kind) {
-  return (kind == lazyImmediate);
+bool KindHandler_arm::isLazyImmediate(const Reference &ref) {
+  return (ref.kindValue() == LLD_ARM_RELOC_LAZY_IMMEDIATE);
 }
 
 
-bool KindHandler_arm::isLazyTarget(Kind kind) {
-  return (kind == lazyTarget);
+bool KindHandler_arm::isLazyTarget(const Reference &ref) {
+  return (ref.kindValue() == LLD_ARM_RELOC_LAZY_TARGET);
 }
 
 
-void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                  uint64_t fixupAddress, uint64_t targetAddress) {
+void KindHandler_arm::applyFixup(Reference::KindNamespace ns, 
+                                 Reference::KindArch arch, 
+                                 Reference::KindValue kindValue, 
+                                 uint64_t addend, uint8_t *location,
+                                 uint64_t fixupAddress, 
+                                 uint64_t targetAddress) {
+  if (ns != Reference::KindNamespace::mach_o)
+    return;
+  assert(arch == Reference::KindArch::ARM);
   //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
-  switch ( (Kinds)kind ) {
-    case thumbBranch22:
+  switch ( kindValue ) {
+    case ARM_THUMB_RELOC_BR22:
       // FIXME
       break;
-    case armBranch24:
+    case ARM_RELOC_BR24:
       // FIXME
       break;
-    case thumbAbsLow16:
+    case LLD_ARM_RELOC_THUMB_ABS_LO16:
       // FIXME
       break;
-    case thumbAbsHigh16:
+    case LLD_ARM_RELOC_THUMB_ABS_HI16:
       // FIXME
       break;
-    case thumbPcRelLow16:
+    case LLD_ARM_RELOC_THUMB_REL_LO16:
       // FIXME
       break;
-    case thumbPcRelHigh16:
+    case LLD_ARM_RELOC_THUMB_REL_HI16:
       // FIXME
       break;
-    case abs32:
+    case LLD_ARM_RELOC_ABS32:
       // FIXME
       break;
-    case pointer32:
+    case LLD_ARM_RELOC_POINTER32:
       // FIXME
       break;
-    case none:
-    case lazyTarget:
-    case lazyImmediate:
-    case subordinateLSDA:
+    case LLD_ARM_RELOC_LAZY_TARGET:
+    case LLD_ARM_RELOC_LAZY_IMMEDIATE:
       // do nothing
       break;
-    case invalid:
-      assert(0 && "invalid Reference Kind");
+    default:
+      llvm_unreachable("invalid ARM Reference Kind");
       break;
   }
 }

Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h Thu Dec 19 15:58:00 2013
@@ -20,6 +20,32 @@
 namespace lld {
 namespace mach_o {
 
+// Additional Reference Kind values used internally.
+enum {
+  LLD_X86_64_RELOC_GOT_LOAD_NOW_LEA = 100,
+  LLD_X86_64_RELOC_TLV_NOW_LEA      = 101,
+  LLD_X86_64_RELOC_LAZY_TARGET      = 102,
+  LLD_X86_64_RELOC_LAZY_IMMEDIATE   = 103,
+  LLD_X86_64_RELOC_SIGNED_32        = 104,
+};
+enum {
+  LLD_X86_RELOC_BRANCH32          = 100, // CALL or JMP 32-bit pc-rel
+  LLD_X86_RELOC_ABS32             = 101, // 32-bit absolute addr in instruction
+  LLD_X86_RELOC_FUNC_REL32        = 102, // 32-bit target from start of func
+  LLD_X86_RELOC_POINTER32         = 103, // 32-bit data pointer
+  LLD_X86_RELOC_LAZY_TARGET       = 104,
+  LLD_X86_RELOC_LAZY_IMMEDIATE    = 105
+};
+enum {
+  LLD_ARM_RELOC_THUMB_ABS_LO16    = 100, // thumb movw of absolute address
+  LLD_ARM_RELOC_THUMB_ABS_HI16    = 101, // thumb movt of absolute address
+  LLD_ARM_RELOC_THUMB_REL_LO16    = 102, // thumb movw of (target - pc)
+  LLD_ARM_RELOC_THUMB_REL_HI16    = 103, // thumb movt of (target - pc)
+  LLD_ARM_RELOC_ABS32             = 104, // 32-bit constant pointer
+  LLD_ARM_RELOC_POINTER32         = 105, // 32-bit data pointer
+  LLD_ARM_RELOC_LAZY_TARGET       = 106,
+  LLD_ARM_RELOC_LAZY_IMMEDIATE    = 107,
+}; 
 
 ///
 /// The KindHandler class is the abstract interface to Reference::Kind
@@ -28,18 +54,20 @@ namespace mach_o {
 ///
 class KindHandler {
 public:
-  typedef Reference::Kind Kind;
 
   static std::unique_ptr<mach_o::KindHandler> create(MachOLinkingContext::Arch);
   virtual ~KindHandler();
-  virtual Kind stringToKind(StringRef str) = 0;
-  virtual StringRef   kindToString(Kind) = 0;
-  virtual bool        isCallSite(Kind) = 0;
-  virtual bool        isPointer(Kind) = 0;
-  virtual bool        isLazyImmediate(Kind) = 0;
-  virtual bool        isLazyTarget(Kind) = 0;
-  virtual void        applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                           uint64_t fixupAddress, uint64_t targetAddress) = 0;
+
+  virtual bool    isCallSite(const Reference&) = 0;
+  virtual bool    isPointer(const Reference&) = 0;
+  virtual bool    isLazyImmediate(const Reference&) = 0;
+  virtual bool    isLazyTarget(const Reference&) = 0;
+  virtual void    applyFixup(Reference::KindNamespace ns, 
+                            Reference::KindArch arch, 
+                            Reference::KindValue kindValue,
+                            uint64_t addend, uint8_t *location,
+                            uint64_t fixupAddress, 
+                            uint64_t targetAddress) = 0;
 
 protected:
   KindHandler();
@@ -49,94 +77,55 @@ protected:
 
 class KindHandler_x86_64 : public KindHandler {
 public:
-  enum Kinds {
-    invalid,         // used to denote an error creating a Reference
-    none,
-    branch32,        // CALL or JMP 32-bit pc-rel
-    ripRel32,        // RIP-rel access pc-rel to fix up location
-    ripRel32_1,      // RIP-rel access pc-rel to fix up location + 1
-    ripRel32_2,      // RIP-rel access pc-rel to fix up location + 2
-    ripRel32_4,      // RIP-rel access pc-rel to fix up location + 4
-    gotLoadRipRel32, // RIP-rel load of GOT slot (can be optimized)
-    gotLoadRipRel32NowLea, // RIP-rel movq load of GOT slot optimized to LEA
-    gotUseRipRel32,  // RIP-rel non-load of GOT slot (not a movq load of GOT)
-    tlvLoadRipRel32, // RIP-rel load of thread local pointer (can be optimized)
-    tlvLoadRipRel32NowLea, // RIP-rel movq load of TLV pointer optimized to LEA
-    pointer64,       // 64-bit data pointer
-    pointerRel32,    // 32-bit pc-rel offset
-    lazyTarget,      // Used in lazy pointers to reference ultimate target
-    lazyImmediate,   // Location in stub where lazy info offset to be stored
-    subordinateFDE,  // Reference to unwind info for this function
-    subordinateLSDA  // Reference to excecption info for this function
-  };
 
+  static const Registry::KindStrings kindStrings[];
+  
   virtual ~KindHandler_x86_64();
-  virtual Kind stringToKind(StringRef str);
-  virtual StringRef kindToString(Kind);
-  virtual bool isCallSite(Kind);
-  virtual bool isPointer(Kind);
-  virtual bool isLazyImmediate(Kind);
-  virtual bool isLazyTarget(Kind);
-  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                  uint64_t fixupAddress, uint64_t targetAddress);
-
+  virtual bool isCallSite(const Reference&);
+  virtual bool isPointer(const Reference&);
+  virtual bool isLazyImmediate(const Reference&);
+  virtual bool isLazyTarget(const Reference&);
+  virtual void applyFixup(Reference::KindNamespace ns, 
+                          Reference::KindArch arch, 
+                          Reference::KindValue kindValue,
+                          uint64_t addend, uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
 };
 
 
 class KindHandler_x86 : public KindHandler {
 public:
-  enum Kinds {
-    invalid,         // used to denote an error creating a Reference
-    none,
-    branch32,        // CALL or JMP 32-bit pc-rel
-    abs32,           // 32-bit absolute address embedded in instruction
-    funcRel32,       // 32-bit offset to target from start of function
-    pointer32,       // 32-bit data pointer
-    lazyTarget,      // Used in lazy pointers to reference ultimate target
-    lazyImmediate,   // Location in stub where lazy info offset to be stored
-    subordinateFDE,  // Reference to unwind info for this function
-    subordinateLSDA  // Reference to excecption info for this function
-  };
+
+  static const Registry::KindStrings kindStrings[];
 
   virtual ~KindHandler_x86();
-  virtual Kind stringToKind(StringRef str);
-  virtual StringRef kindToString(Kind);
-  virtual bool isCallSite(Kind);
-  virtual bool isPointer(Kind);
-  virtual bool isLazyImmediate(Kind);
-  virtual bool isLazyTarget(Kind);
-  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                  uint64_t fixupAddress, uint64_t targetAddress);
+  virtual bool isCallSite(const Reference&);
+  virtual bool isPointer(const Reference&);
+  virtual bool isLazyImmediate(const Reference&);
+  virtual bool isLazyTarget(const Reference&);
+  virtual void applyFixup(Reference::KindNamespace ns, 
+                          Reference::KindArch arch, 
+                          Reference::KindValue kindValue,
+                          uint64_t addend, uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
 
 };
 
 class KindHandler_arm : public KindHandler {
 public:
-  enum Kinds {
-    invalid,         // used to denote an error creating a Reference
-    none,
-    thumbBranch22,   // thumb b or bl with 22/24-bits of displacement
-    armBranch24,     // arm b or bl with 24-bits of displacement
-    thumbAbsLow16,   // thumb movw of absolute address
-    thumbAbsHigh16,  // thumb movt of absolute address
-    thumbPcRelLow16, // thumb movw of (target - pc)
-    thumbPcRelHigh16,// thumb movt of (target - pc)
-    abs32,           // 32-bit absolute address embedded in instructions
-    pointer32,       // 32-bit data pointer
-    lazyTarget,      // Used in lazy pointers to reference ultimate target
-    lazyImmediate,   // Location in stub where lazy info offset to be stored
-    subordinateLSDA  // Reference to excecption info for this function
-  };
+
+  static const Registry::KindStrings kindStrings[];
 
   virtual ~KindHandler_arm();
-  virtual Kind stringToKind(StringRef str);
-  virtual StringRef kindToString(Kind);
-  virtual bool isCallSite(Kind);
-  virtual bool isPointer(Kind);
-  virtual bool isLazyImmediate(Kind);
-  virtual bool isLazyTarget(Kind);
-  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
-                  uint64_t fixupAddress, uint64_t targetAddress);
+  virtual bool isCallSite(const Reference&);
+  virtual bool isPointer(const Reference&);
+  virtual bool isLazyImmediate(const Reference&);
+  virtual bool isLazyTarget(const Reference&);
+  virtual void applyFixup(Reference::KindNamespace ns, 
+                          Reference::KindArch arch, 
+                          Reference::KindValue kindValue,
+                          uint64_t addend, uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
 
 };
 

Modified: lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp Thu Dec 19 15:58:00 2013
@@ -31,7 +31,9 @@ class X86StubAtom : public SimpleDefined
 public:
   X86StubAtom(const File &file, const Atom &lazyPointer)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86::abs32, 2, &lazyPointer, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_ABS32, 2, &lazyPointer, 0);
   }
 
   virtual ContentType contentType() const {
@@ -63,8 +65,12 @@ public:
   X86StubHelperCommonAtom(const File &file, const Atom &cache,
                           const Atom &binder)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86::abs32, 1, &cache,  0);
-    this->addReference(KindHandler_x86::abs32, 7, &binder, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_ABS32, 1, &cache,  0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_ABS32, 7, &binder, 0);
   }
 
   virtual ContentType contentType() const {
@@ -97,8 +103,12 @@ class X86StubHelperAtom : public SimpleD
 public:
   X86StubHelperAtom(const File &file, const Atom &helperCommon)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86::lazyImmediate, 1, this, 0);
-    this->addReference(KindHandler_x86::branch32, 6, &helperCommon, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_LAZY_IMMEDIATE, 1, this, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_BRANCH32, 6, &helperCommon, 0);
   }
 
   virtual ContentType contentType() const {
@@ -130,8 +140,12 @@ class X86LazyPointerAtom : public Simple
 public:
   X86LazyPointerAtom(const File &file, const Atom &helper, const Atom &shlib)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86::pointer32,  0, &helper, 0);
-    this->addReference(KindHandler_x86::lazyTarget, 0, &shlib,  0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_POINTER32,  0, &helper, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_LAZY_TARGET, 0, &shlib,  0);
   }
 
   virtual ContentType contentType() const {
@@ -167,7 +181,9 @@ public:
 
   X86NonLazyPointerAtom(const File &file, const Atom &shlib)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86::pointer32, 0, &shlib, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86, 
+                       LLD_X86_RELOC_POINTER32, 0, &shlib, 0);
   }
 
   virtual ContentType contentType() const {

Modified: lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp Thu Dec 19 15:58:00 2013
@@ -20,6 +20,7 @@
 #include "ReferenceKinds.h"
 
 using llvm::makeArrayRef;
+using namespace llvm::MachO;
 
 namespace lld {
 namespace mach_o {
@@ -31,7 +32,9 @@ class X86_64StubAtom : public SimpleDefi
 public:
   X86_64StubAtom(const File &file, const Atom &lazyPointer)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86_64::ripRel32, 2, &lazyPointer, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_SIGNED, 2, &lazyPointer, 0);
   }
 
   virtual ContentType contentType() const {
@@ -62,8 +65,12 @@ public:
   X86_64StubHelperCommonAtom(const File &file, const Atom &cache,
                              const Atom &binder)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86_64::ripRel32, 3,  &cache, 0);
-    this->addReference(KindHandler_x86_64::ripRel32, 11, &binder, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_SIGNED, 3,  &cache, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_SIGNED, 11, &binder, 0);
   }
 
   virtual ContentType contentType() const {
@@ -96,8 +103,12 @@ class X86_64StubHelperAtom : public Simp
 public:
   X86_64StubHelperAtom(const File &file, const Atom &helperCommon)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86_64::lazyImmediate, 1, this, 0);
-    this->addReference(KindHandler_x86_64::ripRel32, 6, &helperCommon, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       LLD_X86_64_RELOC_LAZY_IMMEDIATE, 1, this, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_SIGNED, 6, &helperCommon, 0);
   }
 
   virtual ContentType contentType() const {
@@ -129,8 +140,12 @@ public:
   X86_64LazyPointerAtom(const File &file, const Atom &helper,
                         const Atom &shlib)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86_64::pointer64, 0, &helper, 0);
-    this->addReference(KindHandler_x86_64::lazyTarget, 0, &shlib, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_UNSIGNED, 0, &helper, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       LLD_X86_64_RELOC_LAZY_TARGET, 0, &shlib, 0);
   }
 
   virtual ContentType contentType() const {
@@ -166,7 +181,9 @@ public:
 
   X86_64NonLazyPointerAtom(const File &file, const Atom &shlib)
       : SimpleDefinedAtom(file) {
-    this->addReference(KindHandler_x86_64::pointer64, 0, &shlib, 0);
+    this->addReference(Reference::KindNamespace::mach_o, 
+                       Reference::KindArch::x86_64, 
+                       X86_64_RELOC_UNSIGNED, 0, &shlib, 0);
   }
 
   virtual ContentType contentType() const {

Modified: lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp Thu Dec 19 15:58:00 2013
@@ -41,8 +41,8 @@ public:
     return true;
   }
 
-  virtual bool isCallSite(int32_t kind) {
-    return _kindHandler.isCallSite(kind);
+  virtual bool isCallSite(const Reference &ref) {
+    return _kindHandler.isCallSite(ref);
   }
 
   virtual const DefinedAtom* getStub(const Atom& target) {
@@ -150,10 +150,10 @@ private:
   class File : public SimpleFile {
   public:
     File(const MachOLinkingContext &context)
-        : SimpleFile(context, "MachO Stubs pass") {}
+        : SimpleFile("MachO Stubs pass") {}
   };
 
-  const MachOLinkingContext                       &_context;
+  const MachOLinkingContext                      &_context;
   mach_o::KindHandler                            &_kindHandler;
   File                                            _file;
   llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToStub;

Modified: lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h (original)
+++ lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h Thu Dec 19 15:58:00 2013
@@ -202,8 +202,10 @@ struct NativeReferenceIvarsV1 {
   enum {
     noTarget = UINT16_MAX
   };
-  uint16_t  offsetInAtom;
-   int16_t  kind;
+  uint32_t  offsetInAtom;
+  uint16_t  kindValue;
+  uint8_t   kindNamespace;
+  uint8_t   kindArch;
   uint16_t  targetIndex;
   uint16_t  addendIndex;
 };
@@ -218,7 +220,9 @@ struct NativeReferenceIvarsV2 {
   };
   uint64_t  offsetInAtom;
   int64_t   addend;
-  int32_t   kind;
+  uint16_t  kindValue;
+  uint8_t   kindNamespace;
+  uint8_t   kindArch;
   uint32_t  targetIndex;
 };
 

Modified: lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp Thu Dec 19 15:58:00 2013
@@ -214,8 +214,9 @@ private:
 class NativeReferenceV1 : public Reference {
 public:
   NativeReferenceV1(const File& f, const NativeReferenceIvarsV1* ivarData)
-      : _file(&f), _ivarData(ivarData) {
-    setKind(ivarData->kind);
+      : Reference((KindNamespace)ivarData->kindNamespace, 
+                  (KindArch)ivarData->kindArch, ivarData->kindValue), 
+        _file(&f), _ivarData(ivarData) {
   }
 
   virtual uint64_t offsetInAtom() const {
@@ -240,8 +241,9 @@ private:
 class NativeReferenceV2 : public Reference {
 public:
   NativeReferenceV2(const File& f, const NativeReferenceIvarsV2* ivarData)
-      : _file(&f), _ivarData(ivarData) {
-    setKind(ivarData->kind);
+      : Reference((KindNamespace)ivarData->kindNamespace, 
+                  (KindArch)ivarData->kindArch, ivarData->kindValue), 
+        _file(&f), _ivarData(ivarData) {
   }
 
   virtual uint64_t offsetInAtom() const {
@@ -267,8 +269,7 @@ public:
 
   /// Instantiates a File object from a native object file.  Ownership
   /// of the MemoryBuffer is transferred to the resulting File object.
-  static error_code make(const LinkingContext &context,
-                         std::unique_ptr<MemoryBuffer> mb,
+  static error_code make(std::unique_ptr<MemoryBuffer> mb,
                          std::vector<std::unique_ptr<lld::File> > &result) {
     const uint8_t *const base =
         reinterpret_cast<const uint8_t *>(mb->getBufferStart());
@@ -293,7 +294,7 @@ public:
                                  << header->chunkCount << "\n");
 
     // instantiate NativeFile object and add values to it as found
-    std::unique_ptr<File> file(new File(context, std::move(mb), path));
+    std::unique_ptr<File> file(new File(std::move(mb), path));
 
     // process each chunk
     for (uint32_t i = 0; i < header->chunkCount; ++i) {
@@ -360,7 +361,7 @@ public:
         for (const Reference *r : *a) {
           llvm::dbgs() << "        offset="
                        << llvm::format("0x%03X", r->offsetInAtom())
-                       << ", kind=" << r->kind()
+                       << ", kind=" << r->kindValue()
                        << ", target=" << r->target() << "\n";
         }
       }
@@ -397,7 +398,6 @@ public:
   virtual const atom_collection<AbsoluteAtom> &absolute() const {
     return _absoluteAtoms;
   }
-  virtual const LinkingContext &getLinkingContext() const { return _context; }
 
 private:
   friend NativeDefinedAtomV1;
@@ -792,14 +792,12 @@ private:
   }
 
   // private constructor, only called by make()
-  File(const LinkingContext &context, std::unique_ptr<MemoryBuffer> mb,
-       StringRef path)
+  File(std::unique_ptr<MemoryBuffer> mb, StringRef path)
       : lld::File(path, kindObject),
         _buffer(std::move(mb)), // Reader now takes ownership of buffer
         _header(nullptr), _targetsTable(nullptr), _targetsTableCount(0),
         _strings(nullptr), _stringsMaxOffset(0), _addends(nullptr),
-        _addendsMaxIndex(0), _contentStart(nullptr), _contentEnd(nullptr),
-        _context(context) {
+        _addendsMaxIndex(0), _contentStart(nullptr), _contentEnd(nullptr) {
     _header =
         reinterpret_cast<const NativeFileHeader *>(_buffer->getBufferStart());
   }
@@ -845,7 +843,7 @@ private:
   };
 
 
-  std::unique_ptr<MemoryBuffer> _buffer;
+  std::unique_ptr<MemoryBuffer>   _buffer;
   const NativeFileHeader*         _header;
   AtomArray<DefinedAtom>          _definedAtoms;
   AtomArray<UndefinedAtom>        _undefinedAtoms;
@@ -862,10 +860,9 @@ private:
   const char*                     _strings;
   uint32_t                        _stringsMaxOffset;
   const Reference::Addend*        _addends;
-  uint32_t _addendsMaxIndex;
-  const uint8_t *_contentStart;
-  const uint8_t *_contentEnd;
-  const LinkingContext &_context;
+  uint32_t                        _addendsMaxIndex;
+  const uint8_t                  *_contentStart;
+  const uint8_t                  *_contentEnd;
 };
 
 inline const lld::File &NativeDefinedAtomV1::file() const {
@@ -1002,19 +999,34 @@ inline void NativeReferenceV2::setAddend
   llvm_unreachable("setAddend() not supported");
 }
 
-class Reader : public lld::Reader {
-public:
-  Reader(const LinkingContext &context) : lld::Reader(context) {}
+} // end namespace native
+
 
+namespace {
+
+class NativeReader : public Reader {
+public:
+  virtual bool canParse(file_magic magic, StringRef, 
+                                                const MemoryBuffer& mb) const {
+    const NativeFileHeader *const header =
+            reinterpret_cast<const NativeFileHeader *>(mb.getBufferStart());
+    return (memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC, 
+                                                  sizeof(header->magic)) == 0);
+  }
+  
   virtual error_code
-  parseFile(std::unique_ptr<MemoryBuffer> &mb,
-            std::vector<std::unique_ptr<lld::File> > &result) const {
-    return File::make(_context, std::move(mb), result);
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File>> &result) const {
+    return lld::native::File::make(std::move(mb), result);
+    return error_code::success();
   }
 };
-} // end namespace native
 
-std::unique_ptr<Reader> createReaderNative(const LinkingContext &context) {
-  return std::unique_ptr<Reader>(new lld::native::Reader(context));
+
 }
+
+void Registry::addSupportNativeObjects() {
+  add(std::unique_ptr<Reader>(new NativeReader())); 
+}
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp Thu Dec 19 15:58:00 2013
@@ -155,7 +155,9 @@ private:
     for (const NativeReferenceIvarsV2 &v2 : _referencesV2) {
       NativeReferenceIvarsV1 v1;
       v1.offsetInAtom = v2.offsetInAtom;
-      v1.kind = v2.kind;
+      v1.kindNamespace = v2.kindNamespace;
+      v1.kindArch = v2.kindArch;
+      v1.kindValue = v2.kindValue;
       v1.targetIndex = (v2.targetIndex == NativeReferenceIvarsV2::noTarget) ?
           NativeReferenceIvarsV1::noTarget : v2.targetIndex;
       v1.addendIndex = this->getAddendIndex(v2.addend);
@@ -431,7 +433,9 @@ private:
     for (const Reference *ref : atom) {
       NativeReferenceIvarsV2 nref;
       nref.offsetInAtom = ref->offsetInAtom();
-      nref.kind = ref->kind();
+      nref.kindNamespace = (uint8_t)ref->kindNamespace();
+      nref.kindArch = (uint8_t)ref->kindArch();
+      nref.kindValue = ref->kindValue();
       nref.targetIndex = this->getTargetIndex(ref->target());
       nref.addend = ref->addend();
       _referencesV2.push_back(nref);

Modified: lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h Thu Dec 19 15:58:00 2013
@@ -27,13 +27,11 @@ class COFFDefinedAtom;
 /// to be fixed up so that the address points to atom Y's address.
 class COFFReference LLVM_FINAL : public Reference {
 public:
-  explicit COFFReference(Kind kind) : _target(nullptr), _offsetInAtom(0) {
-    _kind = kind;
-  }
-
-  COFFReference(const Atom *target, uint32_t offsetInAtom, uint16_t relocType)
-      : _target(target), _offsetInAtom(offsetInAtom) {
-    setKind(static_cast<Reference::Kind>(relocType));
+  COFFReference(const Atom *target, uint32_t offsetInAtom, uint16_t relocType,
+               Reference::KindNamespace ns=Reference::KindNamespace::COFF,
+               Reference::KindArch arch=Reference::KindArch::x86)
+      : Reference(ns, arch, relocType), 
+        _target(target), _offsetInAtom(offsetInAtom) {
   }
 
   virtual const Atom *target() const { return _target; }
@@ -326,7 +324,7 @@ private:
 class VirtualFile : public SimpleFile {
 public:
   VirtualFile(const LinkingContext &ctx)
-      : SimpleFile(ctx, "<virtual-file>"), _nextOrdinal(0) {
+      : SimpleFile("<virtual-file>"), _nextOrdinal(0) {
     setOrdinal(ctx.getNextOrdinalAndIncrement());
   }
 
@@ -343,8 +341,9 @@ private:
 //===----------------------------------------------------------------------===//
 
 template <typename T, typename U>
-void addLayoutEdge(T *a, U *b, lld::Reference::Kind kind) {
-  auto ref = new COFFReference(kind);
+void addLayoutEdge(T *a, U *b, uint32_t which) {
+  auto ref = new COFFReference(nullptr, 0, which, Reference::KindNamespace::all,
+                                                  Reference::KindArch::all);
   ref->setTarget(b);
   a->addReference(std::unique_ptr<COFFReference>(ref));
 }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Thu Dec 19 15:58:00 2013
@@ -21,7 +21,7 @@ namespace pecoff {
 class LinkerGeneratedSymbolFile : public SimpleFile {
 public:
   LinkerGeneratedSymbolFile(const PECOFFLinkingContext &ctx)
-      : SimpleFile(ctx, "<linker-internal-file>"),
+      : SimpleFile("<linker-internal-file>"),
         _imageBaseAtom(*this, ctx.decorateSymbol("__ImageBase"),
                        Atom::scopeGlobal, ctx.getBaseAddress()) {
     addAtom(_imageBaseAtom);

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Thu Dec 19 15:58:00 2013
@@ -78,7 +78,6 @@ bool PECOFFLinkingContext::validateImpl(
     return false;
   }
 
-  _reader = createReaderPECOFF(*this);
   _writer = createWriterPECOFF(*this);
   return true;
 }
@@ -87,7 +86,7 @@ std::unique_ptr<File> PECOFFLinkingConte
   if (entrySymbolName().empty())
     return nullptr;
   std::unique_ptr<SimpleFile> entryFile(
-      new SimpleFile(*this, "command line option /entry"));
+      new SimpleFile("command line option /entry"));
   entryFile->addAtom(
       *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
   return std::move(entryFile);
@@ -97,7 +96,7 @@ std::unique_ptr<File> PECOFFLinkingConte
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(
-      new SimpleFile(*this, "command line option /c (or) /include"));
+      new SimpleFile("command line option /c (or) /include"));
   for (auto undefSymStr : _initialUndefinedSymbols)
     undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
                                    *undefinedSymFile, undefSymStr)));
@@ -208,40 +207,6 @@ StringRef PECOFFLinkingContext::decorate
 
 Writer &PECOFFLinkingContext::writer() const { return *_writer; }
 
-ErrorOr<Reference::Kind>
-PECOFFLinkingContext::relocKindFromString(StringRef str) const {
-#define LLD_CASE(name) .Case(#name, llvm::COFF::name)
-  int32_t ret = llvm::StringSwitch<int32_t>(str)
-        LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
-        LLD_CASE(IMAGE_REL_I386_DIR32)
-        LLD_CASE(IMAGE_REL_I386_DIR32NB)
-        LLD_CASE(IMAGE_REL_I386_SECTION)
-        LLD_CASE(IMAGE_REL_I386_SECREL)
-        LLD_CASE(IMAGE_REL_I386_REL32)
-        .Default(-1);
-#undef LLD_CASE
-  if (ret == -1)
-    return make_error_code(YamlReaderError::illegal_value);
-  return ret;
-}
-
-ErrorOr<std::string>
-PECOFFLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
-  switch (kind) {
-#define LLD_CASE(name)                          \
-    case llvm::COFF::name:                      \
-      return std::string(#name);
-
-    LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
-    LLD_CASE(IMAGE_REL_I386_DIR32)
-    LLD_CASE(IMAGE_REL_I386_DIR32NB)
-    LLD_CASE(IMAGE_REL_I386_SECTION)
-    LLD_CASE(IMAGE_REL_I386_SECREL)
-    LLD_CASE(IMAGE_REL_I386_REL32)
-#undef LLD_CASE
-  }
-  return make_error_code(YamlReaderError::illegal_value);
-}
 
 void PECOFFLinkingContext::setSectionSetMask(StringRef sectionName,
                                              uint32_t newFlags) {
@@ -270,7 +235,8 @@ uint32_t PECOFFLinkingContext::getSectio
   uint32_t clearMask = (ci == _sectionClearMask.end()) ? 0 : ci->second;
   return (flags | setMask) & ~clearMask;
 }
-
+ 
+ 
 void PECOFFLinkingContext::addPasses(PassManager &pm) {
   pm.add(std::unique_ptr<Pass>(new pecoff::SetSubsystemPass(*this)));
   pm.add(std::unique_ptr<Pass>(new pecoff::EdataPass(*this)));

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Thu Dec 19 15:58:00 2013
@@ -59,11 +59,13 @@ private:
   typedef std::map<const coff_section *, SymbolVectorT> SectionToSymbolsT;
   typedef std::map<const StringRef, Atom *> SymbolNameToAtomT;
   typedef std::map<const coff_section *, vector<COFFDefinedFileAtom *> >
-  SectionToAtomsT;
+      SectionToAtomsT;
 
 public:
-  FileCOFF(const PECOFFLinkingContext &context,
-           std::unique_ptr<MemoryBuffer> mb, error_code &ec);
+  typedef const std::map<std::string, std::string> StringMap;
+
+  FileCOFF(std::unique_ptr<MemoryBuffer> mb, StringMap &altNames,
+           error_code &ec);
 
   virtual const atom_collection<DefinedAtom> &defined() const {
     return _definedAtoms;
@@ -81,11 +83,10 @@ public:
     return _absoluteAtoms;
   }
 
-  virtual const LinkingContext &getLinkingContext() const { return _context; }
-
   StringRef getLinkerDirectives() const { return _directives; }
 
 private:
+
   error_code readSymbolTable(vector<const coff_symbol *> &result);
 
   void createAbsoluteAtoms(const SymbolVectorT &symbols,
@@ -95,16 +96,19 @@ private:
                                   vector<const UndefinedAtom *> &result);
 
   error_code createDefinedSymbols(const SymbolVectorT &symbols,
+                                  StringMap &altNames,
                                   vector<const DefinedAtom *> &result);
 
   error_code cacheSectionAttributes();
 
   error_code
-  AtomizeDefinedSymbolsInSection(const coff_section *section,
-                                 vector<const coff_symbol *> &symbols,
-                                 vector<COFFDefinedFileAtom *> &atoms);
+      AtomizeDefinedSymbolsInSection(const coff_section *section,
+                                     StringMap &altNames,
+                                     vector<const coff_symbol *> &symbols,
+                                     vector<COFFDefinedFileAtom *> &atoms);
 
   error_code AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols,
+                                   StringMap &altNames,
                                    vector<const DefinedAtom *> &definedAtoms);
 
   error_code findAtomAt(const coff_section *section, uint32_t targetAddress,
@@ -153,10 +157,9 @@ private:
   // the section.
   std::map<const coff_section *,
            std::map<uint32_t, std::vector<COFFDefinedAtom *> > >
-  _definedAtomLocations;
+      _definedAtomLocations;
 
   mutable llvm::BumpPtrAllocator _alloc;
-  const PECOFFLinkingContext &_context;
   uint64_t _ordinal;
 };
 
@@ -173,34 +176,6 @@ private:
   llvm::BumpPtrAllocator _alloc;
 };
 
-class ReaderCOFF : public Reader {
-public:
-  explicit ReaderCOFF(PECOFFLinkingContext &context)
-      : Reader(context), _PECOFFLinkingContext(context) {}
-
-  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
-                       std::vector<std::unique_ptr<File> > &result) const;
-
-private:
-  error_code handleDirectiveSection(StringRef directives) const;
-
-  ErrorOr<std::string>
-  writeResToTemporaryFile(std::unique_ptr<MemoryBuffer> mb) const;
-
-  ErrorOr<std::string>
-  convertResourceFileToCOFF(std::unique_ptr<MemoryBuffer> mb) const;
-
-  error_code convertAndParseResourceFile(
-      std::unique_ptr<MemoryBuffer> &mb,
-      std::vector<std::unique_ptr<File> > &result) const;
-
-  error_code parseCOFFFile(std::unique_ptr<MemoryBuffer> &mb,
-                           std::vector<std::unique_ptr<File> > &result) const;
-
-  PECOFFLinkingContext &_PECOFFLinkingContext;
-  mutable BumpPtrStringSaver _stringSaver;
-};
-
 // Converts the COFF symbol attribute to the LLD's atom attribute.
 Atom::Scope getScope(const coff_symbol *symbol) {
   switch (symbol->StorageClass) {
@@ -278,10 +253,9 @@ DefinedAtom::Merge getMerge(const coff_a
   }
 }
 
-FileCOFF::FileCOFF(const PECOFFLinkingContext &context,
-                   std::unique_ptr<MemoryBuffer> mb, error_code &ec)
-    : File(mb->getBufferIdentifier(), kindObject), _context(context),
-      _ordinal(0) {
+FileCOFF::FileCOFF(std::unique_ptr<MemoryBuffer> mb, StringMap &altNames,
+                   error_code &ec)
+    : File(mb->getBufferIdentifier(), kindObject), _ordinal(0) {
   OwningPtr<llvm::object::Binary> bin;
   ec = llvm::object::createBinary(mb.release(), bin);
   if (ec)
@@ -304,7 +278,7 @@ FileCOFF::FileCOFF(const PECOFFLinkingCo
   createAbsoluteAtoms(symbols, _absoluteAtoms._atoms);
   if ((ec = createUndefinedAtoms(symbols, _undefinedAtoms._atoms)))
     return;
-  if ((ec = createDefinedSymbols(symbols, _definedAtoms._atoms)))
+  if ((ec = createDefinedSymbols(symbols, altNames, _definedAtoms._atoms)))
     return;
 
   if ((ec = addRelocationReferenceToAtoms()))
@@ -427,6 +401,7 @@ FileCOFF::createUndefinedAtoms(const Sym
 /// the other two, because in order to create the atom for the defined symbol
 /// we need to know the adjacent symbols.
 error_code FileCOFF::createDefinedSymbols(const SymbolVectorT &symbols,
+                                          StringMap &altNames,
                                           vector<const DefinedAtom *> &result) {
   // A defined atom can be merged if its section attribute allows its contents
   // to be merged. In COFF, it's not very easy to get the section attribute
@@ -499,7 +474,7 @@ error_code FileCOFF::createDefinedSymbol
   }
 
   // Atomize the defined symbols.
-  if (error_code ec = AtomizeDefinedSymbols(definedSymbols, result))
+  if (error_code ec = AtomizeDefinedSymbols(definedSymbols, altNames, result))
     return ec;
 
   return error_code::success();
@@ -552,17 +527,19 @@ error_code FileCOFF::cacheSectionAttribu
 /// assumed to have been defined in the \p section.
 error_code
 FileCOFF::AtomizeDefinedSymbolsInSection(const coff_section *section,
+                                         StringMap &altNames,
                                          vector<const coff_symbol *> &symbols,
                                          vector<COFFDefinedFileAtom *> &atoms) {
-  // Sort symbols by position.
+    // Sort symbols by position.
   std::stable_sort(
       symbols.begin(), symbols.end(),
       // For some reason MSVC fails to allow the lambda in this context with a
       // "illegal use of local type in type instantiation". MSVC is clearly
       // wrong here. Force a conversion to function pointer to work around.
-      static_cast<bool (*)(const coff_symbol *, const coff_symbol *)>([](
-          const coff_symbol * a,
-          const coff_symbol * b)->bool { return a->Value < b->Value; }));
+      static_cast<bool(*)(const coff_symbol *, const coff_symbol *)>(
+          [](const coff_symbol * a, const coff_symbol * b)->bool {
+    return a->Value < b->Value;
+  }));
 
   StringRef sectionName;
   if (error_code ec = _obj->getSectionName(section, sectionName))
@@ -626,12 +603,10 @@ FileCOFF::AtomizeDefinedSymbolsInSection
     // if this is the last symbol, take up the remaining data.
     const uint8_t *end = (si + 1 == se) ? secData.data() + secData.size()
                                         : secData.data() + (*(si + 1))->Value;
-    StringRef symbolName = _symbolName[*si];
-    StringRef alias = _context.getAlternateName(symbolName);
-
-    if (!alias.empty()) {
+    auto pos = altNames.find(_symbolName[*si]);
+    if (pos != altNames.end()) {
       auto *atom = new (_alloc) COFFDefinedAtom(
-          *this, alias, sectionName, getScope(*si), type, isComdat, perms,
+          *this, pos->second, sectionName, getScope(*si), type, isComdat, perms,
           DefinedAtom::mergeAsWeak, ArrayRef<uint8_t>(), _ordinal++);
       atoms.push_back(atom);
       _symbolAtom[*si] = atom;
@@ -655,6 +630,7 @@ FileCOFF::AtomizeDefinedSymbolsInSection
 
 error_code
 FileCOFF::AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols,
+                                StringMap &altNames,
                                 vector<const DefinedAtom *> &definedAtoms) {
   // For each section, make atoms for all the symbols defined in the
   // section, and append the atoms to the result objects.
@@ -662,7 +638,8 @@ FileCOFF::AtomizeDefinedSymbols(SectionT
     const coff_section *section = i.first;
     vector<const coff_symbol *> &symbols = i.second;
     vector<COFFDefinedFileAtom *> atoms;
-    if (error_code ec = AtomizeDefinedSymbolsInSection(section, symbols, atoms))
+    if (error_code ec =
+            AtomizeDefinedSymbolsInSection(section, altNames, symbols, atoms))
       return ec;
 
     // Connect atoms with layout-before/layout-after edges.
@@ -815,185 +792,233 @@ error_code FileCOFF::maybeReadLinkerDire
   return error_code::success();
 }
 
-error_code
-ReaderCOFF::parseFile(std::unique_ptr<MemoryBuffer> &mb,
-                      std::vector<std::unique_ptr<File> > &result) const {
-  StringRef magic(mb->getBufferStart(), mb->getBufferSize());
-
-  // The input file should be a resource file, an archive file, a regular COFF
-  // file, or an import library member file. Try to parse in that order. If
-  // the input file does not start with a known magic, parseCOFFImportLibrary
-  // will return an error object.
-  llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(magic);
-
-  if (fileType == llvm::sys::fs::file_magic::windows_resource)
-    return convertAndParseResourceFile(mb, result);
-  if (fileType == llvm::sys::fs::file_magic::coff_import_library)
-    return lld::pecoff::parseCOFFImportLibrary(_context, mb, result);
-  return parseCOFFFile(mb, result);
-}
-
-// Interpret the contents of .drectve section. If exists, the section contains
-// a string containing command line options. The linker is expected to
-// interpret the options as if they were given via the command line.
+// Convert .res file to .coff file and then parse it. Resource file is a file
+// containing various types of data, such as icons, translation texts,
+// etc. "cvtres.exe" command reads an RC file to create a COFF file which
+// encapsulates resource data into rsrc$N sections, where N is an integer.
 //
-// The section mainly contains /defaultlib (-l in Unix), but can contain any
-// options as long as they are valid.
-error_code ReaderCOFF::handleDirectiveSection(StringRef directives) const {
-  DEBUG(llvm::dbgs() << ".drectve: " << directives << "\n");
-
-  // Split the string into tokens, as the shell would do for argv.
-  SmallVector<const char *, 16> tokens;
-  tokens.push_back("link"); // argv[0] is the command name. Will be ignored.
-  llvm::cl::TokenizeWindowsCommandLine(directives, _stringSaver, tokens);
-  tokens.push_back(nullptr);
-
-  // Calls the command line parser to interpret the token string as if they
-  // were given via the command line.
-  int argc = tokens.size() - 1;
-  const char **argv = &tokens[0];
-  std::string errorMessage;
-  llvm::raw_string_ostream stream(errorMessage);
-  bool parseFailed = !WinLinkDriver::parse(argc, argv, _PECOFFLinkingContext,
-                                           stream, /*isDirective*/ true);
-  stream.flush();
-
-  // Print error message if error.
-  if (parseFailed) {
-    llvm::errs() << "Failed to parse '" << directives << "'\n"
-                 << "Reason: " << errorMessage;
-    return make_error_code(llvm::object::object_error::invalid_file_type);
-  }
-  if (!errorMessage.empty()) {
-    llvm::errs() << "lld warning: " << errorMessage << "\n";
+// The linker is not capable to handle RC files directly. Instead, it runs
+// cvtres.exe on RC files and then then link its outputs.
+class ResourceFileReader : public Reader {
+public:
+  virtual bool canParse(file_magic magic, StringRef ext,
+                        const MemoryBuffer &) const {
+    return (magic == llvm::sys::fs::file_magic::windows_resource);
+  }
+
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File> > &result) const {
+    // Convert RC file to COFF
+    ErrorOr<std::string> coffPath = convertResourceFileToCOFF(std::move(mb));
+    if (!coffPath)
+      return error_code(coffPath);
+    llvm::FileRemover coffFileRemover(*coffPath);
+
+    // Read and parse the COFF
+    OwningPtr<MemoryBuffer> opmb;
+    if (error_code ec = MemoryBuffer::getFile(*coffPath, opmb))
+      return ec;
+    std::unique_ptr<MemoryBuffer> newmb(opmb.take());
+    error_code ec;
+    FileCOFF::StringMap emptyMap;
+    std::unique_ptr<FileCOFF> file(
+        new FileCOFF(std::move(newmb), emptyMap, ec));
+    if (ec)
+      return ec;
+    result.push_back(std::move(file));
+    return error_code::success();
   }
-  return error_code::success();
-}
 
-ErrorOr<std::string>
-ReaderCOFF::writeResToTemporaryFile(std::unique_ptr<MemoryBuffer> mb) const {
-  // Get a temporary file path for .res file.
-  SmallString<128> tempFilePath;
-  if (error_code ec =
-          llvm::sys::fs::createTemporaryFile("tmp", "res", tempFilePath))
-    return ec;
+private:
+  static ErrorOr<std::string>
+  writeResToTemporaryFile(std::unique_ptr<MemoryBuffer> mb) {
+    // Get a temporary file path for .res file.
+    SmallString<128> tempFilePath;
+    if (error_code ec =
+            llvm::sys::fs::createTemporaryFile("tmp", "res", tempFilePath))
+      return ec;
 
-  // Write the memory buffer contents to .res file, so that we can run
-  // cvtres.exe on it.
-  OwningPtr<llvm::FileOutputBuffer> buffer;
-  if (error_code ec = llvm::FileOutputBuffer::create(
-          tempFilePath.str(), mb->getBufferSize(), buffer))
-    return ec;
-  memcpy(buffer->getBufferStart(), mb->getBufferStart(), mb->getBufferSize());
-  if (error_code ec = buffer->commit())
-    return ec;
+    // Write the memory buffer contents to .res file, so that we can run
+    // cvtres.exe on it.
+    OwningPtr<llvm::FileOutputBuffer> buffer;
+    if (error_code ec = llvm::FileOutputBuffer::create(
+            tempFilePath.str(), mb->getBufferSize(), buffer))
+      return ec;
+    memcpy(buffer->getBufferStart(), mb->getBufferStart(), mb->getBufferSize());
+    if (error_code ec = buffer->commit())
+      return ec;
 
-  // Convert SmallString -> StringRef -> std::string.
-  return tempFilePath.str().str();
-}
+    // Convert SmallString -> StringRef -> std::string.
+    return tempFilePath.str().str();
+  }
 
-ErrorOr<std::string>
-ReaderCOFF::convertResourceFileToCOFF(std::unique_ptr<MemoryBuffer> mb) const {
-  // Write the resource file to a temporary file.
-  ErrorOr<std::string> inFilePath = writeResToTemporaryFile(std::move(mb));
-  if (!inFilePath)
-    return error_code(inFilePath);
-  llvm::FileRemover inFileRemover(*inFilePath);
-
-  // Create an output file path.
-  SmallString<128> outFilePath;
-  if (error_code ec =
-          llvm::sys::fs::createTemporaryFile("tmp", "obj", outFilePath))
-    return ec;
-  std::string outFileArg = ("/out:" + outFilePath).str();
+  static ErrorOr<std::string>
+  convertResourceFileToCOFF(std::unique_ptr<MemoryBuffer> mb) {
+    // Write the resource file to a temporary file.
+    ErrorOr<std::string> inFilePath = writeResToTemporaryFile(std::move(mb));
+    if (!inFilePath)
+      return error_code(inFilePath);
+    llvm::FileRemover inFileRemover(*inFilePath);
+
+    // Create an output file path.
+    SmallString<128> outFilePath;
+    if (error_code ec =
+            llvm::sys::fs::createTemporaryFile("tmp", "obj", outFilePath))
+      return ec;
+    std::string outFileArg = ("/out:" + outFilePath).str();
 
-  // Construct CVTRES.EXE command line and execute it.
-  std::string program = "cvtres.exe";
-  std::string programPath = llvm::sys::FindProgramByName(program);
-  if (programPath.empty()) {
-    llvm::errs() << "Unable to find " << program << " in PATH\n";
-    return llvm::errc::broken_pipe;
-  }
-  std::vector<const char *> args;
-  args.push_back(programPath.c_str());
-  args.push_back("/machine:x86");
-  args.push_back("/readonly");
-  args.push_back("/nologo");
-  args.push_back(outFileArg.c_str());
-  args.push_back(inFilePath->c_str());
-  args.push_back(nullptr);
-
-  DEBUG({
-    for (const char **p = &args[0]; *p; ++p)
-      llvm::dbgs() << *p << " ";
-    llvm::dbgs() << "\n";
-  });
-
-  if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) {
-    llvm::errs() << program << " failed\n";
-    return llvm::errc::broken_pipe;
+    // Construct CVTRES.EXE command line and execute it.
+    std::string program = "cvtres.exe";
+    std::string programPath = llvm::sys::FindProgramByName(program);
+    if (programPath.empty()) {
+      llvm::errs() << "Unable to find " << program << " in PATH\n";
+      return llvm::errc::broken_pipe;
+    }
+    std::vector<const char *> args;
+    args.push_back(programPath.c_str());
+    args.push_back("/machine:x86");
+    args.push_back("/readonly");
+    args.push_back("/nologo");
+    args.push_back(outFileArg.c_str());
+    args.push_back(inFilePath->c_str());
+    args.push_back(nullptr);
+
+    DEBUG({
+      for (const char **p = &args[0]; *p; ++p)
+        llvm::dbgs() << *p << " ";
+      llvm::dbgs() << "\n";
+    });
+
+    if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) {
+      llvm::errs() << program << " failed\n";
+      return llvm::errc::broken_pipe;
+    }
+    return outFilePath.str().str();
   }
-  return outFilePath.str().str();
-}
+};
 
-// Convert .res file to .coff file and then parse it. Resource file is a file
-// containing various types of data, such as icons, translation texts,
-// etc. "cvtres.exe" command reads an RC file to create a COFF file which
-// encapsulates resource data into rsrc$N sections, where N is an integer.
-//
-// The linker is not capable to handle RC files directly. Instead, it runs
-// cvtres.exe on RC files and then then link its outputs.
-error_code ReaderCOFF::convertAndParseResourceFile(
-    std::unique_ptr<MemoryBuffer> &mb,
-    std::vector<std::unique_ptr<File> > &result) const {
-  // Convert an RC to a COFF
-  ErrorOr<std::string> coffFilePath = convertResourceFileToCOFF(std::move(mb));
-  if (!coffFilePath)
-    return error_code(coffFilePath);
-  llvm::FileRemover coffFileRemover(*coffFilePath);
-
-  // Read and parse the COFF
-  OwningPtr<MemoryBuffer> opmb;
-  if (error_code ec = MemoryBuffer::getFile(*coffFilePath, opmb))
-    return ec;
-  std::unique_ptr<MemoryBuffer> newmb(opmb.take());
-  return parseCOFFFile(newmb, result);
-}
+class COFFObjectReader : public Reader {
+public:
+  COFFObjectReader(PECOFFLinkingContext &ctx) : _context(ctx) {}
 
-error_code
-ReaderCOFF::parseCOFFFile(std::unique_ptr<MemoryBuffer> &mb,
-                          std::vector<std::unique_ptr<File> > &result) const {
-  // Parse the memory buffer as PECOFF file.
-  error_code ec;
-  std::unique_ptr<FileCOFF> file(
-      new FileCOFF(_PECOFFLinkingContext, std::move(mb), ec));
-  if (ec)
-    return ec;
+  virtual bool canParse(file_magic magic, StringRef ext,
+                        const MemoryBuffer &) const {
+    return (magic == llvm::sys::fs::file_magic::coff_object);
+  }
 
-  DEBUG({
-    llvm::dbgs() << "Defined atoms:\n";
-    for (const auto &atom : file->defined()) {
-      llvm::dbgs() << "  " << atom->name() << "\n";
-      for (const Reference *ref : *atom)
-        llvm::dbgs() << "    @" << ref->offsetInAtom() << " -> "
-                     << ref->target()->name() << "\n";
-    }
-  });
-
-  // Interpret .drectve section if the section has contents.
-  StringRef directives = file->getLinkerDirectives();
-  if (!directives.empty())
-    if (error_code ec = handleDirectiveSection(directives))
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry &registry,
+            std::vector<std::unique_ptr<File> > &result) const {
+    // Parse the memory buffer as PECOFF file.
+    error_code ec;
+    std::unique_ptr<FileCOFF> file(
+        new FileCOFF(std::move(mb), _context.alternateNames(), ec));
+    if (ec)
       return ec;
 
-  result.push_back(std::move(file));
-  return error_code::success();
-}
+    // Interpret .drectve section if the section has contents.
+    StringRef directives = file->getLinkerDirectives();
+    if (!directives.empty())
+      if (error_code ec2 = handleDirectiveSection(registry, directives))
+        return ec2;
+
+    result.push_back(std::move(file));
+    return error_code::success();
+  }
+
+private:
+  // Interpret the contents of .drectve section. If exists, the section contains
+  // a string containing command line options. The linker is expected to
+  // interpret the options as if they were given via the command line.
+  //
+  // The section mainly contains /defaultlib (-l in Unix), but can contain any
+  // options as long as they are valid.
+  error_code handleDirectiveSection(const Registry &registry,
+                                    StringRef directives) const {
+    DEBUG(llvm::dbgs() << ".drectve: " << directives << "\n");
+
+    // Split the string into tokens, as the shell would do for argv.
+    SmallVector<const char *, 16> tokens;
+    tokens.push_back("link"); // argv[0] is the command name. Will be ignored.
+    llvm::cl::TokenizeWindowsCommandLine(directives, _stringSaver, tokens);
+    tokens.push_back(nullptr);
+
+    // Calls the command line parser to interpret the token string as if they
+    // were given via the command line.
+    int argc = tokens.size() - 1;
+    const char **argv = &tokens[0];
+    std::string errorMessage;
+    llvm::raw_string_ostream stream(errorMessage);
+    bool parseFailed = !WinLinkDriver::parse(argc, argv, _context, stream,
+                                             /*isDirective*/ true);
+    stream.flush();
+    // Print error message if error.
+    if (parseFailed) {
+      llvm::errs() << "Failed to parse '" << directives << "'\n"
+                   << "Reason: " << errorMessage;
+      return make_error_code(llvm::object::object_error::invalid_file_type);
+    }
+    if (!errorMessage.empty()) {
+      llvm::errs() << "lld warning: " << errorMessage << "\n";
+    }
+    return error_code::success();
+  }
+
+  PECOFFLinkingContext &_context;
+  mutable BumpPtrStringSaver _stringSaver;
+};
+
+using namespace llvm::COFF;
+
+const Registry::KindStrings kindStringsI386[] = {
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_ABSOLUTE),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR16),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_REL16),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR32),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR32NB),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SEG12),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECTION),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECREL),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_TOKEN),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECREL7),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_REL32), LLD_KIND_STRING_END
+};
+
+const Registry::KindStrings kindStringsAMD64[] = {
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ABSOLUTE),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR64),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR32),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR32NB),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_1),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_2),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_3),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_4),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_5),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECTION),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECREL),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECREL7),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_TOKEN),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SREL32),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_PAIR),
+  LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SSPAN32), LLD_KIND_STRING_END
+};
 
 } // end namespace anonymous
 
 namespace lld {
-std::unique_ptr<Reader> createReaderPECOFF(PECOFFLinkingContext &context) {
-  return std::unique_ptr<Reader>(new ReaderCOFF(context));
+
+void Registry::addSupportCOFFObjects(PECOFFLinkingContext &ctx) {
+  add(std::unique_ptr<Reader>(new COFFObjectReader(ctx)));
+  addKindTable(Reference::KindNamespace::COFF, Reference::KindArch::x86,
+               kindStringsI386);
+  addKindTable(Reference::KindNamespace::COFF, Reference::KindArch::x86_64,
+               kindStringsAMD64);
 }
+
+void Registry::addSupportWindowsResourceFiles() {
+  add(std::unique_ptr<Reader>(new ResourceFileReader()));
+}
+
 }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp Thu Dec 19 15:58:00 2013
@@ -125,6 +125,7 @@
 #include "lld/Core/File.h"
 #include "lld/Core/Error.h"
 #include "lld/Core/SharedLibraryAtom.h"
+#include "lld/ReaderWriter/PECOFFLinkingContext.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Object/COFF.h"
@@ -143,16 +144,15 @@
 #include <cstring>
 
 using namespace lld;
+using namespace lld::pecoff;
 using namespace llvm;
 
 namespace lld {
-namespace pecoff {
 
 namespace {
 
-uint8_t FuncAtomContent[] = {
-  0xff, 0x25, 0x00, 0x00, 0x00, 0x00,  // jmp *0x0
-  0xcc, 0xcc                           // int 3; int 3
+uint8_t FuncAtomContent[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *0x0
+                              0xcc, 0xcc // int 3; int 3
 };
 
 /// The defined atom for jump table.
@@ -174,15 +174,14 @@ public:
 
 class FileImportLibrary : public File {
 public:
-  FileImportLibrary(const LinkingContext &context,
-                    std::unique_ptr<MemoryBuffer> mb, error_code &ec)
-      : File(mb->getBufferIdentifier(), kindSharedLibrary), _context(context) {
+  FileImportLibrary(std::unique_ptr<MemoryBuffer> mb, error_code &ec)
+      : File(mb->getBufferIdentifier(), kindSharedLibrary) {
     const char *buf = mb->getBufferStart();
     const char *end = mb->getBufferEnd();
 
     // The size of the string that follows the header.
     uint32_t dataSize = *reinterpret_cast<const support::ulittle32_t *>(
-                             buf + offsetof(COFF::ImportHeader, SizeOfData));
+        buf + offsetof(COFF::ImportHeader, SizeOfData));
 
     // Check if the total size is valid.
     if (end - buf != sizeof(COFF::ImportHeader) + dataSize) {
@@ -191,14 +190,14 @@ public:
     }
 
     uint16_t hint = *reinterpret_cast<const support::ulittle16_t *>(
-                         buf + offsetof(COFF::ImportHeader, OrdinalHint));
+        buf + offsetof(COFF::ImportHeader, OrdinalHint));
     StringRef symbolName(buf + sizeof(COFF::ImportHeader));
     StringRef dllName(buf + sizeof(COFF::ImportHeader) + symbolName.size() + 1);
 
     // TypeInfo is a bitfield. The least significant 2 bits are import
     // type, followed by 3 bit import name type.
     uint16_t typeInfo = *reinterpret_cast<const support::ulittle16_t *>(
-                             buf + offsetof(COFF::ImportHeader, TypeInfo));
+        buf + offsetof(COFF::ImportHeader, TypeInfo));
     int type = typeInfo & 0x3;
     int nameType = (typeInfo >> 2) & 0x7;
 
@@ -231,8 +230,6 @@ public:
     return _noAbsoluteAtoms;
   }
 
-  virtual const LinkingContext &getLinkingContext() const { return _context; }
-
 private:
   const COFFSharedLibraryAtom *addSharedLibraryAtom(uint16_t hint,
                                                     StringRef symbolName,
@@ -256,7 +253,6 @@ private:
 
   atom_collection_vector<DefinedAtom> _definedAtoms;
   atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
-  const LinkingContext &_context;
   mutable llvm::BumpPtrAllocator _alloc;
 
   // Does the same thing as StringRef::ltrim() but removes at most one
@@ -294,8 +290,32 @@ private:
   }
 };
 
+class COFFImportLibraryReader : public Reader {
+public:
+  virtual bool canParse(file_magic magic, StringRef,
+                        const MemoryBuffer &mb) const {
+    if (mb.getBufferSize() < sizeof(COFF::ImportHeader))
+      return false;
+    return (magic == llvm::sys::fs::file_magic::coff_import_library);
+  }
+
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File> > &result) const {
+    error_code ec;
+    auto file = std::unique_ptr<File>(new FileImportLibrary(std::move(mb), ec));
+    if (ec)
+      return ec;
+    result.push_back(std::move(file));
+    return error_code::success();
+  }
+
+};
+
 } // end anonymous namespace
 
+namespace pecoff {
+
 error_code parseCOFFImportLibrary(const LinkingContext &targetInfo,
                                   std::unique_ptr<MemoryBuffer> &mb,
                                   std::vector<std::unique_ptr<File> > &result) {
@@ -308,8 +328,7 @@ error_code parseCOFFImportLibrary(const
     return make_error_code(NativeReaderError::unknown_file_format);
 
   error_code ec;
-  auto file = std::unique_ptr<File>(
-      new FileImportLibrary(targetInfo, std::move(mb), ec));
+  auto file = std::unique_ptr<File>(new FileImportLibrary(std::move(mb), ec));
   if (ec)
     return ec;
   result.push_back(std::move(file));
@@ -317,4 +336,9 @@ error_code parseCOFFImportLibrary(const
 }
 
 } // end namespace pecoff
+
+void Registry::addSupportCOFFImportLibraries() {
+  add(std::unique_ptr<Reader>(new COFFImportLibraryReader()));
+}
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Thu Dec 19 15:58:00 2013
@@ -72,7 +72,7 @@ public:
   };
 
   explicit Chunk(Kind kind) : _kind(kind), _size(0) {}
-  virtual ~Chunk() {};
+  virtual ~Chunk() {}
   virtual void write(uint8_t *buffer) = 0;
   virtual uint64_t size() const { return _size; }
   virtual uint64_t align() const { return 1; }
@@ -106,7 +106,7 @@ public:
       : HeaderChunk(), _context(ctx) {
     // Minimum size of DOS stub is 64 bytes. The next block (PE header) needs to
     // be aligned on 8 byte boundary.
-    size_t size = std::max(_context.getDosStub().size(), (size_t)64);
+    size_t size = std::max(_context.getDosStub().size(), (size_t) 64);
     _size = llvm::RoundUpToAlignment(size, 8);
   }
 
@@ -303,8 +303,8 @@ private:
 
   // Create the content of a relocation block.
   std::vector<uint8_t>
-  createBaseRelocBlock(uint64_t pageAddr,
-                       const std::vector<uint16_t> &offsets) const;
+      createBaseRelocBlock(uint64_t pageAddr,
+                           const std::vector<uint16_t> &offsets) const;
 
   std::vector<uint8_t> _contents;
 };
@@ -454,10 +454,9 @@ void AtomChunk::applyRelocations(uint8_t
   for (const auto *layout : _atomLayouts) {
     const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
     for (const Reference *ref : *atom) {
-      // Skip if this reference is not for relocation.
-      if (ref->kind() < lld::Reference::kindTargetLow)
+      // Skip if this reference is not for COFF relocation.
+      if (ref->kindNamespace() != Reference::KindNamespace::COFF)
         continue;
-
       auto relocSite32 = reinterpret_cast<ulittle32_t *>(
           buffer + layout->_fileOffset + ref->offsetInAtom());
       auto relocSite16 = reinterpret_cast<ulittle16_t *>(relocSite32);
@@ -465,8 +464,7 @@ void AtomChunk::applyRelocations(uint8_t
       // Also account for whatever offset is already stored at the relocation
       // site.
       targetAddr += *relocSite32;
-
-      switch (ref->kind()) {
+      switch (ref->kindValue()) {
       case llvm::COFF::IMAGE_REL_I386_ABSOLUTE:
         // This relocation is no-op.
         break;
@@ -539,7 +537,8 @@ void AtomChunk::addBaseRelocations(std::
   for (const auto *layout : _atomLayouts) {
     const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
     for (const Reference *ref : *atom)
-      if (ref->kind() == llvm::COFF::IMAGE_REL_I386_DIR32)
+      if ((ref->kindNamespace() == Reference::KindNamespace::COFF) &&
+          (ref->kindValue() == llvm::COFF::IMAGE_REL_I386_DIR32))
         relocSites.push_back(layout->_virtualAddr + ref->offsetInAtom());
   }
 }
@@ -753,7 +752,7 @@ private:
   void setImageSizeOnDisk();
   void setAddressOfEntryPoint(AtomChunk *text, PEHeaderChunk *peHeader);
   uint64_t
-  calcSectionSize(llvm::COFF::SectionCharacteristics sectionType) const;
+      calcSectionSize(llvm::COFF::SectionCharacteristics sectionType) const;
 
   uint64_t calcSizeOfInitializedData() const {
     return calcSectionSize(llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA);

Modified: lld/trunk/lib/ReaderWriter/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Reader.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Reader.cpp Thu Dec 19 15:58:00 2013
@@ -11,10 +11,94 @@
 
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/system_error.h"
 
 namespace lld {
+
 Reader::~Reader() {
 }
+
+void Registry::add(std::unique_ptr<Reader> reader) {
+  _readers.push_back(std::move(reader));
+}
+
+error_code 
+Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                          std::vector<std::unique_ptr<File>> &result) const {
+  // Get file type.
+  StringRef content(mb->getBufferStart(), mb->getBufferSize());
+  llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
+  // Get file extension.
+  StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
+
+  // Ask each registered reader if it can handle this file type or extension.
+  for (const std::unique_ptr<Reader> &reader : _readers) {
+    if (reader->canParse(fileType, extension, *mb))
+      return reader->parseFile(mb, *this, result);
+  }
+  
+  // No Reader could parse this file.     
+  return llvm::make_error_code(llvm::errc::executable_format_error);
+}
+
+static const Registry::KindStrings kindStrings[] = {
+  { Reference::kindInGroup,       "in-group" },
+  { Reference::kindLayoutAfter,   "layout-after" },
+  { Reference::kindLayoutBefore,  "layout-before" },
+  LLD_KIND_STRING_END
+};
+
+Registry::Registry() {
+  addKindTable(Reference::KindNamespace::all, Reference::KindArch::all, 
+                                                                  kindStrings);
+}
+
+void Registry::addKindTable(Reference::KindNamespace ns, 
+                            Reference::KindArch arch,
+                            const KindStrings array[]) {
+  KindEntry entry = {ns, arch, array};
+  _kindEntries.push_back(entry);
+}
+
+bool Registry::referenceKindFromString(StringRef inputStr, 
+                                       Reference::KindNamespace &ns,
+                                       Reference::KindArch &arch, 
+                                       Reference::KindValue &value) const {
+  for (const KindEntry &entry : _kindEntries) {
+    for (const KindStrings *pair=entry.array; !pair->name.empty(); ++pair) {
+      if (!inputStr.equals(pair->name))
+        continue;
+      ns = entry.ns;
+      arch = entry.arch;
+      value = pair->value;
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool Registry::referenceKindToString(Reference::KindNamespace ns, 
+                                     Reference::KindArch arch, 
+                                     Reference::KindValue value, 
+                                     StringRef &str) const {
+  for (const KindEntry &entry : _kindEntries) {
+    if (entry.ns != ns)
+      continue;
+    if (entry.arch != arch)
+      continue;
+    for (const KindStrings *pair=entry.array; !pair->name.empty(); ++pair) {
+      if (pair->value != value)
+        continue;
+      str = pair->name;
+      return true;
+    }
+  }
+  return false;
+}
+
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Thu Dec 19 15:58:00 2013
@@ -10,6 +10,7 @@
 #include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/Simple.h"
 #include "lld/ReaderWriter/Writer.h"
+#include "lld/ReaderWriter/YamlContext.h"
 
 #include "lld/Core/ArchiveLibraryFile.h"
 #include "lld/Core/DefinedAtom.h"
@@ -46,18 +47,6 @@ using namespace lld;
 /// how the mapping is done to and from YAML.
 
 namespace {
-/// Most of the traits are context-free and always do the same transformation.
-/// But, there are some traits that need some contextual information to properly
-/// do their transform.  This struct is available via io.getContext() and
-/// supplies contextual information.
-class ContextInfo {
-public:
-  ContextInfo(const LinkingContext &context)
-      : _currentFile(nullptr), _context(context) {}
-
-  lld::File *_currentFile;
-  const LinkingContext &_context;
-};
 
 /// Used when writing yaml files.
 /// In most cases, atoms names are unambiguous, so references can just
@@ -260,9 +249,13 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, Implic
 // more readable than just true/false.
 LLVM_YAML_STRONG_TYPEDEF(bool, ShlibCanBeNull)
 
-// lld::Reference::Kind is a typedef of int32.  We need a stronger
-// type to make template matching work, so invent RefKind.
-LLVM_YAML_STRONG_TYPEDEF(lld::Reference::Kind, RefKind)
+// lld::Reference::Kind is a tuple of <namespace, arch, value>.
+// For yaml, we just want one string that encapsulates the tuple.
+struct RefKind {
+  Reference::KindNamespace ns;
+  Reference::KindArch      arch;
+  uint16_t                 value;
+};
 
 } // namespace anon
 
@@ -276,49 +269,26 @@ namespace yaml {
 
 // This is a custom formatter for RefKind
 template <> struct ScalarTraits<RefKind> {
-  static void output(const RefKind &value, void *ctxt, raw_ostream &out) {
+  static void output(const RefKind &kind, void *ctxt, raw_ostream &out) {
     assert(ctxt != nullptr);
-    ContextInfo *info = reinterpret_cast<ContextInfo *>(ctxt);
-    switch (value) {
-    case lld::Reference::kindLayoutAfter:
-      out << "layout-after";
-      break;
-    case lld::Reference::kindLayoutBefore:
-      out << "layout-before";
-      break;
-    case lld::Reference::kindInGroup:
-      out << "in-group";
-      break;
-    default:
-      if (auto relocStr = info->_context.stringFromRelocKind(value))
-        out << *relocStr;
-      else
-        out << "<unknown>";
-      break;
-    }
+    YamlContext *info = reinterpret_cast<YamlContext *>(ctxt);
+    assert(info->_registry);
+    StringRef str;
+    if (info->_registry->referenceKindToString(kind.ns, kind.arch, kind.value, 
+                                                                           str)) 
+      out << str;
+    else
+      out << (int)(kind.ns) << "-" << (int)(kind.arch) << "-" << kind.value;
   }
 
-  static StringRef input(StringRef scalar, void *ctxt, RefKind &value) {
+  static StringRef input(StringRef scalar, void *ctxt, RefKind &kind) {
     assert(ctxt != nullptr);
-    ContextInfo *info = reinterpret_cast<ContextInfo *>(ctxt);
-    auto relocKind = info->_context.relocKindFromString(scalar);
-    if (!relocKind) {
-      if (scalar.equals("layout-after")) {
-        value = lld::Reference::kindLayoutAfter;
-        return StringRef();
-      }
-      if (scalar.equals("layout-before")) {
-        value = lld::Reference::kindLayoutBefore;
-        return StringRef();
-      }
-      if (scalar.equals("in-group")) {
-        value = lld::Reference::kindInGroup;
-        return StringRef();
-      }
-      return "Invalid relocation kind";
-    }
-    value = *relocKind;
-    return StringRef();
+    YamlContext *info = reinterpret_cast<YamlContext *>(ctxt);
+    assert(info->_registry);
+    if (info->_registry->referenceKindFromString(scalar, kind.ns, kind.arch, 
+                                                                  kind.value)) 
+      return StringRef();
+    return StringRef("unknown reference kind");
   }
 };
 
@@ -595,12 +565,9 @@ template <> struct MappingTraits<const l
   class NormArchiveFile : public lld::ArchiveLibraryFile {
   public:
     NormArchiveFile(IO &io)
-        : ArchiveLibraryFile(((ContextInfo *)io.getContext())->_context, ""),
-          _path() {}
+        : ArchiveLibraryFile(""), _path() {}
     NormArchiveFile(IO &io, const lld::File *file)
-        : ArchiveLibraryFile(((ContextInfo *)io.getContext())->_context,
-                             file->path()),
-          _path(file->path()) {
+        : ArchiveLibraryFile(file->path()), _path(file->path()) {
       // If we want to support writing archives, this constructor would
       // need to populate _members.
     }
@@ -639,15 +606,20 @@ template <> struct MappingTraits<const l
       return nullptr;
     }
 
+    virtual error_code parseAllMembers(
+                          std::vector<std::unique_ptr<File>> &result) const {
+      return error_code::success();
+    }
+    
     StringRef _path;
     std::vector<ArchMember> _members;
   };
 
   class NormalizedFile : public lld::File {
   public:
-    NormalizedFile(IO &io) : File("", kindObject), _IO(io), _rnb(nullptr) {}
+    NormalizedFile(IO &io) : File("", kindObject), _io(io), _rnb(nullptr) {}
     NormalizedFile(IO &io, const lld::File *file)
-        : File(file->path(), kindObject), _IO(io),
+        : File(file->path(), kindObject), _io(io),
           _rnb(new RefNameBuilder(*file)), _path(file->path()) {
       for (const lld::DefinedAtom *a : file->defined())
         _definedAtoms.push_back(a);
@@ -674,10 +646,6 @@ template <> struct MappingTraits<const l
       return _absoluteAtoms;
     }
 
-    virtual const LinkingContext &getLinkingContext() const {
-      return ((ContextInfo *)_IO.getContext())->_context;
-    }
-
     // Allocate a new copy of this string and keep track of allocations
     // in _stringCopies, so they can be freed when File is destroyed.
     StringRef copyString(StringRef str) {
@@ -691,7 +659,7 @@ template <> struct MappingTraits<const l
       return r;
     }
 
-    IO &_IO;
+    IO &_io;
     RefNameBuilder *_rnb;
     StringRef _path;
     AtomList<lld::DefinedAtom> _definedAtoms;
@@ -706,7 +674,6 @@ template <> struct MappingTraits<const l
     FileKinds kind = fileKindObjectAtoms;
     // If reading, peek ahead to see what kind of file this is.
     io.mapOptional("kind", kind, fileKindObjectAtoms);
-    //
     switch (kind) {
     case fileKindObjectAtoms:
       mappingAtoms(io, file);
@@ -725,9 +692,9 @@ template <> struct MappingTraits<const l
 
   static void mappingAtoms(IO &io, const lld::File *&file) {
     MappingNormalizationHeap<NormalizedFile, const lld::File *> keys(io, file);
-    ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+    YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
     assert(info != nullptr);
-    info->_currentFile = keys.operator->();
+    info->_file = keys.operator->();
 
     io.mapOptional("path", keys->_path);
     io.mapOptional("defined-atoms", keys->_definedAtoms);
@@ -750,19 +717,26 @@ template <> struct MappingTraits<const l
   class NormalizedReference : public lld::Reference {
   public:
     NormalizedReference(IO &io)
-        : _target(nullptr), _targetName(), _offset(0), _addend(0) {}
+        : lld::Reference(lld::Reference::KindNamespace::all, 
+                         lld::Reference::KindArch::all, 0),
+         _target(nullptr), _targetName(), _offset(0), _addend(0) {}
 
     NormalizedReference(IO &io, const lld::Reference *ref)
-        : _target(nullptr), _targetName(targetName(io, ref)),
-          _offset(ref->offsetInAtom()), _addend(ref->addend()),
-          _mappedKind(ref->kind()) {}
+        : lld::Reference(ref->kindNamespace(), ref->kindArch(), 
+                                              ref->kindValue()),
+          _target(nullptr), _targetName(targetName(io, ref)),
+          _offset(ref->offsetInAtom()), _addend(ref->addend()) {
+      _mappedKind.ns = ref->kindNamespace();
+      _mappedKind.arch = ref->kindArch();
+      _mappedKind.value = ref->kindValue();
+    }
 
     const lld::Reference *denormalize(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       if (!_targetName.empty())
         _targetName = f->copyString(_targetName);
       DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
@@ -770,7 +744,9 @@ template <> struct MappingTraits<const l
                                         << _targetName << "' ("
                                         << (void *)_targetName.data() << ", "
                                         << _targetName.size() << ")\n");
-      setKind(_mappedKind);
+      setKindNamespace(_mappedKind.ns);
+      setKindArch(_mappedKind.arch);
+      setKindValue(_mappedKind.value);
       return this;
     }
     void bind(const RefNameResolver &);
@@ -830,11 +806,11 @@ template <> struct MappingTraits<const l
         _content.push_back(x);
     }
     const lld::DefinedAtom *denormalize(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       if (!_name.empty())
         _name = f->copyString(_name);
       if (!_refName.empty())
@@ -850,10 +826,10 @@ template <> struct MappingTraits<const l
     void bind(const RefNameResolver &);
     // Extract current File object from YAML I/O parsing context
     const lld::File &fileFromContext(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
-      assert(info->_currentFile != nullptr);
-      return *info->_currentFile;
+      assert(info->_file != nullptr);
+      return *info->_file;
     }
 
     virtual const lld::File &file() const { return _file; }
@@ -927,10 +903,10 @@ template <> struct MappingTraits<const l
     if (io.outputting()) {
       // If writing YAML, check if atom needs a ref-name.
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       assert(f);
       assert(f->_rnb);
       if (f->_rnb->hasRefName(atom)) {
@@ -980,11 +956,11 @@ template <> struct MappingTraits<const l
           _canBeNull(atom->canBeNull()), _fallback(atom->fallback()) {}
 
     const lld::UndefinedAtom *denormalize(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       if (!_name.empty())
         _name = f->copyString(_name);
 
@@ -997,10 +973,10 @@ template <> struct MappingTraits<const l
 
     // Extract current File object from YAML I/O parsing context
     const lld::File &fileFromContext(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
-      assert(info->_currentFile != nullptr);
-      return *info->_currentFile;
+      assert(info->_file != nullptr);
+      return *info->_file;
     }
 
     virtual const lld::File &file() const { return _file; }
@@ -1040,11 +1016,11 @@ template <> struct MappingTraits<const l
           _type(atom->type()), _size(atom->size()) {}
 
     const lld::SharedLibraryAtom *denormalize(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       if (!_name.empty())
         _name = f->copyString(_name);
       if (!_loadName.empty())
@@ -1059,10 +1035,10 @@ template <> struct MappingTraits<const l
 
     // Extract current File object from YAML I/O parsing context
     const lld::File &fileFromContext(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
-      assert(info->_currentFile != nullptr);
-      return *info->_currentFile;
+      assert(info->_file != nullptr);
+      return *info->_file;
     }
 
     virtual const lld::File &file() const { return _file; }
@@ -1104,11 +1080,11 @@ template <> struct MappingTraits<const l
         : _file(fileFromContext(io)), _name(atom->name()),
           _scope(atom->scope()), _value(atom->value()) {}
     const lld::AbsoluteAtom *denormalize(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       if (!_name.empty())
         _name = f->copyString(_name);
 
@@ -1120,10 +1096,10 @@ template <> struct MappingTraits<const l
     }
     // Extract current File object from YAML I/O parsing context
     const lld::File &fileFromContext(IO &io) {
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
-      assert(info->_currentFile != nullptr);
-      return *info->_currentFile;
+      assert(info->_file != nullptr);
+      return *info->_file;
     }
 
     virtual const lld::File &file() const { return _file; }
@@ -1144,10 +1120,10 @@ template <> struct MappingTraits<const l
 
     if (io.outputting()) {
       typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
-      ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+      YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
       assert(info != nullptr);
       NormalizedFile *f =
-          reinterpret_cast<NormalizedFile *>(info->_currentFile);
+          reinterpret_cast<NormalizedFile *>(info->_file);
       assert(f);
       assert(f->_rnb);
       if (f->_rnb->hasRefName(atom)) {
@@ -1226,10 +1202,10 @@ MappingTraits<const lld::Reference *>::N
     IO &io, const lld::Reference *ref) {
   if (ref->target() == nullptr)
     return StringRef();
-  ContextInfo *info = reinterpret_cast<ContextInfo *>(io.getContext());
+  YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
   assert(info != nullptr);
   typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
-  NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_currentFile);
+  NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
   RefNameBuilder *rnb = f->_rnb;
   if (rnb->hasRefName(ref->target()))
     return rnb->refName(ref->target());
@@ -1251,8 +1227,10 @@ public:
       return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
 
     // Create yaml Output writer, using yaml options for context.
-    ContextInfo context(_context);
-    llvm::yaml::Output yout(out, &context);
+    YamlContext yamlContext;
+    yamlContext._linkingContext = &_context;
+    yamlContext._registry = &_context.registry();
+    llvm::yaml::Output yout(out, &yamlContext);
 
     // Write yaml output.
     const lld::File *fileRef = &file;
@@ -1265,12 +1243,21 @@ private:
   const LinkingContext &_context;
 };
 
-class ReaderYAML : public Reader {
+} // end namespace yaml
+
+namespace {
+
+class YAMLReader : public Reader {
 public:
-  ReaderYAML(const LinkingContext &context) : Reader(context) {}
+  YAMLReader(const Registry &registry) : _registry(registry) { }
 
-  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
-                       std::vector<std::unique_ptr<File> > &result) const {
+  virtual bool canParse(file_magic, StringRef ext, const MemoryBuffer&) const {
+    return (ext.equals(".objtxt") || ext.equals(".yaml"));
+  }
+  
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
+            std::vector<std::unique_ptr<File>> &result) const {
     // Note: we do not take ownership of the MemoryBuffer.  That is
     // because yaml may produce multiple File objects, so there is no
     // *one* File to take ownership.  Therefore, the yaml File objects
@@ -1278,15 +1265,16 @@ public:
     // Otherwise the strings will become invalid when this MemoryBuffer
     // is deallocated.
 
-    // Create YAML Input parser.
-    ContextInfo context(_context);
-    llvm::yaml::Input yin(mb->getBuffer(), &context);
+    // Create YAML Input Reader.
+    YamlContext yamlContext;
+    yamlContext._registry = &_registry;
+    llvm::yaml::Input yin(mb->getBuffer(), &yamlContext);
 
     // Fill vector with File objects created by parsing yaml.
     std::vector<const lld::File *> createdFiles;
     yin >> createdFiles;
 
-    // Quit now if there were parsing errors.
+    // Error out now if there were parsing errors.
     if (yin.error())
       return make_error_code(lld::YamlReaderError::illegal_value);
 
@@ -1297,14 +1285,20 @@ public:
     }
     return make_error_code(lld::YamlReaderError::success);
   }
-};
-} // end namespace yaml
+private:
+  const Registry &_registry;
+};  
+
+
+} // anonymous namespace
+
+void Registry::addSupportYamlFiles() {
+  add(std::unique_ptr<Reader>(new YAMLReader(*this)));
+}
+
 
 std::unique_ptr<Writer> createWriterYAML(const LinkingContext &context) {
   return std::unique_ptr<Writer>(new lld::yaml::Writer(context));
 }
 
-std::unique_ptr<Reader> createReaderYAML(const LinkingContext &context) {
-  return std::unique_ptr<Reader>(new lld::yaml::ReaderYAML(context));
-}
 } // end namespace lld

Modified: lld/trunk/test/darwin/hello-world.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/darwin/hello-world.objtxt?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/test/darwin/hello-world.objtxt (original)
+++ lld/trunk/test/darwin/hello-world.objtxt Thu Dec 19 15:58:00 2013
@@ -4,7 +4,7 @@
 # Test that hello-world can be linked into a mach-o executable
 #
 
----
+--- !atoms
 defined-atoms:
     - name:              _main
       type:              code
@@ -14,10 +14,10 @@ defined-atoms:
                            31, C0, 5D, C3 ]
       references:
       - offset:          7
-        kind:            ripRel32
+        kind:            X86_64_RELOC_SIGNED
         target:          LC1
       - offset:          12
-        kind:            branch32
+        kind:            X86_64_RELOC_BRANCH
         target:          _printf
 
     - ref-name:          LC1

Modified: lld/trunk/test/elf/reloc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/reloc.test?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/test/elf/reloc.test (original)
+++ lld/trunk/test/elf/reloc.test Thu Dec 19 15:58:00 2013
@@ -1,4 +1,4 @@
-RUN: lld -flavor gnu -target x86_64 --merge-strings -r --output-filetype=yaml \
+RUN: lld -flavor gnu -target i386 --merge-strings -r --output-filetype=yaml \
 RUN:   %p/Inputs/reloc-test.elf-i386 | FileCheck %s -check-prefix ELF-i386
 
 ELF-i386: defined-atoms:   
@@ -23,10 +23,10 @@ ELF-i386:     alignment:       2^4
 ELF-i386:     section-choice:  custom-required
 ELF-i386:     section-name:    .text.startup
 ELF-i386:     references:      
-ELF-i386:       - kind:            R_X86_64_64
+ELF-i386:       - kind:            R_386_32
 ELF-i386:         offset:          12
 ELF-i386:         target:          [[STRNAMEA]]
-ELF-i386:       - kind:            R_X86_64_PC32
+ELF-i386:       - kind:            R_386_PC32
 ELF-i386:         offset:          17
 ELF-i386:         target:          puts
 ELF-i386:         addend:          252

Modified: lld/trunk/unittests/DriverTests/InputGraphTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/InputGraphTest.cpp?rev=197727&r1=197726&r2=197727&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/InputGraphTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/InputGraphTest.cpp Thu Dec 19 15:58:00 2013
@@ -26,15 +26,6 @@ namespace {
 
 class MyLinkingContext : public LinkingContext {
 public:
-  virtual Reader &getDefaultReader() const { return *_yamlReader; }
-
-  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const {
-    return make_error_code(YamlReaderError::illegal_value);
-  }
-
-  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind k) const {
-    return make_error_code(YamlReaderError::illegal_value);
-  }
 
   virtual Writer &writer() const { llvm_unreachable("no writer!"); }
 
@@ -126,7 +117,7 @@ private:
 class MyObjFile : public SimpleFile {
 public:
   MyObjFile(LinkingContext &context, StringRef path)
-      : SimpleFile(context, path) {}
+      : SimpleFile(path) {}
 };
 
 class InputGraphTest : public testing::Test {





More information about the llvm-commits mailing list