LLVM API Documentation

MachOObjectFile.cpp
Go to the documentation of this file.
00001 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the MachOObjectFile class, which binds the MachOObject
00011 // class to the generic ObjectFile wrapper.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/Object/MachO.h"
00016 #include "llvm/ADT/STLExtras.h"
00017 #include "llvm/ADT/StringSwitch.h"
00018 #include "llvm/ADT/Triple.h"
00019 #include "llvm/Support/DataExtractor.h"
00020 #include "llvm/Support/Debug.h"
00021 #include "llvm/Support/Format.h"
00022 #include "llvm/Support/Host.h"
00023 #include "llvm/Support/LEB128.h"
00024 #include "llvm/Support/MachO.h"
00025 #include "llvm/Support/MemoryBuffer.h"
00026 #include "llvm/Support/raw_ostream.h"
00027 #include <cctype>
00028 #include <cstring>
00029 #include <limits>
00030 
00031 using namespace llvm;
00032 using namespace object;
00033 
00034 namespace {
00035   struct section_base {
00036     char sectname[16];
00037     char segname[16];
00038   };
00039 }
00040 
00041 template<typename T>
00042 static T getStruct(const MachOObjectFile *O, const char *P) {
00043   T Cmd;
00044   memcpy(&Cmd, P, sizeof(T));
00045   if (O->isLittleEndian() != sys::IsLittleEndianHost)
00046     MachO::swapStruct(Cmd);
00047   return Cmd;
00048 }
00049 
00050 static uint32_t
00051 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
00052                                  const MachOObjectFile::LoadCommandInfo &L) {
00053   if (O->is64Bit()) {
00054     MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
00055     return S.nsects;
00056   }
00057   MachO::segment_command S = O->getSegmentLoadCommand(L);
00058   return S.nsects;
00059 }
00060 
00061 static bool isPageZeroSegment(const MachOObjectFile *O,
00062                               const MachOObjectFile::LoadCommandInfo &L) {
00063   if (O->is64Bit()) {
00064     MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
00065     return StringRef("__PAGEZERO").equals(S.segname);
00066   }
00067   MachO::segment_command S = O->getSegmentLoadCommand(L);
00068   return StringRef("__PAGEZERO").equals(S.segname);
00069 }
00070 
00071 
00072 static const char *
00073 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
00074               unsigned Sec) {
00075   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
00076 
00077   bool Is64 = O->is64Bit();
00078   unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
00079                                     sizeof(MachO::segment_command);
00080   unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
00081                                 sizeof(MachO::section);
00082 
00083   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
00084   return reinterpret_cast<const char*>(SectionAddr);
00085 }
00086 
00087 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
00088   return O->getData().substr(Offset, 1).data();
00089 }
00090 
00091 static MachO::nlist_base
00092 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
00093   const char *P = reinterpret_cast<const char *>(DRI.p);
00094   return getStruct<MachO::nlist_base>(O, P);
00095 }
00096 
00097 static StringRef parseSegmentOrSectionName(const char *P) {
00098   if (P[15] == 0)
00099     // Null terminated.
00100     return P;
00101   // Not null terminated, so this is a 16 char string.
00102   return StringRef(P, 16);
00103 }
00104 
00105 // Helper to advance a section or symbol iterator multiple increments at a time.
00106 template<class T>
00107 static void advance(T &it, size_t Val) {
00108   while (Val--)
00109     ++it;
00110 }
00111 
00112 static unsigned getCPUType(const MachOObjectFile *O) {
00113   return O->getHeader().cputype;
00114 }
00115 
00116 static void printRelocationTargetName(const MachOObjectFile *O,
00117                                       const MachO::any_relocation_info &RE,
00118                                       raw_string_ostream &fmt) {
00119   bool IsScattered = O->isRelocationScattered(RE);
00120 
00121   // Target of a scattered relocation is an address.  In the interest of
00122   // generating pretty output, scan through the symbol table looking for a
00123   // symbol that aligns with that address.  If we find one, print it.
00124   // Otherwise, we just print the hex address of the target.
00125   if (IsScattered) {
00126     uint32_t Val = O->getPlainRelocationSymbolNum(RE);
00127 
00128     for (const SymbolRef &Symbol : O->symbols()) {
00129       std::error_code ec;
00130       uint64_t Addr;
00131       StringRef Name;
00132 
00133       if ((ec = Symbol.getAddress(Addr)))
00134         report_fatal_error(ec.message());
00135       if (Addr != Val)
00136         continue;
00137       if ((ec = Symbol.getName(Name)))
00138         report_fatal_error(ec.message());
00139       fmt << Name;
00140       return;
00141     }
00142 
00143     // If we couldn't find a symbol that this relocation refers to, try
00144     // to find a section beginning instead.
00145     for (const SectionRef &Section : O->sections()) {
00146       std::error_code ec;
00147       uint64_t Addr;
00148       StringRef Name;
00149 
00150       if ((ec = Section.getAddress(Addr)))
00151         report_fatal_error(ec.message());
00152       if (Addr != Val)
00153         continue;
00154       if ((ec = Section.getName(Name)))
00155         report_fatal_error(ec.message());
00156       fmt << Name;
00157       return;
00158     }
00159 
00160     fmt << format("0x%x", Val);
00161     return;
00162   }
00163 
00164   StringRef S;
00165   bool isExtern = O->getPlainRelocationExternal(RE);
00166   uint64_t Val = O->getPlainRelocationSymbolNum(RE);
00167 
00168   if (isExtern) {
00169     symbol_iterator SI = O->symbol_begin();
00170     advance(SI, Val);
00171     SI->getName(S);
00172   } else {
00173     section_iterator SI = O->section_begin();
00174     // Adjust for the fact that sections are 1-indexed.
00175     advance(SI, Val - 1);
00176     SI->getName(S);
00177   }
00178 
00179   fmt << S;
00180 }
00181 
00182 static uint32_t
00183 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
00184   return RE.r_word0;
00185 }
00186 
00187 static unsigned
00188 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
00189   return RE.r_word0 & 0xffffff;
00190 }
00191 
00192 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
00193                                     const MachO::any_relocation_info &RE) {
00194   if (O->isLittleEndian())
00195     return (RE.r_word1 >> 24) & 1;
00196   return (RE.r_word1 >> 7) & 1;
00197 }
00198 
00199 static bool
00200 getScatteredRelocationPCRel(const MachOObjectFile *O,
00201                             const MachO::any_relocation_info &RE) {
00202   return (RE.r_word0 >> 30) & 1;
00203 }
00204 
00205 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
00206                                          const MachO::any_relocation_info &RE) {
00207   if (O->isLittleEndian())
00208     return (RE.r_word1 >> 25) & 3;
00209   return (RE.r_word1 >> 5) & 3;
00210 }
00211 
00212 static unsigned
00213 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
00214   return (RE.r_word0 >> 28) & 3;
00215 }
00216 
00217 static unsigned getPlainRelocationType(const MachOObjectFile *O,
00218                                        const MachO::any_relocation_info &RE) {
00219   if (O->isLittleEndian())
00220     return RE.r_word1 >> 28;
00221   return RE.r_word1 & 0xf;
00222 }
00223 
00224 static unsigned
00225 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
00226   return (RE.r_word0 >> 24) & 0xf;
00227 }
00228 
00229 static uint32_t getSectionFlags(const MachOObjectFile *O,
00230                                 DataRefImpl Sec) {
00231   if (O->is64Bit()) {
00232     MachO::section_64 Sect = O->getSection64(Sec);
00233     return Sect.flags;
00234   }
00235   MachO::section Sect = O->getSection(Sec);
00236   return Sect.flags;
00237 }
00238 
00239 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
00240                                  bool Is64bits, std::error_code &EC)
00241     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
00242       SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
00243       DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
00244       HasPageZeroSegment(false) {
00245   uint32_t LoadCommandCount = this->getHeader().ncmds;
00246   MachO::LoadCommandType SegmentLoadType = is64Bit() ?
00247     MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
00248 
00249   MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
00250   for (unsigned I = 0; ; ++I) {
00251     if (Load.C.cmd == MachO::LC_SYMTAB) {
00252       assert(!SymtabLoadCmd && "Multiple symbol tables");
00253       SymtabLoadCmd = Load.Ptr;
00254     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
00255       assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
00256       DysymtabLoadCmd = Load.Ptr;
00257     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
00258       assert(!DataInCodeLoadCmd && "Multiple data in code tables");
00259       DataInCodeLoadCmd = Load.Ptr;
00260     } else if (Load.C.cmd == MachO::LC_DYLD_INFO || 
00261                Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
00262       assert(!DyldInfoLoadCmd && "Multiple dyldinfo load commands");
00263       DyldInfoLoadCmd = Load.Ptr;
00264     } else if (Load.C.cmd == SegmentLoadType) {
00265       uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
00266       for (unsigned J = 0; J < NumSections; ++J) {
00267         const char *Sec = getSectionPtr(this, Load, J);
00268         Sections.push_back(Sec);
00269       }
00270       if (isPageZeroSegment(this, Load))
00271         HasPageZeroSegment = true;
00272     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
00273                Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
00274                Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
00275                Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
00276                Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
00277       Libraries.push_back(Load.Ptr);
00278     }
00279 
00280     if (I == LoadCommandCount - 1)
00281       break;
00282     else
00283       Load = getNextLoadCommandInfo(Load);
00284   }
00285 }
00286 
00287 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
00288   unsigned SymbolTableEntrySize = is64Bit() ?
00289     sizeof(MachO::nlist_64) :
00290     sizeof(MachO::nlist);
00291   Symb.p += SymbolTableEntrySize;
00292 }
00293 
00294 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
00295                                                StringRef &Res) const {
00296   StringRef StringTable = getStringTableData();
00297   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
00298   const char *Start = &StringTable.data()[Entry.n_strx];
00299   Res = StringRef(Start);
00300   return object_error::success;
00301 }
00302 
00303 // getIndirectName() returns the name of the alias'ed symbol who's string table
00304 // index is in the n_value field.
00305 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
00306                                                  StringRef &Res) const {
00307   StringRef StringTable = getStringTableData();
00308   uint64_t NValue;
00309   if (is64Bit()) {
00310     MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
00311     NValue = Entry.n_value;
00312     if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
00313       return object_error::parse_failed;
00314   } else {
00315     MachO::nlist Entry = getSymbolTableEntry(Symb);
00316     NValue = Entry.n_value;
00317     if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
00318       return object_error::parse_failed;
00319   }
00320   if (NValue >= StringTable.size())
00321     return object_error::parse_failed;
00322   const char *Start = &StringTable.data()[NValue];
00323   Res = StringRef(Start);
00324   return object_error::success;
00325 }
00326 
00327 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
00328                                                   uint64_t &Res) const {
00329   if (is64Bit()) {
00330     MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
00331     if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
00332         Entry.n_value == 0)
00333       Res = UnknownAddressOrSize;
00334     else
00335       Res = Entry.n_value;
00336   } else {
00337     MachO::nlist Entry = getSymbolTableEntry(Symb);
00338     if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
00339         Entry.n_value == 0)
00340       Res = UnknownAddressOrSize;
00341     else
00342       Res = Entry.n_value;
00343   }
00344   return object_error::success;
00345 }
00346 
00347 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
00348                                                     uint32_t &Result) const {
00349   uint32_t flags = getSymbolFlags(DRI);
00350   if (flags & SymbolRef::SF_Common) {
00351     MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
00352     Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
00353   } else {
00354     Result = 0;
00355   }
00356   return object_error::success;
00357 }
00358 
00359 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
00360                                                uint64_t &Result) const {
00361   uint64_t BeginOffset;
00362   uint64_t EndOffset = 0;
00363   uint8_t SectionIndex;
00364 
00365   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
00366   uint64_t Value;
00367   getSymbolAddress(DRI, Value);
00368   if (Value == UnknownAddressOrSize) {
00369     Result = UnknownAddressOrSize;
00370     return object_error::success;
00371   }
00372 
00373   BeginOffset = Value;
00374 
00375   SectionIndex = Entry.n_sect;
00376   if (!SectionIndex) {
00377     uint32_t flags = getSymbolFlags(DRI);
00378     if (flags & SymbolRef::SF_Common)
00379       Result = Value;
00380     else
00381       Result = UnknownAddressOrSize;
00382     return object_error::success;
00383   }
00384   // Unfortunately symbols are unsorted so we need to touch all
00385   // symbols from load command
00386   for (const SymbolRef &Symbol : symbols()) {
00387     DataRefImpl DRI = Symbol.getRawDataRefImpl();
00388     Entry = getSymbolTableEntryBase(this, DRI);
00389     getSymbolAddress(DRI, Value);
00390     if (Value == UnknownAddressOrSize)
00391       continue;
00392     if (Entry.n_sect == SectionIndex && Value > BeginOffset)
00393       if (!EndOffset || Value < EndOffset)
00394         EndOffset = Value;
00395   }
00396   if (!EndOffset) {
00397     uint64_t Size;
00398     DataRefImpl Sec;
00399     Sec.d.a = SectionIndex-1;
00400     getSectionSize(Sec, Size);
00401     getSectionAddress(Sec, EndOffset);
00402     EndOffset += Size;
00403   }
00404   Result = EndOffset - BeginOffset;
00405   return object_error::success;
00406 }
00407 
00408 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
00409                                                SymbolRef::Type &Res) const {
00410   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
00411   uint8_t n_type = Entry.n_type;
00412 
00413   Res = SymbolRef::ST_Other;
00414 
00415   // If this is a STAB debugging symbol, we can do nothing more.
00416   if (n_type & MachO::N_STAB) {
00417     Res = SymbolRef::ST_Debug;
00418     return object_error::success;
00419   }
00420 
00421   switch (n_type & MachO::N_TYPE) {
00422     case MachO::N_UNDF :
00423       Res = SymbolRef::ST_Unknown;
00424       break;
00425     case MachO::N_SECT :
00426       Res = SymbolRef::ST_Function;
00427       break;
00428   }
00429   return object_error::success;
00430 }
00431 
00432 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
00433   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
00434 
00435   uint8_t MachOType = Entry.n_type;
00436   uint16_t MachOFlags = Entry.n_desc;
00437 
00438   uint32_t Result = SymbolRef::SF_None;
00439 
00440   if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
00441     Result |= SymbolRef::SF_Undefined;
00442 
00443   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
00444     Result |= SymbolRef::SF_Indirect;
00445 
00446   if (MachOType & MachO::N_STAB)
00447     Result |= SymbolRef::SF_FormatSpecific;
00448 
00449   if (MachOType & MachO::N_EXT) {
00450     Result |= SymbolRef::SF_Global;
00451     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
00452       uint64_t Value;
00453       getSymbolAddress(DRI, Value);
00454       if (Value && Value != UnknownAddressOrSize)
00455         Result |= SymbolRef::SF_Common;
00456     }
00457   }
00458 
00459   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
00460     Result |= SymbolRef::SF_Weak;
00461 
00462   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
00463     Result |= SymbolRef::SF_Thumb;
00464 
00465   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
00466     Result |= SymbolRef::SF_Absolute;
00467 
00468   return Result;
00469 }
00470 
00471 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
00472                                                   section_iterator &Res) const {
00473   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
00474   uint8_t index = Entry.n_sect;
00475 
00476   if (index == 0) {
00477     Res = section_end();
00478   } else {
00479     DataRefImpl DRI;
00480     DRI.d.a = index - 1;
00481     Res = section_iterator(SectionRef(DRI, this));
00482   }
00483 
00484   return object_error::success;
00485 }
00486 
00487 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
00488   Sec.d.a++;
00489 }
00490 
00491 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
00492                                                 StringRef &Result) const {
00493   ArrayRef<char> Raw = getSectionRawName(Sec);
00494   Result = parseSegmentOrSectionName(Raw.data());
00495   return object_error::success;
00496 }
00497 
00498 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
00499                                                    uint64_t &Res) const {
00500   if (is64Bit()) {
00501     MachO::section_64 Sect = getSection64(Sec);
00502     Res = Sect.addr;
00503   } else {
00504     MachO::section Sect = getSection(Sec);
00505     Res = Sect.addr;
00506   }
00507   return object_error::success;
00508 }
00509 
00510 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
00511                                                 uint64_t &Res) const {
00512   if (is64Bit()) {
00513     MachO::section_64 Sect = getSection64(Sec);
00514     Res = Sect.size;
00515   } else {
00516     MachO::section Sect = getSection(Sec);
00517     Res = Sect.size;
00518   }
00519 
00520   return object_error::success;
00521 }
00522 
00523 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
00524                                                     StringRef &Res) const {
00525   uint32_t Offset;
00526   uint64_t Size;
00527 
00528   if (is64Bit()) {
00529     MachO::section_64 Sect = getSection64(Sec);
00530     Offset = Sect.offset;
00531     Size = Sect.size;
00532   } else {
00533     MachO::section Sect = getSection(Sec);
00534     Offset = Sect.offset;
00535     Size = Sect.size;
00536   }
00537 
00538   Res = this->getData().substr(Offset, Size);
00539   return object_error::success;
00540 }
00541 
00542 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
00543                                                      uint64_t &Res) const {
00544   uint32_t Align;
00545   if (is64Bit()) {
00546     MachO::section_64 Sect = getSection64(Sec);
00547     Align = Sect.align;
00548   } else {
00549     MachO::section Sect = getSection(Sec);
00550     Align = Sect.align;
00551   }
00552 
00553   Res = uint64_t(1) << Align;
00554   return object_error::success;
00555 }
00556 
00557 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
00558                                                bool &Res) const {
00559   uint32_t Flags = getSectionFlags(this, Sec);
00560   Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
00561   return object_error::success;
00562 }
00563 
00564 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
00565                                                bool &Result) const {
00566   uint32_t Flags = getSectionFlags(this, Sec);
00567   unsigned SectionType = Flags & MachO::SECTION_TYPE;
00568   Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
00569            !(SectionType == MachO::S_ZEROFILL ||
00570              SectionType == MachO::S_GB_ZEROFILL);
00571   return object_error::success;
00572 }
00573 
00574 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
00575                                               bool &Result) const {
00576   uint32_t Flags = getSectionFlags(this, Sec);
00577   unsigned SectionType = Flags & MachO::SECTION_TYPE;
00578   Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
00579            (SectionType == MachO::S_ZEROFILL ||
00580             SectionType == MachO::S_GB_ZEROFILL);
00581   return object_error::success;
00582 }
00583 
00584 std::error_code
00585 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
00586                                                bool &Result) const {
00587   // FIXME: Unimplemented.
00588   Result = true;
00589   return object_error::success;
00590 }
00591 
00592 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
00593                                                   bool &Result) const {
00594   // FIXME: Unimplemented.
00595   Result = false;
00596   return object_error::success;
00597 }
00598 
00599 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
00600                                                    bool &Res) const {
00601   uint32_t Flags = getSectionFlags(this, Sec);
00602   unsigned SectionType = Flags & MachO::SECTION_TYPE;
00603   Res = SectionType == MachO::S_ZEROFILL ||
00604     SectionType == MachO::S_GB_ZEROFILL;
00605   return object_error::success;
00606 }
00607 
00608 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
00609                                                        bool &Result) const {
00610   // Consider using the code from isSectionText to look for __const sections.
00611   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
00612   // to use section attributes to distinguish code from data.
00613 
00614   // FIXME: Unimplemented.
00615   Result = false;
00616   return object_error::success;
00617 }
00618 
00619 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
00620                                                        DataRefImpl Symb,
00621                                                        bool &Result) const {
00622   SymbolRef::Type ST;
00623   this->getSymbolType(Symb, ST);
00624   if (ST == SymbolRef::ST_Unknown) {
00625     Result = false;
00626     return object_error::success;
00627   }
00628 
00629   uint64_t SectBegin, SectEnd;
00630   getSectionAddress(Sec, SectBegin);
00631   getSectionSize(Sec, SectEnd);
00632   SectEnd += SectBegin;
00633 
00634   uint64_t SymAddr;
00635   getSymbolAddress(Symb, SymAddr);
00636   Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
00637 
00638   return object_error::success;
00639 }
00640 
00641 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
00642   DataRefImpl Ret;
00643   Ret.d.a = Sec.d.a;
00644   Ret.d.b = 0;
00645   return relocation_iterator(RelocationRef(Ret, this));
00646 }
00647 
00648 relocation_iterator
00649 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
00650   uint32_t Num;
00651   if (is64Bit()) {
00652     MachO::section_64 Sect = getSection64(Sec);
00653     Num = Sect.nreloc;
00654   } else {
00655     MachO::section Sect = getSection(Sec);
00656     Num = Sect.nreloc;
00657   }
00658 
00659   DataRefImpl Ret;
00660   Ret.d.a = Sec.d.a;
00661   Ret.d.b = Num;
00662   return relocation_iterator(RelocationRef(Ret, this));
00663 }
00664 
00665 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
00666   ++Rel.d.b;
00667 }
00668 
00669 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
00670                                                       uint64_t &Res) const {
00671   uint64_t Offset;
00672   getRelocationOffset(Rel, Offset);
00673 
00674   DataRefImpl Sec;
00675   Sec.d.a = Rel.d.a;
00676   uint64_t SecAddress;
00677   getSectionAddress(Sec, SecAddress);
00678   Res = SecAddress + Offset;
00679   return object_error::success;
00680 }
00681 
00682 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
00683                                                      uint64_t &Res) const {
00684   assert(getHeader().filetype == MachO::MH_OBJECT &&
00685          "Only implemented for MH_OBJECT");
00686   MachO::any_relocation_info RE = getRelocation(Rel);
00687   Res = getAnyRelocationAddress(RE);
00688   return object_error::success;
00689 }
00690 
00691 symbol_iterator
00692 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
00693   MachO::any_relocation_info RE = getRelocation(Rel);
00694   if (isRelocationScattered(RE))
00695     return symbol_end();
00696 
00697   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
00698   bool isExtern = getPlainRelocationExternal(RE);
00699   if (!isExtern)
00700     return symbol_end();
00701 
00702   MachO::symtab_command S = getSymtabLoadCommand();
00703   unsigned SymbolTableEntrySize = is64Bit() ?
00704     sizeof(MachO::nlist_64) :
00705     sizeof(MachO::nlist);
00706   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
00707   DataRefImpl Sym;
00708   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
00709   return symbol_iterator(SymbolRef(Sym, this));
00710 }
00711 
00712 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
00713                                                    uint64_t &Res) const {
00714   MachO::any_relocation_info RE = getRelocation(Rel);
00715   Res = getAnyRelocationType(RE);
00716   return object_error::success;
00717 }
00718 
00719 std::error_code
00720 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
00721                                        SmallVectorImpl<char> &Result) const {
00722   StringRef res;
00723   uint64_t RType;
00724   getRelocationType(Rel, RType);
00725 
00726   unsigned Arch = this->getArch();
00727 
00728   switch (Arch) {
00729     case Triple::x86: {
00730       static const char *const Table[] =  {
00731         "GENERIC_RELOC_VANILLA",
00732         "GENERIC_RELOC_PAIR",
00733         "GENERIC_RELOC_SECTDIFF",
00734         "GENERIC_RELOC_PB_LA_PTR",
00735         "GENERIC_RELOC_LOCAL_SECTDIFF",
00736         "GENERIC_RELOC_TLV" };
00737 
00738       if (RType > 5)
00739         res = "Unknown";
00740       else
00741         res = Table[RType];
00742       break;
00743     }
00744     case Triple::x86_64: {
00745       static const char *const Table[] =  {
00746         "X86_64_RELOC_UNSIGNED",
00747         "X86_64_RELOC_SIGNED",
00748         "X86_64_RELOC_BRANCH",
00749         "X86_64_RELOC_GOT_LOAD",
00750         "X86_64_RELOC_GOT",
00751         "X86_64_RELOC_SUBTRACTOR",
00752         "X86_64_RELOC_SIGNED_1",
00753         "X86_64_RELOC_SIGNED_2",
00754         "X86_64_RELOC_SIGNED_4",
00755         "X86_64_RELOC_TLV" };
00756 
00757       if (RType > 9)
00758         res = "Unknown";
00759       else
00760         res = Table[RType];
00761       break;
00762     }
00763     case Triple::arm: {
00764       static const char *const Table[] =  {
00765         "ARM_RELOC_VANILLA",
00766         "ARM_RELOC_PAIR",
00767         "ARM_RELOC_SECTDIFF",
00768         "ARM_RELOC_LOCAL_SECTDIFF",
00769         "ARM_RELOC_PB_LA_PTR",
00770         "ARM_RELOC_BR24",
00771         "ARM_THUMB_RELOC_BR22",
00772         "ARM_THUMB_32BIT_BRANCH",
00773         "ARM_RELOC_HALF",
00774         "ARM_RELOC_HALF_SECTDIFF" };
00775 
00776       if (RType > 9)
00777         res = "Unknown";
00778       else
00779         res = Table[RType];
00780       break;
00781     }
00782     case Triple::aarch64: {
00783       static const char *const Table[] = {
00784         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
00785         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
00786         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
00787         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
00788         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
00789         "ARM64_RELOC_ADDEND"
00790       };
00791 
00792       if (RType >= array_lengthof(Table))
00793         res = "Unknown";
00794       else
00795         res = Table[RType];
00796       break;
00797     }
00798     case Triple::ppc: {
00799       static const char *const Table[] =  {
00800         "PPC_RELOC_VANILLA",
00801         "PPC_RELOC_PAIR",
00802         "PPC_RELOC_BR14",
00803         "PPC_RELOC_BR24",
00804         "PPC_RELOC_HI16",
00805         "PPC_RELOC_LO16",
00806         "PPC_RELOC_HA16",
00807         "PPC_RELOC_LO14",
00808         "PPC_RELOC_SECTDIFF",
00809         "PPC_RELOC_PB_LA_PTR",
00810         "PPC_RELOC_HI16_SECTDIFF",
00811         "PPC_RELOC_LO16_SECTDIFF",
00812         "PPC_RELOC_HA16_SECTDIFF",
00813         "PPC_RELOC_JBSR",
00814         "PPC_RELOC_LO14_SECTDIFF",
00815         "PPC_RELOC_LOCAL_SECTDIFF" };
00816 
00817       if (RType > 15)
00818         res = "Unknown";
00819       else
00820         res = Table[RType];
00821       break;
00822     }
00823     case Triple::UnknownArch:
00824       res = "Unknown";
00825       break;
00826   }
00827   Result.append(res.begin(), res.end());
00828   return object_error::success;
00829 }
00830 
00831 std::error_code
00832 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
00833                                           SmallVectorImpl<char> &Result) const {
00834   MachO::any_relocation_info RE = getRelocation(Rel);
00835 
00836   unsigned Arch = this->getArch();
00837 
00838   std::string fmtbuf;
00839   raw_string_ostream fmt(fmtbuf);
00840   unsigned Type = this->getAnyRelocationType(RE);
00841   bool IsPCRel = this->getAnyRelocationPCRel(RE);
00842 
00843   // Determine any addends that should be displayed with the relocation.
00844   // These require decoding the relocation type, which is triple-specific.
00845 
00846   // X86_64 has entirely custom relocation types.
00847   if (Arch == Triple::x86_64) {
00848     bool isPCRel = getAnyRelocationPCRel(RE);
00849 
00850     switch (Type) {
00851       case MachO::X86_64_RELOC_GOT_LOAD:
00852       case MachO::X86_64_RELOC_GOT: {
00853         printRelocationTargetName(this, RE, fmt);
00854         fmt << "@GOT";
00855         if (isPCRel) fmt << "PCREL";
00856         break;
00857       }
00858       case MachO::X86_64_RELOC_SUBTRACTOR: {
00859         DataRefImpl RelNext = Rel;
00860         moveRelocationNext(RelNext);
00861         MachO::any_relocation_info RENext = getRelocation(RelNext);
00862 
00863         // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
00864         // X86_64_RELOC_UNSIGNED.
00865         // NOTE: Scattered relocations don't exist on x86_64.
00866         unsigned RType = getAnyRelocationType(RENext);
00867         if (RType != MachO::X86_64_RELOC_UNSIGNED)
00868           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
00869                              "X86_64_RELOC_SUBTRACTOR.");
00870 
00871         // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
00872         // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
00873         printRelocationTargetName(this, RENext, fmt);
00874         fmt << "-";
00875         printRelocationTargetName(this, RE, fmt);
00876         break;
00877       }
00878       case MachO::X86_64_RELOC_TLV:
00879         printRelocationTargetName(this, RE, fmt);
00880         fmt << "@TLV";
00881         if (isPCRel) fmt << "P";
00882         break;
00883       case MachO::X86_64_RELOC_SIGNED_1:
00884         printRelocationTargetName(this, RE, fmt);
00885         fmt << "-1";
00886         break;
00887       case MachO::X86_64_RELOC_SIGNED_2:
00888         printRelocationTargetName(this, RE, fmt);
00889         fmt << "-2";
00890         break;
00891       case MachO::X86_64_RELOC_SIGNED_4:
00892         printRelocationTargetName(this, RE, fmt);
00893         fmt << "-4";
00894         break;
00895       default:
00896         printRelocationTargetName(this, RE, fmt);
00897         break;
00898     }
00899   // X86 and ARM share some relocation types in common.
00900   } else if (Arch == Triple::x86 || Arch == Triple::arm ||
00901              Arch == Triple::ppc) {
00902     // Generic relocation types...
00903     switch (Type) {
00904       case MachO::GENERIC_RELOC_PAIR: // prints no info
00905         return object_error::success;
00906       case MachO::GENERIC_RELOC_SECTDIFF: {
00907         DataRefImpl RelNext = Rel;
00908         moveRelocationNext(RelNext);
00909         MachO::any_relocation_info RENext = getRelocation(RelNext);
00910 
00911         // X86 sect diff's must be followed by a relocation of type
00912         // GENERIC_RELOC_PAIR.
00913         unsigned RType = getAnyRelocationType(RENext);
00914 
00915         if (RType != MachO::GENERIC_RELOC_PAIR)
00916           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
00917                              "GENERIC_RELOC_SECTDIFF.");
00918 
00919         printRelocationTargetName(this, RE, fmt);
00920         fmt << "-";
00921         printRelocationTargetName(this, RENext, fmt);
00922         break;
00923       }
00924     }
00925 
00926     if (Arch == Triple::x86 || Arch == Triple::ppc) {
00927       switch (Type) {
00928         case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
00929           DataRefImpl RelNext = Rel;
00930           moveRelocationNext(RelNext);
00931           MachO::any_relocation_info RENext = getRelocation(RelNext);
00932 
00933           // X86 sect diff's must be followed by a relocation of type
00934           // GENERIC_RELOC_PAIR.
00935           unsigned RType = getAnyRelocationType(RENext);
00936           if (RType != MachO::GENERIC_RELOC_PAIR)
00937             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
00938                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
00939 
00940           printRelocationTargetName(this, RE, fmt);
00941           fmt << "-";
00942           printRelocationTargetName(this, RENext, fmt);
00943           break;
00944         }
00945         case MachO::GENERIC_RELOC_TLV: {
00946           printRelocationTargetName(this, RE, fmt);
00947           fmt << "@TLV";
00948           if (IsPCRel) fmt << "P";
00949           break;
00950         }
00951         default:
00952           printRelocationTargetName(this, RE, fmt);
00953       }
00954     } else { // ARM-specific relocations
00955       switch (Type) {
00956         case MachO::ARM_RELOC_HALF:
00957         case MachO::ARM_RELOC_HALF_SECTDIFF: {
00958           // Half relocations steal a bit from the length field to encode
00959           // whether this is an upper16 or a lower16 relocation.
00960           bool isUpper = getAnyRelocationLength(RE) >> 1;
00961 
00962           if (isUpper)
00963             fmt << ":upper16:(";
00964           else
00965             fmt << ":lower16:(";
00966           printRelocationTargetName(this, RE, fmt);
00967 
00968           DataRefImpl RelNext = Rel;
00969           moveRelocationNext(RelNext);
00970           MachO::any_relocation_info RENext = getRelocation(RelNext);
00971 
00972           // ARM half relocs must be followed by a relocation of type
00973           // ARM_RELOC_PAIR.
00974           unsigned RType = getAnyRelocationType(RENext);
00975           if (RType != MachO::ARM_RELOC_PAIR)
00976             report_fatal_error("Expected ARM_RELOC_PAIR after "
00977                                "ARM_RELOC_HALF");
00978 
00979           // NOTE: The half of the target virtual address is stashed in the
00980           // address field of the secondary relocation, but we can't reverse
00981           // engineer the constant offset from it without decoding the movw/movt
00982           // instruction to find the other half in its immediate field.
00983 
00984           // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
00985           // symbol/section pointer of the follow-on relocation.
00986           if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
00987             fmt << "-";
00988             printRelocationTargetName(this, RENext, fmt);
00989           }
00990 
00991           fmt << ")";
00992           break;
00993         }
00994         default: {
00995           printRelocationTargetName(this, RE, fmt);
00996         }
00997       }
00998     }
00999   } else
01000     printRelocationTargetName(this, RE, fmt);
01001 
01002   fmt.flush();
01003   Result.append(fmtbuf.begin(), fmtbuf.end());
01004   return object_error::success;
01005 }
01006 
01007 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
01008                                                      bool &Result) const {
01009   unsigned Arch = getArch();
01010   uint64_t Type;
01011   getRelocationType(Rel, Type);
01012 
01013   Result = false;
01014 
01015   // On arches that use the generic relocations, GENERIC_RELOC_PAIR
01016   // is always hidden.
01017   if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
01018     if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
01019   } else if (Arch == Triple::x86_64) {
01020     // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
01021     // an X86_64_RELOC_SUBTRACTOR.
01022     if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
01023       DataRefImpl RelPrev = Rel;
01024       RelPrev.d.a--;
01025       uint64_t PrevType;
01026       getRelocationType(RelPrev, PrevType);
01027       if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
01028         Result = true;
01029     }
01030   }
01031 
01032   return object_error::success;
01033 }
01034 
01035 //
01036 // guessLibraryShortName() is passed a name of a dynamic library and returns a
01037 // guess on what the short name is.  Then name is returned as a substring of the
01038 // StringRef Name passed in.  The name of the dynamic library is recognized as
01039 // a framework if it has one of the two following forms:
01040 //      Foo.framework/Versions/A/Foo
01041 //      Foo.framework/Foo
01042 // Where A and Foo can be any string.  And may contain a trailing suffix
01043 // starting with an underbar.  If the Name is recognized as a framework then
01044 // isFramework is set to true else it is set to false.  If the Name has a
01045 // suffix then Suffix is set to the substring in Name that contains the suffix
01046 // else it is set to a NULL StringRef.
01047 //
01048 // The Name of the dynamic library is recognized as a library name if it has
01049 // one of the two following forms:
01050 //      libFoo.A.dylib
01051 //      libFoo.dylib
01052 // The library may have a suffix trailing the name Foo of the form:
01053 //      libFoo_profile.A.dylib
01054 //      libFoo_profile.dylib
01055 //
01056 // The Name of the dynamic library is also recognized as a library name if it
01057 // has the following form:
01058 //      Foo.qtx
01059 //
01060 // If the Name of the dynamic library is none of the forms above then a NULL
01061 // StringRef is returned.
01062 //
01063 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
01064                                                  bool &isFramework,
01065                                                  StringRef &Suffix) {
01066   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
01067   size_t a, b, c, d, Idx;
01068 
01069   isFramework = false;
01070   Suffix = StringRef();
01071 
01072   // Pull off the last component and make Foo point to it
01073   a = Name.rfind('/');
01074   if (a == Name.npos || a == 0)
01075     goto guess_library;
01076   Foo = Name.slice(a+1, Name.npos);
01077 
01078   // Look for a suffix starting with a '_'
01079   Idx = Foo.rfind('_');
01080   if (Idx != Foo.npos && Foo.size() >= 2) {
01081     Suffix = Foo.slice(Idx, Foo.npos);
01082     Foo = Foo.slice(0, Idx);
01083   }
01084 
01085   // First look for the form Foo.framework/Foo
01086   b = Name.rfind('/', a);
01087   if (b == Name.npos)
01088     Idx = 0;
01089   else
01090     Idx = b+1;
01091   F = Name.slice(Idx, Idx + Foo.size());
01092   DotFramework = Name.slice(Idx + Foo.size(),
01093                             Idx + Foo.size() + sizeof(".framework/")-1);
01094   if (F == Foo && DotFramework == ".framework/") {
01095     isFramework = true;
01096     return Foo;
01097   }
01098 
01099   // Next look for the form Foo.framework/Versions/A/Foo
01100   if (b == Name.npos)
01101     goto guess_library;
01102   c =  Name.rfind('/', b);
01103   if (c == Name.npos || c == 0)
01104     goto guess_library;
01105   V = Name.slice(c+1, Name.npos);
01106   if (!V.startswith("Versions/"))
01107     goto guess_library;
01108   d =  Name.rfind('/', c);
01109   if (d == Name.npos)
01110     Idx = 0;
01111   else
01112     Idx = d+1;
01113   F = Name.slice(Idx, Idx + Foo.size());
01114   DotFramework = Name.slice(Idx + Foo.size(),
01115                             Idx + Foo.size() + sizeof(".framework/")-1);
01116   if (F == Foo && DotFramework == ".framework/") {
01117     isFramework = true;
01118     return Foo;
01119   }
01120 
01121 guess_library:
01122   // pull off the suffix after the "." and make a point to it
01123   a = Name.rfind('.');
01124   if (a == Name.npos || a == 0)
01125     return StringRef();
01126   Dylib = Name.slice(a, Name.npos);
01127   if (Dylib != ".dylib")
01128     goto guess_qtx;
01129 
01130   // First pull off the version letter for the form Foo.A.dylib if any.
01131   if (a >= 3) {
01132     Dot = Name.slice(a-2, a-1);
01133     if (Dot == ".")
01134       a = a - 2;
01135   }
01136 
01137   b = Name.rfind('/', a);
01138   if (b == Name.npos)
01139     b = 0;
01140   else
01141     b = b+1;
01142   // ignore any suffix after an underbar like Foo_profile.A.dylib
01143   Idx = Name.find('_', b);
01144   if (Idx != Name.npos && Idx != b) {
01145     Lib = Name.slice(b, Idx);
01146     Suffix = Name.slice(Idx, a);
01147   }
01148   else
01149     Lib = Name.slice(b, a);
01150   // There are incorrect library names of the form:
01151   // libATS.A_profile.dylib so check for these.
01152   if (Lib.size() >= 3) {
01153     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
01154     if (Dot == ".")
01155       Lib = Lib.slice(0, Lib.size()-2);
01156   }
01157   return Lib;
01158 
01159 guess_qtx:
01160   Qtx = Name.slice(a, Name.npos);
01161   if (Qtx != ".qtx")
01162     return StringRef();
01163   b = Name.rfind('/', a);
01164   if (b == Name.npos)
01165     Lib = Name.slice(0, a);
01166   else
01167     Lib = Name.slice(b+1, a);
01168   // There are library names of the form: QT.A.qtx so check for these.
01169   if (Lib.size() >= 3) {
01170     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
01171     if (Dot == ".")
01172       Lib = Lib.slice(0, Lib.size()-2);
01173   }
01174   return Lib;
01175 }
01176 
01177 // getLibraryShortNameByIndex() is used to get the short name of the library
01178 // for an undefined symbol in a linked Mach-O binary that was linked with the
01179 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
01180 // It is passed the index (0 - based) of the library as translated from
01181 // GET_LIBRARY_ORDINAL (1 - based).
01182 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
01183                                                          StringRef &Res) const {
01184   if (Index >= Libraries.size())
01185     return object_error::parse_failed;
01186 
01187   // If the cache of LibrariesShortNames is not built up do that first for
01188   // all the Libraries.
01189   if (LibrariesShortNames.size() == 0) {
01190     for (unsigned i = 0; i < Libraries.size(); i++) {
01191       MachO::dylib_command D =
01192         getStruct<MachO::dylib_command>(this, Libraries[i]);
01193       if (D.dylib.name >= D.cmdsize)
01194         return object_error::parse_failed;
01195       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
01196       StringRef Name = StringRef(P);
01197       if (D.dylib.name+Name.size() >= D.cmdsize)
01198         return object_error::parse_failed;
01199       StringRef Suffix;
01200       bool isFramework;
01201       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
01202       if (shortName.empty())
01203         LibrariesShortNames.push_back(Name);
01204       else
01205         LibrariesShortNames.push_back(shortName);
01206     }
01207   }
01208 
01209   Res = LibrariesShortNames[Index];
01210   return object_error::success;
01211 }
01212 
01213 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
01214   return getSymbolByIndex(0);
01215 }
01216 
01217 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
01218   DataRefImpl DRI;
01219   if (!SymtabLoadCmd)
01220     return basic_symbol_iterator(SymbolRef(DRI, this));
01221 
01222   MachO::symtab_command Symtab = getSymtabLoadCommand();
01223   unsigned SymbolTableEntrySize = is64Bit() ?
01224     sizeof(MachO::nlist_64) :
01225     sizeof(MachO::nlist);
01226   unsigned Offset = Symtab.symoff +
01227     Symtab.nsyms * SymbolTableEntrySize;
01228   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
01229   return basic_symbol_iterator(SymbolRef(DRI, this));
01230 }
01231 
01232 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
01233   DataRefImpl DRI;
01234   if (!SymtabLoadCmd)
01235     return basic_symbol_iterator(SymbolRef(DRI, this));
01236 
01237   MachO::symtab_command Symtab = getSymtabLoadCommand();
01238   assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
01239   unsigned SymbolTableEntrySize =
01240     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
01241   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
01242   DRI.p += Index * SymbolTableEntrySize;
01243   return basic_symbol_iterator(SymbolRef(DRI, this));
01244 }
01245 
01246 section_iterator MachOObjectFile::section_begin() const {
01247   DataRefImpl DRI;
01248   return section_iterator(SectionRef(DRI, this));
01249 }
01250 
01251 section_iterator MachOObjectFile::section_end() const {
01252   DataRefImpl DRI;
01253   DRI.d.a = Sections.size();
01254   return section_iterator(SectionRef(DRI, this));
01255 }
01256 
01257 uint8_t MachOObjectFile::getBytesInAddress() const {
01258   return is64Bit() ? 8 : 4;
01259 }
01260 
01261 StringRef MachOObjectFile::getFileFormatName() const {
01262   unsigned CPUType = getCPUType(this);
01263   if (!is64Bit()) {
01264     switch (CPUType) {
01265     case llvm::MachO::CPU_TYPE_I386:
01266       return "Mach-O 32-bit i386";
01267     case llvm::MachO::CPU_TYPE_ARM:
01268       return "Mach-O arm";
01269     case llvm::MachO::CPU_TYPE_POWERPC:
01270       return "Mach-O 32-bit ppc";
01271     default:
01272       assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
01273              "64-bit object file when we're not 64-bit?");
01274       return "Mach-O 32-bit unknown";
01275     }
01276   }
01277 
01278   // Make sure the cpu type has the correct mask.
01279   assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
01280          == llvm::MachO::CPU_ARCH_ABI64 &&
01281          "32-bit object file when we're 64-bit?");
01282 
01283   switch (CPUType) {
01284   case llvm::MachO::CPU_TYPE_X86_64:
01285     return "Mach-O 64-bit x86-64";
01286   case llvm::MachO::CPU_TYPE_ARM64:
01287     return "Mach-O arm64";
01288   case llvm::MachO::CPU_TYPE_POWERPC64:
01289     return "Mach-O 64-bit ppc64";
01290   default:
01291     return "Mach-O 64-bit unknown";
01292   }
01293 }
01294 
01295 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
01296   switch (CPUType) {
01297   case llvm::MachO::CPU_TYPE_I386:
01298     return Triple::x86;
01299   case llvm::MachO::CPU_TYPE_X86_64:
01300     return Triple::x86_64;
01301   case llvm::MachO::CPU_TYPE_ARM:
01302     return Triple::arm;
01303   case llvm::MachO::CPU_TYPE_ARM64:
01304     return Triple::aarch64;
01305   case llvm::MachO::CPU_TYPE_POWERPC:
01306     return Triple::ppc;
01307   case llvm::MachO::CPU_TYPE_POWERPC64:
01308     return Triple::ppc64;
01309   default:
01310     return Triple::UnknownArch;
01311   }
01312 }
01313 
01314 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
01315                                 const char **McpuDefault) {
01316   if (McpuDefault)
01317     *McpuDefault = nullptr;
01318 
01319   switch (CPUType) {
01320   case MachO::CPU_TYPE_I386:
01321     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01322     case MachO::CPU_SUBTYPE_I386_ALL:
01323       return Triple("i386-apple-darwin");
01324     default:
01325       return Triple();
01326     }
01327   case MachO::CPU_TYPE_X86_64:
01328     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01329     case MachO::CPU_SUBTYPE_X86_64_ALL:
01330       return Triple("x86_64-apple-darwin");
01331     case MachO::CPU_SUBTYPE_X86_64_H:
01332       return Triple("x86_64h-apple-darwin");
01333     default:
01334       return Triple();
01335     }
01336   case MachO::CPU_TYPE_ARM:
01337     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01338     case MachO::CPU_SUBTYPE_ARM_V4T:
01339       return Triple("armv4t-apple-darwin");
01340     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
01341       return Triple("armv5e-apple-darwin");
01342     case MachO::CPU_SUBTYPE_ARM_XSCALE:
01343       return Triple("xscale-apple-darwin");
01344     case MachO::CPU_SUBTYPE_ARM_V6:
01345       return Triple("armv6-apple-darwin");
01346     case MachO::CPU_SUBTYPE_ARM_V6M:
01347       if (McpuDefault)
01348         *McpuDefault = "cortex-m0";
01349       return Triple("armv6m-apple-darwin");
01350     case MachO::CPU_SUBTYPE_ARM_V7:
01351       return Triple("armv7-apple-darwin");
01352     case MachO::CPU_SUBTYPE_ARM_V7EM:
01353       if (McpuDefault)
01354         *McpuDefault = "cortex-m4";
01355       return Triple("armv7em-apple-darwin");
01356     case MachO::CPU_SUBTYPE_ARM_V7K:
01357       return Triple("armv7k-apple-darwin");
01358     case MachO::CPU_SUBTYPE_ARM_V7M:
01359       if (McpuDefault)
01360         *McpuDefault = "cortex-m3";
01361       return Triple("armv7m-apple-darwin");
01362     case MachO::CPU_SUBTYPE_ARM_V7S:
01363       return Triple("armv7s-apple-darwin");
01364     default:
01365       return Triple();
01366     }
01367   case MachO::CPU_TYPE_ARM64:
01368     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01369     case MachO::CPU_SUBTYPE_ARM64_ALL:
01370       return Triple("arm64-apple-darwin");
01371     default:
01372       return Triple();
01373     }
01374   case MachO::CPU_TYPE_POWERPC:
01375     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01376     case MachO::CPU_SUBTYPE_POWERPC_ALL:
01377       return Triple("ppc-apple-darwin");
01378     default:
01379       return Triple();
01380     }
01381   case MachO::CPU_TYPE_POWERPC64:
01382     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01383     case MachO::CPU_SUBTYPE_POWERPC_ALL:
01384       return Triple("ppc64-apple-darwin");
01385     default:
01386       return Triple();
01387     }
01388   default:
01389     return Triple();
01390   }
01391 }
01392 
01393 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
01394                                      const char **McpuDefault) {
01395   if (McpuDefault)
01396     *McpuDefault = nullptr;
01397 
01398   switch (CPUType) {
01399   case MachO::CPU_TYPE_ARM:
01400     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
01401     case MachO::CPU_SUBTYPE_ARM_V4T:
01402       return Triple("thumbv4t-apple-darwin");
01403     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
01404       return Triple("thumbv5e-apple-darwin");
01405     case MachO::CPU_SUBTYPE_ARM_XSCALE:
01406       return Triple("xscale-apple-darwin");
01407     case MachO::CPU_SUBTYPE_ARM_V6:
01408       return Triple("thumbv6-apple-darwin");
01409     case MachO::CPU_SUBTYPE_ARM_V6M:
01410       if (McpuDefault)
01411         *McpuDefault = "cortex-m0";
01412       return Triple("thumbv6m-apple-darwin");
01413     case MachO::CPU_SUBTYPE_ARM_V7:
01414       return Triple("thumbv7-apple-darwin");
01415     case MachO::CPU_SUBTYPE_ARM_V7EM:
01416       if (McpuDefault)
01417         *McpuDefault = "cortex-m4";
01418       return Triple("thumbv7em-apple-darwin");
01419     case MachO::CPU_SUBTYPE_ARM_V7K:
01420       return Triple("thumbv7k-apple-darwin");
01421     case MachO::CPU_SUBTYPE_ARM_V7M:
01422       if (McpuDefault)
01423         *McpuDefault = "cortex-m3";
01424       return Triple("thumbv7m-apple-darwin");
01425     case MachO::CPU_SUBTYPE_ARM_V7S:
01426       return Triple("thumbv7s-apple-darwin");
01427     default:
01428       return Triple();
01429     }
01430   default:
01431     return Triple();
01432   }
01433 }
01434 
01435 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
01436                                 const char **McpuDefault,
01437         Triple *ThumbTriple) {
01438   Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
01439   *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
01440                                                McpuDefault);
01441   return T;
01442 }
01443 
01444 Triple MachOObjectFile::getHostArch() {
01445   return Triple(sys::getDefaultTargetTriple());
01446 }
01447 
01448 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
01449   return StringSwitch<bool>(ArchFlag)
01450       .Case("i386", true)
01451       .Case("x86_64", true)
01452       .Case("x86_64h", true)
01453       .Case("armv4t", true)
01454       .Case("arm", true)
01455       .Case("armv5e", true)
01456       .Case("armv6", true)
01457       .Case("armv6m", true)
01458       .Case("armv7em", true)
01459       .Case("armv7k", true)
01460       .Case("armv7m", true)
01461       .Case("armv7s", true)
01462       .Case("arm64", true)
01463       .Case("ppc", true)
01464       .Case("ppc64", true)
01465       .Default(false);
01466 }
01467 
01468 unsigned MachOObjectFile::getArch() const {
01469   return getArch(getCPUType(this));
01470 }
01471 
01472 Triple MachOObjectFile::getArch(const char **McpuDefault,
01473                                 Triple *ThumbTriple) const {
01474   Triple T;
01475   if (is64Bit()) {
01476     MachO::mach_header_64 H_64;
01477     H_64 = getHeader64();
01478     T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
01479     *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
01480                                                  McpuDefault);
01481   } else {
01482     MachO::mach_header H;
01483     H = getHeader();
01484     T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
01485     *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
01486                                                  McpuDefault);
01487   }
01488   return T;
01489 }
01490 
01491 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
01492   DataRefImpl DRI;
01493   DRI.d.a = Index;
01494   return section_rel_begin(DRI);
01495 }
01496 
01497 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
01498   DataRefImpl DRI;
01499   DRI.d.a = Index;
01500   return section_rel_end(DRI);
01501 }
01502 
01503 dice_iterator MachOObjectFile::begin_dices() const {
01504   DataRefImpl DRI;
01505   if (!DataInCodeLoadCmd)
01506     return dice_iterator(DiceRef(DRI, this));
01507 
01508   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
01509   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
01510   return dice_iterator(DiceRef(DRI, this));
01511 }
01512 
01513 dice_iterator MachOObjectFile::end_dices() const {
01514   DataRefImpl DRI;
01515   if (!DataInCodeLoadCmd)
01516     return dice_iterator(DiceRef(DRI, this));
01517 
01518   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
01519   unsigned Offset = DicLC.dataoff + DicLC.datasize;
01520   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
01521   return dice_iterator(DiceRef(DRI, this));
01522 }
01523 
01524 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 
01525   : Trie(T), Malformed(false), Done(false) { }
01526 
01527 void ExportEntry::moveToFirst() {
01528   pushNode(0);
01529   pushDownUntilBottom();
01530 }
01531 
01532 void ExportEntry::moveToEnd() {
01533   Stack.clear();
01534   Done = true;
01535 }
01536 
01537 bool ExportEntry::operator==(const ExportEntry &Other) const {
01538   // Common case, one at end, other iterating from begin. 
01539   if (Done || Other.Done)
01540     return (Done == Other.Done);
01541   // Not equal if different stack sizes.
01542   if (Stack.size() != Other.Stack.size())
01543     return false;
01544   // Not equal if different cumulative strings.
01545   if (!CumulativeString.str().equals(Other.CumulativeString.str()))
01546     return false;
01547   // Equal if all nodes in both stacks match.
01548   for (unsigned i=0; i < Stack.size(); ++i) {
01549     if (Stack[i].Start != Other.Stack[i].Start)
01550       return false;
01551   }
01552   return true;  
01553 }
01554 
01555 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
01556   unsigned Count;
01557   uint64_t Result = decodeULEB128(Ptr, &Count);
01558   Ptr += Count;
01559   if (Ptr > Trie.end()) {
01560     Ptr = Trie.end();
01561     Malformed = true;
01562   }
01563   return Result;
01564 }
01565 
01566 StringRef ExportEntry::name() const {
01567   return CumulativeString.str();
01568 }
01569 
01570 uint64_t ExportEntry::flags() const {
01571   return Stack.back().Flags;
01572 }
01573 
01574 uint64_t ExportEntry::address() const {
01575   return Stack.back().Address;
01576 }
01577 
01578 uint64_t ExportEntry::other() const {
01579   return Stack.back().Other;
01580 }
01581 
01582 StringRef ExportEntry::otherName() const {
01583   const char* ImportName = Stack.back().ImportName;
01584   if (ImportName)
01585     return StringRef(ImportName);
01586   return StringRef();
01587 }
01588 
01589 uint32_t ExportEntry::nodeOffset() const {
01590   return Stack.back().Start - Trie.begin();
01591 }
01592 
01593 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 
01594   : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 
01595     ImportName(nullptr), ChildCount(0), NextChildIndex(0),  
01596     ParentStringLength(0), IsExportNode(false) {
01597 }
01598 
01599 void ExportEntry::pushNode(uint64_t offset) {
01600   const uint8_t *Ptr = Trie.begin() + offset;
01601   NodeState State(Ptr);
01602   uint64_t ExportInfoSize = readULEB128(State.Current);
01603   State.IsExportNode = (ExportInfoSize != 0);
01604   const uint8_t* Children = State.Current + ExportInfoSize;
01605   if (State.IsExportNode) {
01606     State.Flags = readULEB128(State.Current);
01607     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
01608       State.Address = 0;
01609       State.Other = readULEB128(State.Current); // dylib ordinal
01610       State.ImportName = reinterpret_cast<const char*>(State.Current);
01611     } else {
01612       State.Address = readULEB128(State.Current);
01613       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
01614         State.Other = readULEB128(State.Current); 
01615     }
01616   }
01617   State.ChildCount = *Children;
01618   State.Current = Children + 1;
01619   State.NextChildIndex = 0;
01620   State.ParentStringLength = CumulativeString.size();
01621   Stack.push_back(State);
01622 }
01623 
01624 void ExportEntry::pushDownUntilBottom() {
01625   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
01626     NodeState &Top = Stack.back();
01627     CumulativeString.resize(Top.ParentStringLength);
01628     for (;*Top.Current != 0; Top.Current++) {
01629       char C = *Top.Current;
01630       CumulativeString.push_back(C);
01631     }
01632     Top.Current += 1;
01633     uint64_t childNodeIndex = readULEB128(Top.Current);
01634     Top.NextChildIndex += 1;
01635     pushNode(childNodeIndex);
01636   }
01637   if (!Stack.back().IsExportNode) {
01638     Malformed = true;
01639     moveToEnd();
01640   }
01641 }
01642 
01643 // We have a trie data structure and need a way to walk it that is compatible
01644 // with the C++ iterator model. The solution is a non-recursive depth first
01645 // traversal where the iterator contains a stack of parent nodes along with a
01646 // string that is the accumulation of all edge strings along the parent chain
01647 // to this point.
01648 //
01649 // There is one “export” node for each exported symbol.  But because some
01650 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
01651 // node may have child nodes too.  
01652 //
01653 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
01654 // child until hitting a node with no children (which is an export node or
01655 // else the trie is malformed). On the way down, each node is pushed on the
01656 // stack ivar.  If there is no more ways down, it pops up one and tries to go
01657 // down a sibling path until a childless node is reached.
01658 void ExportEntry::moveNext() {
01659   if (Stack.empty() || !Stack.back().IsExportNode) {
01660     Malformed = true;
01661     moveToEnd();
01662     return;
01663   }
01664 
01665   Stack.pop_back();
01666   while (!Stack.empty()) {
01667     NodeState &Top = Stack.back();
01668     if (Top.NextChildIndex < Top.ChildCount) {
01669       pushDownUntilBottom();
01670       // Now at the next export node.
01671       return;
01672     } else {
01673       if (Top.IsExportNode) {
01674         // This node has no children but is itself an export node.
01675         CumulativeString.resize(Top.ParentStringLength);
01676         return;
01677       }
01678       Stack.pop_back();
01679     }
01680   }
01681   Done = true;
01682 }
01683 
01684 iterator_range<export_iterator> 
01685 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
01686   ExportEntry Start(Trie);
01687   Start.moveToFirst();
01688 
01689   ExportEntry Finish(Trie);
01690   Finish.moveToEnd();
01691 
01692   return iterator_range<export_iterator>(export_iterator(Start), 
01693                                          export_iterator(Finish));
01694 }
01695 
01696 iterator_range<export_iterator> MachOObjectFile::exports() const {
01697   return exports(getDyldInfoExportsTrie());
01698 }
01699 
01700 
01701 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
01702     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
01703       RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
01704       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
01705 
01706 void MachORebaseEntry::moveToFirst() {
01707   Ptr = Opcodes.begin();
01708   moveNext();
01709 }
01710 
01711 void MachORebaseEntry::moveToEnd() {
01712   Ptr = Opcodes.end();
01713   RemainingLoopCount = 0;
01714   Done = true;
01715 }
01716 
01717 void MachORebaseEntry::moveNext() {
01718   // If in the middle of some loop, move to next rebasing in loop.
01719   SegmentOffset += AdvanceAmount;
01720   if (RemainingLoopCount) {
01721     --RemainingLoopCount;
01722     return;
01723   }
01724   if (Ptr == Opcodes.end()) {
01725     Done = true;
01726     return;
01727   }
01728   bool More = true;
01729   while (More && !Malformed) {
01730     // Parse next opcode and set up next loop.
01731     uint8_t Byte = *Ptr++;
01732     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
01733     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
01734     switch (Opcode) {
01735     case MachO::REBASE_OPCODE_DONE:
01736       More = false;
01737       Done = true;
01738       moveToEnd();
01739       DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
01740       break;
01741     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
01742       RebaseType = ImmValue;
01743       DEBUG_WITH_TYPE(
01744           "mach-o-rebase",
01745           llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
01746                        << "RebaseType=" << (int) RebaseType << "\n");
01747       break;
01748     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
01749       SegmentIndex = ImmValue;
01750       SegmentOffset = readULEB128();
01751       DEBUG_WITH_TYPE(
01752           "mach-o-rebase",
01753           llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
01754                        << "SegmentIndex=" << SegmentIndex << ", "
01755                        << format("SegmentOffset=0x%06X", SegmentOffset)
01756                        << "\n");
01757       break;
01758     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
01759       SegmentOffset += readULEB128();
01760       DEBUG_WITH_TYPE("mach-o-rebase",
01761                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
01762                                    << format("SegmentOffset=0x%06X",
01763                                              SegmentOffset) << "\n");
01764       break;
01765     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
01766       SegmentOffset += ImmValue * PointerSize;
01767       DEBUG_WITH_TYPE("mach-o-rebase",
01768                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
01769                                    << format("SegmentOffset=0x%06X",
01770                                              SegmentOffset) << "\n");
01771       break;
01772     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
01773       AdvanceAmount = PointerSize;
01774       RemainingLoopCount = ImmValue - 1;
01775       DEBUG_WITH_TYPE(
01776           "mach-o-rebase",
01777           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
01778                        << format("SegmentOffset=0x%06X", SegmentOffset)
01779                        << ", AdvanceAmount=" << AdvanceAmount
01780                        << ", RemainingLoopCount=" << RemainingLoopCount
01781                        << "\n");
01782       return;
01783     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
01784       AdvanceAmount = PointerSize;
01785       RemainingLoopCount = readULEB128() - 1;
01786       DEBUG_WITH_TYPE(
01787           "mach-o-rebase",
01788           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
01789                        << format("SegmentOffset=0x%06X", SegmentOffset)
01790                        << ", AdvanceAmount=" << AdvanceAmount
01791                        << ", RemainingLoopCount=" << RemainingLoopCount
01792                        << "\n");
01793       return;
01794     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
01795       AdvanceAmount = readULEB128() + PointerSize;
01796       RemainingLoopCount = 0;
01797       DEBUG_WITH_TYPE(
01798           "mach-o-rebase",
01799           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
01800                        << format("SegmentOffset=0x%06X", SegmentOffset)
01801                        << ", AdvanceAmount=" << AdvanceAmount
01802                        << ", RemainingLoopCount=" << RemainingLoopCount
01803                        << "\n");
01804       return;
01805     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
01806       RemainingLoopCount = readULEB128() - 1;
01807       AdvanceAmount = readULEB128() + PointerSize;
01808       DEBUG_WITH_TYPE(
01809           "mach-o-rebase",
01810           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
01811                        << format("SegmentOffset=0x%06X", SegmentOffset)
01812                        << ", AdvanceAmount=" << AdvanceAmount
01813                        << ", RemainingLoopCount=" << RemainingLoopCount
01814                        << "\n");
01815       return;
01816     default:
01817       Malformed = true;
01818     }
01819   }
01820 }
01821 
01822 uint64_t MachORebaseEntry::readULEB128() {
01823   unsigned Count;
01824   uint64_t Result = decodeULEB128(Ptr, &Count);
01825   Ptr += Count;
01826   if (Ptr > Opcodes.end()) {
01827     Ptr = Opcodes.end();
01828     Malformed = true;
01829   }
01830   return Result;
01831 }
01832 
01833 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
01834 
01835 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
01836 
01837 StringRef MachORebaseEntry::typeName() const {
01838   switch (RebaseType) {
01839   case MachO::REBASE_TYPE_POINTER:
01840     return "pointer";
01841   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
01842     return "text abs32";
01843   case MachO::REBASE_TYPE_TEXT_PCREL32:
01844     return "text rel32";
01845   }
01846   return "unknown";
01847 }
01848 
01849 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
01850   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
01851   return (Ptr == Other.Ptr) &&
01852          (RemainingLoopCount == Other.RemainingLoopCount) &&
01853          (Done == Other.Done);
01854 }
01855 
01856 iterator_range<rebase_iterator>
01857 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
01858   MachORebaseEntry Start(Opcodes, is64);
01859   Start.moveToFirst();
01860 
01861   MachORebaseEntry Finish(Opcodes, is64);
01862   Finish.moveToEnd();
01863 
01864   return iterator_range<rebase_iterator>(rebase_iterator(Start),
01865                                          rebase_iterator(Finish));
01866 }
01867 
01868 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
01869   return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
01870 }
01871 
01872 
01873 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
01874                                Kind BK)
01875     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
01876       Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
01877       BindType(0), PointerSize(is64Bit ? 8 : 4),
01878       TableKind(BK), Malformed(false), Done(false) {}
01879 
01880 void MachOBindEntry::moveToFirst() {
01881   Ptr = Opcodes.begin();
01882   moveNext();
01883 }
01884 
01885 void MachOBindEntry::moveToEnd() {
01886   Ptr = Opcodes.end();
01887   RemainingLoopCount = 0;
01888   Done = true;
01889 }
01890 
01891 void MachOBindEntry::moveNext() {
01892   // If in the middle of some loop, move to next binding in loop.
01893   SegmentOffset += AdvanceAmount;
01894   if (RemainingLoopCount) {
01895     --RemainingLoopCount;
01896     return;
01897   }
01898   if (Ptr == Opcodes.end()) {
01899     Done = true;
01900     return;
01901   }
01902   bool More = true;
01903   while (More && !Malformed) {
01904     // Parse next opcode and set up next loop.
01905     uint8_t Byte = *Ptr++;
01906     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
01907     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
01908     int8_t SignExtended;
01909     const uint8_t *SymStart;
01910     switch (Opcode) {
01911     case MachO::BIND_OPCODE_DONE:
01912       if (TableKind == Kind::Lazy) {
01913         // Lazying bindings have a DONE opcode between entries.  Need to ignore
01914         // it to advance to next entry.  But need not if this is last entry.
01915         bool NotLastEntry = false;
01916         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
01917           if (*P) {
01918             NotLastEntry = true;
01919           }
01920         }
01921         if (NotLastEntry)
01922           break;
01923       }
01924       More = false;
01925       Done = true;
01926       moveToEnd();
01927       DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
01928       break;
01929     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
01930       Ordinal = ImmValue;
01931       DEBUG_WITH_TYPE(
01932           "mach-o-bind",
01933           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
01934                        << "Ordinal=" << Ordinal << "\n");
01935       break;
01936     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
01937       Ordinal = readULEB128();
01938       DEBUG_WITH_TYPE(
01939           "mach-o-bind",
01940           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
01941                        << "Ordinal=" << Ordinal << "\n");
01942       break;
01943     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
01944       if (ImmValue) {
01945         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
01946         Ordinal = SignExtended;
01947       } else
01948         Ordinal = 0;
01949       DEBUG_WITH_TYPE(
01950           "mach-o-bind",
01951           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
01952                        << "Ordinal=" << Ordinal << "\n");
01953       break;
01954     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
01955       Flags = ImmValue;
01956       SymStart = Ptr;
01957       while (*Ptr) {
01958         ++Ptr;
01959       }
01960       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
01961                              Ptr-SymStart);
01962       ++Ptr;
01963       DEBUG_WITH_TYPE(
01964           "mach-o-bind",
01965           llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
01966                        << "SymbolName=" << SymbolName << "\n");
01967       if (TableKind == Kind::Weak) {
01968         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
01969           return;
01970       }
01971       break;
01972     case MachO::BIND_OPCODE_SET_TYPE_IMM:
01973       BindType = ImmValue;
01974       DEBUG_WITH_TYPE(
01975           "mach-o-bind",
01976           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
01977                        << "BindType=" << (int)BindType << "\n");
01978       break;
01979     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
01980       Addend = readSLEB128();
01981       if (TableKind == Kind::Lazy)
01982         Malformed = true;
01983       DEBUG_WITH_TYPE(
01984           "mach-o-bind",
01985           llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
01986                        << "Addend=" << Addend << "\n");
01987       break;
01988     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
01989       SegmentIndex = ImmValue;
01990       SegmentOffset = readULEB128();
01991       DEBUG_WITH_TYPE(
01992           "mach-o-bind",
01993           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
01994                        << "SegmentIndex=" << SegmentIndex << ", "
01995                        << format("SegmentOffset=0x%06X", SegmentOffset)
01996                        << "\n");
01997       break;
01998     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
01999       SegmentOffset += readULEB128();
02000       DEBUG_WITH_TYPE("mach-o-bind",
02001                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
02002                                    << format("SegmentOffset=0x%06X",
02003                                              SegmentOffset) << "\n");
02004       break;
02005     case MachO::BIND_OPCODE_DO_BIND:
02006       AdvanceAmount = PointerSize;
02007       RemainingLoopCount = 0;
02008       DEBUG_WITH_TYPE("mach-o-bind",
02009                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
02010                                    << format("SegmentOffset=0x%06X",
02011                                              SegmentOffset) << "\n");
02012       return;
02013      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
02014       AdvanceAmount = readULEB128();
02015       RemainingLoopCount = 0;
02016       if (TableKind == Kind::Lazy)
02017         Malformed = true;
02018       DEBUG_WITH_TYPE(
02019           "mach-o-bind",
02020           llvm::dbgs() << "BIND_OPCODE_DO_BIND_IMM_TIMES: "
02021                        << format("SegmentOffset=0x%06X", SegmentOffset)
02022                        << ", AdvanceAmount=" << AdvanceAmount
02023                        << ", RemainingLoopCount=" << RemainingLoopCount
02024                        << "\n");
02025       return;
02026     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
02027       AdvanceAmount = ImmValue * PointerSize;
02028       RemainingLoopCount = 0;
02029       if (TableKind == Kind::Lazy)
02030         Malformed = true;
02031       DEBUG_WITH_TYPE("mach-o-bind",
02032                       llvm::dbgs()
02033                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
02034                       << format("SegmentOffset=0x%06X",
02035                                              SegmentOffset) << "\n");
02036       return;
02037     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
02038       RemainingLoopCount = readULEB128() - 1;
02039       AdvanceAmount = readULEB128() + PointerSize;
02040       if (TableKind == Kind::Lazy)
02041         Malformed = true;
02042       DEBUG_WITH_TYPE(
02043           "mach-o-bind",
02044           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
02045                        << format("SegmentOffset=0x%06X", SegmentOffset)
02046                        << ", AdvanceAmount=" << AdvanceAmount
02047                        << ", RemainingLoopCount=" << RemainingLoopCount
02048                        << "\n");
02049       return;
02050     default:
02051       Malformed = true;
02052     }
02053   }
02054 }
02055 
02056 uint64_t MachOBindEntry::readULEB128() {
02057   unsigned Count;
02058   uint64_t Result = decodeULEB128(Ptr, &Count);
02059   Ptr += Count;
02060   if (Ptr > Opcodes.end()) {
02061     Ptr = Opcodes.end();
02062     Malformed = true;
02063   }
02064   return Result;
02065 }
02066 
02067 int64_t MachOBindEntry::readSLEB128() {
02068   unsigned Count;
02069   int64_t Result = decodeSLEB128(Ptr, &Count);
02070   Ptr += Count;
02071   if (Ptr > Opcodes.end()) {
02072     Ptr = Opcodes.end();
02073     Malformed = true;
02074   }
02075   return Result;
02076 }
02077 
02078 
02079 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
02080 
02081 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
02082 
02083 StringRef MachOBindEntry::typeName() const {
02084   switch (BindType) {
02085   case MachO::BIND_TYPE_POINTER:
02086     return "pointer";
02087   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
02088     return "text abs32";
02089   case MachO::BIND_TYPE_TEXT_PCREL32:
02090     return "text rel32";
02091   }
02092   return "unknown";
02093 }
02094 
02095 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
02096 
02097 int64_t MachOBindEntry::addend() const { return Addend; }
02098 
02099 uint32_t MachOBindEntry::flags() const { return Flags; }
02100 
02101 int MachOBindEntry::ordinal() const { return Ordinal; }
02102 
02103 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
02104   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
02105   return (Ptr == Other.Ptr) &&
02106          (RemainingLoopCount == Other.RemainingLoopCount) &&
02107          (Done == Other.Done);
02108 }
02109 
02110 iterator_range<bind_iterator>
02111 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
02112                            MachOBindEntry::Kind BKind) {
02113   MachOBindEntry Start(Opcodes, is64, BKind);
02114   Start.moveToFirst();
02115 
02116   MachOBindEntry Finish(Opcodes, is64, BKind);
02117   Finish.moveToEnd();
02118 
02119   return iterator_range<bind_iterator>(bind_iterator(Start),
02120                                        bind_iterator(Finish));
02121 }
02122 
02123 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
02124   return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
02125                    MachOBindEntry::Kind::Regular);
02126 }
02127 
02128 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
02129   return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
02130                    MachOBindEntry::Kind::Lazy);
02131 }
02132 
02133 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
02134   return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
02135                    MachOBindEntry::Kind::Weak);
02136 }
02137 
02138 StringRef
02139 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
02140   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
02141   return parseSegmentOrSectionName(Raw.data());
02142 }
02143 
02144 ArrayRef<char>
02145 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
02146   const section_base *Base =
02147     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
02148   return makeArrayRef(Base->sectname);
02149 }
02150 
02151 ArrayRef<char>
02152 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
02153   const section_base *Base =
02154     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
02155   return makeArrayRef(Base->segname);
02156 }
02157 
02158 bool
02159 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
02160   const {
02161   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
02162     return false;
02163   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
02164 }
02165 
02166 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
02167     const MachO::any_relocation_info &RE) const {
02168   if (isLittleEndian())
02169     return RE.r_word1 & 0xffffff;
02170   return RE.r_word1 >> 8;
02171 }
02172 
02173 bool MachOObjectFile::getPlainRelocationExternal(
02174     const MachO::any_relocation_info &RE) const {
02175   if (isLittleEndian())
02176     return (RE.r_word1 >> 27) & 1;
02177   return (RE.r_word1 >> 4) & 1;
02178 }
02179 
02180 bool MachOObjectFile::getScatteredRelocationScattered(
02181     const MachO::any_relocation_info &RE) const {
02182   return RE.r_word0 >> 31;
02183 }
02184 
02185 uint32_t MachOObjectFile::getScatteredRelocationValue(
02186     const MachO::any_relocation_info &RE) const {
02187   return RE.r_word1;
02188 }
02189 
02190 unsigned MachOObjectFile::getAnyRelocationAddress(
02191     const MachO::any_relocation_info &RE) const {
02192   if (isRelocationScattered(RE))
02193     return getScatteredRelocationAddress(RE);
02194   return getPlainRelocationAddress(RE);
02195 }
02196 
02197 unsigned MachOObjectFile::getAnyRelocationPCRel(
02198     const MachO::any_relocation_info &RE) const {
02199   if (isRelocationScattered(RE))
02200     return getScatteredRelocationPCRel(this, RE);
02201   return getPlainRelocationPCRel(this, RE);
02202 }
02203 
02204 unsigned MachOObjectFile::getAnyRelocationLength(
02205     const MachO::any_relocation_info &RE) const {
02206   if (isRelocationScattered(RE))
02207     return getScatteredRelocationLength(RE);
02208   return getPlainRelocationLength(this, RE);
02209 }
02210 
02211 unsigned
02212 MachOObjectFile::getAnyRelocationType(
02213                                    const MachO::any_relocation_info &RE) const {
02214   if (isRelocationScattered(RE))
02215     return getScatteredRelocationType(RE);
02216   return getPlainRelocationType(this, RE);
02217 }
02218 
02219 SectionRef
02220 MachOObjectFile::getRelocationSection(
02221                                    const MachO::any_relocation_info &RE) const {
02222   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
02223     return *section_end();
02224   unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
02225   DataRefImpl DRI;
02226   DRI.d.a = SecNum;
02227   return SectionRef(DRI, this);
02228 }
02229 
02230 MachOObjectFile::LoadCommandInfo
02231 MachOObjectFile::getFirstLoadCommandInfo() const {
02232   MachOObjectFile::LoadCommandInfo Load;
02233 
02234   unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
02235                                     sizeof(MachO::mach_header);
02236   Load.Ptr = getPtr(this, HeaderSize);
02237   Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
02238   return Load;
02239 }
02240 
02241 MachOObjectFile::LoadCommandInfo
02242 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
02243   MachOObjectFile::LoadCommandInfo Next;
02244   Next.Ptr = L.Ptr + L.C.cmdsize;
02245   Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
02246   return Next;
02247 }
02248 
02249 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
02250   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
02251 }
02252 
02253 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
02254   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
02255 }
02256 
02257 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
02258                                            unsigned Index) const {
02259   const char *Sec = getSectionPtr(this, L, Index);
02260   return getStruct<MachO::section>(this, Sec);
02261 }
02262 
02263 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
02264                                                 unsigned Index) const {
02265   const char *Sec = getSectionPtr(this, L, Index);
02266   return getStruct<MachO::section_64>(this, Sec);
02267 }
02268 
02269 MachO::nlist
02270 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
02271   const char *P = reinterpret_cast<const char *>(DRI.p);
02272   return getStruct<MachO::nlist>(this, P);
02273 }
02274 
02275 MachO::nlist_64
02276 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
02277   const char *P = reinterpret_cast<const char *>(DRI.p);
02278   return getStruct<MachO::nlist_64>(this, P);
02279 }
02280 
02281 MachO::linkedit_data_command
02282 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
02283   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
02284 }
02285 
02286 MachO::segment_command
02287 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
02288   return getStruct<MachO::segment_command>(this, L.Ptr);
02289 }
02290 
02291 MachO::segment_command_64
02292 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
02293   return getStruct<MachO::segment_command_64>(this, L.Ptr);
02294 }
02295 
02296 MachO::linker_options_command
02297 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
02298   return getStruct<MachO::linker_options_command>(this, L.Ptr);
02299 }
02300 
02301 MachO::version_min_command
02302 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
02303   return getStruct<MachO::version_min_command>(this, L.Ptr);
02304 }
02305 
02306 MachO::dylib_command
02307 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
02308   return getStruct<MachO::dylib_command>(this, L.Ptr);
02309 }
02310 
02311 MachO::dyld_info_command
02312 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
02313   return getStruct<MachO::dyld_info_command>(this, L.Ptr);
02314 }
02315 
02316 MachO::dylinker_command
02317 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
02318   return getStruct<MachO::dylinker_command>(this, L.Ptr);
02319 }
02320 
02321 MachO::uuid_command
02322 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
02323   return getStruct<MachO::uuid_command>(this, L.Ptr);
02324 }
02325 
02326 MachO::source_version_command
02327 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
02328   return getStruct<MachO::source_version_command>(this, L.Ptr);
02329 }
02330 
02331 MachO::entry_point_command
02332 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
02333   return getStruct<MachO::entry_point_command>(this, L.Ptr);
02334 }
02335 
02336 
02337 MachO::any_relocation_info
02338 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
02339   DataRefImpl Sec;
02340   Sec.d.a = Rel.d.a;
02341   uint32_t Offset;
02342   if (is64Bit()) {
02343     MachO::section_64 Sect = getSection64(Sec);
02344     Offset = Sect.reloff;
02345   } else {
02346     MachO::section Sect = getSection(Sec);
02347     Offset = Sect.reloff;
02348   }
02349 
02350   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
02351       getPtr(this, Offset)) + Rel.d.b;
02352   return getStruct<MachO::any_relocation_info>(
02353       this, reinterpret_cast<const char *>(P));
02354 }
02355 
02356 MachO::data_in_code_entry
02357 MachOObjectFile::getDice(DataRefImpl Rel) const {
02358   const char *P = reinterpret_cast<const char *>(Rel.p);
02359   return getStruct<MachO::data_in_code_entry>(this, P);
02360 }
02361 
02362 MachO::mach_header MachOObjectFile::getHeader() const {
02363   return getStruct<MachO::mach_header>(this, getPtr(this, 0));
02364 }
02365 
02366 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
02367   return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
02368 }
02369 
02370 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
02371                                              const MachO::dysymtab_command &DLC,
02372                                              unsigned Index) const {
02373   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
02374   return getStruct<uint32_t>(this, getPtr(this, Offset));
02375 }
02376 
02377 MachO::data_in_code_entry
02378 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
02379                                          unsigned Index) const {
02380   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
02381   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
02382 }
02383 
02384 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
02385   return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
02386 }
02387 
02388 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
02389   return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
02390 }
02391 
02392 MachO::linkedit_data_command
02393 MachOObjectFile::getDataInCodeLoadCommand() const {
02394   if (DataInCodeLoadCmd)
02395     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
02396 
02397   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
02398   MachO::linkedit_data_command Cmd;
02399   Cmd.cmd = MachO::LC_DATA_IN_CODE;
02400   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
02401   Cmd.dataoff = 0;
02402   Cmd.datasize = 0;
02403   return Cmd;
02404 }
02405 
02406 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
02407   if (!DyldInfoLoadCmd) 
02408     return ArrayRef<uint8_t>();
02409 
02410   MachO::dyld_info_command DyldInfo 
02411                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
02412   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
02413                                              getPtr(this, DyldInfo.rebase_off));
02414   return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
02415 }
02416 
02417 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
02418   if (!DyldInfoLoadCmd) 
02419     return ArrayRef<uint8_t>();
02420 
02421   MachO::dyld_info_command DyldInfo 
02422                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
02423   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
02424                                                getPtr(this, DyldInfo.bind_off));
02425   return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
02426 }
02427 
02428 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
02429   if (!DyldInfoLoadCmd) 
02430     return ArrayRef<uint8_t>();
02431 
02432   MachO::dyld_info_command DyldInfo 
02433                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
02434   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
02435                                           getPtr(this, DyldInfo.weak_bind_off));
02436   return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
02437 }
02438 
02439 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
02440   if (!DyldInfoLoadCmd) 
02441     return ArrayRef<uint8_t>();
02442 
02443   MachO::dyld_info_command DyldInfo 
02444                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
02445   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
02446                                           getPtr(this, DyldInfo.lazy_bind_off));
02447   return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
02448 }
02449 
02450 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
02451   if (!DyldInfoLoadCmd) 
02452     return ArrayRef<uint8_t>();
02453 
02454   MachO::dyld_info_command DyldInfo 
02455                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
02456   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
02457                                              getPtr(this, DyldInfo.export_off));
02458   return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
02459 }
02460 
02461 
02462 StringRef MachOObjectFile::getStringTableData() const {
02463   MachO::symtab_command S = getSymtabLoadCommand();
02464   return getData().substr(S.stroff, S.strsize);
02465 }
02466 
02467 bool MachOObjectFile::is64Bit() const {
02468   return getType() == getMachOType(false, true) ||
02469     getType() == getMachOType(true, true);
02470 }
02471 
02472 void MachOObjectFile::ReadULEB128s(uint64_t Index,
02473                                    SmallVectorImpl<uint64_t> &Out) const {
02474   DataExtractor extractor(ObjectFile::getData(), true, 0);
02475 
02476   uint32_t offset = Index;
02477   uint64_t data = 0;
02478   while (uint64_t delta = extractor.getULEB128(&offset)) {
02479     data += delta;
02480     Out.push_back(data);
02481   }
02482 }
02483 
02484 bool MachOObjectFile::isRelocatableObject() const {
02485   return getHeader().filetype == MachO::MH_OBJECT;
02486 }
02487 
02488 ErrorOr<std::unique_ptr<MachOObjectFile>>
02489 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
02490   StringRef Magic = Buffer.getBuffer().slice(0, 4);
02491   std::error_code EC;
02492   std::unique_ptr<MachOObjectFile> Ret;
02493   if (Magic == "\xFE\xED\xFA\xCE")
02494     Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
02495   else if (Magic == "\xCE\xFA\xED\xFE")
02496     Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
02497   else if (Magic == "\xFE\xED\xFA\xCF")
02498     Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
02499   else if (Magic == "\xCF\xFA\xED\xFE")
02500     Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
02501   else
02502     return object_error::parse_failed;
02503 
02504   if (EC)
02505     return EC;
02506   return std::move(Ret);
02507 }
02508