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