//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MachOObjectFile class, which binds the MachOObject
// class to the generic ObjectFile wrapper.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/MachO.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cctype>
#include <cstring>
#include <limits>

using namespace llvm;
using namespace object;

namespace llvm {
namespace object {

struct SymbolTableEntryBase {
  uint32_t StringIndex;
  uint8_t Type;
  uint8_t SectionIndex;
  uint16_t Flags;
};

struct SectionBase {
  char Name[16];
  char SegmentName[16];
};

template<typename T>
static void SwapValue(T &Value) {
  Value = sys::SwapByteOrder(Value);
}

template<typename T>
static void SwapStruct(T &Value);

template<>
void SwapStruct(macho::RelocationEntry &H) {
  SwapValue(H.Word0);
  SwapValue(H.Word1);
}

template<>
void SwapStruct(macho::LoadCommand &L) {
  SwapValue(L.Type);
  SwapValue(L.Size);
}

template<>
void SwapStruct(SymbolTableEntryBase &S) {
  SwapValue(S.StringIndex);
  SwapValue(S.Flags);
}

template<>
void SwapStruct(macho::Section &S) {
  SwapValue(S.Address);
  SwapValue(S.Size);
  SwapValue(S.Offset);
  SwapValue(S.Align);
  SwapValue(S.RelocationTableOffset);
  SwapValue(S.NumRelocationTableEntries);
  SwapValue(S.Flags);
  SwapValue(S.Reserved1);
  SwapValue(S.Reserved2);
}

template<>
void SwapStruct(macho::Section64 &S) {
  SwapValue(S.Address);
  SwapValue(S.Size);
  SwapValue(S.Offset);
  SwapValue(S.Align);
  SwapValue(S.RelocationTableOffset);
  SwapValue(S.NumRelocationTableEntries);
  SwapValue(S.Flags);
  SwapValue(S.Reserved1);
  SwapValue(S.Reserved2);
  SwapValue(S.Reserved3);
}

template<>
void SwapStruct(macho::SymbolTableEntry &S) {
  SwapValue(S.StringIndex);
  SwapValue(S.Flags);
  SwapValue(S.Value);
}

template<>
void SwapStruct(macho::Symbol64TableEntry &S) {
  SwapValue(S.StringIndex);
  SwapValue(S.Flags);
  SwapValue(S.Value);
}

template<>
void SwapStruct(macho::Header &H) {
  SwapValue(H.Magic);
  SwapValue(H.CPUType);
  SwapValue(H.CPUSubtype);
  SwapValue(H.FileType);
  SwapValue(H.NumLoadCommands);
  SwapValue(H.SizeOfLoadCommands);
  SwapValue(H.Flags);
}

template<>
void SwapStruct(macho::Header64Ext &E) {
  SwapValue(E.Reserved);
}

template<>
void SwapStruct(macho::SymtabLoadCommand &C) {
  SwapValue(C.Type);
  SwapValue(C.Size);
  SwapValue(C.SymbolTableOffset);
  SwapValue(C.NumSymbolTableEntries);
  SwapValue(C.StringTableOffset);
  SwapValue(C.StringTableSize);
}

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);
  SwapValue(C.DataOffset);
  SwapValue(C.DataSize);
}

template<>
void SwapStruct(macho::SegmentLoadCommand &C) {
  SwapValue(C.Type);
  SwapValue(C.Size);
  SwapValue(C.VMAddress);
  SwapValue(C.VMSize);
  SwapValue(C.FileOffset);
  SwapValue(C.FileSize);
  SwapValue(C.MaxVMProtection);
  SwapValue(C.InitialVMProtection);
  SwapValue(C.NumSections);
  SwapValue(C.Flags);
}

template<>
void SwapStruct(macho::Segment64LoadCommand &C) {
  SwapValue(C.Type);
  SwapValue(C.Size);
  SwapValue(C.VMAddress);
  SwapValue(C.VMSize);
  SwapValue(C.FileOffset);
  SwapValue(C.FileSize);
  SwapValue(C.MaxVMProtection);
  SwapValue(C.InitialVMProtection);
  SwapValue(C.NumSections);
  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;
  memcpy(&Cmd, P, sizeof(T));
  if (O->isLittleEndian() != sys::IsLittleEndianHost)
    SwapStruct(Cmd);
  return Cmd;
}

