[llvm] r179440 - Finish templating MachObjectFile over endianness.

Rafael Espindola rafael.espindola at gmail.com
Fri Apr 12 18:45:41 PDT 2013


Author: rafael
Date: Fri Apr 12 20:45:40 2013
New Revision: 179440

URL: http://llvm.org/viewvc/llvm-project?rev=179440&view=rev
Log:
Finish templating MachObjectFile over endianness.

We are now able to handle big endian macho files in llvm-readobject. Thanks to
David Fang for providing the object files.

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc
    llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc64
Modified:
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/tools/llvm-readobj/relocations.test
    llvm/trunk/test/tools/llvm-readobj/sections-ext.test
    llvm/trunk/test/tools/llvm-readobj/sections.test
    llvm/trunk/tools/llvm-objdump/MachODump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-readobj/MachODumper.cpp

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Fri Apr 12 20:45:40 2013
@@ -20,7 +20,9 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/Object/MachOFormat.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/MachO.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -36,6 +38,25 @@ struct MachOType {
 };
 
 template<endianness TargetEndianness>
+struct MachOInt24Impl;
+
+template<>
+struct MachOInt24Impl<support::little> {
+  uint8_t bytes[3];
+  operator uint32_t() const {
+    return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];
+  }
+};
+
+template<>
+struct MachOInt24Impl<support::big> {
+  uint8_t bytes[3];
+  operator uint32_t() const {
+    return (bytes[0] << 24) | (bytes[1] << 16) | bytes[2];
+  }
+};
+
+template<endianness TargetEndianness>
 struct MachODataTypeTypedefHelperCommon {
   typedef support::detail::packed_endian_specific_integral
     <uint16_t, TargetEndianness, support::unaligned> MachOInt16;
@@ -43,12 +64,14 @@ struct MachODataTypeTypedefHelperCommon
     <uint32_t, TargetEndianness, support::unaligned> MachOInt32;
   typedef support::detail::packed_endian_specific_integral
     <uint64_t, TargetEndianness, support::unaligned> MachOInt64;
+  typedef MachOInt24Impl<TargetEndianness> MachOInt24;
 };
 
 #define LLVM_MACHOB_IMPORT_TYPES(E)                                          \
 typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \
 typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \
-typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64;
+typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; \
+typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt24 MachOInt24;
 
 template<class MachOT>
 struct MachODataTypeTypedefHelper;
@@ -120,8 +143,11 @@ namespace MachOFormat {
   };
 
   template<endianness TargetEndianness>
