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