[llvm] r180624 - Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser.

Rafael Espindola rafael.espindola at gmail.com
Fri Apr 26 13:07:33 PDT 2013


Author: rafael
Date: Fri Apr 26 15:07:33 2013
New Revision: 180624

URL: http://llvm.org/viewvc/llvm-project?rev=180624&view=rev
Log:
Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser.

For Mach-O there were 2 implementations for parsing object files. A
standalone llvm/Object/MachOObject.h and llvm/Object/MachO.h which
implements the generic interface in llvm/Object/ObjectFile.h.

This patch adds the missing features to MachO.h, moves macho-dump to
use MachO.h and removes ObjectFile.h.

In addition to making sure that check-all is clean, I checked that the
new version produces exactly the same output in all Mach-O files in a
llvm+clang build directory (including executables and shared
libraries).

To test the performance, I ran macho-dump over all the files in a
llvm+clang build directory again, but this time redirecting the output
to /dev/null. Both the old and new versions take about 4.6 seconds
(2.5 user) to finish.

Removed:
    llvm/trunk/include/llvm/ADT/InMemoryStruct.h
    llvm/trunk/include/llvm/Object/MachOObject.h
    llvm/trunk/lib/Object/MachOObject.cpp
Modified:
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
    llvm/trunk/lib/Object/CMakeLists.txt
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
    llvm/trunk/tools/macho-dump/macho-dump.cpp

Removed: llvm/trunk/include/llvm/ADT/InMemoryStruct.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/InMemoryStruct.h?rev=180623&view=auto
==============================================================================
--- llvm/trunk/include/llvm/ADT/InMemoryStruct.h (original)
+++ llvm/trunk/include/llvm/ADT/InMemoryStruct.h (removed)
@@ -1,77 +0,0 @@
-//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_INMEMORYSTRUCT_H
-#define LLVM_ADT_INMEMORYSTRUCT_H
-
-#include <cassert>
-
-namespace llvm {
-
-/// \brief Helper object for abstracting access to an in-memory structure which
-/// may require some kind of temporary storage.
-///
-/// This class is designed to be used for accessing file data structures which
-/// in the common case can be accessed from a direct pointer to a memory mapped
-/// object, but which in some cases may require indirect access to a temporary
-/// structure (which, for example, may have undergone endianness translation).
-template<typename T>
-class InMemoryStruct {
-  typedef T value_type;
-  typedef value_type &reference;
-  typedef value_type *pointer;
-  typedef const value_type &const_reference;
-  typedef const value_type *const_pointer;
-
-  /// \brief The smart pointer target.
-  value_type *Target;
-
-  /// \brief A temporary object which can be used as a target of the smart
-  /// pointer.
-  value_type Contents;
-
-private:
-
-public:
-  InMemoryStruct() : Target(0) {}
-  InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {}
-  InMemoryStruct(pointer Value) : Target(Value) {}
-  InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; }
-  
-  void operator=(const InMemoryStruct<T> &Value) {
-    if (Value.Target != &Value.Contents) {
-      Target = Value.Target;
-    } else {
-      Target = &Contents;
-      Contents = Value.Contents;
-    }
-  }
-  
-  const_reference operator*() const {
-    assert(Target && "Cannot dereference null pointer");
-    return *Target;
-  }
-  reference operator*() {
-    assert(Target && "Cannot dereference null pointer");
-    return *Target;
-  }
-
-  const_pointer operator->() const {
-    return Target;
-  }
-  pointer operator->() {
-    return Target;
-  }
-
-  operator bool() const { return Target != 0; }
-};
-
-}
-
-#endif

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Fri Apr 26 15:07:33 2013
@@ -106,6 +106,9 @@ public:
 
   virtual StringRef getLoadName() const;
 
+  relocation_iterator getSectionRelBegin(unsigned Index) const;
+  relocation_iterator getSectionRelEnd(unsigned Index) 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.
@@ -134,14 +137,32 @@ public:
   // MachO specific structures.
   macho::Section getSection(DataRefImpl DRI) const;
   macho::Section64 getSection64(DataRefImpl DRI) const;
+  macho::Section getSection(const LoadCommandInfo &L, unsigned Index) const;
+  macho::Section64 getSection64(const LoadCommandInfo &L, unsigned Index) const;
   macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;
   macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;
+
   macho::LinkeditDataLoadCommand
   getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
+  macho::SegmentLoadCommand
+  getSegmentLoadCommand(const LoadCommandInfo &L) const;
+  macho::Segment64LoadCommand
+  getSegment64LoadCommand(const LoadCommandInfo &L) const;
+  macho::LinkerOptionsLoadCommand
+  getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
+
   macho::RelocationEntry getRelocation(DataRefImpl Rel) const;
   macho::Header getHeader() const;
+  macho::Header64Ext getHeader64Ext() const;
+  macho::IndirectSymbolTableEntry
+  getIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
+                              unsigned Index) const;
+  macho::DataInCodeTableEntry getDataInCodeTableEntry(uint32_t DataOffset,
+                                                      unsigned Index) const;
   macho::SymtabLoadCommand getSymtabLoadCommand() const;
+  macho::DysymtabLoadCommand getDysymtabLoadCommand() const;
 
+  StringRef getStringTableData() const;
   bool is64Bit() const;
   void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
 
@@ -153,6 +174,7 @@ private:
   typedef SmallVector<const char*, 1> SectionList;
   SectionList Sections;
   const char *SymtabLoadCmd;
+  const char *DysymtabLoadCmd;
 };
 
 }