-  struct RelocationEntry {
-    LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
+  struct RelocationEntry;
+
+  template<>
+  struct RelocationEntry<support::little> {
+    LLVM_MACHOB_IMPORT_TYPES(support::little)
     MachOInt32 Address;
     MachOInt24 SymbolNum;
     uint8_t Bits;
@@ -140,9 +166,33 @@ namespace MachOFormat {
     }
   };
 
+  template<>
+  struct RelocationEntry<support::big> {
+    LLVM_MACHOB_IMPORT_TYPES(support::big)
+    MachOInt32 Address;
+    MachOInt24 SymbolNum;
+    uint8_t Bits;
+
+    unsigned getType() const {
+      return Bits &0xf;
+    }
+    unsigned getExternal() const {
+      return (Bits >> 4) & 0x1;
+    }
+    unsigned getLength() const {
+      return (Bits >> 5) & 0x3;
+    }
+    unsigned getPCRel() const {
+      return Bits >> 7;
+    }
+  };
+
   template<endianness TargetEndianness>
-  struct ScatteredRelocationEntry {
-    LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
+  struct ScatteredRelocationEntry;
+
+  template<>
+  struct ScatteredRelocationEntry<support::little> {
+    LLVM_MACHOB_IMPORT_TYPES(support::little)
     MachOInt24 Address;
     uint8_t Bits;
     MachOInt32 Value;
@@ -161,6 +211,26 @@ namespace MachOFormat {
     }
   };
 
+  template<>
+  struct ScatteredRelocationEntry<support::big> {
+    LLVM_MACHOB_IMPORT_TYPES(support::big)
+    uint8_t Bits;
+    unsigned getType() const {
+      return Bits & 0xf;
+    }
+    unsigned getLength() const {
+      return (Bits >> 4) & 0x3;
+    }
+    unsigned getPCRel() const {
+      return (Bits >> 6) & 0x1;
+    }
+    unsigned getScattered() const {
+      return Bits >> 7;
+    }
+    MachOInt24 Address;
+    MachOInt32 Value;
+  };
+
   template<endianness TargetEndianness>
   struct SymbolTableEntryBase {
     LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
@@ -244,69 +314,32 @@ namespace MachOFormat {
 
 class MachOObjectFileBase : public ObjectFile {
 public:
-  typedef MachOFormat::SymbolTableEntryBase<support::little>
-    SymbolTableEntryBase;
-  typedef MachOFormat::SymtabLoadCommand<support::little> SymtabLoadCommand;
-  typedef MachOFormat::RelocationEntry<support::little> RelocationEntry;
-  typedef MachOFormat::ScatteredRelocationEntry<support::little>
-    ScatteredRelocationEntry;
   typedef MachOFormat::SectionBase SectionBase;
-  typedef MachOFormat::LoadCommand<support::little> LoadCommand;
-  typedef MachOFormat::Header<support::little> Header;
-  typedef MachOFormat::LinkeditDataLoadCommand<support::little>
-    LinkeditDataLoadCommand;
 
-  MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
+  MachOObjectFileBase(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
+                      error_code &ec);
 
-  virtual symbol_iterator begin_symbols() const;
-  virtual symbol_iterator end_symbols() const;
   virtual symbol_iterator begin_dynamic_symbols() const;
   virtual symbol_iterator end_dynamic_symbols() const;
   virtual library_iterator begin_libraries_needed() const;
   virtual library_iterator end_libraries_needed() const;
-  virtual section_iterator end_sections() const;
 
   virtual uint8_t getBytesInAddress() const;
-  virtual StringRef getFileFormatName() const;
-  virtual unsigned getArch() const;
   virtual StringRef getLoadName() const;
 
-  // In a MachO file, sections have a segment name. This is used in the .o
-  // files. They have a single segment, but this field specifies which segment
-  // a section should be put in in the final object.
-  StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
-
-  // Names are stored as 16 bytes. These returns the raw 16 bytes without
-  // interpreting them as a C string.
-  ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
-  ArrayRef<char>getSectionRawFinalSegmentName(DataRefImpl Sec) const;
-
   bool is64Bit() const;
-  const LoadCommand *getLoadCommandInfo(unsigned Index) const;
   void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
-  const Header *getHeader() const;
   unsigned getHeaderSize() const;
   StringRef getData(size_t Offset, size_t Size) const;
-  const RelocationEntry *getRelocation(DataRefImpl Rel) const;
-  bool isScattered(const RelocationEntry *RE) const;
-  bool isPCRel(const RelocationEntry *RE) const;
-  unsigned getLength(const RelocationEntry *RE) const;
-  unsigned getType(const RelocationEntry *RE) const;
 
   static inline bool classof(const Binary *v) {
     return v->isMachO();
   }
 
 protected:
-  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
-  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
-  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
-  virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
-  virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
-  virtual error_code getSymbolSection(DataRefImpl Symb,
-                                      section_iterator &Res) const;
+  StringRef parseSegmentOrSectionName(const char *P) const;
+
   virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
   virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
   virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
   virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
@@ -327,17 +360,75 @@ protected:
 
   typedef SmallVector<DataRefImpl, 1> SectionList;
   SectionList Sections;
+};
+
+template<endianness TargetEndianness>
+class MachOObjectFileMiddle : public MachOObjectFileBase {
+public:
+
+  typedef MachOFormat::SymbolTableEntryBase<TargetEndianness>
+    SymbolTableEntryBase;
+  typedef MachOFormat::LinkeditDataLoadCommand<TargetEndianness>
+    LinkeditDataLoadCommand;
+  typedef MachOFormat::Header<TargetEndianness> Header;
+  typedef MachOFormat::SymtabLoadCommand<TargetEndianness> SymtabLoadCommand;
+  typedef MachOFormat::RelocationEntry<TargetEndianness> RelocationEntry;
+  typedef MachOFormat::ScatteredRelocationEntry<TargetEndianness>
+    ScatteredRelocationEntry;
+  typedef MachOFormat::LoadCommand<TargetEndianness> LoadCommand;
+
+  MachOObjectFileMiddle(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
+
+  const Header *getHeader() const;
+  const LoadCommand *getLoadCommandInfo(unsigned Index) const;
+  const RelocationEntry *getRelocation(DataRefImpl Rel) const;
+  bool isRelocationScattered(const RelocationEntry *RE) const;
+  bool isRelocationPCRel(const RelocationEntry *RE) const;
+  unsigned getRelocationLength(const RelocationEntry *RE) const;
+  unsigned getRelocationTypeImpl(const RelocationEntry *RE) const;
 
   void moveToNextSymbol(DataRefImpl &DRI) const;
   void printRelocationTargetName(const RelocationEntry *RE,
                                  raw_string_ostream &fmt) const;
   const SectionBase *getSectionBase(DataRefImpl DRI) const;
   const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI) const;
+  unsigned getCPUType() const;
+
+  // In a MachO file, sections have a segment name. This is used in the .o
+  // files. They have a single segment, but this field specifies which segment
+  // a section should be put in in the final object.
+  StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
+
+  // Names are stored as 16 bytes. These returns the raw 16 bytes without
+  // interpreting them as a C string.
+  ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
+  ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
+
+  virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
+  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
+  virtual error_code getSymbolType(DataRefImpl Symb,
+                                   SymbolRef::Type &Res) const;
+  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
+  virtual error_code getSymbolSection(DataRefImpl Symb,
+                                      section_iterator &Res) const;
+  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
+  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
+  virtual symbol_iterator begin_symbols() const;
+  virtual unsigned getArch() const;
+  virtual StringRef getFileFormatName() const;
+  virtual symbol_iterator end_symbols() const;
+  virtual section_iterator end_sections() const;
+
+  static bool classof(const Binary *v);
 
 private:
+  // Helper to advance a section or symbol iterator multiple increments at a
+  // time.
+  template<class T>
+  static error_code advance(T &it, size_t Val);
 
-  const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI,
-                                  const SymtabLoadCommand *SymtabLoadCmd) const;
+  template<class T>
+  static void advanceTo(T &it, size_t Val);
 };
 
 template<class MachOT>
@@ -369,11 +460,17 @@ struct MachOObjectFileHelper<MachOType<T
 };
 
 template<class MachOT>
-class MachOObjectFile : public MachOObjectFileBase {
+class MachOObjectFile : public MachOObjectFileMiddle<MachOT::TargetEndianness> {
 public:
   static const endianness TargetEndianness = MachOT::TargetEndianness;
   static const bool Is64Bits = MachOT::Is64Bits;
 
+  typedef MachOObjectFileMiddle<MachOT::TargetEndianness> Base;
+  typedef typename Base::RelocationEntry RelocationEntry;
+  typedef typename Base::SectionBase SectionBase;
+  typedef typename Base::SymbolTableEntryBase SymbolTableEntryBase;
+  typedef typename Base::LoadCommand LoadCommand;
+
   typedef MachOObjectFileHelper<MachOT> Helper;
   static const macho::LoadCommandType SegmentLoadType = Helper::SegmentLoadType;
   typedef typename Helper::SegmentLoadCommand SegmentLoadCommand;
@@ -413,15 +510,491 @@ public:
   void moveToNextSection(DataRefImpl &DRI) const;
 };
 
+typedef MachOObjectFileMiddle<support::little> MachOObjectFileLE;
+typedef MachOObjectFileMiddle<support::big> MachOObjectFileBE;
+
+typedef MachOObjectFile<MachOType<support::little, false> >
+  MachOObjectFileLE32;
+typedef MachOObjectFile<MachOType<support::big, false> >
+  MachOObjectFileBE32;
+typedef MachOObjectFile<MachOType<support::little, true> >
+  MachOObjectFileLE64;
+typedef MachOObjectFile<MachOType<support::big, true> >
+  MachOObjectFileBE64;
+
+template<endianness TargetEndianness>
+MachOObjectFileMiddle<TargetEndianness>::MachOObjectFileMiddle(MemoryBuffer *O,
+                                                               bool Is64Bits,
+                                                               error_code &ec) :
+  MachOObjectFileBase(O, TargetEndianness == support::little, Is64Bits, ec) {
+}
+
+template<endianness E>
+const typename MachOObjectFileMiddle<E>::SymbolTableEntryBase *
+MachOObjectFileMiddle<E>::getSymbolTableEntryBase(DataRefImpl DRI) const {
+  const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
+  const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);
+
+  unsigned Index = DRI.d.b;
+
+  unsigned SymbolTableEntrySize = is64Bit() ?
+    sizeof(MachOObjectFileLE64::SymbolTableEntry) :
+    sizeof(MachOObjectFileLE32::SymbolTableEntry);
+
+  uint64_t Offset = S->SymbolTableOffset + Index * SymbolTableEntrySize;
+  StringRef Data = getData(Offset, SymbolTableEntrySize);
+  return reinterpret_cast<const SymbolTableEntryBase*>(Data.data());
+}
+
+template<endianness E>
+const typename MachOObjectFileMiddle<E>::Header *
+MachOObjectFileMiddle<E>::getHeader() const {
+  StringRef Data = getData(0, sizeof(Header));
+  return reinterpret_cast<const Header*>(Data.data());
+}
+
+template<endianness E>
+const typename MachOObjectFileMiddle<E>::LoadCommand *
+MachOObjectFileMiddle<E>::getLoadCommandInfo(unsigned Index) const {
+  assert(Index < getHeader()->NumLoadCommands);
+  uint64_t Offset;
+  uint64_t NewOffset = getHeaderSize();
+  const LoadCommand *Load;
+  unsigned I = 0;
+  do {
+    Offset = NewOffset;
+    StringRef Data = getData(Offset, sizeof(MachOObjectFileLE::LoadCommand));
+    Load = reinterpret_cast<const LoadCommand*>(Data.data());
+    NewOffset = Offset + Load->Size;
+    ++I;
+  } while (I != Index + 1);
+
+  return reinterpret_cast<const LoadCommand*>(Load);
+}
+
+template<endianness E>
+const typename MachOObjectFileMiddle<E>::RelocationEntry *
+MachOObjectFileMiddle<E>::getRelocation(DataRefImpl Rel) const {
+  if (const MachOObjectFile<MachOType<E, true> > *O =
+      dyn_cast<MachOObjectFile<MachOType<E, true> > >(this))
+    return O->getRelocation(Rel);
+
+  const MachOObjectFile<MachOType<E, false> > *O =
+    cast<MachOObjectFile<MachOType<E, false> > >(this);
+  return O->getRelocation(Rel);
+}
+
+template<endianness E>
+bool
+MachOObjectFileMiddle<E>::isRelocationScattered(const RelocationEntry *RE)
+                                                                         const {
+  if (this->getCPUType() == llvm::MachO::CPUTypeX86_64)
+    return false;
+  return RE->Address & macho::RF_Scattered;
+}
+
+template<endianness E>
+bool
+MachOObjectFileMiddle<E>::isRelocationPCRel(const RelocationEntry *RE) const {
+  typedef MachOObjectFileMiddle<E> ObjType;
+  if (isRelocationScattered(RE)) {
+    const ObjType::ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
+    return SRE->getPCRel();
+  }
+  return RE->getPCRel();
+}
+
+template<endianness E>
+unsigned
+MachOObjectFileMiddle<E>::getRelocationLength(const RelocationEntry *RE) const {
+  typedef MachOObjectFileMiddle<E> ObjType;
+  if (isRelocationScattered(RE)) {
+    const ObjType::ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
+    return SRE->getLength();
+  }
+  return RE->getLength();
+}
+
+template<endianness E>
+unsigned
+MachOObjectFileMiddle<E>::getRelocationTypeImpl(const RelocationEntry *RE)
+                                                                         const {
+  typedef MachOObjectFileMiddle<E> ObjType;
+  if (isRelocationScattered(RE)) {
+    const ObjType::ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
+    return SRE->getType();
+  }
+  return RE->getType();
+}
+
+// Helper to advance a section or symbol iterator multiple increments at a time.
+template<endianness E>
+template<class T>
+error_code MachOObjectFileMiddle<E>::advance(T &it, size_t Val) {
+  error_code ec;
+  while (Val--) {
+    it.increment(ec);
+  }
+  return ec;
+}
+
+template<endianness E>
+template<class T>
+void MachOObjectFileMiddle<E>::advanceTo(T &it, size_t Val) {
+  if (error_code ec = advance(it, Val))
+    report_fatal_error(ec.message());
+}
+
+template<endianness E>
+void
+MachOObjectFileMiddle<E>::printRelocationTargetName(const RelocationEntry *RE,
+                                                raw_string_ostream &fmt) const {
+  bool IsScattered = isRelocationScattered(RE);
+
+  // Target of a scattered relocation is an address.  In the interest of
+  // generating pretty output, scan through the symbol table looking for a
+  // symbol that aligns with that address.  If we find one, print it.
+  // Otherwise, we just print the hex address of the target.
+  if (IsScattered) {
+    uint32_t Val = RE->SymbolNum;
+
+    error_code ec;
+    for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
+        SI.increment(ec)) {
+      if (ec) report_fatal_error(ec.message());
+
+      uint64_t Addr;
+      StringRef Name;
+
+      if ((ec = SI->getAddress(Addr)))
+        report_fatal_error(ec.message());
+      if (Addr != Val) continue;
+      if ((ec = SI->getName(Name)))
+        report_fatal_error(ec.message());
+      fmt << Name;
+      return;
+    }
+
+    // If we couldn't find a symbol that this relocation refers to, try
+    // to find a section beginning instead.
+    for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
+         SI.increment(ec)) {
+      if (ec) report_fatal_error(ec.message());
+
+      uint64_t Addr;
+      StringRef Name;
+
+      if ((ec = SI->getAddress(Addr)))
+        report_fatal_error(ec.message());
+      if (Addr != Val) continue;
+      if ((ec = SI->getName(Name)))
+        report_fatal_error(ec.message());
+      fmt << Name;
+      return;
+    }
+
+    fmt << format("0x%x", Val);
+    return;
+  }
+
+  StringRef S;
+  bool isExtern = RE->getExternal();
+  uint64_t Val = RE->Address;
+
+  if (isExtern) {
+    symbol_iterator SI = begin_symbols();
+    advanceTo(SI, Val);
+    SI->getName(S);
+  } else {
+    section_iterator SI = begin_sections();
+    advanceTo(SI, Val);
+    SI->getName(S);
+  }
+
+  fmt << S;
+}
+
+template<endianness E>
+const typename MachOObjectFileMiddle<E>::SectionBase *
+MachOObjectFileMiddle<E>::getSectionBase(DataRefImpl DRI) const {
+  uintptr_t CommandAddr =
+    reinterpret_cast<uintptr_t>(getLoadCommandInfo(DRI.d.a));
+
+  bool Is64 = is64Bit();
+  unsigned SegmentLoadSize =
+    Is64 ? sizeof(MachOObjectFileLE64::SegmentLoadCommand) :
+           sizeof(MachOObjectFileLE32::SegmentLoadCommand);
+  unsigned SectionSize = Is64 ? sizeof(MachOObjectFileLE64::Section) :
+                                sizeof(MachOObjectFileLE32::Section);
+
+  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
+  return reinterpret_cast<const SectionBase*>(SectionAddr);
+}
+
+template<endianness E>
+unsigned MachOObjectFileMiddle<E>::getCPUType() const {
+  return getHeader()->CPUType;
+}
+
+template<endianness E>
+void MachOObjectFileMiddle<E>::moveToNextSymbol(DataRefImpl &DRI) const {
+  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
+  while (DRI.d.a < LoadCommandCount) {
+    const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
+    if (L->Type == macho::LCT_Symtab) {
+      const SymtabLoadCommand *S =
+        reinterpret_cast<const SymtabLoadCommand *>(L);
+      if (DRI.d.b < S->NumSymbolTableEntries)
+        return;
+    }
+
+    DRI.d.a++;
+    DRI.d.b = 0;
+  }
+}
+
+template<endianness E>
+StringRef
+MachOObjectFileMiddle<E>::getSectionFinalSegmentName(DataRefImpl Sec) const {
+  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
+  return parseSegmentOrSectionName(Raw.data());
+}
+
+template<endianness E>
+ArrayRef<char>
+MachOObjectFileMiddle<E>::getSectionRawName(DataRefImpl Sec) const {
+  const SectionBase *Base = getSectionBase(Sec);
+  return ArrayRef<char>(Base->Name);
+}
+
+template<endianness E>
+ArrayRef<char>
+MachOObjectFileMiddle<E>::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
+  const SectionBase *Base = getSectionBase(Sec);
+  return ArrayRef<char>(Base->SegmentName);
+}
+
+template<endianness E>
+error_code MachOObjectFileMiddle<E>::getSymbolFlags(DataRefImpl DRI,
+                                                    uint32_t &Result) const {
+  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
+
+  uint8_t MachOType = Entry->Type;
+  uint16_t MachOFlags = Entry->Flags;
+
+  // TODO: Correctly set SF_ThreadLocal
+  Result = SymbolRef::SF_None;
+
+  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
+    Result |= SymbolRef::SF_Undefined;
+
+  if (MachOFlags & macho::STF_StabsEntryMask)
+    Result |= SymbolRef::SF_FormatSpecific;
+
+  if (MachOType & MachO::NlistMaskExternal) {
+    Result |= SymbolRef::SF_Global;
+    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
+      Result |= SymbolRef::SF_Common;
+  }
+
+  if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
+    Result |= SymbolRef::SF_Weak;
+
+  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
+    Result |= SymbolRef::SF_Absolute;
+
+  return object_error::success;
+}
+
+template<endianness E>
+error_code MachOObjectFileMiddle<E>::getSymbolType(DataRefImpl Symb,
+                                                   SymbolRef::Type &Res) const {
+  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
+  uint8_t n_type = Entry->Type;
+
+  Res = SymbolRef::ST_Other;
+
+  // If this is a STAB debugging symbol, we can do nothing more.
+  if (n_type & MachO::NlistMaskStab) {
+    Res = SymbolRef::ST_Debug;
+    return object_error::success;
+  }
+
+  switch (n_type & MachO::NlistMaskType) {
+    case MachO::NListTypeUndefined :
+      Res = SymbolRef::ST_Unknown;
+      break;
+    case MachO::NListTypeSection :
+      Res = SymbolRef::ST_Function;
+      break;
+  }
+  return object_error::success;
+}
+
+template<endianness E>
+error_code MachOObjectFileMiddle<E>::getSymbolName(DataRefImpl Symb,
+                                                   StringRef &Res) const {
+  const LoadCommand *L = getLoadCommandInfo(Symb.d.a);
+  const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);
+  StringRef StringTable = getData(S->StringTableOffset, S->StringTableSize);
+  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
+  const char *Start = &StringTable.data()[Entry->StringIndex];
+  Res = StringRef(Start);
+  return object_error::success;
+}
+
+template<endianness E>
+error_code
+MachOObjectFileMiddle<E>::getSymbolSection(DataRefImpl Symb,
+                                           section_iterator &Res) const {
+  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
+  uint8_t index = Entry->SectionIndex;
+
+  if (index == 0)
+    Res = end_sections();
+  else
+    Res = section_iterator(SectionRef(Sections[index-1], this));
+
+  return object_error::success;
+}
+
+
+template<endianness E>
+error_code MachOObjectFileMiddle<E>::getSymbolNMTypeChar(DataRefImpl Symb,
+                                                         char &Res) const {
+  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
+  uint8_t Type = Entry->Type;
+  uint16_t Flags = Entry->Flags;
+
+  char Char;
+  switch (Type & macho::STF_TypeMask) {
+    case macho::STT_Undefined:
+      Char = 'u';
+      break;
+    case macho::STT_Absolute:
+    case macho::STT_Section:
+      Char = 's';
+      break;
+    default:
+      Char = '?';
+      break;
+  }
+
+  if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
+    Char = toupper(static_cast<unsigned char>(Char));
+  Res = Char;
+  return object_error::success;
+}
+
+template<endianness E>
+error_code
+MachOObjectFileMiddle<E>::getSectionName(DataRefImpl Sec,
+                                         StringRef &Result) const {
+  ArrayRef<char> Raw = getSectionRawName(Sec);
+  Result = parseSegmentOrSectionName(Raw.data());
+  return object_error::success;
+}
+
+template<endianness E>
+error_code MachOObjectFileMiddle<E>::getSymbolNext(DataRefImpl Symb,
+                                                     SymbolRef &Res) const {
+  Symb.d.b++;
+  moveToNextSymbol(Symb);
+  Res = SymbolRef(Symb, this);
+  return object_error::success;
+}
+
+template<endianness E>
+symbol_iterator MachOObjectFileMiddle<E>::begin_symbols() const {
+  // DRI.d.a = segment number; DRI.d.b = symbol index.
+  DataRefImpl DRI;
+  moveToNextSymbol(DRI);
+  return symbol_iterator(SymbolRef(DRI, this));
+}
+
+template<endianness E>
+unsigned MachOObjectFileMiddle<E>::getArch() const {
+  switch (getCPUType()) {
+  case llvm::MachO::CPUTypeI386:
+    return Triple::x86;
+  case llvm::MachO::CPUTypeX86_64:
+    return Triple::x86_64;
+  case llvm::MachO::CPUTypeARM:
+    return Triple::arm;
+  case llvm::MachO::CPUTypePowerPC:
+    return Triple::ppc;
+  case llvm::MachO::CPUTypePowerPC64:
+    return Triple::ppc64;
+  default:
+    return Triple::UnknownArch;
+  }
+}
+
+template<endianness E>
+StringRef MachOObjectFileMiddle<E>::getFileFormatName() const {
+  unsigned CPUType = getCPUType();
+  if (!is64Bit()) {
+    switch (CPUType) {
+    case llvm::MachO::CPUTypeI386:
+      return "Mach-O 32-bit i386";
+    case llvm::MachO::CPUTypeARM:
+      return "Mach-O arm";
+    case llvm::MachO::CPUTypePowerPC:
+      return "Mach-O 32-bit ppc";
+    default:
+      assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&
+             "64-bit object file when we're not 64-bit?");
+      return "Mach-O 32-bit unknown";
+    }
+  }
+
+  // Make sure the cpu type has the correct mask.
+  assert((CPUType & llvm::MachO::CPUArchABI64)
+	 == llvm::MachO::CPUArchABI64 &&
+	 "32-bit object file when we're 64-bit?");
+
+  switch (CPUType) {
+  case llvm::MachO::CPUTypeX86_64:
+    return "Mach-O 64-bit x86-64";
+  case llvm::MachO::CPUTypePowerPC64:
+    return "Mach-O 64-bit ppc64";
+  default:
+    return "Mach-O 64-bit unknown";
+  }
+}
+
+template<endianness E>
+symbol_iterator MachOObjectFileMiddle<E>::end_symbols() const {
+  DataRefImpl DRI;
+  DRI.d.a = getHeader()->NumLoadCommands;
+  return symbol_iterator(SymbolRef(DRI, this));
+}
+
+template<endianness E>
+section_iterator MachOObjectFileMiddle<E>::end_sections() const {
+  DataRefImpl DRI;
+  DRI.d.a = getHeader()->NumLoadCommands;
+  return section_iterator(SectionRef(DRI, this));
+}
+
+template<endianness E>
+bool MachOObjectFileMiddle<E>::classof(const Binary *v) {
+  return isa<MachOObjectFile<MachOType<E, false> > >(v) ||
+    isa<MachOObjectFile<MachOType<E, true> > >(v);
+}
+
 template<class MachOT>
 MachOObjectFile<MachOT>::MachOObjectFile(MemoryBuffer *Object,
                                          error_code &ec) :
