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