xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision c3a035d86f91a380bd001eb6ad4cf4faf6bd5e84)
1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/Object/MachO.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include <cctype>
28 #include <cstring>
29 #include <limits>
30 #include <list>
31 
32 using namespace llvm;
33 using namespace object;
34 
35 namespace {
36   struct section_base {
37     char sectname[16];
38     char segname[16];
39   };
40 }
41 
42 static Error
43 malformedError(Twine Msg) {
44   std::string StringMsg = "truncated or malformed object (" + Msg.str() + ")";
45   return make_error<GenericBinaryError>(std::move(StringMsg),
46                                         object_error::parse_failed);
47 }
48 
49 // FIXME: Replace all uses of this function with getStructOrErr.
50 template <typename T>
51 static T getStruct(const MachOObjectFile &O, const char *P) {
52   // Don't read before the beginning or past the end of the file
53   if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
54     report_fatal_error("Malformed MachO file.");
55 
56   T Cmd;
57   memcpy(&Cmd, P, sizeof(T));
58   if (O.isLittleEndian() != sys::IsLittleEndianHost)
59     MachO::swapStruct(Cmd);
60   return Cmd;
61 }
62 
63 template <typename T>
64 static Expected<T> getStructOrErr(const MachOObjectFile &O, const char *P) {
65   // Don't read before the beginning or past the end of the file
66   if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
67     return malformedError("Structure read out-of-range");
68 
69   T Cmd;
70   memcpy(&Cmd, P, sizeof(T));
71   if (O.isLittleEndian() != sys::IsLittleEndianHost)
72     MachO::swapStruct(Cmd);
73   return Cmd;
74 }
75 
76 static const char *
77 getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L,
78               unsigned Sec) {
79   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
80 
81   bool Is64 = O.is64Bit();
82   unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
83                                     sizeof(MachO::segment_command);
84   unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
85                                 sizeof(MachO::section);
86 
87   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
88   return reinterpret_cast<const char*>(SectionAddr);
89 }
90 
91 static const char *getPtr(const MachOObjectFile &O, size_t Offset) {
92   return O.getData().substr(Offset, 1).data();
93 }
94 
95 static MachO::nlist_base
96 getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI) {
97   const char *P = reinterpret_cast<const char *>(DRI.p);
98   return getStruct<MachO::nlist_base>(O, P);
99 }
100 
101 static StringRef parseSegmentOrSectionName(const char *P) {
102   if (P[15] == 0)
103     // Null terminated.
104     return P;
105   // Not null terminated, so this is a 16 char string.
106   return StringRef(P, 16);
107 }
108 
109 // Helper to advance a section or symbol iterator multiple increments at a time.
110 template<class T>
111 static void advance(T &it, size_t Val) {
112   while (Val--)
113     ++it;
114 }
115 
116 static unsigned getCPUType(const MachOObjectFile &O) {
117   return O.getHeader().cputype;
118 }
119 
120 static uint32_t
121 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
122   return RE.r_word0;
123 }
124 
125 static unsigned
126 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
127   return RE.r_word0 & 0xffffff;
128 }
129 
130 static bool getPlainRelocationPCRel(const MachOObjectFile &O,
131                                     const MachO::any_relocation_info &RE) {
132   if (O.isLittleEndian())
133     return (RE.r_word1 >> 24) & 1;
134   return (RE.r_word1 >> 7) & 1;
135 }
136 
137 static bool
138 getScatteredRelocationPCRel(const MachO::any_relocation_info &RE) {
139   return (RE.r_word0 >> 30) & 1;
140 }
141 
142 static unsigned getPlainRelocationLength(const MachOObjectFile &O,
143                                          const MachO::any_relocation_info &RE) {
144   if (O.isLittleEndian())
145     return (RE.r_word1 >> 25) & 3;
146   return (RE.r_word1 >> 5) & 3;
147 }
148 
149 static unsigned
150 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
151   return (RE.r_word0 >> 28) & 3;
152 }
153 
154 static unsigned getPlainRelocationType(const MachOObjectFile &O,
155                                        const MachO::any_relocation_info &RE) {
156   if (O.isLittleEndian())
157     return RE.r_word1 >> 28;
158   return RE.r_word1 & 0xf;
159 }
160 
161 static uint32_t getSectionFlags(const MachOObjectFile &O,
162                                 DataRefImpl Sec) {
163   if (O.is64Bit()) {
164     MachO::section_64 Sect = O.getSection64(Sec);
165     return Sect.flags;
166   }
167   MachO::section Sect = O.getSection(Sec);
168   return Sect.flags;
169 }
170 
171 static Expected<MachOObjectFile::LoadCommandInfo>
172 getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr,
173                    uint32_t LoadCommandIndex) {
174   if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
175     if (CmdOrErr->cmdsize < 8)
176       return malformedError("load command " + Twine(LoadCommandIndex) +
177                             " with size less than 8 bytes");
178     return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
179   } else
180     return CmdOrErr.takeError();
181 }
182 
183 static Expected<MachOObjectFile::LoadCommandInfo>
184 getFirstLoadCommandInfo(const MachOObjectFile &Obj) {
185   unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
186                                       : sizeof(MachO::mach_header);
187   if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds)
188     return malformedError("load command 0 extends past the end all load "
189                           "commands in the file");
190   return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
191 }
192 
193 static Expected<MachOObjectFile::LoadCommandInfo>
194 getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex,
195                        const MachOObjectFile::LoadCommandInfo &L) {
196   unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
197                                       : sizeof(MachO::mach_header);
198   if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
199       Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
200     return malformedError("load command " + Twine(LoadCommandIndex + 1) +
201                           " extends past the end all load commands in the file");
202   return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
203 }
204 
205 template <typename T>
206 static void parseHeader(const MachOObjectFile &Obj, T &Header,
207                         Error &Err) {
208   if (sizeof(T) > Obj.getData().size()) {
209     Err = malformedError("the mach header extends past the end of the "
210                          "file");
211     return;
212   }
213   if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
214     Header = *HeaderOrErr;
215   else
216     Err = HeaderOrErr.takeError();
217 }
218 
219 // This is used to check for overlapping of Mach-O elements.
220 struct MachOElement {
221   uint64_t Offset;
222   uint64_t Size;
223   const char *Name;
224 };
225 
226 static Error checkOverlappingElement(std::list<MachOElement> &Elements,
227                                      uint64_t Offset, uint64_t Size,
228                                      const char *Name) {
229   if (Size == 0)
230     return Error::success();
231 
232   for (auto it=Elements.begin() ; it != Elements.end(); ++it) {
233     auto E = *it;
234     if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
235         (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) ||
236         (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
237       return malformedError(Twine(Name) + " at offset " + Twine(Offset) +
238                             " with a size of " + Twine(Size) + ", overlaps " +
239                             E.Name + " at offset " + Twine(E.Offset) + " with "
240                             "a size of " + Twine(E.Size));
241     auto nt = it;
242     nt++;
243     if (nt != Elements.end()) {
244       auto N = *nt;
245       if (Offset + Size <= N.Offset) {
246         Elements.insert(nt, {Offset, Size, Name});
247         return Error::success();
248       }
249     }
250   }
251   Elements.push_back({Offset, Size, Name});
252   return Error::success();
253 }
254 
255 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
256 // sections to \param Sections, and optionally sets
257 // \param IsPageZeroSegment to true.
258 template <typename Segment, typename Section>
259 static Error parseSegmentLoadCommand(
260     const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load,
261     SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
262     uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
263     std::list<MachOElement> &Elements) {
264   const unsigned SegmentLoadSize = sizeof(Segment);
265   if (Load.C.cmdsize < SegmentLoadSize)
266     return malformedError("load command " + Twine(LoadCommandIndex) +
267                           " " + CmdName + " cmdsize too small");
268   if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
269     Segment S = SegOrErr.get();
270     const unsigned SectionSize = sizeof(Section);
271     uint64_t FileSize = Obj.getData().size();
272     if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
273         S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
274       return malformedError("load command " + Twine(LoadCommandIndex) +
275                             " inconsistent cmdsize in " + CmdName +
276                             " for the number of sections");
277     for (unsigned J = 0; J < S.nsects; ++J) {
278       const char *Sec = getSectionPtr(Obj, Load, J);
279       Sections.push_back(Sec);
280       Section s = getStruct<Section>(Obj, Sec);
281       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
282           Obj.getHeader().filetype != MachO::MH_DSYM &&
283           s.flags != MachO::S_ZEROFILL &&
284           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
285           s.offset > FileSize)
286         return malformedError("offset field of section " + Twine(J) + " in " +
287                               CmdName + " command " + Twine(LoadCommandIndex) +
288                               " extends past the end of the file");
289       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
290           Obj.getHeader().filetype != MachO::MH_DSYM &&
291           s.flags != MachO::S_ZEROFILL &&
292           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 &&
293           s.offset < SizeOfHeaders && s.size != 0)
294         return malformedError("offset field of section " + Twine(J) + " in " +
295                               CmdName + " command " + Twine(LoadCommandIndex) +
296                               " not past the headers of the file");
297       uint64_t BigSize = s.offset;
298       BigSize += s.size;
299       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
300           Obj.getHeader().filetype != MachO::MH_DSYM &&
301           s.flags != MachO::S_ZEROFILL &&
302           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
303           BigSize > FileSize)
304         return malformedError("offset field plus size field of section " +
305                               Twine(J) + " in " + CmdName + " command " +
306                               Twine(LoadCommandIndex) +
307                               " extends past the end of the file");
308       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
309           Obj.getHeader().filetype != MachO::MH_DSYM &&
310           s.flags != MachO::S_ZEROFILL &&
311           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
312           s.size > S.filesize)
313         return malformedError("size field of section " +
314                               Twine(J) + " in " + CmdName + " command " +
315                               Twine(LoadCommandIndex) +
316                               " greater than the segment");
317       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
318           Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
319           s.addr < S.vmaddr)
320         return malformedError("addr field of section " + Twine(J) + " in " +
321                               CmdName + " command " + Twine(LoadCommandIndex) +
322                               " less than the segment's vmaddr");
323       BigSize = s.addr;
324       BigSize += s.size;
325       uint64_t BigEnd = S.vmaddr;
326       BigEnd += S.vmsize;
327       if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
328         return malformedError("addr field plus size of section " + Twine(J) +
329                               " in " + CmdName + " command " +
330                               Twine(LoadCommandIndex) +
331                               " greater than than "
332                               "the segment's vmaddr plus vmsize");
333       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
334           Obj.getHeader().filetype != MachO::MH_DSYM &&
335           s.flags != MachO::S_ZEROFILL &&
336           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL)
337         if (Error Err = checkOverlappingElement(Elements, s.offset, s.size,
338                                                 "section contents"))
339           return Err;
340       if (s.reloff > FileSize)
341         return malformedError("reloff field of section " + Twine(J) + " in " +
342                               CmdName + " command " + Twine(LoadCommandIndex) +
343                               " extends past the end of the file");
344       BigSize = s.nreloc;
345       BigSize *= sizeof(struct MachO::relocation_info);
346       BigSize += s.reloff;
347       if (BigSize > FileSize)
348         return malformedError("reloff field plus nreloc field times sizeof("
349                               "struct relocation_info) of section " +
350                               Twine(J) + " in " + CmdName + " command " +
351                               Twine(LoadCommandIndex) +
352                               " extends past the end of the file");
353       if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc *
354                                               sizeof(struct
355                                               MachO::relocation_info),
356                                               "section relocation entries"))
357         return Err;
358     }
359     if (S.fileoff > FileSize)
360       return malformedError("load command " + Twine(LoadCommandIndex) +
361                             " fileoff field in " + CmdName +
362                             " extends past the end of the file");
363     uint64_t BigSize = S.fileoff;
364     BigSize += S.filesize;
365     if (BigSize > FileSize)
366       return malformedError("load command " + Twine(LoadCommandIndex) +
367                             " fileoff field plus filesize field in " +
368                             CmdName + " extends past the end of the file");
369     if (S.vmsize != 0 && S.filesize > S.vmsize)
370       return malformedError("load command " + Twine(LoadCommandIndex) +
371                             " fileoff field in " + CmdName +
372                             " greater than vmsize field");
373     IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
374   } else
375     return SegOrErr.takeError();
376 
377   return Error::success();
378 }
379 
380 static Error checkSymtabCommand(const MachOObjectFile &Obj,
381                                 const MachOObjectFile::LoadCommandInfo &Load,
382                                 uint32_t LoadCommandIndex,
383                                 const char **SymtabLoadCmd,
384                                 std::list<MachOElement> &Elements) {
385   if (Load.C.cmdsize < sizeof(MachO::symtab_command))
386     return malformedError("load command " + Twine(LoadCommandIndex) +
387                           " LC_SYMTAB cmdsize too small");
388   if (*SymtabLoadCmd != nullptr)
389     return malformedError("more than one LC_SYMTAB command");
390   MachO::symtab_command Symtab =
391     getStruct<MachO::symtab_command>(Obj, Load.Ptr);
392   if (Symtab.cmdsize != sizeof(MachO::symtab_command))
393     return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) +
394                           " has incorrect cmdsize");
395   uint64_t FileSize = Obj.getData().size();
396   if (Symtab.symoff > FileSize)
397     return malformedError("symoff field of LC_SYMTAB command " +
398                           Twine(LoadCommandIndex) + " extends past the end "
399                           "of the file");
400   uint64_t SymtabSize = Symtab.nsyms;
401   const char *struct_nlist_name;
402   if (Obj.is64Bit()) {
403     SymtabSize *= sizeof(MachO::nlist_64);
404     struct_nlist_name = "struct nlist_64";
405   } else {
406     SymtabSize *= sizeof(MachO::nlist);
407     struct_nlist_name = "struct nlist";
408   }
409   uint64_t BigSize = SymtabSize;
410   BigSize += Symtab.symoff;
411   if (BigSize > FileSize)
412     return malformedError("symoff field plus nsyms field times sizeof(" +
413                           Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
414                           Twine(LoadCommandIndex) + " extends past the end "
415                           "of the file");
416   if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize,
417                                           "symbol table"))
418     return Err;
419   if (Symtab.stroff > FileSize)
420     return malformedError("stroff field of LC_SYMTAB command " +
421                           Twine(LoadCommandIndex) + " extends past the end "
422                           "of the file");
423   BigSize = Symtab.stroff;
424   BigSize += Symtab.strsize;
425   if (BigSize > FileSize)
426     return malformedError("stroff field plus strsize field of LC_SYMTAB "
427                           "command " + Twine(LoadCommandIndex) + " extends "
428                           "past the end of the file");
429   if (Error Err = checkOverlappingElement(Elements, Symtab.stroff,
430                                           Symtab.strsize, "string table"))
431     return Err;
432   *SymtabLoadCmd = Load.Ptr;
433   return Error::success();
434 }
435 
436 static Error checkDysymtabCommand(const MachOObjectFile &Obj,
437                                   const MachOObjectFile::LoadCommandInfo &Load,
438                                   uint32_t LoadCommandIndex,
439                                   const char **DysymtabLoadCmd,
440                                   std::list<MachOElement> &Elements) {
441   if (Load.C.cmdsize < sizeof(MachO::dysymtab_command))
442     return malformedError("load command " + Twine(LoadCommandIndex) +
443                           " LC_DYSYMTAB cmdsize too small");
444   if (*DysymtabLoadCmd != nullptr)
445     return malformedError("more than one LC_DYSYMTAB command");
446   MachO::dysymtab_command Dysymtab =
447     getStruct<MachO::dysymtab_command>(Obj, Load.Ptr);
448   if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command))
449     return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) +
450                           " has incorrect cmdsize");
451   uint64_t FileSize = Obj.getData().size();
452   if (Dysymtab.tocoff > FileSize)
453     return malformedError("tocoff field of LC_DYSYMTAB command " +
454                           Twine(LoadCommandIndex) + " extends past the end of "
455                           "the file");
456   uint64_t BigSize = Dysymtab.ntoc;
457   BigSize *= sizeof(MachO::dylib_table_of_contents);
458   BigSize += Dysymtab.tocoff;
459   if (BigSize > FileSize)
460     return malformedError("tocoff field plus ntoc field times sizeof(struct "
461                           "dylib_table_of_contents) of LC_DYSYMTAB command " +
462                           Twine(LoadCommandIndex) + " extends past the end of "
463                           "the file");
464   if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff,
465                                           Dysymtab.ntoc * sizeof(struct
466 					  MachO::dylib_table_of_contents),
467 					  "table of contents"))
468     return Err;
469   if (Dysymtab.modtaboff > FileSize)
470     return malformedError("modtaboff field of LC_DYSYMTAB command " +
471                           Twine(LoadCommandIndex) + " extends past the end of "
472                           "the file");
473   BigSize = Dysymtab.nmodtab;
474   const char *struct_dylib_module_name;
475   uint64_t sizeof_modtab;
476   if (Obj.is64Bit()) {
477     sizeof_modtab = sizeof(MachO::dylib_module_64);
478     struct_dylib_module_name = "struct dylib_module_64";
479   } else {
480     sizeof_modtab = sizeof(MachO::dylib_module);
481     struct_dylib_module_name = "struct dylib_module";
482   }
483   BigSize *= sizeof_modtab;
484   BigSize += Dysymtab.modtaboff;
485   if (BigSize > FileSize)
486     return malformedError("modtaboff field plus nmodtab field times sizeof(" +
487                           Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
488                           "command " + Twine(LoadCommandIndex) + " extends "
489                           "past the end of the file");
490   if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff,
491                                           Dysymtab.nmodtab * sizeof_modtab,
492 					  "module table"))
493     return Err;
494   if (Dysymtab.extrefsymoff > FileSize)
495     return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
496                           Twine(LoadCommandIndex) + " extends past the end of "
497                           "the file");
498   BigSize = Dysymtab.nextrefsyms;
499   BigSize *= sizeof(MachO::dylib_reference);
500   BigSize += Dysymtab.extrefsymoff;
501   if (BigSize > FileSize)
502     return malformedError("extrefsymoff field plus nextrefsyms field times "
503                           "sizeof(struct dylib_reference) of LC_DYSYMTAB "
504                           "command " + Twine(LoadCommandIndex) + " extends "
505                           "past the end of the file");
506   if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff,
507                                           Dysymtab.nextrefsyms *
508                                           sizeof(MachO::dylib_reference),
509 					  "reference table"))
510     return Err;
511   if (Dysymtab.indirectsymoff > FileSize)
512     return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
513                           Twine(LoadCommandIndex) + " extends past the end of "
514                           "the file");
515   BigSize = Dysymtab.nindirectsyms;
516   BigSize *= sizeof(uint32_t);
517   BigSize += Dysymtab.indirectsymoff;
518   if (BigSize > FileSize)
519     return malformedError("indirectsymoff field plus nindirectsyms field times "
520                           "sizeof(uint32_t) of LC_DYSYMTAB command " +
521                           Twine(LoadCommandIndex) + " extends past the end of "
522                           "the file");
523   if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff,
524                                           Dysymtab.nindirectsyms *
525                                           sizeof(uint32_t),
526 					  "indirect table"))
527     return Err;
528   if (Dysymtab.extreloff > FileSize)
529     return malformedError("extreloff field of LC_DYSYMTAB command " +
530                           Twine(LoadCommandIndex) + " extends past the end of "
531                           "the file");
532   BigSize = Dysymtab.nextrel;
533   BigSize *= sizeof(MachO::relocation_info);
534   BigSize += Dysymtab.extreloff;
535   if (BigSize > FileSize)
536     return malformedError("extreloff field plus nextrel field times sizeof"
537                           "(struct relocation_info) of LC_DYSYMTAB command " +
538                           Twine(LoadCommandIndex) + " extends past the end of "
539                           "the file");
540   if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff,
541                                           Dysymtab.nextrel *
542                                           sizeof(MachO::relocation_info),
543 					  "external relocation table"))
544     return Err;
545   if (Dysymtab.locreloff > FileSize)
546     return malformedError("locreloff field of LC_DYSYMTAB command " +
547                           Twine(LoadCommandIndex) + " extends past the end of "
548                           "the file");
549   BigSize = Dysymtab.nlocrel;
550   BigSize *= sizeof(MachO::relocation_info);
551   BigSize += Dysymtab.locreloff;
552   if (BigSize > FileSize)
553     return malformedError("locreloff field plus nlocrel field times sizeof"
554                           "(struct relocation_info) of LC_DYSYMTAB command " +
555                           Twine(LoadCommandIndex) + " extends past the end of "
556                           "the file");
557   if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff,
558                                           Dysymtab.nlocrel *
559                                           sizeof(MachO::relocation_info),
560 					  "local relocation table"))
561     return Err;
562   *DysymtabLoadCmd = Load.Ptr;
563   return Error::success();
564 }
565 
566 static Error checkLinkeditDataCommand(const MachOObjectFile &Obj,
567                                  const MachOObjectFile::LoadCommandInfo &Load,
568                                  uint32_t LoadCommandIndex,
569                                  const char **LoadCmd, const char *CmdName,
570                                  std::list<MachOElement> &Elements,
571                                  const char *ElementName) {
572   if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command))
573     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
574                           CmdName + " cmdsize too small");
575   if (*LoadCmd != nullptr)
576     return malformedError("more than one " + Twine(CmdName) + " command");
577   MachO::linkedit_data_command LinkData =
578     getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr);
579   if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command))
580     return malformedError(Twine(CmdName) + " command " +
581                           Twine(LoadCommandIndex) + " has incorrect cmdsize");
582   uint64_t FileSize = Obj.getData().size();
583   if (LinkData.dataoff > FileSize)
584     return malformedError("dataoff field of " + Twine(CmdName) + " command " +
585                           Twine(LoadCommandIndex) + " extends past the end of "
586                           "the file");
587   uint64_t BigSize = LinkData.dataoff;
588   BigSize += LinkData.datasize;
589   if (BigSize > FileSize)
590     return malformedError("dataoff field plus datasize field of " +
591                           Twine(CmdName) + " command " +
592                           Twine(LoadCommandIndex) + " extends past the end of "
593                           "the file");
594   if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff,
595                                           LinkData.datasize, ElementName))
596     return Err;
597   *LoadCmd = Load.Ptr;
598   return Error::success();
599 }
600 
601 static Error checkDyldInfoCommand(const MachOObjectFile &Obj,
602                                   const MachOObjectFile::LoadCommandInfo &Load,
603                                   uint32_t LoadCommandIndex,
604                                   const char **LoadCmd, const char *CmdName,
605                                   std::list<MachOElement> &Elements) {
606   if (Load.C.cmdsize < sizeof(MachO::dyld_info_command))
607     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
608                           CmdName + " cmdsize too small");
609   if (*LoadCmd != nullptr)
610     return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
611                           "command");
612   MachO::dyld_info_command DyldInfo =
613     getStruct<MachO::dyld_info_command>(Obj, Load.Ptr);
614   if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command))
615     return malformedError(Twine(CmdName) + " command " +
616                           Twine(LoadCommandIndex) + " has incorrect cmdsize");
617   uint64_t FileSize = Obj.getData().size();
618   if (DyldInfo.rebase_off > FileSize)
619     return malformedError("rebase_off field of " + Twine(CmdName) +
620                           " command " + Twine(LoadCommandIndex) + " extends "
621                           "past the end of the file");
622   uint64_t BigSize = DyldInfo.rebase_off;
623   BigSize += DyldInfo.rebase_size;
624   if (BigSize > FileSize)
625     return malformedError("rebase_off field plus rebase_size field of " +
626                           Twine(CmdName) + " command " +
627                           Twine(LoadCommandIndex) + " extends past the end of "
628                           "the file");
629   if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off,
630                                           DyldInfo.rebase_size,
631                                           "dyld rebase info"))
632     return Err;
633   if (DyldInfo.bind_off > FileSize)
634     return malformedError("bind_off field of " + Twine(CmdName) +
635                           " command " + Twine(LoadCommandIndex) + " extends "
636                           "past the end of the file");
637   BigSize = DyldInfo.bind_off;
638   BigSize += DyldInfo.bind_size;
639   if (BigSize > FileSize)
640     return malformedError("bind_off field plus bind_size field of " +
641                           Twine(CmdName) + " command " +
642                           Twine(LoadCommandIndex) + " extends past the end of "
643                           "the file");
644   if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off,
645                                           DyldInfo.bind_size,
646                                           "dyld bind info"))
647     return Err;
648   if (DyldInfo.weak_bind_off > FileSize)
649     return malformedError("weak_bind_off field of " + Twine(CmdName) +
650                           " command " + Twine(LoadCommandIndex) + " extends "
651                           "past the end of the file");
652   BigSize = DyldInfo.weak_bind_off;
653   BigSize += DyldInfo.weak_bind_size;
654   if (BigSize > FileSize)
655     return malformedError("weak_bind_off field plus weak_bind_size field of " +
656                           Twine(CmdName) + " command " +
657                           Twine(LoadCommandIndex) + " extends past the end of "
658                           "the file");
659   if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off,
660                                           DyldInfo.weak_bind_size,
661                                           "dyld weak bind info"))
662     return Err;
663   if (DyldInfo.lazy_bind_off > FileSize)
664     return malformedError("lazy_bind_off field of " + Twine(CmdName) +
665                           " command " + Twine(LoadCommandIndex) + " extends "
666                           "past the end of the file");
667   BigSize = DyldInfo.lazy_bind_off;
668   BigSize += DyldInfo.lazy_bind_size;
669   if (BigSize > FileSize)
670     return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
671                           Twine(CmdName) + " command " +
672                           Twine(LoadCommandIndex) + " extends past the end of "
673                           "the file");
674   if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off,
675                                           DyldInfo.lazy_bind_size,
676                                           "dyld lazy bind info"))
677     return Err;
678   if (DyldInfo.export_off > FileSize)
679     return malformedError("export_off field of " + Twine(CmdName) +
680                           " command " + Twine(LoadCommandIndex) + " extends "
681                           "past the end of the file");
682   BigSize = DyldInfo.export_off;
683   BigSize += DyldInfo.export_size;
684   if (BigSize > FileSize)
685     return malformedError("export_off field plus export_size field of " +
686                           Twine(CmdName) + " command " +
687                           Twine(LoadCommandIndex) + " extends past the end of "
688                           "the file");
689   if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off,
690                                           DyldInfo.export_size,
691                                           "dyld export info"))
692     return Err;
693   *LoadCmd = Load.Ptr;
694   return Error::success();
695 }
696 
697 static Error checkDylibCommand(const MachOObjectFile &Obj,
698                                const MachOObjectFile::LoadCommandInfo &Load,
699                                uint32_t LoadCommandIndex, const char *CmdName) {
700   if (Load.C.cmdsize < sizeof(MachO::dylib_command))
701     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
702                           CmdName + " cmdsize too small");
703   MachO::dylib_command D = getStruct<MachO::dylib_command>(Obj, Load.Ptr);
704   if (D.dylib.name < sizeof(MachO::dylib_command))
705     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
706                           CmdName + " name.offset field too small, not past "
707                           "the end of the dylib_command struct");
708   if (D.dylib.name >= D.cmdsize)
709     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
710                           CmdName + " name.offset field extends past the end "
711                           "of the load command");
712   // Make sure there is a null between the starting offset of the name and
713   // the end of the load command.
714   uint32_t i;
715   const char *P = (const char *)Load.Ptr;
716   for (i = D.dylib.name; i < D.cmdsize; i++)
717     if (P[i] == '\0')
718       break;
719   if (i >= D.cmdsize)
720     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
721                           CmdName + " library name extends past the end of the "
722                           "load command");
723   return Error::success();
724 }
725 
726 static Error checkDylibIdCommand(const MachOObjectFile &Obj,
727                                  const MachOObjectFile::LoadCommandInfo &Load,
728                                  uint32_t LoadCommandIndex,
729                                  const char **LoadCmd) {
730   if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex,
731                                      "LC_ID_DYLIB"))
732     return Err;
733   if (*LoadCmd != nullptr)
734     return malformedError("more than one LC_ID_DYLIB command");
735   if (Obj.getHeader().filetype != MachO::MH_DYLIB &&
736       Obj.getHeader().filetype != MachO::MH_DYLIB_STUB)
737     return malformedError("LC_ID_DYLIB load command in non-dynamic library "
738                           "file type");
739   *LoadCmd = Load.Ptr;
740   return Error::success();
741 }
742 
743 static Error checkDyldCommand(const MachOObjectFile &Obj,
744                               const MachOObjectFile::LoadCommandInfo &Load,
745                               uint32_t LoadCommandIndex, const char *CmdName) {
746   if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
747     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
748                           CmdName + " cmdsize too small");
749   MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr);
750   if (D.name < sizeof(MachO::dylinker_command))
751     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
752                           CmdName + " name.offset field too small, not past "
753                           "the end of the dylinker_command struct");
754   if (D.name >= D.cmdsize)
755     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
756                           CmdName + " name.offset field extends past the end "
757                           "of the load command");
758   // Make sure there is a null between the starting offset of the name and
759   // the end of the load command.
760   uint32_t i;
761   const char *P = (const char *)Load.Ptr;
762   for (i = D.name; i < D.cmdsize; i++)
763     if (P[i] == '\0')
764       break;
765   if (i >= D.cmdsize)
766     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
767                           CmdName + " dyld name extends past the end of the "
768                           "load command");
769   return Error::success();
770 }
771 
772 static Error checkVersCommand(const MachOObjectFile &Obj,
773                               const MachOObjectFile::LoadCommandInfo &Load,
774                               uint32_t LoadCommandIndex,
775                               const char **LoadCmd, const char *CmdName) {
776   if (Load.C.cmdsize != sizeof(MachO::version_min_command))
777     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
778                           CmdName + " has incorrect cmdsize");
779   if (*LoadCmd != nullptr)
780     return malformedError("more than one LC_VERSION_MIN_MACOSX, "
781                           "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
782                           "LC_VERSION_MIN_WATCHOS command");
783   *LoadCmd = Load.Ptr;
784   return Error::success();
785 }
786 
787 static Error 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 (ArchFlag)
2458         *ArchFlag = "armv7k";
2459       return Triple("armv7k-apple-darwin");
2460     case MachO::CPU_SUBTYPE_ARM_V7M:
2461       if (McpuDefault)
2462         *McpuDefault = "cortex-m3";
2463       if (ArchFlag)
2464         *ArchFlag = "armv7m";
2465       return Triple("thumbv7m-apple-darwin");
2466     case MachO::CPU_SUBTYPE_ARM_V7S:
2467       if (ArchFlag)
2468         *ArchFlag = "armv7s";
2469       return Triple("armv7s-apple-darwin");
2470     default:
2471       return Triple();
2472     }
2473   case MachO::CPU_TYPE_ARM64:
2474     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2475     case MachO::CPU_SUBTYPE_ARM64_ALL:
2476       if (ArchFlag)
2477         *ArchFlag = "arm64";
2478       return Triple("arm64-apple-darwin");
2479     default:
2480       return Triple();
2481     }
2482   case MachO::CPU_TYPE_POWERPC:
2483     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2484     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2485       if (ArchFlag)
2486         *ArchFlag = "ppc";
2487       return Triple("ppc-apple-darwin");
2488     default:
2489       return Triple();
2490     }
2491   case MachO::CPU_TYPE_POWERPC64:
2492     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2493     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2494       if (ArchFlag)
2495         *ArchFlag = "ppc64";
2496       return Triple("ppc64-apple-darwin");
2497     default:
2498       return Triple();
2499     }
2500   default:
2501     return Triple();
2502   }
2503 }
2504 
2505 Triple MachOObjectFile::getHostArch() {
2506   return Triple(sys::getDefaultTargetTriple());
2507 }
2508 
2509 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
2510   return StringSwitch<bool>(ArchFlag)
2511       .Case("i386", true)
2512       .Case("x86_64", true)
2513       .Case("x86_64h", true)
2514       .Case("armv4t", true)
2515       .Case("arm", true)
2516       .Case("armv5e", true)
2517       .Case("armv6", true)
2518       .Case("armv6m", true)
2519       .Case("armv7", true)
2520       .Case("armv7em", true)
2521       .Case("armv7k", true)
2522       .Case("armv7m", true)
2523       .Case("armv7s", true)
2524       .Case("arm64", true)
2525       .Case("ppc", true)
2526       .Case("ppc64", true)
2527       .Default(false);
2528 }
2529 
2530 unsigned MachOObjectFile::getArch() const {
2531   return getArch(getCPUType(*this));
2532 }
2533 
2534 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2535   return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2536 }
2537 
2538 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
2539   DataRefImpl DRI;
2540   DRI.d.a = Index;
2541   return section_rel_begin(DRI);
2542 }
2543 
2544 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
2545   DataRefImpl DRI;
2546   DRI.d.a = Index;
2547   return section_rel_end(DRI);
2548 }
2549 
2550 dice_iterator MachOObjectFile::begin_dices() const {
2551   DataRefImpl DRI;
2552   if (!DataInCodeLoadCmd)
2553     return dice_iterator(DiceRef(DRI, this));
2554 
2555   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2556   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2557   return dice_iterator(DiceRef(DRI, this));
2558 }
2559 
2560 dice_iterator MachOObjectFile::end_dices() const {
2561   DataRefImpl DRI;
2562   if (!DataInCodeLoadCmd)
2563     return dice_iterator(DiceRef(DRI, this));
2564 
2565   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2566   unsigned Offset = DicLC.dataoff + DicLC.datasize;
2567   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2568   return dice_iterator(DiceRef(DRI, this));
2569 }
2570 
2571 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
2572     : Trie(T), Malformed(false), Done(false) {}
2573 
2574 void ExportEntry::moveToFirst() {
2575   pushNode(0);
2576   pushDownUntilBottom();
2577 }
2578 
2579 void ExportEntry::moveToEnd() {
2580   Stack.clear();
2581   Done = true;
2582 }
2583 
2584 bool ExportEntry::operator==(const ExportEntry &Other) const {
2585   // Common case, one at end, other iterating from begin.
2586   if (Done || Other.Done)
2587     return (Done == Other.Done);
2588   // Not equal if different stack sizes.
2589   if (Stack.size() != Other.Stack.size())
2590     return false;
2591   // Not equal if different cumulative strings.
2592   if (!CumulativeString.equals(Other.CumulativeString))
2593     return false;
2594   // Equal if all nodes in both stacks match.
2595   for (unsigned i=0; i < Stack.size(); ++i) {
2596     if (Stack[i].Start != Other.Stack[i].Start)
2597       return false;
2598   }
2599   return true;
2600 }
2601 
2602 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
2603   unsigned Count;
2604   uint64_t Result = decodeULEB128(Ptr, &Count);
2605   Ptr += Count;
2606   if (Ptr > Trie.end()) {
2607     Ptr = Trie.end();
2608     Malformed = true;
2609   }
2610   return Result;
2611 }
2612 
2613 StringRef ExportEntry::name() const {
2614   return CumulativeString;
2615 }
2616 
2617 uint64_t ExportEntry::flags() const {
2618   return Stack.back().Flags;
2619 }
2620 
2621 uint64_t ExportEntry::address() const {
2622   return Stack.back().Address;
2623 }
2624 
2625 uint64_t ExportEntry::other() const {
2626   return Stack.back().Other;
2627 }
2628 
2629 StringRef ExportEntry::otherName() const {
2630   const char* ImportName = Stack.back().ImportName;
2631   if (ImportName)
2632     return StringRef(ImportName);
2633   return StringRef();
2634 }
2635 
2636 uint32_t ExportEntry::nodeOffset() const {
2637   return Stack.back().Start - Trie.begin();
2638 }
2639 
2640 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2641     : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
2642       ImportName(nullptr), ChildCount(0), NextChildIndex(0),
2643       ParentStringLength(0), IsExportNode(false) {}
2644 
2645 void ExportEntry::pushNode(uint64_t offset) {
2646   const uint8_t *Ptr = Trie.begin() + offset;
2647   NodeState State(Ptr);
2648   uint64_t ExportInfoSize = readULEB128(State.Current);
2649   State.IsExportNode = (ExportInfoSize != 0);
2650   const uint8_t* Children = State.Current + ExportInfoSize;
2651   if (State.IsExportNode) {
2652     State.Flags = readULEB128(State.Current);
2653     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2654       State.Address = 0;
2655       State.Other = readULEB128(State.Current); // dylib ordinal
2656       State.ImportName = reinterpret_cast<const char*>(State.Current);
2657     } else {
2658       State.Address = readULEB128(State.Current);
2659       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
2660         State.Other = readULEB128(State.Current);
2661     }
2662   }
2663   State.ChildCount = *Children;
2664   State.Current = Children + 1;
2665   State.NextChildIndex = 0;
2666   State.ParentStringLength = CumulativeString.size();
2667   Stack.push_back(State);
2668 }
2669 
2670 void ExportEntry::pushDownUntilBottom() {
2671   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2672     NodeState &Top = Stack.back();
2673     CumulativeString.resize(Top.ParentStringLength);
2674     for (;*Top.Current != 0; Top.Current++) {
2675       char C = *Top.Current;
2676       CumulativeString.push_back(C);
2677     }
2678     Top.Current += 1;
2679     uint64_t childNodeIndex = readULEB128(Top.Current);
2680     Top.NextChildIndex += 1;
2681     pushNode(childNodeIndex);
2682   }
2683   if (!Stack.back().IsExportNode) {
2684     Malformed = true;
2685     moveToEnd();
2686   }
2687 }
2688 
2689 // We have a trie data structure and need a way to walk it that is compatible
2690 // with the C++ iterator model. The solution is a non-recursive depth first
2691 // traversal where the iterator contains a stack of parent nodes along with a
2692 // string that is the accumulation of all edge strings along the parent chain
2693 // to this point.
2694 //
2695 // There is one "export" node for each exported symbol.  But because some
2696 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
2697 // node may have child nodes too.
2698 //
2699 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
2700 // child until hitting a node with no children (which is an export node or
2701 // else the trie is malformed). On the way down, each node is pushed on the
2702 // stack ivar.  If there is no more ways down, it pops up one and tries to go
2703 // down a sibling path until a childless node is reached.
2704 void ExportEntry::moveNext() {
2705   if (Stack.empty() || !Stack.back().IsExportNode) {
2706     Malformed = true;
2707     moveToEnd();
2708     return;
2709   }
2710 
2711   Stack.pop_back();
2712   while (!Stack.empty()) {
2713     NodeState &Top = Stack.back();
2714     if (Top.NextChildIndex < Top.ChildCount) {
2715       pushDownUntilBottom();
2716       // Now at the next export node.
2717       return;
2718     } else {
2719       if (Top.IsExportNode) {
2720         // This node has no children but is itself an export node.
2721         CumulativeString.resize(Top.ParentStringLength);
2722         return;
2723       }
2724       Stack.pop_back();
2725     }
2726   }
2727   Done = true;
2728 }
2729 
2730 iterator_range<export_iterator>
2731 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
2732   ExportEntry Start(Trie);
2733   if (Trie.size() == 0)
2734     Start.moveToEnd();
2735   else
2736     Start.moveToFirst();
2737 
2738   ExportEntry Finish(Trie);
2739   Finish.moveToEnd();
2740 
2741   return make_range(export_iterator(Start), export_iterator(Finish));
2742 }
2743 
2744 iterator_range<export_iterator> MachOObjectFile::exports() const {
2745   return exports(getDyldInfoExportsTrie());
2746 }
2747 
2748 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
2749     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2750       RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
2751       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
2752 
2753 void MachORebaseEntry::moveToFirst() {
2754   Ptr = Opcodes.begin();
2755   moveNext();
2756 }
2757 
2758 void MachORebaseEntry::moveToEnd() {
2759   Ptr = Opcodes.end();
2760   RemainingLoopCount = 0;
2761   Done = true;
2762 }
2763 
2764 void MachORebaseEntry::moveNext() {
2765   // If in the middle of some loop, move to next rebasing in loop.
2766   SegmentOffset += AdvanceAmount;
2767   if (RemainingLoopCount) {
2768     --RemainingLoopCount;
2769     return;
2770   }
2771   if (Ptr == Opcodes.end()) {
2772     Done = true;
2773     return;
2774   }
2775   bool More = true;
2776   while (More && !Malformed) {
2777     // Parse next opcode and set up next loop.
2778     uint8_t Byte = *Ptr++;
2779     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
2780     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
2781     switch (Opcode) {
2782     case MachO::REBASE_OPCODE_DONE:
2783       More = false;
2784       Done = true;
2785       moveToEnd();
2786       DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
2787       break;
2788     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
2789       RebaseType = ImmValue;
2790       DEBUG_WITH_TYPE(
2791           "mach-o-rebase",
2792           llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
2793                        << "RebaseType=" << (int) RebaseType << "\n");
2794       break;
2795     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
2796       SegmentIndex = ImmValue;
2797       SegmentOffset = readULEB128();
2798       DEBUG_WITH_TYPE(
2799           "mach-o-rebase",
2800           llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2801                        << "SegmentIndex=" << SegmentIndex << ", "
2802                        << format("SegmentOffset=0x%06X", SegmentOffset)
2803                        << "\n");
2804       break;
2805     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
2806       SegmentOffset += readULEB128();
2807       DEBUG_WITH_TYPE("mach-o-rebase",
2808                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
2809                                    << format("SegmentOffset=0x%06X",
2810                                              SegmentOffset) << "\n");
2811       break;
2812     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
2813       SegmentOffset += ImmValue * PointerSize;
2814       DEBUG_WITH_TYPE("mach-o-rebase",
2815                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
2816                                    << format("SegmentOffset=0x%06X",
2817                                              SegmentOffset) << "\n");
2818       break;
2819     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
2820       AdvanceAmount = PointerSize;
2821       RemainingLoopCount = ImmValue - 1;
2822       DEBUG_WITH_TYPE(
2823           "mach-o-rebase",
2824           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
2825                        << format("SegmentOffset=0x%06X", SegmentOffset)
2826                        << ", AdvanceAmount=" << AdvanceAmount
2827                        << ", RemainingLoopCount=" << RemainingLoopCount
2828                        << "\n");
2829       return;
2830     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
2831       AdvanceAmount = PointerSize;
2832       RemainingLoopCount = readULEB128() - 1;
2833       DEBUG_WITH_TYPE(
2834           "mach-o-rebase",
2835           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
2836                        << format("SegmentOffset=0x%06X", SegmentOffset)
2837                        << ", AdvanceAmount=" << AdvanceAmount
2838                        << ", RemainingLoopCount=" << RemainingLoopCount
2839                        << "\n");
2840       return;
2841     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
2842       AdvanceAmount = readULEB128() + PointerSize;
2843       RemainingLoopCount = 0;
2844       DEBUG_WITH_TYPE(
2845           "mach-o-rebase",
2846           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
2847                        << format("SegmentOffset=0x%06X", SegmentOffset)
2848                        << ", AdvanceAmount=" << AdvanceAmount
2849                        << ", RemainingLoopCount=" << RemainingLoopCount
2850                        << "\n");
2851       return;
2852     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
2853       RemainingLoopCount = readULEB128() - 1;
2854       AdvanceAmount = readULEB128() + PointerSize;
2855       DEBUG_WITH_TYPE(
2856           "mach-o-rebase",
2857           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
2858                        << format("SegmentOffset=0x%06X", SegmentOffset)
2859                        << ", AdvanceAmount=" << AdvanceAmount
2860                        << ", RemainingLoopCount=" << RemainingLoopCount
2861                        << "\n");
2862       return;
2863     default:
2864       Malformed = true;
2865     }
2866   }
2867 }
2868 
2869 uint64_t MachORebaseEntry::readULEB128() {
2870   unsigned Count;
2871   uint64_t Result = decodeULEB128(Ptr, &Count);
2872   Ptr += Count;
2873   if (Ptr > Opcodes.end()) {
2874     Ptr = Opcodes.end();
2875     Malformed = true;
2876   }
2877   return Result;
2878 }
2879 
2880 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
2881 
2882 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
2883 
2884 StringRef MachORebaseEntry::typeName() const {
2885   switch (RebaseType) {
2886   case MachO::REBASE_TYPE_POINTER:
2887     return "pointer";
2888   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
2889     return "text abs32";
2890   case MachO::REBASE_TYPE_TEXT_PCREL32:
2891     return "text rel32";
2892   }
2893   return "unknown";
2894 }
2895 
2896 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
2897 #ifdef EXPENSIVE_CHECKS
2898   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2899 #else
2900   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
2901 #endif
2902   return (Ptr == Other.Ptr) &&
2903          (RemainingLoopCount == Other.RemainingLoopCount) &&
2904          (Done == Other.Done);
2905 }
2906 
2907 iterator_range<rebase_iterator>
2908 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
2909   MachORebaseEntry Start(Opcodes, is64);
2910   Start.moveToFirst();
2911 
2912   MachORebaseEntry Finish(Opcodes, is64);
2913   Finish.moveToEnd();
2914 
2915   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
2916 }
2917 
2918 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
2919   return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
2920 }
2921 
2922 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
2923     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2924       Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
2925       BindType(0), PointerSize(is64Bit ? 8 : 4),
2926       TableKind(BK), Malformed(false), Done(false) {}
2927 
2928 void MachOBindEntry::moveToFirst() {
2929   Ptr = Opcodes.begin();
2930   moveNext();
2931 }
2932 
2933 void MachOBindEntry::moveToEnd() {
2934   Ptr = Opcodes.end();
2935   RemainingLoopCount = 0;
2936   Done = true;
2937 }
2938 
2939 void MachOBindEntry::moveNext() {
2940   // If in the middle of some loop, move to next binding in loop.
2941   SegmentOffset += AdvanceAmount;
2942   if (RemainingLoopCount) {
2943     --RemainingLoopCount;
2944     return;
2945   }
2946   if (Ptr == Opcodes.end()) {
2947     Done = true;
2948     return;
2949   }
2950   bool More = true;
2951   while (More && !Malformed) {
2952     // Parse next opcode and set up next loop.
2953     uint8_t Byte = *Ptr++;
2954     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
2955     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
2956     int8_t SignExtended;
2957     const uint8_t *SymStart;
2958     switch (Opcode) {
2959     case MachO::BIND_OPCODE_DONE:
2960       if (TableKind == Kind::Lazy) {
2961         // Lazying bindings have a DONE opcode between entries.  Need to ignore
2962         // it to advance to next entry.  But need not if this is last entry.
2963         bool NotLastEntry = false;
2964         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
2965           if (*P) {
2966             NotLastEntry = true;
2967           }
2968         }
2969         if (NotLastEntry)
2970           break;
2971       }
2972       More = false;
2973       Done = true;
2974       moveToEnd();
2975       DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
2976       break;
2977     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
2978       Ordinal = ImmValue;
2979       DEBUG_WITH_TYPE(
2980           "mach-o-bind",
2981           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
2982                        << "Ordinal=" << Ordinal << "\n");
2983       break;
2984     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
2985       Ordinal = readULEB128();
2986       DEBUG_WITH_TYPE(
2987           "mach-o-bind",
2988           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
2989                        << "Ordinal=" << Ordinal << "\n");
2990       break;
2991     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
2992       if (ImmValue) {
2993         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
2994         Ordinal = SignExtended;
2995       } else
2996         Ordinal = 0;
2997       DEBUG_WITH_TYPE(
2998           "mach-o-bind",
2999           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3000                        << "Ordinal=" << Ordinal << "\n");
3001       break;
3002     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
3003       Flags = ImmValue;
3004       SymStart = Ptr;
3005       while (*Ptr) {
3006         ++Ptr;
3007       }
3008       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3009                              Ptr-SymStart);
3010       ++Ptr;
3011       DEBUG_WITH_TYPE(
3012           "mach-o-bind",
3013           llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3014                        << "SymbolName=" << SymbolName << "\n");
3015       if (TableKind == Kind::Weak) {
3016         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
3017           return;
3018       }
3019       break;
3020     case MachO::BIND_OPCODE_SET_TYPE_IMM:
3021       BindType = ImmValue;
3022       DEBUG_WITH_TYPE(
3023           "mach-o-bind",
3024           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3025                        << "BindType=" << (int)BindType << "\n");
3026       break;
3027     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
3028       Addend = readSLEB128();
3029       if (TableKind == Kind::Lazy)
3030         Malformed = true;
3031       DEBUG_WITH_TYPE(
3032           "mach-o-bind",
3033           llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3034                        << "Addend=" << Addend << "\n");
3035       break;
3036     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3037       SegmentIndex = ImmValue;
3038       SegmentOffset = readULEB128();
3039       DEBUG_WITH_TYPE(
3040           "mach-o-bind",
3041           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3042                        << "SegmentIndex=" << SegmentIndex << ", "
3043                        << format("SegmentOffset=0x%06X", SegmentOffset)
3044                        << "\n");
3045       break;
3046     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
3047       SegmentOffset += readULEB128();
3048       DEBUG_WITH_TYPE("mach-o-bind",
3049                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3050                                    << format("SegmentOffset=0x%06X",
3051                                              SegmentOffset) << "\n");
3052       break;
3053     case MachO::BIND_OPCODE_DO_BIND:
3054       AdvanceAmount = PointerSize;
3055       RemainingLoopCount = 0;
3056       DEBUG_WITH_TYPE("mach-o-bind",
3057                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
3058                                    << format("SegmentOffset=0x%06X",
3059                                              SegmentOffset) << "\n");
3060       return;
3061      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
3062       AdvanceAmount = readULEB128() + PointerSize;
3063       RemainingLoopCount = 0;
3064       if (TableKind == Kind::Lazy)
3065         Malformed = true;
3066       DEBUG_WITH_TYPE(
3067           "mach-o-bind",
3068           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3069                        << format("SegmentOffset=0x%06X", SegmentOffset)
3070                        << ", AdvanceAmount=" << AdvanceAmount
3071                        << ", RemainingLoopCount=" << RemainingLoopCount
3072                        << "\n");
3073       return;
3074     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
3075       AdvanceAmount = ImmValue * PointerSize + PointerSize;
3076       RemainingLoopCount = 0;
3077       if (TableKind == Kind::Lazy)
3078         Malformed = true;
3079       DEBUG_WITH_TYPE("mach-o-bind",
3080                       llvm::dbgs()
3081                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
3082                       << format("SegmentOffset=0x%06X",
3083                                              SegmentOffset) << "\n");
3084       return;
3085     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
3086       RemainingLoopCount = readULEB128() - 1;
3087       AdvanceAmount = readULEB128() + PointerSize;
3088       if (TableKind == Kind::Lazy)
3089         Malformed = true;
3090       DEBUG_WITH_TYPE(
3091           "mach-o-bind",
3092           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
3093                        << format("SegmentOffset=0x%06X", SegmentOffset)
3094                        << ", AdvanceAmount=" << AdvanceAmount
3095                        << ", RemainingLoopCount=" << RemainingLoopCount
3096                        << "\n");
3097       return;
3098     default:
3099       Malformed = true;
3100     }
3101   }
3102 }
3103 
3104 uint64_t MachOBindEntry::readULEB128() {
3105   unsigned Count;
3106   uint64_t Result = decodeULEB128(Ptr, &Count);
3107   Ptr += Count;
3108   if (Ptr > Opcodes.end()) {
3109     Ptr = Opcodes.end();
3110     Malformed = true;
3111   }
3112   return Result;
3113 }
3114 
3115 int64_t MachOBindEntry::readSLEB128() {
3116   unsigned Count;
3117   int64_t Result = decodeSLEB128(Ptr, &Count);
3118   Ptr += Count;
3119   if (Ptr > Opcodes.end()) {
3120     Ptr = Opcodes.end();
3121     Malformed = true;
3122   }
3123   return Result;
3124 }
3125 
3126 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
3127 
3128 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
3129 
3130 StringRef MachOBindEntry::typeName() const {
3131   switch (BindType) {
3132   case MachO::BIND_TYPE_POINTER:
3133     return "pointer";
3134   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
3135     return "text abs32";
3136   case MachO::BIND_TYPE_TEXT_PCREL32:
3137     return "text rel32";
3138   }
3139   return "unknown";
3140 }
3141 
3142 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
3143 
3144 int64_t MachOBindEntry::addend() const { return Addend; }
3145 
3146 uint32_t MachOBindEntry::flags() const { return Flags; }
3147 
3148 int MachOBindEntry::ordinal() const { return Ordinal; }
3149 
3150 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
3151 #ifdef EXPENSIVE_CHECKS
3152   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3153 #else
3154   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3155 #endif
3156   return (Ptr == Other.Ptr) &&
3157          (RemainingLoopCount == Other.RemainingLoopCount) &&
3158          (Done == Other.Done);
3159 }
3160 
3161 iterator_range<bind_iterator>
3162 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
3163                            MachOBindEntry::Kind BKind) {
3164   MachOBindEntry Start(Opcodes, is64, BKind);
3165   Start.moveToFirst();
3166 
3167   MachOBindEntry Finish(Opcodes, is64, BKind);
3168   Finish.moveToEnd();
3169 
3170   return make_range(bind_iterator(Start), bind_iterator(Finish));
3171 }
3172 
3173 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
3174   return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
3175                    MachOBindEntry::Kind::Regular);
3176 }
3177 
3178 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
3179   return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
3180                    MachOBindEntry::Kind::Lazy);
3181 }
3182 
3183 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
3184   return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
3185                    MachOBindEntry::Kind::Weak);
3186 }
3187 
3188 MachOObjectFile::load_command_iterator
3189 MachOObjectFile::begin_load_commands() const {
3190   return LoadCommands.begin();
3191 }
3192 
3193 MachOObjectFile::load_command_iterator
3194 MachOObjectFile::end_load_commands() const {
3195   return LoadCommands.end();
3196 }
3197 
3198 iterator_range<MachOObjectFile::load_command_iterator>
3199 MachOObjectFile::load_commands() const {
3200   return make_range(begin_load_commands(), end_load_commands());
3201 }
3202 
3203 StringRef
3204 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
3205   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
3206   return parseSegmentOrSectionName(Raw.data());
3207 }
3208 
3209 ArrayRef<char>
3210 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
3211   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
3212   const section_base *Base =
3213     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
3214   return makeArrayRef(Base->sectname);
3215 }
3216 
3217 ArrayRef<char>
3218 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
3219   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
3220   const section_base *Base =
3221     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
3222   return makeArrayRef(Base->segname);
3223 }
3224 
3225 bool
3226 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
3227   const {
3228   if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
3229     return false;
3230   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
3231 }
3232 
3233 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
3234     const MachO::any_relocation_info &RE) const {
3235   if (isLittleEndian())
3236     return RE.r_word1 & 0xffffff;
3237   return RE.r_word1 >> 8;
3238 }
3239 
3240 bool MachOObjectFile::getPlainRelocationExternal(
3241     const MachO::any_relocation_info &RE) const {
3242   if (isLittleEndian())
3243     return (RE.r_word1 >> 27) & 1;
3244   return (RE.r_word1 >> 4) & 1;
3245 }
3246 
3247 bool MachOObjectFile::getScatteredRelocationScattered(
3248     const MachO::any_relocation_info &RE) const {
3249   return RE.r_word0 >> 31;
3250 }
3251 
3252 uint32_t MachOObjectFile::getScatteredRelocationValue(
3253     const MachO::any_relocation_info &RE) const {
3254   return RE.r_word1;
3255 }
3256 
3257 uint32_t MachOObjectFile::getScatteredRelocationType(
3258     const MachO::any_relocation_info &RE) const {
3259   return (RE.r_word0 >> 24) & 0xf;
3260 }
3261 
3262 unsigned MachOObjectFile::getAnyRelocationAddress(
3263     const MachO::any_relocation_info &RE) const {
3264   if (isRelocationScattered(RE))
3265     return getScatteredRelocationAddress(RE);
3266   return getPlainRelocationAddress(RE);
3267 }
3268 
3269 unsigned MachOObjectFile::getAnyRelocationPCRel(
3270     const MachO::any_relocation_info &RE) const {
3271   if (isRelocationScattered(RE))
3272     return getScatteredRelocationPCRel(RE);
3273   return getPlainRelocationPCRel(*this, RE);
3274 }
3275 
3276 unsigned MachOObjectFile::getAnyRelocationLength(
3277     const MachO::any_relocation_info &RE) const {
3278   if (isRelocationScattered(RE))
3279     return getScatteredRelocationLength(RE);
3280   return getPlainRelocationLength(*this, RE);
3281 }
3282 
3283 unsigned
3284 MachOObjectFile::getAnyRelocationType(
3285                                    const MachO::any_relocation_info &RE) const {
3286   if (isRelocationScattered(RE))
3287     return getScatteredRelocationType(RE);
3288   return getPlainRelocationType(*this, RE);
3289 }
3290 
3291 SectionRef
3292 MachOObjectFile::getAnyRelocationSection(
3293                                    const MachO::any_relocation_info &RE) const {
3294   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
3295     return *section_end();
3296   unsigned SecNum = getPlainRelocationSymbolNum(RE);
3297   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
3298     return *section_end();
3299   DataRefImpl DRI;
3300   DRI.d.a = SecNum - 1;
3301   return SectionRef(DRI, this);
3302 }
3303 
3304 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
3305   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
3306   return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
3307 }
3308 
3309 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
3310   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
3311   return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
3312 }
3313 
3314 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
3315                                            unsigned Index) const {
3316   const char *Sec = getSectionPtr(*this, L, Index);
3317   return getStruct<MachO::section>(*this, Sec);
3318 }
3319 
3320 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
3321                                                 unsigned Index) const {
3322   const char *Sec = getSectionPtr(*this, L, Index);
3323   return getStruct<MachO::section_64>(*this, Sec);
3324 }
3325 
3326 MachO::nlist
3327 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
3328   const char *P = reinterpret_cast<const char *>(DRI.p);
3329   return getStruct<MachO::nlist>(*this, P);
3330 }
3331 
3332 MachO::nlist_64
3333 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
3334   const char *P = reinterpret_cast<const char *>(DRI.p);
3335   return getStruct<MachO::nlist_64>(*this, P);
3336 }
3337 
3338 MachO::linkedit_data_command
3339 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
3340   return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
3341 }
3342 
3343 MachO::segment_command
3344 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
3345   return getStruct<MachO::segment_command>(*this, L.Ptr);
3346 }
3347 
3348 MachO::segment_command_64
3349 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
3350   return getStruct<MachO::segment_command_64>(*this, L.Ptr);
3351 }
3352 
3353 MachO::linker_option_command
3354 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
3355   return getStruct<MachO::linker_option_command>(*this, L.Ptr);
3356 }
3357 
3358 MachO::version_min_command
3359 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
3360   return getStruct<MachO::version_min_command>(*this, L.Ptr);
3361 }
3362 
3363 MachO::note_command
3364 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
3365   return getStruct<MachO::note_command>(*this, L.Ptr);
3366 }
3367 
3368 MachO::build_version_command
3369 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
3370   return getStruct<MachO::build_version_command>(*this, L.Ptr);
3371 }
3372 
3373 MachO::build_tool_version
3374 MachOObjectFile::getBuildToolVersion(unsigned index) const {
3375   return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
3376 }
3377 
3378 MachO::dylib_command
3379 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
3380   return getStruct<MachO::dylib_command>(*this, L.Ptr);
3381 }
3382 
3383 MachO::dyld_info_command
3384 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
3385   return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
3386 }
3387 
3388 MachO::dylinker_command
3389 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
3390   return getStruct<MachO::dylinker_command>(*this, L.Ptr);
3391 }
3392 
3393 MachO::uuid_command
3394 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
3395   return getStruct<MachO::uuid_command>(*this, L.Ptr);
3396 }
3397 
3398 MachO::rpath_command
3399 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
3400   return getStruct<MachO::rpath_command>(*this, L.Ptr);
3401 }
3402 
3403 MachO::source_version_command
3404 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
3405   return getStruct<MachO::source_version_command>(*this, L.Ptr);
3406 }
3407 
3408 MachO::entry_point_command
3409 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
3410   return getStruct<MachO::entry_point_command>(*this, L.Ptr);
3411 }
3412 
3413 MachO::encryption_info_command
3414 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
3415   return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
3416 }
3417 
3418 MachO::encryption_info_command_64
3419 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
3420   return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
3421 }
3422 
3423 MachO::sub_framework_command
3424 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
3425   return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
3426 }
3427 
3428 MachO::sub_umbrella_command
3429 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
3430   return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
3431 }
3432 
3433 MachO::sub_library_command
3434 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
3435   return getStruct<MachO::sub_library_command>(*this, L.Ptr);
3436 }
3437 
3438 MachO::sub_client_command
3439 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
3440   return getStruct<MachO::sub_client_command>(*this, L.Ptr);
3441 }
3442 
3443 MachO::routines_command
3444 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
3445   return getStruct<MachO::routines_command>(*this, L.Ptr);
3446 }
3447 
3448 MachO::routines_command_64
3449 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
3450   return getStruct<MachO::routines_command_64>(*this, L.Ptr);
3451 }
3452 
3453 MachO::thread_command
3454 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
3455   return getStruct<MachO::thread_command>(*this, L.Ptr);
3456 }
3457 
3458 MachO::any_relocation_info
3459 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
3460   DataRefImpl Sec;
3461   Sec.d.a = Rel.d.a;
3462   uint32_t Offset;
3463   if (is64Bit()) {
3464     MachO::section_64 Sect = getSection64(Sec);
3465     Offset = Sect.reloff;
3466   } else {
3467     MachO::section Sect = getSection(Sec);
3468     Offset = Sect.reloff;
3469   }
3470 
3471   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
3472       getPtr(*this, Offset)) + Rel.d.b;
3473   return getStruct<MachO::any_relocation_info>(
3474       *this, reinterpret_cast<const char *>(P));
3475 }
3476 
3477 MachO::data_in_code_entry
3478 MachOObjectFile::getDice(DataRefImpl Rel) const {
3479   const char *P = reinterpret_cast<const char *>(Rel.p);
3480   return getStruct<MachO::data_in_code_entry>(*this, P);
3481 }
3482 
3483 const MachO::mach_header &MachOObjectFile::getHeader() const {
3484   return Header;
3485 }
3486 
3487 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
3488   assert(is64Bit());
3489   return Header64;
3490 }
3491 
3492 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
3493                                              const MachO::dysymtab_command &DLC,
3494                                              unsigned Index) const {
3495   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
3496   return getStruct<uint32_t>(*this, getPtr(*this, Offset));
3497 }
3498 
3499 MachO::data_in_code_entry
3500 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
3501                                          unsigned Index) const {
3502   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
3503   return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
3504 }
3505 
3506 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
3507   if (SymtabLoadCmd)
3508     return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
3509 
3510   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
3511   MachO::symtab_command Cmd;
3512   Cmd.cmd = MachO::LC_SYMTAB;
3513   Cmd.cmdsize = sizeof(MachO::symtab_command);
3514   Cmd.symoff = 0;
3515   Cmd.nsyms = 0;
3516   Cmd.stroff = 0;
3517   Cmd.strsize = 0;
3518   return Cmd;
3519 }
3520 
3521 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
3522   if (DysymtabLoadCmd)
3523     return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
3524 
3525   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
3526   MachO::dysymtab_command Cmd;
3527   Cmd.cmd = MachO::LC_DYSYMTAB;
3528   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
3529   Cmd.ilocalsym = 0;
3530   Cmd.nlocalsym = 0;
3531   Cmd.iextdefsym = 0;
3532   Cmd.nextdefsym = 0;
3533   Cmd.iundefsym = 0;
3534   Cmd.nundefsym = 0;
3535   Cmd.tocoff = 0;
3536   Cmd.ntoc = 0;
3537   Cmd.modtaboff = 0;
3538   Cmd.nmodtab = 0;
3539   Cmd.extrefsymoff = 0;
3540   Cmd.nextrefsyms = 0;
3541   Cmd.indirectsymoff = 0;
3542   Cmd.nindirectsyms = 0;
3543   Cmd.extreloff = 0;
3544   Cmd.nextrel = 0;
3545   Cmd.locreloff = 0;
3546   Cmd.nlocrel = 0;
3547   return Cmd;
3548 }
3549 
3550 MachO::linkedit_data_command
3551 MachOObjectFile::getDataInCodeLoadCommand() const {
3552   if (DataInCodeLoadCmd)
3553     return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
3554 
3555   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
3556   MachO::linkedit_data_command Cmd;
3557   Cmd.cmd = MachO::LC_DATA_IN_CODE;
3558   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3559   Cmd.dataoff = 0;
3560   Cmd.datasize = 0;
3561   return Cmd;
3562 }
3563 
3564 MachO::linkedit_data_command
3565 MachOObjectFile::getLinkOptHintsLoadCommand() const {
3566   if (LinkOptHintsLoadCmd)
3567     return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
3568 
3569   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
3570   // fields.
3571   MachO::linkedit_data_command Cmd;
3572   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
3573   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3574   Cmd.dataoff = 0;
3575   Cmd.datasize = 0;
3576   return Cmd;
3577 }
3578 
3579 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
3580   if (!DyldInfoLoadCmd)
3581     return None;
3582 
3583   MachO::dyld_info_command DyldInfo =
3584       getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3585   const uint8_t *Ptr =
3586       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
3587   return makeArrayRef(Ptr, DyldInfo.rebase_size);
3588 }
3589 
3590 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
3591   if (!DyldInfoLoadCmd)
3592     return None;
3593 
3594   MachO::dyld_info_command DyldInfo =
3595       getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3596   const uint8_t *Ptr =
3597       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
3598   return makeArrayRef(Ptr, DyldInfo.bind_size);
3599 }
3600 
3601 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
3602   if (!DyldInfoLoadCmd)
3603     return None;
3604 
3605   MachO::dyld_info_command DyldInfo =
3606       getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3607   const uint8_t *Ptr =
3608       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
3609   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
3610 }
3611 
3612 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
3613   if (!DyldInfoLoadCmd)
3614     return None;
3615 
3616   MachO::dyld_info_command DyldInfo =
3617       getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3618   const uint8_t *Ptr =
3619       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
3620   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
3621 }
3622 
3623 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
3624   if (!DyldInfoLoadCmd)
3625     return None;
3626 
3627   MachO::dyld_info_command DyldInfo =
3628       getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3629   const uint8_t *Ptr =
3630       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
3631   return makeArrayRef(Ptr, DyldInfo.export_size);
3632 }
3633 
3634 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
3635   if (!UuidLoadCmd)
3636     return None;
3637   // Returning a pointer is fine as uuid doesn't need endian swapping.
3638   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
3639   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
3640 }
3641 
3642 StringRef MachOObjectFile::getStringTableData() const {
3643   MachO::symtab_command S = getSymtabLoadCommand();
3644   return getData().substr(S.stroff, S.strsize);
3645 }
3646 
3647 bool MachOObjectFile::is64Bit() const {
3648   return getType() == getMachOType(false, true) ||
3649     getType() == getMachOType(true, true);
3650 }
3651 
3652 void MachOObjectFile::ReadULEB128s(uint64_t Index,
3653                                    SmallVectorImpl<uint64_t> &Out) const {
3654   DataExtractor extractor(ObjectFile::getData(), true, 0);
3655 
3656   uint32_t offset = Index;
3657   uint64_t data = 0;
3658   while (uint64_t delta = extractor.getULEB128(&offset)) {
3659     data += delta;
3660     Out.push_back(data);
3661   }
3662 }
3663 
3664 bool MachOObjectFile::isRelocatableObject() const {
3665   return getHeader().filetype == MachO::MH_OBJECT;
3666 }
3667 
3668 Expected<std::unique_ptr<MachOObjectFile>>
3669 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
3670                                   uint32_t UniversalCputype,
3671                                   uint32_t UniversalIndex) {
3672   StringRef Magic = Buffer.getBuffer().slice(0, 4);
3673   if (Magic == "\xFE\xED\xFA\xCE")
3674     return MachOObjectFile::create(Buffer, false, false,
3675                                    UniversalCputype, UniversalIndex);
3676   if (Magic == "\xCE\xFA\xED\xFE")
3677     return MachOObjectFile::create(Buffer, true, false,
3678                                    UniversalCputype, UniversalIndex);
3679   if (Magic == "\xFE\xED\xFA\xCF")
3680     return MachOObjectFile::create(Buffer, false, true,
3681                                    UniversalCputype, UniversalIndex);
3682   if (Magic == "\xCF\xFA\xED\xFE")
3683     return MachOObjectFile::create(Buffer, true, true,
3684                                    UniversalCputype, UniversalIndex);
3685   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
3686                                         object_error::invalid_file_type);
3687 }
3688