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