At Jim Grosbach's request detemplate Object/MachO.h.

We are still able to handle mixed endian objects by swapping one struct at a
time.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179778 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index 4b6cb5f..e4d9ce2 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -53,7 +53,7 @@
 static cl::opt<std::string>
   DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
 
-static const Target *GetTarget(const MachOObjectFileBase *MachOObj) {
+static const Target *GetTarget(const MachOObjectFile *MachOObj) {
   // Figure out the target triple.
   if (TripleName.empty()) {
     llvm::Triple TT("unknown-unknown-unknown");
@@ -93,7 +93,7 @@
 
 // Print additional information about an address, if available.
 static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,
-                        const MachOObjectFileBase *MachOObj, raw_ostream &OS) {
+                        const MachOObjectFile *MachOObj, raw_ostream &OS) {
   for (unsigned i = 0; i != Sections.size(); ++i) {
     uint64_t SectAddr = 0, SectSize = 0;
     Sections[i].getAddress(SectAddr);
@@ -184,14 +184,12 @@
   Out << "}\n";
 }
 
-template<endianness E>
 static void
-getSectionsAndSymbols(const typename MachOObjectFileMiddle<E>::Header *Header,
-                      const MachOObjectFileMiddle<E> *MachOObj,
+getSectionsAndSymbols(const macho::Header Header,
+                      MachOObjectFile *MachOObj,
                       std::vector<SectionRef> &Sections,
                       std::vector<SymbolRef> &Symbols,
                       SmallVectorImpl<uint64_t> &FoundFns) {
-  typedef MachOObjectFileMiddle<E> ObjType;
   error_code ec;
   for (symbol_iterator SI = MachOObj->begin_symbols(),
        SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
@@ -205,23 +203,23 @@
     Sections.push_back(*SI);
   }
 
-  for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {
-    const typename ObjType::LoadCommand *Command =
-      MachOObj->getLoadCommandInfo(i);
-    if (Command->Type == macho::LCT_FunctionStarts) {
+  MachOObjectFile::LoadCommandInfo Command =
+    MachOObj->getFirstLoadCommandInfo();
+  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
+    if (Command.C.Type == macho::LCT_FunctionStarts) {
       // We found a function starts segment, parse the addresses for later
       // consumption.
-      const typename ObjType::LinkeditDataLoadCommand *LLC =
-    reinterpret_cast<const typename ObjType::LinkeditDataLoadCommand*>(Command);
+      macho::LinkeditDataLoadCommand LLC =
+        MachOObj->getLinkeditDataLoadCommand(Command);
 
-      MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
+      MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);
     }
+    Command = MachOObj->getNextLoadCommandInfo(Command);
   }
 }
 
-template<endianness E>
 static void DisassembleInputMachO2(StringRef Filename,
-                                   MachOObjectFileMiddle<E> *MachOOF);
+                                   MachOObjectFile *MachOOF);
 
 void llvm::DisassembleInputMachO(StringRef Filename) {
   OwningPtr<MemoryBuffer> Buff;
@@ -231,20 +229,14 @@
     return;
   }
 
-  OwningPtr<MachOObjectFileBase> MachOOF(static_cast<MachOObjectFileBase*>(
+  OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
         ObjectFile::createMachOObjectFile(Buff.take())));
 
-  if (MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachOOF.get())) {
-    DisassembleInputMachO2(Filename, O);
-    return;
-  }
-  MachOObjectFileBE *O = cast<MachOObjectFileBE>(MachOOF.get());
-  DisassembleInputMachO2(Filename, O);
+  DisassembleInputMachO2(Filename, MachOOF.get());
 }
 
-template<endianness E>
 static void DisassembleInputMachO2(StringRef Filename,
-                                   MachOObjectFileMiddle<E> *MachOOF) {
+                                   MachOObjectFile *MachOOF) {
   const Target *TheTarget = GetTarget(MachOOF);
   if (!TheTarget) {
     // GetTarget prints out stuff.
@@ -273,8 +265,7 @@
 
   outs() << '\n' << Filename << ":\n\n";
 
-  const typename MachOObjectFileMiddle<E>::Header *Header =
-    MachOOF->getHeader();
+  macho::Header Header = MachOOF->getHeader();
 
   std::vector<SectionRef> Sections;
   std::vector<SymbolRef> Symbols;
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 6f4b101..9985599 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -191,14 +191,6 @@
   return a_addr < b_addr;
 }
 
-StringRef
-getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) {
-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachO))
-    return O->getSectionFinalSegmentName(DR);
-  const MachOObjectFileBE *O = dyn_cast<MachOObjectFileBE>(MachO);
-  return O->getSectionFinalSegmentName(DR);
-}
-
 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
   const Target *TheTarget = getTarget(Obj);
   // getTarget() will have already issued a diagnostic if necessary, so
@@ -263,10 +255,10 @@
     std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
 
     StringRef SegmentName = "";
