Move everything over to TargetInfo.

I really would have liked to split this patch up, but it would greatly
complicate the lld-core and lld drivers having to deal with both
{Reader,Writer}Option and TargetInfo.

llvm-svn: 173217
diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
index aa3e54c..b12d564 100644
--- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
@@ -5,7 +5,6 @@
   ReaderELF.cpp
   ReferenceKinds.cpp
   WriterELF.cpp
-  WriterOptionsELF.cpp
   X86Reference.cpp
   X86_64Reference.cpp
   )
diff --git a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
index ae859d8..86e61ec 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
@@ -10,6 +10,8 @@
 #ifndef LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
 #define LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
 
+#include "lld/Core/LinkerOptions.h"
+
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
@@ -150,7 +152,7 @@
 
   typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT;
 
-  DefaultELFLayout(const WriterOptionsELF &options) : _options(options) {}
+  DefaultELFLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
 
   /// \brief Return the section order for a input section
   virtual SectionOrder getSectionOrder
@@ -250,7 +252,7 @@
   ELFProgramHeader<ELFT> *_programHeader;
   std::vector<AbsoluteAtomPair> _absoluteAtoms;
   llvm::BumpPtrAllocator _allocator;
-  const WriterOptionsELF _options;
+  const ELFTargetInfo &_targetInfo;
 };
 
 template<class ELFT>
@@ -483,7 +485,7 @@
           segment = segmentInsert.first->second;
         } else {
           segment = new (_allocator.Allocate<Segment<ELFT>>()) Segment<ELFT>(
-            segmentName, getSegmentType(section), _options);
+            segmentName, getSegmentType(section), _targetInfo);
           segmentInsert.first->second = segment;
           _segments.push_back(segment);
         }
@@ -516,7 +518,7 @@
   if (_segments.empty())
     return;
   
-  uint64_t virtualAddress = _options.baseAddress();
+  uint64_t virtualAddress = _targetInfo.getLinkerOptions()._baseAddress;
   
   // HACK: This is a super dirty hack. The elf header and program header are
   // not part of a section, but we need them to be loaded at the base address
@@ -539,7 +541,7 @@
     for (auto &si : _segments) {
       // Align the segment to a page boundary
       fileoffset = llvm::RoundUpToAlignment(fileoffset,
-                                            _options.pageSize());
+                                            _targetInfo.getPageSize());
       si->assignOffsets(fileoffset);
       fileoffset = si->fileOffset() + si->fileSize();
     }
@@ -552,7 +554,7 @@
       (*si)->assignVirtualAddress(address);
       (*si)->setMemSize(address - virtualAddress);
       virtualAddress = llvm::RoundUpToAlignment(address,
-                                                _options.pageSize());
+                                                _targetInfo.getPageSize());
     }
     _programHeader->resetProgramHeaders();
   }
diff --git a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
index 0e329b4..1773137 100644
--- a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
+++ b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
@@ -11,7 +11,7 @@
 #define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H_
 
 #include "lld/Core/range.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -113,7 +113,7 @@
 
   Segment(const StringRef name,
           const ELFLayout::SegmentType type,
-          const WriterOptionsELF &options);
+          const ELFTargetInfo &ti);
 
   /// append a section to a segment
   void append(Section<ELFT> *section);
@@ -168,7 +168,7 @@
 
   inline ELFLayout::SegmentType segmentType() { return _segmentType; }
 
-  inline int pageSize() const { return _options.pageSize(); }
+  inline int pageSize() const { return _targetInfo.getPageSize(); }
 
   inline int64_t atomflags() const { return _atomflags; }
 
@@ -195,19 +195,19 @@
   ELFLayout::SegmentType _segmentType;
   int64_t _flags;
   int64_t _atomflags;
-  const WriterOptionsELF _options;
+  const ELFTargetInfo &_targetInfo;
   llvm::BumpPtrAllocator _segmentAllocate;
 };
 
 template<class ELFT>
 Segment<ELFT>::Segment(const StringRef name,
                        const ELFLayout::SegmentType type,
-                       const WriterOptionsELF &options)
+                       const ELFTargetInfo &ti)
   : Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment)
   , _segmentType(type)
   , _flags(0)
   , _atomflags(0)
