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