Move everything over to TargetInfo.

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

llvm-svn: 173217
diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
index aa3e54c..b12d564 100644
--- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
@@ -5,7 +5,6 @@
   ReaderELF.cpp
   ReferenceKinds.cpp
   WriterELF.cpp
-  WriterOptionsELF.cpp
   X86Reference.cpp
   X86_64Reference.cpp
   )
diff --git a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
index ae859d8..86e61ec 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
@@ -10,6 +10,8 @@
 #ifndef LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
 #define LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
 
+#include "lld/Core/LinkerOptions.h"
+
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
@@ -150,7 +152,7 @@
 
   typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT;
 
-  DefaultELFLayout(const WriterOptionsELF &options) : _options(options) {}
+  DefaultELFLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
 
   /// \brief Return the section order for a input section
   virtual SectionOrder getSectionOrder
@@ -250,7 +252,7 @@
   ELFProgramHeader<ELFT> *_programHeader;
   std::vector<AbsoluteAtomPair> _absoluteAtoms;
   llvm::BumpPtrAllocator _allocator;
-  const WriterOptionsELF _options;
+  const ELFTargetInfo &_targetInfo;
 };
 
 template<class ELFT>
@@ -483,7 +485,7 @@
           segment = segmentInsert.first->second;
         } else {
           segment = new (_allocator.Allocate<Segment<ELFT>>()) Segment<ELFT>(
-            segmentName, getSegmentType(section), _options);
+            segmentName, getSegmentType(section), _targetInfo);
           segmentInsert.first->second = segment;
           _segments.push_back(segment);
         }
@@ -516,7 +518,7 @@
   if (_segments.empty())
     return;
   
-  uint64_t virtualAddress = _options.baseAddress();
+  uint64_t virtualAddress = _targetInfo.getLinkerOptions()._baseAddress;
   
   // HACK: This is a super dirty hack. The elf header and program header are
   // not part of a section, but we need them to be loaded at the base address
@@ -539,7 +541,7 @@
     for (auto &si : _segments) {
       // Align the segment to a page boundary
       fileoffset = llvm::RoundUpToAlignment(fileoffset,
-                                            _options.pageSize());
+                                            _targetInfo.getPageSize());
       si->assignOffsets(fileoffset);
       fileoffset = si->fileOffset() + si->fileSize();
     }
@@ -552,7 +554,7 @@
       (*si)->assignVirtualAddress(address);
       (*si)->setMemSize(address - virtualAddress);
       virtualAddress = llvm::RoundUpToAlignment(address,
-                                                _options.pageSize());
+                                                _targetInfo.getPageSize());
     }
     _programHeader->resetProgramHeaders();
   }
diff --git a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
index 0e329b4..1773137 100644
--- a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
+++ b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
@@ -11,7 +11,7 @@
 #define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H_
 
 #include "lld/Core/range.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -113,7 +113,7 @@
 
   Segment(const StringRef name,
           const ELFLayout::SegmentType type,
-          const WriterOptionsELF &options);
+          const ELFTargetInfo &ti);
 
   /// append a section to a segment
   void append(Section<ELFT> *section);
@@ -168,7 +168,7 @@
 
   inline ELFLayout::SegmentType segmentType() { return _segmentType; }
 
-  inline int pageSize() const { return _options.pageSize(); }
+  inline int pageSize() const { return _targetInfo.getPageSize(); }
 
   inline int64_t atomflags() const { return _atomflags; }
 
@@ -195,19 +195,19 @@
   ELFLayout::SegmentType _segmentType;
   int64_t _flags;
   int64_t _atomflags;
-  const WriterOptionsELF _options;
+  const ELFTargetInfo &_targetInfo;
   llvm::BumpPtrAllocator _segmentAllocate;
 };
 
 template<class ELFT>
 Segment<ELFT>::Segment(const StringRef name,
                        const ELFLayout::SegmentType type,
-                       const WriterOptionsELF &options)
+                       const ELFTargetInfo &ti)
   : Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment)
   , _segmentType(type)
   , _flags(0)
   , _atomflags(0)
