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