Add {,ELF,MachO}TargetInfo.
llvm-svn: 173117
diff --git a/lld/lib/Core/CMakeLists.txt b/lld/lib/Core/CMakeLists.txt
index 877da26..44becf4 100644
--- a/lld/lib/Core/CMakeLists.txt
+++ b/lld/lib/Core/CMakeLists.txt
@@ -7,4 +7,5 @@
   InputFiles.cpp
   Resolver.cpp
   SymbolTable.cpp
+  TargetInfo.cpp
   )
diff --git a/lld/lib/Core/TargetInfo.cpp b/lld/lib/Core/TargetInfo.cpp
new file mode 100644
index 0000000..da834fb
--- /dev/null
+++ b/lld/lib/Core/TargetInfo.cpp
@@ -0,0 +1,35 @@
+//===- lib/Core/TargetInfo.cpp - Linker Target Info Interface -------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/Core/TargetInfo.h"
+
+#include "lld/Core/LinkerOptions.h"
+
+#include "llvm/ADT/Triple.h"
+
+namespace lld {
+TargetInfo::~TargetInfo() {}
+
+llvm::Triple TargetInfo::getTriple() const {
+  return llvm::Triple(llvm::Triple::normalize(_options._target));
+}
+
+bool TargetInfo::is64Bits() const {
+  return getTriple().isArch64Bit();
+}
+
+bool TargetInfo::isLittleEndian() const {
+  // TODO: Do this properly. It is not defined purely by arch.
+  return true;
+}
+
+StringRef TargetInfo::getEntry() const {
+  return _options._entrySymbol;
+}
+} // end namespace lld
diff --git a/lld/lib/Driver/Drivers.cpp b/lld/lib/Driver/Drivers.cpp
index 83fb83c..2063878 100644
--- a/lld/lib/Driver/Drivers.cpp
+++ b/lld/lib/Driver/Drivers.cpp
@@ -15,7 +15,7 @@
 
 #include "lld/Driver/Driver.h"
 
-#include "lld/Driver/LinkerOptions.h"
+#include "lld/Core/LinkerOptions.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
diff --git a/lld/lib/Driver/Targets.cpp b/lld/lib/Driver/Targets.cpp
index 68cb553..ae82e90 100644
--- a/lld/lib/Driver/Targets.cpp
+++ b/lld/lib/Driver/Targets.cpp
@@ -15,6 +15,7 @@
 
 #include "lld/Driver/Target.h"
 
+#include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ReaderArchive.h"
 #include "lld/ReaderWriter/ReaderELF.h"
 #include "lld/ReaderWriter/ReaderYAML.h"
diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
index f69929e..aa3e54c 100644
--- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_lld_library(lldELF
+  ELFTargetInfo.cpp
   HexagonReference.cpp
   PPCReference.cpp
   ReaderELF.cpp
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
new file mode 100644
index 0000000..9a086f8
--- /dev/null
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -0,0 +1,81 @@
+//===- lib/ReaderWriter/ELF/ELFTargetInfo.cpp -----------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
+#include "lld/Core/LinkerOptions.h"
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ELF.h"
+
+namespace lld {
+uint16_t ELFTargetInfo::getOutputType() const {
+  switch (_options._outputKind) {
+  case OutputKind::Executable:
+    return llvm::ELF::ET_EXEC;
+  case OutputKind::Relocatable:
+    return llvm::ELF::ET_REL;
+  case OutputKind::Shared:
+    return llvm::ELF::ET_DYN;
+  }
+  llvm_unreachable("Unhandled OutputKind");
+}
+
+uint16_t ELFTargetInfo::getOutputMachine() const {
+  switch (getTriple().getArch()) {
+  case llvm::Triple::x86:
+    return llvm::ELF::EM_386;
+  case llvm::Triple::x86_64:
+    return llvm::ELF::EM_X86_64;
+  case llvm::Triple::hexagon:
+    return llvm::ELF::EM_HEXAGON;
+  case llvm::Triple::ppc:
+    return llvm::ELF::EM_PPC;
+  default:
+    llvm_unreachable("Unhandled arch");
+  }
+}
+
+class X86ELFTargetInfo final : public ELFTargetInfo {
+public:
+  X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
+
+  virtual uint64_t getPageSize() const { return 0x1000; }
+};
+
+class HexagonELFTargetInfo final : public ELFTargetInfo {
+public:
+  HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
+
+  virtual uint64_t getPageSize() const { return 0x1000; }
+};
+
+class PPCELFTargetInfo final : public ELFTargetInfo {
+public:
+  PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
+
+  virtual bool isLittleEndian() const { return false; }
+
+  virtual uint64_t getPageSize() const { return 0x1000; }
+};
+
+std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(const LinkerOptions &lo) {
+  switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) {
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    return std::unique_ptr<ELFTargetInfo>(new X86ELFTargetInfo(lo));
+  case llvm::Triple::hexagon:
+    return std::unique_ptr<ELFTargetInfo>(new HexagonELFTargetInfo(lo));
+  case llvm::Triple::ppc:
+    return std::unique_ptr<ELFTargetInfo>(new PPCELFTargetInfo(lo));
+  default:
+    return std::unique_ptr<ELFTargetInfo>();
+  }
+}
+} // end namespace lld
diff --git a/lld/lib/ReaderWriter/MachO/CMakeLists.txt b/lld/lib/ReaderWriter/MachO/CMakeLists.txt
index c315ecc..db64d87 100644
--- a/lld/lib/ReaderWriter/MachO/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/MachO/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_lld_library(lldMachO
+  MachOTargetInfo.cpp
   WriterMachO.cpp
   WriterOptionsMachO.cpp
   ReferenceKinds.cpp
diff --git a/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
new file mode 100644
index 0000000..d24680a
--- /dev/null
+++ b/lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
@@ -0,0 +1,62 @@
+//===- lib/ReaderWriter/MachO/MachOTargetInfo.cpp -------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/ReaderWriter/MachOTargetInfo.h"
+
+#include "lld/Core/LinkerOptions.h"
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/MachO.h"
+
+namespace lld {
+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:
+    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:
+    llvm_unreachable("Unknown arch type");
+  }
+}
+
+class GenericMachOTargetInfo final : public MachOTargetInfo {
+public:
+  GenericMachOTargetInfo(const LinkerOptions &lo) : MachOTargetInfo(lo) {}
+
+  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";
+  }
+};
+
+std::unique_ptr<MachOTargetInfo>
+MachOTargetInfo::create(const LinkerOptions &lo) {
+  return std::unique_ptr<MachOTargetInfo>(new GenericMachOTargetInfo(lo));
+}
+} // end namespace lld