xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision 79d6c63f61daa82188f9627cef739c911f8b0b48)
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 static Error checkDyldCommand(const MachOObjectFile *Obj,
629                               const MachOObjectFile::LoadCommandInfo &Load,
630                               uint32_t LoadCommandIndex, const char *CmdName) {
631   if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
632     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
633                           CmdName + " cmdsize too small");
634   MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr);
635   if (D.name < sizeof(MachO::dylinker_command))
636     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
637                           CmdName + " name.offset field too small, not past "
638                           "the end of the dylinker_command struct");
639   if (D.name >= D.cmdsize)
640     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
641                           CmdName + " name.offset field extends past the end "
642                           "of the load command");
643   // Make sure there is a null between the starting offset of the name and
644   // the end of the load command.
645   uint32_t i;
646   const char *P = (const char *)Load.Ptr;
647   for (i = D.name; i < D.cmdsize; i++)
648     if (P[i] == '\0')
649       break;
650   if (i >= D.cmdsize)
651     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
652                           CmdName + " dyld name extends past the end of the "
653                           "load command");
654   return Error::success();
655 }
656 
657 static Error checkVersCommand(const MachOObjectFile *Obj,
658                               const MachOObjectFile::LoadCommandInfo &Load,
659                               uint32_t LoadCommandIndex,
660                               const char **LoadCmd, const char *CmdName) {
661   if (Load.C.cmdsize != sizeof(MachO::version_min_command))
662     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
663                           CmdName + " has incorrect cmdsize");
664   if (*LoadCmd != nullptr)
665     return malformedError("more than one LC_VERSION_MIN_MACOSX, "
666                           "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
667                           "LC_VERSION_MIN_WATCHOS command");
668   *LoadCmd = Load.Ptr;
669   return Error::success();
670 }
671 
672 static Error checkRpathCommand(const MachOObjectFile *Obj,
673                                const MachOObjectFile::LoadCommandInfo &Load,
674                                uint32_t LoadCommandIndex) {
675   if (Load.C.cmdsize < sizeof(MachO::rpath_command))
676     return malformedError("load command " + Twine(LoadCommandIndex) +
677                           " LC_RPATH cmdsize too small");
678   MachO::rpath_command R = getStruct<MachO::rpath_command>(Obj, Load.Ptr);
679   if (R.path < sizeof(MachO::rpath_command))
680     return malformedError("load command " + Twine(LoadCommandIndex) +
681                           " LC_RPATH path.offset field too small, not past "
682                           "the end of the rpath_command struct");
683   if (R.path >= R.cmdsize)
684     return malformedError("load command " + Twine(LoadCommandIndex) +
685                           " LC_RPATH path.offset field extends past the end "
686                           "of the load command");
687   // Make sure there is a null between the starting offset of the path and
688   // the end of the load command.
689   uint32_t i;
690   const char *P = (const char *)Load.Ptr;
691   for (i = R.path; i < R.cmdsize; i++)
692     if (P[i] == '\0')
693       break;
694   if (i >= R.cmdsize)
695     return malformedError("load command " + Twine(LoadCommandIndex) +
696                           " LC_RPATH library name extends past the end of the "
697                           "load command");
698   return Error::success();
699 }
700 
701 static Error checkEncryptCommand(const MachOObjectFile *Obj,
702                                  const MachOObjectFile::LoadCommandInfo &Load,
703                                  uint32_t LoadCommandIndex,
704                                  uint64_t cryptoff, uint64_t cryptsize,
705                                  const char **LoadCmd, const char *CmdName) {
706   if (*LoadCmd != nullptr)
707     return malformedError("more than one LC_ENCRYPTION_INFO and or "
708                           "LC_ENCRYPTION_INFO_64 command");
709   uint64_t FileSize = Obj->getData().size();
710   if (cryptoff > FileSize)
711     return malformedError("cryptoff field of " + Twine(CmdName) +
712                           " command " + Twine(LoadCommandIndex) + " extends "
713                           "past the end of the file");
714   uint64_t BigSize = cryptoff;
715   BigSize += cryptsize;
716   if (BigSize > FileSize)
717     return malformedError("cryptoff field plus cryptsize field of " +
718                           Twine(CmdName) + " command " +
719                           Twine(LoadCommandIndex) + " extends past the end of "
720                           "the file");
721   *LoadCmd = Load.Ptr;
722   return Error::success();
723 }
724 
725 static Error checkLinkerOptCommand(const MachOObjectFile *Obj,
726                                    const MachOObjectFile::LoadCommandInfo &Load,
727                                    uint32_t LoadCommandIndex) {
728   if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
729     return malformedError("load command " + Twine(LoadCommandIndex) +
730                           " LC_LINKER_OPTION cmdsize too small");
731   MachO::linker_option_command L =
732     getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
733   // Make sure the count of strings is correct.
734   const char *string = (const char *)Load.Ptr +
735                        sizeof(struct MachO::linker_option_command);
736   uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
737   uint32_t i = 0;
738   while (left > 0) {
739     while (*string == '\0' && left > 0) {
740       string++;
741       left--;
742     }
743     if (left > 0) {
744       i++;
745       uint32_t NullPos = StringRef(string, left).find('\0');
746       uint32_t len = std::min(NullPos, left) + 1;
747       string += len;
748       left -= len;
749     }
750   }
751   if (L.count != i)
752     return malformedError("load command " + Twine(LoadCommandIndex) +
753                           " LC_LINKER_OPTION string count " + Twine(L.count) +
754                           " does not match number of strings");
755   return Error::success();
756 }
757 
758 static Error checkSubCommand(const MachOObjectFile *Obj,
759                              const MachOObjectFile::LoadCommandInfo &Load,
760                              uint32_t LoadCommandIndex, const char *CmdName,
761                              size_t SizeOfCmd, const char *CmdStructName,
762                              uint32_t PathOffset, const char *PathFieldName) {
763   if (PathOffset < SizeOfCmd)
764     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
765                           CmdName + " " + PathFieldName + ".offset field too "
766                           "small, not past the end of the " + CmdStructName);
767   if (PathOffset >= Load.C.cmdsize)
768     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
769                           CmdName + " " + PathFieldName + ".offset field "
770                           "extends past the end of the load command");
771   // Make sure there is a null between the starting offset of the path and
772   // the end of the load command.
773   uint32_t i;
774   const char *P = (const char *)Load.Ptr;
775   for (i = PathOffset; i < Load.C.cmdsize; i++)
776     if (P[i] == '\0')
777       break;
778   if (i >= Load.C.cmdsize)
779     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
780                           CmdName + " " + PathFieldName + " name extends past "
781                           "the end of the load command");
782   return Error::success();
783 }
784 
785 static Error checkThreadCommand(const MachOObjectFile *Obj,
786                                 const MachOObjectFile::LoadCommandInfo &Load,
787                                 uint32_t LoadCommandIndex,
788                                 const char *CmdName) {
789   if (Load.C.cmdsize < sizeof(MachO::thread_command))
790     return malformedError("load command " + Twine(LoadCommandIndex) +
791                           CmdName + " cmdsize too small");
792   MachO::thread_command T =
793     getStruct<MachO::thread_command>(Obj, Load.Ptr);
794   const char *state = Load.Ptr + sizeof(MachO::thread_command);
795   const char *end = Load.Ptr + T.cmdsize;
796   uint32_t nflavor = 0;
797   uint32_t cputype = getCPUType(Obj);
798   while (state < end) {
799     if(state + sizeof(uint32_t) > end)
800       return malformedError("load command " + Twine(LoadCommandIndex) +
801                             "flavor in " + CmdName + " extends past end of "
802                             "command");
803     uint32_t flavor;
804     memcpy(&flavor, state, sizeof(uint32_t));
805     if (Obj->isLittleEndian() != sys::IsLittleEndianHost)
806       sys::swapByteOrder(flavor);
807     state += sizeof(uint32_t);
808 
809     if(state + sizeof(uint32_t) > end)
810       return malformedError("load command " + Twine(LoadCommandIndex) +
811                             " count in " + CmdName + " extends past end of "
812                             "command");
813     uint32_t count;
814     memcpy(&count, state, sizeof(uint32_t));
815     if (Obj->isLittleEndian() != sys::IsLittleEndianHost)
816       sys::swapByteOrder(count);
817     state += sizeof(uint32_t);
818 
819     if (cputype == MachO::CPU_TYPE_X86_64) {
820       if (flavor == MachO::x86_THREAD_STATE64) {
821         if (count != MachO::x86_THREAD_STATE64_COUNT)
822           return malformedError("load command " + Twine(LoadCommandIndex) +
823                                 " count not x86_THREAD_STATE64_COUNT for "
824                                 "flavor number " + Twine(nflavor) + " which is "
825                                 "a x86_THREAD_STATE64 flavor in " + CmdName +
826                                 " command");
827         if (state + sizeof(MachO::x86_thread_state64_t) > end)
828           return malformedError("load command " + Twine(LoadCommandIndex) +
829                                 " x86_THREAD_STATE64 extends past end of "
830                                 "command in " + CmdName + " command");
831         state += sizeof(MachO::x86_thread_state64_t);
832       } else {
833         return malformedError("load command " + Twine(LoadCommandIndex) +
834                               " unknown flavor (" + Twine(flavor) + ") for "
835                               "flavor number " + Twine(nflavor) + " in " +
836                               CmdName + " command");
837       }
838     } else if (cputype == MachO::CPU_TYPE_ARM) {
839       if (flavor == MachO::ARM_THREAD_STATE) {
840         if (count != MachO::ARM_THREAD_STATE_COUNT)
841           return malformedError("load command " + Twine(LoadCommandIndex) +
842                                 " count not ARM_THREAD_STATE_COUNT for "
843                                 "flavor number " + Twine(nflavor) + " which is "
844                                 "a ARM_THREAD_STATE flavor in " + CmdName +
845                                 " command");
846         if (state + sizeof(MachO::arm_thread_state32_t) > end)
847           return malformedError("load command " + Twine(LoadCommandIndex) +
848                                 " ARM_THREAD_STATE extends past end of "
849                                 "command in " + CmdName + " command");
850         state += sizeof(MachO::arm_thread_state32_t);
851       } else {
852         return malformedError("load command " + Twine(LoadCommandIndex) +
853                               " unknown flavor (" + Twine(flavor) + ") for "
854                               "flavor number " + Twine(nflavor) + " in " +
855                               CmdName + " command");
856       }
857     } else if (cputype == MachO::CPU_TYPE_POWERPC) {
858       if (flavor == MachO::PPC_THREAD_STATE) {
859         if (count != MachO::PPC_THREAD_STATE_COUNT)
860           return malformedError("load command " + Twine(LoadCommandIndex) +
861                                 " count not PPC_THREAD_STATE_COUNT for "
862                                 "flavor number " + Twine(nflavor) + " which is "
863                                 "a PPC_THREAD_STATE flavor in " + CmdName +
864                                 " command");
865         if (state + sizeof(MachO::ppc_thread_state32_t) > end)
866           return malformedError("load command " + Twine(LoadCommandIndex) +
867                                 " PPC_THREAD_STATE extends past end of "
868                                 "command in " + CmdName + " command");
869         state += sizeof(MachO::ppc_thread_state32_t);
870       } else {
871         return malformedError("load command " + Twine(LoadCommandIndex) +
872                               " unknown flavor (" + Twine(flavor) + ") for "
873                               "flavor number " + Twine(nflavor) + " in " +
874                               CmdName + " command");
875       }
876     } else {
877       return malformedError("unknown cputype (" + Twine(cputype) + ") load "
878                             "command " + Twine(LoadCommandIndex) + " for " +
879                             CmdName + " command can't be checked");
880     }
881     nflavor++;
882   }
883   return Error::success();
884 }
885 
886 static Error checkTwoLevelHintsCommand(const MachOObjectFile *Obj,
887                                        const MachOObjectFile::LoadCommandInfo
888                                          &Load,
889                                        uint32_t LoadCommandIndex,
890                                        const char **LoadCmd) {
891   if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
892     return malformedError("load command " + Twine(LoadCommandIndex) +
893                           " LC_TWOLEVEL_HINTS has incorrect cmdsize");
894   if (*LoadCmd != nullptr)
895     return malformedError("more than one LC_TWOLEVEL_HINTS command");
896   MachO::twolevel_hints_command Hints =
897     getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
898   uint64_t FileSize = Obj->getData().size();
899   if (Hints.offset > FileSize)
900     return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
901                           Twine(LoadCommandIndex) + " extends past the end of "
902                           "the file");
903   uint64_t BigSize = Hints.nhints;
904   BigSize *= Hints.nhints * sizeof(MachO::twolevel_hint);
905   BigSize += Hints.offset;
906   if (BigSize > FileSize)
907     return malformedError("offset field plus nhints times sizeof(struct "
908                           "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
909                           Twine(LoadCommandIndex) + " extends past the end of "
910                           "the file");
911   *LoadCmd = Load.Ptr;
912   return Error::success();
913 }
914 
915 Expected<std::unique_ptr<MachOObjectFile>>
916 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
917                         bool Is64Bits, uint32_t UniversalCputype,
918                         uint32_t UniversalIndex) {
919   Error Err;
920   std::unique_ptr<MachOObjectFile> Obj(
921       new MachOObjectFile(std::move(Object), IsLittleEndian,
922                           Is64Bits, Err, UniversalCputype,
923                           UniversalIndex));
924   if (Err)
925     return std::move(Err);
926   return std::move(Obj);
927 }
928 
929 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
930                                  bool Is64bits, Error &Err,
931                                  uint32_t UniversalCputype,
932                                  uint32_t UniversalIndex)
933     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
934       SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
935       DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
936       DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
937       HasPageZeroSegment(false) {
938   ErrorAsOutParameter ErrAsOutParam(&Err);
939   uint64_t SizeOfHeaders;
940   uint32_t cputype;
941   if (is64Bit()) {
942     parseHeader(this, Header64, Err);
943     SizeOfHeaders = sizeof(MachO::mach_header_64);
944     cputype = Header64.cputype;
945   } else {
946     parseHeader(this, Header, Err);
947     SizeOfHeaders = sizeof(MachO::mach_header);
948     cputype = Header.cputype;
949   }
950   if (Err)
951     return;
952   SizeOfHeaders += getHeader().sizeofcmds;
953   if (getData().data() + SizeOfHeaders > getData().end()) {
954     Err = malformedError("load commands extend past the end of the file");
955     return;
956   }
957   if (UniversalCputype != 0 && cputype != UniversalCputype) {
958     Err = malformedError("universal header architecture: " +
959                          Twine(UniversalIndex) + "'s cputype does not match "
960                          "object file's mach header");
961     return;
962   }
963 
964   uint32_t LoadCommandCount = getHeader().ncmds;
965   LoadCommandInfo Load;
966   if (LoadCommandCount != 0) {
967     if (auto LoadOrErr = getFirstLoadCommandInfo(this))
968       Load = *LoadOrErr;
969     else {
970       Err = LoadOrErr.takeError();
971       return;
972     }
973   }
974 
975   const char *DyldIdLoadCmd = nullptr;
976   const char *FuncStartsLoadCmd = nullptr;
977   const char *SplitInfoLoadCmd = nullptr;
978   const char *CodeSignDrsLoadCmd = nullptr;
979   const char *CodeSignLoadCmd = nullptr;
980   const char *VersLoadCmd = nullptr;
981   const char *SourceLoadCmd = nullptr;
982   const char *EntryPointLoadCmd = nullptr;
983   const char *EncryptLoadCmd = nullptr;
984   const char *RoutinesLoadCmd = nullptr;
985   const char *UnixThreadLoadCmd = nullptr;
986   const char *TwoLevelHintsLoadCmd = nullptr;
987   for (unsigned I = 0; I < LoadCommandCount; ++I) {
988     if (is64Bit()) {
989       if (Load.C.cmdsize % 8 != 0) {
990         // We have a hack here to allow 64-bit Mach-O core files to have
991         // LC_THREAD commands that are only a multiple of 4 and not 8 to be
992         // allowed since the macOS kernel produces them.
993         if (getHeader().filetype != MachO::MH_CORE ||
994             Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
995           Err = malformedError("load command " + Twine(I) + " cmdsize not a "
996                                "multiple of 8");
997           return;
998         }
999       }
1000     } else {
1001       if (Load.C.cmdsize % 4 != 0) {
1002         Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1003                              "multiple of 4");
1004         return;
1005       }
1006     }
1007     LoadCommands.push_back(Load);
1008     if (Load.C.cmd == MachO::LC_SYMTAB) {
1009       if ((Err = checkSymtabCommand(this, Load, I, &SymtabLoadCmd)))
1010         return;
1011     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1012       if ((Err = checkDysymtabCommand(this, Load, I, &DysymtabLoadCmd)))
1013         return;
1014     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1015       if ((Err = checkLinkeditDataCommand(this, Load, I, &DataInCodeLoadCmd,
1016                                           "LC_DATA_IN_CODE")))
1017         return;
1018     } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1019       if ((Err = checkLinkeditDataCommand(this, Load, I, &LinkOptHintsLoadCmd,
1020                                           "LC_LINKER_OPTIMIZATION_HINT")))
1021         return;
1022     } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1023       if ((Err = checkLinkeditDataCommand(this, Load, I, &FuncStartsLoadCmd,
1024                                           "LC_FUNCTION_STARTS")))
1025         return;
1026     } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1027       if ((Err = checkLinkeditDataCommand(this, Load, I, &SplitInfoLoadCmd,
1028                                           "LC_SEGMENT_SPLIT_INFO")))
1029         return;
1030     } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1031       if ((Err = checkLinkeditDataCommand(this, Load, I, &CodeSignDrsLoadCmd,
1032                                           "LC_DYLIB_CODE_SIGN_DRS")))
1033         return;
1034     } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1035       if ((Err = checkLinkeditDataCommand(this, Load, I, &CodeSignLoadCmd,
1036                                           "LC_CODE_SIGNATURE")))
1037         return;
1038     } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1039       if ((Err = checkDyldInfoCommand(this, Load, I, &DyldInfoLoadCmd,
1040                                       "LC_DYLD_INFO")))
1041         return;
1042     } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1043       if ((Err = checkDyldInfoCommand(this, Load, I, &DyldInfoLoadCmd,
1044                                       "LC_DYLD_INFO_ONLY")))
1045         return;
1046     } else if (Load.C.cmd == MachO::LC_UUID) {
1047       if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1048         Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1049                              "cmdsize");
1050         return;
1051       }
1052       if (UuidLoadCmd) {
1053         Err = malformedError("more than one LC_UUID command");
1054         return;
1055       }
1056       UuidLoadCmd = Load.Ptr;
1057     } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1058       if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
1059                                          MachO::section_64>(
1060                    this, Load, Sections, HasPageZeroSegment, I,
1061                    "LC_SEGMENT_64", SizeOfHeaders)))
1062         return;
1063     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1064       if ((Err = parseSegmentLoadCommand<MachO::segment_command,
1065                                          MachO::section>(
1066                    this, Load, Sections, HasPageZeroSegment, I,
1067                    "LC_SEGMENT", SizeOfHeaders)))
1068         return;
1069     } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1070       if ((Err = checkDylibIdCommand(this, Load, I, &DyldIdLoadCmd)))
1071         return;
1072     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1073       if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_DYLIB")))
1074         return;
1075       Libraries.push_back(Load.Ptr);
1076     } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1077       if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1078         return;
1079       Libraries.push_back(Load.Ptr);
1080     } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1081       if ((Err = checkDylibCommand(this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1082         return;
1083       Libraries.push_back(Load.Ptr);
1084     } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1085       if ((Err = checkDylibCommand(this, Load, I, "LC_REEXPORT_DYLIB")))
1086         return;
1087       Libraries.push_back(Load.Ptr);
1088     } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1089       if ((Err = checkDylibCommand(this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1090         return;
1091       Libraries.push_back(Load.Ptr);
1092     } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1093       if ((Err = checkDyldCommand(this, Load, I, "LC_ID_DYLINKER")))
1094         return;
1095     } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1096       if ((Err = checkDyldCommand(this, Load, I, "LC_LOAD_DYLINKER")))
1097         return;
1098     } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1099       if ((Err = checkDyldCommand(this, Load, I, "LC_DYLD_ENVIRONMENT")))
1100         return;
1101     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1102       if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
1103                                   "LC_VERSION_MIN_MACOSX")))
1104         return;
1105     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1106       if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
1107                                   "LC_VERSION_MIN_IPHONEOS")))
1108         return;
1109     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1110       if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
1111                                   "LC_VERSION_MIN_TVOS")))
1112         return;
1113     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1114       if ((Err = checkVersCommand(this, Load, I, &VersLoadCmd,
1115                                   "LC_VERSION_MIN_WATCHOS")))
1116         return;
1117     } else if (Load.C.cmd == MachO::LC_RPATH) {
1118       if ((Err = checkRpathCommand(this, Load, I)))
1119         return;
1120     } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1121       if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1122         Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1123                              " has incorrect cmdsize");
1124         return;
1125       }
1126       if (SourceLoadCmd) {
1127         Err = malformedError("more than one LC_SOURCE_VERSION command");
1128         return;
1129       }
1130       SourceLoadCmd = Load.Ptr;
1131     } else if (Load.C.cmd == MachO::LC_MAIN) {
1132       if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1133         Err = malformedError("LC_MAIN command " + Twine(I) +
1134                              " has incorrect cmdsize");
1135         return;
1136       }
1137       if (EntryPointLoadCmd) {
1138         Err = malformedError("more than one LC_MAIN command");
1139         return;
1140       }
1141       EntryPointLoadCmd = Load.Ptr;
1142     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1143       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1144         Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1145                              " has incorrect cmdsize");
1146         return;
1147       }
1148       MachO::encryption_info_command E =
1149         getStruct<MachO::encryption_info_command>(this, Load.Ptr);
1150       if ((Err = checkEncryptCommand(this, Load, I, E.cryptoff, E.cryptsize,
1151                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1152         return;
1153     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1154       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1155         Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1156                              " has incorrect cmdsize");
1157         return;
1158       }
1159       MachO::encryption_info_command_64 E =
1160         getStruct<MachO::encryption_info_command_64>(this, Load.Ptr);
1161       if ((Err = checkEncryptCommand(this, Load, I, E.cryptoff, E.cryptsize,
1162                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1163         return;
1164     } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1165       if ((Err = checkLinkerOptCommand(this, Load, I)))
1166         return;
1167     } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1168       if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1169         Err =  malformedError("load command " + Twine(I) +
1170                               " LC_SUB_FRAMEWORK cmdsize too small");
1171         return;
1172       }
1173       MachO::sub_framework_command S =
1174         getStruct<MachO::sub_framework_command>(this, Load.Ptr);
1175       if ((Err = checkSubCommand(this, Load, I, "LC_SUB_FRAMEWORK",
1176                                  sizeof(MachO::sub_framework_command),
1177                                  "sub_framework_command", S.umbrella,
1178                                  "umbrella")))
1179         return;
1180     } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1181       if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1182         Err =  malformedError("load command " + Twine(I) +
1183                               " LC_SUB_UMBRELLA cmdsize too small");
1184         return;
1185       }
1186       MachO::sub_umbrella_command S =
1187         getStruct<MachO::sub_umbrella_command>(this, Load.Ptr);
1188       if ((Err = checkSubCommand(this, Load, I, "LC_SUB_UMBRELLA",
1189                                  sizeof(MachO::sub_umbrella_command),
1190                                  "sub_umbrella_command", S.sub_umbrella,
1191                                  "sub_umbrella")))
1192         return;
1193     } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1194       if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1195         Err =  malformedError("load command " + Twine(I) +
1196                               " LC_SUB_LIBRARY cmdsize too small");
1197         return;
1198       }
1199       MachO::sub_library_command S =
1200         getStruct<MachO::sub_library_command>(this, Load.Ptr);
1201       if ((Err = checkSubCommand(this, Load, I, "LC_SUB_LIBRARY",
1202                                  sizeof(MachO::sub_library_command),
1203                                  "sub_library_command", S.sub_library,
1204                                  "sub_library")))
1205         return;
1206     } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1207       if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1208         Err =  malformedError("load command " + Twine(I) +
1209                               " LC_SUB_CLIENT cmdsize too small");
1210         return;
1211       }
1212       MachO::sub_client_command S =
1213         getStruct<MachO::sub_client_command>(this, Load.Ptr);
1214       if ((Err = checkSubCommand(this, Load, I, "LC_SUB_CLIENT",
1215                                  sizeof(MachO::sub_client_command),
1216                                  "sub_client_command", S.client, "client")))
1217         return;
1218     } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1219       if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1220         Err = malformedError("LC_ROUTINES command " + Twine(I) +
1221                              " has incorrect cmdsize");
1222         return;
1223       }
1224       if (RoutinesLoadCmd) {
1225         Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1226                              "command");
1227         return;
1228       }
1229       RoutinesLoadCmd = Load.Ptr;
1230     } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1231       if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1232         Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1233                              " has incorrect cmdsize");
1234         return;
1235       }
1236       if (RoutinesLoadCmd) {
1237         Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1238                              "command");
1239         return;
1240       }
1241       RoutinesLoadCmd = Load.Ptr;
1242     } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1243       if ((Err = checkThreadCommand(this, Load, I, "LC_UNIXTHREAD")))
1244         return;
1245       if (UnixThreadLoadCmd) {
1246         Err = malformedError("more than one LC_UNIXTHREAD command");
1247         return;
1248       }
1249       UnixThreadLoadCmd = Load.Ptr;
1250     } else if (Load.C.cmd == MachO::LC_THREAD) {
1251       if ((Err = checkThreadCommand(this, Load, I, "LC_THREAD")))
1252         return;
1253     } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1254        if ((Err = checkTwoLevelHintsCommand(this, Load, I,
1255                                             &TwoLevelHintsLoadCmd)))
1256          return;
1257     }
1258     if (I < LoadCommandCount - 1) {
1259       if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
1260         Load = *LoadOrErr;
1261       else {
1262         Err = LoadOrErr.takeError();
1263         return;
1264       }
1265     }
1266   }
1267   if (!SymtabLoadCmd) {
1268     if (DysymtabLoadCmd) {
1269       Err = malformedError("contains LC_DYSYMTAB load command without a "
1270                            "LC_SYMTAB load command");
1271       return;
1272     }
1273   } else if (DysymtabLoadCmd) {
1274     MachO::symtab_command Symtab =
1275       getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1276     MachO::dysymtab_command Dysymtab =
1277       getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1278     if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1279       Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1280                            "extends past the end of the symbol table");
1281       return;
1282     }
1283     uint64_t BigSize = Dysymtab.ilocalsym;
1284     BigSize += Dysymtab.nlocalsym;
1285     if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1286       Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1287                            "command extends past the end of the symbol table");
1288       return;
1289     }
1290     if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1291       Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
1292                            "extends past the end of the symbol table");
1293       return;
1294     }
1295     BigSize = Dysymtab.iextdefsym;
1296     BigSize += Dysymtab.nextdefsym;
1297     if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1298       Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1299                            "load command extends past the end of the symbol "
1300                            "table");
1301       return;
1302     }
1303     if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1304       Err = malformedError("nundefsym in LC_DYSYMTAB load command "
1305                            "extends past the end of the symbol table");
1306       return;
1307     }
1308     BigSize = Dysymtab.iundefsym;
1309     BigSize += Dysymtab.nundefsym;
1310     if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1311       Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1312                            " command extends past the end of the symbol table");
1313       return;
1314     }
1315   }
1316   if ((getHeader().filetype == MachO::MH_DYLIB ||
1317        getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1318        DyldIdLoadCmd == nullptr) {
1319     Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1320                          "filetype");
1321     return;
1322   }
1323   assert(LoadCommands.size() == LoadCommandCount);
1324 
1325   Err = Error::success();
1326 }
1327 
1328 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
1329   unsigned SymbolTableEntrySize = is64Bit() ?
1330     sizeof(MachO::nlist_64) :
1331     sizeof(MachO::nlist);
1332   Symb.p += SymbolTableEntrySize;
1333 }
1334 
1335 Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
1336   StringRef StringTable = getStringTableData();
1337   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
1338   const char *Start = &StringTable.data()[Entry.n_strx];
1339   if (Start < getData().begin() || Start >= getData().end()) {
1340     return malformedError("bad string index: " + Twine(Entry.n_strx) +
1341                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1342   }
1343   return StringRef(Start);
1344 }
1345 
1346 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
1347   DataRefImpl DRI = Sec.getRawDataRefImpl();
1348   uint32_t Flags = getSectionFlags(this, DRI);
1349   return Flags & MachO::SECTION_TYPE;
1350 }
1351 
1352 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
1353   if (is64Bit()) {
1354     MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
1355     return Entry.n_value;
1356   }
1357   MachO::nlist Entry = getSymbolTableEntry(Sym);
1358   return Entry.n_value;
1359 }
1360 
1361 // getIndirectName() returns the name of the alias'ed symbol who's string table
1362 // index is in the n_value field.
1363 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
1364                                                  StringRef &Res) const {
1365   StringRef StringTable = getStringTableData();
1366   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
1367   if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1368     return object_error::parse_failed;
1369   uint64_t NValue = getNValue(Symb);
1370   if (NValue >= StringTable.size())
1371     return object_error::parse_failed;
1372   const char *Start = &StringTable.data()[NValue];
1373   Res = StringRef(Start);
1374   return std::error_code();
1375 }
1376 
1377 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1378   return getNValue(Sym);
1379 }
1380 
1381 Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
1382   return getSymbolValue(Sym);
1383 }
1384 
1385 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
1386   uint32_t flags = getSymbolFlags(DRI);
1387   if (flags & SymbolRef::SF_Common) {
1388     MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
1389     return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1390   }
1391   return 0;
1392 }
1393 
1394 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
1395   return getNValue(DRI);
1396 }
1397 
1398 Expected<SymbolRef::Type>
1399 MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
1400   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
1401   uint8_t n_type = Entry.n_type;
1402 
1403   // If this is a STAB debugging symbol, we can do nothing more.
1404   if (n_type & MachO::N_STAB)
1405     return SymbolRef::ST_Debug;
1406 
1407   switch (n_type & MachO::N_TYPE) {
1408     case MachO::N_UNDF :
1409       return SymbolRef::ST_Unknown;
1410     case MachO::N_SECT :
1411       Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1412       if (!SecOrError)
1413         return SecOrError.takeError();
1414       section_iterator Sec = *SecOrError;
1415       if (Sec->isData() || Sec->isBSS())
1416         return SymbolRef::ST_Data;
1417       return SymbolRef::ST_Function;
1418   }
1419   return SymbolRef::ST_Other;
1420 }
1421 
1422 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
1423   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
1424 
1425   uint8_t MachOType = Entry.n_type;
1426   uint16_t MachOFlags = Entry.n_desc;
1427 
1428   uint32_t Result = SymbolRef::SF_None;
1429 
1430   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1431     Result |= SymbolRef::SF_Indirect;
1432 
1433   if (MachOType & MachO::N_STAB)
1434     Result |= SymbolRef::SF_FormatSpecific;
1435 
1436   if (MachOType & MachO::N_EXT) {
1437     Result |= SymbolRef::SF_Global;
1438     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1439       if (getNValue(DRI))
1440         Result |= SymbolRef::SF_Common;
1441       else
1442         Result |= SymbolRef::SF_Undefined;
1443     }
1444 
1445     if (!(MachOType & MachO::N_PEXT))
1446       Result |= SymbolRef::SF_Exported;
1447   }
1448 
1449   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1450     Result |= SymbolRef::SF_Weak;
1451 
1452   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1453     Result |= SymbolRef::SF_Thumb;
1454 
1455   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1456     Result |= SymbolRef::SF_Absolute;
1457 
1458   return Result;
1459 }
1460 
1461 Expected<section_iterator>
1462 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
1463   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
1464   uint8_t index = Entry.n_sect;
1465 
1466   if (index == 0)
1467     return section_end();
1468   DataRefImpl DRI;
1469   DRI.d.a = index - 1;
1470   if (DRI.d.a >= Sections.size()){
1471     return malformedError("bad section index: " + Twine((int)index) +
1472                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1473   }
1474   return section_iterator(SectionRef(DRI, this));
1475 }
1476 
1477 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
1478   MachO::nlist_base Entry =
1479       getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
1480   return Entry.n_sect - 1;
1481 }
1482 
1483 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
1484   Sec.d.a++;
1485 }
1486 
1487 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
1488                                                 StringRef &Result) const {
1489   ArrayRef<char> Raw = getSectionRawName(Sec);
1490   Result = parseSegmentOrSectionName(Raw.data());
1491   return std::error_code();
1492 }
1493 
1494 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
1495   if (is64Bit())
1496     return getSection64(Sec).addr;
1497   return getSection(Sec).addr;
1498 }
1499 
1500 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
1501   // In the case if a malformed Mach-O file where the section offset is past
1502   // the end of the file or some part of the section size is past the end of
1503   // the file return a size of zero or a size that covers the rest of the file
1504   // but does not extend past the end of the file.
1505   uint32_t SectOffset, SectType;
1506   uint64_t SectSize;
1507 
1508   if (is64Bit()) {
1509     MachO::section_64 Sect = getSection64(Sec);
1510     SectOffset = Sect.offset;
1511     SectSize = Sect.size;
1512     SectType = Sect.flags & MachO::SECTION_TYPE;
1513   } else {
1514     MachO::section Sect = getSection(Sec);
1515     SectOffset = Sect.offset;
1516     SectSize = Sect.size;
1517     SectType = Sect.flags & MachO::SECTION_TYPE;
1518   }
1519   if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1520     return SectSize;
1521   uint64_t FileSize = getData().size();
1522   if (SectOffset > FileSize)
1523     return 0;
1524   if (FileSize - SectOffset < SectSize)
1525     return FileSize - SectOffset;
1526   return SectSize;
1527 }
1528 
1529 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
1530                                                     StringRef &Res) const {
1531   uint32_t Offset;
1532   uint64_t Size;
1533 
1534   if (is64Bit()) {
1535     MachO::section_64 Sect = getSection64(Sec);
1536     Offset = Sect.offset;
1537     Size = Sect.size;
1538   } else {
1539     MachO::section Sect = getSection(Sec);
1540     Offset = Sect.offset;
1541     Size = Sect.size;
1542   }
1543 
1544   Res = this->getData().substr(Offset, Size);
1545   return std::error_code();
1546 }
1547 
1548 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
1549   uint32_t Align;
1550   if (is64Bit()) {
1551     MachO::section_64 Sect = getSection64(Sec);
1552     Align = Sect.align;
1553   } else {
1554     MachO::section Sect = getSection(Sec);
1555     Align = Sect.align;
1556   }
1557 
1558   return uint64_t(1) << Align;
1559 }
1560 
1561 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
1562   return false;
1563 }
1564 
1565 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
1566   uint32_t Flags = getSectionFlags(this, Sec);
1567   return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
1568 }
1569 
1570 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
1571   uint32_t Flags = getSectionFlags(this, Sec);
1572   unsigned SectionType = Flags & MachO::SECTION_TYPE;
1573   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1574          !(SectionType == MachO::S_ZEROFILL ||
1575            SectionType == MachO::S_GB_ZEROFILL);
1576 }
1577 
1578 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
1579   uint32_t Flags = getSectionFlags(this, Sec);
1580   unsigned SectionType = Flags & MachO::SECTION_TYPE;
1581   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1582          (SectionType == MachO::S_ZEROFILL ||
1583           SectionType == MachO::S_GB_ZEROFILL);
1584 }
1585 
1586 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
1587   return Sec.getRawDataRefImpl().d.a;
1588 }
1589 
1590 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
1591   // FIXME: Unimplemented.
1592   return false;
1593 }
1594 
1595 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
1596   StringRef SegmentName = getSectionFinalSegmentName(Sec);
1597   StringRef SectName;
1598   if (!getSectionName(Sec, SectName))
1599     return (SegmentName == "__LLVM" && SectName == "__bitcode");
1600   return false;
1601 }
1602 
1603 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
1604   DataRefImpl Ret;
1605   Ret.d.a = Sec.d.a;
1606   Ret.d.b = 0;
1607   return relocation_iterator(RelocationRef(Ret, this));
1608 }
1609 
1610 relocation_iterator
1611 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
1612   uint32_t Num;
1613   if (is64Bit()) {
1614     MachO::section_64 Sect = getSection64(Sec);
1615     Num = Sect.nreloc;
1616   } else {
1617     MachO::section Sect = getSection(Sec);
1618     Num = Sect.nreloc;
1619   }
1620 
1621   DataRefImpl Ret;
1622   Ret.d.a = Sec.d.a;
1623   Ret.d.b = Num;
1624   return relocation_iterator(RelocationRef(Ret, this));
1625 }
1626 
1627 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
1628   ++Rel.d.b;
1629 }
1630 
1631 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
1632   assert(getHeader().filetype == MachO::MH_OBJECT &&
1633          "Only implemented for MH_OBJECT");
1634   MachO::any_relocation_info RE = getRelocation(Rel);
1635   return getAnyRelocationAddress(RE);
1636 }
1637 
1638 symbol_iterator
1639 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
1640   MachO::any_relocation_info RE = getRelocation(Rel);
1641   if (isRelocationScattered(RE))
1642     return symbol_end();
1643 
1644   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
1645   bool isExtern = getPlainRelocationExternal(RE);
1646   if (!isExtern)
1647     return symbol_end();
1648 
1649   MachO::symtab_command S = getSymtabLoadCommand();
1650   unsigned SymbolTableEntrySize = is64Bit() ?
1651     sizeof(MachO::nlist_64) :
1652     sizeof(MachO::nlist);
1653   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
1654   DataRefImpl Sym;
1655   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1656   return symbol_iterator(SymbolRef(Sym, this));
1657 }
1658 
1659 section_iterator
1660 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
1661   return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
1662 }
1663 
1664 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
1665   MachO::any_relocation_info RE = getRelocation(Rel);
1666   return getAnyRelocationType(RE);
1667 }
1668 
1669 void MachOObjectFile::getRelocationTypeName(
1670     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1671   StringRef res;
1672   uint64_t RType = getRelocationType(Rel);
1673 
1674   unsigned Arch = this->getArch();
1675 
1676   switch (Arch) {
1677     case Triple::x86: {
1678       static const char *const Table[] =  {
1679         "GENERIC_RELOC_VANILLA",
1680         "GENERIC_RELOC_PAIR",
1681         "GENERIC_RELOC_SECTDIFF",
1682         "GENERIC_RELOC_PB_LA_PTR",
1683         "GENERIC_RELOC_LOCAL_SECTDIFF",
1684         "GENERIC_RELOC_TLV" };
1685 
1686       if (RType > 5)
1687         res = "Unknown";
1688       else
1689         res = Table[RType];
1690       break;
1691     }
1692     case Triple::x86_64: {
1693       static const char *const Table[] =  {
1694         "X86_64_RELOC_UNSIGNED",
1695         "X86_64_RELOC_SIGNED",
1696         "X86_64_RELOC_BRANCH",
1697         "X86_64_RELOC_GOT_LOAD",
1698         "X86_64_RELOC_GOT",
1699         "X86_64_RELOC_SUBTRACTOR",
1700         "X86_64_RELOC_SIGNED_1",
1701         "X86_64_RELOC_SIGNED_2",
1702         "X86_64_RELOC_SIGNED_4",
1703         "X86_64_RELOC_TLV" };
1704 
1705       if (RType > 9)
1706         res = "Unknown";
1707       else
1708         res = Table[RType];
1709       break;
1710     }
1711     case Triple::arm: {
1712       static const char *const Table[] =  {
1713         "ARM_RELOC_VANILLA",
1714         "ARM_RELOC_PAIR",
1715         "ARM_RELOC_SECTDIFF",
1716         "ARM_RELOC_LOCAL_SECTDIFF",
1717         "ARM_RELOC_PB_LA_PTR",
1718         "ARM_RELOC_BR24",
1719         "ARM_THUMB_RELOC_BR22",
1720         "ARM_THUMB_32BIT_BRANCH",
1721         "ARM_RELOC_HALF",
1722         "ARM_RELOC_HALF_SECTDIFF" };
1723 
1724       if (RType > 9)
1725         res = "Unknown";
1726       else
1727         res = Table[RType];
1728       break;
1729     }
1730     case Triple::aarch64: {
1731       static const char *const Table[] = {
1732         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
1733         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
1734         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
1735         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
1736         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
1737         "ARM64_RELOC_ADDEND"
1738       };
1739 
1740       if (RType >= array_lengthof(Table))
1741         res = "Unknown";
1742       else
1743         res = Table[RType];
1744       break;
1745     }
1746     case Triple::ppc: {
1747       static const char *const Table[] =  {
1748         "PPC_RELOC_VANILLA",
1749         "PPC_RELOC_PAIR",
1750         "PPC_RELOC_BR14",
1751         "PPC_RELOC_BR24",
1752         "PPC_RELOC_HI16",
1753         "PPC_RELOC_LO16",
1754         "PPC_RELOC_HA16",
1755         "PPC_RELOC_LO14",
1756         "PPC_RELOC_SECTDIFF",
1757         "PPC_RELOC_PB_LA_PTR",
1758         "PPC_RELOC_HI16_SECTDIFF",
1759         "PPC_RELOC_LO16_SECTDIFF",
1760         "PPC_RELOC_HA16_SECTDIFF",
1761         "PPC_RELOC_JBSR",
1762         "PPC_RELOC_LO14_SECTDIFF",
1763         "PPC_RELOC_LOCAL_SECTDIFF" };
1764 
1765       if (RType > 15)
1766         res = "Unknown";
1767       else
1768         res = Table[RType];
1769       break;
1770     }
1771     case Triple::UnknownArch:
1772       res = "Unknown";
1773       break;
1774   }
1775   Result.append(res.begin(), res.end());
1776 }
1777 
1778 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
1779   MachO::any_relocation_info RE = getRelocation(Rel);
1780   return getAnyRelocationLength(RE);
1781 }
1782 
1783 //
1784 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1785 // guess on what the short name is.  Then name is returned as a substring of the
1786 // StringRef Name passed in.  The name of the dynamic library is recognized as
1787 // a framework if it has one of the two following forms:
1788 //      Foo.framework/Versions/A/Foo
1789 //      Foo.framework/Foo
1790 // Where A and Foo can be any string.  And may contain a trailing suffix
1791 // starting with an underbar.  If the Name is recognized as a framework then
1792 // isFramework is set to true else it is set to false.  If the Name has a
1793 // suffix then Suffix is set to the substring in Name that contains the suffix
1794 // else it is set to a NULL StringRef.
1795 //
1796 // The Name of the dynamic library is recognized as a library name if it has
1797 // one of the two following forms:
1798 //      libFoo.A.dylib
1799 //      libFoo.dylib
1800 // The library may have a suffix trailing the name Foo of the form:
1801 //      libFoo_profile.A.dylib
1802 //      libFoo_profile.dylib
1803 //
1804 // The Name of the dynamic library is also recognized as a library name if it
1805 // has the following form:
1806 //      Foo.qtx
1807 //
1808 // If the Name of the dynamic library is none of the forms above then a NULL
1809 // StringRef is returned.
1810 //
1811 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1812                                                  bool &isFramework,
1813                                                  StringRef &Suffix) {
1814   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1815   size_t a, b, c, d, Idx;
1816 
1817   isFramework = false;
1818   Suffix = StringRef();
1819 
1820   // Pull off the last component and make Foo point to it
1821   a = Name.rfind('/');
1822   if (a == Name.npos || a == 0)
1823     goto guess_library;
1824   Foo = Name.slice(a+1, Name.npos);
1825 
1826   // Look for a suffix starting with a '_'
1827   Idx = Foo.rfind('_');
1828   if (Idx != Foo.npos && Foo.size() >= 2) {
1829     Suffix = Foo.slice(Idx, Foo.npos);
1830     Foo = Foo.slice(0, Idx);
1831   }
1832 
1833   // First look for the form Foo.framework/Foo
1834   b = Name.rfind('/', a);
1835   if (b == Name.npos)
1836     Idx = 0;
1837   else
1838     Idx = b+1;
1839   F = Name.slice(Idx, Idx + Foo.size());
1840   DotFramework = Name.slice(Idx + Foo.size(),
1841                             Idx + Foo.size() + sizeof(".framework/")-1);
1842   if (F == Foo && DotFramework == ".framework/") {
1843     isFramework = true;
1844     return Foo;
1845   }
1846 
1847   // Next look for the form Foo.framework/Versions/A/Foo
1848   if (b == Name.npos)
1849     goto guess_library;
1850   c =  Name.rfind('/', b);
1851   if (c == Name.npos || c == 0)
1852     goto guess_library;
1853   V = Name.slice(c+1, Name.npos);
1854   if (!V.startswith("Versions/"))
1855     goto guess_library;
1856   d =  Name.rfind('/', c);
1857   if (d == Name.npos)
1858     Idx = 0;
1859   else
1860     Idx = d+1;
1861   F = Name.slice(Idx, Idx + Foo.size());
1862   DotFramework = Name.slice(Idx + Foo.size(),
1863                             Idx + Foo.size() + sizeof(".framework/")-1);
1864   if (F == Foo && DotFramework == ".framework/") {
1865     isFramework = true;
1866     return Foo;
1867   }
1868 
1869 guess_library:
1870   // pull off the suffix after the "." and make a point to it
1871   a = Name.rfind('.');
1872   if (a == Name.npos || a == 0)
1873     return StringRef();
1874   Dylib = Name.slice(a, Name.npos);
1875   if (Dylib != ".dylib")
1876     goto guess_qtx;
1877 
1878   // First pull off the version letter for the form Foo.A.dylib if any.
1879   if (a >= 3) {
1880     Dot = Name.slice(a-2, a-1);
1881     if (Dot == ".")
1882       a = a - 2;
1883   }
1884 
1885   b = Name.rfind('/', a);
1886   if (b == Name.npos)
1887     b = 0;
1888   else
1889     b = b+1;
1890   // ignore any suffix after an underbar like Foo_profile.A.dylib
1891   Idx = Name.find('_', b);
1892   if (Idx != Name.npos && Idx != b) {
1893     Lib = Name.slice(b, Idx);
1894     Suffix = Name.slice(Idx, a);
1895   }
1896   else
1897     Lib = Name.slice(b, a);
1898   // There are incorrect library names of the form:
1899   // libATS.A_profile.dylib so check for these.
1900   if (Lib.size() >= 3) {
1901     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1902     if (Dot == ".")
1903       Lib = Lib.slice(0, Lib.size()-2);
1904   }
1905   return Lib;
1906 
1907 guess_qtx:
1908   Qtx = Name.slice(a, Name.npos);
1909   if (Qtx != ".qtx")
1910     return StringRef();
1911   b = Name.rfind('/', a);
1912   if (b == Name.npos)
1913     Lib = Name.slice(0, a);
1914   else
1915     Lib = Name.slice(b+1, a);
1916   // There are library names of the form: QT.A.qtx so check for these.
1917   if (Lib.size() >= 3) {
1918     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1919     if (Dot == ".")
1920       Lib = Lib.slice(0, Lib.size()-2);
1921   }
1922   return Lib;
1923 }
1924 
1925 // getLibraryShortNameByIndex() is used to get the short name of the library
1926 // for an undefined symbol in a linked Mach-O binary that was linked with the
1927 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1928 // It is passed the index (0 - based) of the library as translated from
1929 // GET_LIBRARY_ORDINAL (1 - based).
1930 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1931                                                          StringRef &Res) const {
1932   if (Index >= Libraries.size())
1933     return object_error::parse_failed;
1934 
1935   // If the cache of LibrariesShortNames is not built up do that first for
1936   // all the Libraries.
1937   if (LibrariesShortNames.size() == 0) {
1938     for (unsigned i = 0; i < Libraries.size(); i++) {
1939       MachO::dylib_command D =
1940         getStruct<MachO::dylib_command>(this, Libraries[i]);
1941       if (D.dylib.name >= D.cmdsize)
1942         return object_error::parse_failed;
1943       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1944       StringRef Name = StringRef(P);
1945       if (D.dylib.name+Name.size() >= D.cmdsize)
1946         return object_error::parse_failed;
1947       StringRef Suffix;
1948       bool isFramework;
1949       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1950       if (shortName.empty())
1951         LibrariesShortNames.push_back(Name);
1952       else
1953         LibrariesShortNames.push_back(shortName);
1954     }
1955   }
1956 
1957   Res = LibrariesShortNames[Index];
1958   return std::error_code();
1959 }
1960 
1961 section_iterator
1962 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
1963   DataRefImpl Sec;
1964   Sec.d.a = Rel->getRawDataRefImpl().d.a;
1965   return section_iterator(SectionRef(Sec, this));
1966 }
1967 
1968 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1969   DataRefImpl DRI;
1970   MachO::symtab_command Symtab = getSymtabLoadCommand();
1971   if (!SymtabLoadCmd || Symtab.nsyms == 0)
1972     return basic_symbol_iterator(SymbolRef(DRI, this));
1973 
1974   return getSymbolByIndex(0);
1975 }
1976 
1977 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1978   DataRefImpl DRI;
1979   MachO::symtab_command Symtab = getSymtabLoadCommand();
1980   if (!SymtabLoadCmd || Symtab.nsyms == 0)
1981     return basic_symbol_iterator(SymbolRef(DRI, this));
1982 
1983   unsigned SymbolTableEntrySize = is64Bit() ?
1984     sizeof(MachO::nlist_64) :
1985     sizeof(MachO::nlist);
1986   unsigned Offset = Symtab.symoff +
1987     Symtab.nsyms * SymbolTableEntrySize;
1988   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1989   return basic_symbol_iterator(SymbolRef(DRI, this));
1990 }
1991 
1992 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1993   MachO::symtab_command Symtab = getSymtabLoadCommand();
1994   if (!SymtabLoadCmd || Index >= Symtab.nsyms)
1995     report_fatal_error("Requested symbol index is out of range.");
1996   unsigned SymbolTableEntrySize =
1997     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1998   DataRefImpl DRI;
1999   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
2000   DRI.p += Index * SymbolTableEntrySize;
2001   return basic_symbol_iterator(SymbolRef(DRI, this));
2002 }
2003 
2004 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
2005   MachO::symtab_command Symtab = getSymtabLoadCommand();
2006   if (!SymtabLoadCmd)
2007     report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2008   unsigned SymbolTableEntrySize =
2009     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2010   DataRefImpl DRIstart;
2011   DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
2012   uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2013   return Index;
2014 }
2015 
2016 section_iterator MachOObjectFile::section_begin() const {
2017   DataRefImpl DRI;
2018   return section_iterator(SectionRef(DRI, this));
2019 }
2020 
2021 section_iterator MachOObjectFile::section_end() const {
2022   DataRefImpl DRI;
2023   DRI.d.a = Sections.size();
2024   return section_iterator(SectionRef(DRI, this));
2025 }
2026 
2027 uint8_t MachOObjectFile::getBytesInAddress() const {
2028   return is64Bit() ? 8 : 4;
2029 }
2030 
2031 StringRef MachOObjectFile::getFileFormatName() const {
2032   unsigned CPUType = getCPUType(this);
2033   if (!is64Bit()) {
2034     switch (CPUType) {
2035     case llvm::MachO::CPU_TYPE_I386:
2036       return "Mach-O 32-bit i386";
2037     case llvm::MachO::CPU_TYPE_ARM:
2038       return "Mach-O arm";
2039     case llvm::MachO::CPU_TYPE_POWERPC:
2040       return "Mach-O 32-bit ppc";
2041     default:
2042       return "Mach-O 32-bit unknown";
2043     }
2044   }
2045 
2046   switch (CPUType) {
2047   case llvm::MachO::CPU_TYPE_X86_64:
2048     return "Mach-O 64-bit x86-64";
2049   case llvm::MachO::CPU_TYPE_ARM64:
2050     return "Mach-O arm64";
2051   case llvm::MachO::CPU_TYPE_POWERPC64:
2052     return "Mach-O 64-bit ppc64";
2053   default:
2054     return "Mach-O 64-bit unknown";
2055   }
2056 }
2057 
2058 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
2059   switch (CPUType) {
2060   case llvm::MachO::CPU_TYPE_I386:
2061     return Triple::x86;
2062   case llvm::MachO::CPU_TYPE_X86_64:
2063     return Triple::x86_64;
2064   case llvm::MachO::CPU_TYPE_ARM:
2065     return Triple::arm;
2066   case llvm::MachO::CPU_TYPE_ARM64:
2067     return Triple::aarch64;
2068   case llvm::MachO::CPU_TYPE_POWERPC:
2069     return Triple::ppc;
2070   case llvm::MachO::CPU_TYPE_POWERPC64:
2071     return Triple::ppc64;
2072   default:
2073     return Triple::UnknownArch;
2074   }
2075 }
2076 
2077 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
2078                                       const char **McpuDefault) {
2079   if (McpuDefault)
2080     *McpuDefault = nullptr;
2081 
2082   switch (CPUType) {
2083   case MachO::CPU_TYPE_I386:
2084     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2085     case MachO::CPU_SUBTYPE_I386_ALL:
2086       return Triple("i386-apple-darwin");
2087     default:
2088       return Triple();
2089     }
2090   case MachO::CPU_TYPE_X86_64:
2091     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2092     case MachO::CPU_SUBTYPE_X86_64_ALL:
2093       return Triple("x86_64-apple-darwin");
2094     case MachO::CPU_SUBTYPE_X86_64_H:
2095       return Triple("x86_64h-apple-darwin");
2096     default:
2097       return Triple();
2098     }
2099   case MachO::CPU_TYPE_ARM:
2100     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2101     case MachO::CPU_SUBTYPE_ARM_V4T:
2102       return Triple("armv4t-apple-darwin");
2103     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2104       return Triple("armv5e-apple-darwin");
2105     case MachO::CPU_SUBTYPE_ARM_XSCALE:
2106       return Triple("xscale-apple-darwin");
2107     case MachO::CPU_SUBTYPE_ARM_V6:
2108       return Triple("armv6-apple-darwin");
2109     case MachO::CPU_SUBTYPE_ARM_V6M:
2110       if (McpuDefault)
2111         *McpuDefault = "cortex-m0";
2112       return Triple("armv6m-apple-darwin");
2113     case MachO::CPU_SUBTYPE_ARM_V7:
2114       return Triple("armv7-apple-darwin");
2115     case MachO::CPU_SUBTYPE_ARM_V7EM:
2116       if (McpuDefault)
2117         *McpuDefault = "cortex-m4";
2118       return Triple("thumbv7em-apple-darwin");
2119     case MachO::CPU_SUBTYPE_ARM_V7K:
2120       return Triple("armv7k-apple-darwin");
2121     case MachO::CPU_SUBTYPE_ARM_V7M:
2122       if (McpuDefault)
2123         *McpuDefault = "cortex-m3";
2124       return Triple("thumbv7m-apple-darwin");
2125     case MachO::CPU_SUBTYPE_ARM_V7S:
2126       return Triple("armv7s-apple-darwin");
2127     default:
2128       return Triple();
2129     }
2130   case MachO::CPU_TYPE_ARM64:
2131     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2132     case MachO::CPU_SUBTYPE_ARM64_ALL:
2133       return Triple("arm64-apple-darwin");
2134     default:
2135       return Triple();
2136     }
2137   case MachO::CPU_TYPE_POWERPC:
2138     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2139     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2140       return Triple("ppc-apple-darwin");
2141     default:
2142       return Triple();
2143     }
2144   case MachO::CPU_TYPE_POWERPC64:
2145     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2146     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2147       return Triple("ppc64-apple-darwin");
2148     default:
2149       return Triple();
2150     }
2151   default:
2152     return Triple();
2153   }
2154 }
2155 
2156 Triple MachOObjectFile::getHostArch() {
2157   return Triple(sys::getDefaultTargetTriple());
2158 }
2159 
2160 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
2161   return StringSwitch<bool>(ArchFlag)
2162       .Case("i386", true)
2163       .Case("x86_64", true)
2164       .Case("x86_64h", true)
2165       .Case("armv4t", true)
2166       .Case("arm", true)
2167       .Case("armv5e", true)
2168       .Case("armv6", true)
2169       .Case("armv6m", true)
2170       .Case("armv7", true)
2171       .Case("armv7em", true)
2172       .Case("armv7k", true)
2173       .Case("armv7m", true)
2174       .Case("armv7s", true)
2175       .Case("arm64", true)
2176       .Case("ppc", true)
2177       .Case("ppc64", true)
2178       .Default(false);
2179 }
2180 
2181 unsigned MachOObjectFile::getArch() const {
2182   return getArch(getCPUType(this));
2183 }
2184 
2185 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2186   return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2187 }
2188 
2189 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
2190   DataRefImpl DRI;
2191   DRI.d.a = Index;
2192   return section_rel_begin(DRI);
2193 }
2194 
2195 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
2196   DataRefImpl DRI;
2197   DRI.d.a = Index;
2198   return section_rel_end(DRI);
2199 }
2200 
2201 dice_iterator MachOObjectFile::begin_dices() const {
2202   DataRefImpl DRI;
2203   if (!DataInCodeLoadCmd)
2204     return dice_iterator(DiceRef(DRI, this));
2205 
2206   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2207   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
2208   return dice_iterator(DiceRef(DRI, this));
2209 }
2210 
2211 dice_iterator MachOObjectFile::end_dices() const {
2212   DataRefImpl DRI;
2213   if (!DataInCodeLoadCmd)
2214     return dice_iterator(DiceRef(DRI, this));
2215 
2216   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2217   unsigned Offset = DicLC.dataoff + DicLC.datasize;
2218   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
2219   return dice_iterator(DiceRef(DRI, this));
2220 }
2221 
2222 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
2223     : Trie(T), Malformed(false), Done(false) {}
2224 
2225 void ExportEntry::moveToFirst() {
2226   pushNode(0);
2227   pushDownUntilBottom();
2228 }
2229 
2230 void ExportEntry::moveToEnd() {
2231   Stack.clear();
2232   Done = true;
2233 }
2234 
2235 bool ExportEntry::operator==(const ExportEntry &Other) const {
2236   // Common case, one at end, other iterating from begin.
2237   if (Done || Other.Done)
2238     return (Done == Other.Done);
2239   // Not equal if different stack sizes.
2240   if (Stack.size() != Other.Stack.size())
2241     return false;
2242   // Not equal if different cumulative strings.
2243   if (!CumulativeString.equals(Other.CumulativeString))
2244     return false;
2245   // Equal if all nodes in both stacks match.
2246   for (unsigned i=0; i < Stack.size(); ++i) {
2247     if (Stack[i].Start != Other.Stack[i].Start)
2248       return false;
2249   }
2250   return true;
2251 }
2252 
2253 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
2254   unsigned Count;
2255   uint64_t Result = decodeULEB128(Ptr, &Count);
2256   Ptr += Count;
2257   if (Ptr > Trie.end()) {
2258     Ptr = Trie.end();
2259     Malformed = true;
2260   }
2261   return Result;
2262 }
2263 
2264 StringRef ExportEntry::name() const {
2265   return CumulativeString;
2266 }
2267 
2268 uint64_t ExportEntry::flags() const {
2269   return Stack.back().Flags;
2270 }
2271 
2272 uint64_t ExportEntry::address() const {
2273   return Stack.back().Address;
2274 }
2275 
2276 uint64_t ExportEntry::other() const {
2277   return Stack.back().Other;
2278 }
2279 
2280 StringRef ExportEntry::otherName() const {
2281   const char* ImportName = Stack.back().ImportName;
2282   if (ImportName)
2283     return StringRef(ImportName);
2284   return StringRef();
2285 }
2286 
2287 uint32_t ExportEntry::nodeOffset() const {
2288   return Stack.back().Start - Trie.begin();
2289 }
2290 
2291 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2292     : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
2293       ImportName(nullptr), ChildCount(0), NextChildIndex(0),
2294       ParentStringLength(0), IsExportNode(false) {}
2295 
2296 void ExportEntry::pushNode(uint64_t offset) {
2297   const uint8_t *Ptr = Trie.begin() + offset;
2298   NodeState State(Ptr);
2299   uint64_t ExportInfoSize = readULEB128(State.Current);
2300   State.IsExportNode = (ExportInfoSize != 0);
2301   const uint8_t* Children = State.Current + ExportInfoSize;
2302   if (State.IsExportNode) {
2303     State.Flags = readULEB128(State.Current);
2304     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2305       State.Address = 0;
2306       State.Other = readULEB128(State.Current); // dylib ordinal
2307       State.ImportName = reinterpret_cast<const char*>(State.Current);
2308     } else {
2309       State.Address = readULEB128(State.Current);
2310       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
2311         State.Other = readULEB128(State.Current);
2312     }
2313   }
2314   State.ChildCount = *Children;
2315   State.Current = Children + 1;
2316   State.NextChildIndex = 0;
2317   State.ParentStringLength = CumulativeString.size();
2318   Stack.push_back(State);
2319 }
2320 
2321 void ExportEntry::pushDownUntilBottom() {
2322   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2323     NodeState &Top = Stack.back();
2324     CumulativeString.resize(Top.ParentStringLength);
2325     for (;*Top.Current != 0; Top.Current++) {
2326       char C = *Top.Current;
2327       CumulativeString.push_back(C);
2328     }
2329     Top.Current += 1;
2330     uint64_t childNodeIndex = readULEB128(Top.Current);
2331     Top.NextChildIndex += 1;
2332     pushNode(childNodeIndex);
2333   }
2334   if (!Stack.back().IsExportNode) {
2335     Malformed = true;
2336     moveToEnd();
2337   }
2338 }
2339 
2340 // We have a trie data structure and need a way to walk it that is compatible
2341 // with the C++ iterator model. The solution is a non-recursive depth first
2342 // traversal where the iterator contains a stack of parent nodes along with a
2343 // string that is the accumulation of all edge strings along the parent chain
2344 // to this point.
2345 //
2346 // There is one "export" node for each exported symbol.  But because some
2347 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
2348 // node may have child nodes too.
2349 //
2350 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
2351 // child until hitting a node with no children (which is an export node or
2352 // else the trie is malformed). On the way down, each node is pushed on the
2353 // stack ivar.  If there is no more ways down, it pops up one and tries to go
2354 // down a sibling path until a childless node is reached.
2355 void ExportEntry::moveNext() {
2356   if (Stack.empty() || !Stack.back().IsExportNode) {
2357     Malformed = true;
2358     moveToEnd();
2359     return;
2360   }
2361 
2362   Stack.pop_back();
2363   while (!Stack.empty()) {
2364     NodeState &Top = Stack.back();
2365     if (Top.NextChildIndex < Top.ChildCount) {
2366       pushDownUntilBottom();
2367       // Now at the next export node.
2368       return;
2369     } else {
2370       if (Top.IsExportNode) {
2371         // This node has no children but is itself an export node.
2372         CumulativeString.resize(Top.ParentStringLength);
2373         return;
2374       }
2375       Stack.pop_back();
2376     }
2377   }
2378   Done = true;
2379 }
2380 
2381 iterator_range<export_iterator>
2382 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
2383   ExportEntry Start(Trie);
2384   if (Trie.size() == 0)
2385     Start.moveToEnd();
2386   else
2387     Start.moveToFirst();
2388 
2389   ExportEntry Finish(Trie);
2390   Finish.moveToEnd();
2391 
2392   return make_range(export_iterator(Start), export_iterator(Finish));
2393 }
2394 
2395 iterator_range<export_iterator> MachOObjectFile::exports() const {
2396   return exports(getDyldInfoExportsTrie());
2397 }
2398 
2399 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
2400     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2401       RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
2402       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
2403 
2404 void MachORebaseEntry::moveToFirst() {
2405   Ptr = Opcodes.begin();
2406   moveNext();
2407 }
2408 
2409 void MachORebaseEntry::moveToEnd() {
2410   Ptr = Opcodes.end();
2411   RemainingLoopCount = 0;
2412   Done = true;
2413 }
2414 
2415 void MachORebaseEntry::moveNext() {
2416   // If in the middle of some loop, move to next rebasing in loop.
2417   SegmentOffset += AdvanceAmount;
2418   if (RemainingLoopCount) {
2419     --RemainingLoopCount;
2420     return;
2421   }
2422   if (Ptr == Opcodes.end()) {
2423     Done = true;
2424     return;
2425   }
2426   bool More = true;
2427   while (More && !Malformed) {
2428     // Parse next opcode and set up next loop.
2429     uint8_t Byte = *Ptr++;
2430     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
2431     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
2432     switch (Opcode) {
2433     case MachO::REBASE_OPCODE_DONE:
2434       More = false;
2435       Done = true;
2436       moveToEnd();
2437       DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
2438       break;
2439     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
2440       RebaseType = ImmValue;
2441       DEBUG_WITH_TYPE(
2442           "mach-o-rebase",
2443           llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
2444                        << "RebaseType=" << (int) RebaseType << "\n");
2445       break;
2446     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
2447       SegmentIndex = ImmValue;
2448       SegmentOffset = readULEB128();
2449       DEBUG_WITH_TYPE(
2450           "mach-o-rebase",
2451           llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2452                        << "SegmentIndex=" << SegmentIndex << ", "
2453                        << format("SegmentOffset=0x%06X", SegmentOffset)
2454                        << "\n");
2455       break;
2456     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
2457       SegmentOffset += readULEB128();
2458       DEBUG_WITH_TYPE("mach-o-rebase",
2459                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
2460                                    << format("SegmentOffset=0x%06X",
2461                                              SegmentOffset) << "\n");
2462       break;
2463     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
2464       SegmentOffset += ImmValue * PointerSize;
2465       DEBUG_WITH_TYPE("mach-o-rebase",
2466                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
2467                                    << format("SegmentOffset=0x%06X",
2468                                              SegmentOffset) << "\n");
2469       break;
2470     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
2471       AdvanceAmount = PointerSize;
2472       RemainingLoopCount = ImmValue - 1;
2473       DEBUG_WITH_TYPE(
2474           "mach-o-rebase",
2475           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
2476                        << format("SegmentOffset=0x%06X", SegmentOffset)
2477                        << ", AdvanceAmount=" << AdvanceAmount
2478                        << ", RemainingLoopCount=" << RemainingLoopCount
2479                        << "\n");
2480       return;
2481     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
2482       AdvanceAmount = PointerSize;
2483       RemainingLoopCount = readULEB128() - 1;
2484       DEBUG_WITH_TYPE(
2485           "mach-o-rebase",
2486           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
2487                        << format("SegmentOffset=0x%06X", SegmentOffset)
2488                        << ", AdvanceAmount=" << AdvanceAmount
2489                        << ", RemainingLoopCount=" << RemainingLoopCount
2490                        << "\n");
2491       return;
2492     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
2493       AdvanceAmount = readULEB128() + PointerSize;
2494       RemainingLoopCount = 0;
2495       DEBUG_WITH_TYPE(
2496           "mach-o-rebase",
2497           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
2498                        << format("SegmentOffset=0x%06X", SegmentOffset)
2499                        << ", AdvanceAmount=" << AdvanceAmount
2500                        << ", RemainingLoopCount=" << RemainingLoopCount
2501                        << "\n");
2502       return;
2503     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
2504       RemainingLoopCount = readULEB128() - 1;
2505       AdvanceAmount = readULEB128() + PointerSize;
2506       DEBUG_WITH_TYPE(
2507           "mach-o-rebase",
2508           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
2509                        << format("SegmentOffset=0x%06X", SegmentOffset)
2510                        << ", AdvanceAmount=" << AdvanceAmount
2511                        << ", RemainingLoopCount=" << RemainingLoopCount
2512                        << "\n");
2513       return;
2514     default:
2515       Malformed = true;
2516     }
2517   }
2518 }
2519 
2520 uint64_t MachORebaseEntry::readULEB128() {
2521   unsigned Count;
2522   uint64_t Result = decodeULEB128(Ptr, &Count);
2523   Ptr += Count;
2524   if (Ptr > Opcodes.end()) {
2525     Ptr = Opcodes.end();
2526     Malformed = true;
2527   }
2528   return Result;
2529 }
2530 
2531 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
2532 
2533 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
2534 
2535 StringRef MachORebaseEntry::typeName() const {
2536   switch (RebaseType) {
2537   case MachO::REBASE_TYPE_POINTER:
2538     return "pointer";
2539   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
2540     return "text abs32";
2541   case MachO::REBASE_TYPE_TEXT_PCREL32:
2542     return "text rel32";
2543   }
2544   return "unknown";
2545 }
2546 
2547 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
2548   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2549   return (Ptr == Other.Ptr) &&
2550          (RemainingLoopCount == Other.RemainingLoopCount) &&
2551          (Done == Other.Done);
2552 }
2553 
2554 iterator_range<rebase_iterator>
2555 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
2556   MachORebaseEntry Start(Opcodes, is64);
2557   Start.moveToFirst();
2558 
2559   MachORebaseEntry Finish(Opcodes, is64);
2560   Finish.moveToEnd();
2561 
2562   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
2563 }
2564 
2565 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
2566   return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
2567 }
2568 
2569 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
2570     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2571       Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
2572       BindType(0), PointerSize(is64Bit ? 8 : 4),
2573       TableKind(BK), Malformed(false), Done(false) {}
2574 
2575 void MachOBindEntry::moveToFirst() {
2576   Ptr = Opcodes.begin();
2577   moveNext();
2578 }
2579 
2580 void MachOBindEntry::moveToEnd() {
2581   Ptr = Opcodes.end();
2582   RemainingLoopCount = 0;
2583   Done = true;
2584 }
2585 
2586 void MachOBindEntry::moveNext() {
2587   // If in the middle of some loop, move to next binding in loop.
2588   SegmentOffset += AdvanceAmount;
2589   if (RemainingLoopCount) {
2590     --RemainingLoopCount;
2591     return;
2592   }
2593   if (Ptr == Opcodes.end()) {
2594     Done = true;
2595     return;
2596   }
2597   bool More = true;
2598   while (More && !Malformed) {
2599     // Parse next opcode and set up next loop.
2600     uint8_t Byte = *Ptr++;
2601     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
2602     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
2603     int8_t SignExtended;
2604     const uint8_t *SymStart;
2605     switch (Opcode) {
2606     case MachO::BIND_OPCODE_DONE:
2607       if (TableKind == Kind::Lazy) {
2608         // Lazying bindings have a DONE opcode between entries.  Need to ignore
2609         // it to advance to next entry.  But need not if this is last entry.
2610         bool NotLastEntry = false;
2611         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
2612           if (*P) {
2613             NotLastEntry = true;
2614           }
2615         }
2616         if (NotLastEntry)
2617           break;
2618       }
2619       More = false;
2620       Done = true;
2621       moveToEnd();
2622       DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
2623       break;
2624     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
2625       Ordinal = ImmValue;
2626       DEBUG_WITH_TYPE(
2627           "mach-o-bind",
2628           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
2629                        << "Ordinal=" << Ordinal << "\n");
2630       break;
2631     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
2632       Ordinal = readULEB128();
2633       DEBUG_WITH_TYPE(
2634           "mach-o-bind",
2635           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
2636                        << "Ordinal=" << Ordinal << "\n");
2637       break;
2638     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
2639       if (ImmValue) {
2640         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
2641         Ordinal = SignExtended;
2642       } else
2643         Ordinal = 0;
2644       DEBUG_WITH_TYPE(
2645           "mach-o-bind",
2646           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
2647                        << "Ordinal=" << Ordinal << "\n");
2648       break;
2649     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
2650       Flags = ImmValue;
2651       SymStart = Ptr;
2652       while (*Ptr) {
2653         ++Ptr;
2654       }
2655       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
2656                              Ptr-SymStart);
2657       ++Ptr;
2658       DEBUG_WITH_TYPE(
2659           "mach-o-bind",
2660           llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
2661                        << "SymbolName=" << SymbolName << "\n");
2662       if (TableKind == Kind::Weak) {
2663         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
2664           return;
2665       }
2666       break;
2667     case MachO::BIND_OPCODE_SET_TYPE_IMM:
2668       BindType = ImmValue;
2669       DEBUG_WITH_TYPE(
2670           "mach-o-bind",
2671           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
2672                        << "BindType=" << (int)BindType << "\n");
2673       break;
2674     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
2675       Addend = readSLEB128();
2676       if (TableKind == Kind::Lazy)
2677         Malformed = true;
2678       DEBUG_WITH_TYPE(
2679           "mach-o-bind",
2680           llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
2681                        << "Addend=" << Addend << "\n");
2682       break;
2683     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
2684       SegmentIndex = ImmValue;
2685       SegmentOffset = readULEB128();
2686       DEBUG_WITH_TYPE(
2687           "mach-o-bind",
2688           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2689                        << "SegmentIndex=" << SegmentIndex << ", "
2690                        << format("SegmentOffset=0x%06X", SegmentOffset)
2691                        << "\n");
2692       break;
2693     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
2694       SegmentOffset += readULEB128();
2695       DEBUG_WITH_TYPE("mach-o-bind",
2696                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
2697                                    << format("SegmentOffset=0x%06X",
2698                                              SegmentOffset) << "\n");
2699       break;
2700     case MachO::BIND_OPCODE_DO_BIND:
2701       AdvanceAmount = PointerSize;
2702       RemainingLoopCount = 0;
2703       DEBUG_WITH_TYPE("mach-o-bind",
2704                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
2705                                    << format("SegmentOffset=0x%06X",
2706                                              SegmentOffset) << "\n");
2707       return;
2708      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
2709       AdvanceAmount = readULEB128() + PointerSize;
2710       RemainingLoopCount = 0;
2711       if (TableKind == Kind::Lazy)
2712         Malformed = true;
2713       DEBUG_WITH_TYPE(
2714           "mach-o-bind",
2715           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
2716                        << format("SegmentOffset=0x%06X", SegmentOffset)
2717                        << ", AdvanceAmount=" << AdvanceAmount
2718                        << ", RemainingLoopCount=" << RemainingLoopCount
2719                        << "\n");
2720       return;
2721     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
2722       AdvanceAmount = ImmValue * PointerSize + PointerSize;
2723       RemainingLoopCount = 0;
2724       if (TableKind == Kind::Lazy)
2725         Malformed = true;
2726       DEBUG_WITH_TYPE("mach-o-bind",
2727                       llvm::dbgs()
2728                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
2729                       << format("SegmentOffset=0x%06X",
2730                                              SegmentOffset) << "\n");
2731       return;
2732     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
2733       RemainingLoopCount = readULEB128() - 1;
2734       AdvanceAmount = readULEB128() + PointerSize;
2735       if (TableKind == Kind::Lazy)
2736         Malformed = true;
2737       DEBUG_WITH_TYPE(
2738           "mach-o-bind",
2739           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
2740                        << format("SegmentOffset=0x%06X", SegmentOffset)
2741                        << ", AdvanceAmount=" << AdvanceAmount
2742                        << ", RemainingLoopCount=" << RemainingLoopCount
2743                        << "\n");
2744       return;
2745     default:
2746       Malformed = true;
2747     }
2748   }
2749 }
2750 
2751 uint64_t MachOBindEntry::readULEB128() {
2752   unsigned Count;
2753   uint64_t Result = decodeULEB128(Ptr, &Count);
2754   Ptr += Count;
2755   if (Ptr > Opcodes.end()) {
2756     Ptr = Opcodes.end();
2757     Malformed = true;
2758   }
2759   return Result;
2760 }
2761 
2762 int64_t MachOBindEntry::readSLEB128() {
2763   unsigned Count;
2764   int64_t Result = decodeSLEB128(Ptr, &Count);
2765   Ptr += Count;
2766   if (Ptr > Opcodes.end()) {
2767     Ptr = Opcodes.end();
2768     Malformed = true;
2769   }
2770   return Result;
2771 }
2772 
2773 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
2774 
2775 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
2776 
2777 StringRef MachOBindEntry::typeName() const {
2778   switch (BindType) {
2779   case MachO::BIND_TYPE_POINTER:
2780     return "pointer";
2781   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
2782     return "text abs32";
2783   case MachO::BIND_TYPE_TEXT_PCREL32:
2784     return "text rel32";
2785   }
2786   return "unknown";
2787 }
2788 
2789 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
2790 
2791 int64_t MachOBindEntry::addend() const { return Addend; }
2792 
2793 uint32_t MachOBindEntry::flags() const { return Flags; }
2794 
2795 int MachOBindEntry::ordinal() const { return Ordinal; }
2796 
2797 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
2798   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2799   return (Ptr == Other.Ptr) &&
2800          (RemainingLoopCount == Other.RemainingLoopCount) &&
2801          (Done == Other.Done);
2802 }
2803 
2804 iterator_range<bind_iterator>
2805 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
2806                            MachOBindEntry::Kind BKind) {
2807   MachOBindEntry Start(Opcodes, is64, BKind);
2808   Start.moveToFirst();
2809 
2810   MachOBindEntry Finish(Opcodes, is64, BKind);
2811   Finish.moveToEnd();
2812 
2813   return make_range(bind_iterator(Start), bind_iterator(Finish));
2814 }
2815 
2816 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
2817   return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
2818                    MachOBindEntry::Kind::Regular);
2819 }
2820 
2821 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
2822   return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
2823                    MachOBindEntry::Kind::Lazy);
2824 }
2825 
2826 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
2827   return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
2828                    MachOBindEntry::Kind::Weak);
2829 }
2830 
2831 MachOObjectFile::load_command_iterator
2832 MachOObjectFile::begin_load_commands() const {
2833   return LoadCommands.begin();
2834 }
2835 
2836 MachOObjectFile::load_command_iterator
2837 MachOObjectFile::end_load_commands() const {
2838   return LoadCommands.end();
2839 }
2840 
2841 iterator_range<MachOObjectFile::load_command_iterator>
2842 MachOObjectFile::load_commands() const {
2843   return make_range(begin_load_commands(), end_load_commands());
2844 }
2845 
2846 StringRef
2847 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
2848   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
2849   return parseSegmentOrSectionName(Raw.data());
2850 }
2851 
2852 ArrayRef<char>
2853 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
2854   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
2855   const section_base *Base =
2856     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2857   return makeArrayRef(Base->sectname);
2858 }
2859 
2860 ArrayRef<char>
2861 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
2862   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
2863   const section_base *Base =
2864     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2865   return makeArrayRef(Base->segname);
2866 }
2867 
2868 bool
2869 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
2870   const {
2871   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
2872     return false;
2873   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
2874 }
2875 
2876 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
2877     const MachO::any_relocation_info &RE) const {
2878   if (isLittleEndian())
2879     return RE.r_word1 & 0xffffff;
2880   return RE.r_word1 >> 8;
2881 }
2882 
2883 bool MachOObjectFile::getPlainRelocationExternal(
2884     const MachO::any_relocation_info &RE) const {
2885   if (isLittleEndian())
2886     return (RE.r_word1 >> 27) & 1;
2887   return (RE.r_word1 >> 4) & 1;
2888 }
2889 
2890 bool MachOObjectFile::getScatteredRelocationScattered(
2891     const MachO::any_relocation_info &RE) const {
2892   return RE.r_word0 >> 31;
2893 }
2894 
2895 uint32_t MachOObjectFile::getScatteredRelocationValue(
2896     const MachO::any_relocation_info &RE) const {
2897   return RE.r_word1;
2898 }
2899 
2900 uint32_t MachOObjectFile::getScatteredRelocationType(
2901     const MachO::any_relocation_info &RE) const {
2902   return (RE.r_word0 >> 24) & 0xf;
2903 }
2904 
2905 unsigned MachOObjectFile::getAnyRelocationAddress(
2906     const MachO::any_relocation_info &RE) const {
2907   if (isRelocationScattered(RE))
2908     return getScatteredRelocationAddress(RE);
2909   return getPlainRelocationAddress(RE);
2910 }
2911 
2912 unsigned MachOObjectFile::getAnyRelocationPCRel(
2913     const MachO::any_relocation_info &RE) const {
2914   if (isRelocationScattered(RE))
2915     return getScatteredRelocationPCRel(this, RE);
2916   return getPlainRelocationPCRel(this, RE);
2917 }
2918 
2919 unsigned MachOObjectFile::getAnyRelocationLength(
2920     const MachO::any_relocation_info &RE) const {
2921   if (isRelocationScattered(RE))
2922     return getScatteredRelocationLength(RE);
2923   return getPlainRelocationLength(this, RE);
2924 }
2925 
2926 unsigned
2927 MachOObjectFile::getAnyRelocationType(
2928                                    const MachO::any_relocation_info &RE) const {
2929   if (isRelocationScattered(RE))
2930     return getScatteredRelocationType(RE);
2931   return getPlainRelocationType(this, RE);
2932 }
2933 
2934 SectionRef
2935 MachOObjectFile::getAnyRelocationSection(
2936                                    const MachO::any_relocation_info &RE) const {
2937   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2938     return *section_end();
2939   unsigned SecNum = getPlainRelocationSymbolNum(RE);
2940   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
2941     return *section_end();
2942   DataRefImpl DRI;
2943   DRI.d.a = SecNum - 1;
2944   return SectionRef(DRI, this);
2945 }
2946 
2947 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2948   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2949   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2950 }
2951 
2952 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2953   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2954   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2955 }
2956 
2957 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2958                                            unsigned Index) const {
2959   const char *Sec = getSectionPtr(this, L, Index);
2960   return getStruct<MachO::section>(this, Sec);
2961 }
2962 
2963 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2964                                                 unsigned Index) const {
2965   const char *Sec = getSectionPtr(this, L, Index);
2966   return getStruct<MachO::section_64>(this, Sec);
2967 }
2968 
2969 MachO::nlist
2970 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2971   const char *P = reinterpret_cast<const char *>(DRI.p);
2972   return getStruct<MachO::nlist>(this, P);
2973 }
2974 
2975 MachO::nlist_64
2976 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2977   const char *P = reinterpret_cast<const char *>(DRI.p);
2978   return getStruct<MachO::nlist_64>(this, P);
2979 }
2980 
2981 MachO::linkedit_data_command
2982 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2983   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2984 }
2985 
2986 MachO::segment_command
2987 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2988   return getStruct<MachO::segment_command>(this, L.Ptr);
2989 }
2990 
2991 MachO::segment_command_64
2992 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2993   return getStruct<MachO::segment_command_64>(this, L.Ptr);
2994 }
2995 
2996 MachO::linker_option_command
2997 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2998   return getStruct<MachO::linker_option_command>(this, L.Ptr);
2999 }
3000 
3001 MachO::version_min_command
3002 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
3003   return getStruct<MachO::version_min_command>(this, L.Ptr);
3004 }
3005 
3006 MachO::dylib_command
3007 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
3008   return getStruct<MachO::dylib_command>(this, L.Ptr);
3009 }
3010 
3011 MachO::dyld_info_command
3012 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
3013   return getStruct<MachO::dyld_info_command>(this, L.Ptr);
3014 }
3015 
3016 MachO::dylinker_command
3017 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
3018   return getStruct<MachO::dylinker_command>(this, L.Ptr);
3019 }
3020 
3021 MachO::uuid_command
3022 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
3023   return getStruct<MachO::uuid_command>(this, L.Ptr);
3024 }
3025 
3026 MachO::rpath_command
3027 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
3028   return getStruct<MachO::rpath_command>(this, L.Ptr);
3029 }
3030 
3031 MachO::source_version_command
3032 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
3033   return getStruct<MachO::source_version_command>(this, L.Ptr);
3034 }
3035 
3036 MachO::entry_point_command
3037 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
3038   return getStruct<MachO::entry_point_command>(this, L.Ptr);
3039 }
3040 
3041 MachO::encryption_info_command
3042 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
3043   return getStruct<MachO::encryption_info_command>(this, L.Ptr);
3044 }
3045 
3046 MachO::encryption_info_command_64
3047 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
3048   return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
3049 }
3050 
3051 MachO::sub_framework_command
3052 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
3053   return getStruct<MachO::sub_framework_command>(this, L.Ptr);
3054 }
3055 
3056 MachO::sub_umbrella_command
3057 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
3058   return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
3059 }
3060 
3061 MachO::sub_library_command
3062 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
3063   return getStruct<MachO::sub_library_command>(this, L.Ptr);
3064 }
3065 
3066 MachO::sub_client_command
3067 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
3068   return getStruct<MachO::sub_client_command>(this, L.Ptr);
3069 }
3070 
3071 MachO::routines_command
3072 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
3073   return getStruct<MachO::routines_command>(this, L.Ptr);
3074 }
3075 
3076 MachO::routines_command_64
3077 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
3078   return getStruct<MachO::routines_command_64>(this, L.Ptr);
3079 }
3080 
3081 MachO::thread_command
3082 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
3083   return getStruct<MachO::thread_command>(this, L.Ptr);
3084 }
3085 
3086 MachO::any_relocation_info
3087 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
3088   DataRefImpl Sec;
3089   Sec.d.a = Rel.d.a;
3090   uint32_t Offset;
3091   if (is64Bit()) {
3092     MachO::section_64 Sect = getSection64(Sec);
3093     Offset = Sect.reloff;
3094   } else {
3095     MachO::section Sect = getSection(Sec);
3096     Offset = Sect.reloff;
3097   }
3098 
3099   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
3100       getPtr(this, Offset)) + Rel.d.b;
3101   return getStruct<MachO::any_relocation_info>(
3102       this, reinterpret_cast<const char *>(P));
3103 }
3104 
3105 MachO::data_in_code_entry
3106 MachOObjectFile::getDice(DataRefImpl Rel) const {
3107   const char *P = reinterpret_cast<const char *>(Rel.p);
3108   return getStruct<MachO::data_in_code_entry>(this, P);
3109 }
3110 
3111 const MachO::mach_header &MachOObjectFile::getHeader() const {
3112   return Header;
3113 }
3114 
3115 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
3116   assert(is64Bit());
3117   return Header64;
3118 }
3119 
3120 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
3121                                              const MachO::dysymtab_command &DLC,
3122                                              unsigned Index) const {
3123   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
3124   return getStruct<uint32_t>(this, getPtr(this, Offset));
3125 }
3126 
3127 MachO::data_in_code_entry
3128 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
3129                                          unsigned Index) const {
3130   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
3131   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
3132 }
3133 
3134 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
3135   if (SymtabLoadCmd)
3136     return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
3137 
3138   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
3139   MachO::symtab_command Cmd;
3140   Cmd.cmd = MachO::LC_SYMTAB;
3141   Cmd.cmdsize = sizeof(MachO::symtab_command);
3142   Cmd.symoff = 0;
3143   Cmd.nsyms = 0;
3144   Cmd.stroff = 0;
3145   Cmd.strsize = 0;
3146   return Cmd;
3147 }
3148 
3149 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
3150   if (DysymtabLoadCmd)
3151     return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
3152 
3153   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
3154   MachO::dysymtab_command Cmd;
3155   Cmd.cmd = MachO::LC_DYSYMTAB;
3156   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
3157   Cmd.ilocalsym = 0;
3158   Cmd.nlocalsym = 0;
3159   Cmd.iextdefsym = 0;
3160   Cmd.nextdefsym = 0;
3161   Cmd.iundefsym = 0;
3162   Cmd.nundefsym = 0;
3163   Cmd.tocoff = 0;
3164   Cmd.ntoc = 0;
3165   Cmd.modtaboff = 0;
3166   Cmd.nmodtab = 0;
3167   Cmd.extrefsymoff = 0;
3168   Cmd.nextrefsyms = 0;
3169   Cmd.indirectsymoff = 0;
3170   Cmd.nindirectsyms = 0;
3171   Cmd.extreloff = 0;
3172   Cmd.nextrel = 0;
3173   Cmd.locreloff = 0;
3174   Cmd.nlocrel = 0;
3175   return Cmd;
3176 }
3177 
3178 MachO::linkedit_data_command
3179 MachOObjectFile::getDataInCodeLoadCommand() const {
3180   if (DataInCodeLoadCmd)
3181     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
3182 
3183   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
3184   MachO::linkedit_data_command Cmd;
3185   Cmd.cmd = MachO::LC_DATA_IN_CODE;
3186   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3187   Cmd.dataoff = 0;
3188   Cmd.datasize = 0;
3189   return Cmd;
3190 }
3191 
3192 MachO::linkedit_data_command
3193 MachOObjectFile::getLinkOptHintsLoadCommand() const {
3194   if (LinkOptHintsLoadCmd)
3195     return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
3196 
3197   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
3198   // fields.
3199   MachO::linkedit_data_command Cmd;
3200   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
3201   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3202   Cmd.dataoff = 0;
3203   Cmd.datasize = 0;
3204   return Cmd;
3205 }
3206 
3207 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
3208   if (!DyldInfoLoadCmd)
3209     return None;
3210 
3211   MachO::dyld_info_command DyldInfo =
3212       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
3213   const uint8_t *Ptr =
3214       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off));
3215   return makeArrayRef(Ptr, DyldInfo.rebase_size);
3216 }
3217 
3218 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
3219   if (!DyldInfoLoadCmd)
3220     return None;
3221 
3222   MachO::dyld_info_command DyldInfo =
3223       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
3224   const uint8_t *Ptr =
3225       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off));
3226   return makeArrayRef(Ptr, DyldInfo.bind_size);
3227 }
3228 
3229 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
3230   if (!DyldInfoLoadCmd)
3231     return None;
3232 
3233   MachO::dyld_info_command DyldInfo =
3234       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
3235   const uint8_t *Ptr =
3236       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off));
3237   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
3238 }
3239 
3240 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
3241   if (!DyldInfoLoadCmd)
3242     return None;
3243 
3244   MachO::dyld_info_command DyldInfo =
3245       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
3246   const uint8_t *Ptr =
3247       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off));
3248   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
3249 }
3250 
3251 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
3252   if (!DyldInfoLoadCmd)
3253     return None;
3254 
3255   MachO::dyld_info_command DyldInfo =
3256       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
3257   const uint8_t *Ptr =
3258       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off));
3259   return makeArrayRef(Ptr, DyldInfo.export_size);
3260 }
3261 
3262 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
3263   if (!UuidLoadCmd)
3264     return None;
3265   // Returning a pointer is fine as uuid doesn't need endian swapping.
3266   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
3267   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
3268 }
3269 
3270 StringRef MachOObjectFile::getStringTableData() const {
3271   MachO::symtab_command S = getSymtabLoadCommand();
3272   return getData().substr(S.stroff, S.strsize);
3273 }
3274 
3275 bool MachOObjectFile::is64Bit() const {
3276   return getType() == getMachOType(false, true) ||
3277     getType() == getMachOType(true, true);
3278 }
3279 
3280 void MachOObjectFile::ReadULEB128s(uint64_t Index,
3281                                    SmallVectorImpl<uint64_t> &Out) const {
3282   DataExtractor extractor(ObjectFile::getData(), true, 0);
3283 
3284   uint32_t offset = Index;
3285   uint64_t data = 0;
3286   while (uint64_t delta = extractor.getULEB128(&offset)) {
3287     data += delta;
3288     Out.push_back(data);
3289   }
3290 }
3291 
3292 bool MachOObjectFile::isRelocatableObject() const {
3293   return getHeader().filetype == MachO::MH_OBJECT;
3294 }
3295 
3296 Expected<std::unique_ptr<MachOObjectFile>>
3297 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
3298                                   uint32_t UniversalCputype,
3299                                   uint32_t UniversalIndex) {
3300   StringRef Magic = Buffer.getBuffer().slice(0, 4);
3301   if (Magic == "\xFE\xED\xFA\xCE")
3302     return MachOObjectFile::create(Buffer, false, false,
3303                                    UniversalCputype, UniversalIndex);
3304   if (Magic == "\xCE\xFA\xED\xFE")
3305     return MachOObjectFile::create(Buffer, true, false,
3306                                    UniversalCputype, UniversalIndex);
3307   if (Magic == "\xFE\xED\xFA\xCF")
3308     return MachOObjectFile::create(Buffer, false, true,
3309                                    UniversalCputype, UniversalIndex);
3310   if (Magic == "\xCF\xFA\xED\xFE")
3311     return MachOObjectFile::create(Buffer, true, true,
3312                                    UniversalCputype, UniversalIndex);
3313   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
3314                                         object_error::invalid_file_type);
3315 }
3316