static uint32_t
getSegmentLoadCommandNumSections(const MachOObjectFile *O,
                                 const MachOObjectFile::LoadCommandInfo &L) {
  if (O->is64Bit()) {
    macho::Segment64LoadCommand S = O->getSegment64LoadCommand(L);
    return S.NumSections;
  }
  macho::SegmentLoadCommand S = O->getSegmentLoadCommand(L);
  return S.NumSections;
}

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();
  unsigned SegmentLoadSize = Is64 ? sizeof(macho::Segment64LoadCommand) :
                                    sizeof(macho::SegmentLoadCommand);
  unsigned SectionSize = Is64 ? sizeof(macho::Section64) :
                                sizeof(macho::Section);

  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
  return reinterpret_cast<const char*>(SectionAddr);
}

static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
  return O->getData().substr(Offset, 1).data();
}

static SymbolTableEntryBase
getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
  const char *P = reinterpret_cast<const char *>(DRI.p);
  return getStruct<SymbolTableEntryBase>(O, P);
}

static StringRef parseSegmentOrSectionName(const char *P) {
  if (P[15] == 0)
    // Null terminated.
    return P;
  // Not null terminated, so this is a 16 char string.
  return StringRef(P, 16);
}

// 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) {
  error_code ec;
  while (Val--) {
    it.increment(ec);
  }
  return ec;
}

template<class T>
static void advanceTo(T &it, size_t Val) {
  if (error_code ec = advance(it, Val))
    report_fatal_error(ec.message());
}

static unsigned getCPUType(const MachOObjectFile *O) {
  return O->getHeader().CPUType;
}

static void printRelocationTargetName(const MachOObjectFile *O,
                                      const macho::RelocationEntry &RE,
                                      raw_string_ostream &fmt) {
  bool IsScattered = O->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 = O->getPlainRelocationSymbolNum(RE);

    error_code ec;
    for (symbol_iterator SI = O->begin_symbols(), SE = O->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 = O->begin_sections(), SE = O->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 = O->getPlainRelocationExternal(RE);
  uint64_t Val = O->getPlainRelocationSymbolNum(RE);

  if (isExtern) {
    symbol_iterator SI = O->begin_symbols();
    advanceTo(SI, Val);
    SI->getName(S);
  } else {
    section_iterator SI = O->begin_sections();
    // Adjust for the fact that sections are 1-indexed.
    advanceTo(SI, Val - 1);
    SI->getName(S);
  }

  fmt << S;
}

static uint32_t getPlainRelocationAddress(const macho::RelocationEntry &RE) {
  return RE.Word0;
}

static unsigned
getScatteredRelocationAddress(const macho::RelocationEntry &RE) {
  return RE.Word0 & 0xffffff;
}

static bool getPlainRelocationPCRel(const MachOObjectFile *O,
                                    const macho::RelocationEntry &RE) {
  if (O->isLittleEndian())
    return (RE.Word1 >> 24) & 1;
  return (RE.Word1 >> 7) & 1;
}

static bool
getScatteredRelocationPCRel(const MachOObjectFile *O,
                            const macho::RelocationEntry &RE) {
  return (RE.Word0 >> 30) & 1;
}

static unsigned getPlainRelocationLength(const MachOObjectFile *O,
                                         const macho::RelocationEntry &RE) {
  if (O->isLittleEndian())
    return (RE.Word1 >> 25) & 3;
  return (RE.Word1 >> 5) & 3;
}

static unsigned
getScatteredRelocationLength(const macho::RelocationEntry &RE) {
  return (RE.Word0 >> 28) & 3;
}

static unsigned getPlainRelocationType(const MachOObjectFile *O,
                                       const macho::RelocationEntry &RE) {
  if (O->isLittleEndian())
    return RE.Word1 >> 28;
  return RE.Word1 & 0xf;
}

static unsigned getScatteredRelocationType(const macho::RelocationEntry &RE) {
  return (RE.Word0 >> 24) & 0xf;
}

static uint32_t getSectionFlags(const MachOObjectFile *O,
                                DataRefImpl Sec) {
  if (O->is64Bit()) {
    macho::Section64 Sect = O->getSection64(Sec);
    return Sect.Flags;
  }
  macho::Section Sect = O->getSection(Sec);
  return Sect.Flags;
}

MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
                                 bool IsLittleEndian, bool Is64bits,
                                 error_code &ec)
    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
      SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) {
  uint32_t LoadCommandCount = this->getHeader().NumLoadCommands;
  macho::LoadCommandType SegmentLoadType = is64Bit() ?
    macho::LCT_Segment64 : macho::LCT_Segment;

  MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
  for (unsigned I = 0; ; ++I) {
    if (Load.C.Type == macho::LCT_Symtab) {
      assert(!SymtabLoadCmd && "Multiple symbol tables");
      SymtabLoadCmd = Load.Ptr;
    } 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 char *Sec = getSectionPtr(this, Load, J);
        Sections.push_back(Sec);
      }
    }

    if (I == LoadCommandCount - 1)
      break;
    else
      Load = getNextLoadCommandInfo(Load);
  }
}

