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