<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi Rafael,<div><br></div><div>Just wanted to say “thanks” again for doing this. I like this implementation much better. Patch itself looks great.</div><div><br></div><div>Regards,</div><div>  Jim</div><div><br><div><div>On Apr 18, 2013, at 11:08 AM, Rafael Espindola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Author: rafael<br>Date: Thu Apr 18 13:08:55 2013<br>New Revision: 179778<br><br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project?rev=179778&view=rev">http://llvm.org/viewvc/llvm-project?rev=179778&view=rev</a><br>Log:<br>At Jim Grosbach's request detemplate Object/MachO.h.<br><br>We are still able to handle mixed endian objects by swapping one struct at a<br>time.<br><br>Added:<br>   llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm<br>Modified:<br>   llvm/trunk/include/llvm/Object/Binary.h<br>   llvm/trunk/include/llvm/Object/MachO.h<br>   llvm/trunk/lib/Object/MachOObjectFile.cpp<br>   llvm/trunk/test/tools/llvm-readobj/relocations.test<br>   llvm/trunk/test/tools/llvm-readobj/sections-ext.test<br>   llvm/trunk/test/tools/llvm-readobj/sections.test<br>   llvm/trunk/tools/llvm-objdump/MachODump.cpp<br>   llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp<br>   llvm/trunk/tools/llvm-readobj/MachODumper.cpp<br>   llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp<br><br>Modified: llvm/trunk/include/llvm/Object/Binary.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Binary.h?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Binary.h?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/include/llvm/Object/Binary.h (original)<br>+++ llvm/trunk/include/llvm/Object/Binary.h Thu Apr 18 13:08:55 2013<br>@@ -100,7 +100,8 @@ public:<br>  }<br><br>  bool isLittleEndian() const {<br>-    return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B);<br>+    return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||<br>+             TypeID == ID_MachO32B || TypeID == ID_MachO64B);<br>  }<br>};<br><br><br>Modified: llvm/trunk/include/llvm/Object/MachO.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/include/llvm/Object/MachO.h (original)<br>+++ llvm/trunk/include/llvm/Object/MachO.h Thu Apr 18 13:08:55 2013<br>@@ -7,8 +7,8 @@<br>//<br>//===----------------------------------------------------------------------===//<br>//<br>-// This file declares the MachOObjectFile class, which binds the MachOObject<br>-// class to the generic ObjectFile wrapper.<br>+// This file declares the MachOObjectFile class, which implement the ObjectFile<br>+// interface for MachO files.<br>//<br>//===----------------------------------------------------------------------===//<br><br>@@ -17,1607 +17,140 @@<br><br>#include "llvm/ADT/ArrayRef.h"<br>#include "llvm/ADT/SmallVector.h"<br>-#include "llvm/ADT/Triple.h"<br>#include "llvm/Object/MachOFormat.h"<br>#include "llvm/Object/ObjectFile.h"<br>-#include "llvm/Support/Casting.h"<br>-#include "llvm/Support/Endian.h"<br>-#include "llvm/Support/Format.h"<br>#include "llvm/Support/MachO.h"<br>#include "llvm/Support/raw_ostream.h"<br><br>namespace llvm {<br>namespace object {<br><br>-using support::endianness;<br>-<br>-template<endianness E, bool B><br>-struct MachOType {<br>-  static const endianness TargetEndianness = E;<br>-  static const bool Is64Bits = B;<br>-};<br>-<br>-template<endianness TargetEndianness><br>-struct MachOInt24Impl;<br>-<br>-template<><br>-struct MachOInt24Impl<support::little> {<br>-  uint8_t bytes[3];<br>-  operator uint32_t() const {<br>-    return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];<br>-  }<br>-};<br>-<br>-template<><br>-struct MachOInt24Impl<support::big> {<br>-  uint8_t bytes[3];<br>-  operator uint32_t() const {<br>-    return (bytes[0] << 24) | (bytes[1] << 16) | bytes[2];<br>-  }<br>-};<br>-<br>-template<endianness TargetEndianness><br>-struct MachODataTypeTypedefHelperCommon {<br>-  typedef support::detail::packed_endian_specific_integral<br>-    <uint16_t, TargetEndianness, support::unaligned> MachOInt16;<br>-  typedef support::detail::packed_endian_specific_integral<br>-    <uint32_t, TargetEndianness, support::unaligned> MachOInt32;<br>-  typedef support::detail::packed_endian_specific_integral<br>-    <uint64_t, TargetEndianness, support::unaligned> MachOInt64;<br>-  typedef MachOInt24Impl<TargetEndianness> MachOInt24;<br>-};<br>-<br>-#define LLVM_MACHOB_IMPORT_TYPES_TYPENAME(E)                                 \<br>-typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \<br>-typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \<br>-typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; \<br>-typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt24 MachOInt24;<br>-<br>-#define LLVM_MACHOB_IMPORT_TYPES(E)                                          \<br>-typedef MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \<br>-typedef MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \<br>-typedef MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; \<br>-typedef MachODataTypeTypedefHelperCommon<E>::MachOInt24 MachOInt24;<br>-<br>-template<class MachOT><br>-struct MachODataTypeTypedefHelper;<br>-<br>-template<endianness TargetEndianness><br>-struct MachODataTypeTypedefHelper<MachOType<TargetEndianness, false> > {<br>-  typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base;<br>-  typedef typename Base::MachOInt32 MachOIntPtr;<br>-};<br>-<br>-template<endianness TargetEndianness><br>-struct MachODataTypeTypedefHelper<MachOType<TargetEndianness, true> > {<br>-  typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base;<br>-  typedef typename Base::MachOInt64 MachOIntPtr;<br>-};<br>-<br>-#define LLVM_MACHO_IMPORT_TYPES(MachOT, E, B)                        \<br>-LLVM_MACHOB_IMPORT_TYPES_TYPENAME(E)                                 \<br>-typedef typename                                                     \<br>-  MachODataTypeTypedefHelper <MachOT<E, B> >::MachOIntPtr MachOIntPtr;<br>-<br>-namespace MachOFormat {<br>-  struct SectionBase {<br>-    char Name[16];<br>-    char SegmentName[16];<br>-  };<br>-<br>-  template<class MachOT><br>-  struct Section;<br>-<br>-  template<endianness TargetEndianness><br>-  struct Section<MachOType<TargetEndianness, false> > {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    char Name[16];<br>-    char SegmentName[16];<br>-    MachOInt32 Address;<br>-    MachOInt32 Size;<br>-    MachOInt32 Offset;<br>-    MachOInt32 Align;<br>-    MachOInt32 RelocationTableOffset;<br>-    MachOInt32 NumRelocationTableEntries;<br>-    MachOInt32 Flags;<br>-    MachOInt32 Reserved1;<br>-    MachOInt32 Reserved2;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct Section<MachOType<TargetEndianness, true> > {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    char Name[16];<br>-    char SegmentName[16];<br>-    MachOInt64 Address;<br>-    MachOInt64 Size;<br>-    MachOInt32 Offset;<br>-    MachOInt32 Align;<br>-    MachOInt32 RelocationTableOffset;<br>-    MachOInt32 NumRelocationTableEntries;<br>-    MachOInt32 Flags;<br>-    MachOInt32 Reserved1;<br>-    MachOInt32 Reserved2;<br>-    MachOInt32 Reserved3;<br>-  };<br>-<br>-  struct MachOInt24 {<br>-    uint8_t bytes[3];<br>-    operator uint32_t() const {<br>-      return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];<br>-    }<br>-  };<br>-<br>-  template<bool HostIsLittleEndian, endianness TargetEndianness><br>-  struct RelocationEntry;<br>-<br>-  template<><br>-  struct RelocationEntry<true, support::little> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::little)<br>-    MachOInt32 Address;<br>-    MachOInt24 SymbolNum;<br>-    unsigned PCRel : 1;<br>-    unsigned Length : 2;<br>-    unsigned External : 1;<br>-    unsigned Type : 4;<br>-  };<br>-<br>-  template<><br>-  struct RelocationEntry<false, support::little> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::little)<br>-    MachOInt32 Address;<br>-    MachOInt24 SymbolNum;<br>-    unsigned Type : 4;<br>-    unsigned External : 1;<br>-    unsigned Length : 2;<br>-    unsigned PCRel : 1;<br>-  };<br>-<br>-  template<><br>-  struct RelocationEntry<true, support::big> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::big)<br>-    MachOInt32 Address;<br>-    MachOInt24 SymbolNum;<br>-    unsigned Type : 4;<br>-    unsigned External : 1;<br>-    unsigned Length : 2;<br>-    unsigned PCRel : 1;<br>-  };<br>-<br>-  template<><br>-  struct RelocationEntry<false, support::big> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::big)<br>-    MachOInt32 Address;<br>-    MachOInt24 SymbolNum;<br>-    unsigned PCRel : 1;<br>-    unsigned Length : 2;<br>-    unsigned External : 1;<br>-    unsigned Type : 4;<br>-  };<br>-<br>-  template<bool HostIsLittleEndian, endianness TargetEndianness><br>-  struct ScatteredRelocationEntry;<br>-<br>-  template<><br>-  struct ScatteredRelocationEntry<true, support::little> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::little)<br>-    MachOInt24 Address;<br>-    unsigned Type : 4;<br>-    unsigned Length : 2;<br>-    unsigned PCRel : 1;<br>-    unsigned Scattered : 1;<br>-    MachOInt32 Value;<br>-  };<br>-<br>-  template<><br>-  struct ScatteredRelocationEntry<false, support::little> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::little)<br>-    MachOInt24 Address;<br>-    unsigned Scattered : 1;<br>-    unsigned PCRel : 1;<br>-    unsigned Length : 2;<br>-    unsigned Type : 4;<br>-    MachOInt32 Value;<br>-  };<br>-<br>-  template<><br>-  struct ScatteredRelocationEntry<true, support::big> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::big)<br>-    unsigned Type : 4;<br>-    unsigned Length : 2;<br>-    unsigned PCRel : 1;<br>-    unsigned Scattered : 1;<br>-    MachOInt24 Address;<br>-    MachOInt32 Value;<br>-  };<br>-<br>-  template<><br>-  struct ScatteredRelocationEntry<false, support::big> {<br>-    LLVM_MACHOB_IMPORT_TYPES(support::big)<br>-    unsigned Scattered : 1;<br>-    unsigned PCRel : 1;<br>-    unsigned Length : 2;<br>-    unsigned Type : 4;<br>-    MachOInt24 Address;<br>-    MachOInt32 Value;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct SymbolTableEntryBase {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    MachOInt32 StringIndex;<br>-    uint8_t Type;<br>-    uint8_t SectionIndex;<br>-    MachOInt16 Flags;<br>-  };<br>-<br>-  template<class MachOT><br>-  struct SymbolTableEntry;<br>-<br>-  template<endianness TargetEndianness, bool Is64Bits><br>-  struct SymbolTableEntry<MachOType<TargetEndianness, Is64Bits> > {<br>-    LLVM_MACHO_IMPORT_TYPES(MachOType, TargetEndianness, Is64Bits)<br>-    MachOInt32 StringIndex;<br>-    uint8_t Type;<br>-    uint8_t SectionIndex;<br>-    MachOInt16 Flags;<br>-    MachOIntPtr Value;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct LoadCommand {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    MachOInt32 Type;<br>-    MachOInt32 Size;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct SymtabLoadCommand {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    MachOInt32 Type;<br>-    MachOInt32 Size;<br>-    MachOInt32 SymbolTableOffset;<br>-    MachOInt32 NumSymbolTableEntries;<br>-    MachOInt32 StringTableOffset;<br>-    MachOInt32 StringTableSize;<br>-  };<br>-<br>-  template<class MachOT><br>-  struct SegmentLoadCommand;<br>-<br>-  template<endianness TargetEndianness, bool Is64Bits><br>-  struct SegmentLoadCommand<MachOType<TargetEndianness, Is64Bits> > {<br>-    LLVM_MACHO_IMPORT_TYPES(MachOType, TargetEndianness, Is64Bits)<br>-    MachOInt32 Type;<br>-    MachOInt32 Size;<br>-    char Name[16];<br>-    MachOIntPtr VMAddress;<br>-    MachOIntPtr VMSize;<br>-    MachOIntPtr FileOffset;<br>-    MachOIntPtr FileSize;<br>-    MachOInt32 MaxVMProtection;<br>-    MachOInt32 InitialVMProtection;<br>-    MachOInt32 NumSections;<br>-    MachOInt32 Flags;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct LinkeditDataLoadCommand {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    MachOInt32 Type;<br>-    MachOInt32 Size;<br>-    MachOInt32 DataOffset;<br>-    MachOInt32 DataSize;<br>-  };<br>-<br>-  template<endianness TargetEndianness><br>-  struct Header {<br>-    LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)<br>-    MachOInt32 Magic;<br>-    MachOInt32 CPUType;<br>-    MachOInt32 CPUSubtype;<br>-    MachOInt32 FileType;<br>-    MachOInt32 NumLoadCommands;<br>-    MachOInt32 SizeOfLoadCommands;<br>-    MachOInt32 Flags;<br>-  };<br>-}<br>-<br>-class MachOObjectFileBase : public ObjectFile {<br>-public:<br>-  typedef MachOFormat::SectionBase SectionBase;<br>-<br>-  MachOObjectFileBase(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,<br>-                      error_code &ec);<br>-<br>-  virtual symbol_iterator begin_dynamic_symbols() const;<br>-  virtual symbol_iterator end_dynamic_symbols() const;<br>-  virtual library_iterator begin_libraries_needed() const;<br>-  virtual library_iterator end_libraries_needed() const;<br>-<br>-  virtual uint8_t getBytesInAddress() const;<br>-  virtual StringRef getLoadName() const;<br>-<br>-  bool is64Bit() const;<br>-  void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;<br>-  unsigned getHeaderSize() const;<br>-  StringRef getData(size_t Offset, size_t Size) const;<br>-<br>-  static inline bool classof(const Binary *v) {<br>-    return v->isMachO();<br>-  }<br>-<br>-protected:<br>-  StringRef parseSegmentOrSectionName(const char *P) const;<br>-<br>-  virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;<br>-  virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;<br>-  virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;<br>-  virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,<br>-                                                   bool &Res) const;<br>-  virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;<br>-  virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;<br>-  virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;<br>-<br>-  virtual error_code getRelocationNext(DataRefImpl Rel,<br>-                                       RelocationRef &Res) const;<br>-<br>-  virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;<br>-  virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;<br>-  virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,<br>-                                                 int64_t &Res) const;<br>-<br>-  std::size_t getSectionIndex(DataRefImpl Sec) const;<br>-<br>-  typedef SmallVector<DataRefImpl, 1> SectionList;<br>-  SectionList Sections;<br>-};<br>-<br>-template<endianness TargetEndianness><br>-class MachOObjectFileMiddle : public MachOObjectFileBase {<br>+class MachOObjectFile : public ObjectFile {<br>public:<br>+  struct LoadCommandInfo {<br>+    const char *Ptr;      // Where in memory the load command is.<br>+    macho::LoadCommand C; // The command itself.<br>+  };<br><br>-  typedef MachOFormat::SymbolTableEntryBase<TargetEndianness><br>-    SymbolTableEntryBase;<br>-  typedef MachOFormat::LinkeditDataLoadCommand<TargetEndianness><br>-    LinkeditDataLoadCommand;<br>-  typedef MachOFormat::Header<TargetEndianness> Header;<br>-  typedef MachOFormat::SymtabLoadCommand<TargetEndianness> SymtabLoadCommand;<br>-  typedef MachOFormat::RelocationEntry<sys::IsLittleEndianHost, TargetEndianness> RelocationEntry;<br>-  typedef MachOFormat::ScatteredRelocationEntry<sys::IsLittleEndianHost, TargetEndianness><br>-    ScatteredRelocationEntry;<br>-  typedef MachOFormat::LoadCommand<TargetEndianness> LoadCommand;<br>-<br>-  MachOObjectFileMiddle(MemoryBuffer *Object, bool Is64Bits, error_code &ec);<br>-<br>-  const Header *getHeader() const;<br>-  const LoadCommand *getLoadCommandInfo(unsigned Index) const;<br>-  const RelocationEntry *getRelocation(DataRefImpl Rel) const;<br>-  bool isRelocationScattered(const RelocationEntry *RE) const;<br>-  bool isRelocationPCRel(const RelocationEntry *RE) const;<br>-  unsigned getRelocationLength(const RelocationEntry *RE) const;<br>-  unsigned getRelocationTypeImpl(const RelocationEntry *RE) const;<br>-<br>-  void moveToNextSymbol(DataRefImpl &DRI) const;<br>-  void printRelocationTargetName(const RelocationEntry *RE,<br>-                                 raw_string_ostream &fmt) const;<br>-  const SectionBase *getSectionBase(DataRefImpl DRI) const;<br>-  const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI) const;<br>-  unsigned getCPUType() const;<br>+  MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,<br>+                  error_code &ec);<br><br>-  // In a MachO file, sections have a segment name. This is used in the .o<br>-  // files. They have a single segment, but this field specifies which segment<br>-  // a section should be put in in the final object.<br>-  StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;<br>-<br>-  // Names are stored as 16 bytes. These returns the raw 16 bytes without<br>-  // interpreting them as a C string.<br>-  ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;<br>-  ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;<br>-<br>-  virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;<br>-  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;<br>+  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;<br>+  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;<br>+  virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;<br>+  virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;<br>+  virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;<br>  virtual error_code getSymbolType(DataRefImpl Symb,<br>                                   SymbolRef::Type &Res) const;<br>-  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;<br>+  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;<br>+  virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;<br>  virtual error_code getSymbolSection(DataRefImpl Symb,<br>                                      section_iterator &Res) const;<br>-  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;<br>-  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;<br>-  virtual symbol_iterator begin_symbols() const;<br>-  virtual unsigned getArch() const;<br>-  virtual StringRef getFileFormatName() const;<br>-  virtual symbol_iterator end_symbols() const;<br>-  virtual section_iterator end_sections() const;<br>-<br>-  static bool classof(const Binary *v);<br>-<br>-private:<br>-  // Helper to advance a section or symbol iterator multiple increments at a<br>-  // time.<br>-  template<class T><br>-  static error_code advance(T &it, size_t Val);<br>-<br>-  template<class T><br>-  static void advanceTo(T &it, size_t Val);<br>-};<br>-<br>-template<class MachOT><br>-struct MachOObjectFileHelperCommon;<br>-<br>-template<endianness TargetEndianness, bool Is64Bits><br>-struct MachOObjectFileHelperCommon<MachOType<TargetEndianness, Is64Bits> > {<br>-  typedef<br>-    MachOFormat::SegmentLoadCommand<MachOType<TargetEndianness, Is64Bits> ><br>-    SegmentLoadCommand;<br>-  typedef MachOFormat::SymbolTableEntry<MachOType<TargetEndianness, Is64Bits> ><br>-    SymbolTableEntry;<br>-  typedef MachOFormat::Section<MachOType<TargetEndianness, Is64Bits> > Section;<br>-};<br>-<br>-template<class MachOT><br>-struct MachOObjectFileHelper;<br>-<br>-template<endianness TargetEndianness><br>-struct MachOObjectFileHelper<MachOType<TargetEndianness, false> > :<br>-    public MachOObjectFileHelperCommon<MachOType<TargetEndianness, false> > {<br>-  static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment;<br>-};<br>-<br>-template<endianness TargetEndianness><br>-struct MachOObjectFileHelper<MachOType<TargetEndianness, true> > :<br>-    public MachOObjectFileHelperCommon<MachOType<TargetEndianness, true> > {<br>-  static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment64;<br>-};<br>-<br>-template<class MachOT><br>-class MachOObjectFile : public MachOObjectFileMiddle<MachOT::TargetEndianness> {<br>-public:<br>-  static const endianness TargetEndianness = MachOT::TargetEndianness;<br>-  static const bool Is64Bits = MachOT::Is64Bits;<br>-<br>-  typedef MachOObjectFileMiddle<MachOT::TargetEndianness> Base;<br>-  typedef typename Base::RelocationEntry RelocationEntry;<br>-  typedef typename Base::SectionBase SectionBase;<br>-  typedef typename Base::SymbolTableEntryBase SymbolTableEntryBase;<br>-  typedef typename Base::LoadCommand LoadCommand;<br>-<br>-  typedef MachOObjectFileHelper<MachOT> Helper;<br>-  static const macho::LoadCommandType SegmentLoadType = Helper::SegmentLoadType;<br>-  typedef typename Helper::SegmentLoadCommand SegmentLoadCommand;<br>-  typedef typename Helper::SymbolTableEntry SymbolTableEntry;<br>-  typedef typename Helper::Section Section;<br>-<br>-  MachOObjectFile(MemoryBuffer *Object, error_code &ec);<br>-  static bool classof(const Binary *v);<br>-<br>-  const Section *getSection(DataRefImpl DRI) const;<br>-  const SymbolTableEntry *getSymbolTableEntry(DataRefImpl DRI) const;<br>-  const RelocationEntry *getRelocation(DataRefImpl Rel) const;<br>+  virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;<br><br>+  virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;<br>+  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;<br>  virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;<br>  virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;<br>  virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;<br>  virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;<br>  virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;<br>+  virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;<br>+  virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;<br>+  virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,<br>+                                                   bool &Res) const;<br>+  virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;<br>  virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;<br>+  virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;<br>+  virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,<br>+                                           bool &Result) const;<br>+  virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;<br>  virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;<br>+<br>+  virtual error_code getRelocationNext(DataRefImpl Rel,<br>+                                       RelocationRef &Res) const;<br>  virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;<br>  virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;<br>  virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;<br>  virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;<br>  virtual error_code getRelocationTypeName(DataRefImpl Rel,<br>                                           SmallVectorImpl<char> &Result) const;<br>+  virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,<br>+                                                 int64_t &Res) const;<br>  virtual error_code getRelocationValueString(DataRefImpl Rel,<br>                                           SmallVectorImpl<char> &Result) const;<br>  virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;<br>-  virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;<br>-  virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,<br>-                                           bool &Result) const;<br>-  virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;<br>-  virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;<br>-  virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;<br>-  virtual section_iterator begin_sections() const;<br>-  void moveToNextSection(DataRefImpl &DRI) const;<br>-};<br>-<br>-typedef MachOObjectFileMiddle<support::little> MachOObjectFileLE;<br>-typedef MachOObjectFileMiddle<support::big> MachOObjectFileBE;<br>-<br>-typedef MachOObjectFile<MachOType<support::little, false> ><br>-  MachOObjectFileLE32;<br>-typedef MachOObjectFile<MachOType<support::big, false> ><br>-  MachOObjectFileBE32;<br>-typedef MachOObjectFile<MachOType<support::little, true> ><br>-  MachOObjectFileLE64;<br>-typedef MachOObjectFile<MachOType<support::big, true> ><br>-  MachOObjectFileBE64;<br>-<br>-template<endianness TargetEndianness><br>-MachOObjectFileMiddle<TargetEndianness>::MachOObjectFileMiddle(MemoryBuffer *O,<br>-                                                               bool Is64Bits,<br>-                                                               error_code &ec) :<br>-  MachOObjectFileBase(O, TargetEndianness == support::little, Is64Bits, ec) {<br>-}<br><br>-template<endianness E><br>-const typename MachOObjectFileMiddle<E>::SymbolTableEntryBase *<br>-MachOObjectFileMiddle<E>::getSymbolTableEntryBase(DataRefImpl DRI) const {<br>-  const LoadCommand *L = getLoadCommandInfo(DRI.d.a);<br>-  const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);<br>-<br>-  unsigned Index = DRI.d.b;<br>-<br>-  unsigned SymbolTableEntrySize = is64Bit() ?<br>-    sizeof(MachOObjectFileLE64::SymbolTableEntry) :<br>-    sizeof(MachOObjectFileLE32::SymbolTableEntry);<br>-<br>-  uint64_t Offset = S->SymbolTableOffset + Index * SymbolTableEntrySize;<br>-  StringRef Data = getData(Offset, SymbolTableEntrySize);<br>-  return reinterpret_cast<const SymbolTableEntryBase*>(Data.data());<br>-}<br>-<br>-template<endianness E><br>-const typename MachOObjectFileMiddle<E>::Header *<br>-MachOObjectFileMiddle<E>::getHeader() const {<br>-  StringRef Data = getData(0, sizeof(Header));<br>-  return reinterpret_cast<const Header*>(Data.data());<br>-}<br>-<br>-template<endianness E><br>-const typename MachOObjectFileMiddle<E>::LoadCommand *<br>-MachOObjectFileMiddle<E>::getLoadCommandInfo(unsigned Index) const {<br>-  assert(Index < getHeader()->NumLoadCommands);<br>-  uint64_t Offset;<br>-  uint64_t NewOffset = getHeaderSize();<br>-  const LoadCommand *Load;<br>-  unsigned I = 0;<br>-  do {<br>-    Offset = NewOffset;<br>-    StringRef Data = getData(Offset, sizeof(MachOObjectFileLE::LoadCommand));<br>-    Load = reinterpret_cast<const LoadCommand*>(Data.data());<br>-    NewOffset = Offset + Load->Size;<br>-    ++I;<br>-  } while (I != Index + 1);<br>-<br>-  return reinterpret_cast<const LoadCommand*>(Load);<br>-}<br>-<br>-template<endianness E><br>-const typename MachOObjectFileMiddle<E>::RelocationEntry *<br>-MachOObjectFileMiddle<E>::getRelocation(DataRefImpl Rel) const {<br>-  if (const MachOObjectFile<MachOType<E, true> > *O =<br>-      dyn_cast<MachOObjectFile<MachOType<E, true> > >(this))<br>-    return O->getRelocation(Rel);<br>-<br>-  const MachOObjectFile<MachOType<E, false> > *O =<br>-    cast<MachOObjectFile<MachOType<E, false> > >(this);<br>-  return O->getRelocation(Rel);<br>-}<br>-<br>-template<endianness E><br>-bool<br>-MachOObjectFileMiddle<E>::isRelocationScattered(const RelocationEntry *RE)<br>-                                                                         const {<br>-  if (this->getCPUType() == llvm::MachO::CPUTypeX86_64)<br>-    return false;<br>-  return RE->Address & macho::RF_Scattered;<br>-}<br>-<br>-template<endianness E><br>-bool<br>-MachOObjectFileMiddle<E>::isRelocationPCRel(const RelocationEntry *RE) const {<br>-  typedef MachOObjectFileMiddle<E> ObjType;<br>-  if (isRelocationScattered(RE)) {<br>-    const typename MachOObjectFileMiddle<E>::ScatteredRelocationEntry *SRE =<br>-      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);<br>-    return SRE->PCRel;<br>-  }<br>-  return RE->PCRel;<br>-}<br>-<br>-template<endianness E><br>-unsigned<br>-MachOObjectFileMiddle<E>::getRelocationLength(const RelocationEntry *RE) const {<br>-  typedef MachOObjectFileMiddle<E> ObjType;<br>-  if (isRelocationScattered(RE)) {<br>-    const typename ObjType::ScatteredRelocationEntry *SRE =<br>-      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);<br>-    return SRE->Length;<br>-  }<br>-  return RE->Length;<br>-}<br>-<br>-template<endianness E><br>-unsigned<br>-MachOObjectFileMiddle<E>::getRelocationTypeImpl(const RelocationEntry *RE)<br>-                                                                         const {<br>-  typedef MachOObjectFileMiddle<E> ObjType;<br>-  if (isRelocationScattered(RE)) {<br>-    const typename ObjType::ScatteredRelocationEntry *SRE =<br>-      reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);<br>-    return SRE->Type;<br>-  }<br>-  return RE->Type;<br>-}<br>-<br>-// Helper to advance a section or symbol iterator multiple increments at a time.<br>-template<endianness E><br>-template<class T><br>-error_code MachOObjectFileMiddle<E>::advance(T &it, size_t Val) {<br>-  error_code ec;<br>-  while (Val--) {<br>-    it.increment(ec);<br>-  }<br>-  return ec;<br>-}<br>-<br>-template<endianness E><br>-template<class T><br>-void MachOObjectFileMiddle<E>::advanceTo(T &it, size_t Val) {<br>-  if (error_code ec = advance(it, Val))<br>-    report_fatal_error(ec.message());<br>-}<br>-<br>-template<endianness E><br>-void<br>-MachOObjectFileMiddle<E>::printRelocationTargetName(const RelocationEntry *RE,<br>-                                                raw_string_ostream &fmt) const {<br>-  bool IsScattered = isRelocationScattered(RE);<br>-<br>-  // Target of a scattered relocation is an address.  In the interest of<br>-  // generating pretty output, scan through the symbol table looking for a<br>-  // symbol that aligns with that address.  If we find one, print it.<br>-  // Otherwise, we just print the hex address of the target.<br>-  if (IsScattered) {<br>-    uint32_t Val = RE->SymbolNum;<br>-<br>-    error_code ec;<br>-    for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;<br>-        SI.increment(ec)) {<br>-      if (ec) report_fatal_error(ec.message());<br>-<br>-      uint64_t Addr;<br>-      StringRef Name;<br>-<br>-      if ((ec = SI->getAddress(Addr)))<br>-        report_fatal_error(ec.message());<br>-      if (Addr != Val) continue;<br>-      if ((ec = SI->getName(Name)))<br>-        report_fatal_error(ec.message());<br>-      fmt << Name;<br>-      return;<br>-    }<br>-<br>-    // If we couldn't find a symbol that this relocation refers to, try<br>-    // to find a section beginning instead.<br>-    for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;<br>-         SI.increment(ec)) {<br>-      if (ec) report_fatal_error(ec.message());<br>-<br>-      uint64_t Addr;<br>-      StringRef Name;<br>-<br>-      if ((ec = SI->getAddress(Addr)))<br>-        report_fatal_error(ec.message());<br>-      if (Addr != Val) continue;<br>-      if ((ec = SI->getName(Name)))<br>-        report_fatal_error(ec.message());<br>-      fmt << Name;<br>-      return;<br>-    }<br>-<br>-    fmt << format("0x%x", Val);<br>-    return;<br>-  }<br>-<br>-  StringRef S;<br>-  bool isExtern = RE->External;<br>-  uint64_t Val = RE->Address;<br>-<br>-  if (isExtern) {<br>-    symbol_iterator SI = begin_symbols();<br>-    advanceTo(SI, Val);<br>-    SI->getName(S);<br>-  } else {<br>-    section_iterator SI = begin_sections();<br>-    advanceTo(SI, Val);<br>-    SI->getName(S);<br>-  }<br>-<br>-  fmt << S;<br>-}<br>-<br>-template<endianness E><br>-const typename MachOObjectFileMiddle<E>::SectionBase *<br>-MachOObjectFileMiddle<E>::getSectionBase(DataRefImpl DRI) const {<br>-  uintptr_t CommandAddr =<br>-    reinterpret_cast<uintptr_t>(getLoadCommandInfo(DRI.d.a));<br>-<br>-  bool Is64 = is64Bit();<br>-  unsigned SegmentLoadSize =<br>-    Is64 ? sizeof(MachOObjectFileLE64::SegmentLoadCommand) :<br>-           sizeof(MachOObjectFileLE32::SegmentLoadCommand);<br>-  unsigned SectionSize = Is64 ? sizeof(MachOObjectFileLE64::Section) :<br>-                                sizeof(MachOObjectFileLE32::Section);<br>-<br>-  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;<br>-  return reinterpret_cast<const SectionBase*>(SectionAddr);<br>-}<br>-<br>-template<endianness E><br>-unsigned MachOObjectFileMiddle<E>::getCPUType() const {<br>-  return getHeader()->CPUType;<br>-}<br>-<br>-template<endianness E><br>-void MachOObjectFileMiddle<E>::moveToNextSymbol(DataRefImpl &DRI) const {<br>-  uint32_t LoadCommandCount = getHeader()->NumLoadCommands;<br>-  while (DRI.d.a < LoadCommandCount) {<br>-    const LoadCommand *L = getLoadCommandInfo(DRI.d.a);<br>-    if (L->Type == macho::LCT_Symtab) {<br>-      const SymtabLoadCommand *S =<br>-        reinterpret_cast<const SymtabLoadCommand *>(L);<br>-      if (DRI.d.b < S->NumSymbolTableEntries)<br>-        return;<br>-    }<br>-<br>-    DRI.d.a++;<br>-    DRI.d.b = 0;<br>-  }<br>-}<br>-<br>-template<endianness E><br>-StringRef<br>-MachOObjectFileMiddle<E>::getSectionFinalSegmentName(DataRefImpl Sec) const {<br>-  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);<br>-  return parseSegmentOrSectionName(Raw.data());<br>-}<br>-<br>-template<endianness E><br>-ArrayRef<char><br>-MachOObjectFileMiddle<E>::getSectionRawName(DataRefImpl Sec) const {<br>-  const SectionBase *Base = getSectionBase(Sec);<br>-  return ArrayRef<char>(Base->Name);<br>-}<br>-<br>-template<endianness E><br>-ArrayRef<char><br>-MachOObjectFileMiddle<E>::getSectionRawFinalSegmentName(DataRefImpl Sec) const {<br>-  const SectionBase *Base = getSectionBase(Sec);<br>-  return ArrayRef<char>(Base->SegmentName);<br>-}<br>-<br>-template<endianness E><br>-error_code MachOObjectFileMiddle<E>::getSymbolFlags(DataRefImpl DRI,<br>-                                                    uint32_t &Result) const {<br>-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);<br>-<br>-  uint8_t MachOType = Entry->Type;<br>-  uint16_t MachOFlags = Entry->Flags;<br>-<br>-  // TODO: Correctly set SF_ThreadLocal<br>-  Result = SymbolRef::SF_None;<br>-<br>-  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)<br>-    Result |= SymbolRef::SF_Undefined;<br>-<br>-  if (MachOFlags & macho::STF_StabsEntryMask)<br>-    Result |= SymbolRef::SF_FormatSpecific;<br>-<br>-  if (MachOType & MachO::NlistMaskExternal) {<br>-    Result |= SymbolRef::SF_Global;<br>-    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)<br>-      Result |= SymbolRef::SF_Common;<br>-  }<br>-<br>-  if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))<br>-    Result |= SymbolRef::SF_Weak;<br>-<br>-  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)<br>-    Result |= SymbolRef::SF_Absolute;<br>-<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-error_code MachOObjectFileMiddle<E>::getSymbolType(DataRefImpl Symb,<br>-                                                   SymbolRef::Type &Res) const {<br>-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);<br>-  uint8_t n_type = Entry->Type;<br>-<br>-  Res = SymbolRef::ST_Other;<br>-<br>-  // If this is a STAB debugging symbol, we can do nothing more.<br>-  if (n_type & MachO::NlistMaskStab) {<br>-    Res = SymbolRef::ST_Debug;<br>-    return object_error::success;<br>-  }<br>-<br>-  switch (n_type & MachO::NlistMaskType) {<br>-    case MachO::NListTypeUndefined :<br>-      Res = SymbolRef::ST_Unknown;<br>-      break;<br>-    case MachO::NListTypeSection :<br>-      Res = SymbolRef::ST_Function;<br>-      break;<br>-  }<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-error_code MachOObjectFileMiddle<E>::getSymbolName(DataRefImpl Symb,<br>-                                                   StringRef &Res) const {<br>-  const LoadCommand *L = getLoadCommandInfo(Symb.d.a);<br>-  const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);<br>-  StringRef StringTable = getData(S->StringTableOffset, S->StringTableSize);<br>-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);<br>-  const char *Start = &StringTable.data()[Entry->StringIndex];<br>-  Res = StringRef(Start);<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-error_code<br>-MachOObjectFileMiddle<E>::getSymbolSection(DataRefImpl Symb,<br>-                                           section_iterator &Res) const {<br>-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);<br>-  uint8_t index = Entry->SectionIndex;<br>-<br>-  if (index == 0)<br>-    Res = end_sections();<br>-  else<br>-    Res = section_iterator(SectionRef(Sections[index-1], this));<br>-<br>-  return object_error::success;<br>-}<br>-<br>-<br>-template<endianness E><br>-error_code MachOObjectFileMiddle<E>::getSymbolNMTypeChar(DataRefImpl Symb,<br>-                                                         char &Res) const {<br>-  const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);<br>-  uint8_t Type = Entry->Type;<br>-  uint16_t Flags = Entry->Flags;<br>-<br>-  char Char;<br>-  switch (Type & macho::STF_TypeMask) {<br>-    case macho::STT_Undefined:<br>-      Char = 'u';<br>-      break;<br>-    case macho::STT_Absolute:<br>-    case macho::STT_Section:<br>-      Char = 's';<br>-      break;<br>-    default:<br>-      Char = '?';<br>-      break;<br>-  }<br>-<br>-  if (Flags & (macho::STF_External | macho::STF_PrivateExtern))<br>-    Char = toupper(static_cast<unsigned char>(Char));<br>-  Res = Char;<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-error_code<br>-MachOObjectFileMiddle<E>::getSectionName(DataRefImpl Sec,<br>-                                         StringRef &Result) const {<br>-  ArrayRef<char> Raw = getSectionRawName(Sec);<br>-  Result = parseSegmentOrSectionName(Raw.data());<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-error_code MachOObjectFileMiddle<E>::getSymbolNext(DataRefImpl Symb,<br>-                                                     SymbolRef &Res) const {<br>-  Symb.d.b++;<br>-  moveToNextSymbol(Symb);<br>-  Res = SymbolRef(Symb, this);<br>-  return object_error::success;<br>-}<br>-<br>-template<endianness E><br>-symbol_iterator MachOObjectFileMiddle<E>::begin_symbols() const {<br>-  // DRI.d.a = segment number; DRI.d.b = symbol index.<br>-  DataRefImpl DRI;<br>-  moveToNextSymbol(DRI);<br>-  return symbol_iterator(SymbolRef(DRI, this));<br>-}<br>-<br>-template<endianness E><br>-unsigned MachOObjectFileMiddle<E>::getArch() const {<br>-  switch (getCPUType()) {<br>-  case llvm::MachO::CPUTypeI386:<br>-    return Triple::x86;<br>-  case llvm::MachO::CPUTypeX86_64:<br>-    return Triple::x86_64;<br>-  case llvm::MachO::CPUTypeARM:<br>-    return Triple::arm;<br>-  case llvm::MachO::CPUTypePowerPC:<br>-    return Triple::ppc;<br>-  case llvm::MachO::CPUTypePowerPC64:<br>-    return Triple::ppc64;<br>-  default:<br>-    return Triple::UnknownArch;<br>-  }<br>-}<br>-<br>-template<endianness E><br>-StringRef MachOObjectFileMiddle<E>::getFileFormatName() const {<br>-  unsigned CPUType = getCPUType();<br>-  if (!is64Bit()) {<br>-    switch (CPUType) {<br>-    case llvm::MachO::CPUTypeI386:<br>-      return "Mach-O 32-bit i386";<br>-    case llvm::MachO::CPUTypeARM:<br>-      return "Mach-O arm";<br>-    case llvm::MachO::CPUTypePowerPC:<br>-      return "Mach-O 32-bit ppc";<br>-    default:<br>-      assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&<br>-             "64-bit object file when we're not 64-bit?");<br>-      return "Mach-O 32-bit unknown";<br>-    }<br>-  }<br>-<br>-  // Make sure the cpu type has the correct mask.<br>-  assert((CPUType & llvm::MachO::CPUArchABI64)<br>-<span class="Apple-tab-span" style="white-space: pre;">   </span><span class="Apple-converted-space"> </span>== llvm::MachO::CPUArchABI64 &&<br>-<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>"32-bit object file when we're 64-bit?");<br>-<br>-  switch (CPUType) {<br>-  case llvm::MachO::CPUTypeX86_64:<br>-    return "Mach-O 64-bit x86-64";<br>-  case llvm::MachO::CPUTypePowerPC64:<br>-    return "Mach-O 64-bit ppc64";<br>-  default:<br>-    return "Mach-O 64-bit unknown";<br>-  }<br>-}<br>-<br>-template<endianness E><br>-symbol_iterator MachOObjectFileMiddle<E>::end_symbols() const {<br>-  DataRefImpl DRI;<br>-  DRI.d.a = getHeader()->NumLoadCommands;<br>-  return symbol_iterator(SymbolRef(DRI, this));<br>-}<br>-<br>-template<endianness E><br>-section_iterator MachOObjectFileMiddle<E>::end_sections() const {<br>-  DataRefImpl DRI;<br>-  DRI.d.a = getHeader()->NumLoadCommands;<br>-  return section_iterator(SectionRef(DRI, this));<br>-}<br>-<br>-template<endianness E><br>-bool MachOObjectFileMiddle<E>::classof(const Binary *v) {<br>-  return isa<MachOObjectFile<MachOType<E, false> > >(v) ||<br>-    isa<MachOObjectFile<MachOType<E, true> > >(v);<br>-}<br>-<br>-template<class MachOT><br>-MachOObjectFile<MachOT>::MachOObjectFile(MemoryBuffer *Object,<br>-                                         error_code &ec) :<br>-  MachOObjectFileMiddle<TargetEndianness>(Object, Is64Bits, ec) {<br>-  DataRefImpl DRI;<br>-  moveToNextSection(DRI);<br>-  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;<br>-  while (DRI.d.a < LoadCommandCount) {<br>-    this->Sections.push_back(DRI);<br>-    DRI.d.b++;<br>-    moveToNextSection(DRI);<br>-  }<br>-}<br>-<br>-template<class MachOT><br>-bool MachOObjectFile<MachOT>::classof(const Binary *v) {<br>-  return v->getType() ==<br>-    Base::getMachOType(TargetEndianness == support::little, Is64Bits);<br>-}<br>-<br>-template<class MachOT><br>-const typename MachOObjectFile<MachOT>::Section *<br>-MachOObjectFile<MachOT>::getSection(DataRefImpl DRI) const {<br>-  const SectionBase *Addr = this->getSectionBase(DRI);<br>-  return reinterpret_cast<const Section*>(Addr);<br>-}<br>-<br>-template<class MachOT><br>-const typename MachOObjectFile<MachOT>::SymbolTableEntry *<br>-MachOObjectFile<MachOT>::getSymbolTableEntry(DataRefImpl DRI) const {<br>-  const SymbolTableEntryBase *Base = this->getSymbolTableEntryBase(DRI);<br>-  return reinterpret_cast<const SymbolTableEntry*>(Base);<br>-}<br>-<br>-template<class MachOT><br>-const typename MachOObjectFile<MachOT>::RelocationEntry *<br>-MachOObjectFile<MachOT>::getRelocation(DataRefImpl Rel) const {<br>-  const Section *Sect = getSection(this->Sections[Rel.d.b]);<br>-  uint32_t RelOffset = Sect->RelocationTableOffset;<br>-  uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);<br>-  StringRef Data = this->getData(Offset, sizeof(RelocationEntry));<br>-  return reinterpret_cast<const RelocationEntry*>(Data.data());<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getSectionAddress(DataRefImpl Sec,<br>-                                           uint64_t &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  Res = Sect->Address;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getSectionSize(DataRefImpl Sec,<br>-                                        uint64_t &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  Res = Sect->Size;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getSectionContents(DataRefImpl Sec,<br>-                                            StringRef &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  Res = this->getData(Sect->Offset, Sect->Size);<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getSectionAlignment(DataRefImpl Sec,<br>-                                             uint64_t &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  Res = uint64_t(1) << Sect->Align;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::isSectionText(DataRefImpl Sec, bool &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  Res = Sect->Flags & macho::SF_PureInstructions;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {<br>-  const Section *Sect = getSection(Sec);<br>-  unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;<br>-  Res = SectionType == MachO::SectionTypeZeroFill ||<br>-    SectionType == MachO::SectionTypeZeroFillLarge;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-relocation_iterator<br>-MachOObjectFile<MachOT>::getSectionRelEnd(DataRefImpl Sec) const {<br>-  const Section *Sect = getSection(Sec);<br>-  uint32_t LastReloc = Sect->NumRelocationTableEntries;<br>-  DataRefImpl Ret;<br>-  Ret.d.a = LastReloc;<br>-  Ret.d.b = this->getSectionIndex(Sec);<br>-  return relocation_iterator(RelocationRef(Ret, this));<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationAddress(DataRefImpl Rel,<br>-                                              uint64_t &Res) const {<br>-  const Section *Sect = getSection(this->Sections[Rel.d.b]);<br>-  uint64_t SectAddress = Sect->Address;<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-<br>-  uint64_t RelAddr;<br>-  if (this->isRelocationScattered(RE))<br>-    RelAddr = RE->Address & 0xFFFFFF;<br>-  else<br>-    RelAddr = RE->Address;<br>-<br>-  Res = SectAddress + RelAddr;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationOffset(DataRefImpl Rel,<br>-                                             uint64_t &Res) const {<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-  if (this->isRelocationScattered(RE))<br>-    Res = RE->Address & 0xFFFFFF;<br>-  else<br>-    Res = RE->Address;<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationSymbol(DataRefImpl Rel,<br>-                                             SymbolRef &Res) const {<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-  uint32_t SymbolIdx = RE->SymbolNum;<br>-  bool isExtern = RE->External;<br>-<br>-  DataRefImpl Sym;<br>-  this->moveToNextSymbol(Sym);<br>-  if (isExtern) {<br>-    for (unsigned i = 0; i < SymbolIdx; i++) {<br>-      Sym.d.b++;<br>-      this->moveToNextSymbol(Sym);<br>-      assert(Sym.d.a < this->getHeader()->NumLoadCommands &&<br>-             "Relocation symbol index out of range!");<br>-    }<br>-  }<br>-  Res = SymbolRef(Sym, this);<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code MachOObjectFile<MachOT>::getRelocationType(DataRefImpl Rel,<br>-                                                      uint64_t &Res) const {<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-  Res = this->getRelocationTypeImpl(RE);<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationTypeName(DataRefImpl Rel,<br>-                                          SmallVectorImpl<char> &Result) const {<br>-    // TODO: Support scattered relocations.<br>-  StringRef res;<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-<br>-  unsigned Arch = this->getArch();<br>-<br>-  unsigned r_type = this->getRelocationTypeImpl(RE);<br>-<br>-  switch (Arch) {<br>-    case Triple::x86: {<br>-      static const char *const Table[] =  {<br>-        "GENERIC_RELOC_VANILLA",<br>-        "GENERIC_RELOC_PAIR",<br>-        "GENERIC_RELOC_SECTDIFF",<br>-        "GENERIC_RELOC_PB_LA_PTR",<br>-        "GENERIC_RELOC_LOCAL_SECTDIFF",<br>-        "GENERIC_RELOC_TLV" };<br>-<br>-      if (r_type > 6)<br>-        res = "Unknown";<br>-      else<br>-        res = Table[r_type];<br>-      break;<br>-    }<br>-    case Triple::x86_64: {<br>-      static const char *const Table[] =  {<br>-        "X86_64_RELOC_UNSIGNED",<br>-        "X86_64_RELOC_SIGNED",<br>-        "X86_64_RELOC_BRANCH",<br>-        "X86_64_RELOC_GOT_LOAD",<br>-        "X86_64_RELOC_GOT",<br>-        "X86_64_RELOC_SUBTRACTOR",<br>-        "X86_64_RELOC_SIGNED_1",<br>-        "X86_64_RELOC_SIGNED_2",<br>-        "X86_64_RELOC_SIGNED_4",<br>-        "X86_64_RELOC_TLV" };<br>-<br>-      if (r_type > 9)<br>-        res = "Unknown";<br>-      else<br>-        res = Table[r_type];<br>-      break;<br>-    }<br>-    case Triple::arm: {<br>-      static const char *const Table[] =  {<br>-        "ARM_RELOC_VANILLA",<br>-        "ARM_RELOC_PAIR",<br>-        "ARM_RELOC_SECTDIFF",<br>-        "ARM_RELOC_LOCAL_SECTDIFF",<br>-        "ARM_RELOC_PB_LA_PTR",<br>-        "ARM_RELOC_BR24",<br>-        "ARM_THUMB_RELOC_BR22",<br>-        "ARM_THUMB_32BIT_BRANCH",<br>-        "ARM_RELOC_HALF",<br>-        "ARM_RELOC_HALF_SECTDIFF" };<br>-<br>-      if (r_type > 9)<br>-        res = "Unknown";<br>-      else<br>-        res = Table[r_type];<br>-      break;<br>-    }<br>-    case Triple::ppc: {<br>-      static const char *const Table[] =  {<br>-        "PPC_RELOC_VANILLA",<br>-        "PPC_RELOC_PAIR",<br>-        "PPC_RELOC_BR14",<br>-        "PPC_RELOC_BR24",<br>-        "PPC_RELOC_HI16",<br>-        "PPC_RELOC_LO16",<br>-        "PPC_RELOC_HA16",<br>-        "PPC_RELOC_LO14",<br>-        "PPC_RELOC_SECTDIFF",<br>-        "PPC_RELOC_PB_LA_PTR",<br>-        "PPC_RELOC_HI16_SECTDIFF",<br>-        "PPC_RELOC_LO16_SECTDIFF",<br>-        "PPC_RELOC_HA16_SECTDIFF",<br>-        "PPC_RELOC_JBSR",<br>-        "PPC_RELOC_LO14_SECTDIFF",<br>-        "PPC_RELOC_LOCAL_SECTDIFF" };<br>-<br>-      res = Table[r_type];<br>-      break;<br>-    }<br>-    case Triple::UnknownArch:<br>-      res = "Unknown";<br>-      break;<br>-  }<br>-  Result.append(res.begin(), res.end());<br>-  return object_error::success;<br>-}<br>+  virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;<br>+  virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;<br><br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel,<br>-                                          SmallVectorImpl<char> &Result) const {<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-<br>-  unsigned Arch = this->getArch();<br>-  bool IsScattered = this->isRelocationScattered(RE);<br>-<br>-  std::string fmtbuf;<br>-  raw_string_ostream fmt(fmtbuf);<br>-<br>-  unsigned Type = this->getRelocationTypeImpl(RE);<br>-  bool IsPCRel = this->isRelocationPCRel(RE);<br>-<br>-  // Determine any addends that should be displayed with the relocation.<br>-  // These require decoding the relocation type, which is triple-specific.<br>-<br>-  // X86_64 has entirely custom relocation types.<br>-  if (Arch == Triple::x86_64) {<br>-    bool isPCRel = RE->PCRel;<br>-<br>-    switch (Type) {<br>-      case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD<br>-      case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "@GOT";<br>-        if (isPCRel) fmt << "PCREL";<br>-        break;<br>-      }<br>-      case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR<br>-        DataRefImpl RelNext = Rel;<br>-        RelNext.d.a++;<br>-        const RelocationEntry *RENext = getRelocation(RelNext);<br>-<br>-        // X86_64_SUBTRACTOR must be followed by a relocation of type<br>-        // X86_64_RELOC_UNSIGNED.<br>-        // NOTE: Scattered relocations don't exist on x86_64.<br>-        unsigned RType = RENext->Type;<br>-        if (RType != 0)<br>-          report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "<br>-                             "X86_64_RELOC_SUBTRACTOR.");<br>-<br>-        // The X86_64_RELOC_UNSIGNED contains the minuend symbol,<br>-        // X86_64_SUBTRACTOR contains to the subtrahend.<br>-        this->printRelocationTargetName(RENext, fmt);<br>-        fmt << "-";<br>-        this->printRelocationTargetName(RE, fmt);<br>-        break;<br>-      }<br>-      case macho::RIT_X86_64_TLV:<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "@TLV";<br>-        if (isPCRel) fmt << "P";<br>-        break;<br>-      case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "-1";<br>-        break;<br>-      case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "-2";<br>-        break;<br>-      case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "-4";<br>-        break;<br>-      default:<br>-        this->printRelocationTargetName(RE, fmt);<br>-        break;<br>-    }<br>-  // X86 and ARM share some relocation types in common.<br>-  } else if (Arch == Triple::x86 || Arch == Triple::arm) {<br>-    // Generic relocation types...<br>-    switch (Type) {<br>-      case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info<br>-        return object_error::success;<br>-      case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF<br>-        DataRefImpl RelNext = Rel;<br>-        RelNext.d.a++;<br>-        const RelocationEntry *RENext = getRelocation(RelNext);<br>-<br>-        // X86 sect diff's must be followed by a relocation of type<br>-        // GENERIC_RELOC_PAIR.<br>-        bool isNextScattered = (Arch != Triple::x86_64) &&<br>-                               (RENext->Address & macho::RF_Scattered);<br>-        unsigned RType;<br>-        if (isNextScattered)<br>-          RType = (RENext->Address >> 24) & 0xF;<br>-        else<br>-          RType = RENext->Type;<br>-        if (RType != 1)<br>-          report_fatal_error("Expected GENERIC_RELOC_PAIR after "<br>-                             "GENERIC_RELOC_SECTDIFF.");<br>-<br>-        this->printRelocationTargetName(RE, fmt);<br>-        fmt << "-";<br>-        this->printRelocationTargetName(RENext, fmt);<br>-        break;<br>-      }<br>-    }<br>-<br>-    if (Arch == Triple::x86) {<br>-      // All X86 relocations that need special printing were already<br>-      // handled in the generic code.<br>-      switch (Type) {<br>-        case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF<br>-          DataRefImpl RelNext = Rel;<br>-          RelNext.d.a++;<br>-          const RelocationEntry *RENext = getRelocation(RelNext);<br>-<br>-          // X86 sect diff's must be followed by a relocation of type<br>-          // GENERIC_RELOC_PAIR.<br>-          bool isNextScattered = (Arch != Triple::x86_64) &&<br>-                               (RENext->Address & macho::RF_Scattered);<br>-          unsigned RType;<br>-          if (isNextScattered)<br>-            RType = (RENext->Address >> 24) & 0xF;<br>-          else<br>-            RType = RENext->Type;<br>-          if (RType != 1)<br>-            report_fatal_error("Expected GENERIC_RELOC_PAIR after "<br>-                               "GENERIC_RELOC_LOCAL_SECTDIFF.");<br>-<br>-          this->printRelocationTargetName(RE, fmt);<br>-          fmt << "-";<br>-          this->printRelocationTargetName(RENext, fmt);<br>-          break;<br>-        }<br>-        case macho::RIT_Generic_TLV: {<br>-          this->printRelocationTargetName(RE, fmt);<br>-          fmt << "@TLV";<br>-          if (IsPCRel) fmt << "P";<br>-          break;<br>-        }<br>-        default:<br>-          this->printRelocationTargetName(RE, fmt);<br>-      }<br>-    } else { // ARM-specific relocations<br>-      switch (Type) {<br>-        case macho::RIT_ARM_Half:             // ARM_RELOC_HALF<br>-        case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF<br>-          // Half relocations steal a bit from the length field to encode<br>-          // whether this is an upper16 or a lower16 relocation.<br>-          bool isUpper;<br>-          if (IsScattered)<br>-            isUpper = (RE->Address >> 28) & 1;<br>-          else<br>-            isUpper = (RE->Length >> 1) & 1;<br>-<br>-          if (isUpper)<br>-            fmt << ":upper16:(";<br>-          else<br>-            fmt << ":lower16:(";<br>-          this->printRelocationTargetName(RE, fmt);<br>-<br>-          DataRefImpl RelNext = Rel;<br>-          RelNext.d.a++;<br>-          const RelocationEntry *RENext = getRelocation(RelNext);<br>-<br>-          // ARM half relocs must be followed by a relocation of type<br>-          // ARM_RELOC_PAIR.<br>-          bool isNextScattered = (Arch != Triple::x86_64) &&<br>-                                 (RENext->Address & macho::RF_Scattered);<br>-          unsigned RType;<br>-          if (isNextScattered)<br>-            RType = (RENext->Address >> 24) & 0xF;<br>-          else<br>-            RType = RENext->Type;<br>-<br>-          if (RType != 1)<br>-            report_fatal_error("Expected ARM_RELOC_PAIR after "<br>-                               "GENERIC_RELOC_HALF");<br>-<br>-          // NOTE: The half of the target virtual address is stashed in the<br>-          // address field of the secondary relocation, but we can't reverse<br>-          // engineer the constant offset from it without decoding the movw/movt<br>-          // instruction to find the other half in its immediate field.<br>-<br>-          // ARM_RELOC_HALF_SECTDIFF encodes the second section in the<br>-          // symbol/section pointer of the follow-on relocation.<br>-          if (Type == macho::RIT_ARM_HalfDifference) {<br>-            fmt << "-";<br>-            this->printRelocationTargetName(RENext, fmt);<br>-          }<br>-<br>-          fmt << ")";<br>-          break;<br>-        }<br>-        default: {<br>-          this->printRelocationTargetName(RE, fmt);<br>-        }<br>-      }<br>-    }<br>-  } else<br>-    this->printRelocationTargetName(RE, fmt);<br>-<br>-  fmt.flush();<br>-  Result.append(fmtbuf.begin(), fmtbuf.end());<br>-  return object_error::success;<br>-}<br>+  virtual symbol_iterator begin_symbols() const;<br>+  virtual symbol_iterator end_symbols() const;<br><br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel,<br>-                                             bool &Result) const {<br>-  const RelocationEntry *RE = getRelocation(Rel);<br>-  unsigned Arch = this->getArch();<br>-  unsigned Type = this->getRelocationTypeImpl(RE);<br>-<br>-  Result = false;<br>-<br>-  // On arches that use the generic relocations, GENERIC_RELOC_PAIR<br>-  // is always hidden.<br>-  if (Arch == Triple::x86 || Arch == Triple::arm) {<br>-    if (Type == macho::RIT_Pair) Result = true;<br>-  } else if (Arch == Triple::x86_64) {<br>-    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows<br>-    // an X864_64_RELOC_SUBTRACTOR.<br>-    if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {<br>-      DataRefImpl RelPrev = Rel;<br>-      RelPrev.d.a--;<br>-      const RelocationEntry *REPrev = this->getRelocation(RelPrev);<br>+  virtual symbol_iterator begin_dynamic_symbols() const;<br>+  virtual symbol_iterator end_dynamic_symbols() const;<br><br>-      unsigned PrevType = REPrev->Type;<br>+  virtual section_iterator begin_sections() const;<br>+  virtual section_iterator end_sections() const;<br><br>-      if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;<br>-    }<br>-  }<br>+  virtual library_iterator begin_libraries_needed() const;<br>+  virtual library_iterator end_libraries_needed() const;<br><br>-  return object_error::success;<br>-}<br>+  virtual uint8_t getBytesInAddress() const;<br><br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::getSymbolFileOffset(DataRefImpl Symb,<br>-                                             uint64_t &Res) const {<br>-  const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);<br>-  Res = Entry->Value;<br>-  if (Entry->SectionIndex) {<br>-    const Section *Sec =<br>-      this->getSection(this->Sections[Entry->SectionIndex-1]);<br>-    Res += Sec->Offset - Sec->Address;<br>-  }<br>+  virtual StringRef getFileFormatName() const;<br>+  virtual unsigned getArch() const;<br><br>-  return object_error::success;<br>-}<br>+  virtual StringRef getLoadName() const;<br><br>-template<class MachOT><br>-error_code<br>-MachOObjectFile<MachOT>::sectionContainsSymbol(DataRefImpl Sec,<br>-                                               DataRefImpl Symb,<br>-                                               bool &Result) const {<br>-  SymbolRef::Type ST;<br>-  this->getSymbolType(Symb, ST);<br>-  if (ST == SymbolRef::ST_Unknown) {<br>-    Result = false;<br>-    return object_error::success;<br>-  }<br>+  // In a MachO file, sections have a segment name. This is used in the .o<br>+  // files. They have a single segment, but this field specifies which segment<br>+  // a section should be put in in the final object.<br>+  StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;<br><br>-  uint64_t SectBegin, SectEnd;<br>-  getSectionAddress(Sec, SectBegin);<br>-  getSectionSize(Sec, SectEnd);<br>-  SectEnd += SectBegin;<br>-<br>-  const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);<br>-  uint64_t SymAddr= Entry->Value;<br>-  Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);<br>+  // Names are stored as 16 bytes. These returns the raw 16 bytes without<br>+  // interpreting them as a C string.<br>+  ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;<br>+  ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;<br><br>-  return object_error::success;<br>-}<br>+  // MachO specific Info about relocations.<br>+  bool isRelocationScattered(const macho::RelocationEntry &RE) const;<br>+  unsigned getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const;<br>+  bool getPlainRelocationExternal(const macho::RelocationEntry &RE) const;<br>+  bool getScatteredRelocationScattered(const macho::RelocationEntry &RE) const;<br>+  uint32_t getScatteredRelocationValue(const macho::RelocationEntry &RE) const;<br>+  unsigned getAnyRelocationAddress(const macho::RelocationEntry &RE) const;<br>+  unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const;<br>+  unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const;<br>+  unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const;<br>+<br>+  // Walk load commands.<br>+  LoadCommandInfo getFirstLoadCommandInfo() const;<br>+  LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;<br>+<br>+  // MachO specific structures.<br>+  macho::Section getSection(DataRefImpl DRI) const;<br>+  macho::Section64 getSection64(DataRefImpl DRI) const;<br>+  macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;<br>+  macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;<br>+  macho::LinkeditDataLoadCommand<br>+  getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;<br>+  macho::RelocationEntry getRelocation(DataRefImpl Rel) const;<br>+  macho::Header getHeader() const;<br>+  macho::SymtabLoadCommand getSymtabLoadCommand() const;<br><br>-template<class MachOT><br>-error_code MachOObjectFile<MachOT>::getSymbolAddress(DataRefImpl Symb,<br>-                                                     uint64_t &Res) const {<br>-  const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);<br>-  Res = Entry->Value;<br>-  return object_error::success;<br>-}<br>+  bool is64Bit() const;<br>+  void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;<br><br>-template<class MachOT><br>-error_code MachOObjectFile<MachOT>::getSymbolSize(DataRefImpl DRI,<br>-                                                    uint64_t &Result) const {<br>-  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;<br>-  uint64_t BeginOffset;<br>-  uint64_t EndOffset = 0;<br>-  uint8_t SectionIndex;<br>-<br>-  const SymbolTableEntry *Entry = getSymbolTableEntry(DRI);<br>-  BeginOffset = Entry->Value;<br>-  SectionIndex = Entry->SectionIndex;<br>-  if (!SectionIndex) {<br>-    uint32_t flags = SymbolRef::SF_None;<br>-    this->getSymbolFlags(DRI, flags);<br>-    if (flags & SymbolRef::SF_Common)<br>-      Result = Entry->Value;<br>-    else<br>-      Result = UnknownAddressOrSize;<br>-    return object_error::success;<br>-  }<br>-  // Unfortunately symbols are unsorted so we need to touch all<br>-  // symbols from load command<br>-  DRI.d.b = 0;<br>-  uint32_t Command = DRI.d.a;<br>-  while (Command == DRI.d.a) {<br>-    this->moveToNextSymbol(DRI);<br>-    if (DRI.d.a < LoadCommandCount) {<br>-      Entry = getSymbolTableEntry(DRI);<br>-      if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)<br>-        if (!EndOffset || Entry->Value < EndOffset)<br>-          EndOffset = Entry->Value;<br>-    }<br>-    DRI.d.b++;<br>-  }<br>-  if (!EndOffset) {<br>-    uint64_t Size;<br>-    this->getSectionSize(this->Sections[SectionIndex-1], Size);<br>-    this->getSectionAddress(this->Sections[SectionIndex-1], EndOffset);<br>-    EndOffset += Size;<br>+  static bool classof(const Binary *v) {<br>+    return v->isMachO();<br>  }<br>-  Result = EndOffset - BeginOffset;<br>-  return object_error::success;<br>-}<br><br>-template<class MachOT><br>-error_code MachOObjectFile<MachOT>::getSectionNext(DataRefImpl Sec,<br>-                                                   SectionRef &Res) const {<br>-  Sec.d.b++;<br>-  moveToNextSection(Sec);<br>-  Res = SectionRef(Sec, this);<br>-  return object_error::success;<br>-}<br>-<br>-template<class MachOT><br>-section_iterator MachOObjectFile<MachOT>::begin_sections() const {<br>-  DataRefImpl DRI;<br>-  moveToNextSection(DRI);<br>-  return section_iterator(SectionRef(DRI, this));<br>-}<br>-<br>-template<class MachOT><br>-void MachOObjectFile<MachOT>::moveToNextSection(DataRefImpl &DRI) const {<br>-  uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;<br>-  while (DRI.d.a < LoadCommandCount) {<br>-    const LoadCommand *Command = this->getLoadCommandInfo(DRI.d.a);<br>-    if (Command->Type == SegmentLoadType) {<br>-      const SegmentLoadCommand *SegmentLoadCmd =<br>-        reinterpret_cast<const SegmentLoadCommand*>(Command);<br>-      if (DRI.d.b < SegmentLoadCmd->NumSections)<br>-        return;<br>-    }<br>-<br>-    DRI.d.a++;<br>-    DRI.d.b = 0;<br>-  }<br>-}<br>+private:<br>+  typedef SmallVector<const char*, 1> SectionList;<br>+  SectionList Sections;<br>+  const char *SymtabLoadCmd;<br>+};<br><br>}<br>}<br><br>Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)<br>+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Apr 18 13:08:55 2013<br>@@ -15,9 +15,9 @@<br>#include "llvm/Object/MachO.h"<br>#include "llvm/ADT/Triple.h"<br>#include "llvm/Object/MachOFormat.h"<br>-#include "llvm/Support/Casting.h"<br>#include "llvm/Support/DataExtractor.h"<br>#include "llvm/Support/Format.h"<br>+#include "llvm/Support/Host.h"<br>#include "llvm/Support/MemoryBuffer.h"<br>#include <cctype><br>#include <cstring><br>@@ -29,113 +29,693 @@ using namespace object;<br>namespace llvm {<br>namespace object {<br><br>-MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,<br>-                                         bool IsLittleEndian, bool Is64bits,<br>-                                         error_code &ec)<br>-    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {<br>+struct SymbolTableEntryBase {<br>+  uint32_t StringIndex;<br>+  uint8_t Type;<br>+  uint8_t SectionIndex;<br>+  uint16_t Flags;<br>+};<br>+<br>+struct SectionBase {<br>+  char Name[16];<br>+  char SegmentName[16];<br>+};<br>+<br>+template<typename T><br>+static void SwapValue(T &Value) {<br>+  Value = sys::SwapByteOrder(Value);<br>+}<br>+<br>+template<typename T><br>+static void SwapStruct(T &Value);<br>+<br>+template<><br>+void SwapStruct(macho::RelocationEntry &H) {<br>+  SwapValue(H.Word0);<br>+  SwapValue(H.Word1);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::LoadCommand &L) {<br>+  SwapValue(L.Type);<br>+  SwapValue(L.Size);<br>+}<br>+<br>+template<><br>+void SwapStruct(SymbolTableEntryBase &S) {<br>+  SwapValue(S.StringIndex);<br>+  SwapValue(S.Flags);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::Section &S) {<br>+  SwapValue(S.Address);<br>+  SwapValue(S.Size);<br>+  SwapValue(S.Offset);<br>+  SwapValue(S.Align);<br>+  SwapValue(S.RelocationTableOffset);<br>+  SwapValue(S.NumRelocationTableEntries);<br>+  SwapValue(S.Flags);<br>+  SwapValue(S.Reserved1);<br>+  SwapValue(S.Reserved2);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::Section64 &S) {<br>+  SwapValue(S.Address);<br>+  SwapValue(S.Size);<br>+  SwapValue(S.Offset);<br>+  SwapValue(S.Align);<br>+  SwapValue(S.RelocationTableOffset);<br>+  SwapValue(S.NumRelocationTableEntries);<br>+  SwapValue(S.Flags);<br>+  SwapValue(S.Reserved1);<br>+  SwapValue(S.Reserved2);<br>+  SwapValue(S.Reserved3);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::SymbolTableEntry &S) {<br>+  SwapValue(S.StringIndex);<br>+  SwapValue(S.Flags);<br>+  SwapValue(S.Value);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::Symbol64TableEntry &S) {<br>+  SwapValue(S.StringIndex);<br>+  SwapValue(S.Flags);<br>+  SwapValue(S.Value);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::Header &H) {<br>+  SwapValue(H.Magic);<br>+  SwapValue(H.CPUType);<br>+  SwapValue(H.CPUSubtype);<br>+  SwapValue(H.FileType);<br>+  SwapValue(H.NumLoadCommands);<br>+  SwapValue(H.SizeOfLoadCommands);<br>+  SwapValue(H.Flags);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::SymtabLoadCommand &C) {<br>+  SwapValue(C.Type);<br>+  SwapValue(C.Size);<br>+  SwapValue(C.SymbolTableOffset);<br>+  SwapValue(C.NumSymbolTableEntries);<br>+  SwapValue(C.StringTableOffset);<br>+  SwapValue(C.StringTableSize);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::LinkeditDataLoadCommand &C) {<br>+  SwapValue(C.Type);<br>+  SwapValue(C.Size);<br>+  SwapValue(C.DataOffset);<br>+  SwapValue(C.DataSize);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::SegmentLoadCommand &C) {<br>+  SwapValue(C.Type);<br>+  SwapValue(C.Size);<br>+  SwapValue(C.VMAddress);<br>+  SwapValue(C.VMSize);<br>+  SwapValue(C.FileOffset);<br>+  SwapValue(C.FileSize);<br>+  SwapValue(C.MaxVMProtection);<br>+  SwapValue(C.InitialVMProtection);<br>+  SwapValue(C.NumSections);<br>+  SwapValue(C.Flags);<br>+}<br>+<br>+template<><br>+void SwapStruct(macho::Segment64LoadCommand &C) {<br>+  SwapValue(C.Type);<br>+  SwapValue(C.Size);<br>+  SwapValue(C.VMAddress);<br>+  SwapValue(C.VMSize);<br>+  SwapValue(C.FileOffset);<br>+  SwapValue(C.FileSize);<br>+  SwapValue(C.MaxVMProtection);<br>+  SwapValue(C.InitialVMProtection);<br>+  SwapValue(C.NumSections);<br>+  SwapValue(C.Flags);<br>+}<br>+<br>+static bool isSwappedEndian(const MachOObjectFile *O) {<br>+  return O->isLittleEndian() != sys::IsLittleEndianHost;<br>+}<br>+<br>+static macho::SegmentLoadCommand<br>+getSegmentLoadCommand(const MachOObjectFile *O,<br>+                      const MachOObjectFile::LoadCommandInfo &L) {<br>+  macho::SegmentLoadCommand Cmd;<br>+  memcpy(&Cmd, L.Ptr, sizeof(macho::SegmentLoadCommand));<br>+  if (isSwappedEndian(O))<br>+    SwapStruct(Cmd);<br>+  return Cmd;<br>+}<br>+<br>+static macho::Segment64LoadCommand<br>+getSegment64LoadCommand(const MachOObjectFile *O,<br>+                        const MachOObjectFile::LoadCommandInfo &L) {<br>+  macho::Segment64LoadCommand Cmd;<br>+  memcpy(&Cmd, L.Ptr, sizeof(macho::Segment64LoadCommand));<br>+  if (isSwappedEndian(O))<br>+    SwapStruct(Cmd);<br>+  return Cmd;<br>+}<br>+<br>+static uint32_t<br>+getSegmentLoadCommandNumSections(const MachOObjectFile *O,<br>+                                 const MachOObjectFile::LoadCommandInfo &L) {<br>+  if (O->is64Bit()) {<br>+    macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L);<br>+    return S.NumSections;<br>+  }<br>+  macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L);<br>+  return S.NumSections;<br>}<br><br>-bool MachOObjectFileBase::is64Bit() const {<br>-  return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);<br>+static const SectionBase *<br>+getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,<br>+               unsigned Sec) {<br>+  uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);<br>+<br>+  bool Is64 = O->is64Bit();<br>+  unsigned SegmentLoadSize = Is64 ? sizeof(macho::Segment64LoadCommand) :<br>+                                    sizeof(macho::SegmentLoadCommand);<br>+  unsigned SectionSize = Is64 ? sizeof(macho::Section64) :<br>+                                sizeof(macho::Section);<br>+<br>+  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;<br>+  return reinterpret_cast<const SectionBase*>(SectionAddr);<br>}<br><br>-void MachOObjectFileBase::ReadULEB128s(uint64_t Index,<br>-                                       SmallVectorImpl<uint64_t> &Out) const {<br>-  DataExtractor extractor(ObjectFile::getData(), true, 0);<br>+static const char *getPtr(const MachOObjectFile *O, size_t Offset) {<br>+  return O->getData().substr(Offset, 1).data();<br>+}<br><br>-  uint32_t offset = Index;<br>-  uint64_t data = 0;<br>-  while (uint64_t delta = extractor.getULEB128(&offset)) {<br>-    data += delta;<br>-    Out.push_back(data);<br>-  }<br>+static const char *getSymbolTableEntryPtr(const MachOObjectFile *O,<br>+                                          DataRefImpl DRI) {<br>+  macho::SymtabLoadCommand S = O->getSymtabLoadCommand();<br>+<br>+  unsigned Index = DRI.d.b;<br>+<br>+  unsigned SymbolTableEntrySize = O->is64Bit() ?<br>+    sizeof(macho::Symbol64TableEntry) :<br>+    sizeof(macho::SymbolTableEntry);<br>+<br>+  uint64_t Offset = S.SymbolTableOffset + Index * SymbolTableEntrySize;<br>+  return getPtr(O, Offset);<br>}<br><br>-unsigned MachOObjectFileBase::getHeaderSize() const {<br>-  return is64Bit() ? macho::Header64Size : macho::Header32Size;<br>+static SymbolTableEntryBase<br>+getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {<br>+  const char *P = getSymbolTableEntryPtr(O, DRI);<br>+  SymbolTableEntryBase Ret;<br>+  memcpy(&Ret, P, sizeof(SymbolTableEntryBase));<br>+  if (isSwappedEndian(O))<br>+    SwapStruct(Ret);<br>+<br>+  return Ret;<br>}<br><br>-StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {<br>-  return ObjectFile::getData().substr(Offset, Size);<br>+static StringRef parseSegmentOrSectionName(const char *P) {<br>+  if (P[15] == 0)<br>+    // Null terminated.<br>+    return P;<br>+  // Not null terminated, so this is a 16 char string.<br>+  return StringRef(P, 16);<br>}<br><br>-ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {<br>-  StringRef Magic = Buffer->getBuffer().slice(0, 4);<br>+// Helper to advance a section or symbol iterator multiple increments at a time.<br>+template<class T><br>+static error_code advance(T &it, size_t Val) {<br>  error_code ec;<br>-  ObjectFile *Ret;<br>-  if (Magic == "\xFE\xED\xFA\xCE")<br>-    Ret = new MachOObjectFileBE32(Buffer, ec);<br>-  else if (Magic == "\xCE\xFA\xED\xFE")<br>-    Ret = new MachOObjectFileLE32(Buffer, ec);<br>-  else if (Magic == "\xFE\xED\xFA\xCF")<br>-    Ret = new MachOObjectFileBE64(Buffer, ec);<br>-  else if (Magic == "\xCF\xFA\xED\xFE")<br>-    Ret = new MachOObjectFileLE64(Buffer, ec);<br>-  else<br>-    return NULL;<br>+  while (Val--) {<br>+    it.increment(ec);<br>+  }<br>+  return ec;<br>+}<br><br>-  if (ec)<br>-    return NULL;<br>-  return Ret;<br>+template<class T><br>+static void advanceTo(T &it, size_t Val) {<br>+  if (error_code ec = advance(it, Val))<br>+    report_fatal_error(ec.message());<br>+}<br>+<br>+static unsigned getCPUType(const MachOObjectFile *O) {<br>+  return O->getHeader().CPUType;<br>+}<br>+<br>+static void printRelocationTargetName(const MachOObjectFile *O,<br>+                                      const macho::RelocationEntry &RE,<br>+                                      raw_string_ostream &fmt) {<br>+  bool IsScattered = O->isRelocationScattered(RE);<br>+<br>+  // Target of a scattered relocation is an address.  In the interest of<br>+  // generating pretty output, scan through the symbol table looking for a<br>+  // symbol that aligns with that address.  If we find one, print it.<br>+  // Otherwise, we just print the hex address of the target.<br>+  if (IsScattered) {<br>+    uint32_t Val = O->getPlainRelocationSymbolNum(RE);<br>+<br>+    error_code ec;<br>+    for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols();<br>+         SI != SE; SI.increment(ec)) {<br>+      if (ec) report_fatal_error(ec.message());<br>+<br>+      uint64_t Addr;<br>+      StringRef Name;<br>+<br>+      if ((ec = SI->getAddress(Addr)))<br>+        report_fatal_error(ec.message());<br>+      if (Addr != Val) continue;<br>+      if ((ec = SI->getName(Name)))<br>+        report_fatal_error(ec.message());<br>+      fmt << Name;<br>+      return;<br>+    }<br>+<br>+    // If we couldn't find a symbol that this relocation refers to, try<br>+    // to find a section beginning instead.<br>+    for (section_iterator SI = O->begin_sections(), SE = O->end_sections();<br>+         SI != SE; SI.increment(ec)) {<br>+      if (ec) report_fatal_error(ec.message());<br>+<br>+      uint64_t Addr;<br>+      StringRef Name;<br>+<br>+      if ((ec = SI->getAddress(Addr)))<br>+        report_fatal_error(ec.message());<br>+      if (Addr != Val) continue;<br>+      if ((ec = SI->getName(Name)))<br>+        report_fatal_error(ec.message());<br>+      fmt << Name;<br>+      return;<br>+    }<br>+<br>+    fmt << format("0x%x", Val);<br>+    return;<br>+  }<br>+<br>+  StringRef S;<br>+  bool isExtern = O->getPlainRelocationExternal(RE);<br>+  uint64_t Val = O->getAnyRelocationAddress(RE);<br>+<br>+  if (isExtern) {<br>+    symbol_iterator SI = O->begin_symbols();<br>+    advanceTo(SI, Val);<br>+    SI->getName(S);<br>+  } else {<br>+    section_iterator SI = O->begin_sections();<br>+    advanceTo(SI, Val);<br>+    SI->getName(S);<br>+  }<br>+<br>+  fmt << S;<br>+}<br>+<br>+static uint32_t getPlainRelocationAddress(const macho::RelocationEntry &RE) {<br>+  return RE.Word0;<br>+}<br>+<br>+static unsigned<br>+getScatteredRelocationAddress(const macho::RelocationEntry &RE) {<br>+  return RE.Word0 & 0xffffff;<br>+}<br>+<br>+static bool getPlainRelocationPCRel(const MachOObjectFile *O,<br>+                                    const macho::RelocationEntry &RE) {<br>+  if (O->isLittleEndian())<br>+    return (RE.Word1 >> 24) & 1;<br>+  return (RE.Word1 >> 7) & 1;<br>+}<br>+<br>+static bool<br>+getScatteredRelocationPCRel(const MachOObjectFile *O,<br>+                            const macho::RelocationEntry &RE) {<br>+  return (RE.Word0 >> 30) & 1;<br>+}<br>+<br>+static unsigned getPlainRelocationLength(const MachOObjectFile *O,<br>+                                         const macho::RelocationEntry &RE) {<br>+  if (O->isLittleEndian())<br>+    return (RE.Word1 >> 25) & 3;<br>+  return (RE.Word1 >> 5) & 3;<br>+}<br>+<br>+static unsigned<br>+getScatteredRelocationLength(const macho::RelocationEntry &RE) {<br>+  return (RE.Word0 >> 28) & 3;<br>+}<br>+<br>+static unsigned getPlainRelocationType(const MachOObjectFile *O,<br>+                                       const macho::RelocationEntry &RE) {<br>+  if (O->isLittleEndian())<br>+    return RE.Word1 >> 28;<br>+  return RE.Word1 & 0xf;<br>+}<br>+<br>+static unsigned getScatteredRelocationType(const macho::RelocationEntry &RE) {<br>+  return (RE.Word0 >> 24) & 0xf;<br>+}<br>+<br>+static uint32_t getSectionFlags(const MachOObjectFile *O,<br>+                                DataRefImpl Sec) {<br>+  if (O->is64Bit()) {<br>+    macho::Section64 Sect = O->getSection64(Sec);<br>+    return Sect.Flags;<br>+  }<br>+  macho::Section Sect = O->getSection(Sec);<br>+  return Sect.Flags;<br>+}<br>+<br>+MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,<br>+                                 bool IsLittleEndian, bool Is64bits,<br>+                                 error_code &ec)<br>+    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),<br>+      SymtabLoadCmd(NULL) {<br>+  uint32_t LoadCommandCount = this->getHeader().NumLoadCommands;<br>+  macho::LoadCommandType SegmentLoadType = is64Bit() ?<br>+    macho::LCT_Segment64 : macho::LCT_Segment;<br>+<br>+  MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();<br>+  for (unsigned I = 0; I < LoadCommandCount; ++I) {<br>+    if (Load.C.Type == macho::LCT_Symtab) {<br>+      assert(!SymtabLoadCmd && "Multiple symbol tables");<br>+      SymtabLoadCmd = Load.Ptr;<br>+    }<br>+<br>+    if (Load.C.Type == SegmentLoadType) {<br>+      uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);<br>+      for (unsigned J = 0; J < NumSections; ++J) {<br>+        const SectionBase *Sec = getSectionBase(this, Load, J);<br>+        Sections.push_back(reinterpret_cast<const char*>(Sec));<br>+      }<br>+    }<br>+    Load = getNextLoadCommandInfo(Load);<br>+  }<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb,<br>+                                          SymbolRef &Res) const {<br>+  Symb.d.b++;<br>+  Res = SymbolRef(Symb, this);<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,<br>+                                          StringRef &Res) const {<br>+  macho::SymtabLoadCommand S = getSymtabLoadCommand();<br>+  const char *StringTable = getPtr(this, S.StringTableOffset);<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);<br>+  const char *Start = &StringTable[Entry.StringIndex];<br>+  Res = StringRef(Start);<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,<br>+                                             uint64_t &Res) const {<br>+  if (is64Bit()) {<br>+    macho::Symbol64TableEntry Entry = getSymbol64TableEntry(Symb);<br>+    Res = Entry.Value;<br>+  } else {<br>+    macho::SymbolTableEntry Entry = getSymbolTableEntry(Symb);<br>+    Res = Entry.Value;<br>+  }<br>+  return object_error::success;<br>+}<br>+<br>+error_code<br>+MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,<br>+                                     uint64_t &Res) const {<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);<br>+  getSymbolAddress(Symb, Res);<br>+  if (Entry.SectionIndex) {<br>+    uint64_t Delta;<br>+    DataRefImpl SecRel;<br>+    SecRel.d.a = Entry.SectionIndex-1;<br>+    if (is64Bit()) {<br>+      macho::Section64 Sec = getSection64(SecRel);<br>+      Delta = Sec.Offset - Sec.Address;<br>+    } else {<br>+      macho::Section Sec = getSection(SecRel);<br>+      Delta = Sec.Offset - Sec.Address;<br>+    }<br>+<br>+    Res += Delta;<br>+  }<br>+<br>+  return object_error::success;<br>}<br><br>-/*===-- Symbols -----------------------------------------------------------===*/<br>+error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,<br>+                                          uint64_t &Result) const {<br>+  uint64_t BeginOffset;<br>+  uint64_t EndOffset = 0;<br>+  uint8_t SectionIndex;<br>+<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);<br>+  uint64_t Value;<br>+  getSymbolAddress(DRI, Value);<br>+<br>+  BeginOffset = Value;<br>+<br>+  SectionIndex = Entry.SectionIndex;<br>+  if (!SectionIndex) {<br>+    uint32_t flags = SymbolRef::SF_None;<br>+    this->getSymbolFlags(DRI, flags);<br>+    if (flags & SymbolRef::SF_Common)<br>+      Result = Value;<br>+    else<br>+      Result = UnknownAddressOrSize;<br>+    return object_error::success;<br>+  }<br>+  // Unfortunately symbols are unsorted so we need to touch all<br>+  // symbols from load command<br>+  macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();<br>+  DRI.d.b = 0;<br>+  while (DRI.d.b <= Symtab.NumSymbolTableEntries) {<br>+    Entry = getSymbolTableEntryBase(this, DRI);<br>+    getSymbolAddress(DRI, Value);<br>+    if (Entry.SectionIndex == SectionIndex && Value > BeginOffset)<br>+      if (!EndOffset || Value < EndOffset)<br>+        EndOffset = Value;<br>+    DRI.d.b++;<br>+  }<br>+  if (!EndOffset) {<br>+    uint64_t Size;<br>+    DataRefImpl Sec;<br>+    Sec.d.a = SectionIndex-1;<br>+    getSectionSize(Sec, Size);<br>+    getSectionAddress(Sec, EndOffset);<br>+    EndOffset += Size;<br>+  }<br>+  Result = EndOffset - BeginOffset;<br>+  return object_error::success;<br>+}<br><br>-error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,<br>+error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,<br>+                                          SymbolRef::Type &Res) const {<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);<br>+  uint8_t n_type = Entry.Type;<br>+<br>+  Res = SymbolRef::ST_Other;<br>+<br>+  // If this is a STAB debugging symbol, we can do nothing more.<br>+  if (n_type & MachO::NlistMaskStab) {<br>+    Res = SymbolRef::ST_Debug;<br>+    return object_error::success;<br>+  }<br>+<br>+  switch (n_type & MachO::NlistMaskType) {<br>+    case MachO::NListTypeUndefined :<br>+      Res = SymbolRef::ST_Unknown;<br>+      break;<br>+    case MachO::NListTypeSection :<br>+      Res = SymbolRef::ST_Function;<br>+      break;<br>+  }<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,<br>+                                                char &Res) const {<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);<br>+  uint8_t Type = Entry.Type;<br>+  uint16_t Flags = Entry.Flags;<br>+<br>+  char Char;<br>+  switch (Type & macho::STF_TypeMask) {<br>+    case macho::STT_Undefined:<br>+      Char = 'u';<br>+      break;<br>+    case macho::STT_Absolute:<br>+    case macho::STT_Section:<br>+      Char = 's';<br>+      break;<br>+    default:<br>+      Char = '?';<br>+      break;<br>+  }<br>+<br>+  if (Flags & (macho::STF_External | macho::STF_PrivateExtern))<br>+    Char = toupper(static_cast<unsigned char>(Char));<br>+  Res = Char;<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,<br>+                                           uint32_t &Result) const {<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);<br>+<br>+  uint8_t MachOType = Entry.Type;<br>+  uint16_t MachOFlags = Entry.Flags;<br>+<br>+  // TODO: Correctly set SF_ThreadLocal<br>+  Result = SymbolRef::SF_None;<br>+<br>+  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)<br>+    Result |= SymbolRef::SF_Undefined;<br>+<br>+  if (MachOFlags & macho::STF_StabsEntryMask)<br>+    Result |= SymbolRef::SF_FormatSpecific;<br>+<br>+  if (MachOType & MachO::NlistMaskExternal) {<br>+    Result |= SymbolRef::SF_Global;<br>+    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)<br>+      Result |= SymbolRef::SF_Common;<br>+  }<br>+<br>+  if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))<br>+    Result |= SymbolRef::SF_Weak;<br>+<br>+  if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)<br>+    Result |= SymbolRef::SF_Absolute;<br>+<br>+  return object_error::success;<br>+}<br>+<br>+error_code<br>+MachOObjectFile::getSymbolSection(DataRefImpl Symb,<br>+                                  section_iterator &Res) const {<br>+  SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);<br>+  uint8_t index = Entry.SectionIndex;<br>+<br>+  if (index == 0) {<br>+    Res = end_sections();<br>+  } else {<br>+    DataRefImpl DRI;<br>+    DRI.d.a = index - 1;<br>+    Res = section_iterator(SectionRef(DRI, this));<br>+  }<br>+<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,<br>                                               uint64_t &Val) const {<br>-  report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");<br>+  report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");<br>}<br><br>-symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {<br>-  // TODO: implement<br>-  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");<br>+error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,<br>+                                           SectionRef &Res) const {<br>+  Sec.d.a++;<br>+  Res = SectionRef(Sec, this);<br>+  return object_error::success;<br>}<br><br>-symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const {<br>-  // TODO: implement<br>-  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");<br>+error_code<br>+MachOObjectFile::getSectionName(DataRefImpl Sec,<br>+                                    StringRef &Result) const {<br>+  ArrayRef<char> Raw = getSectionRawName(Sec);<br>+  Result = parseSegmentOrSectionName(Raw.data());<br>+  return object_error::success;<br>}<br><br>-library_iterator MachOObjectFileBase::begin_libraries_needed() const {<br>-  // TODO: implement<br>-  report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");<br>+error_code<br>+MachOObjectFile::getSectionAddress(DataRefImpl Sec,<br>+                                   uint64_t &Res) const {<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    Res = Sect.Address;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    Res = Sect.Address;<br>+  }<br>+  return object_error::success;<br>}<br><br>-library_iterator MachOObjectFileBase::end_libraries_needed() const {<br>-  // TODO: implement<br>-  report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");<br>+error_code<br>+MachOObjectFile::getSectionSize(DataRefImpl Sec,<br>+                                uint64_t &Res) const {<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    Res = Sect.Size;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    Res = Sect.Size;<br>+  }<br>+<br>+  return object_error::success;<br>}<br><br>-StringRef MachOObjectFileBase::getLoadName() const {<br>-  // TODO: Implement<br>-  report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase");<br>+error_code<br>+MachOObjectFile::getSectionContents(DataRefImpl Sec,<br>+                                    StringRef &Res) const {<br>+  uint32_t Offset;<br>+  uint64_t Size;<br>+<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    Offset = Sect.Offset;<br>+    Size = Sect.Size;<br>+  } else {<br>+    macho::Section Sect =getSection(Sec);<br>+    Offset = Sect.Offset;<br>+    Size = Sect.Size;<br>+  }<br>+<br>+  Res = this->getData().substr(Offset, Size);<br>+  return object_error::success;<br>}<br><br>-/*===-- Sections ----------------------------------------------------------===*/<br>+error_code<br>+MachOObjectFile::getSectionAlignment(DataRefImpl Sec,<br>+                                         uint64_t &Res) const {<br>+  uint32_t Align;<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    Align = Sect.Align;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    Align = Sect.Align;<br>+  }<br><br>-std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {<br>-  SectionList::const_iterator loc =<br>-    std::find(Sections.begin(), Sections.end(), Sec);<br>-  assert(loc != Sections.end() && "Sec is not a valid section!");<br>-  return std::distance(Sections.begin(), loc);<br>+  Res = uint64_t(1) << Align;<br>+  return object_error::success;<br>}<br><br>-StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {<br>-  if (P[15] == 0)<br>-    // Null terminated.<br>-    return P;<br>-  // Not null terminated, so this is a 16 char string.<br>-  return StringRef(P, 16);<br>+error_code<br>+MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {<br>+  uint32_t Flags = getSectionFlags(this, Sec);<br>+  Res = Flags & macho::SF_PureInstructions;<br>+  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,<br>+error_code MachOObjectFile::isSectionData(DataRefImpl DRI,<br>                                              bool &Result) const {<br>  // FIXME: Unimplemented.<br>  Result = false;<br>  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI,<br>+error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,<br>                                             bool &Result) const {<br>  // FIXME: Unimplemented.<br>  Result = false;<br>@@ -143,21 +723,30 @@ error_code MachOObjectFileBase::isSectio<br>}<br><br>error_code<br>-MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec,<br>+MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,<br>                                                   bool &Result) const {<br>  // FIXME: Unimplemented.<br>  Result = true;<br>  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec,<br>+error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,<br>                                                 bool &Result) const {<br>  // FIXME: Unimplemented.<br>  Result = false;<br>  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec,<br>+error_code<br>+MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {<br>+  uint32_t Flags = getSectionFlags(this, Sec);<br>+  unsigned SectionType = Flags & MachO::SectionFlagMaskSectionType;<br>+  Res = SectionType == MachO::SectionTypeZeroFill ||<br>+    SectionType == MachO::SectionTypeZeroFillLarge;<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,<br>                                                      bool &Result) const {<br>  // Consider using the code from isSectionText to look for __const sections.<br>  // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS<br>@@ -168,44 +757,752 @@ error_code MachOObjectFileBase::isSectio<br>  return object_error::success;<br>}<br><br>-relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const {<br>+error_code<br>+MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,<br>+                                       DataRefImpl Symb,<br>+                                       bool &Result) const {<br>+  SymbolRef::Type ST;<br>+  this->getSymbolType(Symb, ST);<br>+  if (ST == SymbolRef::ST_Unknown) {<br>+    Result = false;<br>+    return object_error::success;<br>+  }<br>+<br>+  uint64_t SectBegin, SectEnd;<br>+  getSectionAddress(Sec, SectBegin);<br>+  getSectionSize(Sec, SectEnd);<br>+  SectEnd += SectBegin;<br>+<br>+  uint64_t SymAddr;<br>+  getSymbolAddress(Symb, SymAddr);<br>+  Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);<br>+<br>+  return object_error::success;<br>+}<br>+<br>+relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {<br>  DataRefImpl ret;<br>-  ret.d.b = getSectionIndex(Sec);<br>+  ret.d.b = Sec.d.a;<br>  return relocation_iterator(RelocationRef(ret, this));<br>}<br><br>+relocation_iterator<br>+MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {<br>+  uint32_t LastReloc;<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    LastReloc = Sect.NumRelocationTableEntries;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    LastReloc = Sect.NumRelocationTableEntries;<br>+  }<br><br>-/*===-- Relocations -------------------------------------------------------===*/<br>+  DataRefImpl Ret;<br>+  Ret.d.a = LastReloc;<br>+  Ret.d.b = Sec.d.a;<br>+  return relocation_iterator(RelocationRef(Ret, this));<br>+}<br><br>-error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,<br>+error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,<br>                                                  RelocationRef &Res) const {<br>  ++Rel.d.a;<br>  Res = RelocationRef(Rel, this);<br>  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,<br>-                                               LibraryRef &Res) const {<br>-  report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");<br>+error_code<br>+MachOObjectFile::getRelocationAddress(DataRefImpl Rel,<br>+                                      uint64_t &Res) const {<br>+  uint64_t SectAddress;<br>+  DataRefImpl Sec;<br>+  Sec.d.a = Rel.d.b;<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    SectAddress = Sect.Address;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    SectAddress = Sect.Address;<br>+  }<br>+<br>+  macho::RelocationEntry RE = getRelocation(Rel);<br>+  uint64_t RelAddr = getAnyRelocationAddress(RE);<br>+  Res = SectAddress + RelAddr;<br>+  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData,<br>-                                               StringRef &Res) const {<br>-  report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");<br>+error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,<br>+                                                    uint64_t &Res) const {<br>+  macho::RelocationEntry RE = getRelocation(Rel);<br>+  Res = getAnyRelocationAddress(RE);<br>+  return object_error::success;<br>}<br><br>-error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel,<br>-                                                           int64_t &Res) const {<br>+error_code<br>+MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,<br>+                                         SymbolRef &Res) const {<br>+  macho::RelocationEntry RE = getRelocation(Rel);<br>+  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);<br>+  bool isExtern = getPlainRelocationExternal(RE);<br>+<br>+  DataRefImpl Sym;<br>+  if (isExtern) {<br>+    Sym.d.b = SymbolIdx;<br>+  }<br>+  Res = SymbolRef(Sym, this);<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,<br>+                                                  uint64_t &Res) const {<br>+  macho::RelocationEntry RE = getRelocation(Rel);<br>+  Res = getAnyRelocationType(RE);<br>+  return object_error::success;<br>+}<br>+<br>+error_code<br>+MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,<br>+                                       SmallVectorImpl<char> &Result) const {<br>+  StringRef res;<br>+  uint64_t RType;<br>+  getRelocationType(Rel, RType);<br>+<br>+  unsigned Arch = this->getArch();<br>+<br>+  switch (Arch) {<br>+    case Triple::x86: {<br>+      static const char *const Table[] =  {<br>+        "GENERIC_RELOC_VANILLA",<br>+        "GENERIC_RELOC_PAIR",<br>+        "GENERIC_RELOC_SECTDIFF",<br>+        "GENERIC_RELOC_PB_LA_PTR",<br>+        "GENERIC_RELOC_LOCAL_SECTDIFF",<br>+        "GENERIC_RELOC_TLV" };<br>+<br>+      if (RType > 6)<br>+        res = "Unknown";<br>+      else<br>+        res = Table[RType];<br>+      break;<br>+    }<br>+    case Triple::x86_64: {<br>+      static const char *const Table[] =  {<br>+        "X86_64_RELOC_UNSIGNED",<br>+        "X86_64_RELOC_SIGNED",<br>+        "X86_64_RELOC_BRANCH",<br>+        "X86_64_RELOC_GOT_LOAD",<br>+        "X86_64_RELOC_GOT",<br>+        "X86_64_RELOC_SUBTRACTOR",<br>+        "X86_64_RELOC_SIGNED_1",<br>+        "X86_64_RELOC_SIGNED_2",<br>+        "X86_64_RELOC_SIGNED_4",<br>+        "X86_64_RELOC_TLV" };<br>+<br>+      if (RType > 9)<br>+        res = "Unknown";<br>+      else<br>+        res = Table[RType];<br>+      break;<br>+    }<br>+    case Triple::arm: {<br>+      static const char *const Table[] =  {<br>+        "ARM_RELOC_VANILLA",<br>+        "ARM_RELOC_PAIR",<br>+        "ARM_RELOC_SECTDIFF",<br>+        "ARM_RELOC_LOCAL_SECTDIFF",<br>+        "ARM_RELOC_PB_LA_PTR",<br>+        "ARM_RELOC_BR24",<br>+        "ARM_THUMB_RELOC_BR22",<br>+        "ARM_THUMB_32BIT_BRANCH",<br>+        "ARM_RELOC_HALF",<br>+        "ARM_RELOC_HALF_SECTDIFF" };<br>+<br>+      if (RType > 9)<br>+        res = "Unknown";<br>+      else<br>+        res = Table[RType];<br>+      break;<br>+    }<br>+    case Triple::ppc: {<br>+      static const char *const Table[] =  {<br>+        "PPC_RELOC_VANILLA",<br>+        "PPC_RELOC_PAIR",<br>+        "PPC_RELOC_BR14",<br>+        "PPC_RELOC_BR24",<br>+        "PPC_RELOC_HI16",<br>+        "PPC_RELOC_LO16",<br>+        "PPC_RELOC_HA16",<br>+        "PPC_RELOC_LO14",<br>+        "PPC_RELOC_SECTDIFF",<br>+        "PPC_RELOC_PB_LA_PTR",<br>+        "PPC_RELOC_HI16_SECTDIFF",<br>+        "PPC_RELOC_LO16_SECTDIFF",<br>+        "PPC_RELOC_HA16_SECTDIFF",<br>+        "PPC_RELOC_JBSR",<br>+        "PPC_RELOC_LO14_SECTDIFF",<br>+        "PPC_RELOC_LOCAL_SECTDIFF" };<br>+<br>+      res = Table[RType];<br>+      break;<br>+    }<br>+    case Triple::UnknownArch:<br>+      res = "Unknown";<br>+      break;<br>+  }<br>+  Result.append(res.begin(), res.end());<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,<br>+                                                        int64_t &Res) const {<br>  Res = 0;<br>  return object_error::success;<br>}<br><br>+error_code<br>+MachOObjectFile::getRelocationValueString(DataRefImpl Rel,<br>+                                        SmallVectorImpl<char> &Result) const {<br>+  macho::RelocationEntry RE = getRelocation(Rel);<br>+<br>+  unsigned Arch = this->getArch();<br>+<br>+  std::string fmtbuf;<br>+  raw_string_ostream fmt(fmtbuf);<br>+  unsigned Type = this->getAnyRelocationType(RE);<br>+  bool IsPCRel = this->getAnyRelocationPCRel(RE);<br>+<br>+  // Determine any addends that should be displayed with the relocation.<br>+  // These require decoding the relocation type, which is triple-specific.<br>+<br>+  // X86_64 has entirely custom relocation types.<br>+  if (Arch == Triple::x86_64) {<br>+    bool isPCRel = getAnyRelocationPCRel(RE);<br>+<br>+    switch (Type) {<br>+      case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD<br>+      case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "@GOT";<br>+        if (isPCRel) fmt << "PCREL";<br>+        break;<br>+      }<br>+      case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR<br>+        DataRefImpl RelNext = Rel;<br>+        RelNext.d.a++;<br>+        macho::RelocationEntry RENext = getRelocation(RelNext);<br>+<br>+        // X86_64_SUBTRACTOR must be followed by a relocation of type<br>+        // X86_64_RELOC_UNSIGNED.<br>+        // NOTE: Scattered relocations don't exist on x86_64.<br>+        unsigned RType = getAnyRelocationType(RENext);<br>+        if (RType != 0)<br>+          report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "<br>+                             "X86_64_RELOC_SUBTRACTOR.");<br>+<br>+        // The X86_64_RELOC_UNSIGNED contains the minuend symbol,<br>+        // X86_64_SUBTRACTOR contains to the subtrahend.<br>+        printRelocationTargetName(this, RENext, fmt);<br>+        fmt << "-";<br>+        printRelocationTargetName(this, RE, fmt);<br>+        break;<br>+      }<br>+      case macho::RIT_X86_64_TLV:<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "@TLV";<br>+        if (isPCRel) fmt << "P";<br>+        break;<br>+      case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "-1";<br>+        break;<br>+      case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "-2";<br>+        break;<br>+      case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "-4";<br>+        break;<br>+      default:<br>+        printRelocationTargetName(this, RE, fmt);<br>+        break;<br>+    }<br>+  // X86 and ARM share some relocation types in common.<br>+  } else if (Arch == Triple::x86 || Arch == Triple::arm) {<br>+    // Generic relocation types...<br>+    switch (Type) {<br>+      case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info<br>+        return object_error::success;<br>+      case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF<br>+        DataRefImpl RelNext = Rel;<br>+        RelNext.d.a++;<br>+        macho::RelocationEntry RENext = getRelocation(RelNext);<br>+<br>+        // X86 sect diff's must be followed by a relocation of type<br>+        // GENERIC_RELOC_PAIR.<br>+        unsigned RType = getAnyRelocationType(RENext);<br>+<br>+        if (RType != 1)<br>+          report_fatal_error("Expected GENERIC_RELOC_PAIR after "<br>+                             "GENERIC_RELOC_SECTDIFF.");<br>+<br>+        printRelocationTargetName(this, RE, fmt);<br>+        fmt << "-";<br>+        printRelocationTargetName(this, RENext, fmt);<br>+        break;<br>+      }<br>+    }<br>+<br>+    if (Arch == Triple::x86) {<br>+      // All X86 relocations that need special printing were already<br>+      // handled in the generic code.<br>+      switch (Type) {<br>+        case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF<br>+          DataRefImpl RelNext = Rel;<br>+          RelNext.d.a++;<br>+          macho::RelocationEntry RENext = getRelocation(RelNext);<br>+<br>+          // X86 sect diff's must be followed by a relocation of type<br>+          // GENERIC_RELOC_PAIR.<br>+          unsigned RType = getAnyRelocationType(RENext);<br>+          if (RType != 1)<br>+            report_fatal_error("Expected GENERIC_RELOC_PAIR after "<br>+                               "GENERIC_RELOC_LOCAL_SECTDIFF.");<br>+<br>+          printRelocationTargetName(this, RE, fmt);<br>+          fmt << "-";<br>+          printRelocationTargetName(this, RENext, fmt);<br>+          break;<br>+        }<br>+        case macho::RIT_Generic_TLV: {<br>+          printRelocationTargetName(this, RE, fmt);<br>+          fmt << "@TLV";<br>+          if (IsPCRel) fmt << "P";<br>+          break;<br>+        }<br>+        default:<br>+          printRelocationTargetName(this, RE, fmt);<br>+      }<br>+    } else { // ARM-specific relocations<br>+      switch (Type) {<br>+        case macho::RIT_ARM_Half:             // ARM_RELOC_HALF<br>+        case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF<br>+          // Half relocations steal a bit from the length field to encode<br>+          // whether this is an upper16 or a lower16 relocation.<br>+          bool isUpper = getAnyRelocationLength(RE) >> 1;<br>+<br>+          if (isUpper)<br>+            fmt << ":upper16:(";<br>+          else<br>+            fmt << ":lower16:(";<br>+          printRelocationTargetName(this, RE, fmt);<br>+<br>+          DataRefImpl RelNext = Rel;<br>+          RelNext.d.a++;<br>+          macho::RelocationEntry RENext = getRelocation(RelNext);<br>+<br>+          // ARM half relocs must be followed by a relocation of type<br>+          // ARM_RELOC_PAIR.<br>+          unsigned RType = getAnyRelocationType(RENext);<br>+          if (RType != 1)<br>+            report_fatal_error("Expected ARM_RELOC_PAIR after "<br>+                               "GENERIC_RELOC_HALF");<br>+<br>+          // NOTE: The half of the target virtual address is stashed in the<br>+          // address field of the secondary relocation, but we can't reverse<br>+          // engineer the constant offset from it without decoding the movw/movt<br>+          // instruction to find the other half in its immediate field.<br>+<br>+          // ARM_RELOC_HALF_SECTDIFF encodes the second section in the<br>+          // symbol/section pointer of the follow-on relocation.<br>+          if (Type == macho::RIT_ARM_HalfDifference) {<br>+            fmt << "-";<br>+            printRelocationTargetName(this, RENext, fmt);<br>+          }<br>+<br>+          fmt << ")";<br>+          break;<br>+        }<br>+        default: {<br>+          printRelocationTargetName(this, RE, fmt);<br>+        }<br>+      }<br>+    }<br>+  } else<br>+    printRelocationTargetName(this, RE, fmt);<br>+<br>+  fmt.flush();<br>+  Result.append(fmtbuf.begin(), fmtbuf.end());<br>+  return object_error::success;<br>+}<br>+<br>+error_code<br>+MachOObjectFile::getRelocationHidden(DataRefImpl Rel,<br>+                                     bool &Result) const {<br>+  unsigned Arch = getArch();<br>+  uint64_t Type;<br>+  getRelocationType(Rel, Type);<br>+<br>+  Result = false;<br>+<br>+  // On arches that use the generic relocations, GENERIC_RELOC_PAIR<br>+  // is always hidden.<br>+  if (Arch == Triple::x86 || Arch == Triple::arm) {<br>+    if (Type == macho::RIT_Pair) Result = true;<br>+  } else if (Arch == Triple::x86_64) {<br>+    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows<br>+    // an X864_64_RELOC_SUBTRACTOR.<br>+    if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {<br>+      DataRefImpl RelPrev = Rel;<br>+      RelPrev.d.a--;<br>+      uint64_t PrevType;<br>+      getRelocationType(RelPrev, PrevType);<br>+      if (PrevType == macho::RIT_X86_64_Subtractor)<br>+        Result = true;<br>+    }<br>+  }<br>+<br>+  return object_error::success;<br>+}<br>+<br>+error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,<br>+                                               LibraryRef &Res) const {<br>+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");<br>+}<br>+<br>+error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,<br>+                                               StringRef &Res) const {<br>+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");<br>+}<br>+<br>+symbol_iterator MachOObjectFile::begin_symbols() const {<br>+  // DRI.d.a = segment number; DRI.d.b = symbol index.<br>+  DataRefImpl DRI;<br>+  return symbol_iterator(SymbolRef(DRI, this));<br>+}<br><br>-/*===-- Miscellaneous -----------------------------------------------------===*/<br>+symbol_iterator MachOObjectFile::end_symbols() const {<br>+  DataRefImpl DRI;<br>+  if (SymtabLoadCmd) {<br>+    macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();<br>+    DRI.d.b = Symtab.NumSymbolTableEntries;<br>+  }<br>+  return symbol_iterator(SymbolRef(DRI, this));<br>+}<br><br>-uint8_t MachOObjectFileBase::getBytesInAddress() const {<br>+symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {<br>+  // TODO: implement<br>+  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");<br>+}<br>+<br>+symbol_iterator MachOObjectFile::end_dynamic_symbols() const {<br>+  // TODO: implement<br>+  report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");<br>+}<br>+<br>+section_iterator MachOObjectFile::begin_sections() const {<br>+  DataRefImpl DRI;<br>+  return section_iterator(SectionRef(DRI, this));<br>+}<br>+<br>+section_iterator MachOObjectFile::end_sections() const {<br>+  DataRefImpl DRI;<br>+  DRI.d.a = Sections.size();<br>+  return section_iterator(SectionRef(DRI, this));<br>+}<br>+<br>+library_iterator MachOObjectFile::begin_libraries_needed() const {<br>+  // TODO: implement<br>+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");<br>+}<br>+<br>+library_iterator MachOObjectFile::end_libraries_needed() const {<br>+  // TODO: implement<br>+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");<br>+}<br>+<br>+uint8_t MachOObjectFile::getBytesInAddress() const {<br>  return is64Bit() ? 8 : 4;<br>}<br><br>+StringRef MachOObjectFile::getFileFormatName() const {<br>+  unsigned CPUType = getCPUType(this);<br>+  if (!is64Bit()) {<br>+    switch (CPUType) {<br>+    case llvm::MachO::CPUTypeI386:<br>+      return "Mach-O 32-bit i386";<br>+    case llvm::MachO::CPUTypeARM:<br>+      return "Mach-O arm";<br>+    case llvm::MachO::CPUTypePowerPC:<br>+      return "Mach-O 32-bit ppc";<br>+    default:<br>+      assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&<br>+             "64-bit object file when we're not 64-bit?");<br>+      return "Mach-O 32-bit unknown";<br>+    }<br>+  }<br>+<br>+  // Make sure the cpu type has the correct mask.<br>+  assert((CPUType & llvm::MachO::CPUArchABI64)<br>+<span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-converted-space"> </span>== llvm::MachO::CPUArchABI64 &&<br>+<span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>"32-bit object file when we're 64-bit?");<br>+<br>+  switch (CPUType) {<br>+  case llvm::MachO::CPUTypeX86_64:<br>+    return "Mach-O 64-bit x86-64";<br>+  case llvm::MachO::CPUTypePowerPC64:<br>+    return "Mach-O 64-bit ppc64";<br>+  default:<br>+    return "Mach-O 64-bit unknown";<br>+  }<br>+}<br>+<br>+unsigned MachOObjectFile::getArch() const {<br>+  switch (getCPUType(this)) {<br>+  case llvm::MachO::CPUTypeI386:<br>+    return Triple::x86;<br>+  case llvm::MachO::CPUTypeX86_64:<br>+    return Triple::x86_64;<br>+  case llvm::MachO::CPUTypeARM:<br>+    return Triple::arm;<br>+  case llvm::MachO::CPUTypePowerPC:<br>+    return Triple::ppc;<br>+  case llvm::MachO::CPUTypePowerPC64:<br>+    return Triple::ppc64;<br>+  default:<br>+    return Triple::UnknownArch;<br>+  }<br>+}<br>+<br>+StringRef MachOObjectFile::getLoadName() const {<br>+  // TODO: Implement<br>+  report_fatal_error("get_load_name() unimplemented in MachOObjectFile");<br>+}<br>+<br>+StringRef<br>+MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {<br>+  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);<br>+  return parseSegmentOrSectionName(Raw.data());<br>+}<br>+<br>+ArrayRef<char><br>+MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {<br>+  const SectionBase *Base =<br>+    reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);<br>+  return ArrayRef<char>(Base->Name);<br>+}<br>+<br>+ArrayRef<char><br>+MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {<br>+  const SectionBase *Base =<br>+    reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);<br>+  return ArrayRef<char>(Base->SegmentName);<br>+}<br>+<br>+bool<br>+MachOObjectFile::isRelocationScattered(const macho::RelocationEntry &RE)<br>+  const {<br>+  if (getCPUType(this) == llvm::MachO::CPUTypeX86_64)<br>+    return false;<br>+  return getPlainRelocationAddress(RE) & macho::RF_Scattered;<br>+}<br>+<br>+unsigned MachOObjectFile::getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const {<br>+  if (isLittleEndian())<br>+    return RE.Word1 & 0xffffff;<br>+  return RE.Word1 >> 8;<br>+}<br>+<br>+bool MachOObjectFile::getPlainRelocationExternal(const macho::RelocationEntry &RE) const {<br>+  if (isLittleEndian())<br>+    return (RE.Word1 >> 27) & 1;<br>+  return (RE.Word1 >> 4) & 1;<br>+}<br>+<br>+bool<br>+MachOObjectFile::getScatteredRelocationScattered(const macho::RelocationEntry &RE) const {<br>+  return RE.Word0 >> 31;<br>+}<br>+<br>+uint32_t<br>+MachOObjectFile::getScatteredRelocationValue(const macho::RelocationEntry &RE) const {<br>+  return RE.Word1;<br>+}<br>+<br>+unsigned<br>+MachOObjectFile::getAnyRelocationAddress(const macho::RelocationEntry &RE) const {<br>+  if (isRelocationScattered(RE))<br>+    return getScatteredRelocationAddress(RE);<br>+  return getPlainRelocationAddress(RE);<br>+}<br>+<br>+unsigned<br>+MachOObjectFile::getAnyRelocationPCRel(const macho::RelocationEntry &RE) const {<br>+  if (isRelocationScattered(RE))<br>+    return getScatteredRelocationPCRel(this, RE);<br>+  return getPlainRelocationPCRel(this, RE);<br>+}<br>+<br>+unsigned<br>+MachOObjectFile::getAnyRelocationLength(const macho::RelocationEntry &RE) const {<br>+  if (isRelocationScattered(RE))<br>+    return getScatteredRelocationLength(RE);<br>+  return getPlainRelocationLength(this, RE);<br>+}<br>+<br>+unsigned<br>+MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const {<br>+  if (isRelocationScattered(RE))<br>+    return getScatteredRelocationType(RE);<br>+  return getPlainRelocationType(this, RE);<br>+}<br>+<br>+MachOObjectFile::LoadCommandInfo<br>+MachOObjectFile::getFirstLoadCommandInfo() const {<br>+  MachOObjectFile::LoadCommandInfo Load;<br>+<br>+  unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size;<br>+  Load.Ptr = getPtr(this, HeaderSize);<br>+  memcpy(&Load.C, Load.Ptr, sizeof(macho::LoadCommand));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Load.C);<br>+  return Load;<br>+}<br>+<br>+MachOObjectFile::LoadCommandInfo<br>+MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {<br>+  MachOObjectFile::LoadCommandInfo Next;<br>+  Next.Ptr = L.Ptr + L.C.Size;<br>+  memcpy(&Next.C, Next.Ptr, sizeof(macho::LoadCommand));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Next.C);<br>+  return Next;<br>+}<br>+<br>+macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const {<br>+  const SectionBase *Addr =<br>+    reinterpret_cast<const SectionBase*>(Sections[DRI.d.a]);<br>+  macho::Section Ret;<br>+  memcpy(&Ret, Addr, sizeof(macho::Section));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Ret);<br>+  return Ret;<br>+}<br>+<br>+macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const {<br>+  const SectionBase *Addr =<br>+    reinterpret_cast<const SectionBase*>(Sections[DRI.d.a]);<br>+  macho::Section64 Ret;<br>+  memcpy(&Ret, Addr, sizeof(macho::Section64));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Ret);<br>+  return Ret;<br>+}<br>+<br>+macho::SymbolTableEntry<br>+MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {<br>+  const char *P = getSymbolTableEntryPtr(this, DRI);<br>+  macho::SymbolTableEntry Ret;<br>+  memcpy(&Ret, P, sizeof(macho::SymbolTableEntry));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Ret);<br>+  return Ret;<br>+}<br>+<br>+macho::Symbol64TableEntry<br>+MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {<br>+  const char *P = getSymbolTableEntryPtr(this, DRI);<br>+  macho::Symbol64TableEntry Ret;<br>+  memcpy(&Ret, P, sizeof(macho::Symbol64TableEntry));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Ret);<br>+  return Ret;<br>+}<br>+<br>+macho::LinkeditDataLoadCommand<br>+MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const {<br>+  macho::LinkeditDataLoadCommand Cmd;<br>+  memcpy(&Cmd, L.Ptr, sizeof(macho::LinkeditDataLoadCommand));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Cmd);<br>+  return Cmd;<br>+}<br>+<br>+macho::RelocationEntry<br>+MachOObjectFile::getRelocation(DataRefImpl Rel) const {<br>+  uint32_t RelOffset;<br>+  DataRefImpl Sec;<br>+  Sec.d.a = Rel.d.b;<br>+  if (is64Bit()) {<br>+    macho::Section64 Sect = getSection64(Sec);<br>+    RelOffset = Sect.RelocationTableOffset;<br>+  } else {<br>+    macho::Section Sect = getSection(Sec);<br>+    RelOffset = Sect.RelocationTableOffset;<br>+  }<br>+<br>+  uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry);<br>+<br>+  macho::RelocationEntry Ret;<br>+  memcpy(&Ret, getPtr(this, Offset), sizeof(macho::RelocationEntry));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Ret);<br>+<br>+  return Ret;<br>+}<br>+<br>+macho::Header MachOObjectFile::getHeader() const {<br>+  macho::Header H;<br>+  memcpy(&H, getPtr(this, 0), sizeof(macho::Header));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(H);<br>+  return H;<br>+}<br>+<br>+macho::SymtabLoadCommand<br>+MachOObjectFile::getSymtabLoadCommand() const {<br>+  macho::SymtabLoadCommand Cmd;<br>+  memcpy(&Cmd, SymtabLoadCmd, sizeof(macho::SymtabLoadCommand));<br>+  if (isSwappedEndian(this))<br>+    SwapStruct(Cmd);<br>+  return Cmd;<br>+}<br>+<br>+bool MachOObjectFile::is64Bit() const {<br>+  return getType() == getMachOType(false, true) ||<br>+    getType() == getMachOType(true, true);<br>+}<br>+<br>+void MachOObjectFile::ReadULEB128s(uint64_t Index,<br>+                                   SmallVectorImpl<uint64_t> &Out) const {<br>+  DataExtractor extractor(ObjectFile::getData(), true, 0);<br>+<br>+  uint32_t offset = Index;<br>+  uint64_t data = 0;<br>+  while (uint64_t delta = extractor.getULEB128(&offset)) {<br>+    data += delta;<br>+    Out.push_back(data);<br>+  }<br>+}<br>+<br>+ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {<br>+  StringRef Magic = Buffer->getBuffer().slice(0, 4);<br>+  error_code ec;<br>+  ObjectFile *Ret;<br>+  if (Magic == "\xFE\xED\xFA\xCE")<br>+    Ret = new MachOObjectFile(Buffer, false, false, ec);<br>+  else if (Magic == "\xCE\xFA\xED\xFE")<br>+    Ret = new MachOObjectFile(Buffer, true, false, ec);<br>+  else if (Magic == "\xFE\xED\xFA\xCF")<br>+    Ret = new MachOObjectFile(Buffer, false, true, ec);<br>+  else if (Magic == "\xCF\xFA\xED\xFE")<br>+    Ret = new MachOObjectFile(Buffer, true, true, ec);<br>+  else<br>+    return NULL;<br>+<br>+  if (ec)<br>+    return NULL;<br>+  return Ret;<br>+}<br>+<br>} // end namespace object<br>} // end namespace llvm<br><br>Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm?rev=179778&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm?rev=179778&view=auto</a><br>==============================================================================<br>Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm Thu Apr 18 13:08:55 2013 differ<br><br>Modified: llvm/trunk/test/tools/llvm-readobj/relocations.test<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/test/tools/llvm-readobj/relocations.test (original)<br>+++ llvm/trunk/test/tools/llvm-readobj/relocations.test Thu Apr 18 13:08:55 2013<br>@@ -10,6 +10,8 @@ RUN: llvm-readobj -r %p/Inputs/trivial.o<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC<br>RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc64 \<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC64<br>+RUN: llvm-readobj -r -expand-relocs %p/Inputs/trivial.obj.macho-arm \<br>+RUN:   | FileCheck %s -check-prefix MACHO-ARM<br><br>COFF:      Relocations [<br>COFF-NEXT:   Section (1) .text {<br>@@ -82,3 +84,90 @@ MACHO-PPC64-NEXT:   Section __la_symbol_<br>MACHO-PPC64-NEXT:     0x0 0 3 1 0 dyld_stub_binding_helper<br>MACHO-PPC64-NEXT:   }<br>MACHO-PPC64-NEXT: ]<br>+<br>+<br>+MACHO-ARM:       Relocations [<br>+MACHO-ARM-NEXT:    Section __text {<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x38<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 2<br>+MACHO-ARM-NEXT:        Extern: N/A<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_SECTDIFF (2)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 1<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x0<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 2<br>+MACHO-ARM-NEXT:        Extern: N/A<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 1<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x20<br>+MACHO-ARM-NEXT:        PCRel: 1<br>+MACHO-ARM-NEXT:        Length: 2<br>+MACHO-ARM-NEXT:        Extern: 1<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_BR24 (5)<br>+MACHO-ARM-NEXT:        Symbol: _g<br>+MACHO-ARM-NEXT:        Scattered: 0<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x1C<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 1<br>+MACHO-ARM-NEXT:        Extern: 1<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_HALF (8)<br>+MACHO-ARM-NEXT:        Symbol: _g<br>+MACHO-ARM-NEXT:        Scattered: 0<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x0<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 1<br>+MACHO-ARM-NEXT:        Extern: 0<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 0<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x18<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 0<br>+MACHO-ARM-NEXT:        Extern: 1<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_HALF (8)<br>+MACHO-ARM-NEXT:        Symbol: _g<br>+MACHO-ARM-NEXT:        Scattered: 0<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x0<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 0<br>+MACHO-ARM-NEXT:        Extern: 0<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 0<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0xC<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 2<br>+MACHO-ARM-NEXT:        Extern: N/A<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_SECTDIFF (2)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 1<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:      Relocation {<br>+MACHO-ARM-NEXT:        Offset: 0x0<br>+MACHO-ARM-NEXT:        PCRel: 0<br>+MACHO-ARM-NEXT:        Length: 2<br>+MACHO-ARM-NEXT:        Extern: N/A<br>+MACHO-ARM-NEXT:        Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:        Symbol: _b<br>+MACHO-ARM-NEXT:        Scattered: 1<br>+MACHO-ARM-NEXT:      }<br>+MACHO-ARM-NEXT:    }<br>+MACHO-ARM-NEXT:  ]<br><br>Modified: llvm/trunk/test/tools/llvm-readobj/sections-ext.test<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/test/tools/llvm-readobj/sections-ext.test (original)<br>+++ llvm/trunk/test/tools/llvm-readobj/sections-ext.test Thu Apr 18 13:08:55 2013<br>@@ -10,6 +10,8 @@ RUN: llvm-readobj -s -st -sr -sd %p/Inpu<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC<br>RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc64 \<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC64<br>+RUN: llvm-readobj -expand-relocs -s -st -sr -sd %p/Inputs/trivial.obj.macho-arm \<br>+RUN:   | FileCheck %s -check-prefix MACHO-ARM<br><br>COFF:      Sections [<br>COFF-NEXT:   Section {<br>@@ -562,3 +564,278 @@ MACHO-PPC64-NEXT:       0000: 00000000 0<br>MACHO-PPC64-NEXT:     )<br>MACHO-PPC64-NEXT:   }<br>MACHO-PPC64-NEXT: ]<br>+<br>+MACHO-ARM:      Sections [<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 0<br>+MACHO-ARM-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x0<br>+MACHO-ARM-NEXT:     Size: 0x3C<br>+MACHO-ARM-NEXT:     Offset: 664<br>+MACHO-ARM-NEXT:     Alignment: 2<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x2E0<br>+MACHO-ARM-NEXT:     RelocationCount: 9<br>+MACHO-ARM-NEXT:     Type: 0x0<br>+MACHO-ARM-NEXT:     Attributes [ (0x800004)<br>+MACHO-ARM-NEXT:       PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:       SomeInstructions (0x4)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x38<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 2<br>+MACHO-ARM-NEXT:         Extern: N/A<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_SECTDIFF (2)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 1<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x0<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 2<br>+MACHO-ARM-NEXT:         Extern: N/A<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 1<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x20<br>+MACHO-ARM-NEXT:         PCRel: 1<br>+MACHO-ARM-NEXT:         Length: 2<br>+MACHO-ARM-NEXT:         Extern: 1<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_BR24 (5)<br>+MACHO-ARM-NEXT:         Symbol: _g<br>+MACHO-ARM-NEXT:         Scattered: 0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x1C<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 1<br>+MACHO-ARM-NEXT:         Extern: 1<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_HALF (8)<br>+MACHO-ARM-NEXT:         Symbol: _g<br>+MACHO-ARM-NEXT:         Scattered: 0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x0<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 1<br>+MACHO-ARM-NEXT:         Extern: 0<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x18<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 0<br>+MACHO-ARM-NEXT:         Extern: 1<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_HALF (8)<br>+MACHO-ARM-NEXT:         Symbol: _g<br>+MACHO-ARM-NEXT:         Scattered: 0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x0<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 0<br>+MACHO-ARM-NEXT:         Extern: 0<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0xC<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 2<br>+MACHO-ARM-NEXT:         Extern: N/A<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_SECTDIFF (2)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 1<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Relocation {<br>+MACHO-ARM-NEXT:         Offset: 0x0<br>+MACHO-ARM-NEXT:         PCRel: 0<br>+MACHO-ARM-NEXT:         Length: 2<br>+MACHO-ARM-NEXT:         Extern: N/A<br>+MACHO-ARM-NEXT:         Type: ARM_RELOC_PAIR (1)<br>+MACHO-ARM-NEXT:         Symbol: _b<br>+MACHO-ARM-NEXT:         Scattered: 1<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:       Symbol {<br>+MACHO-ARM-NEXT:         Name: _f (4)<br>+MACHO-ARM-NEXT:         Type: 0xF<br>+MACHO-ARM-NEXT:         Section: __text (0x1)<br>+MACHO-ARM-NEXT:         RefType: UndefinedNonLazy (0x0)<br>+MACHO-ARM-NEXT:         Flags [ (0x0)<br>+MACHO-ARM-NEXT:         ]<br>+MACHO-ARM-NEXT:         Value: 0x10<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:       Symbol {<br>+MACHO-ARM-NEXT:         Name: _h (1)<br>+MACHO-ARM-NEXT:         Type: 0xF<br>+MACHO-ARM-NEXT:         Section: __text (0x1)<br>+MACHO-ARM-NEXT:         RefType: UndefinedNonLazy (0x0)<br>+MACHO-ARM-NEXT:         Flags [ (0x0)<br>+MACHO-ARM-NEXT:         ]<br>+MACHO-ARM-NEXT:         Value: 0x0<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:       0000: 04009FE5 00009FE7 1EFF2FE1 38000000  |........../.8...|<br>+MACHO-ARM-NEXT:       0010: 80402DE9 0D70A0E1 000000E3 000040E3  |.@-..p........@.|<br>+MACHO-ARM-NEXT:       0020: F6FFFFEB 0C009FE5 00009FE7 000090E5  |................|<br>+MACHO-ARM-NEXT:       0030: 8040BDE8 1EFF2FE1 10000000           |.@..../.....|<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 1<br>+MACHO-ARM-NEXT:     Name: __textcoal_nt (5F 5F 74 65 78 74 63 6F 61 6C 5F 6E 74 00 00 00)<br>+MACHO-ARM-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x3C<br>+MACHO-ARM-NEXT:     Size: 0x0<br>+MACHO-ARM-NEXT:     Offset: 724<br>+MACHO-ARM-NEXT:     Alignment: 0<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0xB<br>+MACHO-ARM-NEXT:     Attributes [ (0x800000)<br>+MACHO-ARM-NEXT:       PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 2<br>+MACHO-ARM-NEXT:     Name: __const_coal (5F 5F 63 6F 6E 73 74 5F 63 6F 61 6C 00 00 00 00)<br>+MACHO-ARM-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x3C<br>+MACHO-ARM-NEXT:     Size: 0x0<br>+MACHO-ARM-NEXT:     Offset: 724<br>+MACHO-ARM-NEXT:     Alignment: 0<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0xB<br>+MACHO-ARM-NEXT:     Attributes [ (0x0)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 3<br>+MACHO-ARM-NEXT:     Name: __picsymbolstub4 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 34)<br>+MACHO-ARM-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x3C<br>+MACHO-ARM-NEXT:     Size: 0x0<br>+MACHO-ARM-NEXT:     Offset: 724<br>+MACHO-ARM-NEXT:     Alignment: 0<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0x8<br>+MACHO-ARM-NEXT:     Attributes [ (0x0)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x10<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 4<br>+MACHO-ARM-NEXT:     Name: __StaticInit (5F 5F 53 74 61 74 69 63 49 6E 69 74 00 00 00 00)<br>+MACHO-ARM-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x3C<br>+MACHO-ARM-NEXT:     Size: 0x0<br>+MACHO-ARM-NEXT:     Offset: 724<br>+MACHO-ARM-NEXT:     Alignment: 0<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0x0<br>+MACHO-ARM-NEXT:     Attributes [ (0x800000)<br>+MACHO-ARM-NEXT:       PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 5<br>+MACHO-ARM-NEXT:     Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x3C<br>+MACHO-ARM-NEXT:     Size: 0x4<br>+MACHO-ARM-NEXT:     Offset: 724<br>+MACHO-ARM-NEXT:     Alignment: 2<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0x0<br>+MACHO-ARM-NEXT:     Attributes [ (0x0)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:       Symbol {<br>+MACHO-ARM-NEXT:         Name: _b (10)<br>+MACHO-ARM-NEXT:         Type: 0xF<br>+MACHO-ARM-NEXT:         Section: __data (0x6)<br>+MACHO-ARM-NEXT:         RefType: UndefinedNonLazy (0x0)<br>+MACHO-ARM-NEXT:         Flags [ (0x0)<br>+MACHO-ARM-NEXT:         ]<br>+MACHO-ARM-NEXT:         Value: 0x3C<br>+MACHO-ARM-NEXT:       }<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:       0000: 2A000000                             |*...|<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:     Index: 6<br>+MACHO-ARM-NEXT:     Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)<br>+MACHO-ARM-NEXT:     Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:     Address: 0x40<br>+MACHO-ARM-NEXT:     Size: 0x8<br>+MACHO-ARM-NEXT:     Offset: 728<br>+MACHO-ARM-NEXT:     Alignment: 2<br>+MACHO-ARM-NEXT:     RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:     RelocationCount: 0<br>+MACHO-ARM-NEXT:     Type: 0x6<br>+MACHO-ARM-NEXT:     Attributes [ (0x0)<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Reserved1: 0x0<br>+MACHO-ARM-NEXT:     Reserved2: 0x0<br>+MACHO-ARM-NEXT:     Relocations [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     Symbols [<br>+MACHO-ARM-NEXT:     ]<br>+MACHO-ARM-NEXT:     SectionData (<br>+MACHO-ARM-NEXT:       0000: 00000000 00000000                    |........|<br>+MACHO-ARM-NEXT:     )<br>+MACHO-ARM-NEXT:   }<br>+MACHO-ARM-NEXT: ]<br><br>Modified: llvm/trunk/test/tools/llvm-readobj/sections.test<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections.test?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections.test?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/test/tools/llvm-readobj/sections.test (original)<br>+++ llvm/trunk/test/tools/llvm-readobj/sections.test Thu Apr 18 13:08:55 2013<br>@@ -10,6 +10,8 @@ RUN: llvm-readobj -s %p/Inputs/trivial.o<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC<br>RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \<br>RUN:   | FileCheck %s -check-prefix MACHO-PPC64<br>+RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-arm \<br>+RUN:   | FileCheck %s -check-prefix MACHO-ARM<br><br>COFF:      Sections [<br>COFF-NEXT:   Section {<br>@@ -329,3 +331,122 @@ MACHO-PPC64-NEXT:     Reserved1: 0x2<br>MACHO-PPC64-NEXT:     Reserved2: 0x0<br>MACHO-PPC64-NEXT:   }<br>MACHO-PPC64-NEXT: ]<br>+<br>+MACHO-ARM:      Sections [<br>+MACHO-ARM-NEXT:   Section {<br>+MACHO-ARM-NEXT:    Index: 0<br>+MACHO-ARM-NEXT:    Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x0<br>+MACHO-ARM-NEXT:    Size: 0x3C<br>+MACHO-ARM-NEXT:    Offset: 664<br>+MACHO-ARM-NEXT:    Alignment: 2<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x2E0<br>+MACHO-ARM-NEXT:    RelocationCount: 9<br>+MACHO-ARM-NEXT:    Type: 0x0<br>+MACHO-ARM-NEXT:    Attributes [ (0x800004)<br>+MACHO-ARM-NEXT:      PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:      SomeInstructions (0x4)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 1<br>+MACHO-ARM-NEXT:    Name: __textcoal_nt (5F 5F 74 65 78 74 63 6F 61 6C 5F 6E 74 00 00 00)<br>+MACHO-ARM-NEXT:    Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x3C<br>+MACHO-ARM-NEXT:    Size: 0x0<br>+MACHO-ARM-NEXT:    Offset: 724<br>+MACHO-ARM-NEXT:    Alignment: 0<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0xB<br>+MACHO-ARM-NEXT:    Attributes [ (0x800000)<br>+MACHO-ARM-NEXT:      PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 2<br>+MACHO-ARM-NEXT:    Name: __const_coal (5F 5F 63 6F 6E 73 74 5F 63 6F 61 6C 00 00 00 00)<br>+MACHO-ARM-NEXT:    Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x3C<br>+MACHO-ARM-NEXT:    Size: 0x0<br>+MACHO-ARM-NEXT:    Offset: 724<br>+MACHO-ARM-NEXT:    Alignment: 0<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0xB<br>+MACHO-ARM-NEXT:    Attributes [ (0x0)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 3<br>+MACHO-ARM-NEXT:    Name: __picsymbolstub4 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 34)<br>+MACHO-ARM-NEXT:    Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x3C<br>+MACHO-ARM-NEXT:    Size: 0x0<br>+MACHO-ARM-NEXT:    Offset: 724<br>+MACHO-ARM-NEXT:    Alignment: 0<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0x8<br>+MACHO-ARM-NEXT:    Attributes [ (0x0)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x10<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 4<br>+MACHO-ARM-NEXT:    Name: __StaticInit (5F 5F 53 74 61 74 69 63 49 6E 69 74 00 00 00 00)<br>+MACHO-ARM-NEXT:    Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x3C<br>+MACHO-ARM-NEXT:    Size: 0x0<br>+MACHO-ARM-NEXT:    Offset: 724<br>+MACHO-ARM-NEXT:    Alignment: 0<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0x0<br>+MACHO-ARM-NEXT:    Attributes [ (0x800000)<br>+MACHO-ARM-NEXT:      PureInstructions (0x800000)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 5<br>+MACHO-ARM-NEXT:    Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x3C<br>+MACHO-ARM-NEXT:    Size: 0x4<br>+MACHO-ARM-NEXT:    Offset: 724<br>+MACHO-ARM-NEXT:    Alignment: 2<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0x0<br>+MACHO-ARM-NEXT:    Attributes [ (0x0)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:  Section {<br>+MACHO-ARM-NEXT:    Index: 6<br>+MACHO-ARM-NEXT:    Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)<br>+MACHO-ARM-NEXT:    Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)<br>+MACHO-ARM-NEXT:    Address: 0x40<br>+MACHO-ARM-NEXT:    Size: 0x8<br>+MACHO-ARM-NEXT:    Offset: 728<br>+MACHO-ARM-NEXT:    Alignment: 2<br>+MACHO-ARM-NEXT:    RelocationOffset: 0x0<br>+MACHO-ARM-NEXT:    RelocationCount: 0<br>+MACHO-ARM-NEXT:    Type: 0x6<br>+MACHO-ARM-NEXT:    Attributes [ (0x0)<br>+MACHO-ARM-NEXT:    ]<br>+MACHO-ARM-NEXT:    Reserved1: 0x0<br>+MACHO-ARM-NEXT:    Reserved2: 0x0<br>+MACHO-ARM-NEXT:  }<br>+MACHO-ARM-NEXT:]<br><br>Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)<br>+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Thu Apr 18 13:08:55 2013<br>@@ -53,7 +53,7 @@ static cl::opt<bool><br>static cl::opt<std::string><br>  DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));<br><br>-static const Target *GetTarget(const MachOObjectFileBase *MachOObj) {<br>+static const Target *GetTarget(const MachOObjectFile *MachOObj) {<br>  // Figure out the target triple.<br>  if (TripleName.empty()) {<br>    llvm::Triple TT("unknown-unknown-unknown");<br>@@ -93,7 +93,7 @@ struct SymbolSorter {<br><br>// Print additional information about an address, if available.<br>static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,<br>-                        const MachOObjectFileBase *MachOObj, raw_ostream &OS) {<br>+                        const MachOObjectFile *MachOObj, raw_ostream &OS) {<br>  for (unsigned i = 0; i != Sections.size(); ++i) {<br>    uint64_t SectAddr = 0, SectSize = 0;<br>    Sections[i].getAddress(SectAddr);<br>@@ -184,14 +184,12 @@ static void emitDOTFile(const char *File<br>  Out << "}\n";<br>}<br><br>-template<endianness E><br>static void<br>-getSectionsAndSymbols(const typename MachOObjectFileMiddle<E>::Header *Header,<br>-                      const MachOObjectFileMiddle<E> *MachOObj,<br>+getSectionsAndSymbols(const macho::Header Header,<br>+                      MachOObjectFile *MachOObj,<br>                      std::vector<SectionRef> &Sections,<br>                      std::vector<SymbolRef> &Symbols,<br>                      SmallVectorImpl<uint64_t> &FoundFns) {<br>-  typedef MachOObjectFileMiddle<E> ObjType;<br>  error_code ec;<br>  for (symbol_iterator SI = MachOObj->begin_symbols(),<br>       SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))<br>@@ -205,23 +203,23 @@ getSectionsAndSymbols(const typename Mac<br>    Sections.push_back(*SI);<br>  }<br><br>-  for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {<br>-    const typename ObjType::LoadCommand *Command =<br>-      MachOObj->getLoadCommandInfo(i);<br>-    if (Command->Type == macho::LCT_FunctionStarts) {<br>+  MachOObjectFile::LoadCommandInfo Command =<br>+    MachOObj->getFirstLoadCommandInfo();<br>+  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {<br>+    if (Command.C.Type == macho::LCT_FunctionStarts) {<br>      // We found a function starts segment, parse the addresses for later<br>      // consumption.<br>-      const typename ObjType::LinkeditDataLoadCommand *LLC =<br>-    reinterpret_cast<const typename ObjType::LinkeditDataLoadCommand*>(Command);<br>+      macho::LinkeditDataLoadCommand LLC =<br>+        MachOObj->getLinkeditDataLoadCommand(Command);<br><br>-      MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);<br>+      MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);<br>    }<br>+    Command = MachOObj->getNextLoadCommandInfo(Command);<br>  }<br>}<br><br>-template<endianness E><br>static void DisassembleInputMachO2(StringRef Filename,<br>-                                   MachOObjectFileMiddle<E> *MachOOF);<br>+                                   MachOObjectFile *MachOOF);<br><br>void llvm::DisassembleInputMachO(StringRef Filename) {<br>  OwningPtr<MemoryBuffer> Buff;<br>@@ -231,20 +229,14 @@ void llvm::DisassembleInputMachO(StringR<br>    return;<br>  }<br><br>-  OwningPtr<MachOObjectFileBase> MachOOF(static_cast<MachOObjectFileBase*>(<br>+  OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(<br>        ObjectFile::createMachOObjectFile(Buff.take())));<br><br>-  if (MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachOOF.get())) {<br>-    DisassembleInputMachO2(Filename, O);<br>-    return;<br>-  }<br>-  MachOObjectFileBE *O = cast<MachOObjectFileBE>(MachOOF.get());<br>-  DisassembleInputMachO2(Filename, O);<br>+  DisassembleInputMachO2(Filename, MachOOF.get());<br>}<br><br>-template<endianness E><br>static void DisassembleInputMachO2(StringRef Filename,<br>-                                   MachOObjectFileMiddle<E> *MachOOF) {<br>+                                   MachOObjectFile *MachOOF) {<br>  const Target *TheTarget = GetTarget(MachOOF);<br>  if (!TheTarget) {<br>    // GetTarget prints out stuff.<br>@@ -273,8 +265,7 @@ static void DisassembleInputMachO2(Strin<br><br>  outs() << '\n' << Filename << ":\n\n";<br><br>-  const typename MachOObjectFileMiddle<E>::Header *Header =<br>-    MachOOF->getHeader();<br>+  macho::Header Header = MachOOF->getHeader();<br><br>  std::vector<SectionRef> Sections;<br>  std::vector<SymbolRef> Symbols;<br><br>Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)<br>+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Thu Apr 18 13:08:55 2013<br>@@ -191,14 +191,6 @@ bool llvm::RelocAddressLess(RelocationRe<br>  return a_addr < b_addr;<br>}<br><br>-StringRef<br>-getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) {<br>-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachO))<br>-    return O->getSectionFinalSegmentName(DR);<br>-  const MachOObjectFileBE *O = dyn_cast<MachOObjectFileBE>(MachO);<br>-  return O->getSectionFinalSegmentName(DR);<br>-}<br>-<br>static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {<br>  const Target *TheTarget = getTarget(Obj);<br>  // getTarget() will have already issued a diagnostic if necessary, so<br>@@ -263,10 +255,10 @@ static void DisassembleObject(const Obje<br>    std::sort(Rels.begin(), Rels.end(), RelocAddressLess);<br><br>    StringRef SegmentName = "";<br>-    if (const MachOObjectFileBase *MachO =<br>-        dyn_cast<const MachOObjectFileBase>(Obj)) {<br>+    if (const MachOObjectFile *MachO =<br>+        dyn_cast<const MachOObjectFile>(Obj)) {<br>      DataRefImpl DR = i->getRawDataRefImpl();<br>-      SegmentName = getSectionFinalSegmentName(MachO, DR);<br>+      SegmentName = MachO->getSectionFinalSegmentName(DR);<br>    }<br>    StringRef name;<br>    if (error(i->getName(name))) break;<br>@@ -608,10 +600,10 @@ static void PrintSymbolTable(const Objec<br>      else if (Section == o->end_sections())<br>        outs() << "*UND*";<br>      else {<br>-        if (const MachOObjectFileBase *MachO =<br>-            dyn_cast<const MachOObjectFileBase>(o)) {<br>+        if (const MachOObjectFile *MachO =<br>+            dyn_cast<const MachOObjectFile>(o)) {<br>          DataRefImpl DR = Section->getRawDataRefImpl();<br>-          StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);<br>+          StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);<br>          outs() << SegmentName << ",";<br>        }<br>        StringRef SectionName;<br><br>Modified: llvm/trunk/tools/llvm-readobj/MachODumper.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (original)<br>+++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Thu Apr 18 13:08:55 2013<br>@@ -27,7 +27,7 @@ namespace {<br><br>class MachODumper : public ObjDumper {<br>public:<br>-  MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer)<br>+  MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer)<br>    : ObjDumper(Writer)<br>    , Obj(Obj) { }<br><br>@@ -43,14 +43,12 @@ private:<br><br>  void printRelocation(section_iterator SecI, relocation_iterator RelI);<br><br>-  template<support::endianness E><br>-  void printRelocation(const MachOObjectFileMiddle<E> *Obj,<br>+  void printRelocation(const MachOObjectFile *Obj,<br>                       section_iterator SecI, relocation_iterator RelI);<br><br>-  template<support::endianness E><br>-  void printSections(const MachOObjectFileMiddle<E> *Obj);<br>+  void printSections(const MachOObjectFile *Obj);<br><br>-  const MachOObjectFileBase *Obj;<br>+  const MachOObjectFile *Obj;<br>};<br><br>} // namespace<br>@@ -61,7 +59,7 @@ namespace llvm {<br>error_code createMachODumper(const object::ObjectFile *Obj,<br>                             StreamWriter& Writer,<br>                             OwningPtr<ObjDumper> &Result) {<br>-  const MachOObjectFileBase *MachOObj = dyn_cast<MachOObjectFileBase>(Obj);<br>+  const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj);<br>  if (!MachOObj)<br>    return readobj_error::unsupported_obj_file_format;<br><br>@@ -164,59 +162,53 @@ namespace {<br>  };<br>}<br><br>-template<class MachOT><br>-static void getSection(const MachOObjectFile<MachOT> *Obj,<br>-                       DataRefImpl DRI,<br>+static void getSection(const MachOObjectFile *Obj,<br>+                       DataRefImpl Sec,<br>                       MachOSection &Section) {<br>-  const typename MachOObjectFile<MachOT>::Section *Sect = Obj->getSection(DRI);<br>-  Section.Address     = Sect->Address;<br>-  Section.Size        = Sect->Size;<br>-  Section.Offset      = Sect->Offset;<br>-  Section.Alignment   = Sect->Align;<br>-  Section.RelocationTableOffset = Sect->RelocationTableOffset;<br>-  Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;<br>-  Section.Flags       = Sect->Flags;<br>-  Section.Reserved1   = Sect->Reserved1;<br>-  Section.Reserved2   = Sect->Reserved2;<br>-}<br>-<br>-static void getSection(const MachOObjectFileBase *Obj,<br>-                       DataRefImpl DRI,<br>-                       MachOSection &Section) {<br>-  if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))<br>-    return getSection(O, DRI, Section);<br>-  if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))<br>-    return getSection(O, DRI, Section);<br>-  if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))<br>-    return getSection(O, DRI, Section);<br>-  const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);<br>-  getSection(O, DRI, Section);<br>+  if (!Obj->is64Bit()) {<br>+    macho::Section Sect = Obj->getSection(Sec);<br>+    Section.Address     = Sect.Address;<br>+    Section.Size        = Sect.Size;<br>+    Section.Offset      = Sect.Offset;<br>+    Section.Alignment   = Sect.Align;<br>+    Section.RelocationTableOffset = Sect.RelocationTableOffset;<br>+    Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;<br>+    Section.Flags       = Sect.Flags;<br>+    Section.Reserved1   = Sect.Reserved1;<br>+    Section.Reserved2   = Sect.Reserved2;<br>+    return;<br>+  }<br>+  macho::Section64 Sect = Obj->getSection64(Sec);<br>+  Section.Address     = Sect.Address;<br>+  Section.Size        = Sect.Size;<br>+  Section.Offset      = Sect.Offset;<br>+  Section.Alignment   = Sect.Align;<br>+  Section.RelocationTableOffset = Sect.RelocationTableOffset;<br>+  Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;<br>+  Section.Flags       = Sect.Flags;<br>+  Section.Reserved1   = Sect.Reserved1;<br>+  Section.Reserved2   = Sect.Reserved2;<br>}<br><br>-template<class MachOT><br>-static void getSymbol(const MachOObjectFile<MachOT> *Obj,<br>-                      DataRefImpl DRI,<br>-                      MachOSymbol &Symbol) {<br>-  const typename MachOObjectFile<MachOT>::SymbolTableEntry *Entry =<br>-    Obj->getSymbolTableEntry(DRI);<br>-  Symbol.StringIndex  = Entry->StringIndex;<br>-  Symbol.Type         = Entry->Type;<br>-  Symbol.SectionIndex = Entry->SectionIndex;<br>-  Symbol.Flags        = Entry->Flags;<br>-  Symbol.Value        = Entry->Value;<br>-}<br><br>-static void getSymbol(const MachOObjectFileBase *Obj,<br>+static void getSymbol(const MachOObjectFile *Obj,<br>                      DataRefImpl DRI,<br>                      MachOSymbol &Symbol) {<br>-  if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))<br>-    return getSymbol(O, DRI, Symbol);<br>-  if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))<br>-    return getSymbol(O, DRI, Symbol);<br>-  if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))<br>-    return getSymbol(O, DRI, Symbol);<br>-  const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);<br>-  getSymbol(O, DRI, Symbol);<br>+  if (!Obj->is64Bit()) {<br>+    macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI);<br>+    Symbol.StringIndex  = Entry.StringIndex;<br>+    Symbol.Type         = Entry.Type;<br>+    Symbol.SectionIndex = Entry.SectionIndex;<br>+    Symbol.Flags        = Entry.Flags;<br>+    Symbol.Value        = Entry.Value;<br>+    return;<br>+  }<br>+  macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI);<br>+  Symbol.StringIndex  = Entry.StringIndex;<br>+  Symbol.Type         = Entry.Type;<br>+  Symbol.SectionIndex = Entry.SectionIndex;<br>+  Symbol.Flags        = Entry.Flags;<br>+  Symbol.Value        = Entry.Value;<br>}<br><br>void MachODumper::printFileHeaders() {<br>@@ -224,14 +216,10 @@ void MachODumper::printFileHeaders() {<br>}<br><br>void MachODumper::printSections() {<br>-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))<br>-    return printSections(O);<br>-  const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);<br>-  return printSections(O);<br>+  return printSections(Obj);<br>}<br><br>-template<support::endianness E><br>-void MachODumper::printSections(const MachOObjectFileMiddle<E> *Obj) {<br>+void MachODumper::printSections(const MachOObjectFile *Obj) {<br>  ListScope Group(W, "Sections");<br><br>  int SectionIndex = -1;<br>@@ -344,14 +332,10 @@ void MachODumper::printRelocations() {<br><br>void MachODumper::printRelocation(section_iterator SecI,<br>                                  relocation_iterator RelI) {<br>-  if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))<br>-    return printRelocation(O, SecI, RelI);<br>-  const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);<br>-  return printRelocation(O, SecI, RelI);<br>+  return printRelocation(Obj, SecI, RelI);<br>}<br><br>-template<support::endianness E><br>-void MachODumper::printRelocation(const MachOObjectFileMiddle<E> *Obj,<br>+void MachODumper::printRelocation(const MachOObjectFile *Obj,<br>                                  section_iterator SecI,<br>                                  relocation_iterator RelI) {<br>  uint64_t Offset;<br>@@ -364,31 +348,30 @@ void MachODumper::printRelocation(const<br>  if (error(Symbol.getName(SymbolName))) return;<br><br>  DataRefImpl DR = RelI->getRawDataRefImpl();<br>-  const typename MachOObjectFileMiddle<E>::RelocationEntry *RE =<br>-    Obj->getRelocation(DR);<br>+  macho::RelocationEntry RE = Obj->getRelocation(DR);<br>  bool IsScattered = Obj->isRelocationScattered(RE);<br><br>  if (opts::ExpandRelocs) {<br>    DictScope Group(W, "Relocation");<br>    W.printHex("Offset", Offset);<br>-    W.printNumber("PCRel", Obj->isRelocationPCRel(RE));<br>-    W.printNumber("Length", Obj->getRelocationLength(RE));<br>+    W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE));<br>+    W.printNumber("Length", Obj->getAnyRelocationLength(RE));<br>    if (IsScattered)<br>      W.printString("Extern", StringRef("N/A"));<br>    else<br>-      W.printNumber("Extern", RE->External);<br>-    W.printNumber("Type", RelocName, RE->Type);<br>+      W.printNumber("Extern", Obj->getPlainRelocationExternal(RE));<br>+    W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE));<br>    W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");<br>    W.printNumber("Scattered", IsScattered);<br>  } else {<br>    raw_ostream& OS = W.startLine();<br>    OS << W.hex(Offset)<br>-       << " " << Obj->isRelocationPCRel(RE)<br>-       << " " << Obj->getRelocationLength(RE);<br>+       << " " << Obj->getAnyRelocationPCRel(RE)<br>+       << " " << Obj->getAnyRelocationLength(RE);<br>    if (IsScattered)<br>      OS << " n/a";<br>    else<br>-      OS << " " << RE->External;<br>+      OS << " " << Obj->getPlainRelocationExternal(RE);<br>    OS << " " << RelocName<br>       << " " << IsScattered<br>       << " " << (SymbolName.size() > 0 ? SymbolName : "-")<br><br>Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=179778&r1=179777&r2=179778&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=179778&r1=179777&r2=179778&view=diff</a><br>==============================================================================<br>--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)<br>+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Thu Apr 18 13:08:55 2013<br>@@ -233,7 +233,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(co<br>    // On Darwin we may find DWARF in separate object file in<br>    // resource directory.<br>    ObjectFile *DbgObj = Obj;<br>-    if (isa<MachOObjectFileBase>(Obj)) {<br>+    if (isa<MachOObjectFile>(Obj)) {<br>      const std::string &ResourceName =<br>          getDarwinDWARFResourceForModule(ModuleName);<br>      ObjectFile *ResourceObj = getObjectFile(ResourceName);<br><br><br>_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></div></blockquote></div><br></div></body></html>