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