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