error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb,
                                          SymbolRef &Res) const {
  unsigned SymbolTableEntrySize = is64Bit() ?
    sizeof(macho::Symbol64TableEntry) :
    sizeof(macho::SymbolTableEntry);
  Symb.p += SymbolTableEntrySize;
  Res = SymbolRef(Symb, this);
  return object_error::success;
}

error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
                                          StringRef &Res) const {
  StringRef StringTable = getStringTableData();
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
  const char *Start = &StringTable.data()[Entry.StringIndex];
  Res = StringRef(Start);
  return object_error::success;
}

error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
                                             uint64_t &Res) const {
  if (is64Bit()) {
    macho::Symbol64TableEntry Entry = getSymbol64TableEntry(Symb);
    Res = Entry.Value;
  } else {
    macho::SymbolTableEntry Entry = getSymbolTableEntry(Symb);
    Res = Entry.Value;
  }
  return object_error::success;
}

error_code
MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
                                     uint64_t &Res) const {
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
  getSymbolAddress(Symb, Res);
  if (Entry.SectionIndex) {
    uint64_t Delta;
    DataRefImpl SecRel;
    SecRel.d.a = Entry.SectionIndex-1;
    if (is64Bit()) {
      macho::Section64 Sec = getSection64(SecRel);
      Delta = Sec.Offset - Sec.Address;
    } else {
      macho::Section Sec = getSection(SecRel);
      Delta = Sec.Offset - Sec.Address;
    }

    Res += Delta;
  }

  return object_error::success;
}

error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
                                               uint32_t &Result) const {
  uint32_t flags;
  this->getSymbolFlags(DRI, flags);
  if (flags & SymbolRef::SF_Common) {
    SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);
    Result = 1 << MachO::GET_COMM_ALIGN(Entry.Flags);
  } else {
    Result = 0;
  }
  return object_error::success;
}

error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
                                          uint64_t &Result) const {
  uint64_t BeginOffset;
  uint64_t EndOffset = 0;
  uint8_t SectionIndex;

  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);
  uint64_t Value;
  getSymbolAddress(DRI, Value);

  BeginOffset = Value;

  SectionIndex = Entry.SectionIndex;
  if (!SectionIndex) {
    uint32_t flags = SymbolRef::SF_None;
    this->getSymbolFlags(DRI, flags);
    if (flags & SymbolRef::SF_Common)
      Result = Value;
    else
      Result = UnknownAddressOrSize;
    return object_error::success;
  }
  // Unfortunately symbols are unsorted so we need to touch all
  // symbols from load command
  error_code ec;
  for (symbol_iterator I = begin_symbols(), E = end_symbols(); I != E;
       I.increment(ec)) {
    DataRefImpl DRI = I->getRawDataRefImpl();
    Entry = getSymbolTableEntryBase(this, DRI);
    getSymbolAddress(DRI, Value);
    if (Entry.SectionIndex == SectionIndex && Value > BeginOffset)
      if (!EndOffset || Value < EndOffset)
        EndOffset = Value;
  }
  if (!EndOffset) {
    uint64_t Size;
    DataRefImpl Sec;
    Sec.d.a = SectionIndex-1;
    getSectionSize(Sec, Size);
    getSectionAddress(Sec, EndOffset);
    EndOffset += Size;
  }
  Result = EndOffset - BeginOffset;
  return object_error::success;
}

error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
                                          SymbolRef::Type &Res) const {
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, 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 MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
                                                char &Res) const {
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, 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;
}

error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
                                           uint32_t &Result) const {
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, 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) {
      uint64_t Value;
      getSymbolAddress(DRI, Value);
      if (Value)
        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
MachOObjectFile::getSymbolSection(DataRefImpl Symb,
                                  section_iterator &Res) const {
  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
  uint8_t index = Entry.SectionIndex;

  if (index == 0) {
    Res = end_sections();
  } else {
    DataRefImpl DRI;
    DRI.d.a = index - 1;
    Res = section_iterator(SectionRef(DRI, this));
  }

  return object_error::success;
}

error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
                                           uint64_t &Val) const {
  report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
}

