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