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