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