• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
2  //
3  //                     The LLVM Compiler Infrastructure
4  //
5  // This file is distributed under the University of Illinois Open Source
6  // License. See LICENSE.TXT for details.
7  //
8  //===----------------------------------------------------------------------===//
9  //
10  // This file defines the MachOObjectFile class, which binds the MachOObject
11  // class to the generic ObjectFile wrapper.
12  //
13  //===----------------------------------------------------------------------===//
14  
15  #include "llvm/Object/MachO.h"
16  #include "llvm/ADT/STLExtras.h"
17  #include "llvm/ADT/StringSwitch.h"
18  #include "llvm/ADT/Triple.h"
19  #include "llvm/Support/DataExtractor.h"
20  #include "llvm/Support/Debug.h"
21  #include "llvm/Support/Format.h"
22  #include "llvm/Support/Host.h"
23  #include "llvm/Support/LEB128.h"
24  #include "llvm/Support/MachO.h"
25  #include "llvm/Support/MemoryBuffer.h"
26  #include "llvm/Support/raw_ostream.h"
27  #include <cctype>
28  #include <cstring>
29  #include <limits>
30  
31  using namespace llvm;
32  using namespace object;
33  
34  namespace {
35    struct section_base {
36      char sectname[16];
37      char segname[16];
38    };
39  }
40  
41  // FIXME: Replace all uses of this function with getStructOrErr.
42  template <typename T>
getStruct(const MachOObjectFile * O,const char * P)43  static T getStruct(const MachOObjectFile *O, const char *P) {
44    // Don't read before the beginning or past the end of the file
45    if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
46      report_fatal_error("Malformed MachO file.");
47  
48    T Cmd;
49    memcpy(&Cmd, P, sizeof(T));
50    if (O->isLittleEndian() != sys::IsLittleEndianHost)
51      MachO::swapStruct(Cmd);
52    return Cmd;
53  }
54  
55  template <typename T>
getStructOrErr(const MachOObjectFile * O,const char * P)56  static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
57    // Don't read before the beginning or past the end of the file
58    if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
59      return object_error::parse_failed;
60  
61    T Cmd;
62    memcpy(&Cmd, P, sizeof(T));
63    if (O->isLittleEndian() != sys::IsLittleEndianHost)
64      MachO::swapStruct(Cmd);
65    return Cmd;
66  }
67  
68  static const char *
getSectionPtr(const MachOObjectFile * O,MachOObjectFile::LoadCommandInfo L,unsigned Sec)69  getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
70                unsigned Sec) {
71    uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
72  
73    bool Is64 = O->is64Bit();
74    unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
75                                      sizeof(MachO::segment_command);
76    unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
77                                  sizeof(MachO::section);
78  
79    uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
80    return reinterpret_cast<const char*>(SectionAddr);
81  }
82  
getPtr(const MachOObjectFile * O,size_t Offset)83  static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
84    return O->getData().substr(Offset, 1).data();
85  }
86  
87  static MachO::nlist_base
getSymbolTableEntryBase(const MachOObjectFile * O,DataRefImpl DRI)88  getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
89    const char *P = reinterpret_cast<const char *>(DRI.p);
90    return getStruct<MachO::nlist_base>(O, P);
91  }
92  
parseSegmentOrSectionName(const char * P)93  static StringRef parseSegmentOrSectionName(const char *P) {
94    if (P[15] == 0)
95      // Null terminated.
96      return P;
97    // Not null terminated, so this is a 16 char string.
98    return StringRef(P, 16);
99  }
100  
101  // Helper to advance a section or symbol iterator multiple increments at a time.
102  template<class T>
advance(T & it,size_t Val)103  static void advance(T &it, size_t Val) {
104    while (Val--)
105      ++it;
106  }
107  
getCPUType(const MachOObjectFile * O)108  static unsigned getCPUType(const MachOObjectFile *O) {
109    return O->getHeader().cputype;
110  }
111  
112  static uint32_t
getPlainRelocationAddress(const MachO::any_relocation_info & RE)113  getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
114    return RE.r_word0;
115  }
116  
117  static unsigned
getScatteredRelocationAddress(const MachO::any_relocation_info & RE)118  getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
119    return RE.r_word0 & 0xffffff;
120  }
121  
getPlainRelocationPCRel(const MachOObjectFile * O,const MachO::any_relocation_info & RE)122  static bool getPlainRelocationPCRel(const MachOObjectFile *O,
123                                      const MachO::any_relocation_info &RE) {
124    if (O->isLittleEndian())
125      return (RE.r_word1 >> 24) & 1;
126    return (RE.r_word1 >> 7) & 1;
127  }
128  
129  static bool
getScatteredRelocationPCRel(const MachOObjectFile * O,const MachO::any_relocation_info & RE)130  getScatteredRelocationPCRel(const MachOObjectFile *O,
131                              const MachO::any_relocation_info &RE) {
132    return (RE.r_word0 >> 30) & 1;
133  }
134  
getPlainRelocationLength(const MachOObjectFile * O,const MachO::any_relocation_info & RE)135  static unsigned getPlainRelocationLength(const MachOObjectFile *O,
136                                           const MachO::any_relocation_info &RE) {
137    if (O->isLittleEndian())
138      return (RE.r_word1 >> 25) & 3;
139    return (RE.r_word1 >> 5) & 3;
140  }
141  
142  static unsigned
getScatteredRelocationLength(const MachO::any_relocation_info & RE)143  getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
144    return (RE.r_word0 >> 28) & 3;
145  }
146  
getPlainRelocationType(const MachOObjectFile * O,const MachO::any_relocation_info & RE)147  static unsigned getPlainRelocationType(const MachOObjectFile *O,
148                                         const MachO::any_relocation_info &RE) {
149    if (O->isLittleEndian())
150      return RE.r_word1 >> 28;
151    return RE.r_word1 & 0xf;
152  }
153  
getSectionFlags(const MachOObjectFile * O,DataRefImpl Sec)154  static uint32_t getSectionFlags(const MachOObjectFile *O,
155                                  DataRefImpl Sec) {
156    if (O->is64Bit()) {
157      MachO::section_64 Sect = O->getSection64(Sec);
158      return Sect.flags;
159    }
160    MachO::section Sect = O->getSection(Sec);
161    return Sect.flags;
162  }
163  
164  static ErrorOr<MachOObjectFile::LoadCommandInfo>
getLoadCommandInfo(const MachOObjectFile * Obj,const char * Ptr)165  getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) {
166    auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr);
167    if (!CmdOrErr)
168      return CmdOrErr.getError();
169    if (CmdOrErr->cmdsize < 8)
170      return object_error::macho_small_load_command;
171    MachOObjectFile::LoadCommandInfo Load;
172    Load.Ptr = Ptr;
173    Load.C = CmdOrErr.get();
174    return Load;
175  }
176  
177  static ErrorOr<MachOObjectFile::LoadCommandInfo>
getFirstLoadCommandInfo(const MachOObjectFile * Obj)178  getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
179    unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
180                                         : sizeof(MachO::mach_header);
181    return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize));
182  }
183  
184  static ErrorOr<MachOObjectFile::LoadCommandInfo>
getNextLoadCommandInfo(const MachOObjectFile * Obj,const MachOObjectFile::LoadCommandInfo & L)185  getNextLoadCommandInfo(const MachOObjectFile *Obj,
186                         const MachOObjectFile::LoadCommandInfo &L) {
187    return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
188  }
189  
190  template <typename T>
parseHeader(const MachOObjectFile * Obj,T & Header,std::error_code & EC)191  static void parseHeader(const MachOObjectFile *Obj, T &Header,
192                          std::error_code &EC) {
193    auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
194    if (HeaderOrErr)
195      Header = HeaderOrErr.get();
196    else
197      EC = HeaderOrErr.getError();
198  }
199  
200  // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
201  // sections to \param Sections, and optionally sets
202  // \param IsPageZeroSegment to true.
203  template <typename SegmentCmd>
parseSegmentLoadCommand(const MachOObjectFile * Obj,const MachOObjectFile::LoadCommandInfo & Load,SmallVectorImpl<const char * > & Sections,bool & IsPageZeroSegment)204  static std::error_code parseSegmentLoadCommand(
205      const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
206      SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment) {
207    const unsigned SegmentLoadSize = sizeof(SegmentCmd);
208    if (Load.C.cmdsize < SegmentLoadSize)
209      return object_error::macho_load_segment_too_small;
210    auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr);
211    if (!SegOrErr)
212      return SegOrErr.getError();
213    SegmentCmd S = SegOrErr.get();
214    const unsigned SectionSize =
215        Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section);
216    if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
217        S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
218      return object_error::macho_load_segment_too_many_sections;
219    for (unsigned J = 0; J < S.nsects; ++J) {
220      const char *Sec = getSectionPtr(Obj, Load, J);
221      Sections.push_back(Sec);
222    }
223    IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
224    return std::error_code();
225  }
226  
MachOObjectFile(MemoryBufferRef Object,bool IsLittleEndian,bool Is64bits,std::error_code & EC)227  MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
228                                   bool Is64bits, std::error_code &EC)
229      : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
230        SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
231        DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
232        DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
233        HasPageZeroSegment(false) {
234    if (is64Bit())
235      parseHeader(this, Header64, EC);
236    else
237      parseHeader(this, Header, EC);
238    if (EC)
239      return;
240  
241    uint32_t LoadCommandCount = getHeader().ncmds;
242    if (LoadCommandCount == 0)
243      return;
244  
245    auto LoadOrErr = getFirstLoadCommandInfo(this);
246    if (!LoadOrErr) {
247      EC = LoadOrErr.getError();
248      return;
249    }
250    LoadCommandInfo Load = LoadOrErr.get();
251    for (unsigned I = 0; I < LoadCommandCount; ++I) {
252      LoadCommands.push_back(Load);
253      if (Load.C.cmd == MachO::LC_SYMTAB) {
254        // Multiple symbol tables
255        if (SymtabLoadCmd) {
256          EC = object_error::parse_failed;
257          return;
258        }
259        SymtabLoadCmd = Load.Ptr;
260      } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
261        // Multiple dynamic symbol tables
262        if (DysymtabLoadCmd) {
263          EC = object_error::parse_failed;
264          return;
265        }
266        DysymtabLoadCmd = Load.Ptr;
267      } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
268        // Multiple data in code tables
269        if (DataInCodeLoadCmd) {
270          EC = object_error::parse_failed;
271          return;
272        }
273        DataInCodeLoadCmd = Load.Ptr;
274      } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
275        // Multiple linker optimization hint tables
276        if (LinkOptHintsLoadCmd) {
277          EC = object_error::parse_failed;
278          return;
279        }
280        LinkOptHintsLoadCmd = Load.Ptr;
281      } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
282                 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
283        // Multiple dyldinfo load commands
284        if (DyldInfoLoadCmd) {
285          EC = object_error::parse_failed;
286          return;
287        }
288        DyldInfoLoadCmd = Load.Ptr;
289      } else if (Load.C.cmd == MachO::LC_UUID) {
290        // Multiple UUID load commands
291        if (UuidLoadCmd) {
292          EC = object_error::parse_failed;
293          return;
294        }
295        UuidLoadCmd = Load.Ptr;
296      } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
297        if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>(
298                 this, Load, Sections, HasPageZeroSegment)))
299          return;
300      } else if (Load.C.cmd == MachO::LC_SEGMENT) {
301        if ((EC = parseSegmentLoadCommand<MachO::segment_command>(
302                 this, Load, Sections, HasPageZeroSegment)))
303          return;
304      } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
305                 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
306                 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
307                 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
308                 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
309        Libraries.push_back(Load.Ptr);
310      }
311      if (I < LoadCommandCount - 1) {
312        auto LoadOrErr = getNextLoadCommandInfo(this, Load);
313        if (!LoadOrErr) {
314          EC = LoadOrErr.getError();
315          return;
316        }
317        Load = LoadOrErr.get();
318      }
319    }
320    assert(LoadCommands.size() == LoadCommandCount);
321  }
322  
moveSymbolNext(DataRefImpl & Symb) const323  void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
324    unsigned SymbolTableEntrySize = is64Bit() ?
325      sizeof(MachO::nlist_64) :
326      sizeof(MachO::nlist);
327    Symb.p += SymbolTableEntrySize;
328  }
329  
getSymbolName(DataRefImpl Symb) const330  ErrorOr<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
331    StringRef StringTable = getStringTableData();
332    MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
333    const char *Start = &StringTable.data()[Entry.n_strx];
334    if (Start < getData().begin() || Start >= getData().end())
335      report_fatal_error(
336          "Symbol name entry points before beginning or past end of file.");
337    return StringRef(Start);
338  }
339  
getSectionType(SectionRef Sec) const340  unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
341    DataRefImpl DRI = Sec.getRawDataRefImpl();
342    uint32_t Flags = getSectionFlags(this, DRI);
343    return Flags & MachO::SECTION_TYPE;
344  }
345  
getNValue(DataRefImpl Sym) const346  uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
347    if (is64Bit()) {
348      MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
349      return Entry.n_value;
350    }
351    MachO::nlist Entry = getSymbolTableEntry(Sym);
352    return Entry.n_value;
353  }
354  
355  // getIndirectName() returns the name of the alias'ed symbol who's string table
356  // index is in the n_value field.
getIndirectName(DataRefImpl Symb,StringRef & Res) const357  std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
358                                                   StringRef &Res) const {
359    StringRef StringTable = getStringTableData();
360    MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
361    if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
362      return object_error::parse_failed;
363    uint64_t NValue = getNValue(Symb);
364    if (NValue >= StringTable.size())
365      return object_error::parse_failed;
366    const char *Start = &StringTable.data()[NValue];
367    Res = StringRef(Start);
368    return std::error_code();
369  }
370  
getSymbolValueImpl(DataRefImpl Sym) const371  uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
372    return getNValue(Sym);
373  }
374  
getSymbolAddress(DataRefImpl Sym) const375  ErrorOr<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
376    return getSymbolValue(Sym);
377  }
378  
getSymbolAlignment(DataRefImpl DRI) const379  uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
380    uint32_t flags = getSymbolFlags(DRI);
381    if (flags & SymbolRef::SF_Common) {
382      MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
383      return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
384    }
385    return 0;
386  }
387  
getCommonSymbolSizeImpl(DataRefImpl DRI) const388  uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
389    return getNValue(DRI);
390  }
391  
getSymbolType(DataRefImpl Symb) const392  SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
393    MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
394    uint8_t n_type = Entry.n_type;
395  
396    // If this is a STAB debugging symbol, we can do nothing more.
397    if (n_type & MachO::N_STAB)
398      return SymbolRef::ST_Debug;
399  
400    switch (n_type & MachO::N_TYPE) {
401      case MachO::N_UNDF :
402        return SymbolRef::ST_Unknown;
403      case MachO::N_SECT :
404        section_iterator Sec = *getSymbolSection(Symb);
405        if (Sec->isData() || Sec->isBSS())
406          return SymbolRef::ST_Data;
407        return SymbolRef::ST_Function;
408    }
409    return SymbolRef::ST_Other;
410  }
411  
getSymbolFlags(DataRefImpl DRI) const412  uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
413    MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
414  
415    uint8_t MachOType = Entry.n_type;
416    uint16_t MachOFlags = Entry.n_desc;
417  
418    uint32_t Result = SymbolRef::SF_None;
419  
420    if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
421      Result |= SymbolRef::SF_Indirect;
422  
423    if (MachOType & MachO::N_STAB)
424      Result |= SymbolRef::SF_FormatSpecific;
425  
426    if (MachOType & MachO::N_EXT) {
427      Result |= SymbolRef::SF_Global;
428      if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
429        if (getNValue(DRI))
430          Result |= SymbolRef::SF_Common;
431        else
432          Result |= SymbolRef::SF_Undefined;
433      }
434  
435      if (!(MachOType & MachO::N_PEXT))
436        Result |= SymbolRef::SF_Exported;
437    }
438  
439    if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
440      Result |= SymbolRef::SF_Weak;
441  
442    if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
443      Result |= SymbolRef::SF_Thumb;
444  
445    if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
446      Result |= SymbolRef::SF_Absolute;
447  
448    return Result;
449  }
450  
451  ErrorOr<section_iterator>
getSymbolSection(DataRefImpl Symb) const452  MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
453    MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
454    uint8_t index = Entry.n_sect;
455  
456    if (index == 0)
457      return section_end();
458    DataRefImpl DRI;
459    DRI.d.a = index - 1;
460    if (DRI.d.a >= Sections.size())
461      report_fatal_error("getSymbolSection: Invalid section index.");
462    return section_iterator(SectionRef(DRI, this));
463  }
464  
getSymbolSectionID(SymbolRef Sym) const465  unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
466    MachO::nlist_base Entry =
467        getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
468    return Entry.n_sect - 1;
469  }
470  
moveSectionNext(DataRefImpl & Sec) const471  void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
472    Sec.d.a++;
473  }
474  
getSectionName(DataRefImpl Sec,StringRef & Result) const475  std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
476                                                  StringRef &Result) const {
477    ArrayRef<char> Raw = getSectionRawName(Sec);
478    Result = parseSegmentOrSectionName(Raw.data());
479    return std::error_code();
480  }
481  
getSectionAddress(DataRefImpl Sec) const482  uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
483    if (is64Bit())
484      return getSection64(Sec).addr;
485    return getSection(Sec).addr;
486  }
487  
getSectionSize(DataRefImpl Sec) const488  uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
489    // In the case if a malformed Mach-O file where the section offset is past
490    // the end of the file or some part of the section size is past the end of
491    // the file return a size of zero or a size that covers the rest of the file
492    // but does not extend past the end of the file.
493    uint32_t SectOffset, SectType;
494    uint64_t SectSize;
495  
496    if (is64Bit()) {
497      MachO::section_64 Sect = getSection64(Sec);
498      SectOffset = Sect.offset;
499      SectSize = Sect.size;
500      SectType = Sect.flags & MachO::SECTION_TYPE;
501    } else {
502      MachO::section Sect = getSection(Sec);
503      SectOffset = Sect.offset;
504      SectSize = Sect.size;
505      SectType = Sect.flags & MachO::SECTION_TYPE;
506    }
507    if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
508      return SectSize;
509    uint64_t FileSize = getData().size();
510    if (SectOffset > FileSize)
511      return 0;
512    if (FileSize - SectOffset < SectSize)
513      return FileSize - SectOffset;
514    return SectSize;
515  }
516  
getSectionContents(DataRefImpl Sec,StringRef & Res) const517  std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
518                                                      StringRef &Res) const {
519    uint32_t Offset;
520    uint64_t Size;
521  
522    if (is64Bit()) {
523      MachO::section_64 Sect = getSection64(Sec);
524      Offset = Sect.offset;
525      Size = Sect.size;
526    } else {
527      MachO::section Sect = getSection(Sec);
528      Offset = Sect.offset;
529      Size = Sect.size;
530    }
531  
532    Res = this->getData().substr(Offset, Size);
533    return std::error_code();
534  }
535  
getSectionAlignment(DataRefImpl Sec) const536  uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
537    uint32_t Align;
538    if (is64Bit()) {
539      MachO::section_64 Sect = getSection64(Sec);
540      Align = Sect.align;
541    } else {
542      MachO::section Sect = getSection(Sec);
543      Align = Sect.align;
544    }
545  
546    return uint64_t(1) << Align;
547  }
548  
isSectionText(DataRefImpl Sec) const549  bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
550    uint32_t Flags = getSectionFlags(this, Sec);
551    return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
552  }
553  
isSectionData(DataRefImpl Sec) const554  bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
555    uint32_t Flags = getSectionFlags(this, Sec);
556    unsigned SectionType = Flags & MachO::SECTION_TYPE;
557    return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
558           !(SectionType == MachO::S_ZEROFILL ||
559             SectionType == MachO::S_GB_ZEROFILL);
560  }
561  
isSectionBSS(DataRefImpl Sec) const562  bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
563    uint32_t Flags = getSectionFlags(this, Sec);
564    unsigned SectionType = Flags & MachO::SECTION_TYPE;
565    return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
566           (SectionType == MachO::S_ZEROFILL ||
567            SectionType == MachO::S_GB_ZEROFILL);
568  }
569  
getSectionID(SectionRef Sec) const570  unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
571    return Sec.getRawDataRefImpl().d.a;
572  }
573  
isSectionVirtual(DataRefImpl Sec) const574  bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
575    // FIXME: Unimplemented.
576    return false;
577  }
578  
section_rel_begin(DataRefImpl Sec) const579  relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
580    DataRefImpl Ret;
581    Ret.d.a = Sec.d.a;
582    Ret.d.b = 0;
583    return relocation_iterator(RelocationRef(Ret, this));
584  }
585  
586  relocation_iterator
section_rel_end(DataRefImpl Sec) const587  MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
588    uint32_t Num;
589    if (is64Bit()) {
590      MachO::section_64 Sect = getSection64(Sec);
591      Num = Sect.nreloc;
592    } else {
593      MachO::section Sect = getSection(Sec);
594      Num = Sect.nreloc;
595    }
596  
597    DataRefImpl Ret;
598    Ret.d.a = Sec.d.a;
599    Ret.d.b = Num;
600    return relocation_iterator(RelocationRef(Ret, this));
601  }
602  
moveRelocationNext(DataRefImpl & Rel) const603  void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
604    ++Rel.d.b;
605  }
606  
getRelocationOffset(DataRefImpl Rel) const607  uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
608    assert(getHeader().filetype == MachO::MH_OBJECT &&
609           "Only implemented for MH_OBJECT");
610    MachO::any_relocation_info RE = getRelocation(Rel);
611    return getAnyRelocationAddress(RE);
612  }
613  
614  symbol_iterator
getRelocationSymbol(DataRefImpl Rel) const615  MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
616    MachO::any_relocation_info RE = getRelocation(Rel);
617    if (isRelocationScattered(RE))
618      return symbol_end();
619  
620    uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
621    bool isExtern = getPlainRelocationExternal(RE);
622    if (!isExtern)
623      return symbol_end();
624  
625    MachO::symtab_command S = getSymtabLoadCommand();
626    unsigned SymbolTableEntrySize = is64Bit() ?
627      sizeof(MachO::nlist_64) :
628      sizeof(MachO::nlist);
629    uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
630    DataRefImpl Sym;
631    Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
632    return symbol_iterator(SymbolRef(Sym, this));
633  }
634  
635  section_iterator
getRelocationSection(DataRefImpl Rel) const636  MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
637    return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
638  }
639  
getRelocationType(DataRefImpl Rel) const640  uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
641    MachO::any_relocation_info RE = getRelocation(Rel);
642    return getAnyRelocationType(RE);
643  }
644  
getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result) const645  void MachOObjectFile::getRelocationTypeName(
646      DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
647    StringRef res;
648    uint64_t RType = getRelocationType(Rel);
649  
650    unsigned Arch = this->getArch();
651  
652    switch (Arch) {
653      case Triple::x86: {
654        static const char *const Table[] =  {
655          "GENERIC_RELOC_VANILLA",
656          "GENERIC_RELOC_PAIR",
657          "GENERIC_RELOC_SECTDIFF",
658          "GENERIC_RELOC_PB_LA_PTR",
659          "GENERIC_RELOC_LOCAL_SECTDIFF",
660          "GENERIC_RELOC_TLV" };
661  
662        if (RType > 5)
663          res = "Unknown";
664        else
665          res = Table[RType];
666        break;
667      }
668      case Triple::x86_64: {
669        static const char *const Table[] =  {
670          "X86_64_RELOC_UNSIGNED",
671          "X86_64_RELOC_SIGNED",
672          "X86_64_RELOC_BRANCH",
673          "X86_64_RELOC_GOT_LOAD",
674          "X86_64_RELOC_GOT",
675          "X86_64_RELOC_SUBTRACTOR",
676          "X86_64_RELOC_SIGNED_1",
677          "X86_64_RELOC_SIGNED_2",
678          "X86_64_RELOC_SIGNED_4",
679          "X86_64_RELOC_TLV" };
680  
681        if (RType > 9)
682          res = "Unknown";
683        else
684          res = Table[RType];
685        break;
686      }
687      case Triple::arm: {
688        static const char *const Table[] =  {
689          "ARM_RELOC_VANILLA",
690          "ARM_RELOC_PAIR",
691          "ARM_RELOC_SECTDIFF",
692          "ARM_RELOC_LOCAL_SECTDIFF",
693          "ARM_RELOC_PB_LA_PTR",
694          "ARM_RELOC_BR24",
695          "ARM_THUMB_RELOC_BR22",
696          "ARM_THUMB_32BIT_BRANCH",
697          "ARM_RELOC_HALF",
698          "ARM_RELOC_HALF_SECTDIFF" };
699  
700        if (RType > 9)
701          res = "Unknown";
702        else
703          res = Table[RType];
704        break;
705      }
706      case Triple::aarch64: {
707        static const char *const Table[] = {
708          "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
709          "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
710          "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
711          "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
712          "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
713          "ARM64_RELOC_ADDEND"
714        };
715  
716        if (RType >= array_lengthof(Table))
717          res = "Unknown";
718        else
719          res = Table[RType];
720        break;
721      }
722      case Triple::ppc: {
723        static const char *const Table[] =  {
724          "PPC_RELOC_VANILLA",
725          "PPC_RELOC_PAIR",
726          "PPC_RELOC_BR14",
727          "PPC_RELOC_BR24",
728          "PPC_RELOC_HI16",
729          "PPC_RELOC_LO16",
730          "PPC_RELOC_HA16",
731          "PPC_RELOC_LO14",
732          "PPC_RELOC_SECTDIFF",
733          "PPC_RELOC_PB_LA_PTR",
734          "PPC_RELOC_HI16_SECTDIFF",
735          "PPC_RELOC_LO16_SECTDIFF",
736          "PPC_RELOC_HA16_SECTDIFF",
737          "PPC_RELOC_JBSR",
738          "PPC_RELOC_LO14_SECTDIFF",
739          "PPC_RELOC_LOCAL_SECTDIFF" };
740  
741        if (RType > 15)
742          res = "Unknown";
743        else
744          res = Table[RType];
745        break;
746      }
747      case Triple::UnknownArch:
748        res = "Unknown";
749        break;
750    }
751    Result.append(res.begin(), res.end());
752  }
753  
getRelocationLength(DataRefImpl Rel) const754  uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
755    MachO::any_relocation_info RE = getRelocation(Rel);
756    return getAnyRelocationLength(RE);
757  }
758  
759  //
760  // guessLibraryShortName() is passed a name of a dynamic library and returns a
761  // guess on what the short name is.  Then name is returned as a substring of the
762  // StringRef Name passed in.  The name of the dynamic library is recognized as
763  // a framework if it has one of the two following forms:
764  //      Foo.framework/Versions/A/Foo
765  //      Foo.framework/Foo
766  // Where A and Foo can be any string.  And may contain a trailing suffix
767  // starting with an underbar.  If the Name is recognized as a framework then
768  // isFramework is set to true else it is set to false.  If the Name has a
769  // suffix then Suffix is set to the substring in Name that contains the suffix
770  // else it is set to a NULL StringRef.
771  //
772  // The Name of the dynamic library is recognized as a library name if it has
773  // one of the two following forms:
774  //      libFoo.A.dylib
775  //      libFoo.dylib
776  // The library may have a suffix trailing the name Foo of the form:
777  //      libFoo_profile.A.dylib
778  //      libFoo_profile.dylib
779  //
780  // The Name of the dynamic library is also recognized as a library name if it
781  // has the following form:
782  //      Foo.qtx
783  //
784  // If the Name of the dynamic library is none of the forms above then a NULL
785  // StringRef is returned.
786  //
guessLibraryShortName(StringRef Name,bool & isFramework,StringRef & Suffix)787  StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
788                                                   bool &isFramework,
789                                                   StringRef &Suffix) {
790    StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
791    size_t a, b, c, d, Idx;
792  
793    isFramework = false;
794    Suffix = StringRef();
795  
796    // Pull off the last component and make Foo point to it
797    a = Name.rfind('/');
798    if (a == Name.npos || a == 0)
799      goto guess_library;
800    Foo = Name.slice(a+1, Name.npos);
801  
802    // Look for a suffix starting with a '_'
803    Idx = Foo.rfind('_');
804    if (Idx != Foo.npos && Foo.size() >= 2) {
805      Suffix = Foo.slice(Idx, Foo.npos);
806      Foo = Foo.slice(0, Idx);
807    }
808  
809    // First look for the form Foo.framework/Foo
810    b = Name.rfind('/', a);
811    if (b == Name.npos)
812      Idx = 0;
813    else
814      Idx = b+1;
815    F = Name.slice(Idx, Idx + Foo.size());
816    DotFramework = Name.slice(Idx + Foo.size(),
817                              Idx + Foo.size() + sizeof(".framework/")-1);
818    if (F == Foo && DotFramework == ".framework/") {
819      isFramework = true;
820      return Foo;
821    }
822  
823    // Next look for the form Foo.framework/Versions/A/Foo
824    if (b == Name.npos)
825      goto guess_library;
826    c =  Name.rfind('/', b);
827    if (c == Name.npos || c == 0)
828      goto guess_library;
829    V = Name.slice(c+1, Name.npos);
830    if (!V.startswith("Versions/"))
831      goto guess_library;
832    d =  Name.rfind('/', c);
833    if (d == Name.npos)
834      Idx = 0;
835    else
836      Idx = d+1;
837    F = Name.slice(Idx, Idx + Foo.size());
838    DotFramework = Name.slice(Idx + Foo.size(),
839                              Idx + Foo.size() + sizeof(".framework/")-1);
840    if (F == Foo && DotFramework == ".framework/") {
841      isFramework = true;
842      return Foo;
843    }
844  
845  guess_library:
846    // pull off the suffix after the "." and make a point to it
847    a = Name.rfind('.');
848    if (a == Name.npos || a == 0)
849      return StringRef();
850    Dylib = Name.slice(a, Name.npos);
851    if (Dylib != ".dylib")
852      goto guess_qtx;
853  
854    // First pull off the version letter for the form Foo.A.dylib if any.
855    if (a >= 3) {
856      Dot = Name.slice(a-2, a-1);
857      if (Dot == ".")
858        a = a - 2;
859    }
860  
861    b = Name.rfind('/', a);
862    if (b == Name.npos)
863      b = 0;
864    else
865      b = b+1;
866    // ignore any suffix after an underbar like Foo_profile.A.dylib
867    Idx = Name.find('_', b);
868    if (Idx != Name.npos && Idx != b) {
869      Lib = Name.slice(b, Idx);
870      Suffix = Name.slice(Idx, a);
871    }
872    else
873      Lib = Name.slice(b, a);
874    // There are incorrect library names of the form:
875    // libATS.A_profile.dylib so check for these.
876    if (Lib.size() >= 3) {
877      Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
878      if (Dot == ".")
879        Lib = Lib.slice(0, Lib.size()-2);
880    }
881    return Lib;
882  
883  guess_qtx:
884    Qtx = Name.slice(a, Name.npos);
885    if (Qtx != ".qtx")
886      return StringRef();
887    b = Name.rfind('/', a);
888    if (b == Name.npos)
889      Lib = Name.slice(0, a);
890    else
891      Lib = Name.slice(b+1, a);
892    // There are library names of the form: QT.A.qtx so check for these.
893    if (Lib.size() >= 3) {
894      Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
895      if (Dot == ".")
896        Lib = Lib.slice(0, Lib.size()-2);
897    }
898    return Lib;
899  }
900  
901  // getLibraryShortNameByIndex() is used to get the short name of the library
902  // for an undefined symbol in a linked Mach-O binary that was linked with the
903  // normal two-level namespace default (that is MH_TWOLEVEL in the header).
904  // It is passed the index (0 - based) of the library as translated from
905  // GET_LIBRARY_ORDINAL (1 - based).
getLibraryShortNameByIndex(unsigned Index,StringRef & Res) const906  std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
907                                                           StringRef &Res) const {
908    if (Index >= Libraries.size())
909      return object_error::parse_failed;
910  
911    // If the cache of LibrariesShortNames is not built up do that first for
912    // all the Libraries.
913    if (LibrariesShortNames.size() == 0) {
914      for (unsigned i = 0; i < Libraries.size(); i++) {
915        MachO::dylib_command D =
916          getStruct<MachO::dylib_command>(this, Libraries[i]);
917        if (D.dylib.name >= D.cmdsize)
918          return object_error::parse_failed;
919        const char *P = (const char *)(Libraries[i]) + D.dylib.name;
920        StringRef Name = StringRef(P);
921        if (D.dylib.name+Name.size() >= D.cmdsize)
922          return object_error::parse_failed;
923        StringRef Suffix;
924        bool isFramework;
925        StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
926        if (shortName.empty())
927          LibrariesShortNames.push_back(Name);
928        else
929          LibrariesShortNames.push_back(shortName);
930      }
931    }
932  
933    Res = LibrariesShortNames[Index];
934    return std::error_code();
935  }
936  
937  section_iterator
getRelocationRelocatedSection(relocation_iterator Rel) const938  MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
939    DataRefImpl Sec;
940    Sec.d.a = Rel->getRawDataRefImpl().d.a;
941    return section_iterator(SectionRef(Sec, this));
942  }
943  
symbol_begin_impl() const944  basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
945    return getSymbolByIndex(0);
946  }
947  
symbol_end_impl() const948  basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
949    DataRefImpl DRI;
950    if (!SymtabLoadCmd)
951      return basic_symbol_iterator(SymbolRef(DRI, this));
952  
953    MachO::symtab_command Symtab = getSymtabLoadCommand();
954    unsigned SymbolTableEntrySize = is64Bit() ?
955      sizeof(MachO::nlist_64) :
956      sizeof(MachO::nlist);
957    unsigned Offset = Symtab.symoff +
958      Symtab.nsyms * SymbolTableEntrySize;
959    DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
960    return basic_symbol_iterator(SymbolRef(DRI, this));
961  }
962  
getSymbolByIndex(unsigned Index) const963  basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
964    DataRefImpl DRI;
965    if (!SymtabLoadCmd)
966      return basic_symbol_iterator(SymbolRef(DRI, this));
967  
968    MachO::symtab_command Symtab = getSymtabLoadCommand();
969    if (Index >= Symtab.nsyms)
970      report_fatal_error("Requested symbol index is out of range.");
971    unsigned SymbolTableEntrySize =
972      is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
973    DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
974    DRI.p += Index * SymbolTableEntrySize;
975    return basic_symbol_iterator(SymbolRef(DRI, this));
976  }
977  
section_begin() const978  section_iterator MachOObjectFile::section_begin() const {
979    DataRefImpl DRI;
980    return section_iterator(SectionRef(DRI, this));
981  }
982  
section_end() const983  section_iterator MachOObjectFile::section_end() const {
984    DataRefImpl DRI;
985    DRI.d.a = Sections.size();
986    return section_iterator(SectionRef(DRI, this));
987  }
988  
getBytesInAddress() const989  uint8_t MachOObjectFile::getBytesInAddress() const {
990    return is64Bit() ? 8 : 4;
991  }
992  
getFileFormatName() const993  StringRef MachOObjectFile::getFileFormatName() const {
994    unsigned CPUType = getCPUType(this);
995    if (!is64Bit()) {
996      switch (CPUType) {
997      case llvm::MachO::CPU_TYPE_I386:
998        return "Mach-O 32-bit i386";
999      case llvm::MachO::CPU_TYPE_ARM:
1000        return "Mach-O arm";
1001      case llvm::MachO::CPU_TYPE_POWERPC:
1002        return "Mach-O 32-bit ppc";
1003      default:
1004        return "Mach-O 32-bit unknown";
1005      }
1006    }
1007  
1008    switch (CPUType) {
1009    case llvm::MachO::CPU_TYPE_X86_64:
1010      return "Mach-O 64-bit x86-64";
1011    case llvm::MachO::CPU_TYPE_ARM64:
1012      return "Mach-O arm64";
1013    case llvm::MachO::CPU_TYPE_POWERPC64:
1014      return "Mach-O 64-bit ppc64";
1015    default:
1016      return "Mach-O 64-bit unknown";
1017    }
1018  }
1019  
getArch(uint32_t CPUType)1020  Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1021    switch (CPUType) {
1022    case llvm::MachO::CPU_TYPE_I386:
1023      return Triple::x86;
1024    case llvm::MachO::CPU_TYPE_X86_64:
1025      return Triple::x86_64;
1026    case llvm::MachO::CPU_TYPE_ARM:
1027      return Triple::arm;
1028    case llvm::MachO::CPU_TYPE_ARM64:
1029      return Triple::aarch64;
1030    case llvm::MachO::CPU_TYPE_POWERPC:
1031      return Triple::ppc;
1032    case llvm::MachO::CPU_TYPE_POWERPC64:
1033      return Triple::ppc64;
1034    default:
1035      return Triple::UnknownArch;
1036    }
1037  }
1038  
getArch(uint32_t CPUType,uint32_t CPUSubType,const char ** McpuDefault)1039  Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1040                                  const char **McpuDefault) {
1041    if (McpuDefault)
1042      *McpuDefault = nullptr;
1043  
1044    switch (CPUType) {
1045    case MachO::CPU_TYPE_I386:
1046      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1047      case MachO::CPU_SUBTYPE_I386_ALL:
1048        return Triple("i386-apple-darwin");
1049      default:
1050        return Triple();
1051      }
1052    case MachO::CPU_TYPE_X86_64:
1053      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1054      case MachO::CPU_SUBTYPE_X86_64_ALL:
1055        return Triple("x86_64-apple-darwin");
1056      case MachO::CPU_SUBTYPE_X86_64_H:
1057        return Triple("x86_64h-apple-darwin");
1058      default:
1059        return Triple();
1060      }
1061    case MachO::CPU_TYPE_ARM:
1062      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1063      case MachO::CPU_SUBTYPE_ARM_V4T:
1064        return Triple("armv4t-apple-darwin");
1065      case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1066        return Triple("armv5e-apple-darwin");
1067      case MachO::CPU_SUBTYPE_ARM_XSCALE:
1068        return Triple("xscale-apple-darwin");
1069      case MachO::CPU_SUBTYPE_ARM_V6:
1070        return Triple("armv6-apple-darwin");
1071      case MachO::CPU_SUBTYPE_ARM_V6M:
1072        if (McpuDefault)
1073          *McpuDefault = "cortex-m0";
1074        return Triple("armv6m-apple-darwin");
1075      case MachO::CPU_SUBTYPE_ARM_V7:
1076        return Triple("armv7-apple-darwin");
1077      case MachO::CPU_SUBTYPE_ARM_V7EM:
1078        if (McpuDefault)
1079          *McpuDefault = "cortex-m4";
1080        return Triple("armv7em-apple-darwin");
1081      case MachO::CPU_SUBTYPE_ARM_V7K:
1082        return Triple("armv7k-apple-darwin");
1083      case MachO::CPU_SUBTYPE_ARM_V7M:
1084        if (McpuDefault)
1085          *McpuDefault = "cortex-m3";
1086        return Triple("armv7m-apple-darwin");
1087      case MachO::CPU_SUBTYPE_ARM_V7S:
1088        return Triple("armv7s-apple-darwin");
1089      default:
1090        return Triple();
1091      }
1092    case MachO::CPU_TYPE_ARM64:
1093      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1094      case MachO::CPU_SUBTYPE_ARM64_ALL:
1095        return Triple("arm64-apple-darwin");
1096      default:
1097        return Triple();
1098      }
1099    case MachO::CPU_TYPE_POWERPC:
1100      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1101      case MachO::CPU_SUBTYPE_POWERPC_ALL:
1102        return Triple("ppc-apple-darwin");
1103      default:
1104        return Triple();
1105      }
1106    case MachO::CPU_TYPE_POWERPC64:
1107      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1108      case MachO::CPU_SUBTYPE_POWERPC_ALL:
1109        return Triple("ppc64-apple-darwin");
1110      default:
1111        return Triple();
1112      }
1113    default:
1114      return Triple();
1115    }
1116  }
1117  
getThumbArch(uint32_t CPUType,uint32_t CPUSubType,const char ** McpuDefault)1118  Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1119                                       const char **McpuDefault) {
1120    if (McpuDefault)
1121      *McpuDefault = nullptr;
1122  
1123    switch (CPUType) {
1124    case MachO::CPU_TYPE_ARM:
1125      switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1126      case MachO::CPU_SUBTYPE_ARM_V4T:
1127        return Triple("thumbv4t-apple-darwin");
1128      case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1129        return Triple("thumbv5e-apple-darwin");
1130      case MachO::CPU_SUBTYPE_ARM_XSCALE:
1131        return Triple("xscale-apple-darwin");
1132      case MachO::CPU_SUBTYPE_ARM_V6:
1133        return Triple("thumbv6-apple-darwin");
1134      case MachO::CPU_SUBTYPE_ARM_V6M:
1135        if (McpuDefault)
1136          *McpuDefault = "cortex-m0";
1137        return Triple("thumbv6m-apple-darwin");
1138      case MachO::CPU_SUBTYPE_ARM_V7:
1139        return Triple("thumbv7-apple-darwin");
1140      case MachO::CPU_SUBTYPE_ARM_V7EM:
1141        if (McpuDefault)
1142          *McpuDefault = "cortex-m4";
1143        return Triple("thumbv7em-apple-darwin");
1144      case MachO::CPU_SUBTYPE_ARM_V7K:
1145        return Triple("thumbv7k-apple-darwin");
1146      case MachO::CPU_SUBTYPE_ARM_V7M:
1147        if (McpuDefault)
1148          *McpuDefault = "cortex-m3";
1149        return Triple("thumbv7m-apple-darwin");
1150      case MachO::CPU_SUBTYPE_ARM_V7S:
1151        return Triple("thumbv7s-apple-darwin");
1152      default:
1153        return Triple();
1154      }
1155    default:
1156      return Triple();
1157    }
1158  }
1159  
getArch(uint32_t CPUType,uint32_t CPUSubType,const char ** McpuDefault,Triple * ThumbTriple)1160  Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1161                                  const char **McpuDefault, Triple *ThumbTriple) {
1162    Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1163    *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1164                                                 McpuDefault);
1165    return T;
1166  }
1167  
getHostArch()1168  Triple MachOObjectFile::getHostArch() {
1169    return Triple(sys::getDefaultTargetTriple());
1170  }
1171  
isValidArch(StringRef ArchFlag)1172  bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1173    return StringSwitch<bool>(ArchFlag)
1174        .Case("i386", true)
1175        .Case("x86_64", true)
1176        .Case("x86_64h", true)
1177        .Case("armv4t", true)
1178        .Case("arm", true)
1179        .Case("armv5e", true)
1180        .Case("armv6", true)
1181        .Case("armv6m", true)
1182        .Case("armv7", true)
1183        .Case("armv7em", true)
1184        .Case("armv7k", true)
1185        .Case("armv7m", true)
1186        .Case("armv7s", true)
1187        .Case("arm64", true)
1188        .Case("ppc", true)
1189        .Case("ppc64", true)
1190        .Default(false);
1191  }
1192  
getArch() const1193  unsigned MachOObjectFile::getArch() const {
1194    return getArch(getCPUType(this));
1195  }
1196  
getArch(const char ** McpuDefault,Triple * ThumbTriple) const1197  Triple MachOObjectFile::getArch(const char **McpuDefault,
1198                                  Triple *ThumbTriple) const {
1199    *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1200    return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1201  }
1202  
section_rel_begin(unsigned Index) const1203  relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1204    DataRefImpl DRI;
1205    DRI.d.a = Index;
1206    return section_rel_begin(DRI);
1207  }
1208  
section_rel_end(unsigned Index) const1209  relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1210    DataRefImpl DRI;
1211    DRI.d.a = Index;
1212    return section_rel_end(DRI);
1213  }
1214  
begin_dices() const1215  dice_iterator MachOObjectFile::begin_dices() const {
1216    DataRefImpl DRI;
1217    if (!DataInCodeLoadCmd)
1218      return dice_iterator(DiceRef(DRI, this));
1219  
1220    MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1221    DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1222    return dice_iterator(DiceRef(DRI, this));
1223  }
1224  
end_dices() const1225  dice_iterator MachOObjectFile::end_dices() const {
1226    DataRefImpl DRI;
1227    if (!DataInCodeLoadCmd)
1228      return dice_iterator(DiceRef(DRI, this));
1229  
1230    MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1231    unsigned Offset = DicLC.dataoff + DicLC.datasize;
1232    DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1233    return dice_iterator(DiceRef(DRI, this));
1234  }
1235  
ExportEntry(ArrayRef<uint8_t> T)1236  ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1237      : Trie(T), Malformed(false), Done(false) {}
1238  
moveToFirst()1239  void ExportEntry::moveToFirst() {
1240    pushNode(0);
1241    pushDownUntilBottom();
1242  }
1243  
moveToEnd()1244  void ExportEntry::moveToEnd() {
1245    Stack.clear();
1246    Done = true;
1247  }
1248  
operator ==(const ExportEntry & Other) const1249  bool ExportEntry::operator==(const ExportEntry &Other) const {
1250    // Common case, one at end, other iterating from begin.
1251    if (Done || Other.Done)
1252      return (Done == Other.Done);
1253    // Not equal if different stack sizes.
1254    if (Stack.size() != Other.Stack.size())
1255      return false;
1256    // Not equal if different cumulative strings.
1257    if (!CumulativeString.equals(Other.CumulativeString))
1258      return false;
1259    // Equal if all nodes in both stacks match.
1260    for (unsigned i=0; i < Stack.size(); ++i) {
1261      if (Stack[i].Start != Other.Stack[i].Start)
1262        return false;
1263    }
1264    return true;
1265  }
1266  
readULEB128(const uint8_t * & Ptr)1267  uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1268    unsigned Count;
1269    uint64_t Result = decodeULEB128(Ptr, &Count);
1270    Ptr += Count;
1271    if (Ptr > Trie.end()) {
1272      Ptr = Trie.end();
1273      Malformed = true;
1274    }
1275    return Result;
1276  }
1277  
name() const1278  StringRef ExportEntry::name() const {
1279    return CumulativeString;
1280  }
1281  
flags() const1282  uint64_t ExportEntry::flags() const {
1283    return Stack.back().Flags;
1284  }
1285  
address() const1286  uint64_t ExportEntry::address() const {
1287    return Stack.back().Address;
1288  }
1289  
other() const1290  uint64_t ExportEntry::other() const {
1291    return Stack.back().Other;
1292  }
1293  
otherName() const1294  StringRef ExportEntry::otherName() const {
1295    const char* ImportName = Stack.back().ImportName;
1296    if (ImportName)
1297      return StringRef(ImportName);
1298    return StringRef();
1299  }
1300  
nodeOffset() const1301  uint32_t ExportEntry::nodeOffset() const {
1302    return Stack.back().Start - Trie.begin();
1303  }
1304  
NodeState(const uint8_t * Ptr)1305  ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1306      : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1307        ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1308        ParentStringLength(0), IsExportNode(false) {}
1309  
pushNode(uint64_t offset)1310  void ExportEntry::pushNode(uint64_t offset) {
1311    const uint8_t *Ptr = Trie.begin() + offset;
1312    NodeState State(Ptr);
1313    uint64_t ExportInfoSize = readULEB128(State.Current);
1314    State.IsExportNode = (ExportInfoSize != 0);
1315    const uint8_t* Children = State.Current + ExportInfoSize;
1316    if (State.IsExportNode) {
1317      State.Flags = readULEB128(State.Current);
1318      if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1319        State.Address = 0;
1320        State.Other = readULEB128(State.Current); // dylib ordinal
1321        State.ImportName = reinterpret_cast<const char*>(State.Current);
1322      } else {
1323        State.Address = readULEB128(State.Current);
1324        if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1325          State.Other = readULEB128(State.Current);
1326      }
1327    }
1328    State.ChildCount = *Children;
1329    State.Current = Children + 1;
1330    State.NextChildIndex = 0;
1331    State.ParentStringLength = CumulativeString.size();
1332    Stack.push_back(State);
1333  }
1334  
pushDownUntilBottom()1335  void ExportEntry::pushDownUntilBottom() {
1336    while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1337      NodeState &Top = Stack.back();
1338      CumulativeString.resize(Top.ParentStringLength);
1339      for (;*Top.Current != 0; Top.Current++) {
1340        char C = *Top.Current;
1341        CumulativeString.push_back(C);
1342      }
1343      Top.Current += 1;
1344      uint64_t childNodeIndex = readULEB128(Top.Current);
1345      Top.NextChildIndex += 1;
1346      pushNode(childNodeIndex);
1347    }
1348    if (!Stack.back().IsExportNode) {
1349      Malformed = true;
1350      moveToEnd();
1351    }
1352  }
1353  
1354  // We have a trie data structure and need a way to walk it that is compatible
1355  // with the C++ iterator model. The solution is a non-recursive depth first
1356  // traversal where the iterator contains a stack of parent nodes along with a
1357  // string that is the accumulation of all edge strings along the parent chain
1358  // to this point.
1359  //
1360  // There is one "export" node for each exported symbol.  But because some
1361  // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1362  // node may have child nodes too.
1363  //
1364  // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1365  // child until hitting a node with no children (which is an export node or
1366  // else the trie is malformed). On the way down, each node is pushed on the
1367  // stack ivar.  If there is no more ways down, it pops up one and tries to go
1368  // down a sibling path until a childless node is reached.
moveNext()1369  void ExportEntry::moveNext() {
1370    if (Stack.empty() || !Stack.back().IsExportNode) {
1371      Malformed = true;
1372      moveToEnd();
1373      return;
1374    }
1375  
1376    Stack.pop_back();
1377    while (!Stack.empty()) {
1378      NodeState &Top = Stack.back();
1379      if (Top.NextChildIndex < Top.ChildCount) {
1380        pushDownUntilBottom();
1381        // Now at the next export node.
1382        return;
1383      } else {
1384        if (Top.IsExportNode) {
1385          // This node has no children but is itself an export node.
1386          CumulativeString.resize(Top.ParentStringLength);
1387          return;
1388        }
1389        Stack.pop_back();
1390      }
1391    }
1392    Done = true;
1393  }
1394  
1395  iterator_range<export_iterator>
exports(ArrayRef<uint8_t> Trie)1396  MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1397    ExportEntry Start(Trie);
1398    if (Trie.size() == 0)
1399      Start.moveToEnd();
1400    else
1401      Start.moveToFirst();
1402  
1403    ExportEntry Finish(Trie);
1404    Finish.moveToEnd();
1405  
1406    return make_range(export_iterator(Start), export_iterator(Finish));
1407  }
1408  
exports() const1409  iterator_range<export_iterator> MachOObjectFile::exports() const {
1410    return exports(getDyldInfoExportsTrie());
1411  }
1412  
MachORebaseEntry(ArrayRef<uint8_t> Bytes,bool is64Bit)1413  MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1414      : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1415        RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1416        PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1417  
moveToFirst()1418  void MachORebaseEntry::moveToFirst() {
1419    Ptr = Opcodes.begin();
1420    moveNext();
1421  }
1422  
moveToEnd()1423  void MachORebaseEntry::moveToEnd() {
1424    Ptr = Opcodes.end();
1425    RemainingLoopCount = 0;
1426    Done = true;
1427  }
1428  
moveNext()1429  void MachORebaseEntry::moveNext() {
1430    // If in the middle of some loop, move to next rebasing in loop.
1431    SegmentOffset += AdvanceAmount;
1432    if (RemainingLoopCount) {
1433      --RemainingLoopCount;
1434      return;
1435    }
1436    if (Ptr == Opcodes.end()) {
1437      Done = true;
1438      return;
1439    }
1440    bool More = true;
1441    while (More && !Malformed) {
1442      // Parse next opcode and set up next loop.
1443      uint8_t Byte = *Ptr++;
1444      uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1445      uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1446      switch (Opcode) {
1447      case MachO::REBASE_OPCODE_DONE:
1448        More = false;
1449        Done = true;
1450        moveToEnd();
1451        DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1452        break;
1453      case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1454        RebaseType = ImmValue;
1455        DEBUG_WITH_TYPE(
1456            "mach-o-rebase",
1457            llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1458                         << "RebaseType=" << (int) RebaseType << "\n");
1459        break;
1460      case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1461        SegmentIndex = ImmValue;
1462        SegmentOffset = readULEB128();
1463        DEBUG_WITH_TYPE(
1464            "mach-o-rebase",
1465            llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1466                         << "SegmentIndex=" << SegmentIndex << ", "
1467                         << format("SegmentOffset=0x%06X", SegmentOffset)
1468                         << "\n");
1469        break;
1470      case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1471        SegmentOffset += readULEB128();
1472        DEBUG_WITH_TYPE("mach-o-rebase",
1473                        llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1474                                     << format("SegmentOffset=0x%06X",
1475                                               SegmentOffset) << "\n");
1476        break;
1477      case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1478        SegmentOffset += ImmValue * PointerSize;
1479        DEBUG_WITH_TYPE("mach-o-rebase",
1480                        llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1481                                     << format("SegmentOffset=0x%06X",
1482                                               SegmentOffset) << "\n");
1483        break;
1484      case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1485        AdvanceAmount = PointerSize;
1486        RemainingLoopCount = ImmValue - 1;
1487        DEBUG_WITH_TYPE(
1488            "mach-o-rebase",
1489            llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1490                         << format("SegmentOffset=0x%06X", SegmentOffset)
1491                         << ", AdvanceAmount=" << AdvanceAmount
1492                         << ", RemainingLoopCount=" << RemainingLoopCount
1493                         << "\n");
1494        return;
1495      case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1496        AdvanceAmount = PointerSize;
1497        RemainingLoopCount = readULEB128() - 1;
1498        DEBUG_WITH_TYPE(
1499            "mach-o-rebase",
1500            llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1501                         << format("SegmentOffset=0x%06X", SegmentOffset)
1502                         << ", AdvanceAmount=" << AdvanceAmount
1503                         << ", RemainingLoopCount=" << RemainingLoopCount
1504                         << "\n");
1505        return;
1506      case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1507        AdvanceAmount = readULEB128() + PointerSize;
1508        RemainingLoopCount = 0;
1509        DEBUG_WITH_TYPE(
1510            "mach-o-rebase",
1511            llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1512                         << format("SegmentOffset=0x%06X", SegmentOffset)
1513                         << ", AdvanceAmount=" << AdvanceAmount
1514                         << ", RemainingLoopCount=" << RemainingLoopCount
1515                         << "\n");
1516        return;
1517      case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1518        RemainingLoopCount = readULEB128() - 1;
1519        AdvanceAmount = readULEB128() + PointerSize;
1520        DEBUG_WITH_TYPE(
1521            "mach-o-rebase",
1522            llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1523                         << format("SegmentOffset=0x%06X", SegmentOffset)
1524                         << ", AdvanceAmount=" << AdvanceAmount
1525                         << ", RemainingLoopCount=" << RemainingLoopCount
1526                         << "\n");
1527        return;
1528      default:
1529        Malformed = true;
1530      }
1531    }
1532  }
1533  
readULEB128()1534  uint64_t MachORebaseEntry::readULEB128() {
1535    unsigned Count;
1536    uint64_t Result = decodeULEB128(Ptr, &Count);
1537    Ptr += Count;
1538    if (Ptr > Opcodes.end()) {
1539      Ptr = Opcodes.end();
1540      Malformed = true;
1541    }
1542    return Result;
1543  }
1544  
segmentIndex() const1545  uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1546  
segmentOffset() const1547  uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1548  
typeName() const1549  StringRef MachORebaseEntry::typeName() const {
1550    switch (RebaseType) {
1551    case MachO::REBASE_TYPE_POINTER:
1552      return "pointer";
1553    case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1554      return "text abs32";
1555    case MachO::REBASE_TYPE_TEXT_PCREL32:
1556      return "text rel32";
1557    }
1558    return "unknown";
1559  }
1560  
operator ==(const MachORebaseEntry & Other) const1561  bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1562    assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1563    return (Ptr == Other.Ptr) &&
1564           (RemainingLoopCount == Other.RemainingLoopCount) &&
1565           (Done == Other.Done);
1566  }
1567  
1568  iterator_range<rebase_iterator>
rebaseTable(ArrayRef<uint8_t> Opcodes,bool is64)1569  MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1570    MachORebaseEntry Start(Opcodes, is64);
1571    Start.moveToFirst();
1572  
1573    MachORebaseEntry Finish(Opcodes, is64);
1574    Finish.moveToEnd();
1575  
1576    return make_range(rebase_iterator(Start), rebase_iterator(Finish));
1577  }
1578  
rebaseTable() const1579  iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1580    return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1581  }
1582  
MachOBindEntry(ArrayRef<uint8_t> Bytes,bool is64Bit,Kind BK)1583  MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
1584      : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1585        Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1586        BindType(0), PointerSize(is64Bit ? 8 : 4),
1587        TableKind(BK), Malformed(false), Done(false) {}
1588  
moveToFirst()1589  void MachOBindEntry::moveToFirst() {
1590    Ptr = Opcodes.begin();
1591    moveNext();
1592  }
1593  
moveToEnd()1594  void MachOBindEntry::moveToEnd() {
1595    Ptr = Opcodes.end();
1596    RemainingLoopCount = 0;
1597    Done = true;
1598  }
1599  
moveNext()1600  void MachOBindEntry::moveNext() {
1601    // If in the middle of some loop, move to next binding in loop.
1602    SegmentOffset += AdvanceAmount;
1603    if (RemainingLoopCount) {
1604      --RemainingLoopCount;
1605      return;
1606    }
1607    if (Ptr == Opcodes.end()) {
1608      Done = true;
1609      return;
1610    }
1611    bool More = true;
1612    while (More && !Malformed) {
1613      // Parse next opcode and set up next loop.
1614      uint8_t Byte = *Ptr++;
1615      uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1616      uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1617      int8_t SignExtended;
1618      const uint8_t *SymStart;
1619      switch (Opcode) {
1620      case MachO::BIND_OPCODE_DONE:
1621        if (TableKind == Kind::Lazy) {
1622          // Lazying bindings have a DONE opcode between entries.  Need to ignore
1623          // it to advance to next entry.  But need not if this is last entry.
1624          bool NotLastEntry = false;
1625          for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1626            if (*P) {
1627              NotLastEntry = true;
1628            }
1629          }
1630          if (NotLastEntry)
1631            break;
1632        }
1633        More = false;
1634        Done = true;
1635        moveToEnd();
1636        DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1637        break;
1638      case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1639        Ordinal = ImmValue;
1640        DEBUG_WITH_TYPE(
1641            "mach-o-bind",
1642            llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1643                         << "Ordinal=" << Ordinal << "\n");
1644        break;
1645      case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1646        Ordinal = readULEB128();
1647        DEBUG_WITH_TYPE(
1648            "mach-o-bind",
1649            llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1650                         << "Ordinal=" << Ordinal << "\n");
1651        break;
1652      case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1653        if (ImmValue) {
1654          SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1655          Ordinal = SignExtended;
1656        } else
1657          Ordinal = 0;
1658        DEBUG_WITH_TYPE(
1659            "mach-o-bind",
1660            llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1661                         << "Ordinal=" << Ordinal << "\n");
1662        break;
1663      case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1664        Flags = ImmValue;
1665        SymStart = Ptr;
1666        while (*Ptr) {
1667          ++Ptr;
1668        }
1669        SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1670                               Ptr-SymStart);
1671        ++Ptr;
1672        DEBUG_WITH_TYPE(
1673            "mach-o-bind",
1674            llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1675                         << "SymbolName=" << SymbolName << "\n");
1676        if (TableKind == Kind::Weak) {
1677          if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1678            return;
1679        }
1680        break;
1681      case MachO::BIND_OPCODE_SET_TYPE_IMM:
1682        BindType = ImmValue;
1683        DEBUG_WITH_TYPE(
1684            "mach-o-bind",
1685            llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1686                         << "BindType=" << (int)BindType << "\n");
1687        break;
1688      case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1689        Addend = readSLEB128();
1690        if (TableKind == Kind::Lazy)
1691          Malformed = true;
1692        DEBUG_WITH_TYPE(
1693            "mach-o-bind",
1694            llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1695                         << "Addend=" << Addend << "\n");
1696        break;
1697      case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1698        SegmentIndex = ImmValue;
1699        SegmentOffset = readULEB128();
1700        DEBUG_WITH_TYPE(
1701            "mach-o-bind",
1702            llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1703                         << "SegmentIndex=" << SegmentIndex << ", "
1704                         << format("SegmentOffset=0x%06X", SegmentOffset)
1705                         << "\n");
1706        break;
1707      case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1708        SegmentOffset += readULEB128();
1709        DEBUG_WITH_TYPE("mach-o-bind",
1710                        llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1711                                     << format("SegmentOffset=0x%06X",
1712                                               SegmentOffset) << "\n");
1713        break;
1714      case MachO::BIND_OPCODE_DO_BIND:
1715        AdvanceAmount = PointerSize;
1716        RemainingLoopCount = 0;
1717        DEBUG_WITH_TYPE("mach-o-bind",
1718                        llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1719                                     << format("SegmentOffset=0x%06X",
1720                                               SegmentOffset) << "\n");
1721        return;
1722       case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1723        AdvanceAmount = readULEB128() + PointerSize;
1724        RemainingLoopCount = 0;
1725        if (TableKind == Kind::Lazy)
1726          Malformed = true;
1727        DEBUG_WITH_TYPE(
1728            "mach-o-bind",
1729            llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1730                         << format("SegmentOffset=0x%06X", SegmentOffset)
1731                         << ", AdvanceAmount=" << AdvanceAmount
1732                         << ", RemainingLoopCount=" << RemainingLoopCount
1733                         << "\n");
1734        return;
1735      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1736        AdvanceAmount = ImmValue * PointerSize + PointerSize;
1737        RemainingLoopCount = 0;
1738        if (TableKind == Kind::Lazy)
1739          Malformed = true;
1740        DEBUG_WITH_TYPE("mach-o-bind",
1741                        llvm::dbgs()
1742                        << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1743                        << format("SegmentOffset=0x%06X",
1744                                               SegmentOffset) << "\n");
1745        return;
1746      case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1747        RemainingLoopCount = readULEB128() - 1;
1748        AdvanceAmount = readULEB128() + PointerSize;
1749        if (TableKind == Kind::Lazy)
1750          Malformed = true;
1751        DEBUG_WITH_TYPE(
1752            "mach-o-bind",
1753            llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1754                         << format("SegmentOffset=0x%06X", SegmentOffset)
1755                         << ", AdvanceAmount=" << AdvanceAmount
1756                         << ", RemainingLoopCount=" << RemainingLoopCount
1757                         << "\n");
1758        return;
1759      default:
1760        Malformed = true;
1761      }
1762    }
1763  }
1764  
readULEB128()1765  uint64_t MachOBindEntry::readULEB128() {
1766    unsigned Count;
1767    uint64_t Result = decodeULEB128(Ptr, &Count);
1768    Ptr += Count;
1769    if (Ptr > Opcodes.end()) {
1770      Ptr = Opcodes.end();
1771      Malformed = true;
1772    }
1773    return Result;
1774  }
1775  
readSLEB128()1776  int64_t MachOBindEntry::readSLEB128() {
1777    unsigned Count;
1778    int64_t Result = decodeSLEB128(Ptr, &Count);
1779    Ptr += Count;
1780    if (Ptr > Opcodes.end()) {
1781      Ptr = Opcodes.end();
1782      Malformed = true;
1783    }
1784    return Result;
1785  }
1786  
segmentIndex() const1787  uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1788  
segmentOffset() const1789  uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1790  
typeName() const1791  StringRef MachOBindEntry::typeName() const {
1792    switch (BindType) {
1793    case MachO::BIND_TYPE_POINTER:
1794      return "pointer";
1795    case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1796      return "text abs32";
1797    case MachO::BIND_TYPE_TEXT_PCREL32:
1798      return "text rel32";
1799    }
1800    return "unknown";
1801  }
1802  
symbolName() const1803  StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1804  
addend() const1805  int64_t MachOBindEntry::addend() const { return Addend; }
1806  
flags() const1807  uint32_t MachOBindEntry::flags() const { return Flags; }
1808  
ordinal() const1809  int MachOBindEntry::ordinal() const { return Ordinal; }
1810  
operator ==(const MachOBindEntry & Other) const1811  bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1812    assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1813    return (Ptr == Other.Ptr) &&
1814           (RemainingLoopCount == Other.RemainingLoopCount) &&
1815           (Done == Other.Done);
1816  }
1817  
1818  iterator_range<bind_iterator>
bindTable(ArrayRef<uint8_t> Opcodes,bool is64,MachOBindEntry::Kind BKind)1819  MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1820                             MachOBindEntry::Kind BKind) {
1821    MachOBindEntry Start(Opcodes, is64, BKind);
1822    Start.moveToFirst();
1823  
1824    MachOBindEntry Finish(Opcodes, is64, BKind);
1825    Finish.moveToEnd();
1826  
1827    return make_range(bind_iterator(Start), bind_iterator(Finish));
1828  }
1829  
bindTable() const1830  iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1831    return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1832                     MachOBindEntry::Kind::Regular);
1833  }
1834  
lazyBindTable() const1835  iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1836    return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1837                     MachOBindEntry::Kind::Lazy);
1838  }
1839  
weakBindTable() const1840  iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1841    return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1842                     MachOBindEntry::Kind::Weak);
1843  }
1844  
1845  MachOObjectFile::load_command_iterator
begin_load_commands() const1846  MachOObjectFile::begin_load_commands() const {
1847    return LoadCommands.begin();
1848  }
1849  
1850  MachOObjectFile::load_command_iterator
end_load_commands() const1851  MachOObjectFile::end_load_commands() const {
1852    return LoadCommands.end();
1853  }
1854  
1855  iterator_range<MachOObjectFile::load_command_iterator>
load_commands() const1856  MachOObjectFile::load_commands() const {
1857    return make_range(begin_load_commands(), end_load_commands());
1858  }
1859  
1860  StringRef
getSectionFinalSegmentName(DataRefImpl Sec) const1861  MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1862    ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1863    return parseSegmentOrSectionName(Raw.data());
1864  }
1865  
1866  ArrayRef<char>
getSectionRawName(DataRefImpl Sec) const1867  MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1868    assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1869    const section_base *Base =
1870      reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1871    return makeArrayRef(Base->sectname);
1872  }
1873  
1874  ArrayRef<char>
getSectionRawFinalSegmentName(DataRefImpl Sec) const1875  MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1876    assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1877    const section_base *Base =
1878      reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1879    return makeArrayRef(Base->segname);
1880  }
1881  
1882  bool
isRelocationScattered(const MachO::any_relocation_info & RE) const1883  MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1884    const {
1885    if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1886      return false;
1887    return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1888  }
1889  
getPlainRelocationSymbolNum(const MachO::any_relocation_info & RE) const1890  unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1891      const MachO::any_relocation_info &RE) const {
1892    if (isLittleEndian())
1893      return RE.r_word1 & 0xffffff;
1894    return RE.r_word1 >> 8;
1895  }
1896  
getPlainRelocationExternal(const MachO::any_relocation_info & RE) const1897  bool MachOObjectFile::getPlainRelocationExternal(
1898      const MachO::any_relocation_info &RE) const {
1899    if (isLittleEndian())
1900      return (RE.r_word1 >> 27) & 1;
1901    return (RE.r_word1 >> 4) & 1;
1902  }
1903  
getScatteredRelocationScattered(const MachO::any_relocation_info & RE) const1904  bool MachOObjectFile::getScatteredRelocationScattered(
1905      const MachO::any_relocation_info &RE) const {
1906    return RE.r_word0 >> 31;
1907  }
1908  
getScatteredRelocationValue(const MachO::any_relocation_info & RE) const1909  uint32_t MachOObjectFile::getScatteredRelocationValue(
1910      const MachO::any_relocation_info &RE) const {
1911    return RE.r_word1;
1912  }
1913  
getScatteredRelocationType(const MachO::any_relocation_info & RE) const1914  uint32_t MachOObjectFile::getScatteredRelocationType(
1915      const MachO::any_relocation_info &RE) const {
1916    return (RE.r_word0 >> 24) & 0xf;
1917  }
1918  
getAnyRelocationAddress(const MachO::any_relocation_info & RE) const1919  unsigned MachOObjectFile::getAnyRelocationAddress(
1920      const MachO::any_relocation_info &RE) const {
1921    if (isRelocationScattered(RE))
1922      return getScatteredRelocationAddress(RE);
1923    return getPlainRelocationAddress(RE);
1924  }
1925  
getAnyRelocationPCRel(const MachO::any_relocation_info & RE) const1926  unsigned MachOObjectFile::getAnyRelocationPCRel(
1927      const MachO::any_relocation_info &RE) const {
1928    if (isRelocationScattered(RE))
1929      return getScatteredRelocationPCRel(this, RE);
1930    return getPlainRelocationPCRel(this, RE);
1931  }
1932  
getAnyRelocationLength(const MachO::any_relocation_info & RE) const1933  unsigned MachOObjectFile::getAnyRelocationLength(
1934      const MachO::any_relocation_info &RE) const {
1935    if (isRelocationScattered(RE))
1936      return getScatteredRelocationLength(RE);
1937    return getPlainRelocationLength(this, RE);
1938  }
1939  
1940  unsigned
getAnyRelocationType(const MachO::any_relocation_info & RE) const1941  MachOObjectFile::getAnyRelocationType(
1942                                     const MachO::any_relocation_info &RE) const {
1943    if (isRelocationScattered(RE))
1944      return getScatteredRelocationType(RE);
1945    return getPlainRelocationType(this, RE);
1946  }
1947  
1948  SectionRef
getAnyRelocationSection(const MachO::any_relocation_info & RE) const1949  MachOObjectFile::getAnyRelocationSection(
1950                                     const MachO::any_relocation_info &RE) const {
1951    if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1952      return *section_end();
1953    unsigned SecNum = getPlainRelocationSymbolNum(RE);
1954    if (SecNum == MachO::R_ABS || SecNum > Sections.size())
1955      return *section_end();
1956    DataRefImpl DRI;
1957    DRI.d.a = SecNum - 1;
1958    return SectionRef(DRI, this);
1959  }
1960  
getSection(DataRefImpl DRI) const1961  MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1962    assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1963    return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1964  }
1965  
getSection64(DataRefImpl DRI) const1966  MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1967    assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1968    return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1969  }
1970  
getSection(const LoadCommandInfo & L,unsigned Index) const1971  MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1972                                             unsigned Index) const {
1973    const char *Sec = getSectionPtr(this, L, Index);
1974    return getStruct<MachO::section>(this, Sec);
1975  }
1976  
getSection64(const LoadCommandInfo & L,unsigned Index) const1977  MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1978                                                  unsigned Index) const {
1979    const char *Sec = getSectionPtr(this, L, Index);
1980    return getStruct<MachO::section_64>(this, Sec);
1981  }
1982  
1983  MachO::nlist
getSymbolTableEntry(DataRefImpl DRI) const1984  MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1985    const char *P = reinterpret_cast<const char *>(DRI.p);
1986    return getStruct<MachO::nlist>(this, P);
1987  }
1988  
1989  MachO::nlist_64
getSymbol64TableEntry(DataRefImpl DRI) const1990  MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1991    const char *P = reinterpret_cast<const char *>(DRI.p);
1992    return getStruct<MachO::nlist_64>(this, P);
1993  }
1994  
1995  MachO::linkedit_data_command
getLinkeditDataLoadCommand(const LoadCommandInfo & L) const1996  MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1997    return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1998  }
1999  
2000  MachO::segment_command
getSegmentLoadCommand(const LoadCommandInfo & L) const2001  MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2002    return getStruct<MachO::segment_command>(this, L.Ptr);
2003  }
2004  
2005  MachO::segment_command_64
getSegment64LoadCommand(const LoadCommandInfo & L) const2006  MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2007    return getStruct<MachO::segment_command_64>(this, L.Ptr);
2008  }
2009  
2010  MachO::linker_option_command
getLinkerOptionLoadCommand(const LoadCommandInfo & L) const2011  MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2012    return getStruct<MachO::linker_option_command>(this, L.Ptr);
2013  }
2014  
2015  MachO::version_min_command
getVersionMinLoadCommand(const LoadCommandInfo & L) const2016  MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2017    return getStruct<MachO::version_min_command>(this, L.Ptr);
2018  }
2019  
2020  MachO::dylib_command
getDylibIDLoadCommand(const LoadCommandInfo & L) const2021  MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2022    return getStruct<MachO::dylib_command>(this, L.Ptr);
2023  }
2024  
2025  MachO::dyld_info_command
getDyldInfoLoadCommand(const LoadCommandInfo & L) const2026  MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2027    return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2028  }
2029  
2030  MachO::dylinker_command
getDylinkerCommand(const LoadCommandInfo & L) const2031  MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2032    return getStruct<MachO::dylinker_command>(this, L.Ptr);
2033  }
2034  
2035  MachO::uuid_command
getUuidCommand(const LoadCommandInfo & L) const2036  MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2037    return getStruct<MachO::uuid_command>(this, L.Ptr);
2038  }
2039  
2040  MachO::rpath_command
getRpathCommand(const LoadCommandInfo & L) const2041  MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2042    return getStruct<MachO::rpath_command>(this, L.Ptr);
2043  }
2044  
2045  MachO::source_version_command
getSourceVersionCommand(const LoadCommandInfo & L) const2046  MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2047    return getStruct<MachO::source_version_command>(this, L.Ptr);
2048  }
2049  
2050  MachO::entry_point_command
getEntryPointCommand(const LoadCommandInfo & L) const2051  MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2052    return getStruct<MachO::entry_point_command>(this, L.Ptr);
2053  }
2054  
2055  MachO::encryption_info_command
getEncryptionInfoCommand(const LoadCommandInfo & L) const2056  MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2057    return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2058  }
2059  
2060  MachO::encryption_info_command_64
getEncryptionInfoCommand64(const LoadCommandInfo & L) const2061  MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2062    return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2063  }
2064  
2065  MachO::sub_framework_command
getSubFrameworkCommand(const LoadCommandInfo & L) const2066  MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2067    return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2068  }
2069  
2070  MachO::sub_umbrella_command
getSubUmbrellaCommand(const LoadCommandInfo & L) const2071  MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2072    return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2073  }
2074  
2075  MachO::sub_library_command
getSubLibraryCommand(const LoadCommandInfo & L) const2076  MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2077    return getStruct<MachO::sub_library_command>(this, L.Ptr);
2078  }
2079  
2080  MachO::sub_client_command
getSubClientCommand(const LoadCommandInfo & L) const2081  MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2082    return getStruct<MachO::sub_client_command>(this, L.Ptr);
2083  }
2084  
2085  MachO::routines_command
getRoutinesCommand(const LoadCommandInfo & L) const2086  MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2087    return getStruct<MachO::routines_command>(this, L.Ptr);
2088  }
2089  
2090  MachO::routines_command_64
getRoutinesCommand64(const LoadCommandInfo & L) const2091  MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2092    return getStruct<MachO::routines_command_64>(this, L.Ptr);
2093  }
2094  
2095  MachO::thread_command
getThreadCommand(const LoadCommandInfo & L) const2096  MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2097    return getStruct<MachO::thread_command>(this, L.Ptr);
2098  }
2099  
2100  MachO::any_relocation_info
getRelocation(DataRefImpl Rel) const2101  MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2102    DataRefImpl Sec;
2103    Sec.d.a = Rel.d.a;
2104    uint32_t Offset;
2105    if (is64Bit()) {
2106      MachO::section_64 Sect = getSection64(Sec);
2107      Offset = Sect.reloff;
2108    } else {
2109      MachO::section Sect = getSection(Sec);
2110      Offset = Sect.reloff;
2111    }
2112  
2113    auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2114        getPtr(this, Offset)) + Rel.d.b;
2115    return getStruct<MachO::any_relocation_info>(
2116        this, reinterpret_cast<const char *>(P));
2117  }
2118  
2119  MachO::data_in_code_entry
getDice(DataRefImpl Rel) const2120  MachOObjectFile::getDice(DataRefImpl Rel) const {
2121    const char *P = reinterpret_cast<const char *>(Rel.p);
2122    return getStruct<MachO::data_in_code_entry>(this, P);
2123  }
2124  
getHeader() const2125  const MachO::mach_header &MachOObjectFile::getHeader() const {
2126    return Header;
2127  }
2128  
getHeader64() const2129  const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2130    assert(is64Bit());
2131    return Header64;
2132  }
2133  
getIndirectSymbolTableEntry(const MachO::dysymtab_command & DLC,unsigned Index) const2134  uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2135                                               const MachO::dysymtab_command &DLC,
2136                                               unsigned Index) const {
2137    uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2138    return getStruct<uint32_t>(this, getPtr(this, Offset));
2139  }
2140  
2141  MachO::data_in_code_entry
getDataInCodeTableEntry(uint32_t DataOffset,unsigned Index) const2142  MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2143                                           unsigned Index) const {
2144    uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2145    return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2146  }
2147  
getSymtabLoadCommand() const2148  MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2149    if (SymtabLoadCmd)
2150      return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2151  
2152    // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2153    MachO::symtab_command Cmd;
2154    Cmd.cmd = MachO::LC_SYMTAB;
2155    Cmd.cmdsize = sizeof(MachO::symtab_command);
2156    Cmd.symoff = 0;
2157    Cmd.nsyms = 0;
2158    Cmd.stroff = 0;
2159    Cmd.strsize = 0;
2160    return Cmd;
2161  }
2162  
getDysymtabLoadCommand() const2163  MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2164    if (DysymtabLoadCmd)
2165      return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2166  
2167    // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2168    MachO::dysymtab_command Cmd;
2169    Cmd.cmd = MachO::LC_DYSYMTAB;
2170    Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2171    Cmd.ilocalsym = 0;
2172    Cmd.nlocalsym = 0;
2173    Cmd.iextdefsym = 0;
2174    Cmd.nextdefsym = 0;
2175    Cmd.iundefsym = 0;
2176    Cmd.nundefsym = 0;
2177    Cmd.tocoff = 0;
2178    Cmd.ntoc = 0;
2179    Cmd.modtaboff = 0;
2180    Cmd.nmodtab = 0;
2181    Cmd.extrefsymoff = 0;
2182    Cmd.nextrefsyms = 0;
2183    Cmd.indirectsymoff = 0;
2184    Cmd.nindirectsyms = 0;
2185    Cmd.extreloff = 0;
2186    Cmd.nextrel = 0;
2187    Cmd.locreloff = 0;
2188    Cmd.nlocrel = 0;
2189    return Cmd;
2190  }
2191  
2192  MachO::linkedit_data_command
getDataInCodeLoadCommand() const2193  MachOObjectFile::getDataInCodeLoadCommand() const {
2194    if (DataInCodeLoadCmd)
2195      return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2196  
2197    // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2198    MachO::linkedit_data_command Cmd;
2199    Cmd.cmd = MachO::LC_DATA_IN_CODE;
2200    Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2201    Cmd.dataoff = 0;
2202    Cmd.datasize = 0;
2203    return Cmd;
2204  }
2205  
2206  MachO::linkedit_data_command
getLinkOptHintsLoadCommand() const2207  MachOObjectFile::getLinkOptHintsLoadCommand() const {
2208    if (LinkOptHintsLoadCmd)
2209      return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2210  
2211    // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2212    // fields.
2213    MachO::linkedit_data_command Cmd;
2214    Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2215    Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2216    Cmd.dataoff = 0;
2217    Cmd.datasize = 0;
2218    return Cmd;
2219  }
2220  
getDyldInfoRebaseOpcodes() const2221  ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2222    if (!DyldInfoLoadCmd)
2223      return None;
2224  
2225    MachO::dyld_info_command DyldInfo =
2226        getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2227    const uint8_t *Ptr =
2228        reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off));
2229    return makeArrayRef(Ptr, DyldInfo.rebase_size);
2230  }
2231  
getDyldInfoBindOpcodes() const2232  ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2233    if (!DyldInfoLoadCmd)
2234      return None;
2235  
2236    MachO::dyld_info_command DyldInfo =
2237        getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2238    const uint8_t *Ptr =
2239        reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off));
2240    return makeArrayRef(Ptr, DyldInfo.bind_size);
2241  }
2242  
getDyldInfoWeakBindOpcodes() const2243  ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2244    if (!DyldInfoLoadCmd)
2245      return None;
2246  
2247    MachO::dyld_info_command DyldInfo =
2248        getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2249    const uint8_t *Ptr =
2250        reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off));
2251    return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
2252  }
2253  
getDyldInfoLazyBindOpcodes() const2254  ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2255    if (!DyldInfoLoadCmd)
2256      return None;
2257  
2258    MachO::dyld_info_command DyldInfo =
2259        getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2260    const uint8_t *Ptr =
2261        reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off));
2262    return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
2263  }
2264  
getDyldInfoExportsTrie() const2265  ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2266    if (!DyldInfoLoadCmd)
2267      return None;
2268  
2269    MachO::dyld_info_command DyldInfo =
2270        getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2271    const uint8_t *Ptr =
2272        reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off));
2273    return makeArrayRef(Ptr, DyldInfo.export_size);
2274  }
2275  
getUuid() const2276  ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2277    if (!UuidLoadCmd)
2278      return None;
2279    // Returning a pointer is fine as uuid doesn't need endian swapping.
2280    const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2281    return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
2282  }
2283  
getStringTableData() const2284  StringRef MachOObjectFile::getStringTableData() const {
2285    MachO::symtab_command S = getSymtabLoadCommand();
2286    return getData().substr(S.stroff, S.strsize);
2287  }
2288  
is64Bit() const2289  bool MachOObjectFile::is64Bit() const {
2290    return getType() == getMachOType(false, true) ||
2291      getType() == getMachOType(true, true);
2292  }
2293  
ReadULEB128s(uint64_t Index,SmallVectorImpl<uint64_t> & Out) const2294  void MachOObjectFile::ReadULEB128s(uint64_t Index,
2295                                     SmallVectorImpl<uint64_t> &Out) const {
2296    DataExtractor extractor(ObjectFile::getData(), true, 0);
2297  
2298    uint32_t offset = Index;
2299    uint64_t data = 0;
2300    while (uint64_t delta = extractor.getULEB128(&offset)) {
2301      data += delta;
2302      Out.push_back(data);
2303    }
2304  }
2305  
isRelocatableObject() const2306  bool MachOObjectFile::isRelocatableObject() const {
2307    return getHeader().filetype == MachO::MH_OBJECT;
2308  }
2309  
2310  ErrorOr<std::unique_ptr<MachOObjectFile>>
createMachOObjectFile(MemoryBufferRef Buffer)2311  ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2312    StringRef Magic = Buffer.getBuffer().slice(0, 4);
2313    std::error_code EC;
2314    std::unique_ptr<MachOObjectFile> Ret;
2315    if (Magic == "\xFE\xED\xFA\xCE")
2316      Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2317    else if (Magic == "\xCE\xFA\xED\xFE")
2318      Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2319    else if (Magic == "\xFE\xED\xFA\xCF")
2320      Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2321    else if (Magic == "\xCF\xFA\xED\xFE")
2322      Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2323    else
2324      return object_error::parse_failed;
2325  
2326    if (EC)
2327      return EC;
2328    return std::move(Ret);
2329  }
2330