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