-    if (const MachOObjectFileBase *MachO =
-        dyn_cast<const MachOObjectFileBase>(Obj)) {
+    if (const MachOObjectFile *MachO =
+        dyn_cast<const MachOObjectFile>(Obj)) {
       DataRefImpl DR = i->getRawDataRefImpl();
-      SegmentName = getSectionFinalSegmentName(MachO, DR);
+      SegmentName = MachO->getSectionFinalSegmentName(DR);
     }
     StringRef name;
     if (error(i->getName(name))) break;
@@ -608,10 +600,10 @@
       else if (Section == o->end_sections())
         outs() << "*UND*";
       else {
-        if (const MachOObjectFileBase *MachO =
-            dyn_cast<const MachOObjectFileBase>(o)) {
+        if (const MachOObjectFile *MachO =
+            dyn_cast<const MachOObjectFile>(o)) {
           DataRefImpl DR = Section->getRawDataRefImpl();
-          StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);
+          StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
           outs() << SegmentName << ",";
         }
         StringRef SectionName;
diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp
index d4eaae6..54de49c 100644
--- a/tools/llvm-readobj/MachODumper.cpp
+++ b/tools/llvm-readobj/MachODumper.cpp
@@ -27,7 +27,7 @@
 
 class MachODumper : public ObjDumper {
 public:
-  MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer)
+  MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer)
     : ObjDumper(Writer)
     , Obj(Obj) { }
 
@@ -43,14 +43,12 @@
 
   void printRelocation(section_iterator SecI, relocation_iterator RelI);
 
-  template<support::endianness E>
-  void printRelocation(const MachOObjectFileMiddle<E> *Obj,
+  void printRelocation(const MachOObjectFile *Obj,
                        section_iterator SecI, relocation_iterator RelI);
 
-  template<support::endianness E>
-  void printSections(const MachOObjectFileMiddle<E> *Obj);
+  void printSections(const MachOObjectFile *Obj);
 
-  const MachOObjectFileBase *Obj;
+  const MachOObjectFile *Obj;
 };
 
 } // namespace
@@ -61,7 +59,7 @@
 error_code createMachODumper(const object::ObjectFile *Obj,
                              StreamWriter& Writer,
                              OwningPtr<ObjDumper> &Result) {
-  const MachOObjectFileBase *MachOObj = dyn_cast<MachOObjectFileBase>(Obj);
+  const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj);
   if (!MachOObj)
     return readobj_error::unsupported_obj_file_format;
 
@@ -164,59 +162,53 @@
   };
 }
 
-template<class MachOT>
-static void getSection(const MachOObjectFile<MachOT> *Obj,
-                       DataRefImpl DRI,
+static void getSection(const MachOObjectFile *Obj,
+                       DataRefImpl Sec,
                        MachOSection &Section) {
-  const typename MachOObjectFile<MachOT>::Section *Sect = Obj->getSection(DRI);
-  Section.Address     = Sect->Address;
-  Section.Size        = Sect->Size;
-  Section.Offset      = Sect->Offset;
-  Section.Alignment   = Sect->Align;
-  Section.RelocationTableOffset = Sect->RelocationTableOffset;
-  Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
-  Section.Flags       = Sect->Flags;
-  Section.Reserved1   = Sect->Reserved1;
-  Section.Reserved2   = Sect->Reserved2;
+  if (!Obj->is64Bit()) {
+    macho::Section Sect = Obj->getSection(Sec);
+    Section.Address     = Sect.Address;
+    Section.Size        = Sect.Size;
+    Section.Offset      = Sect.Offset;
+    Section.Alignment   = Sect.Align;
+    Section.RelocationTableOffset = Sect.RelocationTableOffset;
+    Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;
+    Section.Flags       = Sect.Flags;
+    Section.Reserved1   = Sect.Reserved1;
+    Section.Reserved2   = Sect.Reserved2;
+    return;
+  }
+  macho::Section64 Sect = Obj->getSection64(Sec);
+  Section.Address     = Sect.Address;
+  Section.Size        = Sect.Size;
+  Section.Offset      = Sect.Offset;
+  Section.Alignment   = Sect.Align;
+  Section.RelocationTableOffset = Sect.RelocationTableOffset;
+  Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;
+  Section.Flags       = Sect.Flags;
+  Section.Reserved1   = Sect.Reserved1;
+  Section.Reserved2   = Sect.Reserved2;
 }
 
-static void getSection(const MachOObjectFileBase *Obj,
-                       DataRefImpl DRI,
-                       MachOSection &Section) {
-  if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
-    return getSection(O, DRI, Section);
-  if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
-    return getSection(O, DRI, Section);
-  if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
-    return getSection(O, DRI, Section);
-  const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
-  getSection(O, DRI, Section);
-}
 
-template<class MachOT>
-static void getSymbol(const MachOObjectFile<MachOT> *Obj,
+static void getSymbol(const MachOObjectFile *Obj,
                       DataRefImpl DRI,
                       MachOSymbol &Symbol) {
-  const typename MachOObjectFile<MachOT>::SymbolTableEntry *Entry =
-    Obj->getSymbolTableEntry(DRI);
-  Symbol.StringIndex  = Entry->StringIndex;
-  Symbol.Type         = Entry->Type;
-  Symbol.SectionIndex = Entry->SectionIndex;
-  Symbol.Flags        = Entry->Flags;
-  Symbol.Value        = Entry->Value;
-}
-
-static void getSymbol(const MachOObjectFileBase *Obj,
-                      DataRefImpl DRI,
-                      MachOSymbol &Symbol) {
-  if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
-    return getSymbol(O, DRI, Symbol);
-  if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
-    return getSymbol(O, DRI, Symbol);
-  if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
-    return getSymbol(O, DRI, Symbol);
-  const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
-  getSymbol(O, DRI, Symbol);
+  if (!Obj->is64Bit()) {
+    macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI);
+    Symbol.StringIndex  = Entry.StringIndex;
+    Symbol.Type         = Entry.Type;
+    Symbol.SectionIndex = Entry.SectionIndex;
+    Symbol.Flags        = Entry.Flags;
+    Symbol.Value        = Entry.Value;
+    return;
+  }
+  macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI);
+  Symbol.StringIndex  = Entry.StringIndex;
+  Symbol.Type         = Entry.Type;
+  Symbol.SectionIndex = Entry.SectionIndex;
+  Symbol.Flags        = Entry.Flags;
+  Symbol.Value        = Entry.Value;
 }
 
 void MachODumper::printFileHeaders() {
@@ -224,14 +216,10 @@
 }
 
 void MachODumper::printSections() {
-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
-    return printSections(O);
-  const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
-  return printSections(O);
+  return printSections(Obj);
 }
 
