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