error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
                                           SectionRef &Res) const {
  Sec.d.a++;
  Res = SectionRef(Sec, this);
  return object_error::success;
}

error_code
MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
  ArrayRef<char> Raw = getSectionRawName(Sec);
  Result = parseSegmentOrSectionName(Raw.data());
  return object_error::success;
}

error_code
MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Res = Sect.Address;
  } else {
    macho::Section Sect = getSection(Sec);
    Res = Sect.Address;
  }
  return object_error::success;
}

error_code
MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Res = Sect.Size;
  } else {
    macho::Section Sect = getSection(Sec);
    Res = Sect.Size;
  }

  return object_error::success;
}

error_code
MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
  uint32_t Offset;
  uint64_t Size;

  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Offset = Sect.Offset;
    Size = Sect.Size;
  } else {
    macho::Section Sect =getSection(Sec);
    Offset = Sect.Offset;
    Size = Sect.Size;
  }

  Res = this->getData().substr(Offset, Size);
  return object_error::success;
}

error_code
MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
  uint32_t Align;
  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Align = Sect.Align;
  } else {
    macho::Section Sect = getSection(Sec);
    Align = Sect.Align;
  }

  Res = uint64_t(1) << Align;
  return object_error::success;
}

error_code
MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
  uint32_t Flags = getSectionFlags(this, Sec);
  Res = Flags & macho::SF_PureInstructions;
  return object_error::success;
}

error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const {
  // FIXME: Unimplemented.
  Result = false;
  return object_error::success;
}

error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const {
  // FIXME: Unimplemented.
  Result = false;
  return object_error::success;
}

error_code
MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
                                               bool &Result) const {
  // FIXME: Unimplemented.
  Result = true;
  return object_error::success;
}

error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
                                             bool &Result) const {
  // FIXME: Unimplemented.
  Result = false;
  return object_error::success;
}

error_code
MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
  uint32_t Flags = getSectionFlags(this, Sec);
  unsigned SectionType = Flags & MachO::SectionFlagMaskSectionType;
  Res = SectionType == MachO::SectionTypeZeroFill ||
    SectionType == MachO::SectionTypeZeroFillLarge;
  return object_error::success;
}

error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
                                                  bool &Result) const {
  // Consider using the code from isSectionText to look for __const sections.
  // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
  // to use section attributes to distinguish code from data.

  // FIXME: Unimplemented.
  Result = false;
  return object_error::success;
}

error_code
MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
                                       bool &Result) const {
  SymbolRef::Type ST;
  this->getSymbolType(Symb, ST);
  if (ST == SymbolRef::ST_Unknown) {
    Result = false;
    return object_error::success;
  }

  uint64_t SectBegin, SectEnd;
  getSectionAddress(Sec, SectBegin);
  getSectionSize(Sec, SectEnd);
  SectEnd += SectBegin;

  uint64_t SymAddr;
  getSymbolAddress(Symb, SymAddr);
  Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);

  return object_error::success;
}

relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
  uint32_t Offset;
  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Offset = Sect.RelocationTableOffset;
  } else {
    macho::Section Sect = getSection(Sec);
    Offset = Sect.RelocationTableOffset;
  }

  DataRefImpl Ret;
  Ret.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  return relocation_iterator(RelocationRef(Ret, this));
}

relocation_iterator
MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
  uint32_t Offset;
  uint32_t Num;
  if (is64Bit()) {
    macho::Section64 Sect = getSection64(Sec);
    Offset = Sect.RelocationTableOffset;
    Num = Sect.NumRelocationTableEntries;
  } else {
    macho::Section Sect = getSection(Sec);
    Offset = Sect.RelocationTableOffset;
    Num = Sect.NumRelocationTableEntries;
  }

  const macho::RelocationEntry *P =
    reinterpret_cast<const macho::RelocationEntry*>(getPtr(this, Offset));

  DataRefImpl Ret;
  Ret.p = reinterpret_cast<uintptr_t>(P + Num);
  return relocation_iterator(RelocationRef(Ret, this));
}