Removed: llvm/trunk/include/llvm/Object/MachOObject.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachOObject.h?rev=180623&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Object/MachOObject.h (original)
+++ llvm/trunk/include/llvm/Object/MachOObject.h (removed)
@@ -1,212 +0,0 @@
-//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MACHOOBJECT_H
-#define LLVM_OBJECT_MACHOOBJECT_H
-
-#include "llvm/ADT/InMemoryStruct.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/MachOFormat.h"
-#include <string>
-
-namespace llvm {
-
-class MemoryBuffer;
-class raw_ostream;
-
-namespace object {
-
-/// \brief Wrapper object for manipulating Mach-O object files.
-///
-/// This class is designed to implement a full-featured, efficient, portable,
-/// and robust Mach-O interface to Mach-O object files. It does not attempt to
-/// smooth over rough edges in the Mach-O format or generalize access to object
-/// independent features.
-///
-/// The class is designed around accessing the Mach-O object which is expected
-/// to be fully loaded into memory.
-///
-/// This class is *not* suitable for concurrent use. For efficient operation,
-/// the class uses APIs which rely on the ability to cache the results of
-/// certain calls in internal objects which are not safe for concurrent
-/// access. This allows the API to be zero-copy on the common paths.
-//
-// FIXME: It would be cool if we supported a "paged" MemoryBuffer
-// implementation. This would allow us to implement a more sensible version of
-// MemoryObject which can work like a MemoryBuffer, but be more efficient for
-// objects which are in the current address space.
-class MachOObject {
-public:
-  struct LoadCommandInfo {
-    /// The load command information.
-    macho::LoadCommand Command;
-
-    /// The offset to the start of the load command in memory.
-    uint64_t Offset;
-  };
-
-private:
-  OwningPtr<MemoryBuffer> Buffer;
-
-  /// Whether the object is little endian.
-  bool IsLittleEndian;
-  /// Whether the object is 64-bit.
-  bool Is64Bit;
-  /// Whether the object is swapped endianness from the host.
-  bool IsSwappedEndian;
-  /// Whether the string table has been registered.
-  bool HasStringTable;
-
-  /// The cached information on the load commands.
-  LoadCommandInfo *LoadCommands;
-  mutable unsigned NumLoadedCommands;
-
-  /// The cached copy of the header.
-  macho::Header Header;
-  macho::Header64Ext Header64Ext;
-
-  /// Cache string table information.
-  StringRef StringTable;
-
-private:
-  MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
-
-public:
-  ~MachOObject();
-
-  /// \brief Load a Mach-O object from a MemoryBuffer object.
-  ///
-  /// \param Buffer - The buffer to load the object from. This routine takes
-  /// exclusive ownership of the buffer (which is passed to the returned object
-  /// on success).
-  /// \param ErrorStr [out] - If given, will be set to a user readable error
-  /// message on failure.
-  /// \returns The loaded object, or null on error.
-  static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
-                                     std::string *ErrorStr = 0);
-
-  /// @name File Information
-  /// @{
-
-  bool isLittleEndian() const { return IsLittleEndian; }
-  bool isSwappedEndian() const { return IsSwappedEndian; }
-  bool is64Bit() const { return Is64Bit; }
-
-  unsigned getHeaderSize() const {
-    return Is64Bit ? macho::Header64Size : macho::Header32Size;
-  }
-
-  StringRef getData(size_t Offset, size_t Size) const;
-
-  /// @}
-  /// @name String Table Data
-  /// @{
-
-  StringRef getStringTableData() const {
-    assert(HasStringTable && "String table has not been registered!");
-    return StringTable;
-  }
-
-  StringRef getStringAtIndex(unsigned Index) const {
-    size_t End = getStringTableData().find('\0', Index);
-    return getStringTableData().slice(Index, End);
-  }
-
-  void RegisterStringTable(macho::SymtabLoadCommand &SLC);
-
-  /// @}
-  /// @name Object Header Access
-  /// @{
-
-  const macho::Header &getHeader() const { return Header; }
-  const macho::Header64Ext &getHeader64Ext() const {
-    assert(is64Bit() && "Invalid access!");
-    return Header64Ext;
-  }
-
-  /// @}
-  /// @name Object Structure Access
-  /// @{
-
-  // TODO: Would be useful to have an iterator based version
-  // of this.
-  /// \brief Retrieve the information for the given load command.
-  const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
-
-  void ReadSegmentLoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
-  void ReadSegment64LoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
-  void ReadSymtabLoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
-  void ReadDysymtabLoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
-  void ReadLinkeditDataLoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
-  void ReadLinkerOptionsLoadCommand(
-    const LoadCommandInfo &LCI,
-    InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
-  void ReadIndirectSymbolTableEntry(
-    const macho::DysymtabLoadCommand &DLC,
-    unsigned Index,
-    InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
-  void ReadSection(
-    const LoadCommandInfo &LCI,
-    unsigned Index,
-    InMemoryStruct<macho::Section> &Res) const;
-  void ReadSection64(
-    const LoadCommandInfo &LCI,
-    unsigned Index,
-    InMemoryStruct<macho::Section64> &Res) const;
-  void ReadRelocationEntry(
-    uint64_t RelocationTableOffset, unsigned Index,
-    InMemoryStruct<macho::RelocationEntry> &Res) const;
-  void ReadSymbolTableEntry(
-    uint64_t SymbolTableOffset, unsigned Index,
-    InMemoryStruct<macho::SymbolTableEntry> &Res) const;
-  void ReadSymbol64TableEntry(
-    uint64_t SymbolTableOffset, unsigned Index,
-    InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
-  void ReadDataInCodeTableEntry(
-    uint64_t TableOffset, unsigned Index,
-    InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
-  void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
-
-  /// @}
-
-  /// @name Object Dump Facilities
-  /// @{
-  /// dump - Support for debugging, callable in GDB: V->dump()
-  //
-  void dump() const;
-  void dumpHeader() const;
-
-  /// print - Implement operator<< on Value.
-  ///
-  void print(raw_ostream &O) const;
-  void printHeader(raw_ostream &O) const;
-
-  /// @}
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
-  V.print(OS);
-  return OS;
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h Fri Apr 26 15:07:33 2013
@@ -16,7 +16,7 @@
 
 #include "RuntimeDyldImpl.h"
 #include "llvm/ADT/IndexedMap.h"
-#include "llvm/Object/MachOObject.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/Support/Format.h"
 
 using namespace llvm;

Modified: llvm/trunk/lib/Object/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/lib/Object/CMakeLists.txt (original)
+++ llvm/trunk/lib/Object/CMakeLists.txt Fri Apr 26 15:07:33 2013
@@ -4,7 +4,6 @@ add_llvm_library(LLVMObject
   COFFObjectFile.cpp
   ELFObjectFile.cpp
   Error.cpp
-  MachOObject.cpp
   MachOObjectFile.cpp
   Object.cpp
   ObjectFile.cpp

Removed: llvm/trunk/lib/Object/MachOObject.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObject.cpp?rev=180623&view=auto
==============================================================================
--- llvm/trunk/lib/Object/MachOObject.cpp (original)
+++ llvm/trunk/lib/Object/MachOObject.cpp (removed)
@@ -1,422 +0,0 @@
-//===- MachOObject.cpp - Mach-O Object File Wrapper -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/MachOObject.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SwapByteOrder.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-/* Translation Utilities */
-
-template<typename T>
-static void SwapValue(T &Value) {
-  Value = sys::SwapByteOrder(Value);
-}
-
-template<typename T>
-static void SwapStruct(T &Value);
-
-template<typename T>
-static void ReadInMemoryStruct(const MachOObject &MOO,
-                               StringRef Buffer, uint64_t Base,
-                               InMemoryStruct<T> &Res) {
-  typedef T struct_type;
-  uint64_t Size = sizeof(struct_type);
-
-  // Check that the buffer contains the expected data.
-  if (Base + Size >  Buffer.size()) {
-    Res = 0;
-    return;
-  }
-
-  // Check whether we can return a direct pointer.
-  struct_type *Ptr = reinterpret_cast<struct_type *>(
-                       const_cast<char *>(Buffer.data() + Base));
-  if (!MOO.isSwappedEndian()) {
-    Res = Ptr;
-    return;
-  }
-
-  // Otherwise, copy the struct and translate the values.
-  Res = *Ptr;
-  SwapStruct(*Res);
-}
-
-/* *** */
-
-MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_,
-                         bool Is64Bit_)
-  : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_),
-    IsSwappedEndian(IsLittleEndian != sys::IsLittleEndianHost),
-    HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) {
-  // Load the common header.
-  memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header));
-  if (IsSwappedEndian) {
-    SwapValue(Header.Magic);
-    SwapValue(Header.CPUType);
-    SwapValue(Header.CPUSubtype);
-    SwapValue(Header.FileType);
-    SwapValue(Header.NumLoadCommands);
-    SwapValue(Header.SizeOfLoadCommands);
-    SwapValue(Header.Flags);
-  }
-
-  if (is64Bit()) {
-    memcpy(&Header64Ext, Buffer->getBuffer().data() + sizeof(Header),
-           sizeof(Header64Ext));
-    if (IsSwappedEndian) {
-      SwapValue(Header64Ext.Reserved);
-    }
-  }
-
-  // Create the load command array if sane.
-  if (getHeader().NumLoadCommands < (1 << 20))
-    LoadCommands = new LoadCommandInfo[getHeader().NumLoadCommands];
-}
-
-MachOObject::~MachOObject() {
-  delete [] LoadCommands;
-}
-
-MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer,
-                                         std::string *ErrorStr) {
-  // First, check the magic value and initialize the basic object info.
-  bool IsLittleEndian = false, Is64Bit = false;
-  StringRef Magic = Buffer->getBuffer().slice(0, 4);
-  if (Magic == "\xFE\xED\xFA\xCE") {
-  }  else if (Magic == "\xCE\xFA\xED\xFE") {
-    IsLittleEndian = true;
-  } else if (Magic == "\xFE\xED\xFA\xCF") {
-    Is64Bit = true;
-  } else if (Magic == "\xCF\xFA\xED\xFE") {
-    IsLittleEndian = true;
-    Is64Bit = true;
-  } else {
-    if (ErrorStr) *ErrorStr = "not a Mach object file (invalid magic)";
-    return 0;
-  }
-
-  // Ensure that the at least the full header is present.
-  unsigned HeaderSize = Is64Bit ? macho::Header64Size : macho::Header32Size;
-  if (Buffer->getBufferSize() < HeaderSize) {
-    if (ErrorStr) *ErrorStr = "not a Mach object file (invalid header)";
-    return 0;
-  }
-
-  OwningPtr<MachOObject> Object(new MachOObject(Buffer, IsLittleEndian,
-                                                Is64Bit));
-
-  // Check for bogus number of load commands.
-  if (Object->getHeader().NumLoadCommands >= (1 << 20)) {
-    if (ErrorStr) *ErrorStr = "not a Mach object file (unreasonable header)";
-    return 0;
-  }
-
-  if (ErrorStr) *ErrorStr = "";
-  return Object.take();
-}
-
-StringRef MachOObject::getData(size_t Offset, size_t Size) const {
-  return Buffer->getBuffer().substr(Offset,Size);
-}
-
-void MachOObject::RegisterStringTable(macho::SymtabLoadCommand &SLC) {
-  HasStringTable = true;
-  StringTable = Buffer->getBuffer().substr(SLC.StringTableOffset,
-                                           SLC.StringTableSize);
-}
-
-const MachOObject::LoadCommandInfo &
-MachOObject::getLoadCommandInfo(unsigned Index) const {
-  assert(Index < getHeader().NumLoadCommands && "Invalid index!");
-
-  // Load the command, if necessary.
-  if (Index >= NumLoadedCommands) {
-    uint64_t Offset;
-    if (Index == 0) {
-      Offset = getHeaderSize();
-    } else {
-      const LoadCommandInfo &Prev = getLoadCommandInfo(Index - 1);
-      Offset = Prev.Offset + Prev.Command.Size;
-    }
-
-    LoadCommandInfo &Info = LoadCommands[Index];
-    memcpy(&Info.Command, Buffer->getBuffer().data() + Offset,
-           sizeof(macho::LoadCommand));
-    if (IsSwappedEndian) {
-      SwapValue(Info.Command.Type);
-      SwapValue(Info.Command.Size);
-    }
-    Info.Offset = Offset;
-    NumLoadedCommands = Index + 1;
-  }
-
-  return LoadCommands[Index];
-}
-
-template<>
-void SwapStruct(macho::SegmentLoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.VMAddress);
-  SwapValue(Value.VMSize);
-  SwapValue(Value.FileOffset);
-  SwapValue(Value.FileSize);
-  SwapValue(Value.MaxVMProtection);
-  SwapValue(Value.InitialVMProtection);
-  SwapValue(Value.NumSections);
-  SwapValue(Value.Flags);
-}
-void MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI,
-                         InMemoryStruct<macho::SegmentLoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::Segment64LoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.VMAddress);
-  SwapValue(Value.VMSize);
-  SwapValue(Value.FileOffset);
-  SwapValue(Value.FileSize);
-  SwapValue(Value.MaxVMProtection);
-  SwapValue(Value.InitialVMProtection);
-  SwapValue(Value.NumSections);
-  SwapValue(Value.Flags);
-}
-void MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI,
-                       InMemoryStruct<macho::Segment64LoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::SymtabLoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.SymbolTableOffset);
-  SwapValue(Value.NumSymbolTableEntries);
-  SwapValue(Value.StringTableOffset);
-  SwapValue(Value.StringTableSize);
-}
-void MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI,
-                          InMemoryStruct<macho::SymtabLoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::DysymtabLoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.LocalSymbolsIndex);
-  SwapValue(Value.NumLocalSymbols);
-  SwapValue(Value.ExternalSymbolsIndex);
-  SwapValue(Value.NumExternalSymbols);
-  SwapValue(Value.UndefinedSymbolsIndex);
-  SwapValue(Value.NumUndefinedSymbols);
-  SwapValue(Value.TOCOffset);
-  SwapValue(Value.NumTOCEntries);
-  SwapValue(Value.ModuleTableOffset);
-  SwapValue(Value.NumModuleTableEntries);
-  SwapValue(Value.ReferenceSymbolTableOffset);
-  SwapValue(Value.NumReferencedSymbolTableEntries);
-  SwapValue(Value.IndirectSymbolTableOffset);
-  SwapValue(Value.NumIndirectSymbolTableEntries);
-  SwapValue(Value.ExternalRelocationTableOffset);
-  SwapValue(Value.NumExternalRelocationTableEntries);
-  SwapValue(Value.LocalRelocationTableOffset);
-  SwapValue(Value.NumLocalRelocationTableEntries);
-}
-void MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI,
-                        InMemoryStruct<macho::DysymtabLoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::LinkeditDataLoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.DataOffset);
-  SwapValue(Value.DataSize);
-}
-void MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI,
-                    InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::LinkerOptionsLoadCommand &Value) {
-  SwapValue(Value.Type);
-  SwapValue(Value.Size);
-  SwapValue(Value.Count);
-}
-void MachOObject::ReadLinkerOptionsLoadCommand(const LoadCommandInfo &LCI,
-                   InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const {
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::IndirectSymbolTableEntry &Value) {
-  SwapValue(Value.Index);
-}
-void
-MachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
-                                          unsigned Index,
-                   InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const {
-  uint64_t Offset = (DLC.IndirectSymbolTableOffset +
-                     Index * sizeof(macho::IndirectSymbolTableEntry));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-
-template<>
-void SwapStruct(macho::Section &Value) {
-  SwapValue(Value.Address);
-  SwapValue(Value.Size);
-  SwapValue(Value.Offset);
-  SwapValue(Value.Align);
-  SwapValue(Value.RelocationTableOffset);
-  SwapValue(Value.NumRelocationTableEntries);
-  SwapValue(Value.Flags);
-  SwapValue(Value.Reserved1);
-  SwapValue(Value.Reserved2);
-}
-void MachOObject::ReadSection(const LoadCommandInfo &LCI,
-                              unsigned Index,
-                              InMemoryStruct<macho::Section> &Res) const {
-  assert(LCI.Command.Type == macho::LCT_Segment &&
-         "Unexpected load command info!");
-  uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) +
-                     Index * sizeof(macho::Section));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::Section64 &Value) {
-  SwapValue(Value.Address);
-  SwapValue(Value.Size);
-  SwapValue(Value.Offset);
-  SwapValue(Value.Align);
-  SwapValue(Value.RelocationTableOffset);
-  SwapValue(Value.NumRelocationTableEntries);
-  SwapValue(Value.Flags);
-  SwapValue(Value.Reserved1);
-  SwapValue(Value.Reserved2);
-  SwapValue(Value.Reserved3);
-}
-void MachOObject::ReadSection64(const LoadCommandInfo &LCI,
-                                unsigned Index,
-                                InMemoryStruct<macho::Section64> &Res) const {
-  assert(LCI.Command.Type == macho::LCT_Segment64 &&
-         "Unexpected load command info!");
-  uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) +
-                     Index * sizeof(macho::Section64));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::RelocationEntry &Value) {
-  SwapValue(Value.Word0);
-  SwapValue(Value.Word1);
-}
-void MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset,
-                                      unsigned Index,
-                            InMemoryStruct<macho::RelocationEntry> &Res) const {
-  uint64_t Offset = (RelocationTableOffset +
-                     Index * sizeof(macho::RelocationEntry));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::SymbolTableEntry &Value) {
-  SwapValue(Value.StringIndex);
-  SwapValue(Value.Flags);
-  SwapValue(Value.Value);
-}
-void MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset,
-                                       unsigned Index,
-                           InMemoryStruct<macho::SymbolTableEntry> &Res) const {
-  uint64_t Offset = (SymbolTableOffset +
-                     Index * sizeof(macho::SymbolTableEntry));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::Symbol64TableEntry &Value) {
-  SwapValue(Value.StringIndex);
-  SwapValue(Value.Flags);
-  SwapValue(Value.Value);
-}
-void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset,
-                                       unsigned Index,
-                         InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
-  uint64_t Offset = (SymbolTableOffset +
-                     Index * sizeof(macho::Symbol64TableEntry));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-template<>
-void SwapStruct(macho::DataInCodeTableEntry &Value) {
-  SwapValue(Value.Offset);
-  SwapValue(Value.Length);
-  SwapValue(Value.Kind);
-}
-void MachOObject::ReadDataInCodeTableEntry(uint64_t TableOffset,
-                                           unsigned Index,
-                       InMemoryStruct<macho::DataInCodeTableEntry> &Res) const {
-  uint64_t Offset = (TableOffset +
-                     Index * sizeof(macho::DataInCodeTableEntry));
-  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
-}
-
-void MachOObject::ReadULEB128s(uint64_t Index,
-                               SmallVectorImpl<uint64_t> &Out) const {
-  DataExtractor extractor(Buffer->getBuffer(), true, 0);
-
-  uint32_t offset = Index;
-  uint64_t data = 0;
-  while (uint64_t delta = extractor.getULEB128(&offset)) {
-    data += delta;
-    Out.push_back(data);
-  }
-}
-
-/* ** */
-// Object Dumping Facilities
-void MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; }
-void MachOObject::dumpHeader() const { printHeader(dbgs()); dbgs() << '\n'; }
-
-void MachOObject::printHeader(raw_ostream &O) const {
-  O << "('cputype', " << Header.CPUType << ")\n";
-  O << "('cpusubtype', " << Header.CPUSubtype << ")\n";
-  O << "('filetype', " << Header.FileType << ")\n";
-  O << "('num_load_commands', " << Header.NumLoadCommands << ")\n";
-  O << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n";
-  O << "('flag', " << Header.Flags << ")\n";
-
-  // Print extended header if 64-bit.
-  if (is64Bit())
-    O << "('reserved', " << Header64Ext.Reserved << ")\n";
-}
-
-void MachOObject::print(raw_ostream &O) const {
-  O << "Header:\n";
-  printHeader(O);
-  O << "Load Commands:\n";
-
-  O << "Buffer:\n";
-}

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Fri Apr 26 15:07:33 2013
@@ -120,6 +120,11 @@ void SwapStruct(macho::Header &H) {
 }
 
 template<>
