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