error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
                                              RelocationRef &Res) const {
  const macho::RelocationEntry *P =
    reinterpret_cast<const macho::RelocationEntry *>(Rel.p);
  Rel.p = reinterpret_cast<uintptr_t>(P + 1);
  Res = RelocationRef(Rel, this);
  return object_error::success;
}

error_code
MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
  report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
}

error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
                                                uint64_t &Res) const {
  macho::RelocationEntry RE = getRelocation(Rel);
  Res = getAnyRelocationAddress(RE);
  return object_error::success;
}

error_code
MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const {
  macho::RelocationEntry RE = getRelocation(Rel);
  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
  bool isExtern = getPlainRelocationExternal(RE);
  if (!isExtern) {
    Res = *end_symbols();
    return object_error::success;
  }

  macho::SymtabLoadCommand S = getSymtabLoadCommand();
  unsigned SymbolTableEntrySize = is64Bit() ?
    sizeof(macho::Symbol64TableEntry) :
    sizeof(macho::SymbolTableEntry);
  uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize;
  DataRefImpl Sym;
  Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  Res = SymbolRef(Sym, this);
  return object_error::success;
}

error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
                                              uint64_t &Res) const {
  macho::RelocationEntry RE = getRelocation(Rel);
  Res = getAnyRelocationType(RE);
  return object_error::success;
}

error_code
MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
                                       SmallVectorImpl<char> &Result) const {
  StringRef res;
  uint64_t RType;
  getRelocationType(Rel, RType);

  unsigned Arch = this->getArch();

  switch (Arch) {
    case Triple::x86: {
      static const char *const Table[] =  {
        "GENERIC_RELOC_VANILLA",
        "GENERIC_RELOC_PAIR",
        "GENERIC_RELOC_SECTDIFF",
        "GENERIC_RELOC_PB_LA_PTR",
        "GENERIC_RELOC_LOCAL_SECTDIFF",
        "GENERIC_RELOC_TLV" };

      if (RType > 6)
        res = "Unknown";
      else
        res = Table[RType];
      break;
    }
    case Triple::x86_64: {
      static const char *const Table[] =  {
        "X86_64_RELOC_UNSIGNED",
        "X86_64_RELOC_SIGNED",
        "X86_64_RELOC_BRANCH",
        "X86_64_RELOC_GOT_LOAD",
        "X86_64_RELOC_GOT",
        "X86_64_RELOC_SUBTRACTOR",
        "X86_64_RELOC_SIGNED_1",
        "X86_64_RELOC_SIGNED_2",
        "X86_64_RELOC_SIGNED_4",
        "X86_64_RELOC_TLV" };

      if (RType > 9)
        res = "Unknown";
      else
        res = Table[RType];
      break;
    }
    case Triple::arm: {
      static const char *const Table[] =  {
        "ARM_RELOC_VANILLA",
        "ARM_RELOC_PAIR",
        "ARM_RELOC_SECTDIFF",
        "ARM_RELOC_LOCAL_SECTDIFF",
        "ARM_RELOC_PB_LA_PTR",
        "ARM_RELOC_BR24",
        "ARM_THUMB_RELOC_BR22",
        "ARM_THUMB_32BIT_BRANCH",
        "ARM_RELOC_HALF",
        "ARM_RELOC_HALF_SECTDIFF" };

      if (RType > 9)
        res = "Unknown";
      else
        res = Table[RType];
      break;
    }
    case Triple::ppc: {
      static const char *const Table[] =  {
        "PPC_RELOC_VANILLA",
        "PPC_RELOC_PAIR",
        "PPC_RELOC_BR14",
        "PPC_RELOC_BR24",
        "PPC_RELOC_HI16",
        "PPC_RELOC_LO16",
        "PPC_RELOC_HA16",
        "PPC_RELOC_LO14",
        "PPC_RELOC_SECTDIFF",
        "PPC_RELOC_PB_LA_PTR",
        "PPC_RELOC_HI16_SECTDIFF",
        "PPC_RELOC_LO16_SECTDIFF",
        "PPC_RELOC_HA16_SECTDIFF",
        "PPC_RELOC_JBSR",
        "PPC_RELOC_LO14_SECTDIFF",
        "PPC_RELOC_LOCAL_SECTDIFF" };

      res = Table[RType];
      break;
    }
    case Triple::UnknownArch:
      res = "Unknown";
      break;
  }
  Result.append(res.begin(), res.end());
  return object_error::success;
}