-  MachOObjectFileBase(Object, Is64Bits, ec) {
+  MachOObjectFileMiddle<TargetEndianness>(Object, Is64Bits, ec) {
   DataRefImpl DRI;
   moveToNextSection(DRI);
-  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
+  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
   while (DRI.d.a < LoadCommandCount) {
-    Sections.push_back(DRI);
+    this->Sections.push_back(DRI);
     DRI.d.b++;
     moveToNextSection(DRI);
   }
@@ -429,30 +1002,31 @@ MachOObjectFile<MachOT>::MachOObjectFile
 
 template<class MachOT>
 bool MachOObjectFile<MachOT>::classof(const Binary *v) {
-  return v->getType() == getMachOType(true, Is64Bits);
+  return v->getType() ==
+    Base::getMachOType(TargetEndianness == support::little, Is64Bits);
 }
 
 template<class MachOT>
 const typename MachOObjectFile<MachOT>::Section *
 MachOObjectFile<MachOT>::getSection(DataRefImpl DRI) const {
-  const SectionBase *Addr = getSectionBase(DRI);
+  const SectionBase *Addr = this->getSectionBase(DRI);
   return reinterpret_cast<const Section*>(Addr);
 }
 
 template<class MachOT>
 const typename MachOObjectFile<MachOT>::SymbolTableEntry *
 MachOObjectFile<MachOT>::getSymbolTableEntry(DataRefImpl DRI) const {
-  const SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
+  const SymbolTableEntryBase *Base = this->getSymbolTableEntryBase(DRI);
   return reinterpret_cast<const SymbolTableEntry*>(Base);
 }
 
 template<class MachOT>
 const typename MachOObjectFile<MachOT>::RelocationEntry *
 MachOObjectFile<MachOT>::getRelocation(DataRefImpl Rel) const {
-  const Section *Sect = getSection(Sections[Rel.d.b]);
+  const Section *Sect = getSection(this->Sections[Rel.d.b]);
   uint32_t RelOffset = Sect->RelocationTableOffset;
   uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);
-  StringRef Data = getData(Offset, sizeof(RelocationEntry));
+  StringRef Data = this->getData(Offset, sizeof(RelocationEntry));
   return reinterpret_cast<const RelocationEntry*>(Data.data());
 }
 
@@ -479,7 +1053,7 @@ error_code
 MachOObjectFile<MachOT>::getSectionContents(DataRefImpl Sec,
                                             StringRef &Res) const {
   const Section *Sect = getSection(Sec);
-  Res = getData(Sect->Offset, Sect->Size);
+  Res = this->getData(Sect->Offset, Sect->Size);
   return object_error::success;
 }
 
@@ -517,7 +1091,7 @@ MachOObjectFile<MachOT>::getSectionRelEn
   uint32_t LastReloc = Sect->NumRelocationTableEntries;
   DataRefImpl Ret;
   Ret.d.a = LastReloc;
-  Ret.d.b = getSectionIndex(Sec);
+  Ret.d.b = this->getSectionIndex(Sec);
   return relocation_iterator(RelocationRef(Ret, this));
 }
 