-  , _options(options) {
+  , _targetInfo(ti) {
   this->_align2 = 0;
   this->_fsize = 0;
 }
@@ -268,7 +268,7 @@
       SegmentSlice<ELFT> *slice = nullptr;
       // If the newOffset computed is more than a page away, lets create
       // a seperate segment, so that memory is not used up while running
-      if ((newOffset - curOffset) > _options.pageSize()) {
+      if ((newOffset - curOffset) > _targetInfo.getPageSize()) {
         // TODO: use std::find here
         for (auto s : slices()) {
           if (s->startSection() == startSection) {
@@ -286,7 +286,7 @@
         slice->setSize(curSliceSize);
         slice->setAlign(sliceAlign);
         uint64_t newPageOffset =
-          llvm::RoundUpToAlignment(curOffset, _options.pageSize());
+          llvm::RoundUpToAlignment(curOffset, _targetInfo.getPageSize());
         newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());
         curSliceFileOffset = newOffset;
         startSectionIter = endSectionIter;
@@ -332,7 +332,7 @@
 Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
   for (auto slice : slices()) {
     // Align to a page
-    addr = llvm::RoundUpToAlignment(addr, _options.pageSize());
+    addr = llvm::RoundUpToAlignment(addr, _targetInfo.getPageSize());
     // Align to the slice alignment
     addr = llvm::RoundUpToAlignment(addr, slice->align2());
 
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index 9a086f8..5c4cbfc 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -23,6 +23,13 @@
     return llvm::ELF::ET_REL;
   case OutputKind::Shared:
     return llvm::ELF::ET_DYN;
+  case OutputKind::Core:
+    return llvm::ELF::ET_CORE;
+  case OutputKind::SharedStubs:
+  case OutputKind::DebugSymbols:
+  case OutputKind::Bundle:
+  case OutputKind::Preload:
+    break;
   }
   llvm_unreachable("Unhandled OutputKind");
 }
@@ -42,21 +49,21 @@
   }
 }
 
-class X86ELFTargetInfo final : public ELFTargetInfo {
+class X86ELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 };
 
-class HexagonELFTargetInfo final : public ELFTargetInfo {
+class HexagonELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 };
 
-class PPCELFTargetInfo final : public ELFTargetInfo {
+class PPCELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
 
diff --git a/lld/lib/ReaderWriter/ELF/ELFWriter.h b/lld/lib/ReaderWriter/ELF/ELFWriter.h
index 517d61c..20b83fd 100644
--- a/lld/lib/ReaderWriter/ELF/ELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/ELFWriter.h
@@ -12,7 +12,7 @@
 
 #include "lld/Core/File.h"
 #include "lld/Core/InputFiles.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "ReferenceKinds.h"
 
 namespace lld {
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
index 1820b2c..f0531ac 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
@@ -15,7 +15,7 @@
 #include "lld/Core/UndefinedAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 #include "AtomsELF.h"
 
 namespace lld {
@@ -30,9 +30,7 @@
 class CRuntimeFile : public File {
 public:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-  CRuntimeFile(const WriterOptionsELF &options) 
-    : File("C runtime") 
-  { }
+  CRuntimeFile(const ELFTargetInfo &) : File("C runtime") {}
   
   /// \brief add a global absolute atom
   void addAbsoluteAtom(const StringRef symbolName) {
diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
index 16e53f2..deaf663 100644
--- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
@@ -13,10 +13,12 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "lld/ReaderWriter/ReaderELF.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
+#include "lld/ReaderWriter/Reader.h"
+
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+#include "lld/ReaderWriter/ReaderArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
@@ -326,12 +328,9 @@
 /// memory buffer for ELF class and bit width
 class ReaderELF : public Reader {
 public:
-  ReaderELF(const ReaderOptionsELF &,
-            ReaderOptionsArchive &readerOptionsArchive)
-      : _readerOptionsArchive(readerOptionsArchive),
-        _readerArchive(_readerOptionsArchive) {
-    _readerOptionsArchive.setReader(this);
-  }
+  ReaderELF(const TargetInfo & ti, std::function<ReaderFunc> read)
+      : Reader(ti),
+        _readerArchive(ti, read) {}
 
   error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
                        std::vector<std::unique_ptr<File>> &result) {
@@ -411,18 +410,13 @@
   }
 
 private:
-  ReaderOptionsArchive &_readerOptionsArchive;
   ReaderArchive _readerArchive;
 };
 } // end anon namespace.
 
 namespace lld {
-ReaderOptionsELF::ReaderOptionsELF() {}
-
-ReaderOptionsELF::~ReaderOptionsELF() {}
-
-Reader *createReaderELF(const ReaderOptionsELF &options,
-                        ReaderOptionsArchive &optionsArchive) {
-  return new ReaderELF(options, optionsArchive);
+std::unique_ptr<Reader> createReaderELF(const TargetInfo & ti,
+                                        std::function<ReaderFunc> read) {
+  return std::unique_ptr<Reader>(new ReaderELF(ti, std::move(read)));
 }
 } // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
index 083e843..769895a 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
@@ -11,29 +11,30 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
 
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ELF.h"
 
 namespace lld {
 namespace elf {
-KindHandler::KindHandler() {
-}
+KindHandler::KindHandler() {}
 
-KindHandler::~KindHandler() {
-}
+KindHandler::~KindHandler() {}
 
 std::unique_ptr<KindHandler>
-KindHandler::makeHandler(uint16_t arch, llvm::support::endianness endian) {
+KindHandler::makeHandler(llvm::Triple::ArchType arch, bool isLittleEndian) {
   switch(arch) {
-  case llvm::ELF::EM_HEXAGON:
+  case llvm::Triple::hexagon:
     return std::unique_ptr<KindHandler>(new HexagonKindHandler());
-  case llvm::ELF::EM_386:
+  case llvm::Triple::x86:
     return std::unique_ptr<KindHandler>(new X86KindHandler());
-  case llvm::ELF::EM_X86_64:
+  case llvm::Triple::x86_64:
     return std::unique_ptr<KindHandler>(new X86_64KindHandler());
-  case llvm::ELF::EM_PPC:
-    return std::unique_ptr<KindHandler>(new PPCKindHandler(endian));
+  case llvm::Triple::ppc:
+    return std::unique_ptr<KindHandler>(
+        new PPCKindHandler(isLittleEndian ? llvm::support::little
+                                          : llvm::support::big));
   default:
     llvm_unreachable("arch not supported");
   }
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
index faa4299..45f6cae 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
@@ -9,9 +9,12 @@
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
 
 #include <functional>
 #include <map>
@@ -32,8 +35,8 @@
 public:
   typedef Reference::Kind Kind;
 
-  static std::unique_ptr<KindHandler> makeHandler(uint16_t arch,
-                                      llvm::support::endianness endian);
+  static std::unique_ptr<KindHandler> makeHandler(llvm::Triple::ArchType arch,
+                                                  bool isLittleEndian);
   virtual             ~KindHandler();
   virtual Kind        stringToKind(StringRef str) = 0;
   virtual StringRef   kindToString(Kind) = 0;
diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
index d9be025..73bb6bb 100644
--- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
 #include "DefaultELFLayout.h"
 #include "ExecutableAtoms.h"
 
@@ -26,7 +28,7 @@
   typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
   typedef Elf_Sym_Impl<ELFT> Elf_Sym;
 
-  ELFExecutableWriter(const WriterOptionsELF &options);
+  ELFExecutableWriter(const ELFTargetInfo &ti);
 
 private:
   // build the sections that need to be created
@@ -49,7 +51,7 @@
 
   void createDefaultSections();
 
-  const WriterOptionsELF &_options;
+  const ELFTargetInfo &_targetInfo;
 
   typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
   std::unique_ptr<KindHandler> _referenceKindHandler;
@@ -69,12 +71,12 @@
 //  ELFExecutableWriter
 //===----------------------------------------------------------------------===//
 template<class ELFT>
-ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options)
-  : _options(options)
+ELFExecutableWriter<ELFT>::ELFExecutableWriter(const ELFTargetInfo &ti)
+  : _targetInfo(ti)
   , _referenceKindHandler(KindHandler::makeHandler(
-      _options.machine(), (endianness)ELFT::TargetEndianness))
-  , _runtimeFile(options) {
-  _layout =new DefaultELFLayout<ELFT>(options);
+                              ti.getTriple().getArch(), ti.isLittleEndian()))
+  , _runtimeFile(ti) {
+  _layout = new DefaultELFLayout<ELFT>(ti);
 }
 
 template<class ELFT>
@@ -248,14 +250,14 @@
   if (ec)
     return ec;
 
-  _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
-                                                        : ELF::ELFCLASS32));
-  _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big
-                                    ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);
+  _elfHeader->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
+                                                            : ELF::ELFCLASS32);
+  _elfHeader->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
+                                    ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
   _elfHeader->e_ident(ELF::EI_VERSION, 1);
   _elfHeader->e_ident(ELF::EI_OSABI, 0);
-  _elfHeader->e_type(_options.type());
-  _elfHeader->e_machine(_options.machine());
+  _elfHeader->e_type(_targetInfo.getOutputType());
+  _elfHeader->e_machine(_targetInfo.getOutputMachine());
   _elfHeader->e_version(1);
   _elfHeader->e_entry(0ULL);
   _elfHeader->e_phoff(_programHeader->fileOffset());
@@ -305,24 +307,24 @@
 }
 } // namespace elf
 
-Writer *createWriterELF(const WriterOptionsELF &options) {
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
   using llvm::object::ELFType;
   // Set the default layout to be the static executable layout
   // We would set the layout to a dynamic executable layout
   // if we came across any shared libraries in the process
 
-  if (!options.is64Bit() && options.endianness() == llvm::support::little)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options);
-  else if (options.is64Bit() && options.endianness() == llvm::support::little)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options);
-  else if (!options.is64Bit() && options.endianness() == llvm::support::big)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options);
-  else if (options.is64Bit() && options.endianness() == llvm::support::big)
-    return
-      new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options);
+  if (!TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(TI));
+  else if (TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(TI));
+  else if (!TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(TI));
+  else if (TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(TI));
 
   llvm_unreachable("Invalid Options!");
 }
diff --git a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
deleted file mode 100644
index 4d832ae..0000000
--- a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===- lib/ReaderWriter/ELF/WriterOptionsELF.cpp ----------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/WriterELF.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/system_error.h"
-
-
-namespace lld {
-
-StringRef WriterOptionsELF::entryPoint() const {
-  if (_type == llvm::ELF::ET_EXEC)
-    return _entryPoint;
-  return StringRef();
-}
-
-} // namespace lld