-  , _options(options) {
+  , _targetInfo(ti) {
   this->_align2 = 0;
   this->_fsize = 0;
 }
@@ -268,7 +268,7 @@
       SegmentSlice<ELFT> *slice = nullptr;
       // If the newOffset computed is more than a page away, lets create
       // a seperate segment, so that memory is not used up while running
-      if ((newOffset - curOffset) > _options.pageSize()) {
+      if ((newOffset - curOffset) > _targetInfo.getPageSize()) {
         // TODO: use std::find here
         for (auto s : slices()) {
           if (s->startSection() == startSection) {
@@ -286,7 +286,7 @@
         slice->setSize(curSliceSize);
         slice->setAlign(sliceAlign);
         uint64_t newPageOffset =
-          llvm::RoundUpToAlignment(curOffset, _options.pageSize());
+          llvm::RoundUpToAlignment(curOffset, _targetInfo.getPageSize());
         newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());
         curSliceFileOffset = newOffset;
         startSectionIter = endSectionIter;
@@ -332,7 +332,7 @@
 Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
   for (auto slice : slices()) {
     // Align to a page
-    addr = llvm::RoundUpToAlignment(addr, _options.pageSize());
+    addr = llvm::RoundUpToAlignment(addr, _targetInfo.getPageSize());
     // Align to the slice alignment
     addr = llvm::RoundUpToAlignment(addr, slice->align2());
 
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index 9a086f8..5c4cbfc 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -23,6 +23,13 @@
     return llvm::ELF::ET_REL;
   case OutputKind::Shared:
     return llvm::ELF::ET_DYN;
+  case OutputKind::Core:
+    return llvm::ELF::ET_CORE;
+  case OutputKind::SharedStubs:
+  case OutputKind::DebugSymbols:
+  case OutputKind::Bundle:
+  case OutputKind::Preload:
+    break;
   }
   llvm_unreachable("Unhandled OutputKind");
 }
@@ -42,21 +49,21 @@
   }
 }
 
-class X86ELFTargetInfo final : public ELFTargetInfo {
+class X86ELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 };
 
-class HexagonELFTargetInfo final : public ELFTargetInfo {
+class HexagonELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 };
 
-class PPCELFTargetInfo final : public ELFTargetInfo {
+class PPCELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
diff --git a/lld/lib/ReaderWriter/ELF/ELFWriter.h b/lld/lib/ReaderWriter/ELF/ELFWriter.h
index 517d61c..20b83fd 100644
--- a/lld/lib/ReaderWriter/ELF/ELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/ELFWriter.h
@@ -12,7 +12,7 @@
 
 #include "lld/Core/File.h"
 #include "lld/Core/InputFiles.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "ReferenceKinds.h"
 
 namespace lld {
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
index 1820b2c..f0531ac 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
@@ -15,7 +15,7 @@
 #include "lld/Core/UndefinedAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "AtomsELF.h"
 
 namespace lld {
@@ -30,9 +30,7 @@
 class CRuntimeFile : public File {
 public:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-  CRuntimeFile(const WriterOptionsELF &options) 
-    : File("C runtime") 
-  { }
+  CRuntimeFile(const ELFTargetInfo &) : File("C runtime") {}
   
   /// \brief add a global absolute atom
   void addAbsoluteAtom(const StringRef symbolName) {
diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
index 16e53f2..deaf663 100644
--- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
@@ -13,10 +13,12 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/ReaderELF.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
+#include "lld/ReaderWriter/Reader.h"
+
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+#include "lld/ReaderWriter/ReaderArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
@@ -326,12 +328,9 @@
 /// memory buffer for ELF class and bit width
 class ReaderELF : public Reader {
 public:
-  ReaderELF(const ReaderOptionsELF &,
-            ReaderOptionsArchive &readerOptionsArchive)
-      : _readerOptionsArchive(readerOptionsArchive),
-        _readerArchive(_readerOptionsArchive) {
-    _readerOptionsArchive.setReader(this);
-  }
+  ReaderELF(const TargetInfo & ti, std::function<ReaderFunc> read)
+      : Reader(ti),
+        _readerArchive(ti, read) {}
 
   error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
                        std::vector<std::unique_ptr<File>> &result) {
@@ -411,18 +410,13 @@
   }
 
 private:
-  ReaderOptionsArchive &_readerOptionsArchive;
   ReaderArchive _readerArchive;
 };
 } // end anon namespace.
 
 namespace lld {
-ReaderOptionsELF::ReaderOptionsELF() {}
-
-ReaderOptionsELF::~ReaderOptionsELF() {}
-
-Reader *createReaderELF(const ReaderOptionsELF &options,
-                        ReaderOptionsArchive &optionsArchive) {
-  return new ReaderELF(options, optionsArchive);
+std::unique_ptr<Reader> createReaderELF(const TargetInfo & ti,
+                                        std::function<ReaderFunc> read) {
+  return std::unique_ptr<Reader>(new ReaderELF(ti, std::move(read)));
 }
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
index 083e843..769895a 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
@@ -11,29 +11,30 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
 
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ELF.h"
 
 namespace lld {
 namespace elf {
-KindHandler::KindHandler() {
-}
+KindHandler::KindHandler() {}
 
-KindHandler::~KindHandler() {
-}
+KindHandler::~KindHandler() {}
 
 std::unique_ptr<KindHandler>
-KindHandler::makeHandler(uint16_t arch, llvm::support::endianness endian) {
+KindHandler::makeHandler(llvm::Triple::ArchType arch, bool isLittleEndian) {
   switch(arch) {
-  case llvm::ELF::EM_HEXAGON:
+  case llvm::Triple::hexagon:
     return std::unique_ptr<KindHandler>(new HexagonKindHandler());
-  case llvm::ELF::EM_386:
+  case llvm::Triple::x86:
     return std::unique_ptr<KindHandler>(new X86KindHandler());
-  case llvm::ELF::EM_X86_64:
+  case llvm::Triple::x86_64:
     return std::unique_ptr<KindHandler>(new X86_64KindHandler());
-  case llvm::ELF::EM_PPC:
-    return std::unique_ptr<KindHandler>(new PPCKindHandler(endian));
+  case llvm::Triple::ppc:
+    return std::unique_ptr<KindHandler>(
+        new PPCKindHandler(isLittleEndian ? llvm::support::little
+                                          : llvm::support::big));
   default:
     llvm_unreachable("arch not supported");
   }
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
index faa4299..45f6cae 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
@@ -9,9 +9,12 @@
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
 
 #include <functional>
 #include <map>
@@ -32,8 +35,8 @@
 public:
   typedef Reference::Kind Kind;
 
-  static std::unique_ptr<KindHandler> makeHandler(uint16_t arch,
-                                      llvm::support::endianness endian);
+  static std::unique_ptr<KindHandler> makeHandler(llvm::Triple::ArchType arch,
+                                                  bool isLittleEndian);
   virtual             ~KindHandler();
   virtual Kind        stringToKind(StringRef str) = 0;
   virtual StringRef   kindToString(Kind) = 0;
diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
index d9be025..73bb6bb 100644
--- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
 #include "DefaultELFLayout.h"
 #include "ExecutableAtoms.h"
 
@@ -26,7 +28,7 @@
   typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
   typedef Elf_Sym_Impl<ELFT> Elf_Sym;
 
-  ELFExecutableWriter(const WriterOptionsELF &options);
+  ELFExecutableWriter(const ELFTargetInfo &ti);
 
 private:
   // build the sections that need to be created
@@ -49,7 +51,7 @@
 
   void createDefaultSections();
 
-  const WriterOptionsELF &_options;
+  const ELFTargetInfo &_targetInfo;
 
   typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
   std::unique_ptr<KindHandler> _referenceKindHandler;
@@ -69,12 +71,12 @@
 //  ELFExecutableWriter
 //===----------------------------------------------------------------------===//
 template<class ELFT>
-ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options)
-  : _options(options)
+ELFExecutableWriter<ELFT>::ELFExecutableWriter(const ELFTargetInfo &ti)
+  : _targetInfo(ti)
   , _referenceKindHandler(KindHandler::makeHandler(
-      _options.machine(), (endianness)ELFT::TargetEndianness))
-  , _runtimeFile(options) {
-  _layout =new DefaultELFLayout<ELFT>(options);
+                              ti.getTriple().getArch(), ti.isLittleEndian()))
+  , _runtimeFile(ti) {
+  _layout = new DefaultELFLayout<ELFT>(ti);
 }
 
 template<class ELFT>
@@ -248,14 +250,14 @@
   if (ec)
     return ec;
 
-  _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
-                                                        : ELF::ELFCLASS32));
-  _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big
-                                    ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);
+  _elfHeader->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
+                                                            : ELF::ELFCLASS32);
+  _elfHeader->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
+                                    ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
   _elfHeader->e_ident(ELF::EI_VERSION, 1);
   _elfHeader->e_ident(ELF::EI_OSABI, 0);
-  _elfHeader->e_type(_options.type());
-  _elfHeader->e_machine(_options.machine());
+  _elfHeader->e_type(_targetInfo.getOutputType());
+  _elfHeader->e_machine(_targetInfo.getOutputMachine());
   _elfHeader->e_version(1);
   _elfHeader->e_entry(0ULL);
   _elfHeader->e_phoff(_programHeader->fileOffset());
@@ -305,24 +307,24 @@
 }
 } // namespace elf
 
-Writer *createWriterELF(const WriterOptionsELF &options) {
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
   using llvm::object::ELFType;
   // Set the default layout to be the static executable layout
   // We would set the layout to a dynamic executable layout
   // if we came across any shared libraries in the process
 
-  if (!options.is64Bit() && options.endianness() == llvm::support::little)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options);
-  else if (options.is64Bit() && options.endianness() == llvm::support::little)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options);
-  else if (!options.is64Bit() && options.endianness() == llvm::support::big)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options);
-  else if (options.is64Bit() && options.endianness() == llvm::support::big)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options);
+  if (!TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(TI));
+  else if (TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(TI));
+  else if (!TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(TI));
+  else if (TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(TI));
 
   llvm_unreachable("Invalid Options!");
 }
