This is my Driver refactoring patch. 

The major changes are:
1) LinkerOptions has been merged into TargetInfo
2) LinkerInvocation has been merged into Driver
3) Drivers no longer convert arguments into an intermediate (core) argument 
   list, but instead create a TargetInfo object and call setter methods on 
   it. This is only how in-process linking would work. That is, you can 
   programmatically set up a TargetInfo object which controls the linking.
4) Lots of tweaks to test suite to work with driver changes
5) Add the DarwinDriver
6) I heavily doxygen commented TargetInfo.h

Things to do after this patch is committed:
a) Consider renaming TargetInfo, given its new roll. 
b) Consider pulling the list of input files out of TargetInfo. This will 
   enable in-process clients to create one TargetInfo the re-use it with 
   different input file lists.
c) Work out a way for Drivers to format the warnings and error done in 
   core linking.

llvm-svn: 178776
diff --git a/lld/lib/ReaderWriter/CMakeLists.txt b/lld/lib/ReaderWriter/CMakeLists.txt
index 2ad3165..fa3e71e 100644
--- a/lld/lib/ReaderWriter/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/CMakeLists.txt
@@ -6,6 +6,7 @@
 add_subdirectory(PECOFF)
 add_subdirectory(YAML)
 add_lld_library(lldReaderWriter
+  CoreTargetInfo.cpp
   LinkerScript.cpp
   Reader.cpp
   ReaderArchive.cpp
diff --git a/lld/lib/ReaderWriter/CoreTargetInfo.cpp b/lld/lib/ReaderWriter/CoreTargetInfo.cpp
new file mode 100644
index 0000000..18da837
--- /dev/null
+++ b/lld/lib/ReaderWriter/CoreTargetInfo.cpp
@@ -0,0 +1,395 @@
+//===- lib/ReaderWriter/CoreTargetInfo.cpp --------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/ReaderWriter/CoreTargetInfo.h"
+
+#include "lld/Core/Pass.h"
+#include "lld/Core/PassManager.h"
+#include "lld/Passes/LayoutPass.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+
+using namespace lld;
+
+namespace {
+
+/// \brief Simple atom created by the stubs pass.
+class TestingStubAtom : public DefinedAtom {
+public:
+  TestingStubAtom(const File &F, const Atom&) : _file(F) {
+    static uint32_t lastOrdinal = 0;
+    _ordinal = lastOrdinal++;
+  }
+
+  virtual const File &file() const {
+    return _file;
+  }
+
+  virtual StringRef name() const {
+    return StringRef();
+  }
+
+  virtual uint64_t ordinal() const {
+    return _ordinal;
+  }
+
+  virtual uint64_t size() const {
+    return 0;
+  }
+
+  virtual Scope scope() const {
+    return DefinedAtom::scopeLinkageUnit;
+  }
+
+  virtual Interposable interposable() const {
+    return DefinedAtom::interposeNo;
+  }
+
+  virtual Merge merge() const {
+    return DefinedAtom::mergeNo;
+  }
+
+  virtual ContentType contentType() const  {
+    return DefinedAtom::typeStub;
+  }
+
+  virtual Alignment alignment() const {
+    return Alignment(0, 0);
+  }
+
+  virtual SectionChoice sectionChoice() const {
+    return DefinedAtom::sectionBasedOnContent;
+  }
+
+  virtual StringRef customSectionName() const {
+    return StringRef();
+  }
+  
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+  
+  virtual DeadStripKind deadStrip() const {
+    return DefinedAtom::deadStripNormal;
+  }
+
+  virtual ContentPermissions permissions() const  {
+    return DefinedAtom::permR_X;
+  }
+
+  virtual bool isThumb() const {
+    return false;
+  }
+
+  virtual bool isAlias() const {
+    return false;
+  }
+
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>();
+  }
+
+  virtual reference_iterator begin() const {
+    return reference_iterator(*this, nullptr);
+  }
+
+  virtual reference_iterator end() const {
+    return reference_iterator(*this, nullptr);
+  }
+
+  virtual const Reference *derefIterator(const void *iter) const {
+    return nullptr;
+  }
+
+  virtual void incrementIterator(const void *&iter) const {
+  }
+
+private:
+  const File &_file;
+  uint32_t _ordinal;
+};
+
+/// \brief Simple atom created by the GOT pass.
+class TestingGOTAtom : public DefinedAtom {
+public:
+  TestingGOTAtom(const File &F, const Atom&) : _file(F) {
+    static uint32_t lastOrdinal = 0;
+    _ordinal = lastOrdinal++;
+  }
+
+  virtual const File &file() const {
+    return _file;
+  }
+
+  virtual StringRef name() const {
+    return StringRef();
+  }
+
+  virtual uint64_t ordinal() const {
+    return _ordinal;
+  }
+
+  virtual uint64_t size() const {
+    return 0;
+  }
+
+  virtual Scope scope() const {
+    return DefinedAtom::scopeLinkageUnit;
+  }
+
+  virtual Interposable interposable() const {
+    return DefinedAtom::interposeNo;
+  }
+
+  virtual Merge merge() const {
+    return DefinedAtom::mergeNo;
+  }
+
+  virtual ContentType contentType() const  {
+    return DefinedAtom::typeGOT;
+  }
+
+  virtual Alignment alignment() const {
+    return Alignment(3, 0);
+  }
+
+  virtual SectionChoice sectionChoice() const {
+    return DefinedAtom::sectionBasedOnContent;
+  }
+
+  virtual StringRef customSectionName() const {
+    return StringRef();
+  }
+
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+
+  virtual DeadStripKind deadStrip() const {
+    return DefinedAtom::deadStripNormal;
+  }
+
+  virtual ContentPermissions permissions() const  {
+    return DefinedAtom::permRW_;
+  }
+
+  virtual bool isThumb() const {
+    return false;
+  }
+
+  virtual bool isAlias() const {
+    return false;
+  }
+
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>();
+  }
+
+  virtual reference_iterator begin() const {
+    return reference_iterator(*this, nullptr);
+  }
+
+  virtual reference_iterator end() const {
+    return reference_iterator(*this, nullptr);
+  }
+
+  virtual const Reference *derefIterator(const void *iter) const {
+    return nullptr;
+  }
+
+  virtual void incrementIterator(const void *&iter) const {
+  }
+
+private:
+  const File &_file;
+  uint32_t _ordinal;
+};
+
+class TestingPassFile : public MutableFile {
+public:
+  TestingPassFile(const TargetInfo &ti) : MutableFile(ti, "Testing pass") {}
+
+  virtual void addAtom(const Atom &atom) {
+    if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom))
+      _definedAtoms._atoms.push_back(defAtom);
+    else
+      llvm_unreachable("atom has unknown definition kind");
+  }
+
+  virtual DefinedAtomRange definedAtoms() {
+    return range<std::vector<const DefinedAtom*>::iterator>(
+                  _definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
+  }
+    
+  virtual const atom_collection<DefinedAtom> &defined() const {
+    return _definedAtoms;
+  }
+  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;
+  }
+
+private:
+  atom_collection_vector<DefinedAtom>       _definedAtoms;
+  atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
+  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+  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:
+  TestingStubsPass(const TargetInfo &ti) : _file(TestingPassFile(ti))
+  {}
+
+  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 const DefinedAtom *getStub(const Atom &target) {
+    const DefinedAtom *result = new TestingStubAtom(_file, target);
+    _file.addAtom(*result);
+    return result;
+  }
+
+  virtual void addStubAtoms(MutableFile &mergedFile) {
+    for (const DefinedAtom *stub : _file.defined() ) {
+      mergedFile.addAtom(*stub);
+    }
+  }
+
+private:
+  TestingPassFile _file;
+};
+
+class TestingGOTPass : public GOTPass {
+public:
+  TestingGOTPass(const TargetInfo &ti) : _file(TestingPassFile(ti))
+  {}
+
+  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;
+      }
+    }
+    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
+  }
+
+  virtual const DefinedAtom *makeGOTEntry(const Atom &target) {
+    return new TestingGOTAtom(_file, target);
+  }
+
+private:
+  TestingPassFile _file;
+};
+
+} // anonymous namespace
+
+
+CoreTargetInfo::CoreTargetInfo() {
+}
+
+
+void CoreTargetInfo::addPasses(PassManager &pm) const {
+  for (StringRef name : _passNames) {
+    if ( name.equals("layout") )
+      pm.add(std::unique_ptr<Pass>((new LayoutPass())));
+    else if ( name.equals("GOT") )
+      pm.add(std::unique_ptr<Pass>(new TestingGOTPass(*this)));
+    else if ( name.equals("stubs") )
+      pm.add(std::unique_ptr<Pass>(new TestingStubsPass(*this)));
+    else
+      llvm_unreachable("bad pass name");
+  }
+}
+
+
+error_code CoreTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                            std::vector<std::unique_ptr<File>> &result) const {
+  if (!_reader)
+      _reader = createReaderYAML(*this);
+  return _reader->parseFile(mb,result);
+}
+
+Writer &CoreTargetInfo::writer() const {
+  if (!_writer)
+    _writer = createWriterYAML(*this);
+  return *_writer;
+}
+
+
+ErrorOr<Reference::Kind> 
+CoreTargetInfo::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(yaml_reader_error::illegal_value);
+}
+
+ErrorOr<std::string> 
+CoreTargetInfo::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(yaml_reader_error::illegal_value);
+}
+
+
+
diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h
index c5f66bc..28501d9 100644
--- a/lld/lib/ReaderWriter/ELF/Atoms.h
+++ b/lld/lib/ReaderWriter/ELF/Atoms.h
@@ -512,7 +512,8 @@
                const Elf_Shdr *section, llvm::ArrayRef<uint8_t> contentData,
                uint64_t offset)
       : _owningFile(file), _sectionName(sectionName), _section(section),