+void SwapStruct(macho::Header64Ext &E) {
+  SwapValue(E.Reserved);
+}
+
+template<>
 void SwapStruct(macho::SymtabLoadCommand &C) {
   SwapValue(C.Type);
   SwapValue(C.Size);
@@ -130,6 +135,30 @@ void SwapStruct(macho::SymtabLoadCommand
 }
 
 template<>
+void SwapStruct(macho::DysymtabLoadCommand &C) {
+  SwapValue(C.Type);
+  SwapValue(C.Size);
+  SwapValue(C.LocalSymbolsIndex);
+  SwapValue(C.NumLocalSymbols);
+  SwapValue(C.ExternalSymbolsIndex);
+  SwapValue(C.NumExternalSymbols);
+  SwapValue(C.UndefinedSymbolsIndex);
+  SwapValue(C.NumUndefinedSymbols);
+  SwapValue(C.TOCOffset);
+  SwapValue(C.NumTOCEntries);
+  SwapValue(C.ModuleTableOffset);
+  SwapValue(C.NumModuleTableEntries);
+  SwapValue(C.ReferenceSymbolTableOffset);
+  SwapValue(C.NumReferencedSymbolTableEntries);
+  SwapValue(C.IndirectSymbolTableOffset);
+  SwapValue(C.NumIndirectSymbolTableEntries);
+  SwapValue(C.ExternalRelocationTableOffset);
+  SwapValue(C.NumExternalRelocationTableEntries);
+  SwapValue(C.LocalRelocationTableOffset);
+  SwapValue(C.NumLocalRelocationTableEntries);
+}
+
+template<>
 void SwapStruct(macho::LinkeditDataLoadCommand &C) {
   SwapValue(C.Type);
   SwapValue(C.Size);
@@ -165,6 +194,25 @@ void SwapStruct(macho::Segment64LoadComm
   SwapValue(C.Flags);
 }
 
+template<>
+void SwapStruct(macho::IndirectSymbolTableEntry &C) {
+  SwapValue(C.Index);
+}
+
+template<>
+void SwapStruct(macho::LinkerOptionsLoadCommand &C) {
+  SwapValue(C.Type);
+  SwapValue(C.Size);
+  SwapValue(C.Count);
+}
+
+template<>
+void SwapStruct(macho::DataInCodeTableEntry &C) {
+  SwapValue(C.Offset);
+  SwapValue(C.Length);
+  SwapValue(C.Kind);
+}
+
 template<typename T>
 T getStruct(const MachOObjectFile *O, const char *P) {
   T Cmd;
@@ -174,32 +222,20 @@ T getStruct(const MachOObjectFile *O, co
   return Cmd;
 }
 
-static macho::SegmentLoadCommand
-getSegmentLoadCommand(const MachOObjectFile *O,
-                      const MachOObjectFile::LoadCommandInfo &L) {
-  return getStruct<macho::SegmentLoadCommand>(O, L.Ptr);
-}
-
-static macho::Segment64LoadCommand
-getSegment64LoadCommand(const MachOObjectFile *O,
-                        const MachOObjectFile::LoadCommandInfo &L) {
-  return getStruct<macho::Segment64LoadCommand>(O, L.Ptr);
-}
-
 static uint32_t
 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
                                  const MachOObjectFile::LoadCommandInfo &L) {
   if (O->is64Bit()) {
-    macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L);
+    macho::Segment64LoadCommand S = O->getSegment64LoadCommand(L);
     return S.NumSections;
   }
-  macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L);
+  macho::SegmentLoadCommand S = O->getSegmentLoadCommand(L);
   return S.NumSections;
 }
 