@@ -525,12 +1099,12 @@ template<class MachOT>
 error_code
 MachOObjectFile<MachOT>::getRelocationAddress(DataRefImpl Rel,
                                               uint64_t &Res) const {
-  const Section *Sect = getSection(Sections[Rel.d.b]);
+  const Section *Sect = getSection(this->Sections[Rel.d.b]);
   uint64_t SectAddress = Sect->Address;
   const RelocationEntry *RE = getRelocation(Rel);
 
   uint64_t RelAddr;
-  if (isScattered(RE))
+  if (this->isRelocationScattered(RE))
     RelAddr = RE->Address & 0xFFFFFF;
   else
     RelAddr = RE->Address;
@@ -544,7 +1118,7 @@ error_code
 MachOObjectFile<MachOT>::getRelocationOffset(DataRefImpl Rel,
                                              uint64_t &Res) const {
   const RelocationEntry *RE = getRelocation(Rel);
-  if (isScattered(RE))
+  if (this->isRelocationScattered(RE))
     Res = RE->Address & 0xFFFFFF;
   else
     Res = RE->Address;
@@ -560,12 +1134,12 @@ MachOObjectFile<MachOT>::getRelocationSy
   bool isExtern = RE->getExternal();
 
   DataRefImpl Sym;
-  moveToNextSymbol(Sym);
+  this->moveToNextSymbol(Sym);
   if (isExtern) {
     for (unsigned i = 0; i < SymbolIdx; i++) {
       Sym.d.b++;
-      moveToNextSymbol(Sym);
-      assert(Sym.d.a < getHeader()->NumLoadCommands &&
+      this->moveToNextSymbol(Sym);
+      assert(Sym.d.a < this->getHeader()->NumLoadCommands &&
              "Relocation symbol index out of range!");
     }
   }
@@ -577,7 +1151,7 @@ template<class MachOT>
 error_code MachOObjectFile<MachOT>::getRelocationType(DataRefImpl Rel,
                                                       uint64_t &Res) const {
   const RelocationEntry *RE = getRelocation(Rel);
-  Res = getType(RE);
+  Res = this->getRelocationTypeImpl(RE);
   return object_error::success;
 }
 
@@ -589,9 +1163,9 @@ MachOObjectFile<MachOT>::getRelocationTy
   StringRef res;
   const RelocationEntry *RE = getRelocation(Rel);
 
-  unsigned Arch = getArch();
+  unsigned Arch = this->getArch();
 
-  unsigned r_type = getType(RE);
+  unsigned r_type = this->getRelocationTypeImpl(RE);
 
   switch (Arch) {
     case Triple::x86: {
@@ -683,14 +1257,14 @@ MachOObjectFile<MachOT>::getRelocationVa
                                           SmallVectorImpl<char> &Result) const {
   const RelocationEntry *RE = getRelocation(Rel);
 
-  unsigned Arch = getArch();
-  bool IsScattered = isScattered(RE);
+  unsigned Arch = this->getArch();
+  bool IsScattered = this->isRelocationScattered(RE);
 
   std::string fmtbuf;
   raw_string_ostream fmt(fmtbuf);
 
-  unsigned Type = getType(RE);
-  bool IsPCRel = isPCRel(RE);
+  unsigned Type = this->getRelocationTypeImpl(RE);
+  bool IsPCRel = this->isRelocationPCRel(RE);
 
   // Determine any addends that should be displayed with the relocation.
   // These require decoding the relocation type, which is triple-specific.
@@ -702,7 +1276,7 @@ MachOObjectFile<MachOT>::getRelocationVa
     switch (Type) {
       case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD
       case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "@GOT";
         if (isPCRel) fmt << "PCREL";
         break;
@@ -722,30 +1296,30 @@ MachOObjectFile<MachOT>::getRelocationVa
 
         // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
         // X86_64_SUBTRACTOR contains to the subtrahend.
-        printRelocationTargetName(RENext, fmt);
+        this->printRelocationTargetName(RENext, fmt);
         fmt << "-";
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         break;
       }
       case macho::RIT_X86_64_TLV:
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "@TLV";
         if (isPCRel) fmt << "P";
         break;
       case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "-1";
         break;
       case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "-2";
         break;
       case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "-4";
         break;
       default:
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         break;
     }
   // X86 and ARM share some relocation types in common.
@@ -772,9 +1346,9 @@ MachOObjectFile<MachOT>::getRelocationVa
           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                              "GENERIC_RELOC_SECTDIFF.");
 
-        printRelocationTargetName(RE, fmt);
+        this->printRelocationTargetName(RE, fmt);
         fmt << "-";
-        printRelocationTargetName(RENext, fmt);
+        this->printRelocationTargetName(RENext, fmt);
         break;
       }
     }
@@ -801,19 +1375,19 @@ MachOObjectFile<MachOT>::getRelocationVa
             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
 
-          printRelocationTargetName(RE, fmt);
+          this->printRelocationTargetName(RE, fmt);
           fmt << "-";
-          printRelocationTargetName(RENext, fmt);
+          this->printRelocationTargetName(RENext, fmt);
           break;
         }
         case macho::RIT_Generic_TLV: {
-          printRelocationTargetName(RE, fmt);
+          this->printRelocationTargetName(RE, fmt);
           fmt << "@TLV";
           if (IsPCRel) fmt << "P";
           break;
         }
         default:
-          printRelocationTargetName(RE, fmt);
+          this->printRelocationTargetName(RE, fmt);
       }
     } else { // ARM-specific relocations
       switch (Type) {
@@ -831,7 +1405,7 @@ MachOObjectFile<MachOT>::getRelocationVa
             fmt << ":upper16:(";
           else
             fmt << ":lower16:(";
-          printRelocationTargetName(RE, fmt);
+          this->printRelocationTargetName(RE, fmt);
 
           DataRefImpl RelNext = Rel;
           RelNext.d.a++;
@@ -860,19 +1434,19 @@ MachOObjectFile<MachOT>::getRelocationVa
           // symbol/section pointer of the follow-on relocation.
           if (Type == macho::RIT_ARM_HalfDifference) {
             fmt << "-";
-            printRelocationTargetName(RENext, fmt);
+            this->printRelocationTargetName(RENext, fmt);
           }
 
           fmt << ")";
           break;
         }
         default: {
-          printRelocationTargetName(RE, fmt);
+          this->printRelocationTargetName(RE, fmt);
         }
       }
     }
   } else
-    printRelocationTargetName(RE, fmt);
+    this->printRelocationTargetName(RE, fmt);
 
   fmt.flush();
   Result.append(fmtbuf.begin(), fmtbuf.end());