diff --git a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
deleted file mode 100644
index 4d832ae..0000000
--- a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===- lib/ReaderWriter/ELF/WriterOptionsELF.cpp ----------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/WriterELF.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/system_error.h"
-
-
-namespace lld {
-
-StringRef WriterOptionsELF::entryPoint() const {
-  if (_type == llvm::ELF::ET_EXEC)
-    return _entryPoint;
-  return StringRef();
-}
-
-} // namespace lld
diff --git a/lld/lib/ReaderWriter/MachO/CMakeLists.txt b/lld/lib/ReaderWriter/MachO/CMakeLists.txt
index db64d87..c23ca18 100644
--- a/lld/lib/ReaderWriter/MachO/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/MachO/CMakeLists.txt
@@ -1,7 +1,6 @@
 add_lld_library(lldMachO
   MachOTargetInfo.cpp
   WriterMachO.cpp
-  WriterOptionsMachO.cpp
   ReferenceKinds.cpp
   )
 
diff --git a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
index ac80059..fb1e575 100644
--- a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
+++ b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
@@ -15,8 +15,7 @@
 #include "lld/Core/UndefinedAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
-
-#include "lld/ReaderWriter/WriterMachO.h"
+#include "lld/Core/TargetInfo.h"
 
 #include "SimpleAtoms.hpp"
 
@@ -30,10 +29,10 @@
 //
 class CRuntimeFile : public SimpleFile {
 public:
-    CRuntimeFile(const WriterOptionsMachO &options) 
+    CRuntimeFile(const MachOTargetInfo &ti) 
       : SimpleFile("C runtime"), _undefMain(*this, "_main") {
       // only main executables need _main
-      if ( options.outputKind() == WriterOptionsMachO::outputDynamicExecutable)
+      if (ti.getLinkerOptions()._outputKind == OutputKind::Executable)
         this->addAtom(_undefMain);
    }
         
diff --git a/lld/lib/ReaderWriter/MachO/GOTPass.hpp b/lld/lib/ReaderWriter/MachO/GOTPass.hpp
index 6a7c451..9618302 100644
--- a/lld/lib/ReaderWriter/MachO/GOTPass.hpp
+++ b/lld/lib/ReaderWriter/MachO/GOTPass.hpp
@@ -29,7 +29,7 @@
     return true;
   }
 
-  virtual bool isGOTAccess(Reference::Kind, bool& canBypassGOT) {
+  virtual bool isGOTAccess(int32_t, bool& canBypassGOT) {
     return false;
   }
 
diff --git a/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
index d24680a..f374966 100644
--- a/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
@@ -41,7 +41,25 @@
   }
 }
 