-static const SectionBase *
-getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
-               unsigned Sec) {
+static const char *
+getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
+              unsigned Sec) {
   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
 
   bool Is64 = O->is64Bit();
@@ -209,7 +245,7 @@ getSectionBase(const MachOObjectFile *O,
                                 sizeof(macho::Section);
 
   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
-  return reinterpret_cast<const SectionBase*>(SectionAddr);
+  return reinterpret_cast<const char*>(SectionAddr);
 }
 
 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
@@ -377,7 +413,7 @@ MachOObjectFile::MachOObjectFile(MemoryB
                                  bool IsLittleEndian, bool Is64bits,
                                  error_code &ec)
     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
-      SymtabLoadCmd(NULL) {
+      SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) {
   uint32_t LoadCommandCount = this->getHeader().NumLoadCommands;
   macho::LoadCommandType SegmentLoadType = is64Bit() ?
     macho::LCT_Segment64 : macho::LCT_Segment;
@@ -387,13 +423,14 @@ MachOObjectFile::MachOObjectFile(MemoryB
     if (Load.C.Type == macho::LCT_Symtab) {
       assert(!SymtabLoadCmd && "Multiple symbol tables");
       SymtabLoadCmd = Load.Ptr;
-    }
-
-    if (Load.C.Type == SegmentLoadType) {
+    } else if (Load.C.Type == macho::LCT_Dysymtab) {
+      assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
+      DysymtabLoadCmd = Load.Ptr;
+    } else if (Load.C.Type == SegmentLoadType) {
       uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
       for (unsigned J = 0; J < NumSections; ++J) {
-        const SectionBase *Sec = getSectionBase(this, Load, J);
-        Sections.push_back(reinterpret_cast<const char*>(Sec));
+        const char *Sec = getSectionPtr(this, Load, J);
+        Sections.push_back(Sec);
       }
     }
 
@@ -416,10 +453,9 @@ error_code MachOObjectFile::getSymbolNex
 
 error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
                                           StringRef &Res) const {
-  macho::SymtabLoadCommand S = getSymtabLoadCommand();
-  const char *StringTable = getPtr(this, S.StringTableOffset);
+  StringRef StringTable = getStringTableData();
   SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
-  const char *Start = &StringTable[Entry.StringIndex];
+  const char *Start = &StringTable.data()[Entry.StringIndex];
   Res = StringRef(Start);
   return object_error::success;
 }
@@ -1271,6 +1307,18 @@ StringRef MachOObjectFile::getLoadName()
   report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
 }
 
+relocation_iterator MachOObjectFile::getSectionRelBegin(unsigned Index) const {
+  DataRefImpl DRI;
+  DRI.d.a = Index;
+  return getSectionRelBegin(DRI);
+}
+
+relocation_iterator MachOObjectFile::getSectionRelEnd(unsigned Index) const {
+  DataRefImpl DRI;
+  DRI.d.a = Index;
+  return getSectionRelEnd(DRI);
+}
+
 StringRef
 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
@@ -1375,6 +1423,18 @@ macho::Section64 MachOObjectFile::getSec
   return getStruct<macho::Section64>(this, Sections[DRI.d.a]);
 }
 