@@ -884,8 +1458,8 @@ error_code
 MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel,
                                              bool &Result) const {
   const RelocationEntry *RE = getRelocation(Rel);
-  unsigned Arch = getArch();
-  unsigned Type = getType(RE);
+  unsigned Arch = this->getArch();
+  unsigned Type = this->getRelocationTypeImpl(RE);
 
   Result = false;
 
@@ -899,7 +1473,7 @@ MachOObjectFile<MachOT>::getRelocationHi
     if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
       DataRefImpl RelPrev = Rel;
       RelPrev.d.a--;
-      const RelocationEntry *REPrev = getRelocation(RelPrev);
+      const RelocationEntry *REPrev = this->getRelocation(RelPrev);
 
       unsigned PrevType = REPrev->getType();
 
@@ -917,7 +1491,8 @@ MachOObjectFile<MachOT>::getSymbolFileOf
   const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
   Res = Entry->Value;
   if (Entry->SectionIndex) {
-    const Section *Sec = getSection(Sections[Entry->SectionIndex-1]);
+    const Section *Sec =
+      this->getSection(this->Sections[Entry->SectionIndex-1]);
     Res += Sec->Offset - Sec->Address;
   }
 
@@ -930,7 +1505,7 @@ MachOObjectFile<MachOT>::sectionContains
                                                DataRefImpl Symb,
                                                bool &Result) const {
   SymbolRef::Type ST;
-  getSymbolType(Symb, ST);
+  this->getSymbolType(Symb, ST);
   if (ST == SymbolRef::ST_Unknown) {
     Result = false;
     return object_error::success;
@@ -959,7 +1534,7 @@ error_code MachOObjectFile<MachOT>::getS
 template<class MachOT>
 error_code MachOObjectFile<MachOT>::getSymbolSize(DataRefImpl DRI,
                                                     uint64_t &Result) const {
-  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
+  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
   uint64_t BeginOffset;
   uint64_t EndOffset = 0;
   uint8_t SectionIndex;
@@ -969,7 +1544,7 @@ error_code MachOObjectFile<MachOT>::getS
   SectionIndex = Entry->SectionIndex;
   if (!SectionIndex) {
     uint32_t flags = SymbolRef::SF_None;
-    getSymbolFlags(DRI, flags);
+    this->getSymbolFlags(DRI, flags);
     if (flags & SymbolRef::SF_Common)
       Result = Entry->Value;
     else
@@ -981,7 +1556,7 @@ error_code MachOObjectFile<MachOT>::getS
   DRI.d.b = 0;
   uint32_t Command = DRI.d.a;
   while (Command == DRI.d.a) {
-    moveToNextSymbol(DRI);
+    this->moveToNextSymbol(DRI);
     if (DRI.d.a < LoadCommandCount) {
       Entry = getSymbolTableEntry(DRI);
       if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
@@ -992,8 +1567,8 @@ error_code MachOObjectFile<MachOT>::getS
   }
   if (!EndOffset) {
     uint64_t Size;
-    getSectionSize(Sections[SectionIndex-1], Size);
-    getSectionAddress(Sections[SectionIndex-1], EndOffset);
+    this->getSectionSize(this->Sections[SectionIndex-1], Size);
+    this->getSectionAddress(this->Sections[SectionIndex-1], EndOffset);
     EndOffset += Size;
   }
   Result = EndOffset - BeginOffset;
@@ -1018,9 +1593,9 @@ section_iterator MachOObjectFile<MachOT>
 
 template<class MachOT>
 void MachOObjectFile<MachOT>::moveToNextSection(DataRefImpl &DRI) const {
-  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
+  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
   while (DRI.d.a < LoadCommandCount) {
-    const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
+    const LoadCommand *Command = this->getLoadCommandInfo(DRI.d.a);
     if (Command->Type == SegmentLoadType) {
       const SegmentLoadCommand *SegmentLoadCmd =
         reinterpret_cast<const SegmentLoadCommand*>(Command);
@@ -1033,10 +1608,6 @@ void MachOObjectFile<MachOT>::moveToNext
   }
 }
 
-  typedef MachOObjectFile<MachOType<support::little, false> >
-    MachOObjectFile32Le;
-  typedef MachOObjectFile<MachOType<support::little, true> >
-    MachOObjectFile64Le;
 }
 }
 

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Fri Apr 12 20:45:40 2013
@@ -29,30 +29,14 @@ using namespace object;
 namespace llvm {
 namespace object {
 
-MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits,
+MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
+                                         bool IsLittleEndian, bool Is64bits,
                                          error_code &ec)
-    : ObjectFile(getMachOType(true, Is64bits), Object) {
+    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
 }
 
 bool MachOObjectFileBase::is64Bit() const {
-  return isa<MachOObjectFile64Le>(this);
-}
-
-const MachOObjectFileBase::LoadCommand *
-MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const {
-  uint64_t Offset;
-  uint64_t NewOffset = getHeaderSize();
-  const LoadCommand *Load;
-  unsigned I = 0;
-  do {
-    Offset = NewOffset;
-    StringRef Data = getData(Offset, sizeof(LoadCommand));
-    Load = reinterpret_cast<const LoadCommand*>(Data.data());
-    NewOffset = Offset + Load->Size;
-    ++I;
-  } while (I != Index + 1);
-
-  return Load;
+  return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);
 }
 
 void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
@@ -67,11 +51,6 @@ void MachOObjectFileBase::ReadULEB128s(u
   }
 }
 
-const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const {
-  StringRef Data = getData(0, sizeof(Header));
-  return reinterpret_cast<const Header*>(Data.data());
-}
-
 unsigned MachOObjectFileBase::getHeaderSize() const {
   return is64Bit() ? macho::Header64Size : macho::Header32Size;
 }
@@ -80,55 +59,21 @@ StringRef MachOObjectFileBase::getData(s
   return ObjectFile::getData().substr(Offset, Size);
 }
 
-const MachOObjectFileBase::RelocationEntry *
-MachOObjectFileBase::getRelocation(DataRefImpl Rel) const {
-  if (const MachOObjectFile32Le *O = dyn_cast<MachOObjectFile32Le>(this))
-    return O->getRelocation(Rel);
-  const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(this);
-  return O->getRelocation(Rel);
-}
-
-bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const {
-  unsigned Arch = getArch();
-  return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered);
-}
-
-bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const {
-  if (isScattered(RE)) {
-    const ScatteredRelocationEntry *SRE =
-      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
-    return SRE->getPCRel();
-  }
-  return RE->getPCRel();
-}
-
-unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const {
-  if (isScattered(RE)) {
-    const ScatteredRelocationEntry *SRE =
-      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
-    return SRE->getLength();
-  }
-  return RE->getLength();
-}
-
-unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const {
-  if (isScattered(RE)) {
-    const ScatteredRelocationEntry *SRE =
-      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
-    return SRE->getType();
-  }
-  return RE->getType();
-}
-
 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
   StringRef Magic = Buffer->getBuffer().slice(0, 4);
   error_code ec;
-  bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
   ObjectFile *Ret;
-  if (Is64Bits)
-    Ret = new MachOObjectFile64Le(Buffer, ec);
+  if (Magic == "\xFE\xED\xFA\xCE")
+    Ret = new MachOObjectFileBE32(Buffer, ec);
+  else if (Magic == "\xCE\xFA\xED\xFE")
+    Ret = new MachOObjectFileLE32(Buffer, ec);
+  else if (Magic == "\xFE\xED\xFA\xCF")
+    Ret = new MachOObjectFileBE64(Buffer, ec);
+  else if (Magic == "\xCF\xFA\xED\xFE")
+    Ret = new MachOObjectFileLE64(Buffer, ec);
   else
-    Ret = new MachOObjectFile32Le(Buffer, ec);
+    return NULL;
+
   if (ec)
     return NULL;
   return Ret;
@@ -136,183 +81,11 @@ ObjectFile *ObjectFile::createMachOObjec
 
 /*===-- Symbols -----------------------------------------------------------===*/
 
-void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const {
-  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
-  while (DRI.d.a < LoadCommandCount) {
-    const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
-    if (Command->Type == macho::LCT_Symtab) {
-      const SymtabLoadCommand *SymtabLoadCmd =
-        reinterpret_cast<const SymtabLoadCommand*>(Command);
-      if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
-        return;
-    }
-
-    DRI.d.a++;
-    DRI.d.b = 0;
-  }
-}
-
-const MachOObjectFileBase::SymbolTableEntryBase *
-MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const {
-  const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
-  const SymtabLoadCommand *SymtabLoadCmd =
-    reinterpret_cast<const SymtabLoadCommand*>(Command);
-  return getSymbolTableEntryBase(DRI, SymtabLoadCmd);
-}
-
-const MachOObjectFileBase::SymbolTableEntryBase *
-MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI,
-                                 const SymtabLoadCommand *SymtabLoadCmd) const {
-  uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset;
-  unsigned Index = DRI.d.b;
-
-  unsigned SymbolTableEntrySize = is64Bit() ?
-    sizeof(MachOObjectFile64Le::SymbolTableEntry) :
-    sizeof(MachOObjectFile32Le::SymbolTableEntry);
-
-  uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
-  StringRef Data = getData(Offset, SymbolTableEntrySize);
-  return reinterpret_cast<const SymbolTableEntryBase*>(Data.data());
-}
-
-error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI,
-                                              SymbolRef &Result) const {
-  DRI.d.b++;
-  moveToNextSymbol(DRI);
-  Result = SymbolRef(DRI, this);
-  return object_error::success;
-}
-
-error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI,
-                                              StringRef &Result) const {
-  const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
-  const SymtabLoadCommand *SymtabLoadCmd =
-    reinterpret_cast<const SymtabLoadCommand*>(Command);
-
-  StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset,
-                                  SymtabLoadCmd->StringTableSize);
-
-  const SymbolTableEntryBase *Entry =
-    getSymbolTableEntryBase(DRI, SymtabLoadCmd);
-  uint32_t StringIndex = Entry->StringIndex;
-
-  const char *Start = &StringTable.data()[StringIndex];
-  Result = StringRef(Start);
-
-  return object_error::success;
-}
-
-error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI,
-                                                    char &Result) const {
-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
-  uint8_t Type = Entry->Type;
-  uint16_t Flags = Entry->Flags;
-
-  char Char;
-  switch (Type & macho::STF_TypeMask) {
-    case macho::STT_Undefined:
-      Char = 'u';
-      break;
-    case macho::STT_Absolute:
-    case macho::STT_Section:
-      Char = 's';
-      break;
-    default:
-      Char = '?';
-      break;
-  }
-
-  if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
-    Char = toupper(static_cast<unsigned char>(Char));
-  Result = Char;
-  return object_error::success;
-}
-
-error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI,
-                                               uint32_t &Result) const {
-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
-  uint8_t MachOType = Entry->Type;
-  uint16_t MachOFlags = Entry->Flags;
-
-  // TODO: Correctly set SF_ThreadLocal
-  Result = SymbolRef::SF_None;
-
-  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
-    Result |= SymbolRef::SF_Undefined;
-
-  if (MachOFlags & macho::STF_StabsEntryMask)
-    Result |= SymbolRef::SF_FormatSpecific;
-
-  if (MachOType & MachO::NlistMaskExternal) {
-    Result |= SymbolRef::SF_Global;
-    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
-      Result |= SymbolRef::SF_Common;
-  }
-
-  if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
-    Result |= SymbolRef::SF_Weak;
-
-  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
-    Result |= SymbolRef::SF_Absolute;
-
-  return object_error::success;
-}
-
-error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb,
-                                                 section_iterator &Res) const {
-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
-  uint8_t index = Entry->SectionIndex;
-
-  if (index == 0)
-    Res = end_sections();
-  else
-    Res = section_iterator(SectionRef(Sections[index-1], this));
-
-  return object_error::success;
-}
-
-error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb,
-                                              SymbolRef::Type &Res) const {
-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
-  uint8_t n_type = Entry->Type;
-
-  Res = SymbolRef::ST_Other;
-
-  // If this is a STAB debugging symbol, we can do nothing more.
-  if (n_type & MachO::NlistMaskStab) {
-    Res = SymbolRef::ST_Debug;
-    return object_error::success;
-  }
-
-  switch (n_type & MachO::NlistMaskType) {
-    case MachO::NListTypeUndefined :
-      Res = SymbolRef::ST_Unknown;
-      break;
-    case MachO::NListTypeSection :
-      Res = SymbolRef::ST_Function;
-      break;
-  }
-  return object_error::success;
-}
-
 error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
                                                uint64_t &Val) const {
   report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
 }
 
-symbol_iterator MachOObjectFileBase::begin_symbols() const {
-  // DRI.d.a = segment number; DRI.d.b = symbol index.
-  DataRefImpl DRI;
-  moveToNextSymbol(DRI);
-  return symbol_iterator(SymbolRef(DRI, this));
-}
-
-symbol_iterator MachOObjectFileBase::end_symbols() const {
-  DataRefImpl DRI;
-  DRI.d.a = getHeader()->NumLoadCommands;
-  return symbol_iterator(SymbolRef(DRI, this));
-}
-
 symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
   // TODO: implement
   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
@@ -347,23 +120,7 @@ std::size_t MachOObjectFileBase::getSect
   return std::distance(Sections.begin(), loc);
 }
 
-const MachOObjectFileBase::SectionBase*
-MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const {
-  const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
-  uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(Command);
-
-  bool Is64 = is64Bit();
-  unsigned SegmentLoadSize =
-    Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) :
-           sizeof(MachOObjectFile32Le::SegmentLoadCommand);
-  unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) :
-                                sizeof(MachOObjectFile32Le::Section);
-
-  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
-  return reinterpret_cast<const SectionBase*>(SectionAddr);
-}
-
-static StringRef parseSegmentOrSectionName(const char *P) {
+StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
   if (P[15] == 0)
     // Null terminated.
     return P;
@@ -371,30 +128,6 @@ static StringRef parseSegmentOrSectionNa
   return StringRef(P, 16);
 }
 
-ArrayRef<char> MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const {
-  const SectionBase *Base = getSectionBase(DRI);
-  return ArrayRef<char>(Base->Name);
-}
-
-error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI,
-                                               StringRef &Result) const {
-  ArrayRef<char> Raw = getSectionRawName(DRI);
-  Result = parseSegmentOrSectionName(Raw.data());
-  return object_error::success;
-}
-
-ArrayRef<char>
-MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
-  const SectionBase *Base = getSectionBase(Sec);
-  return ArrayRef<char>(Base->SegmentName);
-}
-
-StringRef
-MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const {
-  ArrayRef<char> Raw = getSectionRawFinalSegmentName(DRI);
-  return parseSegmentOrSectionName(Raw.data());
-}
-
 error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
                                               bool &Result) const {
   // FIXME: Unimplemented.
@@ -441,11 +174,6 @@ relocation_iterator MachOObjectFileBase:
   return relocation_iterator(RelocationRef(ret, this));
 }
 
-section_iterator MachOObjectFileBase::end_sections() const {
-  DataRefImpl DRI;
-  DRI.d.a = getHeader()->NumLoadCommands;
-  return section_iterator(SectionRef(DRI, this));
-}
 
 /*===-- Relocations -------------------------------------------------------===*/
 
@@ -456,88 +184,6 @@ error_code MachOObjectFileBase::getReloc
   return object_error::success;
 }
 
-// Helper to advance a section or symbol iterator multiple increments at a time.
-template<class T>
-error_code advance(T &it, size_t Val) {
-  error_code ec;
-  while (Val--) {
-    it.increment(ec);
-  }
-  return ec;
-}
-
-template<class T>
-void advanceTo(T &it, size_t Val) {
-  if (error_code ec = advance(it, Val))
-    report_fatal_error(ec.message());
-}
-
-void
-MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
-                                               raw_string_ostream &fmt) const {
-  // Target of a scattered relocation is an address.  In the interest of
-  // generating pretty output, scan through the symbol table looking for a
-  // symbol that aligns with that address.  If we find one, print it.
-  // Otherwise, we just print the hex address of the target.
-  if (isScattered(RE)) {
-    uint32_t Val = RE->SymbolNum;
-
-    error_code ec;
-    for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
-        SI.increment(ec)) {
-      if (ec) report_fatal_error(ec.message());
-
-      uint64_t Addr;
-      StringRef Name;
-
-      if ((ec = SI->getAddress(Addr)))
-        report_fatal_error(ec.message());
-      if (Addr != Val) continue;
-      if ((ec = SI->getName(Name)))
-        report_fatal_error(ec.message());
-      fmt << Name;
-      return;
-    }
-
-    // If we couldn't find a symbol that this relocation refers to, try
-    // to find a section beginning instead.
-    for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
-         SI.increment(ec)) {
-      if (ec) report_fatal_error(ec.message());
-
-      uint64_t Addr;
-      StringRef Name;
-
-      if ((ec = SI->getAddress(Addr)))
-        report_fatal_error(ec.message());
-      if (Addr != Val) continue;
-      if ((ec = SI->getName(Name)))
-        report_fatal_error(ec.message());
-      fmt << Name;
-      return;
-    }
-
-    fmt << format("0x%x", Val);
-    return;
-  }
-
-  StringRef S;
-  bool isExtern = RE->getExternal();
-  uint32_t Val = RE->Address;
-
-  if (isExtern) {
-    symbol_iterator SI = begin_symbols();
-    advanceTo(SI, Val);
-    SI->getName(S);
-  } else {
-    section_iterator SI = begin_sections();
-    advanceTo(SI, Val);
-    SI->getName(S);
-  }
-
-  fmt << S;
-}
-
 error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
                                                LibraryRef &Res) const {
   report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
@@ -561,53 +207,5 @@ uint8_t MachOObjectFileBase::getBytesInA
   return is64Bit() ? 8 : 4;
 }
 