error_code
MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
                                          SmallVectorImpl<char> &Result) const {
  macho::RelocationEntry RE = getRelocation(Rel);

  unsigned Arch = this->getArch();

  std::string fmtbuf;
  raw_string_ostream fmt(fmtbuf);
  unsigned Type = this->getAnyRelocationType(RE);
  bool IsPCRel = this->getAnyRelocationPCRel(RE);

  // Determine any addends that should be displayed with the relocation.
  // These require decoding the relocation type, which is triple-specific.

  // X86_64 has entirely custom relocation types.
  if (Arch == Triple::x86_64) {
    bool isPCRel = getAnyRelocationPCRel(RE);

    switch (Type) {
      case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD
      case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT
        printRelocationTargetName(this, RE, fmt);
        fmt << "@GOT";
        if (isPCRel) fmt << "PCREL";
        break;
      }
      case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
        DataRefImpl RelNext = Rel;
        RelNext.d.a++;
        macho::RelocationEntry RENext = getRelocation(RelNext);

        // X86_64_SUBTRACTOR must be followed by a relocation of type
        // X86_64_RELOC_UNSIGNED.
        // NOTE: Scattered relocations don't exist on x86_64.
        unsigned RType = getAnyRelocationType(RENext);
        if (RType != 0)
          report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
                             "X86_64_RELOC_SUBTRACTOR.");

        // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
        // X86_64_SUBTRACTOR contains to the subtrahend.
        printRelocationTargetName(this, RENext, fmt);
        fmt << "-";
        printRelocationTargetName(this, RE, fmt);
        break;
      }
      case macho::RIT_X86_64_TLV:
        printRelocationTargetName(this, RE, fmt);
        fmt << "@TLV";
        if (isPCRel) fmt << "P";
        break;
      case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
        printRelocationTargetName(this, RE, fmt);
        fmt << "-1";
        break;
      case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
        printRelocationTargetName(this, RE, fmt);
        fmt << "-2";
        break;
      case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
        printRelocationTargetName(this, RE, fmt);
        fmt << "-4";
        break;
      default:
        printRelocationTargetName(this, RE, fmt);
        break;
    }
  // X86 and ARM share some relocation types in common.
  } else if (Arch == Triple::x86 || Arch == Triple::arm) {
    // Generic relocation types...
    switch (Type) {
      case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
        return object_error::success;
      case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
        DataRefImpl RelNext = Rel;
        RelNext.d.a++;
        macho::RelocationEntry RENext = getRelocation(RelNext);

        // X86 sect diff's must be followed by a relocation of type
        // GENERIC_RELOC_PAIR.
        unsigned RType = getAnyRelocationType(RENext);

        if (RType != 1)
          report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                             "GENERIC_RELOC_SECTDIFF.");

        printRelocationTargetName(this, RE, fmt);
        fmt << "-";
        printRelocationTargetName(this, RENext, fmt);
        break;
      }
    }

    if (Arch == Triple::x86) {
      // All X86 relocations that need special printing were already
      // handled in the generic code.
      switch (Type) {
        case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
          DataRefImpl RelNext = Rel;
          RelNext.d.a++;
          macho::RelocationEntry RENext = getRelocation(RelNext);

          // X86 sect diff's must be followed by a relocation of type
          // GENERIC_RELOC_PAIR.
          unsigned RType = getAnyRelocationType(RENext);
          if (RType != 1)
            report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                               "GENERIC_RELOC_LOCAL_SECTDIFF.");

          printRelocationTargetName(this, RE, fmt);
          fmt << "-";
          printRelocationTargetName(this, RENext, fmt);
          break;
        }
        case macho::RIT_Generic_TLV: {
          printRelocationTargetName(this, RE, fmt);
          fmt << "@TLV";
          if (IsPCRel) fmt << "P";
          break;
        }
        default:
          printRelocationTargetName(this, RE, fmt);
      }
    } else { // ARM-specific relocations
      switch (Type) {
        case macho::RIT_ARM_Half:             // ARM_RELOC_HALF
        case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
          // Half relocations steal a bit from the length field to encode
          // whether this is an upper16 or a lower16 relocation.
          bool isUpper = getAnyRelocationLength(RE) >> 1;

          if (isUpper)
            fmt << ":upper16:(";
          else
            fmt << ":lower16:(";
          printRelocationTargetName(this, RE, fmt);

          DataRefImpl RelNext = Rel;
          RelNext.d.a++;
          macho::RelocationEntry RENext = getRelocation(RelNext);

          // ARM half relocs must be followed by a relocation of type
          // ARM_RELOC_PAIR.
          unsigned RType = getAnyRelocationType(RENext);
          if (RType != 1)
            report_fatal_error("Expected ARM_RELOC_PAIR after "
                               "GENERIC_RELOC_HALF");

          // NOTE: The half of the target virtual address is stashed in the
          // address field of the secondary relocation, but we can't reverse
          // engineer the constant offset from it without decoding the movw/movt
          // instruction to find the other half in its immediate field.

          // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
          // symbol/section pointer of the follow-on relocation.
          if (Type == macho::RIT_ARM_HalfDifference) {
            fmt << "-";
            printRelocationTargetName(this, RENext, fmt);
          }

          fmt << ")";
          break;
        }
        default: {
          printRelocationTargetName(this, RE, fmt);
        }
      }
    }
  } else
    printRelocationTargetName(this, RE, fmt);

  fmt.flush();
  Result.append(fmtbuf.begin(), fmtbuf.end());
  return object_error::success;
}