+macho::Section MachOObjectFile::getSection(const LoadCommandInfo &L,
+                                           unsigned Index) const {
+  const char *Sec = getSectionPtr(this, L, Index);
+  return getStruct<macho::Section>(this, Sec);
+}
+
+macho::Section64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
+                                               unsigned Index) const {
+  const char *Sec = getSectionPtr(this, L, Index);
+  return getStruct<macho::Section64>(this, Sec);
+}
+
 macho::SymbolTableEntry
 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
   const char *P = reinterpret_cast<const char *>(DRI.p);
@@ -1392,6 +1452,21 @@ MachOObjectFile::getLinkeditDataLoadComm
   return getStruct<macho::LinkeditDataLoadCommand>(this, L.Ptr);
 }
 
+macho::SegmentLoadCommand
+MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
+  return getStruct<macho::SegmentLoadCommand>(this, L.Ptr);
+}
+
+macho::Segment64LoadCommand
+MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
+  return getStruct<macho::Segment64LoadCommand>(this, L.Ptr);
+}
+
+macho::LinkerOptionsLoadCommand
+MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
+  return getStruct<macho::LinkerOptionsLoadCommand>(this, L.Ptr);
+}
+
 macho::RelocationEntry
 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
   const char *P = reinterpret_cast<const char *>(Rel.p);
@@ -1402,11 +1477,39 @@ macho::Header MachOObjectFile::getHeader
   return getStruct<macho::Header>(this, getPtr(this, 0));
 }
 
-macho::SymtabLoadCommand
-MachOObjectFile::getSymtabLoadCommand() const {
+macho::Header64Ext MachOObjectFile::getHeader64Ext() const {
+  return
+    getStruct<macho::Header64Ext>(this, getPtr(this, sizeof(macho::Header)));
+}
+
+macho::IndirectSymbolTableEntry MachOObjectFile::getIndirectSymbolTableEntry(
+                                          const macho::DysymtabLoadCommand &DLC,
+                                          unsigned Index) const {
+  uint64_t Offset = DLC.IndirectSymbolTableOffset +
+    Index * sizeof(macho::IndirectSymbolTableEntry);
+  return getStruct<macho::IndirectSymbolTableEntry>(this, getPtr(this, Offset));
+}
+
+macho::DataInCodeTableEntry
+MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
+                                         unsigned Index) const {
+  uint64_t Offset = DataOffset + Index * sizeof(macho::DataInCodeTableEntry);
+  return getStruct<macho::DataInCodeTableEntry>(this, getPtr(this, Offset));
+}
+
+macho::SymtabLoadCommand MachOObjectFile::getSymtabLoadCommand() const {
   return getStruct<macho::SymtabLoadCommand>(this, SymtabLoadCmd);
 }
 
+macho::DysymtabLoadCommand MachOObjectFile::getDysymtabLoadCommand() const {
+  return getStruct<macho::DysymtabLoadCommand>(this, DysymtabLoadCmd);
+}
+
+StringRef MachOObjectFile::getStringTableData() const {
+  macho::SymtabLoadCommand S = getSymtabLoadCommand();
+  return getData().substr(S.StringTableOffset, S.StringTableSize);
+}
+
 bool MachOObjectFile::is64Bit() const {
   return getType() == getMachOType(false, true) ||
     getType() == getMachOType(true, true);

Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Fri Apr 26 15:07:33 2013
@@ -17,7 +17,7 @@
 #include "llvm/ExecutionEngine/ObjectBuffer.h"
 #include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/Object/MachOObject.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Memory.h"

Modified: llvm/trunk/tools/macho-dump/macho-dump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/macho-dump/macho-dump.cpp?rev=180624&r1=180623&r2=180624&view=diff
==============================================================================
--- llvm/trunk/tools/macho-dump/macho-dump.cpp (original)
+++ llvm/trunk/tools/macho-dump/macho-dump.cpp Fri Apr 26 15:07:33 2013
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Object/MachOObject.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -66,7 +67,8 @@ static void DumpSegmentCommandData(Strin
   outs() << "  ('flags', " << Flags << ")\n";
 }
 
-static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name,
+static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index,
+                           StringRef Name,
                            StringRef SegmentName, uint64_t Address,
                            uint64_t Size, uint32_t Offset,
                            uint32_t Align, uint32_t RelocationTableOffset,
@@ -92,26 +94,22 @@ static int DumpSectionData(MachOObject &
   outs() << "   ),\n";
 
   // Dump the relocation entries.
-  int Res = 0;
   outs() << "  ('_relocations', [\n";
-  for (unsigned i = 0; i != NumRelocationTableEntries; ++i) {
-    InMemoryStruct<macho::RelocationEntry> RE;
-    Obj.ReadRelocationEntry(RelocationTableOffset, i, RE);
-    if (!RE) {
-      Res = Error("unable to read relocation table entry '" + Twine(i) + "'");
-      break;
-    }
-    
-    outs() << "    # Relocation " << i << "\n";
-    outs() << "    (('word-0', " << format("0x%x", RE->Word0) << "),\n";
-    outs() << "     ('word-1', " << format("0x%x", RE->Word1) << ")),\n";
+  unsigned RelNum = 0;
+  error_code EC;
+  for (relocation_iterator I = Obj.getSectionRelBegin(Index),
+         E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) {
+    macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl());
+    outs() << "    # Relocation " << RelNum << "\n";
+    outs() << "    (('word-0', " << format("0x%x", RE.Word0) << "),\n";
+    outs() << "     ('word-1', " << format("0x%x", RE.Word1) << ")),\n";
   }
   outs() << "  ])\n";
 
   // Dump the section data, if requested.
   if (ShowSectionData) {
     outs() << "  ('_section_data', '";
-    StringRef Data = Obj.getData(Offset, Size);
+    StringRef Data = Obj.getData().substr(Offset, Size);
     for (unsigned i = 0; i != Data.size(); ++i) {
       if (i && (i % 4) == 0)
         outs() << ' ';
@@ -121,208 +119,162 @@ static int DumpSectionData(MachOObject &
     outs() << "')\n";
   }
 
-  return Res;
+  return 0;
 }
 
-static int DumpSegmentCommand(MachOObject &Obj,
-                               const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::SegmentLoadCommand> SLC;
-  Obj.ReadSegmentLoadCommand(LCI, SLC);
-  if (!SLC)
-    return Error("unable to read segment load command");
-
-  DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
-                         SLC->VMSize, SLC->FileOffset, SLC->FileSize,
-                         SLC->MaxVMProtection, SLC->InitialVMProtection,
-                         SLC->NumSections, SLC->Flags);
+static int DumpSegmentCommand(const MachOObjectFile &Obj,
+                              const MachOObjectFile::LoadCommandInfo &LCI) {
+  macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI);
+
+  DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress,
+                         SLC.VMSize, SLC.FileOffset, SLC.FileSize,
+                         SLC.MaxVMProtection, SLC.InitialVMProtection,
+                         SLC.NumSections, SLC.Flags);
 
   // Dump the sections.
-  int Res = 0;
   outs() << "  ('sections', [\n";
-  for (unsigned i = 0; i != SLC->NumSections; ++i) {
-    InMemoryStruct<macho::Section> Sect;
-    Obj.ReadSection(LCI, i, Sect);
-    if (!SLC) {
-      Res = Error("unable to read section '" + Twine(i) + "'");
-      break;
-    }
-
-    if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
-                               StringRef(Sect->SegmentName, 16), Sect->Address,
-                               Sect->Size, Sect->Offset, Sect->Align,
-                               Sect->RelocationTableOffset,
-                               Sect->NumRelocationTableEntries, Sect->Flags,
-                               Sect->Reserved1, Sect->Reserved2)))
-      break;
+  for (unsigned i = 0; i != SLC.NumSections; ++i) {
+    macho::Section Sect = Obj.getSection(LCI, i);
+    DumpSectionData(Obj, i, StringRef(Sect.Name, 16),
+                    StringRef(Sect.SegmentName, 16), Sect.Address,
+                    Sect.Size, Sect.Offset, Sect.Align,
+                    Sect.RelocationTableOffset,
+                    Sect.NumRelocationTableEntries, Sect.Flags,
+                    Sect.Reserved1, Sect.Reserved2);
   }
   outs() << "  ])\n";
 
