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