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