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