-StringRef MachOObjectFileBase::getFileFormatName() const {
-  if (!is64Bit()) {
-    switch (getHeader()->CPUType) {
-    case llvm::MachO::CPUTypeI386:
-      return "Mach-O 32-bit i386";
-    case llvm::MachO::CPUTypeARM:
-      return "Mach-O arm";
-    case llvm::MachO::CPUTypePowerPC:
-      return "Mach-O 32-bit ppc";
-    default:
-      assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 0 &&
-             "64-bit object file when we're not 64-bit?");
-      return "Mach-O 32-bit unknown";
-    }
-  }
-
-  // Make sure the cpu type has the correct mask.
-  assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64)
-	 == llvm::MachO::CPUArchABI64 &&
-	 "32-bit object file when we're 64-bit?");
-
-  switch (getHeader()->CPUType) {
-  case llvm::MachO::CPUTypeX86_64:
-    return "Mach-O 64-bit x86-64";
-  case llvm::MachO::CPUTypePowerPC64:
-    return "Mach-O 64-bit ppc64";
-  default:
-    return "Mach-O 64-bit unknown";
-  }
-}
-
-unsigned MachOObjectFileBase::getArch() const {
-  switch (getHeader()->CPUType) {
-  case llvm::MachO::CPUTypeI386:
-    return Triple::x86;
-  case llvm::MachO::CPUTypeX86_64:
-    return Triple::x86_64;
-  case llvm::MachO::CPUTypeARM:
-    return Triple::arm;
-  case llvm::MachO::CPUTypePowerPC:
-    return Triple::ppc;
-  case llvm::MachO::CPUTypePowerPC64:
-    return Triple::ppc64;
-  default:
-    return Triple::UnknownArch;
-  }
-}
-
 } // end namespace object
 } // end namespace llvm

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc?rev=179440&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc Fri Apr 12 20:45:40 2013 differ

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc64?rev=179440&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc64 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-ppc64 Fri Apr 12 20:45:40 2013 differ

Modified: llvm/trunk/test/tools/llvm-readobj/relocations.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/relocations.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/relocations.test Fri Apr 12 20:45:40 2013
@@ -6,6 +6,10 @@ RUN: llvm-readobj -r %p/Inputs/trivial.o
 RUN:   | FileCheck %s -check-prefix MACHO-I386
 RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-x86-64 \
 RUN:   | FileCheck %s -check-prefix MACHO-X86-64
+RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC
+RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc64 \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC64
 
 COFF:      Relocations [
 COFF-NEXT:   Section (1) .text {
@@ -40,3 +44,41 @@ MACHO-X86-64-NEXT:    0x9 1 2 1 X86_64_R
 MACHO-X86-64-NEXT:    0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
 MACHO-X86-64-NEXT:  }
 MACHO-X86-64-NEXT:]
