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