-  return Res;
+  return 0;
 }
 
-static int DumpSegment64Command(MachOObject &Obj,
-                               const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::Segment64LoadCommand> SLC;
-  Obj.ReadSegment64LoadCommand(LCI, SLC);
-  if (!SLC)
-    return Error("unable to read segment load command");
-
-  DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
-                         SLC->VMSize, SLC->FileOffset, SLC->FileSize,
-                         SLC->MaxVMProtection, SLC->InitialVMProtection,
-                         SLC->NumSections, SLC->Flags);
+static int DumpSegment64Command(const MachOObjectFile &Obj,
+                                const MachOObjectFile::LoadCommandInfo &LCI) {
+  macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI);
+  DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress,
+                          SLC.VMSize, SLC.FileOffset, SLC.FileSize,
+                          SLC.MaxVMProtection, SLC.InitialVMProtection,
+                          SLC.NumSections, SLC.Flags);
 
   // Dump the sections.
-  int Res = 0;
   outs() << "  ('sections', [\n";
-  for (unsigned i = 0; i != SLC->NumSections; ++i) {
-    InMemoryStruct<macho::Section64> Sect;
-    Obj.ReadSection64(LCI, i, Sect);
-    if (!SLC) {
-      Res = Error("unable to read section '" + Twine(i) + "'");
-      break;
-    }
+  for (unsigned i = 0; i != SLC.NumSections; ++i) {
+    macho::Section64 Sect = Obj.getSection64(LCI, i);
 
-    if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
-                               StringRef(Sect->SegmentName, 16), Sect->Address,
-                               Sect->Size, Sect->Offset, Sect->Align,
-                               Sect->RelocationTableOffset,
-                               Sect->NumRelocationTableEntries, Sect->Flags,
-                               Sect->Reserved1, Sect->Reserved2,
-                               Sect->Reserved3)))
-      break;
+    DumpSectionData(Obj, i, StringRef(Sect.Name, 16),
+                    StringRef(Sect.SegmentName, 16), Sect.Address,
+                    Sect.Size, Sect.Offset, Sect.Align,
+                    Sect.RelocationTableOffset,
+                    Sect.NumRelocationTableEntries, Sect.Flags,
+                    Sect.Reserved1, Sect.Reserved2,
+                    Sect.Reserved3);
   }
   outs() << "  ])\n";
 
-  return Res;
+  return 0;
 }
 
-static void DumpSymbolTableEntryData(MachOObject &Obj,
+static void DumpSymbolTableEntryData(const MachOObjectFile &Obj,
                                      unsigned Index, uint32_t StringIndex,
                                      uint8_t Type, uint8_t SectionIndex,
-                                     uint16_t Flags, uint64_t Value) {
+                                     uint16_t Flags, uint64_t Value,
+                                     StringRef StringTable) {
+  const char *Name = &StringTable.data()[StringIndex];
   outs() << "    # Symbol " << Index << "\n";
   outs() << "   (('n_strx', " << StringIndex << ")\n";
   outs() << "    ('n_type', " << format("0x%x", Type) << ")\n";
   outs() << "    ('n_sect', " << uint32_t(SectionIndex) << ")\n";
   outs() << "    ('n_desc', " << Flags << ")\n";
   outs() << "    ('n_value', " << Value << ")\n";
-  outs() << "    ('_string', '" << Obj.getStringAtIndex(StringIndex) << "')\n";
+  outs() << "    ('_string', '" << Name << "')\n";
   outs() << "   ),\n";
 }
 
-static int DumpSymtabCommand(MachOObject &Obj,
-                             const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::SymtabLoadCommand> SLC;
-  Obj.ReadSymtabLoadCommand(LCI, SLC);
-  if (!SLC)
-    return Error("unable to read segment load command");
-
-  outs() << "  ('symoff', " << SLC->SymbolTableOffset << ")\n";
-  outs() << "  ('nsyms', " << SLC->NumSymbolTableEntries << ")\n";
-  outs() << "  ('stroff', " << SLC->StringTableOffset << ")\n";
-  outs() << "  ('strsize', " << SLC->StringTableSize << ")\n";
+static int DumpSymtabCommand(const MachOObjectFile &Obj) {
+  macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand();
 
-  // Cache the string table data.
-  Obj.RegisterStringTable(*SLC);
+  outs() << "  ('symoff', " << SLC.SymbolTableOffset << ")\n";
+  outs() << "  ('nsyms', " << SLC.NumSymbolTableEntries << ")\n";
+  outs() << "  ('stroff', " << SLC.StringTableOffset << ")\n";
+  outs() << "  ('strsize', " << SLC.StringTableSize << ")\n";
 
   // Dump the string data.
   outs() << "  ('_string_data', '";
-  outs().write_escaped(Obj.getStringTableData(),
+  StringRef StringTable = Obj.getStringTableData();
+  outs().write_escaped(StringTable,
                        /*UseHexEscapes=*/true) << "')\n";
 
   // Dump the symbol table.
-  int Res = 0;
   outs() << "  ('_symbols', [\n";
-  for (unsigned i = 0; i != SLC->NumSymbolTableEntries; ++i) {
+  error_code EC;
+  unsigned SymNum = 0;
+  for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
+       I.increment(EC), ++SymNum) {
+    DataRefImpl DRI = I->getRawDataRefImpl();
     if (Obj.is64Bit()) {
-      InMemoryStruct<macho::Symbol64TableEntry> STE;
-      Obj.ReadSymbol64TableEntry(SLC->SymbolTableOffset, i, STE);
-      if (!STE) {
-        Res = Error("unable to read symbol: '" + Twine(i) + "'");
-        break;
-      }
-
-      DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
-                               STE->SectionIndex, STE->Flags, STE->Value);
+      macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI);
+      DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type,
+                               STE.SectionIndex, STE.Flags, STE.Value,
+                               StringTable);
     } else {
-      InMemoryStruct<macho::SymbolTableEntry> STE;
-      Obj.ReadSymbolTableEntry(SLC->SymbolTableOffset, i, STE);
-      if (!SLC) {
-        Res = Error("unable to read symbol: '" + Twine(i) + "'");
-        break;
-      }
-
-      DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
-                               STE->SectionIndex, STE->Flags, STE->Value);
+      macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI);
+      DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type,
+                               STE.SectionIndex, STE.Flags, STE.Value,
+                               StringTable);
     }
   }
   outs() << "  ])\n";
 