+
+MACHO-PPC: Relocations [
+MACHO-PPC-NEXT:   Section __text {
+MACHO-PPC-NEXT:     0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:     0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:     0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:     0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:     0x18 1 2 0 PPC_RELOC_BR24 0 _b
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section __picsymbolstub1 {
+MACHO-PPC-NEXT:     0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:     0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:     0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:     0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section __la_symbol_ptr {
+MACHO-PPC-NEXT:     0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT: ]
+
+MACHO-PPC64: Relocations [
+MACHO-PPC64-NEXT:   Section __text {
+MACHO-PPC64-NEXT:     0x24 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x0 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x1C 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x58 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x18 1 2 0 0 _b
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section __picsymbolstub1 {
+MACHO-PPC64-NEXT:     0x14 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x0 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0xC 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     0x24 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section __la_symbol_ptr {
+MACHO-PPC64-NEXT:     0x0 0 3 1 0 dyld_stub_binding_helper
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT: ]

Modified: llvm/trunk/test/tools/llvm-readobj/sections-ext.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/sections-ext.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/sections-ext.test Fri Apr 12 20:45:40 2013
@@ -6,6 +6,10 @@ RUN: llvm-readobj -s -st -sr -sd %p/Inpu
 RUN:   | FileCheck %s -check-prefix MACHO-I386
 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-x86-64 \
 RUN:   | FileCheck %s -check-prefix MACHO-X86-64
+RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC
+RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc64 \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC64
 
 COFF:      Sections [
 COFF-NEXT:   Section {
@@ -249,3 +253,312 @@ MACHO-X86-64-NEXT:      0000: 48656C6C 6
 MACHO-X86-64-NEXT:    )
 MACHO-X86-64-NEXT:  }
 MACHO-X86-64-NEXT:]
+
+MACHO-PPC: Sections [
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 0
+MACHO-PPC-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x0
+MACHO-PPC-NEXT:     Size: 0x3C
+MACHO-PPC-NEXT:     Offset: 528
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x27C
+MACHO-PPC-NEXT:     RelocationCount: 5
+MACHO-PPC-NEXT:     Type: 0x0
+MACHO-PPC-NEXT:     Attributes [ (0x800004)
+MACHO-PPC-NEXT:       PureInstructions (0x800000)
+MACHO-PPC-NEXT:       SomeInstructions (0x4)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:     Relocations [
+MACHO-PPC-NEXT:       0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:       0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:       0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:       0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:       0x18 1 2 0 PPC_RELOC_BR24 0 _b
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Symbols [
+MACHO-PPC-NEXT:       Symbol {
+MACHO-PPC-NEXT:         Name: _f (4)
+MACHO-PPC-NEXT:         Type: 0xF
+MACHO-PPC-NEXT:         Section: __text (0x1)
+MACHO-PPC-NEXT:         RefType: UndefinedNonLazy (0x0)
+MACHO-PPC-NEXT:         Flags [ (0x0)
+MACHO-PPC-NEXT:         ]
+MACHO-PPC-NEXT:         Value: 0x0
+MACHO-PPC-NEXT:       }
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     SectionData (
+MACHO-PPC-NEXT:       0000: 7C0802A6 93E1FFFC 429F0005 7FE802A6  ||.......B.......|
+MACHO-PPC-NEXT:       0010: 90010008 9421FFB0 48000029 3C5F0000  |.....!..H..)<_..|
+MACHO-PPC-NEXT:       0020: 38210050 80420058 80010008 83E1FFFC  |8!.P.B.X........|
+MACHO-PPC-NEXT:       0030: 7C0803A6 80620000 4E800020           ||....b..N.. |
+MACHO-PPC-NEXT:     )
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 1
+MACHO-PPC-NEXT:     Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
+MACHO-PPC-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x40
+MACHO-PPC-NEXT:     Size: 0x20
+MACHO-PPC-NEXT:     Offset: 592
+MACHO-PPC-NEXT:     Alignment: 5
+MACHO-PPC-NEXT:     RelocationOffset: 0x2A4
+MACHO-PPC-NEXT:     RelocationCount: 4
+MACHO-PPC-NEXT:     Type: 0x8
+MACHO-PPC-NEXT:     Attributes [ (0x800004)
+MACHO-PPC-NEXT:       PureInstructions (0x800000)
+MACHO-PPC-NEXT:       SomeInstructions (0x4)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x20
+MACHO-PPC-NEXT:     Relocations [
+MACHO-PPC-NEXT:       0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:       0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:       0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
+MACHO-PPC-NEXT:       0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Symbols [
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     SectionData (
+MACHO-PPC-NEXT:       0000: 7C0802A6 429F0005 7D6802A6 3D6B0000  ||...B...}h..=k..|
+MACHO-PPC-NEXT:       0010: 7C0803A6 858B0020 7D8903A6 4E800420  ||...... }...N.. |
+MACHO-PPC-NEXT:     )
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 2
+MACHO-PPC-NEXT:     Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x60
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 624
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x0
+MACHO-PPC-NEXT:     RelocationCount: 0
+MACHO-PPC-NEXT:     Type: 0x0
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:     Relocations [
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Symbols [
+MACHO-PPC-NEXT:       Symbol {
+MACHO-PPC-NEXT:         Name: _b (1)
+MACHO-PPC-NEXT:         Type: 0xF
+MACHO-PPC-NEXT:         Section: __data (0x3)
+MACHO-PPC-NEXT:         RefType: UndefinedNonLazy (0x0)
+MACHO-PPC-NEXT:         Flags [ (0x0)
+MACHO-PPC-NEXT:         ]
+MACHO-PPC-NEXT:         Value: 0x60
+MACHO-PPC-NEXT:       }
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     SectionData (
+MACHO-PPC-NEXT:       0000: 0000002A                             |...*|
+MACHO-PPC-NEXT:     )
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 3
+MACHO-PPC-NEXT:     Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x64
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 628
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x0
+MACHO-PPC-NEXT:     RelocationCount: 0
+MACHO-PPC-NEXT:     Type: 0x6
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x1
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:     Relocations [
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Symbols [
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     SectionData (
+MACHO-PPC-NEXT:       0000: 00000000                             |....|
+MACHO-PPC-NEXT:     )
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 4
+MACHO-PPC-NEXT:     Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x68
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 632
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x2C4
+MACHO-PPC-NEXT:     RelocationCount: 1
+MACHO-PPC-NEXT:     Type: 0x7
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x2
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:     Relocations [
+MACHO-PPC-NEXT:       0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Symbols [
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     SectionData (
+MACHO-PPC-NEXT:       0000: 00000000                             |....|
+MACHO-PPC-NEXT:     )
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT: ]
+
+
+MACHO-PPC64:  Sections [
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 0
+MACHO-PPC64-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x0
+MACHO-PPC64-NEXT:     Size: 0x3C
+MACHO-PPC64-NEXT:     Offset: 608
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x2D4
+MACHO-PPC64-NEXT:     RelocationCount: 5
+MACHO-PPC64-NEXT:     Type: 0x0
+MACHO-PPC64-NEXT:     Attributes [ (0x800004)
+MACHO-PPC64-NEXT:       PureInstructions (0x800000)
+MACHO-PPC64-NEXT:       SomeInstructions (0x4)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:     Relocations [
+MACHO-PPC64-NEXT:       0x24 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x0 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x1C 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x58 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x18 1 2 0 0 _b
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Symbols [
+MACHO-PPC64-NEXT:       Symbol {
+MACHO-PPC64-NEXT:         Name: _f (4)
+MACHO-PPC64-NEXT:         Type: 0xF
+MACHO-PPC64-NEXT:         Section: __text (0x1)
+MACHO-PPC64-NEXT:         RefType: UndefinedNonLazy (0x0)
+MACHO-PPC64-NEXT:         Flags [ (0x0)
+MACHO-PPC64-NEXT:         ]
+MACHO-PPC64-NEXT:         Value: 0x0
+MACHO-PPC64-NEXT:       }
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     SectionData (
+MACHO-PPC64-NEXT:       0000: 7C0802A6 FBE1FFF8 429F0005 7FE802A6  ||.......B.......|
+MACHO-PPC64-NEXT:       0010: F8010010 F821FF81 48000029 3C5F0000  |.....!..H..)<_..|
+MACHO-PPC64-NEXT:       0020: 38210080 E8420058 E8010010 EBE1FFF8  |8!...B.X........|
+MACHO-PPC64-NEXT:       0030: 7C0803A6 E8620002 4E800020           ||....b..N.. |
+MACHO-PPC64-NEXT:     )
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 1
+MACHO-PPC64-NEXT:     Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
+MACHO-PPC64-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x40
+MACHO-PPC64-NEXT:     Size: 0x20
+MACHO-PPC64-NEXT:     Offset: 672
+MACHO-PPC64-NEXT:     Alignment: 5
+MACHO-PPC64-NEXT:     RelocationOffset: 0x2FC
+MACHO-PPC64-NEXT:     RelocationCount: 4
+MACHO-PPC64-NEXT:     Type: 0x8
+MACHO-PPC64-NEXT:     Attributes [ (0x800004)
+MACHO-PPC64-NEXT:       PureInstructions (0x800000)
+MACHO-PPC64-NEXT:       SomeInstructions (0x4)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x20
+MACHO-PPC64-NEXT:     Relocations [
+MACHO-PPC64-NEXT:       0x14 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x0 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0xC 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:       0x24 0 2 n/a 1 _b
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Symbols [
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     SectionData (
+MACHO-PPC64-NEXT:       0000: 7C0802A6 429F0005 7D6802A6 3D6B0000  ||...B...}h..=k..|
+MACHO-PPC64-NEXT:       0010: 7C0803A6 E98B0025 7D8903A6 4E800420  ||......%}...N.. |
+MACHO-PPC64-NEXT:     )
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 2
+MACHO-PPC64-NEXT:     Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x60
+MACHO-PPC64-NEXT:     Size: 0x4
+MACHO-PPC64-NEXT:     Offset: 704
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x0
+MACHO-PPC64-NEXT:     RelocationCount: 0
+MACHO-PPC64-NEXT:     Type: 0x0
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:     Relocations [
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Symbols [
+MACHO-PPC64-NEXT:       Symbol {
+MACHO-PPC64-NEXT:         Name: _b (1)
+MACHO-PPC64-NEXT:         Type: 0xF
+MACHO-PPC64-NEXT:         Section: __data (0x3)
+MACHO-PPC64-NEXT:         RefType: UndefinedNonLazy (0x0)
+MACHO-PPC64-NEXT:         Flags [ (0x0)
+MACHO-PPC64-NEXT:         ]
+MACHO-PPC64-NEXT:         Value: 0x60
+MACHO-PPC64-NEXT:       }
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     SectionData (
+MACHO-PPC64-NEXT:       0000: 0000002A                             |...*|
+MACHO-PPC64-NEXT:     )
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 3
+MACHO-PPC64-NEXT:     Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x64
+MACHO-PPC64-NEXT:     Size: 0x8
+MACHO-PPC64-NEXT:     Offset: 708
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x0
+MACHO-PPC64-NEXT:     RelocationCount: 0
+MACHO-PPC64-NEXT:     Type: 0x6
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x1
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:     Relocations [
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Symbols [
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     SectionData (
+MACHO-PPC64-NEXT:       0000: 00000000 00000000                    |........|
+MACHO-PPC64-NEXT:     )
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 4
+MACHO-PPC64-NEXT:     Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x6C
+MACHO-PPC64-NEXT:     Size: 0x8
+MACHO-PPC64-NEXT:     Offset: 716
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x31C
+MACHO-PPC64-NEXT:     RelocationCount: 1
+MACHO-PPC64-NEXT:     Type: 0x7
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x2
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:     Relocations [
+MACHO-PPC64-NEXT:       0x0 0 3 1 0 dyld_stub_binding_helper
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Symbols [
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     SectionData (
+MACHO-PPC64-NEXT:       0000: 00000000 00000000                    |........|
+MACHO-PPC64-NEXT:     )
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT: ]

Modified: llvm/trunk/test/tools/llvm-readobj/sections.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections.test?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/sections.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/sections.test Fri Apr 12 20:45:40 2013
@@ -6,6 +6,10 @@ RUN: llvm-readobj -s %p/Inputs/trivial.o
 RUN:   | FileCheck %s -check-prefix MACHO-I386
 RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-x86-64 \
 RUN:   | FileCheck %s -check-prefix MACHO-X86-64
+RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC
+RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
+RUN:   | FileCheck %s -check-prefix MACHO-PPC64
 
 COFF:      Sections [
 COFF-NEXT:   Section {
@@ -151,3 +155,177 @@ MACHO-X86-64-NEXT:    Reserved1: 0x0
 MACHO-X86-64-NEXT:    Reserved2: 0x0
 MACHO-X86-64-NEXT:  }
 MACHO-X86-64-NEXT:]
+
+MACHO-PPC: Sections [
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 0
+MACHO-PPC-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x0
+MACHO-PPC-NEXT:     Size: 0x3C
+MACHO-PPC-NEXT:     Offset: 528
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x27C
+MACHO-PPC-NEXT:     RelocationCount: 5
+MACHO-PPC-NEXT:     Type: 0x0
+MACHO-PPC-NEXT:     Attributes [ (0x800004)
+MACHO-PPC-NEXT:       PureInstructions (0x800000)
+MACHO-PPC-NEXT:       SomeInstructions (0x4)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 1
+MACHO-PPC-NEXT:     Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
+MACHO-PPC-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x40
+MACHO-PPC-NEXT:     Size: 0x20
+MACHO-PPC-NEXT:     Offset: 592
+MACHO-PPC-NEXT:     Alignment: 5
+MACHO-PPC-NEXT:     RelocationOffset: 0x2A4
+MACHO-PPC-NEXT:     RelocationCount: 4
+MACHO-PPC-NEXT:     Type: 0x8
+MACHO-PPC-NEXT:     Attributes [ (0x800004)
+MACHO-PPC-NEXT:       PureInstructions (0x800000)
+MACHO-PPC-NEXT:       SomeInstructions (0x4)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x20
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 2
+MACHO-PPC-NEXT:     Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x60
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 624
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x0
+MACHO-PPC-NEXT:     RelocationCount: 0
+MACHO-PPC-NEXT:     Type: 0x0
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x0
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 3
+MACHO-PPC-NEXT:     Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x64
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 628
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x0
+MACHO-PPC-NEXT:     RelocationCount: 0
+MACHO-PPC-NEXT:     Type: 0x6
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x1
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT:   Section {
+MACHO-PPC-NEXT:     Index: 4
+MACHO-PPC-NEXT:     Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC-NEXT:     Address: 0x68
+MACHO-PPC-NEXT:     Size: 0x4
+MACHO-PPC-NEXT:     Offset: 632
+MACHO-PPC-NEXT:     Alignment: 2
+MACHO-PPC-NEXT:     RelocationOffset: 0x2C4
+MACHO-PPC-NEXT:     RelocationCount: 1
+MACHO-PPC-NEXT:     Type: 0x7
+MACHO-PPC-NEXT:     Attributes [ (0x0)
+MACHO-PPC-NEXT:     ]
+MACHO-PPC-NEXT:     Reserved1: 0x2
+MACHO-PPC-NEXT:     Reserved2: 0x0
+MACHO-PPC-NEXT:   }
+MACHO-PPC-NEXT: ]
+
+MACHO-PPC64: Sections [
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 0
+MACHO-PPC64-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x0
+MACHO-PPC64-NEXT:     Size: 0x3C
+MACHO-PPC64-NEXT:     Offset: 608
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x2D4
+MACHO-PPC64-NEXT:     RelocationCount: 5
+MACHO-PPC64-NEXT:     Type: 0x0
+MACHO-PPC64-NEXT:     Attributes [ (0x800004)
+MACHO-PPC64-NEXT:       PureInstructions (0x800000)
+MACHO-PPC64-NEXT:       SomeInstructions (0x4)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 1
+MACHO-PPC64-NEXT:     Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
+MACHO-PPC64-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x40
+MACHO-PPC64-NEXT:     Size: 0x20
+MACHO-PPC64-NEXT:     Offset: 672
+MACHO-PPC64-NEXT:     Alignment: 5
+MACHO-PPC64-NEXT:     RelocationOffset: 0x2FC
+MACHO-PPC64-NEXT:     RelocationCount: 4
+MACHO-PPC64-NEXT:     Type: 0x8
+MACHO-PPC64-NEXT:     Attributes [ (0x800004)
+MACHO-PPC64-NEXT:       PureInstructions (0x800000)
+MACHO-PPC64-NEXT:       SomeInstructions (0x4)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x20
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 2
+MACHO-PPC64-NEXT:     Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x60
+MACHO-PPC64-NEXT:     Size: 0x4
+MACHO-PPC64-NEXT:     Offset: 704
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x0
+MACHO-PPC64-NEXT:     RelocationCount: 0
+MACHO-PPC64-NEXT:     Type: 0x0
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x0
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 3
+MACHO-PPC64-NEXT:     Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x64
+MACHO-PPC64-NEXT:     Size: 0x8
+MACHO-PPC64-NEXT:     Offset: 708
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x0
+MACHO-PPC64-NEXT:     RelocationCount: 0
+MACHO-PPC64-NEXT:     Type: 0x6
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x1
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT:   Section {
+MACHO-PPC64-NEXT:     Index: 4
+MACHO-PPC64-NEXT:     Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
+MACHO-PPC64-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+MACHO-PPC64-NEXT:     Address: 0x6C
+MACHO-PPC64-NEXT:     Size: 0x8
+MACHO-PPC64-NEXT:     Offset: 716
+MACHO-PPC64-NEXT:     Alignment: 2
+MACHO-PPC64-NEXT:     RelocationOffset: 0x31C
+MACHO-PPC64-NEXT:     RelocationCount: 1
+MACHO-PPC64-NEXT:     Type: 0x7
+MACHO-PPC64-NEXT:     Attributes [ (0x0)
+MACHO-PPC64-NEXT:     ]
+MACHO-PPC64-NEXT:     Reserved1: 0x2
+MACHO-PPC64-NEXT:     Reserved2: 0x0
+MACHO-PPC64-NEXT:   }
+MACHO-PPC64-NEXT: ]

Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Fri Apr 12 20:45:40 2013
@@ -27,6 +27,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Object/MachO.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
@@ -183,11 +184,14 @@ static void emitDOTFile(const char *File
   Out << "}\n";
 }
 
-static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header,
-                                  MachOObjectFileBase *MachOObj,
-                                  std::vector<SectionRef> &Sections,
-                                  std::vector<SymbolRef> &Symbols,
-                                  SmallVectorImpl<uint64_t> &FoundFns) {
+template<endianness E>
+static void
+getSectionsAndSymbols(const typename MachOObjectFileMiddle<E>::Header *Header,
+                      const MachOObjectFileMiddle<E> *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))
@@ -202,19 +206,23 @@ static void getSectionsAndSymbols(const
   }
 
   for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {
-    const MachOObjectFileBase::LoadCommand *Command =
+    const typename ObjType::LoadCommand *Command =
       MachOObj->getLoadCommandInfo(i);
     if (Command->Type == macho::LCT_FunctionStarts) {
       // We found a function starts segment, parse the addresses for later
       // consumption.
-      const MachOObjectFileBase::LinkeditDataLoadCommand *LLC =
- reinterpret_cast<const MachOObjectFileBase::LinkeditDataLoadCommand*>(Command);
+      const typename ObjType::LinkeditDataLoadCommand *LLC =
+    reinterpret_cast<const typename ObjType::LinkeditDataLoadCommand*>(Command);
 
       MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
     }
   }
 }
 
+template<endianness E>
+static void DisassembleInputMachO2(StringRef Filename,
+                                   MachOObjectFileMiddle<E> *MachOOF);
+
 void llvm::DisassembleInputMachO(StringRef Filename) {
   OwningPtr<MemoryBuffer> Buff;
 
@@ -226,7 +234,18 @@ void llvm::DisassembleInputMachO(StringR
   OwningPtr<MachOObjectFileBase> MachOOF(static_cast<MachOObjectFileBase*>(
         ObjectFile::createMachOObjectFile(Buff.take())));
 
-  const Target *TheTarget = GetTarget(MachOOF.get());
+  if (MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachOOF.get())) {
+    DisassembleInputMachO2(Filename, O);
+    return;
+  }
+  MachOObjectFileBE *O = cast<MachOObjectFileBE>(MachOOF.get());
+  DisassembleInputMachO2(Filename, O);
+}
+
+template<endianness E>
+static void DisassembleInputMachO2(StringRef Filename,
+                                   MachOObjectFileMiddle<E> *MachOOF) {
+  const Target *TheTarget = GetTarget(MachOOF);
   if (!TheTarget) {
     // GetTarget prints out stuff.
     return;
@@ -254,13 +273,14 @@ void llvm::DisassembleInputMachO(StringR
 
   outs() << '\n' << Filename << ":\n\n";
 
-  const MachOObjectFileBase::Header *Header = MachOOF->getHeader();
+  const typename MachOObjectFileMiddle<E>::Header *Header =
+    MachOOF->getHeader();
 
   std::vector<SectionRef> Sections;
   std::vector<SymbolRef> Symbols;
   SmallVector<uint64_t, 8> FoundFns;
 
-  getSectionsAndSymbols(Header, MachOOF.get(), Sections, Symbols, FoundFns);
+  getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns);
 
   // Make a copy of the unsorted symbol list. FIXME: duplication
   std::vector<SymbolRef> UnsortedSymbols(Symbols);
@@ -274,7 +294,7 @@ void llvm::DisassembleInputMachO(StringR
 #endif
 
   OwningPtr<DIContext> diContext;
-  ObjectFile *DbgObj = MachOOF.get();
+  ObjectFile *DbgObj = MachOOF;
   // Try to find debug info and set up the DIContext for it.
   if (UseDbg) {
     // A separate DSym file path was specified, parse it as a macho file,
@@ -563,7 +583,7 @@ void llvm::DisassembleInputMachO(StringR
                 Relocs[j].second.getName(SymName);
 
                 outs() << "\t# " << SymName << ' ';
-                DumpAddress(Addr, Sections, MachOOF.get(), outs());
+                DumpAddress(Addr, Sections, MachOOF, outs());
               }
 
             // If this instructions contains an address, see if we can evaluate
@@ -572,7 +592,7 @@ void llvm::DisassembleInputMachO(StringR
                                                           Inst.Address,
                                                           Inst.Size);
             if (targ != -1ULL)
-              DumpAddress(targ, Sections, MachOOF.get(), outs());
+              DumpAddress(targ, Sections, MachOOF, outs());
 
             // Print debug info.
             if (diContext) {

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Fri Apr 12 20:45:40 2013
@@ -191,6 +191,14 @@ bool llvm::RelocAddressLess(RelocationRe
   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
@@ -255,9 +263,10 @@ static void DisassembleObject(const Obje
     std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
 
     StringRef SegmentName = "";
-    if (const MachOObjectFileBase *MachO = dyn_cast<const MachOObjectFileBase>(Obj)) {
+    if (const MachOObjectFileBase *MachO =
+        dyn_cast<const MachOObjectFileBase>(Obj)) {
       DataRefImpl DR = i->getRawDataRefImpl();
-      SegmentName = MachO->getSectionFinalSegmentName(DR);
+      SegmentName = getSectionFinalSegmentName(MachO, DR);
     }
     StringRef name;
     if (error(i->getName(name))) break;
@@ -591,9 +600,10 @@ static void PrintSymbolTable(const Objec
       else if (Section == o->end_sections())
         outs() << "*UND*";
       else {
-        if (const MachOObjectFileBase *MachO = dyn_cast<const MachOObjectFileBase>(o)) {
+        if (const MachOObjectFileBase *MachO =
+            dyn_cast<const MachOObjectFileBase>(o)) {
           DataRefImpl DR = Section->getRawDataRefImpl();
-          StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
+          StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);
           outs() << SegmentName << ",";
         }
         StringRef SectionName;

Modified: llvm/trunk/tools/llvm-readobj/MachODumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=179440&r1=179439&r2=179440&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Fri Apr 12 20:45:40 2013
@@ -27,7 +27,7 @@ namespace {
 
 class MachODumper : public ObjDumper {
 public:
-  MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer)
+  MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer)
     : ObjDumper(Writer)
     , Obj(Obj) { }
 
@@ -43,7 +43,14 @@ private:
 
   void printRelocation(section_iterator SecI, relocation_iterator RelI);
 
-  const llvm::object::MachOObjectFileBase *Obj;
+  template<support::endianness E>
+  void printRelocation(const MachOObjectFileMiddle<E> *Obj,
+                       section_iterator SecI, relocation_iterator RelI);
+
+  template<support::endianness E>
+  void printSections(const MachOObjectFileMiddle<E> *Obj);
+
+  const MachOObjectFileBase *Obj;
 };
 
 } // namespace
@@ -157,58 +164,59 @@ namespace {
   };
 }
 
-static void getSection(const MachOObjectFileBase *Obj,
+template<class MachOT>
+static void getSection(const MachOObjectFile<MachOT> *Obj,
                        DataRefImpl DRI,
                        MachOSection &Section) {
-  if (const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(Obj)) {
-    const MachOObjectFile64Le::Section *Sect = O->getSection(DRI);
+  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;
+}
 
-    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;
-  } else {
-    const MachOObjectFile32Le *O2 = cast<MachOObjectFile32Le>(Obj);
-    const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI);
+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);
+}
 
-    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;
-  }
+template<class MachOT>
+static void getSymbol(const MachOObjectFile<MachOT> *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 MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(Obj)) {
-    const MachOObjectFile64Le::SymbolTableEntry *Entry =
-      O->getSymbolTableEntry(DRI);
-    Symbol.StringIndex  = Entry->StringIndex;
-    Symbol.Type         = Entry->Type;
-    Symbol.SectionIndex = Entry->SectionIndex;
-    Symbol.Flags        = Entry->Flags;
-    Symbol.Value        = Entry->Value;
-  } else {
-    const MachOObjectFile32Le *O2 = cast<MachOObjectFile32Le>(Obj);
-    const MachOObjectFile32Le::SymbolTableEntry *Entry =
-      O2->getSymbolTableEntry(DRI);
-    Symbol.StringIndex  = Entry->StringIndex;
-    Symbol.Type         = Entry->Type;
-    Symbol.SectionIndex = Entry->SectionIndex;
-    Symbol.Flags        = Entry->Flags;
-    Symbol.Value        = Entry->Value;
-  }
+  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);
 }
 
 void MachODumper::printFileHeaders() {
@@ -216,6 +224,14 @@ void MachODumper::printFileHeaders() {
 }
 
 void MachODumper::printSections() {
+  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
+    return printSections(O);
+  const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
+  return printSections(O);
+}
+
+template<support::endianness E>
+void MachODumper::printSections(const MachOObjectFileMiddle<E> *Obj) {
   ListScope Group(W, "Sections");
 
   int SectionIndex = -1;
@@ -328,6 +344,16 @@ void MachODumper::printRelocations() {
 
 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);
+}
+
+template<support::endianness E>
+void MachODumper::printRelocation(const MachOObjectFileMiddle<E> *Obj,
+                                  section_iterator SecI,
+                                  relocation_iterator RelI) {
   uint64_t Offset;
   SmallString<32> RelocName;
   StringRef SymbolName;
@@ -338,14 +364,15 @@ void MachODumper::printRelocation(sectio
   if (error(Symbol.getName(SymbolName))) return;
 
   DataRefImpl DR = RelI->getRawDataRefImpl();
-  const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR);
-  bool IsScattered = Obj->isScattered(RE);
+  const typename MachOObjectFileMiddle<E>::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->isPCRel(RE));
-    W.printNumber("Length", Obj->getLength(RE));
+    W.printNumber("PCRel", Obj->isRelocationPCRel(RE));
+    W.printNumber("Length", Obj->getRelocationLength(RE));
     if (IsScattered)
       W.printString("Extern", StringRef("N/A"));
     else
@@ -356,8 +383,8 @@ void MachODumper::printRelocation(sectio
   } else {
     raw_ostream& OS = W.startLine();
     OS << W.hex(Offset)
-       << " " << Obj->isPCRel(RE)
-       << " " << Obj->getLength(RE);
+       << " " << Obj->isRelocationPCRel(RE)
+       << " " << Obj->getRelocationLength(RE);
     if (IsScattered)
       OS << " n/a";
     else
@@ -399,6 +426,7 @@ void MachODumper::printSymbol(symbol_ite
   StringRef SectionName;
   section_iterator SecI(Obj->end_sections());
   if (error(SymI->getSection(SecI)) ||
+      SecI == Obj->end_sections() ||
       error(SecI->getName(SectionName)))
     SectionName = "";
 





More information about the llvm-commits mailing list