-template<support::endianness E>
-void MachODumper::printSections(const MachOObjectFileMiddle<E> *Obj) {
+void MachODumper::printSections(const MachOObjectFile *Obj) {
   ListScope Group(W, "Sections");
 
   int SectionIndex = -1;
@@ -344,14 +332,10 @@
 
 void MachODumper::printRelocation(section_iterator SecI,
                                   relocation_iterator RelI) {
-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
-    return printRelocation(O, SecI, RelI);
-  const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
-  return printRelocation(O, SecI, RelI);
+  return printRelocation(Obj, SecI, RelI);
 }
 
-template<support::endianness E>
-void MachODumper::printRelocation(const MachOObjectFileMiddle<E> *Obj,
+void MachODumper::printRelocation(const MachOObjectFile *Obj,
                                   section_iterator SecI,
                                   relocation_iterator RelI) {
   uint64_t Offset;
@@ -364,31 +348,30 @@
   if (error(Symbol.getName(SymbolName))) return;
 
   DataRefImpl DR = RelI->getRawDataRefImpl();
-  const typename MachOObjectFileMiddle<E>::RelocationEntry *RE =
-    Obj->getRelocation(DR);
+  macho::RelocationEntry RE = Obj->getRelocation(DR);
   bool IsScattered = Obj->isRelocationScattered(RE);
 
   if (opts::ExpandRelocs) {
     DictScope Group(W, "Relocation");
     W.printHex("Offset", Offset);
-    W.printNumber("PCRel", Obj->isRelocationPCRel(RE));
-    W.printNumber("Length", Obj->getRelocationLength(RE));
+    W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE));
+    W.printNumber("Length", Obj->getAnyRelocationLength(RE));
     if (IsScattered)
       W.printString("Extern", StringRef("N/A"));
     else
-      W.printNumber("Extern", RE->External);
-    W.printNumber("Type", RelocName, RE->Type);
+      W.printNumber("Extern", Obj->getPlainRelocationExternal(RE));
+    W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE));
     W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
     W.printNumber("Scattered", IsScattered);
   } else {
     raw_ostream& OS = W.startLine();
     OS << W.hex(Offset)
-       << " " << Obj->isRelocationPCRel(RE)
-       << " " << Obj->getRelocationLength(RE);
+       << " " << Obj->getAnyRelocationPCRel(RE)
+       << " " << Obj->getAnyRelocationLength(RE);
     if (IsScattered)
       OS << " n/a";
     else
-      OS << " " << RE->External;
+      OS << " " << Obj->getPlainRelocationExternal(RE);
     OS << " " << RelocName
        << " " << IsScattered
        << " " << (SymbolName.size() > 0 ? SymbolName : "-")
diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp
index ffe8712..29d91a0 100644
--- a/tools/llvm-symbolizer/LLVMSymbolize.cpp
+++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp
@@ -233,7 +233,7 @@
     // On Darwin we may find DWARF in separate object file in
     // resource directory.
     ObjectFile *DbgObj = Obj;
-    if (isa<MachOObjectFileBase>(Obj)) {
+    if (isa<MachOObjectFile>(Obj)) {
       const std::string &ResourceName =
           getDarwinDWARFResourceForModule(ModuleName);
       ObjectFile *ResourceObj = getObjectFile(ResourceName);