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/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");
+  }
 }