error_code
MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
  unsigned Arch = getArch();
  uint64_t Type;
  getRelocationType(Rel, Type);

  Result = false;

  // On arches that use the generic relocations, GENERIC_RELOC_PAIR
  // is always hidden.
  if (Arch == Triple::x86 || Arch == Triple::arm) {
    if (Type == macho::RIT_Pair) Result = true;
  } else if (Arch == Triple::x86_64) {
    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
    // an X864_64_RELOC_SUBTRACTOR.
    if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
      DataRefImpl RelPrev = Rel;
      RelPrev.d.a--;
      uint64_t PrevType;
      getRelocationType(RelPrev, PrevType);
      if (PrevType == macho::RIT_X86_64_Subtractor)
        Result = true;
    }
  }

  return object_error::success;
}

error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
                                           LibraryRef &Res) const {
  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}

error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
                                           StringRef &Res) const {
  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}

symbol_iterator MachOObjectFile::begin_symbols() const {
  DataRefImpl DRI;
  if (!SymtabLoadCmd)
    return symbol_iterator(SymbolRef(DRI, this));

  macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();
  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.SymbolTableOffset));
  return symbol_iterator(SymbolRef(DRI, this));
}

symbol_iterator MachOObjectFile::end_symbols() const {
  DataRefImpl DRI;
  if (!SymtabLoadCmd)
    return symbol_iterator(SymbolRef(DRI, this));

  macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();
  unsigned SymbolTableEntrySize = is64Bit() ?
    sizeof(macho::Symbol64TableEntry) :
    sizeof(macho::SymbolTableEntry);
  unsigned Offset = Symtab.SymbolTableOffset +
    Symtab.NumSymbolTableEntries * SymbolTableEntrySize;
  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
  return symbol_iterator(SymbolRef(DRI, this));
}

symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
  // TODO: implement
  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
}

symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
  // TODO: implement
  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
}

section_iterator MachOObjectFile::begin_sections() const {
  DataRefImpl DRI;
  return section_iterator(SectionRef(DRI, this));
}

section_iterator MachOObjectFile::end_sections() const {
  DataRefImpl DRI;
  DRI.d.a = Sections.size();
  return section_iterator(SectionRef(DRI, this));
}

library_iterator MachOObjectFile::begin_libraries_needed() const {
  // TODO: implement
  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}

library_iterator MachOObjectFile::end_libraries_needed() const {
  // TODO: implement
  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}

uint8_t MachOObjectFile::getBytesInAddress() const {
  return is64Bit() ? 8 : 4;
}

StringRef MachOObjectFile::getFileFormatName() const {
  unsigned CPUType = getCPUType(this);
  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";
  }
}

unsigned MachOObjectFile::getArch() const {
  switch (getCPUType(this)) {
  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;
  }
}

StringRef MachOObjectFile::getLoadName() const {
  // TODO: Implement
  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);
  return parseSegmentOrSectionName(Raw.data());
}

ArrayRef<char>
MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
  const SectionBase *Base =
    reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);
  return ArrayRef<char>(Base->Name);
}

ArrayRef<char>
MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
  const SectionBase *Base =
    reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);
  return ArrayRef<char>(Base->SegmentName);
}

bool
MachOObjectFile::isRelocationScattered(const macho::RelocationEntry &RE)
  const {
  if (getCPUType(this) == llvm::MachO::CPUTypeX86_64)
    return false;
  return getPlainRelocationAddress(RE) & macho::RF_Scattered;
}

