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