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(MachOObjectFile::LoadCommandInfo) > 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(MachOObjectFile::LoadCommandInfo) >
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 &&
256 	  S.fileoff == 0 && 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 &&
282           s.size != 0 && s.addr < S.vmaddr)
283         return malformedError("addr field of section " +
284                               Twine(J) + " in " + CmdName + " command " +
285 			      Twine(LoadCommandIndex) +
286 			      " less than the segment's vmaddr");
287       BigSize = s.addr;
288       BigSize += s.size;
289       uint64_t BigEnd = S.vmaddr;
290       BigEnd += S.vmsize;
291       if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
292         return malformedError("addr field plus size of section " +
293                               Twine(J) + " in " + CmdName + " command " +
294 			      Twine(LoadCommandIndex) + " greater than than "
295                               "the segment's vmaddr plus vmsize");
296       if (s.reloff > FileSize)
297         return malformedError("reloff field of section " +
298                               Twine(J) + " in " + CmdName + " command " +
299 			      Twine(LoadCommandIndex) +
300                               " extends past the end of the file");
301       BigSize = s.nreloc;
302       BigSize *= sizeof(struct MachO::relocation_info);
303       BigSize += s.reloff;
304       if (BigSize > FileSize)
305         return malformedError("reloff field plus nreloc field times sizeof("
306                               "struct relocation_info) of section " +
307                               Twine(J) + " in " + CmdName + " command " +
308 			      Twine(LoadCommandIndex) +
309                               " extends past the end of the file");
310     }
311     if (S.fileoff > FileSize)
312       return malformedError("load command " + Twine(LoadCommandIndex) +
313                             " fileoff field in " + CmdName +
314                             " extends past the end of the file");
315     uint64_t BigSize = S.fileoff;
316     BigSize += S.filesize;
317     if (BigSize > FileSize)
318       return malformedError("load command " + Twine(LoadCommandIndex) +
319                             " fileoff field plus filesize field in " +
320                             CmdName + " extends past the end of the file");
321     if (S.vmsize != 0 && S.filesize > S.vmsize)
322       return malformedError("load command " + Twine(LoadCommandIndex) +
323                             " fileoff field in " + CmdName +
324                             " greater than vmsize field");
325     IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
326   } else
327     return SegOrErr.takeError();
328 
329   return Error::success();
330 }
331 
332 Expected<std::unique_ptr<MachOObjectFile>>
333 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
334                         bool Is64Bits) {
335   Error Err;
336   std::unique_ptr<MachOObjectFile> Obj(
337       new MachOObjectFile(std::move(Object), IsLittleEndian,
338                            Is64Bits, Err));
339   if (Err)
340     return std::move(Err);
341   return std::move(Obj);
342 }
343 
344 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
345                                  bool Is64bits, Error &Err)
346     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
347       SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
348       DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
349       DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
350       HasPageZeroSegment(false) {
351   ErrorAsOutParameter ErrAsOutParam(&Err);
352   uint64_t SizeOfHeaders;
353   if (is64Bit()) {
354     parseHeader(this, Header64, Err);
355     SizeOfHeaders = sizeof(MachO::mach_header_64);
356   } else {
357     parseHeader(this, Header, Err);
358     SizeOfHeaders = sizeof(MachO::mach_header);
359   }
360   if (Err)
361     return;
362   SizeOfHeaders += getHeader().sizeofcmds;
363   if (getData().data() + SizeOfHeaders > getData().end()) {
364     Err = malformedError("load commands extend past the end of the file");
365     return;
366   }
367 
368   uint32_t LoadCommandCount = getHeader().ncmds;
369   if (LoadCommandCount == 0)
370     return;
371 
372   LoadCommandInfo Load;
373   if (auto LoadOrErr = getFirstLoadCommandInfo(this))
374     Load = *LoadOrErr;
375   else {
376     Err = LoadOrErr.takeError();
377     return;
378   }
379 
380   for (unsigned I = 0; I < LoadCommandCount; ++I) {
381     if (is64Bit()) {
382       if (Load.C.cmdsize % 8 != 0) {
383         // We have a hack here to allow 64-bit Mach-O core files to have
384         // LC_THREAD commands that are only a multiple of 4 and not 8 to be
385         // allowed since the macOS kernel produces them.
386         if (getHeader().filetype != MachO::MH_CORE ||
387             Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
388           Err = malformedError("load command " + Twine(I) + " cmdsize not a "
389                                "multiple of 8");
390           return;
391         }
392       }
393     } else {
394       if (Load.C.cmdsize % 4 != 0) {
395         Err = malformedError("load command " + Twine(I) + " cmdsize not a "
396                              "multiple of 4");
397         return;
398       }
399     }
400     LoadCommands.push_back(Load);
401     if (Load.C.cmd == MachO::LC_SYMTAB) {
402       // Multiple symbol tables
403       if (SymtabLoadCmd) {
404         Err = malformedError("Multiple symbol tables");
405         return;
406       }
407       SymtabLoadCmd = Load.Ptr;
408     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
409       // Multiple dynamic symbol tables
410       if (DysymtabLoadCmd) {
411         Err = malformedError("Multiple dynamic symbol tables");
412         return;
413       }
414       DysymtabLoadCmd = Load.Ptr;
415     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
416       // Multiple data in code tables
417       if (DataInCodeLoadCmd) {
418         Err = malformedError("Multiple data-in-code tables");
419         return;
420       }
421       DataInCodeLoadCmd = Load.Ptr;
422     } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
423       // Multiple linker optimization hint tables
424       if (LinkOptHintsLoadCmd) {
425         Err = malformedError("Multiple linker optimization hint tables");
426         return;
427       }
428       LinkOptHintsLoadCmd = Load.Ptr;
429     } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
430                Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
431       // Multiple dyldinfo load commands
432       if (DyldInfoLoadCmd) {
433         Err = malformedError("Multiple dyldinfo load commands");
434         return;
435       }
436       DyldInfoLoadCmd = Load.Ptr;
437     } else if (Load.C.cmd == MachO::LC_UUID) {
438       // Multiple UUID load commands
439       if (UuidLoadCmd) {
440         Err = malformedError("Multiple UUID load commands");
441         return;
442       }
443       UuidLoadCmd = Load.Ptr;
444     } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
445       if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
446                                          MachO::section_64>(
447                    this, Load, Sections, HasPageZeroSegment, I,
448                    "LC_SEGMENT_64", SizeOfHeaders)))
449         return;
450     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
451       if ((Err = parseSegmentLoadCommand<MachO::segment_command,
452                                          MachO::section>(
453                    this, Load, Sections, HasPageZeroSegment, I,
454                    "LC_SEGMENT", SizeOfHeaders)))
455         return;
456     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
457                Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
458                Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
459                Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
460                Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
461       Libraries.push_back(Load.Ptr);
462     }
463     if (I < LoadCommandCount - 1) {
464       if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
465         Load = *LoadOrErr;
466       else {
467         Err = LoadOrErr.takeError();
468         return;
469       }
470     }
471   }
472   if (!SymtabLoadCmd) {
473     if (DysymtabLoadCmd) {
474       Err = malformedError("contains LC_DYSYMTAB load command without a "
475                            "LC_SYMTAB load command");
476       return;
477     }
478   } else if (DysymtabLoadCmd) {
479     MachO::symtab_command Symtab =
480       getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
481     MachO::dysymtab_command Dysymtab =
482       getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
483     if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
484       Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
485                            "extends past the end of the symbol table");
486       return;
487     }
488     uint64_t BigSize = Dysymtab.ilocalsym;
489     BigSize += Dysymtab.nlocalsym;
490     if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
491       Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
492                            "command extends past the end of the symbol table");
493       return;
494     }
495     if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
496       Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
497                            "extends past the end of the symbol table");
498       return;
499     }
500     BigSize = Dysymtab.iextdefsym;
501     BigSize += Dysymtab.nextdefsym;
502     if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
503       Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
504                            "load command extends past the end of the symbol "
505                            "table");
506       return;
507     }
508     if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
509       Err = malformedError("nundefsym in LC_DYSYMTAB load command "
510                            "extends past the end of the symbol table");
511       return;
512     }
513     BigSize = Dysymtab.iundefsym;
514     BigSize += Dysymtab.nundefsym;
515     if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
516       Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
517                            " command extends past the end of the symbol table");
518       return;
519     }
520   }
521   assert(LoadCommands.size() == LoadCommandCount);
522 
523   Err = Error::success();
524 }
525 
526 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
527   unsigned SymbolTableEntrySize = is64Bit() ?
528     sizeof(MachO::nlist_64) :
529     sizeof(MachO::nlist);
530   Symb.p += SymbolTableEntrySize;
531 }
532 
533 Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
534   StringRef StringTable = getStringTableData();
535   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
536   const char *Start = &StringTable.data()[Entry.n_strx];
537   if (Start < getData().begin() || Start >= getData().end()) {
538     return malformedError("bad string index: " + Twine(Entry.n_strx) +
539                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
540   }
541   return StringRef(Start);
542 }
543 
544 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
545   DataRefImpl DRI = Sec.getRawDataRefImpl();
546   uint32_t Flags = getSectionFlags(this, DRI);
547   return Flags & MachO::SECTION_TYPE;
548 }
549 
550 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
551   if (is64Bit()) {
552     MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
553     return Entry.n_value;
554   }
555   MachO::nlist Entry = getSymbolTableEntry(Sym);
556   return Entry.n_value;
557 }
558 
559 // getIndirectName() returns the name of the alias'ed symbol who's string table
560 // index is in the n_value field.
561 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
562                                                  StringRef &Res) const {
563   StringRef StringTable = getStringTableData();
564   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
565   if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
566     return object_error::parse_failed;
567   uint64_t NValue = getNValue(Symb);
568   if (NValue >= StringTable.size())
569     return object_error::parse_failed;
570   const char *Start = &StringTable.data()[NValue];
571   Res = StringRef(Start);
572   return std::error_code();
573 }
574 
575 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
576   return getNValue(Sym);
577 }
578 
579 Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
580   return getSymbolValue(Sym);
581 }
582 
583 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
584   uint32_t flags = getSymbolFlags(DRI);
585   if (flags & SymbolRef::SF_Common) {
586     MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
587     return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
588   }
589   return 0;
590 }
591 
592 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
593   return getNValue(DRI);
594 }
595 
596 Expected<SymbolRef::Type>
597 MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
598   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
599   uint8_t n_type = Entry.n_type;
600 
601   // If this is a STAB debugging symbol, we can do nothing more.
602   if (n_type & MachO::N_STAB)
603     return SymbolRef::ST_Debug;
604 
605   switch (n_type & MachO::N_TYPE) {
606     case MachO::N_UNDF :
607       return SymbolRef::ST_Unknown;
608     case MachO::N_SECT :
609       Expected<section_iterator> SecOrError = getSymbolSection(Symb);
610       if (!SecOrError)
611         return SecOrError.takeError();
612       section_iterator Sec = *SecOrError;
613       if (Sec->isData() || Sec->isBSS())
614         return SymbolRef::ST_Data;
615       return SymbolRef::ST_Function;
616   }
617   return SymbolRef::ST_Other;
618 }
619 
620 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
621   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
622 
623   uint8_t MachOType = Entry.n_type;
624   uint16_t MachOFlags = Entry.n_desc;
625 
626   uint32_t Result = SymbolRef::SF_None;
627 
628   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
629     Result |= SymbolRef::SF_Indirect;
630 
631   if (MachOType & MachO::N_STAB)
632     Result |= SymbolRef::SF_FormatSpecific;
633 
634   if (MachOType & MachO::N_EXT) {
635     Result |= SymbolRef::SF_Global;
636     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
637       if (getNValue(DRI))
638         Result |= SymbolRef::SF_Common;
639       else
640         Result |= SymbolRef::SF_Undefined;
641     }
642 
643     if (!(MachOType & MachO::N_PEXT))
644       Result |= SymbolRef::SF_Exported;
645   }
646 
647   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
648     Result |= SymbolRef::SF_Weak;
649 
650   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
651     Result |= SymbolRef::SF_Thumb;
652 
653   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
654     Result |= SymbolRef::SF_Absolute;
655 
656   return Result;
657 }
658 
659 Expected<section_iterator>
660 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
661   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
662   uint8_t index = Entry.n_sect;
663 
664   if (index == 0)
665     return section_end();
666   DataRefImpl DRI;
667   DRI.d.a = index - 1;
668   if (DRI.d.a >= Sections.size()){
669     return malformedError("bad section index: " + Twine((int)index) +
670                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
671   }
672   return section_iterator(SectionRef(DRI, this));
673 }
674 
675 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
676   MachO::nlist_base Entry =
677       getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
678   return Entry.n_sect - 1;
679 }
680 
681 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
682   Sec.d.a++;
683 }
684 
685 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
686                                                 StringRef &Result) const {
687   ArrayRef<char> Raw = getSectionRawName(Sec);
688   Result = parseSegmentOrSectionName(Raw.data());
689   return std::error_code();
690 }
691 
692 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
693   if (is64Bit())
694     return getSection64(Sec).addr;
695   return getSection(Sec).addr;
696 }
697 
698 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
699   // In the case if a malformed Mach-O file where the section offset is past
700   // the end of the file or some part of the section size is past the end of
701   // the file return a size of zero or a size that covers the rest of the file
702   // but does not extend past the end of the file.
703   uint32_t SectOffset, SectType;
704   uint64_t SectSize;
705 
706   if (is64Bit()) {
707     MachO::section_64 Sect = getSection64(Sec);
708     SectOffset = Sect.offset;
709     SectSize = Sect.size;
710     SectType = Sect.flags & MachO::SECTION_TYPE;
711   } else {
712     MachO::section Sect = getSection(Sec);
713     SectOffset = Sect.offset;
714     SectSize = Sect.size;
715     SectType = Sect.flags & MachO::SECTION_TYPE;
716   }
717   if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
718     return SectSize;
719   uint64_t FileSize = getData().size();
720   if (SectOffset > FileSize)
721     return 0;
722   if (FileSize - SectOffset < SectSize)
723     return FileSize - SectOffset;
724   return SectSize;
725 }
726 
727 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
728                                                     StringRef &Res) const {
729   uint32_t Offset;
730   uint64_t Size;
731 
732   if (is64Bit()) {
733     MachO::section_64 Sect = getSection64(Sec);
734     Offset = Sect.offset;
735     Size = Sect.size;
736   } else {
737     MachO::section Sect = getSection(Sec);
738     Offset = Sect.offset;
739     Size = Sect.size;
740   }
741 
742   Res = this->getData().substr(Offset, Size);
743   return std::error_code();
744 }
745 
746 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
747   uint32_t Align;
748   if (is64Bit()) {
749     MachO::section_64 Sect = getSection64(Sec);
750     Align = Sect.align;
751   } else {
752     MachO::section Sect = getSection(Sec);
753     Align = Sect.align;
754   }
755 
756   return uint64_t(1) << Align;
757 }
758 
759 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
760   return false;
761 }
762 
763 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
764   uint32_t Flags = getSectionFlags(this, Sec);
765   return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
766 }
767 
768 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
769   uint32_t Flags = getSectionFlags(this, Sec);
770   unsigned SectionType = Flags & MachO::SECTION_TYPE;
771   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
772          !(SectionType == MachO::S_ZEROFILL ||
773            SectionType == MachO::S_GB_ZEROFILL);
774 }
775 
776 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
777   uint32_t Flags = getSectionFlags(this, Sec);
778   unsigned SectionType = Flags & MachO::SECTION_TYPE;
779   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
780          (SectionType == MachO::S_ZEROFILL ||
781           SectionType == MachO::S_GB_ZEROFILL);
782 }
783 
784 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
785   return Sec.getRawDataRefImpl().d.a;
786 }
787 
788 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
789   // FIXME: Unimplemented.
790   return false;
791 }
792 
793 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
794   StringRef SegmentName = getSectionFinalSegmentName(Sec);
795   StringRef SectName;
796   if (!getSectionName(Sec, SectName))
797     return (SegmentName == "__LLVM" && SectName == "__bitcode");
798   return false;
799 }
800 
801 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
802   DataRefImpl Ret;
803   Ret.d.a = Sec.d.a;
804   Ret.d.b = 0;
805   return relocation_iterator(RelocationRef(Ret, this));
806 }
807 
808 relocation_iterator
809 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
810   uint32_t Num;
811   if (is64Bit()) {
812     MachO::section_64 Sect = getSection64(Sec);
813     Num = Sect.nreloc;
814   } else {
815     MachO::section Sect = getSection(Sec);
816     Num = Sect.nreloc;
817   }
818 
819   DataRefImpl Ret;
820   Ret.d.a = Sec.d.a;
821   Ret.d.b = Num;
822   return relocation_iterator(RelocationRef(Ret, this));
823 }
824 
825 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
826   ++Rel.d.b;
827 }
828 
829 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
830   assert(getHeader().filetype == MachO::MH_OBJECT &&
831          "Only implemented for MH_OBJECT");
832   MachO::any_relocation_info RE = getRelocation(Rel);
833   return getAnyRelocationAddress(RE);
834 }
835 
836 symbol_iterator
837 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
838   MachO::any_relocation_info RE = getRelocation(Rel);
839   if (isRelocationScattered(RE))
840     return symbol_end();
841 
842   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
843   bool isExtern = getPlainRelocationExternal(RE);
844   if (!isExtern)
845     return symbol_end();
846 
847   MachO::symtab_command S = getSymtabLoadCommand();
848   unsigned SymbolTableEntrySize = is64Bit() ?
849     sizeof(MachO::nlist_64) :
850     sizeof(MachO::nlist);
851   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
852   DataRefImpl Sym;
853   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
854   return symbol_iterator(SymbolRef(Sym, this));
855 }
856 
857 section_iterator
858 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
859   return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
860 }
861 
862 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
863   MachO::any_relocation_info RE = getRelocation(Rel);
864   return getAnyRelocationType(RE);
865 }
866 
867 void MachOObjectFile::getRelocationTypeName(
868     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
869   StringRef res;
870   uint64_t RType = getRelocationType(Rel);
871 
872   unsigned Arch = this->getArch();
873 
874   switch (Arch) {
875     case Triple::x86: {
876       static const char *const Table[] =  {
877         "GENERIC_RELOC_VANILLA",
878         "GENERIC_RELOC_PAIR",
879         "GENERIC_RELOC_SECTDIFF",
880         "GENERIC_RELOC_PB_LA_PTR",
881         "GENERIC_RELOC_LOCAL_SECTDIFF",
882         "GENERIC_RELOC_TLV" };
883 
884       if (RType > 5)
885         res = "Unknown";
886       else
887         res = Table[RType];
888       break;
889     }
890     case Triple::x86_64: {
891       static const char *const Table[] =  {
892         "X86_64_RELOC_UNSIGNED",
893         "X86_64_RELOC_SIGNED",
894         "X86_64_RELOC_BRANCH",
895         "X86_64_RELOC_GOT_LOAD",
896         "X86_64_RELOC_GOT",
897         "X86_64_RELOC_SUBTRACTOR",
898         "X86_64_RELOC_SIGNED_1",
899         "X86_64_RELOC_SIGNED_2",
900         "X86_64_RELOC_SIGNED_4",
901         "X86_64_RELOC_TLV" };
902 
903       if (RType > 9)
904         res = "Unknown";
905       else
906         res = Table[RType];
907       break;
908     }
909     case Triple::arm: {
910       static const char *const Table[] =  {
911         "ARM_RELOC_VANILLA",
912         "ARM_RELOC_PAIR",
913         "ARM_RELOC_SECTDIFF",
914         "ARM_RELOC_LOCAL_SECTDIFF",
915         "ARM_RELOC_PB_LA_PTR",
916         "ARM_RELOC_BR24",
917         "ARM_THUMB_RELOC_BR22",
918         "ARM_THUMB_32BIT_BRANCH",
919         "ARM_RELOC_HALF",
920         "ARM_RELOC_HALF_SECTDIFF" };
921 
922       if (RType > 9)
923         res = "Unknown";
924       else
925         res = Table[RType];
926       break;
927     }
928     case Triple::aarch64: {
929       static const char *const Table[] = {
930         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
931         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
932         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
933         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
934         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
935         "ARM64_RELOC_ADDEND"
936       };
937 
938       if (RType >= array_lengthof(Table))
939         res = "Unknown";
940       else
941         res = Table[RType];
942       break;
943     }
944     case Triple::ppc: {
945       static const char *const Table[] =  {
946         "PPC_RELOC_VANILLA",
947         "PPC_RELOC_PAIR",
948         "PPC_RELOC_BR14",
949         "PPC_RELOC_BR24",
950         "PPC_RELOC_HI16",
951         "PPC_RELOC_LO16",
952         "PPC_RELOC_HA16",
953         "PPC_RELOC_LO14",
954         "PPC_RELOC_SECTDIFF",
955         "PPC_RELOC_PB_LA_PTR",
956         "PPC_RELOC_HI16_SECTDIFF",
957         "PPC_RELOC_LO16_SECTDIFF",
958         "PPC_RELOC_HA16_SECTDIFF",
959         "PPC_RELOC_JBSR",
960         "PPC_RELOC_LO14_SECTDIFF",
961         "PPC_RELOC_LOCAL_SECTDIFF" };
962 
963       if (RType > 15)
964         res = "Unknown";
965       else
966         res = Table[RType];
967       break;
968     }
969     case Triple::UnknownArch:
970       res = "Unknown";
971       break;
972   }
973   Result.append(res.begin(), res.end());
974 }
975 
976 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
977   MachO::any_relocation_info RE = getRelocation(Rel);
978   return getAnyRelocationLength(RE);
979 }
980 
981 //
982 // guessLibraryShortName() is passed a name of a dynamic library and returns a
983 // guess on what the short name is.  Then name is returned as a substring of the
984 // StringRef Name passed in.  The name of the dynamic library is recognized as
985 // a framework if it has one of the two following forms:
986 //      Foo.framework/Versions/A/Foo
987 //      Foo.framework/Foo
988 // Where A and Foo can be any string.  And may contain a trailing suffix
989 // starting with an underbar.  If the Name is recognized as a framework then
990 // isFramework is set to true else it is set to false.  If the Name has a
991 // suffix then Suffix is set to the substring in Name that contains the suffix
992 // else it is set to a NULL StringRef.
993 //
994 // The Name of the dynamic library is recognized as a library name if it has
995 // one of the two following forms:
996 //      libFoo.A.dylib
997 //      libFoo.dylib
998 // The library may have a suffix trailing the name Foo of the form:
999 //      libFoo_profile.A.dylib
1000 //      libFoo_profile.dylib
1001 //
1002 // The Name of the dynamic library is also recognized as a library name if it
1003 // has the following form:
1004 //      Foo.qtx
1005 //
1006 // If the Name of the dynamic library is none of the forms above then a NULL
1007 // StringRef is returned.
1008 //
1009 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1010                                                  bool &isFramework,
1011                                                  StringRef &Suffix) {
1012   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1013   size_t a, b, c, d, Idx;
1014 
1015   isFramework = false;
1016   Suffix = StringRef();
1017 
1018   // Pull off the last component and make Foo point to it
1019   a = Name.rfind('/');
1020   if (a == Name.npos || a == 0)
1021     goto guess_library;
1022   Foo = Name.slice(a+1, Name.npos);
1023 
1024   // Look for a suffix starting with a '_'
1025   Idx = Foo.rfind('_');
1026   if (Idx != Foo.npos && Foo.size() >= 2) {
1027     Suffix = Foo.slice(Idx, Foo.npos);
1028     Foo = Foo.slice(0, Idx);
1029   }
1030 
1031   // First look for the form Foo.framework/Foo
1032   b = Name.rfind('/', a);
1033   if (b == Name.npos)
1034     Idx = 0;
1035   else
1036     Idx = b+1;
1037   F = Name.slice(Idx, Idx + Foo.size());
1038   DotFramework = Name.slice(Idx + Foo.size(),
1039                             Idx + Foo.size() + sizeof(".framework/")-1);
1040   if (F == Foo && DotFramework == ".framework/") {
1041     isFramework = true;
1042     return Foo;
1043   }
1044 
1045   // Next look for the form Foo.framework/Versions/A/Foo
1046   if (b == Name.npos)
1047     goto guess_library;
1048   c =  Name.rfind('/', b);
1049   if (c == Name.npos || c == 0)
1050     goto guess_library;
1051   V = Name.slice(c+1, Name.npos);
1052   if (!V.startswith("Versions/"))
1053     goto guess_library;
1054   d =  Name.rfind('/', c);
1055   if (d == Name.npos)
1056     Idx = 0;
1057   else
1058     Idx = d+1;
1059   F = Name.slice(Idx, Idx + Foo.size());
1060   DotFramework = Name.slice(Idx + Foo.size(),
1061                             Idx + Foo.size() + sizeof(".framework/")-1);
1062   if (F == Foo && DotFramework == ".framework/") {
1063     isFramework = true;
1064     return Foo;
1065   }
1066 
1067 guess_library:
1068   // pull off the suffix after the "." and make a point to it
1069   a = Name.rfind('.');
1070   if (a == Name.npos || a == 0)
1071     return StringRef();
1072   Dylib = Name.slice(a, Name.npos);
1073   if (Dylib != ".dylib")
1074     goto guess_qtx;
1075 
1076   // First pull off the version letter for the form Foo.A.dylib if any.
1077   if (a >= 3) {
1078     Dot = Name.slice(a-2, a-1);
1079     if (Dot == ".")
1080       a = a - 2;
1081   }
1082 
1083   b = Name.rfind('/', a);
1084   if (b == Name.npos)
1085     b = 0;
1086   else
1087     b = b+1;
1088   // ignore any suffix after an underbar like Foo_profile.A.dylib
1089   Idx = Name.find('_', b);
1090   if (Idx != Name.npos && Idx != b) {
1091     Lib = Name.slice(b, Idx);
1092     Suffix = Name.slice(Idx, a);
1093   }
1094   else
1095     Lib = Name.slice(b, a);
1096   // There are incorrect library names of the form:
1097   // libATS.A_profile.dylib so check for these.
1098   if (Lib.size() >= 3) {
1099     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1100     if (Dot == ".")
1101       Lib = Lib.slice(0, Lib.size()-2);
1102   }
1103   return Lib;
1104 
1105 guess_qtx:
1106   Qtx = Name.slice(a, Name.npos);
1107   if (Qtx != ".qtx")
1108     return StringRef();
1109   b = Name.rfind('/', a);
1110   if (b == Name.npos)
1111     Lib = Name.slice(0, a);
1112   else
1113     Lib = Name.slice(b+1, a);
1114   // There are library names of the form: QT.A.qtx so check for these.
1115   if (Lib.size() >= 3) {
1116     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1117     if (Dot == ".")
1118       Lib = Lib.slice(0, Lib.size()-2);
1119   }
1120   return Lib;
1121 }
1122 
1123 // getLibraryShortNameByIndex() is used to get the short name of the library
1124 // for an undefined symbol in a linked Mach-O binary that was linked with the
1125 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1126 // It is passed the index (0 - based) of the library as translated from
1127 // GET_LIBRARY_ORDINAL (1 - based).
1128 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1129                                                          StringRef &Res) const {
1130   if (Index >= Libraries.size())
1131     return object_error::parse_failed;
1132 
1133   // If the cache of LibrariesShortNames is not built up do that first for
1134   // all the Libraries.
1135   if (LibrariesShortNames.size() == 0) {
1136     for (unsigned i = 0; i < Libraries.size(); i++) {
1137       MachO::dylib_command D =
1138         getStruct<MachO::dylib_command>(this, Libraries[i]);
1139       if (D.dylib.name >= D.cmdsize)
1140         return object_error::parse_failed;
1141       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1142       StringRef Name = StringRef(P);
1143       if (D.dylib.name+Name.size() >= D.cmdsize)
1144         return object_error::parse_failed;
1145       StringRef Suffix;
1146       bool isFramework;
1147       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1148       if (shortName.empty())
1149         LibrariesShortNames.push_back(Name);
1150       else
1151         LibrariesShortNames.push_back(shortName);
1152     }
1153   }
1154 
1155   Res = LibrariesShortNames[Index];
1156   return std::error_code();
1157 }
1158 
1159 section_iterator
1160 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
1161   DataRefImpl Sec;
1162   Sec.d.a = Rel->getRawDataRefImpl().d.a;
1163   return section_iterator(SectionRef(Sec, this));
1164 }
1165 
1166 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1167   DataRefImpl DRI;
1168   MachO::symtab_command Symtab = getSymtabLoadCommand();
1169   if (!SymtabLoadCmd || Symtab.nsyms == 0)
1170     return basic_symbol_iterator(SymbolRef(DRI, this));
1171 
1172   return getSymbolByIndex(0);
1173 }
1174 
1175 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1176   DataRefImpl DRI;
1177   MachO::symtab_command Symtab = getSymtabLoadCommand();
1178   if (!SymtabLoadCmd || Symtab.nsyms == 0)
1179     return basic_symbol_iterator(SymbolRef(DRI, this));
1180 
1181   unsigned SymbolTableEntrySize = is64Bit() ?
1182     sizeof(MachO::nlist_64) :
1183     sizeof(MachO::nlist);
1184   unsigned Offset = Symtab.symoff +
1185     Symtab.nsyms * SymbolTableEntrySize;
1186   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1187   return basic_symbol_iterator(SymbolRef(DRI, this));
1188 }
1189 
1190 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1191   MachO::symtab_command Symtab = getSymtabLoadCommand();
1192   if (!SymtabLoadCmd || Index >= Symtab.nsyms)
1193     report_fatal_error("Requested symbol index is out of range.");
1194   unsigned SymbolTableEntrySize =
1195     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1196   DataRefImpl DRI;
1197   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1198   DRI.p += Index * SymbolTableEntrySize;
1199   return basic_symbol_iterator(SymbolRef(DRI, this));
1200 }
1201 
1202 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
1203   MachO::symtab_command Symtab = getSymtabLoadCommand();
1204   if (!SymtabLoadCmd)
1205     report_fatal_error("getSymbolIndex() called with no symbol table symbol");
1206   unsigned SymbolTableEntrySize =
1207     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1208   DataRefImpl DRIstart;
1209   DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1210   uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
1211   return Index;
1212 }
1213 
1214 section_iterator MachOObjectFile::section_begin() const {
1215   DataRefImpl DRI;
1216   return section_iterator(SectionRef(DRI, this));
1217 }
1218 
1219 section_iterator MachOObjectFile::section_end() const {
1220   DataRefImpl DRI;
1221   DRI.d.a = Sections.size();
1222   return section_iterator(SectionRef(DRI, this));
1223 }
1224 
1225 uint8_t MachOObjectFile::getBytesInAddress() const {
1226   return is64Bit() ? 8 : 4;
1227 }
1228 
1229 StringRef MachOObjectFile::getFileFormatName() const {
1230   unsigned CPUType = getCPUType(this);
1231   if (!is64Bit()) {
1232     switch (CPUType) {
1233     case llvm::MachO::CPU_TYPE_I386:
1234       return "Mach-O 32-bit i386";
1235     case llvm::MachO::CPU_TYPE_ARM:
1236       return "Mach-O arm";
1237     case llvm::MachO::CPU_TYPE_POWERPC:
1238       return "Mach-O 32-bit ppc";
1239     default:
1240       return "Mach-O 32-bit unknown";
1241     }
1242   }
1243 
1244   switch (CPUType) {
1245   case llvm::MachO::CPU_TYPE_X86_64:
1246     return "Mach-O 64-bit x86-64";
1247   case llvm::MachO::CPU_TYPE_ARM64:
1248     return "Mach-O arm64";
1249   case llvm::MachO::CPU_TYPE_POWERPC64:
1250     return "Mach-O 64-bit ppc64";
1251   default:
1252     return "Mach-O 64-bit unknown";
1253   }
1254 }
1255 
1256 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1257   switch (CPUType) {
1258   case llvm::MachO::CPU_TYPE_I386:
1259     return Triple::x86;
1260   case llvm::MachO::CPU_TYPE_X86_64:
1261     return Triple::x86_64;
1262   case llvm::MachO::CPU_TYPE_ARM:
1263     return Triple::arm;
1264   case llvm::MachO::CPU_TYPE_ARM64:
1265     return Triple::aarch64;
1266   case llvm::MachO::CPU_TYPE_POWERPC:
1267     return Triple::ppc;
1268   case llvm::MachO::CPU_TYPE_POWERPC64:
1269     return Triple::ppc64;
1270   default:
1271     return Triple::UnknownArch;
1272   }
1273 }
1274 
1275 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
1276                                       const char **McpuDefault) {
1277   if (McpuDefault)
1278     *McpuDefault = nullptr;
1279 
1280   switch (CPUType) {
1281   case MachO::CPU_TYPE_I386:
1282     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1283     case MachO::CPU_SUBTYPE_I386_ALL:
1284       return Triple("i386-apple-darwin");
1285     default:
1286       return Triple();
1287     }
1288   case MachO::CPU_TYPE_X86_64:
1289     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1290     case MachO::CPU_SUBTYPE_X86_64_ALL:
1291       return Triple("x86_64-apple-darwin");
1292     case MachO::CPU_SUBTYPE_X86_64_H:
1293       return Triple("x86_64h-apple-darwin");
1294     default:
1295       return Triple();
1296     }
1297   case MachO::CPU_TYPE_ARM:
1298     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1299     case MachO::CPU_SUBTYPE_ARM_V4T:
1300       return Triple("armv4t-apple-darwin");
1301     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1302       return Triple("armv5e-apple-darwin");
1303     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1304       return Triple("xscale-apple-darwin");
1305     case MachO::CPU_SUBTYPE_ARM_V6:
1306       return Triple("armv6-apple-darwin");
1307     case MachO::CPU_SUBTYPE_ARM_V6M:
1308       if (McpuDefault)
1309         *McpuDefault = "cortex-m0";
1310       return Triple("armv6m-apple-darwin");
1311     case MachO::CPU_SUBTYPE_ARM_V7:
1312       return Triple("armv7-apple-darwin");
1313     case MachO::CPU_SUBTYPE_ARM_V7EM:
1314       if (McpuDefault)
1315         *McpuDefault = "cortex-m4";
1316       return Triple("thumbv7em-apple-darwin");
1317     case MachO::CPU_SUBTYPE_ARM_V7K:
1318       return Triple("armv7k-apple-darwin");
1319     case MachO::CPU_SUBTYPE_ARM_V7M:
1320       if (McpuDefault)
1321         *McpuDefault = "cortex-m3";
1322       return Triple("thumbv7m-apple-darwin");
1323     case MachO::CPU_SUBTYPE_ARM_V7S:
1324       return Triple("armv7s-apple-darwin");
1325     default:
1326       return Triple();
1327     }
1328   case MachO::CPU_TYPE_ARM64:
1329     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1330     case MachO::CPU_SUBTYPE_ARM64_ALL:
1331       return Triple("arm64-apple-darwin");
1332     default:
1333       return Triple();
1334     }
1335   case MachO::CPU_TYPE_POWERPC:
1336     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1337     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1338       return Triple("ppc-apple-darwin");
1339     default:
1340       return Triple();
1341     }
1342   case MachO::CPU_TYPE_POWERPC64:
1343     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1344     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1345       return Triple("ppc64-apple-darwin");
1346     default:
1347       return Triple();
1348     }
1349   default:
1350     return Triple();
1351   }
1352 }
1353 
1354 Triple MachOObjectFile::getHostArch() {
1355   return Triple(sys::getDefaultTargetTriple());
1356 }
1357 
1358 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1359   return StringSwitch<bool>(ArchFlag)
1360       .Case("i386", true)
1361       .Case("x86_64", true)
1362       .Case("x86_64h", true)
1363       .Case("armv4t", true)
1364       .Case("arm", true)
1365       .Case("armv5e", true)
1366       .Case("armv6", true)
1367       .Case("armv6m", true)
1368       .Case("armv7", true)
1369       .Case("armv7em", true)
1370       .Case("armv7k", true)
1371       .Case("armv7m", true)
1372       .Case("armv7s", true)
1373       .Case("arm64", true)
1374       .Case("ppc", true)
1375       .Case("ppc64", true)
1376       .Default(false);
1377 }
1378 
1379 unsigned MachOObjectFile::getArch() const {
1380   return getArch(getCPUType(this));
1381 }
1382 
1383 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
1384   return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
1385 }
1386 
1387 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1388   DataRefImpl DRI;
1389   DRI.d.a = Index;
1390   return section_rel_begin(DRI);
1391 }
1392 
1393 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1394   DataRefImpl DRI;
1395   DRI.d.a = Index;
1396   return section_rel_end(DRI);
1397 }
1398 
1399 dice_iterator MachOObjectFile::begin_dices() const {
1400   DataRefImpl DRI;
1401   if (!DataInCodeLoadCmd)
1402     return dice_iterator(DiceRef(DRI, this));
1403 
1404   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1405   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1406   return dice_iterator(DiceRef(DRI, this));
1407 }
1408 
1409 dice_iterator MachOObjectFile::end_dices() const {
1410   DataRefImpl DRI;
1411   if (!DataInCodeLoadCmd)
1412     return dice_iterator(DiceRef(DRI, this));
1413 
1414   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1415   unsigned Offset = DicLC.dataoff + DicLC.datasize;
1416   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1417   return dice_iterator(DiceRef(DRI, this));
1418 }
1419 
1420 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1421     : Trie(T), Malformed(false), Done(false) {}
1422 
1423 void ExportEntry::moveToFirst() {
1424   pushNode(0);
1425   pushDownUntilBottom();
1426 }
1427 
1428 void ExportEntry::moveToEnd() {
1429   Stack.clear();
1430   Done = true;
1431 }
1432 
1433 bool ExportEntry::operator==(const ExportEntry &Other) const {
1434   // Common case, one at end, other iterating from begin.
1435   if (Done || Other.Done)
1436     return (Done == Other.Done);
1437   // Not equal if different stack sizes.
1438   if (Stack.size() != Other.Stack.size())
1439     return false;
1440   // Not equal if different cumulative strings.
1441   if (!CumulativeString.equals(Other.CumulativeString))
1442     return false;
1443   // Equal if all nodes in both stacks match.
1444   for (unsigned i=0; i < Stack.size(); ++i) {
1445     if (Stack[i].Start != Other.Stack[i].Start)
1446       return false;
1447   }
1448   return true;
1449 }
1450 
1451 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1452   unsigned Count;
1453   uint64_t Result = decodeULEB128(Ptr, &Count);
1454   Ptr += Count;
1455   if (Ptr > Trie.end()) {
1456     Ptr = Trie.end();
1457     Malformed = true;
1458   }
1459   return Result;
1460 }
1461 
1462 StringRef ExportEntry::name() const {
1463   return CumulativeString;
1464 }
1465 
1466 uint64_t ExportEntry::flags() const {
1467   return Stack.back().Flags;
1468 }
1469 
1470 uint64_t ExportEntry::address() const {
1471   return Stack.back().Address;
1472 }
1473 
1474 uint64_t ExportEntry::other() const {
1475   return Stack.back().Other;
1476 }
1477 
1478 StringRef ExportEntry::otherName() const {
1479   const char* ImportName = Stack.back().ImportName;
1480   if (ImportName)
1481     return StringRef(ImportName);
1482   return StringRef();
1483 }
1484 
1485 uint32_t ExportEntry::nodeOffset() const {
1486   return Stack.back().Start - Trie.begin();
1487 }
1488 
1489 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1490     : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1491       ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1492       ParentStringLength(0), IsExportNode(false) {}
1493 
1494 void ExportEntry::pushNode(uint64_t offset) {
1495   const uint8_t *Ptr = Trie.begin() + offset;
1496   NodeState State(Ptr);
1497   uint64_t ExportInfoSize = readULEB128(State.Current);
1498   State.IsExportNode = (ExportInfoSize != 0);
1499   const uint8_t* Children = State.Current + ExportInfoSize;
1500   if (State.IsExportNode) {
1501     State.Flags = readULEB128(State.Current);
1502     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1503       State.Address = 0;
1504       State.Other = readULEB128(State.Current); // dylib ordinal
1505       State.ImportName = reinterpret_cast<const char*>(State.Current);
1506     } else {
1507       State.Address = readULEB128(State.Current);
1508       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1509         State.Other = readULEB128(State.Current);
1510     }
1511   }
1512   State.ChildCount = *Children;
1513   State.Current = Children + 1;
1514   State.NextChildIndex = 0;
1515   State.ParentStringLength = CumulativeString.size();
1516   Stack.push_back(State);
1517 }
1518 
1519 void ExportEntry::pushDownUntilBottom() {
1520   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1521     NodeState &Top = Stack.back();
1522     CumulativeString.resize(Top.ParentStringLength);
1523     for (;*Top.Current != 0; Top.Current++) {
1524       char C = *Top.Current;
1525       CumulativeString.push_back(C);
1526     }
1527     Top.Current += 1;
1528     uint64_t childNodeIndex = readULEB128(Top.Current);
1529     Top.NextChildIndex += 1;
1530     pushNode(childNodeIndex);
1531   }
1532   if (!Stack.back().IsExportNode) {
1533     Malformed = true;
1534     moveToEnd();
1535   }
1536 }
1537 
1538 // We have a trie data structure and need a way to walk it that is compatible
1539 // with the C++ iterator model. The solution is a non-recursive depth first
1540 // traversal where the iterator contains a stack of parent nodes along with a
1541 // string that is the accumulation of all edge strings along the parent chain
1542 // to this point.
1543 //
1544 // There is one "export" node for each exported symbol.  But because some
1545 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1546 // node may have child nodes too.
1547 //
1548 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1549 // child until hitting a node with no children (which is an export node or
1550 // else the trie is malformed). On the way down, each node is pushed on the
1551 // stack ivar.  If there is no more ways down, it pops up one and tries to go
1552 // down a sibling path until a childless node is reached.
1553 void ExportEntry::moveNext() {
1554   if (Stack.empty() || !Stack.back().IsExportNode) {
1555     Malformed = true;
1556     moveToEnd();
1557     return;
1558   }
1559 
1560   Stack.pop_back();
1561   while (!Stack.empty()) {
1562     NodeState &Top = Stack.back();
1563     if (Top.NextChildIndex < Top.ChildCount) {
1564       pushDownUntilBottom();
1565       // Now at the next export node.
1566       return;
1567     } else {
1568       if (Top.IsExportNode) {
1569         // This node has no children but is itself an export node.
1570         CumulativeString.resize(Top.ParentStringLength);
1571         return;
1572       }
1573       Stack.pop_back();
1574     }
1575   }
1576   Done = true;
1577 }
1578 
1579 iterator_range<export_iterator>
1580 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1581   ExportEntry Start(Trie);
1582   if (Trie.size() == 0)
1583     Start.moveToEnd();
1584   else
1585     Start.moveToFirst();
1586 
1587   ExportEntry Finish(Trie);
1588   Finish.moveToEnd();
1589 
1590   return make_range(export_iterator(Start), export_iterator(Finish));
1591 }
1592 
1593 iterator_range<export_iterator> MachOObjectFile::exports() const {
1594   return exports(getDyldInfoExportsTrie());
1595 }
1596 
1597 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1598     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1599       RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1600       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1601 
1602 void MachORebaseEntry::moveToFirst() {
1603   Ptr = Opcodes.begin();
1604   moveNext();
1605 }
1606 
1607 void MachORebaseEntry::moveToEnd() {
1608   Ptr = Opcodes.end();
1609   RemainingLoopCount = 0;
1610   Done = true;
1611 }
1612 
1613 void MachORebaseEntry::moveNext() {
1614   // If in the middle of some loop, move to next rebasing in loop.
1615   SegmentOffset += AdvanceAmount;
1616   if (RemainingLoopCount) {
1617     --RemainingLoopCount;
1618     return;
1619   }
1620   if (Ptr == Opcodes.end()) {
1621     Done = true;
1622     return;
1623   }
1624   bool More = true;
1625   while (More && !Malformed) {
1626     // Parse next opcode and set up next loop.
1627     uint8_t Byte = *Ptr++;
1628     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1629     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1630     switch (Opcode) {
1631     case MachO::REBASE_OPCODE_DONE:
1632       More = false;
1633       Done = true;
1634       moveToEnd();
1635       DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1636       break;
1637     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1638       RebaseType = ImmValue;
1639       DEBUG_WITH_TYPE(
1640           "mach-o-rebase",
1641           llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1642                        << "RebaseType=" << (int) RebaseType << "\n");
1643       break;
1644     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1645       SegmentIndex = ImmValue;
1646       SegmentOffset = readULEB128();
1647       DEBUG_WITH_TYPE(
1648           "mach-o-rebase",
1649           llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1650                        << "SegmentIndex=" << SegmentIndex << ", "
1651                        << format("SegmentOffset=0x%06X", SegmentOffset)
1652                        << "\n");
1653       break;
1654     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1655       SegmentOffset += readULEB128();
1656       DEBUG_WITH_TYPE("mach-o-rebase",
1657                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1658                                    << format("SegmentOffset=0x%06X",
1659                                              SegmentOffset) << "\n");
1660       break;
1661     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1662       SegmentOffset += ImmValue * PointerSize;
1663       DEBUG_WITH_TYPE("mach-o-rebase",
1664                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1665                                    << format("SegmentOffset=0x%06X",
1666                                              SegmentOffset) << "\n");
1667       break;
1668     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1669       AdvanceAmount = PointerSize;
1670       RemainingLoopCount = ImmValue - 1;
1671       DEBUG_WITH_TYPE(
1672           "mach-o-rebase",
1673           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1674                        << format("SegmentOffset=0x%06X", SegmentOffset)
1675                        << ", AdvanceAmount=" << AdvanceAmount
1676                        << ", RemainingLoopCount=" << RemainingLoopCount
1677                        << "\n");
1678       return;
1679     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1680       AdvanceAmount = PointerSize;
1681       RemainingLoopCount = readULEB128() - 1;
1682       DEBUG_WITH_TYPE(
1683           "mach-o-rebase",
1684           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1685                        << format("SegmentOffset=0x%06X", SegmentOffset)
1686                        << ", AdvanceAmount=" << AdvanceAmount
1687                        << ", RemainingLoopCount=" << RemainingLoopCount
1688                        << "\n");
1689       return;
1690     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1691       AdvanceAmount = readULEB128() + PointerSize;
1692       RemainingLoopCount = 0;
1693       DEBUG_WITH_TYPE(
1694           "mach-o-rebase",
1695           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1696                        << format("SegmentOffset=0x%06X", SegmentOffset)
1697                        << ", AdvanceAmount=" << AdvanceAmount
1698                        << ", RemainingLoopCount=" << RemainingLoopCount
1699                        << "\n");
1700       return;
1701     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1702       RemainingLoopCount = readULEB128() - 1;
1703       AdvanceAmount = readULEB128() + PointerSize;
1704       DEBUG_WITH_TYPE(
1705           "mach-o-rebase",
1706           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1707                        << format("SegmentOffset=0x%06X", SegmentOffset)
1708                        << ", AdvanceAmount=" << AdvanceAmount
1709                        << ", RemainingLoopCount=" << RemainingLoopCount
1710                        << "\n");
1711       return;
1712     default:
1713       Malformed = true;
1714     }
1715   }
1716 }
1717 
1718 uint64_t MachORebaseEntry::readULEB128() {
1719   unsigned Count;
1720   uint64_t Result = decodeULEB128(Ptr, &Count);
1721   Ptr += Count;
1722   if (Ptr > Opcodes.end()) {
1723     Ptr = Opcodes.end();
1724     Malformed = true;
1725   }
1726   return Result;
1727 }
1728 
1729 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1730 
1731 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1732 
1733 StringRef MachORebaseEntry::typeName() const {
1734   switch (RebaseType) {
1735   case MachO::REBASE_TYPE_POINTER:
1736     return "pointer";
1737   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1738     return "text abs32";
1739   case MachO::REBASE_TYPE_TEXT_PCREL32:
1740     return "text rel32";
1741   }
1742   return "unknown";
1743 }
1744 
1745 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1746   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1747   return (Ptr == Other.Ptr) &&
1748          (RemainingLoopCount == Other.RemainingLoopCount) &&
1749          (Done == Other.Done);
1750 }
1751 
1752 iterator_range<rebase_iterator>
1753 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1754   MachORebaseEntry Start(Opcodes, is64);
1755   Start.moveToFirst();
1756 
1757   MachORebaseEntry Finish(Opcodes, is64);
1758   Finish.moveToEnd();
1759 
1760   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
1761 }
1762 
1763 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1764   return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1765 }
1766 
1767 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
1768     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1769       Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1770       BindType(0), PointerSize(is64Bit ? 8 : 4),
1771       TableKind(BK), Malformed(false), Done(false) {}
1772 
1773 void MachOBindEntry::moveToFirst() {
1774   Ptr = Opcodes.begin();
1775   moveNext();
1776 }
1777 
1778 void MachOBindEntry::moveToEnd() {
1779   Ptr = Opcodes.end();
1780   RemainingLoopCount = 0;
1781   Done = true;
1782 }
1783 
1784 void MachOBindEntry::moveNext() {
1785   // If in the middle of some loop, move to next binding in loop.
1786   SegmentOffset += AdvanceAmount;
1787   if (RemainingLoopCount) {
1788     --RemainingLoopCount;
1789     return;
1790   }
1791   if (Ptr == Opcodes.end()) {
1792     Done = true;
1793     return;
1794   }
1795   bool More = true;
1796   while (More && !Malformed) {
1797     // Parse next opcode and set up next loop.
1798     uint8_t Byte = *Ptr++;
1799     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1800     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1801     int8_t SignExtended;
1802     const uint8_t *SymStart;
1803     switch (Opcode) {
1804     case MachO::BIND_OPCODE_DONE:
1805       if (TableKind == Kind::Lazy) {
1806         // Lazying bindings have a DONE opcode between entries.  Need to ignore
1807         // it to advance to next entry.  But need not if this is last entry.
1808         bool NotLastEntry = false;
1809         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1810           if (*P) {
1811             NotLastEntry = true;
1812           }
1813         }
1814         if (NotLastEntry)
1815           break;
1816       }
1817       More = false;
1818       Done = true;
1819       moveToEnd();
1820       DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1821       break;
1822     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1823       Ordinal = ImmValue;
1824       DEBUG_WITH_TYPE(
1825           "mach-o-bind",
1826           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1827                        << "Ordinal=" << Ordinal << "\n");
1828       break;
1829     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1830       Ordinal = readULEB128();
1831       DEBUG_WITH_TYPE(
1832           "mach-o-bind",
1833           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1834                        << "Ordinal=" << Ordinal << "\n");
1835       break;
1836     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1837       if (ImmValue) {
1838         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1839         Ordinal = SignExtended;
1840       } else
1841         Ordinal = 0;
1842       DEBUG_WITH_TYPE(
1843           "mach-o-bind",
1844           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1845                        << "Ordinal=" << Ordinal << "\n");
1846       break;
1847     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1848       Flags = ImmValue;
1849       SymStart = Ptr;
1850       while (*Ptr) {
1851         ++Ptr;
1852       }
1853       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1854                              Ptr-SymStart);
1855       ++Ptr;
1856       DEBUG_WITH_TYPE(
1857           "mach-o-bind",
1858           llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1859                        << "SymbolName=" << SymbolName << "\n");
1860       if (TableKind == Kind::Weak) {
1861         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1862           return;
1863       }
1864       break;
1865     case MachO::BIND_OPCODE_SET_TYPE_IMM:
1866       BindType = ImmValue;
1867       DEBUG_WITH_TYPE(
1868           "mach-o-bind",
1869           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1870                        << "BindType=" << (int)BindType << "\n");
1871       break;
1872     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1873       Addend = readSLEB128();
1874       if (TableKind == Kind::Lazy)
1875         Malformed = true;
1876       DEBUG_WITH_TYPE(
1877           "mach-o-bind",
1878           llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1879                        << "Addend=" << Addend << "\n");
1880       break;
1881     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1882       SegmentIndex = ImmValue;
1883       SegmentOffset = readULEB128();
1884       DEBUG_WITH_TYPE(
1885           "mach-o-bind",
1886           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1887                        << "SegmentIndex=" << SegmentIndex << ", "
1888                        << format("SegmentOffset=0x%06X", SegmentOffset)
1889                        << "\n");
1890       break;
1891     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1892       SegmentOffset += readULEB128();
1893       DEBUG_WITH_TYPE("mach-o-bind",
1894                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1895                                    << format("SegmentOffset=0x%06X",
1896                                              SegmentOffset) << "\n");
1897       break;
1898     case MachO::BIND_OPCODE_DO_BIND:
1899       AdvanceAmount = PointerSize;
1900       RemainingLoopCount = 0;
1901       DEBUG_WITH_TYPE("mach-o-bind",
1902                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1903                                    << format("SegmentOffset=0x%06X",
1904                                              SegmentOffset) << "\n");
1905       return;
1906      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1907       AdvanceAmount = readULEB128() + PointerSize;
1908       RemainingLoopCount = 0;
1909       if (TableKind == Kind::Lazy)
1910         Malformed = true;
1911       DEBUG_WITH_TYPE(
1912           "mach-o-bind",
1913           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1914                        << format("SegmentOffset=0x%06X", SegmentOffset)
1915                        << ", AdvanceAmount=" << AdvanceAmount
1916                        << ", RemainingLoopCount=" << RemainingLoopCount
1917                        << "\n");
1918       return;
1919     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1920       AdvanceAmount = ImmValue * PointerSize + PointerSize;
1921       RemainingLoopCount = 0;
1922       if (TableKind == Kind::Lazy)
1923         Malformed = true;
1924       DEBUG_WITH_TYPE("mach-o-bind",
1925                       llvm::dbgs()
1926                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1927                       << format("SegmentOffset=0x%06X",
1928                                              SegmentOffset) << "\n");
1929       return;
1930     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1931       RemainingLoopCount = readULEB128() - 1;
1932       AdvanceAmount = readULEB128() + PointerSize;
1933       if (TableKind == Kind::Lazy)
1934         Malformed = true;
1935       DEBUG_WITH_TYPE(
1936           "mach-o-bind",
1937           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1938                        << format("SegmentOffset=0x%06X", SegmentOffset)
1939                        << ", AdvanceAmount=" << AdvanceAmount
1940                        << ", RemainingLoopCount=" << RemainingLoopCount
1941                        << "\n");
1942       return;
1943     default:
1944       Malformed = true;
1945     }
1946   }
1947 }
1948 
1949 uint64_t MachOBindEntry::readULEB128() {
1950   unsigned Count;
1951   uint64_t Result = decodeULEB128(Ptr, &Count);
1952   Ptr += Count;
1953   if (Ptr > Opcodes.end()) {
1954     Ptr = Opcodes.end();
1955     Malformed = true;
1956   }
1957   return Result;
1958 }
1959 
1960 int64_t MachOBindEntry::readSLEB128() {
1961   unsigned Count;
1962   int64_t Result = decodeSLEB128(Ptr, &Count);
1963   Ptr += Count;
1964   if (Ptr > Opcodes.end()) {
1965     Ptr = Opcodes.end();
1966     Malformed = true;
1967   }
1968   return Result;
1969 }
1970 
1971 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1972 
1973 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1974 
1975 StringRef MachOBindEntry::typeName() const {
1976   switch (BindType) {
1977   case MachO::BIND_TYPE_POINTER:
1978     return "pointer";
1979   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1980     return "text abs32";
1981   case MachO::BIND_TYPE_TEXT_PCREL32:
1982     return "text rel32";
1983   }
1984   return "unknown";
1985 }
1986 
1987 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1988 
1989 int64_t MachOBindEntry::addend() const { return Addend; }
1990 
1991 uint32_t MachOBindEntry::flags() const { return Flags; }
1992 
1993 int MachOBindEntry::ordinal() const { return Ordinal; }
1994 
1995 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1996   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1997   return (Ptr == Other.Ptr) &&
1998          (RemainingLoopCount == Other.RemainingLoopCount) &&
1999          (Done == Other.Done);
2000 }
2001 
2002 iterator_range<bind_iterator>
2003 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
2004                            MachOBindEntry::Kind BKind) {
2005   MachOBindEntry Start(Opcodes, is64, BKind);
2006   Start.moveToFirst();
2007 
2008   MachOBindEntry Finish(Opcodes, is64, BKind);
2009   Finish.moveToEnd();
2010 
2011   return make_range(bind_iterator(Start), bind_iterator(Finish));
2012 }
2013 
2014 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
2015   return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
2016                    MachOBindEntry::Kind::Regular);
2017 }
2018 
2019 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
2020   return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
2021                    MachOBindEntry::Kind::Lazy);
2022 }
2023 
2024 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
2025   return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
2026                    MachOBindEntry::Kind::Weak);
2027 }
2028 
2029 MachOObjectFile::load_command_iterator
2030 MachOObjectFile::begin_load_commands() const {
2031   return LoadCommands.begin();
2032 }
2033 
2034 MachOObjectFile::load_command_iterator
2035 MachOObjectFile::end_load_commands() const {
2036   return LoadCommands.end();
2037 }
2038 
2039 iterator_range<MachOObjectFile::load_command_iterator>
2040 MachOObjectFile::load_commands() const {
2041   return make_range(begin_load_commands(), end_load_commands());
2042 }
2043 
2044 StringRef
2045 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
2046   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
2047   return parseSegmentOrSectionName(Raw.data());
2048 }
2049 
2050 ArrayRef<char>
2051 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
2052   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
2053   const section_base *Base =
2054     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2055   return makeArrayRef(Base->sectname);
2056 }
2057 
2058 ArrayRef<char>
2059 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
2060   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
2061   const section_base *Base =
2062     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2063   return makeArrayRef(Base->segname);
2064 }
2065 
2066 bool
2067 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
2068   const {
2069   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
2070     return false;
2071   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
2072 }
2073 
2074 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
2075     const MachO::any_relocation_info &RE) const {
2076   if (isLittleEndian())
2077     return RE.r_word1 & 0xffffff;
2078   return RE.r_word1 >> 8;
2079 }
2080 
2081 bool MachOObjectFile::getPlainRelocationExternal(
2082     const MachO::any_relocation_info &RE) const {
2083   if (isLittleEndian())
2084     return (RE.r_word1 >> 27) & 1;
2085   return (RE.r_word1 >> 4) & 1;
2086 }
2087 
2088 bool MachOObjectFile::getScatteredRelocationScattered(
2089     const MachO::any_relocation_info &RE) const {
2090   return RE.r_word0 >> 31;
2091 }
2092 
2093 uint32_t MachOObjectFile::getScatteredRelocationValue(
2094     const MachO::any_relocation_info &RE) const {
2095   return RE.r_word1;
2096 }
2097 
2098 uint32_t MachOObjectFile::getScatteredRelocationType(
2099     const MachO::any_relocation_info &RE) const {
2100   return (RE.r_word0 >> 24) & 0xf;
2101 }
2102 
2103 unsigned MachOObjectFile::getAnyRelocationAddress(
2104     const MachO::any_relocation_info &RE) const {
2105   if (isRelocationScattered(RE))
2106     return getScatteredRelocationAddress(RE);
2107   return getPlainRelocationAddress(RE);
2108 }
2109 
2110 unsigned MachOObjectFile::getAnyRelocationPCRel(
2111     const MachO::any_relocation_info &RE) const {
2112   if (isRelocationScattered(RE))
2113     return getScatteredRelocationPCRel(this, RE);
2114   return getPlainRelocationPCRel(this, RE);
2115 }
2116 
2117 unsigned MachOObjectFile::getAnyRelocationLength(
2118     const MachO::any_relocation_info &RE) const {
2119   if (isRelocationScattered(RE))
2120     return getScatteredRelocationLength(RE);
2121   return getPlainRelocationLength(this, RE);
2122 }
2123 
2124 unsigned
2125 MachOObjectFile::getAnyRelocationType(
2126                                    const MachO::any_relocation_info &RE) const {
2127   if (isRelocationScattered(RE))
2128     return getScatteredRelocationType(RE);
2129   return getPlainRelocationType(this, RE);
2130 }
2131 
2132 SectionRef
2133 MachOObjectFile::getAnyRelocationSection(
2134                                    const MachO::any_relocation_info &RE) const {
2135   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2136     return *section_end();
2137   unsigned SecNum = getPlainRelocationSymbolNum(RE);
2138   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
2139     return *section_end();
2140   DataRefImpl DRI;
2141   DRI.d.a = SecNum - 1;
2142   return SectionRef(DRI, this);
2143 }
2144 
2145 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2146   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2147   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2148 }
2149 
2150 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2151   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2152   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2153 }
2154 
2155 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2156                                            unsigned Index) const {
2157   const char *Sec = getSectionPtr(this, L, Index);
2158   return getStruct<MachO::section>(this, Sec);
2159 }
2160 
2161 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2162                                                 unsigned Index) const {
2163   const char *Sec = getSectionPtr(this, L, Index);
2164   return getStruct<MachO::section_64>(this, Sec);
2165 }
2166 
2167 MachO::nlist
2168 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2169   const char *P = reinterpret_cast<const char *>(DRI.p);
2170   return getStruct<MachO::nlist>(this, P);
2171 }
2172 
2173 MachO::nlist_64
2174 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2175   const char *P = reinterpret_cast<const char *>(DRI.p);
2176   return getStruct<MachO::nlist_64>(this, P);
2177 }
2178 
2179 MachO::linkedit_data_command
2180 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2181   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2182 }
2183 
2184 MachO::segment_command
2185 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2186   return getStruct<MachO::segment_command>(this, L.Ptr);
2187 }
2188 
2189 MachO::segment_command_64
2190 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2191   return getStruct<MachO::segment_command_64>(this, L.Ptr);
2192 }
2193 
2194 MachO::linker_option_command
2195 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2196   return getStruct<MachO::linker_option_command>(this, L.Ptr);
2197 }
2198 
2199 MachO::version_min_command
2200 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2201   return getStruct<MachO::version_min_command>(this, L.Ptr);
2202 }
2203 
2204 MachO::dylib_command
2205 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2206   return getStruct<MachO::dylib_command>(this, L.Ptr);
2207 }
2208 
2209 MachO::dyld_info_command
2210 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2211   return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2212 }
2213 
2214 MachO::dylinker_command
2215 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2216   return getStruct<MachO::dylinker_command>(this, L.Ptr);
2217 }
2218 
2219 MachO::uuid_command
2220 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2221   return getStruct<MachO::uuid_command>(this, L.Ptr);
2222 }
2223 
2224 MachO::rpath_command
2225 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2226   return getStruct<MachO::rpath_command>(this, L.Ptr);
2227 }
2228 
2229 MachO::source_version_command
2230 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2231   return getStruct<MachO::source_version_command>(this, L.Ptr);
2232 }
2233 
2234 MachO::entry_point_command
2235 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2236   return getStruct<MachO::entry_point_command>(this, L.Ptr);
2237 }
2238 
2239 MachO::encryption_info_command
2240 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2241   return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2242 }
2243 
2244 MachO::encryption_info_command_64
2245 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2246   return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2247 }
2248 
2249 MachO::sub_framework_command
2250 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2251   return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2252 }
2253 
2254 MachO::sub_umbrella_command
2255 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2256   return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2257 }
2258 
2259 MachO::sub_library_command
2260 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2261   return getStruct<MachO::sub_library_command>(this, L.Ptr);
2262 }
2263 
2264 MachO::sub_client_command
2265 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2266   return getStruct<MachO::sub_client_command>(this, L.Ptr);
2267 }
2268 
2269 MachO::routines_command
2270 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2271   return getStruct<MachO::routines_command>(this, L.Ptr);
2272 }
2273 
2274 MachO::routines_command_64
2275 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2276   return getStruct<MachO::routines_command_64>(this, L.Ptr);
2277 }
2278 
2279 MachO::thread_command
2280 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2281   return getStruct<MachO::thread_command>(this, L.Ptr);
2282 }
2283 
2284 MachO::any_relocation_info
2285 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2286   DataRefImpl Sec;
2287   Sec.d.a = Rel.d.a;
2288   uint32_t Offset;
2289   if (is64Bit()) {
2290     MachO::section_64 Sect = getSection64(Sec);
2291     Offset = Sect.reloff;
2292   } else {
2293     MachO::section Sect = getSection(Sec);
2294     Offset = Sect.reloff;
2295   }
2296 
2297   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2298       getPtr(this, Offset)) + Rel.d.b;
2299   return getStruct<MachO::any_relocation_info>(
2300       this, reinterpret_cast<const char *>(P));
2301 }
2302 
2303 MachO::data_in_code_entry
2304 MachOObjectFile::getDice(DataRefImpl Rel) const {
2305   const char *P = reinterpret_cast<const char *>(Rel.p);
2306   return getStruct<MachO::data_in_code_entry>(this, P);
2307 }
2308 
2309 const MachO::mach_header &MachOObjectFile::getHeader() const {
2310   return Header;
2311 }
2312 
2313 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2314   assert(is64Bit());
2315   return Header64;
2316 }
2317 
2318 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2319                                              const MachO::dysymtab_command &DLC,
2320                                              unsigned Index) const {
2321   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2322   return getStruct<uint32_t>(this, getPtr(this, Offset));
2323 }
2324 
2325 MachO::data_in_code_entry
2326 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2327                                          unsigned Index) const {
2328   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2329   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2330 }
2331 
2332 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2333   if (SymtabLoadCmd)
2334     return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2335 
2336   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2337   MachO::symtab_command Cmd;
2338   Cmd.cmd = MachO::LC_SYMTAB;
2339   Cmd.cmdsize = sizeof(MachO::symtab_command);
2340   Cmd.symoff = 0;
2341   Cmd.nsyms = 0;
2342   Cmd.stroff = 0;
2343   Cmd.strsize = 0;
2344   return Cmd;
2345 }
2346 
2347 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2348   if (DysymtabLoadCmd)
2349     return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2350 
2351   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2352   MachO::dysymtab_command Cmd;
2353   Cmd.cmd = MachO::LC_DYSYMTAB;
2354   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2355   Cmd.ilocalsym = 0;
2356   Cmd.nlocalsym = 0;
2357   Cmd.iextdefsym = 0;
2358   Cmd.nextdefsym = 0;
2359   Cmd.iundefsym = 0;
2360   Cmd.nundefsym = 0;
2361   Cmd.tocoff = 0;
2362   Cmd.ntoc = 0;
2363   Cmd.modtaboff = 0;
2364   Cmd.nmodtab = 0;
2365   Cmd.extrefsymoff = 0;
2366   Cmd.nextrefsyms = 0;
2367   Cmd.indirectsymoff = 0;
2368   Cmd.nindirectsyms = 0;
2369   Cmd.extreloff = 0;
2370   Cmd.nextrel = 0;
2371   Cmd.locreloff = 0;
2372   Cmd.nlocrel = 0;
2373   return Cmd;
2374 }
2375 
2376 MachO::linkedit_data_command
2377 MachOObjectFile::getDataInCodeLoadCommand() const {
2378   if (DataInCodeLoadCmd)
2379     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2380 
2381   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2382   MachO::linkedit_data_command Cmd;
2383   Cmd.cmd = MachO::LC_DATA_IN_CODE;
2384   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2385   Cmd.dataoff = 0;
2386   Cmd.datasize = 0;
2387   return Cmd;
2388 }
2389 
2390 MachO::linkedit_data_command
2391 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2392   if (LinkOptHintsLoadCmd)
2393     return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2394 
2395   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2396   // fields.
2397   MachO::linkedit_data_command Cmd;
2398   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2399   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2400   Cmd.dataoff = 0;
2401   Cmd.datasize = 0;
2402   return Cmd;
2403 }
2404 
2405 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2406   if (!DyldInfoLoadCmd)
2407     return None;
2408 
2409   MachO::dyld_info_command DyldInfo =
2410       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2411   const uint8_t *Ptr =
2412       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off));
2413   return makeArrayRef(Ptr, DyldInfo.rebase_size);
2414 }
2415 
2416 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2417   if (!DyldInfoLoadCmd)
2418     return None;
2419 
2420   MachO::dyld_info_command DyldInfo =
2421       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2422   const uint8_t *Ptr =
2423       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off));
2424   return makeArrayRef(Ptr, DyldInfo.bind_size);
2425 }
2426 
2427 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2428   if (!DyldInfoLoadCmd)
2429     return None;
2430 
2431   MachO::dyld_info_command DyldInfo =
2432       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2433   const uint8_t *Ptr =
2434       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off));
2435   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
2436 }
2437 
2438 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2439   if (!DyldInfoLoadCmd)
2440     return None;
2441 
2442   MachO::dyld_info_command DyldInfo =
2443       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2444   const uint8_t *Ptr =
2445       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off));
2446   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
2447 }
2448 
2449 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2450   if (!DyldInfoLoadCmd)
2451     return None;
2452 
2453   MachO::dyld_info_command DyldInfo =
2454       getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2455   const uint8_t *Ptr =
2456       reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off));
2457   return makeArrayRef(Ptr, DyldInfo.export_size);
2458 }
2459 
2460 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2461   if (!UuidLoadCmd)
2462     return None;
2463   // Returning a pointer is fine as uuid doesn't need endian swapping.
2464   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2465   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
2466 }
2467 
2468 StringRef MachOObjectFile::getStringTableData() const {
2469   MachO::symtab_command S = getSymtabLoadCommand();
2470   return getData().substr(S.stroff, S.strsize);
2471 }
2472 
2473 bool MachOObjectFile::is64Bit() const {
2474   return getType() == getMachOType(false, true) ||
2475     getType() == getMachOType(true, true);
2476 }
2477 
2478 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2479                                    SmallVectorImpl<uint64_t> &Out) const {
2480   DataExtractor extractor(ObjectFile::getData(), true, 0);
2481 
2482   uint32_t offset = Index;
2483   uint64_t data = 0;
2484   while (uint64_t delta = extractor.getULEB128(&offset)) {
2485     data += delta;
2486     Out.push_back(data);
2487   }
2488 }
2489 
2490 bool MachOObjectFile::isRelocatableObject() const {
2491   return getHeader().filetype == MachO::MH_OBJECT;
2492 }
2493 
2494 Expected<std::unique_ptr<MachOObjectFile>>
2495 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2496   StringRef Magic = Buffer.getBuffer().slice(0, 4);
2497   if (Magic == "\xFE\xED\xFA\xCE")
2498     return MachOObjectFile::create(Buffer, false, false);
2499   if (Magic == "\xCE\xFA\xED\xFE")
2500     return MachOObjectFile::create(Buffer, true, false);
2501   if (Magic == "\xFE\xED\xFA\xCF")
2502     return MachOObjectFile::create(Buffer, false, true);
2503   if (Magic == "\xCF\xFA\xED\xFE")
2504     return MachOObjectFile::create(Buffer, true, true);
2505   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
2506                                         object_error::invalid_file_type);
2507 }
2508