-class GenericMachOTargetInfo final : public MachOTargetInfo {
+bool MachOTargetInfo::addEntryPointLoadCommand() const {
+  switch (_options._outputKind) {
+  case OutputKind::Executable:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool MachOTargetInfo::addUnixThreadLoadCommand() const {
+  switch (_options._outputKind) {
+  case OutputKind::Executable:
+    return true;
+  default:
+    return false;
+  }
+}
+
+class GenericMachOTargetInfo LLVM_FINAL : public MachOTargetInfo {
 public:
   GenericMachOTargetInfo(const LinkerOptions &lo) : MachOTargetInfo(lo) {}
 
@@ -49,6 +67,8 @@
   virtual uint64_t getPageZeroSize() const { return getPageSize(); }
 
   virtual StringRef getEntry() const {
+    if (_options._outputKind != OutputKind::Executable)
+      return "";
     if (!_options._entrySymbol.empty())
       return _options._entrySymbol;
     return "_main";
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
index 6186aa2..5d21a88 100644
--- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
 
 #include "llvm/Support/ErrorHandling.h"
 
@@ -28,18 +29,16 @@
 KindHandler::~KindHandler() {
 }
 
-KindHandler *KindHandler::makeHandler(WriterOptionsMachO::Architecture arch) {
+KindHandler *KindHandler::makeHandler(llvm::Triple::ArchType arch) {
   switch( arch ) {
-   case WriterOptionsMachO::arch_x86_64:
+    case llvm::Triple::x86_64:
       return new KindHandler_x86_64();
-      break;
-    case WriterOptionsMachO::arch_x86:
+    case llvm::Triple::x86:
       return new KindHandler_x86();
-      break;
-    case WriterOptionsMachO::arch_armv6:
-    case WriterOptionsMachO::arch_armv7:
+    case llvm::Triple::arm:
       return new KindHandler_arm();
-      break;
+    default:
+      llvm_unreachable("Unknown arch");
   }
 }
 
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
index 0811808..fcae76e 100644
--- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
@@ -10,7 +10,8 @@
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterMachO.h"
+
+#include "llvm/ADT/Triple.h"
 
 #ifndef LLD_READER_WRITER_MACHO_REFERENCE_KINDS_H_
 #define LLD_READER_WRITER_MACHO_REFERENCE_KINDS_H_
@@ -28,7 +29,7 @@
 public:
   typedef Reference::Kind Kind;
   
-  static KindHandler *makeHandler(WriterOptionsMachO::Architecture arch);
+  static KindHandler *makeHandler(llvm::Triple::ArchType arch);
   virtual             ~KindHandler();
   virtual Kind        stringToKind(StringRef str) = 0;
   virtual StringRef   kindToString(Kind) = 0;
diff --git a/lld/lib/ReaderWriter/MachO/StubsPass.hpp b/lld/lib/ReaderWriter/MachO/StubsPass.hpp
index 71e7654..28453cf 100644
--- a/lld/lib/ReaderWriter/MachO/StubsPass.hpp
+++ b/lld/lib/ReaderWriter/MachO/StubsPass.hpp
@@ -28,19 +28,19 @@
 
 class StubsPass : public lld::StubsPass {
 public:
-  StubsPass(const WriterOptionsMachO &options) 
-    : _options(options), 
-      _kindHandler(KindHandler::makeHandler(options.architecture())),
+  StubsPass(const MachOTargetInfo &ti) 
+    : _targetInfo(ti),
+      _kindHandler(KindHandler::makeHandler(_targetInfo.getTriple().getArch())),
       _helperCommonAtom(nullptr),
       _helperCacheAtom(nullptr),
       _helperBinderAtom(nullptr) {
   }
 
   virtual bool noTextRelocs() {
-    return _options.noTextRelocations();
+    return !_targetInfo.getLinkerOptions()._textRelocations;
   }
 
-  virtual bool isCallSite(Reference::Kind kind) {
+  virtual bool isCallSite(int32_t kind) {
     return _kindHandler->isCallSite(kind);
   }
 
@@ -58,16 +58,15 @@
   }
 
   const DefinedAtom* makeStub(const Atom& target) {
-    switch ( _options.architecture() ) {
-      case WriterOptionsMachO::arch_x86_64:
+    switch (_targetInfo.getTriple().getArch()) {
+      case llvm::Triple::x86_64:
         return makeStub_x86_64(target);
-
-      case WriterOptionsMachO::arch_x86:
+      case llvm::Triple::x86:
         return makeStub_x86(target);
-
-      case WriterOptionsMachO::arch_armv6:
-      case WriterOptionsMachO::arch_armv7:
+      case llvm::Triple::arm:
         return makeStub_arm(target);
+      default:
+        llvm_unreachable("Unknown arch");
     }
   }
 
@@ -151,7 +150,7 @@
       }
   };
 
-  const WriterOptionsMachO                       &_options;
+  const MachOTargetInfo                          &_targetInfo;
   KindHandler                                    *_kindHandler;
   File                                            _file;
   llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToStub;
diff --git a/lld/lib/ReaderWriter/MachO/WriterMachO.cpp b/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
index 0a83338..64a6be3 100644
--- a/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
+++ b/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/WriterMachO.h"
+#include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -23,12 +23,15 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
 
 #include "lld/Core/DefinedAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/InputFiles.h"
+#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/Reference.h"
 #include "lld/Core/SharedLibraryAtom.h"
+#include "lld/ReaderWriter/MachOTargetInfo.h"
 
 #include <vector>
 #include <map>
@@ -104,7 +107,7 @@
 class SectionChunk : public Chunk {
 public:
   static SectionChunk*  make(DefinedAtom::ContentType,
-                             const WriterOptionsMachO &options,
+                             const MachOTargetInfo &ti,
                              class MachOWriter &writer);
   virtual StringRef     segmentName() const;
   virtual bool          occupiesNoDiskSpace();
@@ -126,12 +129,12 @@
                 SectionChunk(StringRef seg,
                              StringRef sect,
                              uint32_t flags,
-                             const WriterOptionsMachO &options,
+                             const MachOTargetInfo &ti,
                              class MachOWriter &writer);
 
   StringRef                 _segmentName;
   StringRef                 _sectionName;
-  const WriterOptionsMachO &_options;
+  const MachOTargetInfo    &_targetInfo;
   class MachOWriter        &_writer;
   uint32_t                  _flags;
   uint32_t                  _permissions;
@@ -146,7 +149,7 @@
 //
 class MachHeaderChunk : public Chunk {
 public:
-                MachHeaderChunk(const WriterOptionsMachO &options,
+                MachHeaderChunk(const MachOTargetInfo &ti,
                                 const File &file);
   virtual StringRef     segmentName() const;
   virtual void          write(uint8_t *fileBuffer);
@@ -155,7 +158,7 @@
   uint64_t              loadCommandsSize();
 
 private:
-  uint32_t              filetype(WriterOptionsMachO::OutputKind kind);
+  uint32_t              filetype(OutputKind);
   uint32_t              magic(uint32_t cpuType);
 
   mach_header               _mh;
@@ -171,7 +174,7 @@
 class LoadCommandsChunk : public Chunk {
 public:
                       LoadCommandsChunk(MachHeaderChunk&,
-                                        const WriterOptionsMachO &options,
+                                        const MachOTargetInfo &,
                                         class MachOWriter&);
   virtual StringRef   segmentName() const;
   virtual void        write(uint8_t *fileBuffer);
@@ -197,7 +200,7 @@
   };
 
   MachHeaderChunk             &_mh;
-  const WriterOptionsMachO    &_options;
+  const MachOTargetInfo       &_targetInfo;
   class MachOWriter           &_writer;
   segment_command             *_linkEditSegment;
   symtab_command              *_symbolTableLoadCommand;
@@ -340,7 +343,7 @@
 //
 class MachOWriter : public Writer {
 public:
-              MachOWriter(const WriterOptionsMachO &options);
+              MachOWriter(const MachOTargetInfo &ti);
 
   virtual error_code  writeFile(const lld::File &file, StringRef path);
   virtual StubsPass  *stubPass();  
@@ -373,7 +376,7 @@
 
   typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
 
-  const WriterOptionsMachO   &_options;
+  const MachOTargetInfo      &_targetInfo;
   KindHandler                *_referenceKindHandler;
   StubsPass                   _stubsPass;
   GOTPass                     _gotPass;
@@ -459,46 +462,46 @@
 //===----------------------------------------------------------------------===//
 
 SectionChunk::SectionChunk(StringRef seg, StringRef sect,
-                           uint32_t flags, const WriterOptionsMachO &options,
+                           uint32_t flags, const MachOTargetInfo &ti,
                                                 MachOWriter &writer)
- : _segmentName(seg), _sectionName(sect), _options(options),
+ : _segmentName(seg), _sectionName(sect), _targetInfo(ti),
    _writer(writer), _flags(flags), _permissions(0) {
 
 }
 
 SectionChunk* SectionChunk::make(DefinedAtom::ContentType type,
-                                 const WriterOptionsMachO &options,
+                                 const MachOTargetInfo &ti,
                                  MachOWriter &writer) {
   switch ( type ) {
     case DefinedAtom::typeCode:
       return new SectionChunk("__TEXT", "__text",
                               S_REGULAR | S_ATTR_PURE_INSTRUCTIONS,
-                              options, writer);
+                              ti, writer);
       break;
     case DefinedAtom::typeCString:
        return new SectionChunk("__TEXT", "__cstring",
                                S_CSTRING_LITERALS,
-                              options, writer);
+                              ti, writer);
        break;
     case DefinedAtom::typeStub:
       return new SectionChunk("__TEXT", "__stubs",
                               S_SYMBOL_STUBS | S_ATTR_PURE_INSTRUCTIONS,
-                              options, writer);
+                              ti, writer);
       break;
     case DefinedAtom::typeStubHelper:
       return new SectionChunk("__TEXT", "__stub_helper",
                               S_REGULAR | S_ATTR_PURE_INSTRUCTIONS,
-                              options, writer);
+                              ti, writer);
       break;
     case DefinedAtom::typeLazyPointer:
       return new SectionChunk("__DATA", "__la_symbol_ptr",
                               S_LAZY_SYMBOL_POINTERS,
-                              options, writer);
+                              ti, writer);
       break;
     case DefinedAtom::typeGOT:
       return new SectionChunk("__DATA", "__got",
                               S_NON_LAZY_SYMBOL_POINTERS,
-                              options, writer);
+                              ti, writer);
       break;
     default:
       assert(0 && "TO DO: add support for more sections");
@@ -595,13 +598,12 @@
 //  MachHeaderChunk
 //===----------------------------------------------------------------------===//
 
-MachHeaderChunk::MachHeaderChunk(const WriterOptionsMachO &options,
-                                                            const File &file) {
+MachHeaderChunk::MachHeaderChunk(const MachOTargetInfo &ti, const File &file) {
   // Set up mach_header based on options
-  _mh.magic      = this->magic(options.cpuType());
-  _mh.cputype    = options.cpuType();
-  _mh.cpusubtype = options.cpuSubtype();
-  _mh.filetype   = this->filetype(options.outputKind());
+  _mh.magic      = this->magic(ti.getCPUType());
+  _mh.cputype    = ti.getCPUType();
+  _mh.cpusubtype = ti.getCPUSubType();
+  _mh.filetype   = this->filetype(ti.getLinkerOptions()._outputKind);
   _mh.ncmds      = 0;
   _mh.sizeofcmds = 0;
   _mh.flags      = 0;
@@ -639,22 +641,29 @@
     case CPU_TYPE_X86_64:
       return MH_MAGIC_64;
   }
-  assert(0 && "file cpu type not supported");
+  llvm_unreachable("file CPU type not supported");
   return 0;
 }
 
-uint32_t MachHeaderChunk::filetype(WriterOptionsMachO::OutputKind kind) {
+uint32_t MachHeaderChunk::filetype(OutputKind kind) {
   switch ( kind ) {
-    case WriterOptionsMachO::outputDynamicExecutable:
-      return MH_EXECUTE;
-    case WriterOptionsMachO::outputDylib:
-      return MH_DYLIB;
-    case WriterOptionsMachO::outputBundle:
-      return MH_BUNDLE;
-    case WriterOptionsMachO::outputObjectFile:
-      return MH_OBJECT;
+  case OutputKind::Executable:
+    return MH_EXECUTE;
+  case OutputKind::Relocatable:
+    return MH_OBJECT;
+  case OutputKind::Shared:
+    return MH_DYLIB;
+  case OutputKind::SharedStubs:
+    return MH_DYLIB_STUB;
+  case OutputKind::Bundle:
+    return MH_BUNDLE;
+  case OutputKind::Preload:
+  case OutputKind::DebugSymbols:
+  case OutputKind::Core:
+    break;
   }
-  assert(0 && "file outputkind not supported");
+  llvm_unreachable("file OutputKind not supported");
+  return 0;
 }
 
 
@@ -664,9 +673,9 @@
 //===----------------------------------------------------------------------===//
 
 LoadCommandsChunk::LoadCommandsChunk(MachHeaderChunk &mh,
-                                     const WriterOptionsMachO &options,
+                                     const MachOTargetInfo &ti,
                                      MachOWriter& writer)
- : _mh(mh), _options(options), _writer(writer),
+ : _mh(mh), _targetInfo(ti), _writer(writer),
    _linkEditSegment(nullptr), _symbolTableLoadCommand(nullptr),
    _entryPointLoadCommand(nullptr), _threadLoadCommand(nullptr), 
    _dyldInfoLoadCommand(nullptr) {
@@ -714,7 +723,7 @@
 void LoadCommandsChunk::computeSize(const lld::File &file) {
   const bool is64 = _writer.use64BitMachO();
   // Main executables have a __PAGEZERO segment.
-  uint64_t pageZeroSize = _options.pageZeroSize();
+  uint64_t pageZeroSize = _targetInfo.getPageZeroSize();
   if ( pageZeroSize != 0 ) {
     assert(is64 || (pageZeroSize < 0xFFFFFFFF));
     segment_command* pzSegCmd = new segment_command(0, is64);
@@ -796,12 +805,11 @@
   this->addLoadCommand(_dyldInfoLoadCommand);
 
   // Add entry point load command to main executables
-  if ( _options.addEntryPointLoadCommand() ) {
+  if (_targetInfo.addEntryPointLoadCommand()) {
     _entryPointLoadCommand = new entry_point_command(is64);
     this->addLoadCommand(_entryPointLoadCommand);
-  }
-  else if ( _options.addUnixThreadLoadCommand() ) {
-    _threadLoadCommand = new thread_command(_options.cpuType(), is64);
+  } else if (_targetInfo.addUnixThreadLoadCommand()) {
+    _threadLoadCommand = new thread_command(_targetInfo.getCPUType(), is64);
     this->addLoadCommand(_threadLoadCommand);
   }
   
@@ -1295,10 +1303,10 @@
 //  MachOWriter
 //===----------------------------------------------------------------------===//
 
-MachOWriter::MachOWriter(const WriterOptionsMachO &options)
-  : _options(options), 
-    _referenceKindHandler(KindHandler::makeHandler(_options.architecture())), 
-    _stubsPass(options), _cRuntimeFile(options), 
+MachOWriter::MachOWriter(const MachOTargetInfo &ti)
+  : _targetInfo(ti),
+    _referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch())),
+    _stubsPass(ti), _cRuntimeFile(ti),
     _bindingInfo(nullptr), _lazyBindingInfo(nullptr),
     _symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
     _linkEditStartOffset(0), _linkEditStartAddress(0) {
@@ -1339,7 +1347,7 @@
     DefinedAtom::ContentType type = atom->contentType();
     auto pos = map.find(type);
     if ( pos == map.end() ) {
-      SectionChunk *chunk = SectionChunk::make(type, _options, *this);
+      SectionChunk *chunk = SectionChunk::make(type, _targetInfo, *this);
       map[type] = chunk;
       chunk->appendAtom(atom);
     }
@@ -1352,10 +1360,10 @@
 
 
   // Make chunks in __TEXT for mach_header and load commands at start.
-  MachHeaderChunk *mhc = new MachHeaderChunk(_options, file);
+  MachHeaderChunk *mhc = new MachHeaderChunk(_targetInfo, file);
   _chunks.push_back(mhc);
 
-  _loadCommandsChunk = new LoadCommandsChunk(*mhc, _options, *this);
+  _loadCommandsChunk = new LoadCommandsChunk(*mhc, _targetInfo, *this);
   _chunks.push_back(_loadCommandsChunk);
 
   _paddingChunk = new LoadCommandPaddingChunk(*_loadCommandsChunk);
@@ -1388,15 +1396,15 @@
 void MachOWriter::buildAtomToAddressMap() {
   DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs() 
                    << "assign atom addresses:\n");
-  const bool lookForEntry = 
-      (_options.outputKind() == WriterOptionsMachO::outputDynamicExecutable);
+  const bool lookForEntry = _targetInfo.getLinkerOptions()._outputKind ==
+                            OutputKind::Executable;
   for (SectionChunk *chunk : _sectionChunks ) {
     for (const SectionChunk::AtomInfo &info : chunk->atoms() ) {
       _atomToAddress[info.atom] = chunk->address() + info.offsetInSection;
       if (       lookForEntry
               && (info.atom->contentType() == DefinedAtom::typeCode)
               && (info.atom->size() != 0)
-              &&  info.atom->name().equals(_options.entryPointName()) ) {
+              &&  info.atom->name() == _targetInfo.getEntry()) {
         _entryAtom = info.atom;
       }
       DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()  
@@ -1419,7 +1427,7 @@
   DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs() 
                     << "assign file offsets:\n");
   uint64_t offset = 0;
-  uint64_t address = _options.pageZeroSize();
+  uint64_t address = _targetInfo.getPageZeroSize();
   for ( Chunk *chunk : _chunks ) {
     if ( chunk->segmentName().equals("__LINKEDIT") ) {
       _linkEditStartOffset  = Chunk::alignTo(offset, 12);
@@ -1457,7 +1465,7 @@
   const uint64_t kInvalidAddress = (uint64_t)(-1);
   StringRef lastSegName("__TEXT");
   *segIndex = 0;
-  if ( _options.pageZeroSize() != 0 ) {
+  if ( _targetInfo.getPageZeroSize() != 0 ) {
       *segIndex = 1;
   }
   *segStartAddr = kInvalidAddress;
@@ -1481,15 +1489,7 @@
 }
 
 bool MachOWriter::use64BitMachO() const {
-  switch ( _options.cpuType() ) {
-    case CPU_TYPE_ARM:
-    case CPU_TYPE_I386:
-      return false;
-    case CPU_TYPE_X86_64:
-      return true;
-  }
-  assert(0 && "unknown cpu type");
-  return false;
+  return _targetInfo.getTriple().isArch64Bit();
 }
 
 
@@ -1542,8 +1542,8 @@
 } // namespace mach_o
 
 
-Writer* createWriterMachO(const WriterOptionsMachO &options) {
-  return new lld::mach_o::MachOWriter(options);
+std::unique_ptr<Writer> createWriterMachO(const MachOTargetInfo &ti) {
+  return std::unique_ptr<Writer>(new lld::mach_o::MachOWriter(ti));
 }
 
 } // namespace lld
diff --git a/lld/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp b/lld/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp
deleted file mode 100644
index bb831b4..0000000
--- a/lld/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-//===- lib/ReaderWriter/MachO/WriterOptionsMachO.cpp ----------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/WriterMachO.h"
-
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/system_error.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-#include "MachOFormat.hpp"
-
-namespace lld {
-
-WriterOptionsMachO::WriterOptionsMachO() 
- : _outputkind(outputDynamicExecutable),
-   _architecture(arch_x86),
-   _pageZeroSize(0x1000),
-   _noTextRelocations(true) {
-}
-
-WriterOptionsMachO::~WriterOptionsMachO() {
-}
-
-StringRef WriterOptionsMachO::archName() const {
-  switch ( _architecture ) {
-    case arch_x86_64:
-      return StringRef("x86_64");
-    case arch_x86:
-       return StringRef("i386");
-    case arch_armv6:
-       return StringRef("armv6");
-    case arch_armv7:
-       return StringRef("armv7");
-  }
-  llvm_unreachable("unknown arch");
-} 
-
-uint32_t WriterOptionsMachO::cpuType() const {
-  switch ( _architecture ) {
-    case arch_x86_64:
-       return mach_o::CPU_TYPE_X86_64;
-    case arch_x86:
-       return mach_o::CPU_TYPE_I386;
-    case arch_armv6:
-    case arch_armv7:
-       return mach_o::CPU_TYPE_ARM;
-  }
-  llvm_unreachable("unknown arch");
-}
-
-uint32_t WriterOptionsMachO::cpuSubtype() const {
-  switch ( _architecture ) {
-    case arch_x86_64:
-       return mach_o::CPU_SUBTYPE_X86_64_ALL;
-    case arch_x86:
-       return mach_o::CPU_SUBTYPE_X86_ALL;
-    case arch_armv6:
-       return mach_o::CPU_SUBTYPE_ARM_V6;
-    case arch_armv7:
-       return mach_o::CPU_SUBTYPE_ARM_V7;
-  }
-  llvm_unreachable("unknown arch");
-}
-
-uint64_t WriterOptionsMachO::pageZeroSize() const { 
-  switch ( _outputkind ) {
-    case outputDynamicExecutable:
-      return _pageZeroSize; 
-    case outputDylib:
-    case outputBundle:
-    case outputObjectFile:
-      assert(_pageZeroSize == 0);
-      return 0;
-  }
-  llvm_unreachable("unknown outputkind");
-}
-
-bool WriterOptionsMachO::addEntryPointLoadCommand() const {
-  switch ( _outputkind ) {
-    case outputDynamicExecutable:
-      // Only main executables have an entry point
-      return false; 
-    case outputDylib:
-    case outputBundle:
-    case outputObjectFile:
-      return false;
-  }
-  llvm_unreachable("unknown outputkind");
-}
-
-bool WriterOptionsMachO::addUnixThreadLoadCommand() const {
-  switch ( _outputkind ) {
-    case outputDynamicExecutable:
-      // Only main executables have an entry point
-      return true; 
-    case outputDylib:
-    case outputBundle:
-    case outputObjectFile:
-      return false;
-  }
-  llvm_unreachable("unknown outputkind");
-}
-
-StringRef WriterOptionsMachO::entryPointName() const {
-  switch ( _outputkind ) {
-    case outputDynamicExecutable:
-      // Only main executables have an entry point
-      if ( ! _customEntryPointName.empty() ) {
-        return _customEntryPointName;
-      }
-      else {
-        if ( true || this->addEntryPointLoadCommand() ) 
-          return StringRef("_main");
-        else
-          return StringRef("start"); 
-      }
-      break;
-    case outputDylib:
-    case outputBundle:
-    case outputObjectFile:
-      return StringRef();
-  }
-  llvm_unreachable("unknown outputkind");
-}
-
-
-} // namespace lld
-
diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
index 36389d0..0a69ae4 100644
--- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp
+++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/ReaderNative.h"
+#include "lld/ReaderWriter/Reader.h"
 
 #include "lld/Core/Atom.h"
 #include "lld/Core/Error.h"
@@ -914,39 +914,24 @@
 
 inline void NativeReferenceV1::setAddend(Addend a) {
   // Do nothing if addend value is not being changed.
-  if ( this->addend() == a )
+  if (addend() == a)
     return;
-  assert(0 && "setAddend() not supported");
+  llvm_unreachable("setAddend() not supported");
 }
 
-
 class Reader : public lld::Reader {
 public:
-  Reader(const ReaderOptionsNative &options) {}
+  Reader(const TargetInfo &ti)
+   : lld::Reader(ti) {}
   
   virtual error_code parseFile(std::unique_ptr<MemoryBuffer> mb, 
                                std::vector<std::unique_ptr<lld::File>> &result) {
     return File::make(mb, mb->getBufferIdentifier(), result);
   }
 };
+} // end namespace native
 
-
-
-} // namespace native
-
-Reader* createReaderNative(const ReaderOptionsNative &options) {
-  return new lld::native::Reader(options);
+std::unique_ptr<Reader> createReaderNative(const TargetInfo &ti) {
+  return std::unique_ptr<Reader>(new lld::native::Reader(ti));
 }
-
-ReaderOptionsNative::ReaderOptionsNative() {
-}
-
-ReaderOptionsNative::~ReaderOptionsNative() {
-}
-
-
-} // namespace lld
-
-
-
-
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/Native/WriterNative.cpp b/lld/lib/ReaderWriter/Native/WriterNative.cpp
index 615dfac..8b7026d 100644
--- a/lld/lib/ReaderWriter/Native/WriterNative.cpp
+++ b/lld/lib/ReaderWriter/Native/WriterNative.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/WriterNative.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "lld/Core/File.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -28,7 +28,7 @@
 ///
 class Writer : public lld::Writer {
 public:
-  Writer(const WriterOptionsNative &options) {}
+  Writer(const TargetInfo &ti) {}
   
   virtual error_code writeFile(const lld::File &file, StringRef outPath) {
     // reserve first byte for unnamed atoms
@@ -576,21 +576,9 @@
   NameToOffsetVector                      _sectionNames;
   NameToOffsetVector                      _sharedLibraryNames;
 };
+} // end namespace native
 
-
-} // namespace native
-
-Writer* createWriterNative(const WriterOptionsNative &options) {
-  return new lld::native::Writer(options);
+std::unique_ptr<Writer> createWriterNative(const TargetInfo &ti) {
+  return std::unique_ptr<Writer>(new native::Writer(ti));
 }
-
-WriterOptionsNative::WriterOptionsNative() {
-}
-
-WriterOptionsNative::~WriterOptionsNative() {
-}
-
-
-} // namespace lld
-
-
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
index 3058e81..f9e473e 100644
--- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/ReaderPECOFF.h"
+#include "lld/ReaderWriter/Reader.h"
 #include "lld/Core/File.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -359,7 +359,7 @@
 
 class ReaderCOFF : public Reader {
 public:
-  ReaderCOFF(const ReaderOptionsPECOFF &options) {}
+  ReaderCOFF(const TargetInfo &ti) : Reader(ti) {}
 
   error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
                        std::vector<std::unique_ptr<File>> &result) {
@@ -373,22 +373,11 @@
     return error_code::success();
   }
 };
-
-} // namespace anonymous
-
+} // end namespace anonymous
 
 namespace lld {
-
-Reader *createReaderPECOFF(const ReaderOptionsPECOFF &options) {
-  return new ReaderCOFF(options);
+std::unique_ptr<Reader> createReaderPECOFF(const TargetInfo & ti,
+                                           std::function<ReaderFunc>) {
+  return std::unique_ptr<Reader>(new ReaderCOFF(ti));
 }
-
-ReaderOptionsPECOFF::ReaderOptionsPECOFF() {
 }
-
-ReaderOptionsPECOFF::~ReaderOptionsPECOFF() {
-}
-
-} // namespace lld
-
-
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index 8fec44e..f9163ea 100644
--- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -7,29 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/WriterPECOFF.h"
+#include "lld/ReaderWriter/Writer.h"
 
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 
 
 namespace lld {
-namespace pe_coff {
-
-// define PE/COFF writer class here
-
-
-} // namespace pe_coff
-
-Writer* createWriterPECOFF(const WriterOptionsPECOFF &options) {
-  assert(0 && "PE/COFF support not implemented yet");
+std::unique_ptr<Writer> createWriterPECOFF(const TargetInfo &) {
+  llvm_unreachable("PE/COFF support not implemented yet");
   return nullptr;
 }
-
-WriterOptionsPECOFF::WriterOptionsPECOFF() {
-}
-
-WriterOptionsPECOFF::~WriterOptionsPECOFF() {
-}
-
-} // namespace lld
-
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/Reader.cpp b/lld/lib/ReaderWriter/Reader.cpp
index f4395e8..29c1aec 100644
--- a/lld/lib/ReaderWriter/Reader.cpp
+++ b/lld/lib/ReaderWriter/Reader.cpp
@@ -14,29 +14,17 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/system_error.h"
 
-
 namespace lld {
-
-Reader::Reader() {
-}
-
 Reader::~Reader() {
 }
 
 error_code Reader::readFile(StringRef path,
-                                  std::vector<std::unique_ptr<File>> &result) {
+                            std::vector<std::unique_ptr<File>> &result) {
   OwningPtr<llvm::MemoryBuffer> opmb;
-  if ( error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb) )
+  if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb))
     return ec;
  
   std::unique_ptr<MemoryBuffer> mb(opmb.take());
   return this->parseFile(std::move(mb), result);
 }
-
-
-
-ReaderOptions::ReaderOptions() {
-}
-
-} // namespace lld 
-
+} // end namespace lld 
diff --git a/lld/lib/ReaderWriter/ReaderArchive.cpp b/lld/lib/ReaderWriter/ReaderArchive.cpp
index 9995561..0fe4c2d 100644
--- a/lld/lib/ReaderWriter/ReaderArchive.cpp
+++ b/lld/lib/ReaderWriter/ReaderArchive.cpp
@@ -9,7 +9,11 @@
 
 #include "lld/ReaderWriter/ReaderArchive.h"
 
+#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/LinkerOptions.h"
+
 #include "llvm/ADT/Hashing.h"
+#include "llvm/Object/ObjectFile.h"
 
 #include <unordered_map>
 
@@ -46,8 +50,8 @@
     
     std::vector<std::unique_ptr<File>> result;
 
-    if ((ec = _options.reader()->parseFile(std::unique_ptr<MemoryBuffer>
-                                           (ci->getBuffer()), result)))
+    LinkerInput li(std::unique_ptr<MemoryBuffer>(ci->getBuffer()));
+    if ((ec = _getReader(li)->parseFile(li.takeBuffer(), result)))
       return nullptr;
 
     assert(result.size() == 1);
@@ -109,8 +113,8 @@
   }
 
 private:
+  std::function<ErrorOr<Reader&> (const LinkerInput &)> _getReader;
   std::unique_ptr<llvm::object::Archive> _archive;
-  const ReaderOptionsArchive _options;
   atom_collection_vector<DefinedAtom>       _definedAtoms;
   atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
   atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
@@ -118,13 +122,13 @@
 
 public:
   /// only subclasses of ArchiveLibraryFile can be instantiated 
-  explicit FileArchive(llvm::MemoryBuffer *mb, 
-                       const ReaderOptionsArchive &options, 
-                       error_code &ec)
-                      :ArchiveLibraryFile(mb->getBufferIdentifier()),
-                       _options(options) { 
+  FileArchive(const TargetInfo &ti,
+              std::function<ErrorOr<Reader&> (const LinkerInput &)> getReader,
+              std::unique_ptr<llvm::MemoryBuffer> mb,
+              error_code &ec)
+      : ArchiveLibraryFile(mb->getBufferIdentifier()), _getReader(getReader) {
     std::unique_ptr<llvm::object::Archive> archive_obj(
-      new llvm::object::Archive(mb, ec));
+        new llvm::object::Archive(mb.release(), ec));
     if (ec)
       return;
     _archive.swap(archive_obj);
@@ -148,23 +152,23 @@
 // Returns a vector of Files that are contained in the archive file 
 // pointed to by the MemoryBuffer
 error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> mb,
-		std::vector<std::unique_ptr<File>> &result) {
+                                    std::vector<std::unique_ptr<File>> &result){
   error_code ec;
   
-  if (_options.isForceLoad()) {
+  if (_options._forceLoadArchives) {
     _archive.reset(new llvm::object::Archive(mb.release(), ec));
     if (ec)
       return ec;
     
     for (auto mf = _archive->begin_children(), 
               me = _archive->end_children(); mf != me; ++mf) {
-    	if ((ec = _options.reader()->parseFile(std::unique_ptr<MemoryBuffer>
-                                             (mf->getBuffer()), result)))
+      LinkerInput li(std::unique_ptr<MemoryBuffer>(mf->getBuffer()));
+      if ((ec = _getReader(li)->parseFile(li.takeBuffer(), result)))
         return ec;
     }
   } else {
     std::unique_ptr<File> f;
-    f.reset(new FileArchive(mb.release(), _options, ec));
+    f.reset(new FileArchive(_targetInfo, _getReader, std::move(mb), ec));
     if (ec)
       return ec;
 
@@ -172,5 +176,4 @@
   }
   return llvm::error_code::success();
 }
-
-} // namespace lld
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/Writer.cpp b/lld/lib/ReaderWriter/Writer.cpp
index 93dbcf5..5b8be07 100644
--- a/lld/lib/ReaderWriter/Writer.cpp
+++ b/lld/lib/ReaderWriter/Writer.cpp
@@ -9,17 +9,10 @@
 
 #include "lld/ReaderWriter/Writer.h"
 
-
 namespace lld {
-
 Writer::Writer() {
 }
 
 Writer::~Writer() {
 }
-
-WriterOptions::WriterOptions() {
-}
-
-} // namespace lld
-
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 310e8b4..30e52d0 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -8,14 +8,15 @@
 //===----------------------------------------------------------------------===//
 
 
+#include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Writer.h"
+
 #include "lld/Core/ArchiveLibraryFile.h"
 #include "lld/Core/DefinedAtom.h"
 #include "lld/Core/Error.h"
 #include "lld/Core/File.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/ReaderYAML.h"
-#include "lld/ReaderWriter/WriterYAML.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -38,6 +39,7 @@
 using llvm::yaml::SequenceTraits;
 using llvm::yaml::DocumentListTraits;
 
+using namespace lld;
 
 /// The conversion of Atoms to and from YAML uses LLVM's YAML I/O.  This
 /// file just defines template specializations on the lld types which control
@@ -51,17 +53,12 @@
 /// supplies contextual information.
 class ContextInfo {
 public:
-  ContextInfo(const lld::ReaderOptionsYAML &ro)
-    : _currentFile(nullptr), _readerOptions(&ro), _writerOptions(nullptr) { }
-  ContextInfo(const lld::WriterOptionsYAML &wo)
-    : _currentFile(nullptr), _readerOptions(nullptr), _writerOptions(&wo) { }
+  ContextInfo(const TargetInfo &ti) : _currentFile(nullptr), _targetInfo(ti) {}
 
-  lld::File                     *_currentFile;
-  const lld::ReaderOptionsYAML  *_readerOptions;
-  const lld::WriterOptionsYAML  *_writerOptions;
+  lld::File       *_currentFile;
+  const TargetInfo &_targetInfo;
 };
 
-
 /// Used when writing yaml files.
 /// In most cases, atoms names are unambiguous, so references can just
 /// use the atom name as the target (e.g. target: foo).  But in a few
@@ -293,13 +290,17 @@
                                                       llvm::raw_ostream &out) {
     assert(ctxt != nullptr);
     ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
-    out << info->_writerOptions->kindToString(value);
+    auto relocStr = info->_targetInfo.stringFromRelocKind(value);
+    out << (relocStr ? *relocStr : "<unknown>");
   }
 
   static StringRef input(StringRef scalar, void *ctxt, RefKind &value) {
     assert(ctxt != nullptr);
     ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
-    value = info->_readerOptions->kindFromString(scalar);
+    auto relocKind = info->_targetInfo.relocKindFromString(scalar);
+    if (!relocKind)
+      return "Invalid relocation kind";
+    value = *relocKind;
     return StringRef();
   }
 };
@@ -1260,8 +1261,7 @@
 
 class Writer : public lld::Writer {
 public:
-  Writer(const WriterOptionsYAML &options) : _options(options) {
-  }
+  Writer(const TargetInfo &ti) : _targetInfo(ti) {}
   
   virtual error_code writeFile(const lld::File &file, StringRef outPath) {
     // Create stream to path.
@@ -1271,7 +1271,7 @@
       return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
 
     // Create yaml Output writer, using yaml options for context.
-    ContextInfo context(_options);
+    ContextInfo context(_targetInfo);
     llvm::yaml::Output yout(out, &context);
     
     // Write yaml output.
@@ -1282,24 +1282,21 @@
   }
   
   virtual StubsPass *stubPass() {
-    return _options.stubPass();
+    return _targetInfo.getStubPass();
   }
   
   virtual GOTPass *gotPass() {
-    return _options.gotPass();
+    return _targetInfo.getGOTPass();
   }
   
   
 private:
-  const WriterOptionsYAML &_options;
+  const TargetInfo &_targetInfo;
 };
 
-
-
 class ReaderYAML : public Reader {
 public:
-  ReaderYAML(const ReaderOptionsYAML &options) : _options(options) {
-  }
+  ReaderYAML(const TargetInfo &ti) : Reader(ti) {}
 
   error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
                        std::vector<std::unique_ptr<File>> &result) {
@@ -1311,7 +1308,7 @@
     // is deallocated.
 
     // Create YAML Input parser.
-    ContextInfo context(_options);
+    ContextInfo context(_targetInfo);
     llvm::yaml::Input yin(mb->getBuffer(), &context);
     
     // Fill vector with File objects created by parsing yaml.
@@ -1329,38 +1326,14 @@
     }
     return make_error_code(lld::yaml_reader_error::success);
   }
-
-private:
-  const ReaderOptionsYAML       &_options;
 };
+} // end namespace yaml
 
-
-
-} // namespace yaml
-
-
-Writer *createWriterYAML(const WriterOptionsYAML &options) {
-  return new lld::yaml::Writer(options);
+std::unique_ptr<Writer> createWriterYAML(const TargetInfo &ti) {
+  return std::unique_ptr<Writer>(new lld::yaml::Writer(ti));
 }
 
-WriterOptionsYAML::WriterOptionsYAML() {
+std::unique_ptr<Reader> createReaderYAML(const TargetInfo &ti) {
+  return std::unique_ptr<Reader>(new lld::yaml::ReaderYAML(ti));
 }
-
-WriterOptionsYAML::~WriterOptionsYAML() {
-}
-
-
-
-Reader *createReaderYAML(const ReaderOptionsYAML &options) {
-  return new lld::yaml::ReaderYAML(options);
-}
-
-ReaderOptionsYAML::ReaderOptionsYAML() {
-}
-
-ReaderOptionsYAML::~ReaderOptionsYAML() {
-}
-
-
-} // namespace lld
-
+} // end namespace lld