unsigned MachOObjectFile::getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const {
  if (isLittleEndian())
    return RE.Word1 & 0xffffff;
  return RE.Word1 >> 8;
}

bool MachOObjectFile::getPlainRelocationExternal(const macho::RelocationEntry &RE) const {
  if (isLittleEndian())
    return (RE.Word1 >> 27) & 1;
  return (RE.Word1 >> 4) & 1;
}

bool
MachOObjectFile::getScatteredRelocationScattered(const macho::RelocationEntry &RE) const {
  return RE.Word0 >> 31;
}

uint32_t
MachOObjectFile::getScatteredRelocationValue(const macho::RelocationEntry &RE) const {
  return RE.Word1;
}

unsigned
MachOObjectFile::getAnyRelocationAddress(const macho::RelocationEntry &RE) const {
  if (isRelocationScattered(RE))
    return getScatteredRelocationAddress(RE);
  return getPlainRelocationAddress(RE);
}

unsigned
MachOObjectFile::getAnyRelocationPCRel(const macho::RelocationEntry &RE) const {
  if (isRelocationScattered(RE))
    return getScatteredRelocationPCRel(this, RE);
  return getPlainRelocationPCRel(this, RE);
}

unsigned
MachOObjectFile::getAnyRelocationLength(const macho::RelocationEntry &RE) const {
  if (isRelocationScattered(RE))
    return getScatteredRelocationLength(RE);
  return getPlainRelocationLength(this, RE);
}

unsigned
MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const {
  if (isRelocationScattered(RE))
    return getScatteredRelocationType(RE);
  return getPlainRelocationType(this, RE);
}

SectionRef
MachOObjectFile::getRelocationSection(const macho::RelocationEntry &RE) const {
  if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
    return *end_sections();
  unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
  DataRefImpl DRI;
  DRI.d.a = SecNum;
  return SectionRef(DRI, this);
}

MachOObjectFile::LoadCommandInfo
MachOObjectFile::getFirstLoadCommandInfo() const {
  MachOObjectFile::LoadCommandInfo Load;

  unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size;
  Load.Ptr = getPtr(this, HeaderSize);
  Load.C = getStruct<macho::LoadCommand>(this, Load.Ptr);
  return Load;
}

MachOObjectFile::LoadCommandInfo
MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
  MachOObjectFile::LoadCommandInfo Next;
  Next.Ptr = L.Ptr + L.C.Size;
  Next.C = getStruct<macho::LoadCommand>(this, Next.Ptr);
  return Next;
}

macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const {
  return getStruct<macho::Section>(this, Sections[DRI.d.a]);
}

macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
  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);
  return getStruct<macho::SymbolTableEntry>(this, P);
}

macho::Symbol64TableEntry
MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
  const char *P = reinterpret_cast<const char *>(DRI.p);
  return getStruct<macho::Symbol64TableEntry>(this, P);
}

macho::LinkeditDataLoadCommand
MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const {
  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);
  return getStruct<macho::RelocationEntry>(this, P);
}

macho::Header MachOObjectFile::getHeader() const {
  return getStruct<macho::Header>(this, getPtr(this, 0));
}

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);
}

void MachOObjectFile::ReadULEB128s(uint64_t Index,
                                   SmallVectorImpl<uint64_t> &Out) const {
  DataExtractor extractor(ObjectFile::getData(), true, 0);

  uint32_t offset = Index;
  uint64_t data = 0;
  while (uint64_t delta = extractor.getULEB128(&offset)) {
    data += delta;
    Out.push_back(data);
  }
}

ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
  StringRef Magic = Buffer->getBuffer().slice(0, 4);
  error_code ec;
  ObjectFile *Ret;
  if (Magic == "\xFE\xED\xFA\xCE")
    Ret = new MachOObjectFile(Buffer, false, false, ec);
  else if (Magic == "\xCE\xFA\xED\xFE")
    Ret = new MachOObjectFile(Buffer, true, false, ec);
  else if (Magic == "\xFE\xED\xFA\xCF")
    Ret = new MachOObjectFile(Buffer, false, true, ec);
  else if (Magic == "\xCF\xFA\xED\xFE")
    Ret = new MachOObjectFile(Buffer, true, true, ec);
  else
    return NULL;

  if (ec)
    return NULL;
  return Ret;
}

} // end namespace object
} // end namespace llvm