-        _contentData(contentData), _offset(offset) {}
+        _contentData(contentData), _offset(offset) {
+  }
 
   virtual const class ELFFile<ELFT> &file() const {
     return _owningFile;
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
index 73a4c16..8c520ff 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
@@ -16,7 +16,6 @@
 #include "SectionChunks.h"
 #include "SegmentChunks.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/STDExtras.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -28,6 +27,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Format.h"
 
 #include <map>
 #include <tuple>
@@ -667,7 +667,6 @@
   }
   firstLoadSegment->prepend(_programHeader);
   firstLoadSegment->prepend(_header);
-
   bool newSegmentHeaderAdded = true;
   while (true) {
     for (auto si : _segments) {
diff --git a/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h b/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
index c642672..c019df1 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
@@ -13,7 +13,6 @@
 #include "DefaultLayout.h"
 #include "TargetHandler.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 
 #include "llvm/ADT/Triple.h"
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index 3395609..338096d 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -12,41 +12,38 @@
 #include "TargetHandler.h"
 #include "Targets.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/Passes/LayoutPass.h"
 #include "lld/ReaderWriter/ReaderLinkerScript.h"
 
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 
 namespace lld {
-ELFTargetInfo::ELFTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {}
+ELFTargetInfo::ELFTargetInfo(llvm::Triple triple)
+ : _outputFileType(elf::ET_EXEC)
+ , _triple(triple)
+ , _baseAddress(0)
+ , _isStaticExecutable(false)
+ , _outputYAML(false)
+ , _noInhibitExec(false)
+ , _mergeCommonStrings(false)
+ , _runLayoutPass(true) {
+}
 
-uint16_t ELFTargetInfo::getOutputType() const {
-  switch (_options._outputKind) {
-  case OutputKind::StaticExecutable:
-  case OutputKind::DynamicExecutable:
-    return llvm::ELF::ET_EXEC;
-  case OutputKind::Relocatable:
-    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;
-  case OutputKind::Invalid:
-    llvm_unreachable("Invalid output kind!");
-  }
-  llvm_unreachable("Unhandled OutputKind");
+bool ELFTargetInfo::is64Bits() const {
+  return getTriple().isArch64Bit();
+}
+
+bool ELFTargetInfo::isLittleEndian() const {
+  // TODO: Do this properly. It is not defined purely by arch.
+  return true;
 }
 
 void ELFTargetInfo::addPasses(PassManager &pm) const {
-  pm.add(std::unique_ptr<Pass>(new LayoutPass()));
+  if (_runLayoutPass)
+    pm.add(std::unique_ptr<Pass>(new LayoutPass()));
 }
 
 uint16_t ELFTargetInfo::getOutputMachine() const {
@@ -64,31 +61,63 @@
   }
 }
 
-ErrorOr<Reader &> ELFTargetInfo::getReader(const LinkerInput &input) const {
-  DEBUG_WITH_TYPE("inputs", llvm::dbgs() << input.getPath() << "\n");
-  auto buffer = input.getBuffer();
-  if (!buffer)
-    return error_code(buffer);
-  auto magic = llvm::sys::fs::identify_magic(buffer->getBuffer());
-  // Assume unknown file types are linker scripts.
-  if (magic == llvm::sys::fs::file_magic::unknown) {
-    if (!_linkerScriptReader)
-      _linkerScriptReader.reset(new ReaderLinkerScript(
-          *this,
-          std::bind(&ELFTargetInfo::getReader, this, std::placeholders::_1)));
-    return *_linkerScriptReader;
+bool ELFTargetInfo::validate(raw_ostream &diagnostics) {
+  if (_outputFileType == elf::ET_EXEC) {
+    if (_entrySymbolName.empty()) {
+      _entrySymbolName = "_start";
+    }
+  }
+  
+  if (_inputFiles.empty()) {
+    diagnostics << "No input files\n";
+    return true;
   }
 
-  // Assume anything else is an ELF file.
-  if (!_elfReader)
-    _elfReader = createReaderELF(*this, std::bind(&ELFTargetInfo::getReader,
-                                                  this, std::placeholders::_1));
-  return *_elfReader;
+
+  return false;
 }
 
-ErrorOr<Writer &> ELFTargetInfo::getWriter() const {
+
+bool ELFTargetInfo::isDynamic() const {
+  switch (_outputFileType) {
+  case llvm::ELF::ET_EXEC:
+    if (_isStaticExecutable)
+      return false;
+    else
+      return true;
+  case llvm::ELF::ET_DYN:
+    return true;
+  }
+  return false;
+}
+
+
+error_code ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                          std::vector<std::unique_ptr<File>> &result) const {
+  if (!_elfReader)
+    _elfReader = createReaderELF(*this);
+  error_code ec = _elfReader->parseFile(mb, result);
+  if (ec) {
+    // Not an ELF file, check file extension to see if it might be yaml
+    StringRef path = mb->getBufferIdentifier();
+    if ( path.endswith(".objtxt") ) {
+      if (!_yamlReader)
+          _yamlReader = createReaderYAML(*this);
+      ec = _yamlReader->parseFile(mb, result);
+    }
+    if (ec) {
+      // Not a yaml file, assume it is a linkerscript
+      if (!_linkerScriptReader)
+        _linkerScriptReader.reset(new ReaderLinkerScript(*this));
+      ec = _linkerScriptReader->parseFile(mb, result);
+    }
+  }
+  return ec;
+}
+
+Writer &ELFTargetInfo::writer() const {
   if (!_writer) {
-    if (_options._outputYAML)
+    if (_outputYAML)
       _writer = createWriterYAML(*this);
     else
       _writer = createWriterELF(*this);
@@ -96,27 +125,40 @@
   return *_writer;
 }
 
-std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(const LinkerOptions &lo) {
-  switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) {
+
+std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(llvm::Triple triple) {
+  switch (triple.getArch()) {
   case llvm::Triple::x86:
-    return std::unique_ptr<ELFTargetInfo>(new lld::elf::X86TargetInfo(lo));
+    return std::unique_ptr<ELFTargetInfo>(new lld::elf::X86TargetInfo(triple));
   case llvm::Triple::x86_64:
     return std::unique_ptr<
-        ELFTargetInfo>(new lld::elf::X86_64TargetInfo(lo));
+        ELFTargetInfo>(new lld::elf::X86_64TargetInfo(triple));
   case llvm::Triple::hexagon:
     return std::unique_ptr<
-        ELFTargetInfo>(new lld::elf::HexagonTargetInfo(lo));
+        ELFTargetInfo>(new lld::elf::HexagonTargetInfo(triple));
   case llvm::Triple::ppc:
-    return std::unique_ptr<ELFTargetInfo>(new lld::elf::PPCTargetInfo(lo));
+    return std::unique_ptr<ELFTargetInfo>(new lld::elf::PPCTargetInfo(triple));
   default:
     return std::unique_ptr<ELFTargetInfo>();
   }
 }
 
-StringRef ELFTargetInfo::getEntry() const {
-  if (!_options._entrySymbol.empty())
-    return _options._entrySymbol;
-  return "_start";
+bool ELFTargetInfo::appendLibrary(StringRef libName) {
+  SmallString<128> fullPath;
+  for (StringRef dir : _inputSearchPaths) {
+    // FIXME: need to handle other extensions, like .so
+    fullPath.assign(dir);
+    llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
+    StringRef pathref = fullPath.str();
+    unsigned pathlen = pathref.size();
+    if (llvm::sys::fs::exists(pathref)) {
+      char *x = _extraStrings.Allocate<char>(pathlen);
+      memcpy(x, pathref.data(), pathlen);
+      appendInputFile(StringRef(x,pathlen));
+      return false;
+    }
+  }
+  return true;
 }
 
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
index 4216cd5..d2ecbb2 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
@@ -49,6 +49,7 @@
 
   /// \brief add an undefined atom
   virtual void addUndefinedAtom(StringRef symbolName) {
+    assert(!symbolName.empty() && "UndefinedAtoms must have a name");
     Elf_Sym *symbol = new (_allocator) Elf_Sym;
     symbol->st_name = 0;
     symbol->st_value = 0;
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
index fc0bde0..6bc283d 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
@@ -46,7 +46,7 @@
 /// absolute symbols
 template<class ELFT>
 void ExecutableWriter<ELFT>::addDefaultAtoms() {
-  _runtimeFile.addUndefinedAtom(this->_targetInfo.getEntry());
+  _runtimeFile.addUndefinedAtom(this->_targetInfo.entrySymbolName());
   _runtimeFile.addAbsoluteAtom("__bss_start");
   _runtimeFile.addAbsoluteAtom("__bss_end");
   _runtimeFile.addAbsoluteAtom("_end");
diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h
index cbc2fff..a4c7124 100644
--- a/lld/lib/ReaderWriter/ELF/File.h
+++ b/lld/lib/ReaderWriter/ELF/File.h
@@ -143,7 +143,7 @@
     // Sections that have merge string property
     std::vector<const Elf_Shdr *> mergeStringSections;
 
-    bool doStringsMerge = _elfTargetInfo.getLinkerOptions()._mergeCommonStrings;
+    bool doStringsMerge = _elfTargetInfo.mergeCommonStrings();
 
     // Handle: SHT_REL and SHT_RELA sections:
     // Increment over the sections, when REL/RELA section types are found add
diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
index fe8efdd..64400dc 100644
--- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h
+++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
@@ -18,6 +18,7 @@
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/Format.h"
 
 /// \brief An Header represents the Elf[32/64]_Ehdr structure at the
 ///        start of an ELF executable file.
@@ -98,10 +99,10 @@
     FindPhdr(uint64_t type, uint64_t flags, uint64_t flagsClear)
              : _type(type)
              , _flags(flags)
-             , _flagsClear(flagsClear)
-    {}
+             , _flagsClear(flagsClear) {
+    }
 
-    bool operator()(const Elf_Phdr *j) const {
+    bool operator()(const llvm::object::Elf_Phdr_Impl<ELFT> *j) const {
       return ((j->p_type == _type) &&
               ((j->p_flags & _flags) == _flags) &&
               (!(j->p_flags & _flagsClear)));
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
index b0ee2e4..a02caa7 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
@@ -29,7 +29,8 @@
               sizeof(insn_encodings_v4) / sizeof(Instruction))
 
 /// \brief finds the scatter Bits that need to be used to apply relocations
-uint32_t findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
+inline uint32_t 
+findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
   for (int32_t i = 0; i < numInsns ; i++) {
     if (((insn & 0xc000) == 0) && !(encodings[i].isDuplex))
       continue;
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
index d7c15d4..cc928e6 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
@@ -212,8 +212,7 @@
 } // end anonymous namespace
 
 void elf::HexagonTargetInfo::addPasses(PassManager &pm) const {
-  if (_options._outputKind == OutputKind::DynamicExecutable ||
-           _options._outputKind == OutputKind::Shared)
+  if (isDynamic())
     pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
   ELFTargetInfo::addPasses(pm);
 }
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
index ddba886..49d9143 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
@@ -22,8 +22,8 @@
 
 #define LLD_CASE(name) .Case(#name, llvm::ELF::name)
 
-ErrorOr<int32_t> elf::HexagonTargetInfo::relocKindFromString(
-    StringRef str) const {
+ErrorOr<Reference::Kind> 
+elf::HexagonTargetInfo::relocKindFromString(StringRef str) const {
   int32_t ret = llvm::StringSwitch<int32_t>(str)
         LLD_CASE(R_HEX_NONE)
         LLD_CASE(R_HEX_B22_PCREL)
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
index ca8fb94..82f4c6b 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
@@ -12,7 +12,6 @@
 
 #include "HexagonTargetHandler.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 
 #include "llvm/Object/ELF.h"
@@ -23,15 +22,14 @@
 
 class HexagonTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
-  HexagonTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+  HexagonTargetInfo(llvm::Triple triple) 
+    : ELFTargetInfo(triple) {
     _targetHandler = std::unique_ptr<TargetHandlerBase>(
         new HexagonTargetHandler(*this));
   }
 
-  virtual uint64_t getPageSize() const { return 0x1000; }
-
-  virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const;
+  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
   virtual void addPasses(PassManager &) const;
 
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index 2cc81dd..40f14bb 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -345,7 +345,7 @@
   _Header->e_shnum(_shdrtab->numHeaders());
   _Header->e_shstrndx(_shstrtab->ordinal());
   uint64_t virtualAddr = 0;
-  _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
+  _layout->findAtomAddrByName(_targetInfo.entrySymbolName(), virtualAddr);
   _Header->e_entry(virtualAddr);
 
   // HACK: We have to write out the header and program header here even though
diff --git a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
index e69de29..337b02f 100644
--- a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
@@ -0,0 +1,36 @@
+#include "PPCTargetInfo.h"
+
+#include "lld/Core/LLVM.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorOr.h"
+
+using namespace lld;
+
+#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
+
+ErrorOr<Reference::Kind> elf::PPCTargetInfo::relocKindFromString(
+    StringRef str) const {
+  int32_t ret = llvm::StringSwitch<int32_t>(str)
+    LLD_CASE(R_PPC_NONE)
+    LLD_CASE(R_PPC_ADDR32)
+    .Default(-1);
+
+  if (ret == -1)
+    return make_error_code(yaml_reader_error::illegal_value);
+  return ret;
+}
+
+#undef LLD_CASE
+
+#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
+
+ErrorOr<std::string> 
+elf::PPCTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
+  switch (kind) {
+  LLD_CASE(R_PPC_NONE)
+  LLD_CASE(R_PPC_ADDR32)
+  }
+
+  return make_error_code(yaml_reader_error::illegal_value);
+}
diff --git a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
index 97ba655..0777676 100644
--- a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
@@ -12,7 +12,6 @@
 
 #include "PPCTargetHandler.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 
 #include "llvm/Object/ELF.h"
@@ -22,14 +21,15 @@
 namespace elf {
 class PPCTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
-  PPCTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+  PPCTargetInfo(llvm::Triple triple)
+    : ELFTargetInfo(triple) {
     _targetHandler = std::unique_ptr<TargetHandlerBase>(
         new PPCTargetHandler(*this));
   }
 
   virtual bool isLittleEndian() const { return false; }
-
-  virtual uint64_t getPageSize() const { return 0x1000; }
+  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 };
 
 } // elf
diff --git a/lld/lib/ReaderWriter/ELF/Reader.cpp b/lld/lib/ReaderWriter/ELF/Reader.cpp
index be2fedb..cb6e9cd 100644
--- a/lld/lib/ReaderWriter/ELF/Reader.cpp
+++ b/lld/lib/ReaderWriter/ELF/Reader.cpp
@@ -78,12 +78,12 @@
 /// memory buffer for ELF class and bit width
 class ELFReader : public Reader {
 public:
-  ELFReader(const ELFTargetInfo &ti, std::function<ReaderFunc> read)
-      : lld::Reader(ti), _elfTargetInfo(ti), _readerArchive(ti, read) {
+  ELFReader(const ELFTargetInfo &ti)
+      : lld::Reader(ti), _elfTargetInfo(ti), _readerArchive(ti, *this) {
   }
 
-  error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
-                       std::vector<std::unique_ptr<File> > &result) {
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File> > &result) const {
     using llvm::object::ELFType;
     llvm::sys::LLVMFileType fileType =
         llvm::sys::IdentifyFileType(mb->getBufferStart(),
@@ -112,10 +112,10 @@
       break;
     }
     case llvm::sys::Archive_FileType:
-      ec = _readerArchive.parseFile(std::move(mb), result);
+      ec = _readerArchive.parseFile(mb, result);
       break;
     default:
-      llvm_unreachable("not supported format");
+      return llvm::make_error_code(llvm::errc::executable_format_error);
       break;
     }
 
@@ -131,8 +131,7 @@
 };
 } // end namespace elf
 
-std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &eti,
-                                        std::function<ReaderFunc> read) {
-  return std::unique_ptr<Reader>(new elf::ELFReader(eti, std::move(read)));
+std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &targetinfo) {
+  return std::unique_ptr<Reader>(new elf::ELFReader(targetinfo));
 }
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h
index 2bca266..8237529 100644
--- a/lld/lib/ReaderWriter/ELF/SectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h
@@ -603,13 +603,13 @@
   /// \brief Get the symbol table index for an Atom. If it's not in the symbol
   /// table, return STN_UNDEF.
   uint32_t getSymbolTableIndex(const Atom *a) const {
-    auto se = std::find_if(_symbolTable.begin(), _symbolTable.end(),
+    auto entry = std::find_if(_symbolTable.begin(), _symbolTable.end(),
                            [=](const SymbolEntry &se) {
       return se._atom == a;
     });
-    if (se == _symbolTable.end())
+    if (entry == _symbolTable.end())
       return STN_UNDEF;
-    return std::distance(_symbolTable.begin(), se);
+    return std::distance(_symbolTable.begin(), entry);
   }
 
   virtual void finalize() { finalize(true); }
diff --git a/lld/lib/ReaderWriter/ELF/TargetHandler.h b/lld/lib/ReaderWriter/ELF/TargetHandler.h
index ebdb203..ab30c36 100644
--- a/lld/lib/ReaderWriter/ELF/TargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/TargetHandler.h
@@ -19,7 +19,6 @@
 #include "Layout.h"
 
 #include "lld/Core/InputFiles.h"
-#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/TargetInfo.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp
index 6e2744e..a174ef0 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.cpp
+++ b/lld/lib/ReaderWriter/ELF/Writer.cpp
@@ -1,4 +1,4 @@
-//===- lib/ReaderWriter/ELF/Writer.cpp ------------------------------------===//
+//===- lib/ReaderWriter/ELF/WriterELF.cpp ---------------------------------===//
 //
 //                             The LLVM Linker
 //
@@ -6,53 +6,63 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include "ExecutableWriter.h"
+
+#include "lld/ReaderWriter/Writer.h"
+
 #include "DynamicLibraryWriter.h"
+#include "ExecutableWriter.h"
+
 
 using namespace llvm;
 using namespace llvm::object;
-
 namespace lld {
 
-std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &info) {
   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
 
-  const LinkerOptions &options = TI.getLinkerOptions();
-
-  if ((options._outputKind == OutputKind::StaticExecutable) ||
-      (options._outputKind == OutputKind::DynamicExecutable)) {
-    if (!TI.is64Bits() && TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
-    else if (TI.is64Bits() && TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
-    else if (!TI.is64Bits() && !TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
-    else if (TI.is64Bits() && !TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
-    llvm_unreachable("Invalid Options!");
-  } else if (options._outputKind == OutputKind::Shared) {
-    if (!TI.is64Bits() && TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(TI));
-    else if (TI.is64Bits() && TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(TI));
-    else if (!TI.is64Bits() && !TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(TI));
-    else if (TI.is64Bits() && !TI.isLittleEndian())
-      return std::unique_ptr<Writer>(new
-          elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(TI));
-    llvm_unreachable("Invalid Options!");
+  switch(info.getOutputType()) {
+  case llvm::ELF::ET_EXEC:
+    if (info.is64Bits()) {
+      if (info.isLittleEndian()) 
+        return std::unique_ptr<Writer>(new
+            elf::ExecutableWriter<ELFType<support::little, 8, true>>(info));
+      else
+        return std::unique_ptr<Writer>(new
+                elf::ExecutableWriter<ELFType<support::big, 8, true>>(info));
+    } else {
+      if (info.isLittleEndian()) 
+        return std::unique_ptr<Writer>(new
+            elf::ExecutableWriter<ELFType<support::little, 4, false>>(info));
+      else
+        return std::unique_ptr<Writer>(new
+                elf::ExecutableWriter<ELFType<support::big, 4, false>>(info));
+    }
+  break;
+  case llvm::ELF::ET_DYN:
+    if (info.is64Bits()) {
+      if (info.isLittleEndian()) 
+        return std::unique_ptr<Writer>(new
+          elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(info));
+      else
+        return std::unique_ptr<Writer>(new
+              elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(info));
+    } else {
+      if (info.isLittleEndian()) 
+        return std::unique_ptr<Writer>(new
+          elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(info));
+      else
+        return std::unique_ptr<Writer>(new
+              elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(info));
+    }
+  break;
+  case llvm::ELF::ET_REL:
+    llvm_unreachable("TODO: support -r mode");
+  default:
+    llvm_unreachable("unsupported output type");
   }
-  else
-    llvm_unreachable("unsupported options");
 }
-}
+
+} // namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/Writer.h b/lld/lib/ReaderWriter/ELF/Writer.h
index 7e67c31..20b330e 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.h
+++ b/lld/lib/ReaderWriter/ELF/Writer.h
@@ -28,7 +28,7 @@
   virtual void buildChunks(const File &file) = 0;
 
   /// \brief Writes the chunks into the output file specified by path
-  virtual error_code writeFile(const File &File, StringRef path) = 0;
+  virtual error_code writeFile(const File &file, StringRef path) = 0;
 
   /// \brief Get the virtual address of \p atom after layout.
   virtual uint64_t addressOfAtom(const Atom *atom) = 0;
diff --git a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
index e69de29..8a0737c 100644
--- a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
@@ -0,0 +1,36 @@
+#include "X86TargetInfo.h"
+
+#include "lld/Core/LLVM.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorOr.h"
+
+using namespace lld;
+
+#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
+
+ErrorOr<Reference::Kind> elf::X86TargetInfo::relocKindFromString(
+    StringRef str) const {
+  int32_t ret = llvm::StringSwitch<int32_t>(str)
+    LLD_CASE(R_386_NONE)
+    LLD_CASE(R_386_PC32)
+    .Default(-1);
+
+  if (ret == -1)
+    return make_error_code(yaml_reader_error::illegal_value);
+  return ret;
+}
+
+#undef LLD_CASE
+
+#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
+
+ErrorOr<std::string> 
+elf::X86TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
+  switch (kind) {
+  LLD_CASE(R_386_NONE)
+  LLD_CASE(R_386_PC32)
+  }
+
+  return make_error_code(yaml_reader_error::illegal_value);
+}
diff --git a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
index c66a42f..00007af 100644
--- a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
@@ -12,7 +12,6 @@
 
 #include "X86TargetHandler.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 
 #include "llvm/Object/ELF.h"
@@ -22,12 +21,14 @@
 namespace elf {
 class X86TargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
-  X86TargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+  X86TargetInfo(llvm::Triple triple) 
+    : ELFTargetInfo(triple) {
     _targetHandler = std::unique_ptr<TargetHandlerBase>(
         new X86TargetHandler(*this));
   }
 
-  virtual uint64_t getPageSize() const { return 0x1000; }
+  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 };
 } // end namespace elf
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
index bb6236e..cad8dd2 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
@@ -399,18 +399,29 @@
 } // end anon namespace
 
 void elf::X86_64TargetInfo::addPasses(PassManager &pm) const {
-  if (_options._outputKind == OutputKind::StaticExecutable)
-    pm.add(std::unique_ptr<Pass>(new StaticGOTPLTPass(*this)));
-  else if (_options._outputKind == OutputKind::DynamicExecutable ||
-           _options._outputKind == OutputKind::Shared)
+  switch (_outputFileType) {
+  case llvm::ELF::ET_EXEC:
+    if (_isStaticExecutable)
+      pm.add(std::unique_ptr<Pass>(new StaticGOTPLTPass(*this)));
+    else
+      pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
+    break;
+  case llvm::ELF::ET_DYN:
     pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
+    break;
+  case llvm::ELF::ET_REL:
+    break;
+  default:
+    llvm_unreachable("Unhandled output file type");
+  }
   ELFTargetInfo::addPasses(pm);
 }
 
+
 #define LLD_CASE(name) .Case(#name, llvm::ELF::name)
 
-ErrorOr<int32_t> elf::X86_64TargetInfo::relocKindFromString(
-    StringRef str) const {
+ErrorOr<Reference::Kind> 
+elf::X86_64TargetInfo::relocKindFromString(StringRef str) const {
   int32_t ret = llvm::StringSwitch<int32_t>(str)
     LLD_CASE(R_X86_64_NONE)
     LLD_CASE(R_X86_64_64)
@@ -462,8 +473,8 @@
 
 #define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
 
-ErrorOr<std::string> elf::X86_64TargetInfo::stringFromRelocKind(
-    int32_t kind) const {
+ErrorOr<std::string> 
+elf::X86_64TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
   switch (kind) {
   LLD_CASE(R_X86_64_NONE)
   LLD_CASE(R_X86_64_64)
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
index 11adab4..4c8afa0 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
@@ -12,7 +12,6 @@
 
 #include "X86_64TargetHandler.h"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 
 #include "llvm/Object/ELF.h"
@@ -29,19 +28,18 @@
 
 class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
-  X86_64TargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+  X86_64TargetInfo(llvm::Triple triple) 
+    : ELFTargetInfo(triple) {
     _targetHandler =
         std::unique_ptr<TargetHandlerBase>(new X86_64TargetHandler(*this));
   }
 
-  virtual uint64_t getPageSize() const { return 0x1000; }
-
   virtual void addPasses(PassManager &) const;
 
   virtual uint64_t getBaseAddress() const {
-    if (_options._baseAddress == 0)
+    if (_baseAddress == 0)
       return 0x400000;
-    return _options._baseAddress;
+    return _baseAddress;
   }
 
   virtual bool isDynamicRelocation(const DefinedAtom &,
@@ -66,8 +64,8 @@
     }
   }
 
-  virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const;
-  virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const;
+  virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+  virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
 };
 } // end namespace elf
diff --git a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
index de8d521..54dcb69 100644
--- a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
+++ b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.hpp
@@ -29,13 +29,13 @@
 class CRuntimeFile : public SimpleFile {
 public:
     CRuntimeFile(const MachOTargetInfo &ti) 
-      : SimpleFile(ti, "C runtime"), _undefMain(*this, "_main") {
+      : SimpleFile(ti, "C runtime"), _undefMain(*this, ti.entrySymbolName()) {
       // only main executables need _main
-      if (ti.getLinkerOptions()._outputKind == OutputKind::StaticExecutable ||
-          ti.getLinkerOptions()._outputKind == OutputKind::DynamicExecutable)
+      if (ti.outputFileType() == MH_EXECUTE) {
         this->addAtom(_undefMain);
+      }
    }
-        
+
 private:
   SimpleUndefinedAtom   _undefMain;
 };
diff --git a/lld/lib/ReaderWriter/MachO/MachOFormat.hpp b/lld/lib/ReaderWriter/MachO/MachOFormat.hpp
index 2010a7f..41b432a 100644
--- a/lld/lib/ReaderWriter/MachO/MachOFormat.hpp
+++ b/lld/lib/ReaderWriter/MachO/MachOFormat.hpp
@@ -40,12 +40,14 @@
   CPU_SUBTYPE_X86_ALL    = 0x00000003,
   CPU_SUBTYPE_X86_64_ALL = 0x00000003,
   CPU_SUBTYPE_ARM_V6     = 0x00000006,
-  CPU_SUBTYPE_ARM_V7     = 0x00000009
+  CPU_SUBTYPE_ARM_V7     = 0x00000009,
+  CPU_SUBTYPE_ARM_V7S    = 0x0000000B
 };
 
 enum {
   MH_OBJECT     = 0x1,
   MH_EXECUTE    = 0x2,
+  MH_PRELOAD    = 0x5,
   MH_DYLIB      = 0x6,
   MH_DYLINKER   = 0x7,
   MH_BUNDLE     = 0x8,
@@ -494,7 +496,7 @@
       // in-memory matches on-disk, so copy first fields followed by path
       ::memcpy(to, (uint8_t*)&cmd, 24);
       ::memcpy(&to[24], _loadPath.data(), _loadPath.size());
-      ::memset(&to[12+_loadPath.size()], 0, cmdsize-(12+_loadPath.size()));
+      ::memset(&to[24+_loadPath.size()], 0, cmdsize-(24+_loadPath.size()));
     }
   }
 
diff --git a/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
index 0b2d077..f60f32e 100644
--- a/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
@@ -10,83 +10,244 @@
 #include "lld/ReaderWriter/MachOTargetInfo.h"
 #include "GOTPass.hpp"
 #include "StubsPass.hpp"
+#include "ReferenceKinds.h"
+#include "MachOFormat.hpp"
 
-#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/PassManager.h"
+#include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "lld/Passes/LayoutPass.h"
 
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
-#include "llvm/Support/MachO.h"
+
+using lld::mach_o::KindHandler;
+
 
 namespace lld {
+
+
+MachOTargetInfo::PackedVersion::PackedVersion(StringRef str) {
+  if (parse(str, *this))
+    llvm_unreachable("bad version string");
+}
+
+/// Construct 32-bit PackedVersion from string "X.Y.Z" where
+/// bits are xxxx.yy.zz.  Largest number is 65535.255.255
+bool MachOTargetInfo::PackedVersion::parse(StringRef str, 
+                                    MachOTargetInfo::PackedVersion &result) {
+  result._value = 0;
+
+  if (str.empty()) 
+    return false;
+  
+  SmallVector<StringRef, 3> parts;
+  llvm::SplitString(str, parts, ".");
+  
+  unsigned long long num;
+  if (llvm::getAsUnsignedInteger(parts[0], 10, num))
+    return true;
+  if (num > 65535)
+    return true;
+  result._value = num << 16;
+  
+  if (parts.size() > 1) {
+    if (llvm::getAsUnsignedInteger(parts[1], 10, num))
+      return true;
+    if (num > 255)
+      return true;
+    result._value |= (num << 8);
+  }
+  
+  if (parts.size() > 2) {
+    if (llvm::getAsUnsignedInteger(parts[2], 10, num))
+      return true;
+    if (num > 255)
+      return true;
+    result._value |= num;
+  }
+  
+  return false;
+}
+
+bool MachOTargetInfo::PackedVersion::operator<(
+                                              const PackedVersion &rhs) const {
+  return _value < rhs._value;
+}
+
+bool MachOTargetInfo::PackedVersion::operator>=(
+                                              const PackedVersion &rhs) const { 
+  return _value >= rhs._value;
+}
+
+bool MachOTargetInfo::PackedVersion::operator==(
+                                              const PackedVersion &rhs) const {
+  return _value == rhs._value;
+}
+
+
+MachOTargetInfo::MachOTargetInfo() 
+  : _outputFileType(mach_o::MH_EXECUTE)
+  , _outputFileTypeStatic(false)
+  , _arch(arch_unknown)
+  , _os(OS::macOSX)
+  , _osMinVersion("0.0")
+  , _pageZeroSize(0x1000)
+  , _kindHandler(nullptr) { 
+}
+
+ 
+MachOTargetInfo::~MachOTargetInfo() {
+}
+
 uint32_t MachOTargetInfo::getCPUType() const {
-  switch (getTriple().getArch()) {
-  case llvm::Triple::x86:
-    return llvm::MachO::CPUTypeI386;
-  case llvm::Triple::x86_64:
-    return llvm::MachO::CPUTypeX86_64;
-  case llvm::Triple::arm:
-    return llvm::MachO::CPUTypeARM;
-  default:
+  switch (_arch) {
+  case MachOTargetInfo::arch_x86:
+    return mach_o::CPU_TYPE_I386;
+  case MachOTargetInfo::arch_x86_64:
+    return mach_o::CPU_TYPE_X86_64;
+  case MachOTargetInfo::arch_armv6:
+  case MachOTargetInfo::arch_armv7:
+  case MachOTargetInfo::arch_armv7s:
+    return mach_o::CPU_TYPE_ARM;
+  case MachOTargetInfo::arch_unknown:
     llvm_unreachable("Unknown arch type");
   }
 }
 
 uint32_t MachOTargetInfo::getCPUSubType() const {
-  switch (getTriple().getArch()) {
-  case llvm::Triple::x86:
-    return llvm::MachO::CPUSubType_I386_ALL;
-  case llvm::Triple::x86_64:
-    return llvm::MachO::CPUSubType_X86_64_ALL;
-  case llvm::Triple::arm:
-    return llvm::MachO::CPUSubType_ARM_ALL;
-  default:
+  switch (_arch) {
+  case MachOTargetInfo::arch_x86:
+    return mach_o::CPU_SUBTYPE_X86_ALL;
+  case MachOTargetInfo::arch_x86_64:
+    return mach_o::CPU_SUBTYPE_X86_64_ALL;
+  case MachOTargetInfo::arch_armv6:
+    return mach_o::CPU_SUBTYPE_ARM_V6;
+  case MachOTargetInfo::arch_armv7:
+    return mach_o::CPU_SUBTYPE_ARM_V7;
+  case MachOTargetInfo::arch_armv7s:
+    return mach_o::CPU_SUBTYPE_ARM_V7S;
+  case MachOTargetInfo::arch_unknown:
     llvm_unreachable("Unknown arch type");
   }
 }
 
-bool MachOTargetInfo::addEntryPointLoadCommand() const {
-  switch (_options._outputKind) {
-  case OutputKind::StaticExecutable:
-  case OutputKind::DynamicExecutable:
+
+bool MachOTargetInfo::outputTypeHasEntry() const {
+  switch (_outputFileType) {
+  case mach_o::MH_EXECUTE:
+  case mach_o::MH_DYLINKER:
+  case mach_o::MH_PRELOAD:
     return true;
   default:
     return false;
   }
 }
 
+
+bool MachOTargetInfo::minOS(StringRef mac, StringRef iOS) const  {
+  switch (_os) {
+  case OS::macOSX:
+    return (_osMinVersion >= PackedVersion(mac));
+  case OS::iOS:
+  case OS::iOS_simulator:
+    return (_osMinVersion >= PackedVersion(iOS));
+  }
+  llvm_unreachable("target not configured for iOS or MacOSX");
+}
+
+bool MachOTargetInfo::addEntryPointLoadCommand() const {
+  if ((_outputFileType == mach_o::MH_EXECUTE) && !_outputFileTypeStatic) {
+    return minOS("10.8", "6.0");
+  }
+  return false;
+}
+
 bool MachOTargetInfo::addUnixThreadLoadCommand() const {
-  switch (_options._outputKind) {
-  case OutputKind::StaticExecutable:
-  case OutputKind::DynamicExecutable:
+  switch (_outputFileType) {
+  case mach_o::MH_EXECUTE:
+    if (_outputFileTypeStatic)
+      return true;
+    else
+      return !minOS("10.8", "6.0");
+    break;
+  case mach_o::MH_DYLINKER:
+  case mach_o::MH_PRELOAD:
     return true;
   default:
     return false;
   }
 }
 
-class GenericMachOTargetInfo LLVM_FINAL : public MachOTargetInfo {
-public:
-  GenericMachOTargetInfo(const LinkerOptions &lo) : MachOTargetInfo(lo) {}
+bool MachOTargetInfo::validate(raw_ostream &diagnostics) {
+  if ((_outputFileType == mach_o::MH_EXECUTE) && _entrySymbolName.empty()) {
+    if (_outputFileTypeStatic) {
+      _entrySymbolName = "start";
+    }
+    else {
+      // If targeting newer OS, use _main
+      if (addEntryPointLoadCommand())
+        _entrySymbolName = "_main";
 
-  virtual uint64_t getPageSize() const { return 0x1000; }
-  virtual uint64_t getPageZeroSize() const { return getPageSize(); }
-
-  virtual StringRef getEntry() const {
-    if (!_options._entrySymbol.empty())
-      return _options._entrySymbol;
-    return "_main";
+      // If targeting older OS, use start (in crt1.o)
+      if (addUnixThreadLoadCommand())
+        _entrySymbolName = "start";
+    }
   }
 
-  virtual void addPasses(PassManager &pm) const {
-    pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
-    pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
-    pm.add(std::unique_ptr<Pass>(new LayoutPass()));
-  }
-};
-
-std::unique_ptr<MachOTargetInfo>
-MachOTargetInfo::create(const LinkerOptions &lo) {
-  return std::unique_ptr<MachOTargetInfo>(new GenericMachOTargetInfo(lo));
+  return false;
 }
+
+bool MachOTargetInfo::setOS(OS os, StringRef minOSVersion) {
+  _os = os;
+  return PackedVersion::parse(minOSVersion, _osMinVersion);
+}
+
+void MachOTargetInfo::addPasses(PassManager &pm) const {
+  pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
+  pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
+  pm.add(std::unique_ptr<Pass>(new LayoutPass()));
+}
+
+
+
+error_code MachOTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                          std::vector<std::unique_ptr<File>> &result) const {
+//  if (!_machoReader)
+//    _machoReader = createReaderMachO(*this);
+//  error_code ec = _machoReader->parseFile(mb,result);
+//  if (ec) {
+    if (!_yamlReader)
+      _yamlReader = createReaderYAML(*this);
+      return _yamlReader->parseFile(mb,result);
+//  }
+  
+  return error_code::success();
+}
+
+
+Writer &MachOTargetInfo::writer() const {
+  if (!_writer) {
+    _writer = createWriterMachO(*this);
+  }
+  return *_writer;
+}
+
+KindHandler &MachOTargetInfo::kindHandler() const {
+  if (!_kindHandler)
+    _kindHandler = KindHandler::create(_arch);
+  return *_kindHandler;
+}
+
+ErrorOr<Reference::Kind> 
+MachOTargetInfo::relocKindFromString(StringRef str) const {
+  return kindHandler().stringToKind(str);
+ }
+
+ErrorOr<std::string> 
+MachOTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
+  return std::string(kindHandler().kindToString(kind));
+}
+
+
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
index d2fb617..d2ad3a2 100644
--- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
@@ -10,6 +10,7 @@
 
 #include "ReferenceKinds.h"
 
+
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
@@ -29,14 +30,17 @@
 KindHandler::~KindHandler() {
 }
 
-KindHandler *KindHandler::makeHandler(llvm::Triple::ArchType arch) {
+std::unique_ptr<mach_o::KindHandler> KindHandler::create(
+                                                MachOTargetInfo::Arch arch) {
   switch( arch ) {
-    case llvm::Triple::x86_64:
-      return new KindHandler_x86_64();
-    case llvm::Triple::x86:
-      return new KindHandler_x86();
-    case llvm::Triple::arm:
-      return new KindHandler_arm();
+    case MachOTargetInfo::arch_x86_64:
+      return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86_64());
+    case MachOTargetInfo::arch_x86:
+      return std::unique_ptr<mach_o::KindHandler>(new KindHandler_x86());
+    case MachOTargetInfo::arch_armv6:
+    case MachOTargetInfo::arch_armv7:
+    case MachOTargetInfo::arch_armv7s:
+      return std::unique_ptr<mach_o::KindHandler>(new KindHandler_arm());
     default:
       llvm_unreachable("Unknown arch");
   }
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
index 1fce85f..a9bf0e6 100644
--- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h
@@ -10,6 +10,7 @@
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
+#include "lld/ReaderWriter/MachOTargetInfo.h"
 
 #include "llvm/ADT/Triple.h"
 
@@ -29,7 +30,7 @@
 public:
   typedef Reference::Kind Kind;
 
-  static KindHandler *makeHandler(llvm::Triple::ArchType arch);
+  static std::unique_ptr<mach_o::KindHandler> create(MachOTargetInfo::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 6452494..558fe13 100644
--- a/lld/lib/ReaderWriter/MachO/StubsPass.hpp
+++ b/lld/lib/ReaderWriter/MachO/StubsPass.hpp
@@ -13,7 +13,6 @@
 #include "llvm/ADT/DenseMap.h"
 
 #include "lld/Core/DefinedAtom.h"
-#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/SharedLibraryAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
@@ -31,7 +30,7 @@
 public:
   StubsPass(const MachOTargetInfo &ti) 
     : _targetInfo(ti)
-    , _kindHandler(KindHandler::makeHandler(_targetInfo.getTriple().getArch()))
+    , _kindHandler(_targetInfo.kindHandler())
     , _file(ti)
     , _helperCommonAtom(nullptr)
     , _helperCacheAtom(nullptr)
@@ -39,11 +38,11 @@
   }
 
   virtual bool noTextRelocs() {
-    return !_targetInfo.getLinkerOptions()._textRelocations;
+    return true;
   }
 
   virtual bool isCallSite(int32_t kind) {
-    return _kindHandler->isCallSite(kind);
+    return _kindHandler.isCallSite(kind);
   }
 
   virtual const DefinedAtom* getStub(const Atom& target) {
@@ -60,15 +59,17 @@
   }
 
   const DefinedAtom* makeStub(const Atom& target) {
-    switch (_targetInfo.getTriple().getArch()) {
-      case llvm::Triple::x86_64:
+    switch (_targetInfo.arch()) {
+      case MachOTargetInfo::arch_x86_64:
         return makeStub_x86_64(target);
-      case llvm::Triple::x86:
+      case MachOTargetInfo::arch_x86:
         return makeStub_x86(target);
-      case llvm::Triple::arm:
+      case MachOTargetInfo::arch_armv6:
+      case MachOTargetInfo::arch_armv7:
+      case MachOTargetInfo::arch_armv7s:
         return makeStub_arm(target);
       default:
-        llvm_unreachable("Unknown arch");
+        llvm_unreachable("Unknown mach-o arch");
     }
   }
 
@@ -153,7 +154,7 @@
   };
 
   const MachOTargetInfo                          &_targetInfo;
-  KindHandler                                    *_kindHandler;
+  mach_o::KindHandler                            &_kindHandler;
   File                                            _file;
   llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToStub;
   std::vector<const DefinedAtom*>                 _lazyPointers;
diff --git a/lld/lib/ReaderWriter/MachO/WriterMachO.cpp b/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
index b0e5fd2..e91a3d9 100644
--- a/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
+++ b/lld/lib/ReaderWriter/MachO/WriterMachO.cpp
@@ -28,7 +28,6 @@
 #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"
@@ -155,7 +154,6 @@
   uint64_t              loadCommandsSize();
 
 private:
-  uint32_t              filetype(OutputKind);
   uint32_t              magic(uint32_t cpuType);
 
   mach_header               _mh;
@@ -350,7 +348,7 @@
                                 uint64_t *segStartAddr, uint64_t *segEndAddr);
 
   const std::vector<Chunk*> chunks() { return _chunks; }
-  KindHandler *kindHandler() { return _referenceKindHandler; }
+  mach_o::KindHandler &kindHandler() { return _referenceKindHandler; }
 
   bool use64BitMachO() const;
 
@@ -372,7 +370,7 @@
   typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
 
   const MachOTargetInfo      &_targetInfo;
-  KindHandler                *_referenceKindHandler;
+  mach_o::KindHandler        &_referenceKindHandler;
   CRuntimeFile                _cRuntimeFile;
   LoadCommandsChunk          *_loadCommandsChunk;
   LoadCommandPaddingChunk    *_paddingChunk;
@@ -580,7 +578,7 @@
       if ( ref->target() != nullptr )
         targetAddress = _writer.addressOfAtom(ref->target());
       uint64_t fixupAddress = _writer.addressOfAtom(atomInfo.atom) + offset;
-      _writer.kindHandler()->applyFixup(ref->kind(), ref->addend(),
+      _writer.kindHandler().applyFixup(ref->kind(), ref->addend(), 
                             &atomContent[offset], fixupAddress, targetAddress);
     }
   }
@@ -596,7 +594,7 @@
   _mh.magic      = this->magic(ti.getCPUType());
   _mh.cputype    = ti.getCPUType();
   _mh.cpusubtype = ti.getCPUSubType();
-  _mh.filetype   = this->filetype(ti.getLinkerOptions()._outputKind);
+  _mh.filetype   = ti.outputFileType();
   _mh.ncmds      = 0;
   _mh.sizeofcmds = 0;
   _mh.flags      = 0;
@@ -638,30 +636,6 @@
   return 0;
 }
 
-uint32_t MachHeaderChunk::filetype(OutputKind kind) {
-  switch ( kind ) {
-  case OutputKind::StaticExecutable:
-  case OutputKind::DynamicExecutable:
-    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;
-  case OutputKind::Invalid:
-    llvm_unreachable("Invalid output kind!");
-  }
-  llvm_unreachable("file OutputKind not supported");
-  return 0;
-}
-
 
 
 //===----------------------------------------------------------------------===//
@@ -719,7 +693,7 @@
 void LoadCommandsChunk::computeSize(const lld::File &file) {
   const bool is64 = _writer.use64BitMachO();
   // Main executables have a __PAGEZERO segment.
-  uint64_t pageZeroSize = _targetInfo.getPageZeroSize();
+  uint64_t pageZeroSize = _targetInfo.pageZeroSize();
   if ( pageZeroSize != 0 ) {
     assert(is64 || (pageZeroSize < 0xFFFFFFFF));
     segment_command* pzSegCmd = new segment_command(0, is64);
@@ -1032,7 +1006,7 @@
           const SharedLibraryAtom *shlTarget
                                         = dyn_cast<SharedLibraryAtom>(target);
           if ( shlTarget != nullptr ) {
-            assert(_writer.kindHandler()->isPointer(ref->kind()));
+            assert(_writer.kindHandler().isPointer(ref->kind()));
             targetName = shlTarget->name();
             ordinal = 1; // FIXME
           }
@@ -1099,14 +1073,14 @@
 void LazyBindingInfoChunk::updateHelper(const DefinedAtom *lazyPointerAtom,
                                         uint32_t offset) {
   for (const Reference *ref : *lazyPointerAtom ) {
-    if ( ! _writer.kindHandler()->isPointer(ref->kind() ) )
+    if ( ! _writer.kindHandler().isPointer(ref->kind() ) )
       continue;
     const Atom *targ = ref->target();
     const DefinedAtom *helperAtom = dyn_cast<DefinedAtom>(targ);
     assert(helperAtom != nullptr);
     // Found helper atom.  Search it for Reference that is lazy immediate value.
     for (const Reference *href : *helperAtom ) {
-      if ( _writer.kindHandler()->isLazyImmediate(href->kind()) ) {
+      if ( _writer.kindHandler().isLazyImmediate(href->kind()) ) {
         (const_cast<Reference*>(href))->setAddend(offset);
         return;
       }
@@ -1156,7 +1130,7 @@
       int flags = 0;
       StringRef name;
       for (const Reference *ref : *lazyPointerAtom ) {
-        if ( _writer.kindHandler()->isLazyTarget(ref->kind()) ) {
+        if ( _writer.kindHandler().isLazyTarget(ref->kind()) ) {
           const Atom *shlib = ref->target();
           assert(shlib != nullptr);
           name = shlib->name();
@@ -1301,7 +1275,7 @@
 
 MachOWriter::MachOWriter(const MachOTargetInfo &ti)
   : _targetInfo(ti),
-    _referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch())),
+    _referenceKindHandler(ti.kindHandler()),
     _cRuntimeFile(ti),
     _bindingInfo(nullptr), _lazyBindingInfo(nullptr),
     _symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
@@ -1392,17 +1366,14 @@
 void MachOWriter::buildAtomToAddressMap() {
   DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
                    << "assign atom addresses:\n");
-  const bool lookForEntry = _targetInfo.getLinkerOptions()._outputKind ==
-                            OutputKind::StaticExecutable ||
-                            _targetInfo.getLinkerOptions()._outputKind ==
-                            OutputKind::DynamicExecutable;
+  const bool lookForEntry = _targetInfo.outputTypeHasEntry();
   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() == _targetInfo.getEntry()) {
+              &&  info.atom->name() == _targetInfo.entrySymbolName()) {
         _entryAtom = info.atom;
       }
       DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
@@ -1425,7 +1396,7 @@
   DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
                     << "assign file offsets:\n");
   uint64_t offset = 0;
-  uint64_t address = _targetInfo.getPageZeroSize();
+  uint64_t address = _targetInfo.pageZeroSize();
   for ( Chunk *chunk : _chunks ) {
     if ( chunk->segmentName().equals("__LINKEDIT") ) {
       _linkEditStartOffset  = Chunk::alignTo(offset, 12);
@@ -1463,7 +1434,7 @@
   const uint64_t kInvalidAddress = (uint64_t)(-1);
   StringRef lastSegName("__TEXT");
   *segIndex = 0;
-  if ( _targetInfo.getPageZeroSize() != 0 ) {
+  if ( _targetInfo.pageZeroSize() != 0 ) {
       *segIndex = 1;
   }
   *segStartAddr = kInvalidAddress;
@@ -1487,7 +1458,17 @@
 }
 
 bool MachOWriter::use64BitMachO() const {
-  return _targetInfo.getTriple().isArch64Bit();
+  switch (_targetInfo.arch()) {
+    case MachOTargetInfo::arch_x86_64:
+      return true;
+    case MachOTargetInfo::arch_x86:
+    case MachOTargetInfo::arch_armv6:
+    case MachOTargetInfo::arch_armv7:
+    case MachOTargetInfo::arch_armv7s:
+      return false;
+    default:
+      llvm_unreachable("Unknown mach-o arch");
+  }
 }
 
 
diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
index 1255a22..ac3cf3b 100644
--- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp
+++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
@@ -916,8 +916,8 @@
    : lld::Reader(ti) {}
 
   virtual error_code parseFile(
-      std::unique_ptr<MemoryBuffer> mb,
-      std::vector<std::unique_ptr<lld::File> > &result) {
+      std::unique_ptr<MemoryBuffer> &mb,
+      std::vector<std::unique_ptr<lld::File> > &result) const {
     return File::make(_targetInfo, mb, mb->getBufferIdentifier(), result);
   }
 };
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
index 9b33daf..b752a79 100644
--- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -369,8 +369,8 @@
 public:
   ReaderCOFF(const TargetInfo &ti) : Reader(ti) {}
 
-  error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
-                       std::vector<std::unique_ptr<File> > &result) {
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File> > &result) const {
     llvm::error_code ec;
     std::unique_ptr<File> f(new FileCOFF(_targetInfo, std::move(mb), ec));
     if (ec) {
diff --git a/lld/lib/ReaderWriter/Reader.cpp b/lld/lib/ReaderWriter/Reader.cpp
index 17ee4f3..9f08ed2 100644
--- a/lld/lib/ReaderWriter/Reader.cpp
+++ b/lld/lib/ReaderWriter/Reader.cpp
@@ -19,12 +19,12 @@
 }
 
 error_code Reader::readFile(StringRef path,
-                            std::vector<std::unique_ptr<File>> &result) {
+                            std::vector<std::unique_ptr<File>> &result) const {
   OwningPtr<llvm::MemoryBuffer> 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);
+  return this->parseFile(mb, result);
 }
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ReaderArchive.cpp b/lld/lib/ReaderWriter/ReaderArchive.cpp
index 370348b..d3287dd 100644
--- a/lld/lib/ReaderWriter/ReaderArchive.cpp
+++ b/lld/lib/ReaderWriter/ReaderArchive.cpp
@@ -10,7 +10,6 @@
 #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"
@@ -46,8 +45,10 @@
     OwningPtr<MemoryBuffer> buff;
     if (ci->getMemoryBuffer(buff, true))
       return nullptr;
-    LinkerInput li(std::unique_ptr<MemoryBuffer>(buff.take()));
-    if (_getReader(li)->parseFile(li.takeBuffer(), result))
+    std::unique_ptr<MemoryBuffer> mb(buff.take());
+    if (_targetInfo.logInputFiles())
+      llvm::outs() << buff->getBufferIdentifier() << "\n";
+    if (_targetInfo.parseFile(mb, result))
       return nullptr;
 
     assert(result.size() == 1);
@@ -121,8 +122,7 @@
   }
 
 private:
-  std::function<ErrorOr<Reader&> (const LinkerInput &)> _getReader;
-  std::unique_ptr<llvm::object::Archive> _archive;
+  std::unique_ptr<llvm::object::Archive>    _archive;
   atom_collection_vector<DefinedAtom>       _definedAtoms;
   atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
   atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
@@ -132,10 +132,8 @@
 public:
   /// only subclasses of ArchiveLibraryFile can be instantiated
   FileArchive(const TargetInfo &ti,
-              std::function<ErrorOr<Reader &>(const LinkerInput &)> getReader,
               std::unique_ptr<llvm::MemoryBuffer> mb, error_code &ec)
-      : ArchiveLibraryFile(ti, mb->getBufferIdentifier()),
-        _getReader(getReader) {
+      : ArchiveLibraryFile(ti, mb->getBufferIdentifier()) {
     std::unique_ptr<llvm::object::Archive> archive_obj(
         new llvm::object::Archive(mb.release(), ec));
     if (ec)
@@ -155,16 +153,17 @@
     }
   }
 
-  std::unordered_map<StringRef, llvm::object::Archive::child_iterator> _symbolMemberMap;
+  std::unordered_map<StringRef, 
+                     llvm::object::Archive::child_iterator> _symbolMemberMap;
 }; // class FileArchive
 
 // 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){
+error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
+                            std::vector<std::unique_ptr<File>> &result) const {
   error_code ec;
 
-  if (_options._forceLoadArchives) {
+  if (_targetInfo.forceLoadAllArchives()) {
     _archive.reset(new llvm::object::Archive(mb.release(), ec));
     if (ec)
       return ec;
@@ -174,13 +173,15 @@
       OwningPtr<MemoryBuffer> buff;
       if ((ec = mf->getMemoryBuffer(buff, true)))
         return ec;
-      LinkerInput li(std::unique_ptr<MemoryBuffer>(buff.take()));
-      if ((ec = _getReader(li)->parseFile(li.takeBuffer(), result)))
+      std::unique_ptr<MemoryBuffer> mbc(buff.take());
+      if (_targetInfo.logInputFiles())
+        llvm::outs() << buff->getBufferIdentifier() << "\n";
+      if ((ec = _targetInfo.parseFile(mbc, result)))
         return ec;
     }
   } else {
     std::unique_ptr<File> f;
-    f.reset(new FileArchive(_targetInfo, _getReader, std::move(mb), ec));
+    f.reset(new FileArchive(_targetInfo, std::move(mb), ec));
     if (ec)
       return ec;
 
diff --git a/lld/lib/ReaderWriter/ReaderLinkerScript.cpp b/lld/lib/ReaderWriter/ReaderLinkerScript.cpp
index 4beb32a..646f97e 100644
--- a/lld/lib/ReaderWriter/ReaderLinkerScript.cpp
+++ b/lld/lib/ReaderWriter/ReaderLinkerScript.cpp
@@ -11,7 +11,6 @@
 
 #include "lld/Core/Error.h"
 #include "lld/Core/File.h"
-#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/LinkerScript.h"
 
 using namespace lld;
@@ -81,8 +80,8 @@
 
 namespace lld {
 error_code
-ReaderLinkerScript::parseFile(std::unique_ptr<llvm::MemoryBuffer> mb,
-                              std::vector<std::unique_ptr<File> > &result) {
+ReaderLinkerScript::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
+                            std::vector<std::unique_ptr<File> > &result) const {
   auto lsf = LinkerScriptFile::create(_targetInfo, std::move(mb));
   if (!lsf)
     return lsf;
@@ -91,10 +90,7 @@
   for (const auto &c : ls->_commands) {
     if (auto group = dyn_cast<Group>(c))
       for (const auto &path : group->getPaths()) {
-        auto reader = _getReader(LinkerInput(path._path));
-        if (!reader)
-          return reader;
-        if (error_code ec = reader->readFile(path._path, result))
+        if (error_code ec = _targetInfo.readFile(path._path, result))
           return ec;
       }
   }
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index c2945f7..5100d3a 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -288,16 +288,44 @@
                                                       llvm::raw_ostream &out) {
     assert(ctxt != nullptr);
     ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
-    auto relocStr = info->_targetInfo.stringFromRelocKind(value);
-    out << (relocStr ? *relocStr : "<unknown>");
-  }
+    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->_targetInfo.stringFromRelocKind(value))
+        out << *relocStr;
+      else 
+        out << "<unknown>";
+      break;
+    }
+  } 
 
   static StringRef input(StringRef scalar, void *ctxt, RefKind &value) {
     assert(ctxt != nullptr);
     ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
     auto relocKind = info->_targetInfo.relocKindFromString(scalar);
-    if (!relocKind)
+    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();
   }
@@ -1314,8 +1342,8 @@
 public:
   ReaderYAML(const TargetInfo &ti) : Reader(ti) {}
 
-  error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
-                       std::vector<std::unique_ptr<File>> &result) {
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                       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