-  return Res;
+  return 0;
 }
 
-static int DumpDysymtabCommand(MachOObject &Obj,
-                             const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::DysymtabLoadCommand> DLC;
-  Obj.ReadDysymtabLoadCommand(LCI, DLC);
-  if (!DLC)
-    return Error("unable to read segment load command");
-
-  outs() << "  ('ilocalsym', " << DLC->LocalSymbolsIndex << ")\n";
-  outs() << "  ('nlocalsym', " << DLC->NumLocalSymbols << ")\n";
-  outs() << "  ('iextdefsym', " << DLC->ExternalSymbolsIndex << ")\n";
-  outs() << "  ('nextdefsym', " << DLC->NumExternalSymbols << ")\n";
-  outs() << "  ('iundefsym', " << DLC->UndefinedSymbolsIndex << ")\n";
-  outs() << "  ('nundefsym', " << DLC->NumUndefinedSymbols << ")\n";
-  outs() << "  ('tocoff', " << DLC->TOCOffset << ")\n";
-  outs() << "  ('ntoc', " << DLC->NumTOCEntries << ")\n";
-  outs() << "  ('modtaboff', " << DLC->ModuleTableOffset << ")\n";
-  outs() << "  ('nmodtab', " << DLC->NumModuleTableEntries << ")\n";
-  outs() << "  ('extrefsymoff', " << DLC->ReferenceSymbolTableOffset << ")\n";
+static int DumpDysymtabCommand(const MachOObjectFile &Obj) {
+  macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand();
+
+  outs() << "  ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n";
+  outs() << "  ('nlocalsym', " << DLC.NumLocalSymbols << ")\n";
+  outs() << "  ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n";
+  outs() << "  ('nextdefsym', " << DLC.NumExternalSymbols << ")\n";
+  outs() << "  ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n";
+  outs() << "  ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n";
+  outs() << "  ('tocoff', " << DLC.TOCOffset << ")\n";
+  outs() << "  ('ntoc', " << DLC.NumTOCEntries << ")\n";
+  outs() << "  ('modtaboff', " << DLC.ModuleTableOffset << ")\n";
+  outs() << "  ('nmodtab', " << DLC.NumModuleTableEntries << ")\n";
+  outs() << "  ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n";
   outs() << "  ('nextrefsyms', "
-         << DLC->NumReferencedSymbolTableEntries << ")\n";
-  outs() << "  ('indirectsymoff', " << DLC->IndirectSymbolTableOffset << ")\n";
+         << DLC.NumReferencedSymbolTableEntries << ")\n";
+  outs() << "  ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n";
   outs() << "  ('nindirectsyms', "
-         << DLC->NumIndirectSymbolTableEntries << ")\n";
-  outs() << "  ('extreloff', " << DLC->ExternalRelocationTableOffset << ")\n";
-  outs() << "  ('nextrel', " << DLC->NumExternalRelocationTableEntries << ")\n";
-  outs() << "  ('locreloff', " << DLC->LocalRelocationTableOffset << ")\n";
-  outs() << "  ('nlocrel', " << DLC->NumLocalRelocationTableEntries << ")\n";
+         << DLC.NumIndirectSymbolTableEntries << ")\n";
+  outs() << "  ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n";
+  outs() << "  ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n";
+  outs() << "  ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n";
+  outs() << "  ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n";
 
   // Dump the indirect symbol table.
-  int Res = 0;
   outs() << "  ('_indirect_symbols', [\n";
-  for (unsigned i = 0; i != DLC->NumIndirectSymbolTableEntries; ++i) {
-    InMemoryStruct<macho::IndirectSymbolTableEntry> ISTE;
-    Obj.ReadIndirectSymbolTableEntry(*DLC, i, ISTE);
-    if (!ISTE) {
-      Res = Error("unable to read segment load command");
-      break;
-    }
-
+  for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) {
+    macho::IndirectSymbolTableEntry ISTE =
+      Obj.getIndirectSymbolTableEntry(DLC, i);
     outs() << "    # Indirect Symbol " << i << "\n";
     outs() << "    (('symbol_index', "
-           << format("0x%x", ISTE->Index) << "),),\n";
+           << format("0x%x", ISTE.Index) << "),),\n";
   }
   outs() << "  ])\n";
 
-  return Res;
+  return 0;
 }
 
-static int DumpLinkeditDataCommand(MachOObject &Obj,
-                                   const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
-  Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
-  if (!LLC)
-    return Error("unable to read segment load command");
-
-  outs() << "  ('dataoff', " << LLC->DataOffset << ")\n"
-         << "  ('datasize', " << LLC->DataSize << ")\n"
+static int
+DumpLinkeditDataCommand(const MachOObjectFile &Obj,
+                        const MachOObjectFile::LoadCommandInfo &LCI) {
+  macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI);
+  outs() << "  ('dataoff', " << LLC.DataOffset << ")\n"
+         << "  ('datasize', " << LLC.DataSize << ")\n"
          << "  ('_addresses', [\n";
 
   SmallVector<uint64_t, 8> Addresses;
-  Obj.ReadULEB128s(LLC->DataOffset, Addresses);
+  Obj.ReadULEB128s(LLC.DataOffset, Addresses);
   for (unsigned i = 0, e = Addresses.size(); i != e; ++i)
     outs() << "    # Address " << i << '\n'
            << "    ('address', " << format("0x%x", Addresses[i]) << "),\n";
@@ -332,28 +284,22 @@ static int DumpLinkeditDataCommand(MachO
   return 0;
 }
 
-static int DumpDataInCodeDataCommand(MachOObject &Obj,
-                                     const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
-  Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
-  if (!LLC)
-    return Error("unable to read data-in-code load command");
-
-  outs() << "  ('dataoff', " << LLC->DataOffset << ")\n"
-         << "  ('datasize', " << LLC->DataSize << ")\n"
+static int
+DumpDataInCodeDataCommand(const MachOObjectFile &Obj,
+                          const MachOObjectFile::LoadCommandInfo &LCI) {
+  macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI);
+  outs() << "  ('dataoff', " << LLC.DataOffset << ")\n"
+         << "  ('datasize', " << LLC.DataSize << ")\n"
          << "  ('_data_regions', [\n";
 
-
-  unsigned NumRegions = LLC->DataSize / 8;
+  unsigned NumRegions = LLC.DataSize / 8;
   for (unsigned i = 0; i < NumRegions; ++i) {
-    InMemoryStruct<macho::DataInCodeTableEntry> DICE;
-    Obj.ReadDataInCodeTableEntry(LLC->DataOffset, i, DICE);
-    if (!DICE)
-      return Error("unable to read DataInCodeTableEntry");
+    macho::DataInCodeTableEntry DICE =
+      Obj.getDataInCodeTableEntry(LLC.DataOffset, i);
     outs() << "    # DICE " << i << "\n"
-           << "    ('offset', " << DICE->Offset << ")\n"
-           << "    ('length', " << DICE->Length << ")\n"
-           << "    ('kind', " << DICE->Kind << ")\n";
+           << "    ('offset', " << DICE.Offset << ")\n"
+           << "    ('length', " << DICE.Length << ")\n"
+           << "    ('kind', " << DICE.Kind << ")\n";
   }
 
   outs() <<"  ])\n";
@@ -361,99 +307,111 @@ static int DumpDataInCodeDataCommand(Mac
   return 0;
 }
 
-static int DumpLinkerOptionsCommand(MachOObject &Obj,
-                                    const MachOObject::LoadCommandInfo &LCI) {
-  InMemoryStruct<macho::LinkerOptionsLoadCommand> LOLC;
-  Obj.ReadLinkerOptionsLoadCommand(LCI, LOLC);
-  if (!LOLC)
-    return Error("unable to read linker options load command");
-
-  outs() << "  ('count', " << LOLC->Count << ")\n"
-         << "  ('_strings', [\n";
-
-  uint64_t DataSize = LOLC->Size - sizeof(macho::LinkerOptionsLoadCommand);
-  StringRef Data = Obj.getData(
-    LCI.Offset + sizeof(macho::LinkerOptionsLoadCommand), DataSize);
-  for (unsigned i = 0; i != LOLC->Count; ++i) {
-    std::pair<StringRef,StringRef> Split = Data.split('\0');
-    outs() << "\t\"";
-    outs().write_escaped(Split.first);
-    outs() << "\",\n";
-    Data = Split.second;
-  }
-  outs() <<"  ])\n";
+static int
+DumpLinkerOptionsCommand(const MachOObjectFile &Obj,
+                         const MachOObjectFile::LoadCommandInfo &LCI) {
+  macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI);
+   outs() << "  ('count', " << LOLC.Count << ")\n"
+          << "  ('_strings', [\n";
+
+   uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand);
+   const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand);
+   StringRef Data(P, DataSize);
+   for (unsigned i = 0; i != LOLC.Count; ++i) {
+     std::pair<StringRef,StringRef> Split = Data.split('\0');
+     outs() << "\t\"";
+     outs().write_escaped(Split.first);
+     outs() << "\",\n";
+     Data = Split.second;
+   }
+   outs() <<"  ])\n";
 
   return 0;
 }
 
-
-static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
-  const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index);
-  int Res = 0;
-
-  outs() << "  # Load Command " << Index << "\n"
-         << " (('command', " << LCI.Command.Type << ")\n"
-         << "  ('size', " << LCI.Command.Size << ")\n";
-  switch (LCI.Command.Type) {
+static int DumpLoadCommand(const MachOObjectFile &Obj,
+                           MachOObjectFile::LoadCommandInfo &LCI) {
+  switch (LCI.C.Type) {
   case macho::LCT_Segment:
-    Res = DumpSegmentCommand(Obj, LCI);
-    break;
+    return DumpSegmentCommand(Obj, LCI);
   case macho::LCT_Segment64:
-    Res = DumpSegment64Command(Obj, LCI);
-    break;
+    return DumpSegment64Command(Obj, LCI);
   case macho::LCT_Symtab:
-    Res = DumpSymtabCommand(Obj, LCI);
-    break;
+    return DumpSymtabCommand(Obj);
   case macho::LCT_Dysymtab:
-    Res = DumpDysymtabCommand(Obj, LCI);
-    break;
+    return DumpDysymtabCommand(Obj);
   case macho::LCT_CodeSignature:
   case macho::LCT_SegmentSplitInfo:
   case macho::LCT_FunctionStarts:
-    Res = DumpLinkeditDataCommand(Obj, LCI);
-    break;
+    return DumpLinkeditDataCommand(Obj, LCI);
   case macho::LCT_DataInCode:
-    Res = DumpDataInCodeDataCommand(Obj, LCI);
-    break;
+    return DumpDataInCodeDataCommand(Obj, LCI);
   case macho::LCT_LinkerOptions:
-    Res = DumpLinkerOptionsCommand(Obj, LCI);
-    break;
+    return DumpLinkerOptionsCommand(Obj, LCI);
   default:
-    Warning("unknown load command: " + Twine(LCI.Command.Type));
-    break;
+    Warning("unknown load command: " + Twine(LCI.C.Type));
+    return 0;
   }
-  outs() << " ),\n";
+}
+
 
+static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index,
+                           MachOObjectFile::LoadCommandInfo &LCI) {
+  outs() << "  # Load Command " << Index << "\n"
+         << " (('command', " << LCI.C.Type << ")\n"
+         << "  ('size', " << LCI.C.Size << ")\n";
+  int Res = DumpLoadCommand(Obj, LCI);
+  outs() << " ),\n";
   return Res;
 }
 
+static void printHeader(const MachOObjectFile *Obj,
+                        const macho::Header &Header) {
+  outs() << "('cputype', " << Header.CPUType << ")\n";
+  outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n";
+  outs() << "('filetype', " << Header.FileType << ")\n";
+  outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n";
+  outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n";
+  outs() << "('flag', " << Header.Flags << ")\n";
+
+  // Print extended header if 64-bit.
+  if (Obj->is64Bit()) {
+    macho::Header64Ext Header64Ext = Obj->getHeader64Ext();
+    outs() << "('reserved', " << Header64Ext.Reserved << ")\n";
+  }
+}
+
 int main(int argc, char **argv) {
   ProgramName = argv[0];
   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
 
   cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n");
 
-  // Load the input file.
-  std::string ErrorStr;
-  OwningPtr<MemoryBuffer> InputBuffer;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer))
-    return Error("unable to read input: '" + ec.message() + "'");
-
-  // Construct the Mach-O wrapper object.
-  OwningPtr<MachOObject> InputObject(
-    MachOObject::LoadFromBuffer(InputBuffer.take(), &ErrorStr));
+  OwningPtr<Binary> Binary;
+  if (error_code EC = createBinary(InputFile, Binary))
+    return Error("unable to read input: '" + EC.message() + "'");
+
+  const MachOObjectFile *InputObject = dyn_cast<MachOObjectFile>(Binary.get());
   if (!InputObject)
-    return Error("unable to load object: '" + ErrorStr + "'");
+    return Error("Not a MachO object");
 
   // Print the header
-  InputObject->printHeader(outs());
+  macho::Header Header = InputObject->getHeader();
+  printHeader(InputObject, Header);
 
   // Print the load commands.
   int Res = 0;
+  MachOObjectFile::LoadCommandInfo Command =
+    InputObject->getFirstLoadCommandInfo();
   outs() << "('load_commands', [\n";
-  for (unsigned i = 0; i != InputObject->getHeader().NumLoadCommands; ++i)
-    if ((Res = DumpLoadCommand(*InputObject, i)))
+  for (unsigned i = 0; ; ++i) {
+    if (DumpLoadCommand(*InputObject, i, Command))
       break;
+
+    if (i == Header.NumLoadCommands - 1)
+      break;
+    Command = InputObject->getNextLoadCommandInfo(Command);
+  }
   outs() << "])\n";
 
   return Res;





More information about the llvm-commits mailing list