xref: /freebsd/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision d9a42747950146bf03cda7f6e25d219253f8a57a)
1 //===- MachOObjectFile.cpp - Mach-O object file binding -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the MachOObjectFile class, which binds the MachOObject
10 // class to the generic ObjectFile wrapper.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/None.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/BinaryFormat/MachO.h"
23 #include "llvm/BinaryFormat/Swift.h"
24 #include "llvm/Object/Error.h"
25 #include "llvm/Object/MachO.h"
26 #include "llvm/Object/ObjectFile.h"
27 #include "llvm/Object/SymbolicFile.h"
28 #include "llvm/Support/DataExtractor.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/Errc.h"
31 #include "llvm/Support/Error.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/FileSystem.h"
34 #include "llvm/Support/Format.h"
35 #include "llvm/Support/Host.h"
36 #include "llvm/Support/LEB128.h"
37 #include "llvm/Support/MemoryBufferRef.h"
38 #include "llvm/Support/Path.h"
39 #include "llvm/Support/SwapByteOrder.h"
40 #include "llvm/Support/raw_ostream.h"
41 #include <algorithm>
42 #include <cassert>
43 #include <cstddef>
44 #include <cstdint>
45 #include <cstring>
46 #include <limits>
47 #include <list>
48 #include <memory>
49 #include <system_error>
50 
51 using namespace llvm;
52 using namespace object;
53 
54 namespace {
55 
56   struct section_base {
57     char sectname[16];
58     char segname[16];
59   };
60 
61 } // end anonymous namespace
62 
63 static Error malformedError(const Twine &Msg) {
64   return make_error<GenericBinaryError>("truncated or malformed object (" +
65                                             Msg + ")",
66                                         object_error::parse_failed);
67 }
68 
69 // FIXME: Replace all uses of this function with getStructOrErr.
70 template <typename T>
71 static T getStruct(const MachOObjectFile &O, const char *P) {
72   // Don't read before the beginning or past the end of the file
73   if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
74     report_fatal_error("Malformed MachO file.");
75 
76   T Cmd;
77   memcpy(&Cmd, P, sizeof(T));
78   if (O.isLittleEndian() != sys::IsLittleEndianHost)
79     MachO::swapStruct(Cmd);
80   return Cmd;
81 }
82 
83 template <typename T>
84 static Expected<T> getStructOrErr(const MachOObjectFile &O, const char *P) {
85   // Don't read before the beginning or past the end of the file
86   if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
87     return malformedError("Structure read out-of-range");
88 
89   T Cmd;
90   memcpy(&Cmd, P, sizeof(T));
91   if (O.isLittleEndian() != sys::IsLittleEndianHost)
92     MachO::swapStruct(Cmd);
93   return Cmd;
94 }
95 
96 static const char *
97 getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L,
98               unsigned Sec) {
99   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
100 
101   bool Is64 = O.is64Bit();
102   unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
103                                     sizeof(MachO::segment_command);
104   unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
105                                 sizeof(MachO::section);
106 
107   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
108   return reinterpret_cast<const char*>(SectionAddr);
109 }
110 
111 static const char *getPtr(const MachOObjectFile &O, size_t Offset) {
112   assert(Offset <= O.getData().size());
113   return O.getData().data() + Offset;
114 }
115 
116 static MachO::nlist_base
117 getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI) {
118   const char *P = reinterpret_cast<const char *>(DRI.p);
119   return getStruct<MachO::nlist_base>(O, P);
120 }
121 
122 static StringRef parseSegmentOrSectionName(const char *P) {
123   if (P[15] == 0)
124     // Null terminated.
125     return P;
126   // Not null terminated, so this is a 16 char string.
127   return StringRef(P, 16);
128 }
129 
130 static unsigned getCPUType(const MachOObjectFile &O) {
131   return O.getHeader().cputype;
132 }
133 
134 static unsigned getCPUSubType(const MachOObjectFile &O) {
135   return O.getHeader().cpusubtype;
136 }
137 
138 static uint32_t
139 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
140   return RE.r_word0;
141 }
142 
143 static unsigned
144 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
145   return RE.r_word0 & 0xffffff;
146 }
147 
148 static bool getPlainRelocationPCRel(const MachOObjectFile &O,
149                                     const MachO::any_relocation_info &RE) {
150   if (O.isLittleEndian())
151     return (RE.r_word1 >> 24) & 1;
152   return (RE.r_word1 >> 7) & 1;
153 }
154 
155 static bool
156 getScatteredRelocationPCRel(const MachO::any_relocation_info &RE) {
157   return (RE.r_word0 >> 30) & 1;
158 }
159 
160 static unsigned getPlainRelocationLength(const MachOObjectFile &O,
161                                          const MachO::any_relocation_info &RE) {
162   if (O.isLittleEndian())
163     return (RE.r_word1 >> 25) & 3;
164   return (RE.r_word1 >> 5) & 3;
165 }
166 
167 static unsigned
168 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
169   return (RE.r_word0 >> 28) & 3;
170 }
171 
172 static unsigned getPlainRelocationType(const MachOObjectFile &O,
173                                        const MachO::any_relocation_info &RE) {
174   if (O.isLittleEndian())
175     return RE.r_word1 >> 28;
176   return RE.r_word1 & 0xf;
177 }
178 
179 static uint32_t getSectionFlags(const MachOObjectFile &O,
180                                 DataRefImpl Sec) {
181   if (O.is64Bit()) {
182     MachO::section_64 Sect = O.getSection64(Sec);
183     return Sect.flags;
184   }
185   MachO::section Sect = O.getSection(Sec);
186   return Sect.flags;
187 }
188 
189 static Expected<MachOObjectFile::LoadCommandInfo>
190 getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr,
191                    uint32_t LoadCommandIndex) {
192   if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
193     if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())
194       return malformedError("load command " + Twine(LoadCommandIndex) +
195                             " extends past end of file");
196     if (CmdOrErr->cmdsize < 8)
197       return malformedError("load command " + Twine(LoadCommandIndex) +
198                             " with size less than 8 bytes");
199     return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
200   } else
201     return CmdOrErr.takeError();
202 }
203 
204 static Expected<MachOObjectFile::LoadCommandInfo>
205 getFirstLoadCommandInfo(const MachOObjectFile &Obj) {
206   unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
207                                       : sizeof(MachO::mach_header);
208   if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds)
209     return malformedError("load command 0 extends past the end all load "
210                           "commands in the file");
211   return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
212 }
213 
214 static Expected<MachOObjectFile::LoadCommandInfo>
215 getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex,
216                        const MachOObjectFile::LoadCommandInfo &L) {
217   unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
218                                       : sizeof(MachO::mach_header);
219   if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
220       Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
221     return malformedError("load command " + Twine(LoadCommandIndex + 1) +
222                           " extends past the end all load commands in the file");
223   return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
224 }
225 
226 template <typename T>
227 static void parseHeader(const MachOObjectFile &Obj, T &Header,
228                         Error &Err) {
229   if (sizeof(T) > Obj.getData().size()) {
230     Err = malformedError("the mach header extends past the end of the "
231                          "file");
232     return;
233   }
234   if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
235     Header = *HeaderOrErr;
236   else
237     Err = HeaderOrErr.takeError();
238 }
239 
240 // This is used to check for overlapping of Mach-O elements.
241 struct MachOElement {
242   uint64_t Offset;
243   uint64_t Size;
244   const char *Name;
245 };
246 
247 static Error checkOverlappingElement(std::list<MachOElement> &Elements,
248                                      uint64_t Offset, uint64_t Size,
249                                      const char *Name) {
250   if (Size == 0)
251     return Error::success();
252 
253   for (auto it = Elements.begin(); it != Elements.end(); ++it) {
254     const auto &E = *it;
255     if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
256         (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) ||
257         (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
258       return malformedError(Twine(Name) + " at offset " + Twine(Offset) +
259                             " with a size of " + Twine(Size) + ", overlaps " +
260                             E.Name + " at offset " + Twine(E.Offset) + " with "
261                             "a size of " + Twine(E.Size));
262     auto nt = it;
263     nt++;
264     if (nt != Elements.end()) {
265       const auto &N = *nt;
266       if (Offset + Size <= N.Offset) {
267         Elements.insert(nt, {Offset, Size, Name});
268         return Error::success();
269       }
270     }
271   }
272   Elements.push_back({Offset, Size, Name});
273   return Error::success();
274 }
275 
276 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
277 // sections to \param Sections, and optionally sets
278 // \param IsPageZeroSegment to true.
279 template <typename Segment, typename Section>
280 static Error parseSegmentLoadCommand(
281     const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load,
282     SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
283     uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
284     std::list<MachOElement> &Elements) {
285   const unsigned SegmentLoadSize = sizeof(Segment);
286   if (Load.C.cmdsize < SegmentLoadSize)
287     return malformedError("load command " + Twine(LoadCommandIndex) +
288                           " " + CmdName + " cmdsize too small");
289   if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
290     Segment S = SegOrErr.get();
291     const unsigned SectionSize = sizeof(Section);
292     uint64_t FileSize = Obj.getData().size();
293     if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
294         S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
295       return malformedError("load command " + Twine(LoadCommandIndex) +
296                             " inconsistent cmdsize in " + CmdName +
297                             " for the number of sections");
298     for (unsigned J = 0; J < S.nsects; ++J) {
299       const char *Sec = getSectionPtr(Obj, Load, J);
300       Sections.push_back(Sec);
301       auto SectionOrErr = getStructOrErr<Section>(Obj, Sec);
302       if (!SectionOrErr)
303         return SectionOrErr.takeError();
304       Section s = SectionOrErr.get();
305       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
306           Obj.getHeader().filetype != MachO::MH_DSYM &&
307           s.flags != MachO::S_ZEROFILL &&
308           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
309           s.offset > FileSize)
310         return malformedError("offset field of section " + Twine(J) + " in " +
311                               CmdName + " command " + Twine(LoadCommandIndex) +
312                               " extends past the end of the file");
313       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
314           Obj.getHeader().filetype != MachO::MH_DSYM &&
315           s.flags != MachO::S_ZEROFILL &&
316           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 &&
317           s.offset < SizeOfHeaders && s.size != 0)
318         return malformedError("offset field of section " + Twine(J) + " in " +
319                               CmdName + " command " + Twine(LoadCommandIndex) +
320                               " not past the headers of the file");
321       uint64_t BigSize = s.offset;
322       BigSize += s.size;
323       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
324           Obj.getHeader().filetype != MachO::MH_DSYM &&
325           s.flags != MachO::S_ZEROFILL &&
326           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
327           BigSize > FileSize)
328         return malformedError("offset field plus size field of section " +
329                               Twine(J) + " in " + CmdName + " command " +
330                               Twine(LoadCommandIndex) +
331                               " extends past the end of the file");
332       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
333           Obj.getHeader().filetype != MachO::MH_DSYM &&
334           s.flags != MachO::S_ZEROFILL &&
335           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
336           s.size > S.filesize)
337         return malformedError("size field of section " +
338                               Twine(J) + " in " + CmdName + " command " +
339                               Twine(LoadCommandIndex) +
340                               " greater than the segment");
341       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
342           Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
343           s.addr < S.vmaddr)
344         return malformedError("addr field of section " + Twine(J) + " in " +
345                               CmdName + " command " + Twine(LoadCommandIndex) +
346                               " less than the segment's vmaddr");
347       BigSize = s.addr;
348       BigSize += s.size;
349       uint64_t BigEnd = S.vmaddr;
350       BigEnd += S.vmsize;
351       if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
352         return malformedError("addr field plus size of section " + Twine(J) +
353                               " in " + CmdName + " command " +
354                               Twine(LoadCommandIndex) +
355                               " greater than than "
356                               "the segment's vmaddr plus vmsize");
357       if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
358           Obj.getHeader().filetype != MachO::MH_DSYM &&
359           s.flags != MachO::S_ZEROFILL &&
360           s.flags != MachO::S_THREAD_LOCAL_ZEROFILL)
361         if (Error Err = checkOverlappingElement(Elements, s.offset, s.size,
362                                                 "section contents"))
363           return Err;
364       if (s.reloff > FileSize)
365         return malformedError("reloff field of section " + Twine(J) + " in " +
366                               CmdName + " command " + Twine(LoadCommandIndex) +
367                               " extends past the end of the file");
368       BigSize = s.nreloc;
369       BigSize *= sizeof(struct MachO::relocation_info);
370       BigSize += s.reloff;
371       if (BigSize > FileSize)
372         return malformedError("reloff field plus nreloc field times sizeof("
373                               "struct relocation_info) of section " +
374                               Twine(J) + " in " + CmdName + " command " +
375                               Twine(LoadCommandIndex) +
376                               " extends past the end of the file");
377       if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc *
378                                               sizeof(struct
379                                               MachO::relocation_info),
380                                               "section relocation entries"))
381         return Err;
382     }
383     if (S.fileoff > FileSize)
384       return malformedError("load command " + Twine(LoadCommandIndex) +
385                             " fileoff field in " + CmdName +
386                             " extends past the end of the file");
387     uint64_t BigSize = S.fileoff;
388     BigSize += S.filesize;
389     if (BigSize > FileSize)
390       return malformedError("load command " + Twine(LoadCommandIndex) +
391                             " fileoff field plus filesize field in " +
392                             CmdName + " extends past the end of the file");
393     if (S.vmsize != 0 && S.filesize > S.vmsize)
394       return malformedError("load command " + Twine(LoadCommandIndex) +
395                             " filesize field in " + CmdName +
396                             " greater than vmsize field");
397     IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
398   } else
399     return SegOrErr.takeError();
400 
401   return Error::success();
402 }
403 
404 static Error checkSymtabCommand(const MachOObjectFile &Obj,
405                                 const MachOObjectFile::LoadCommandInfo &Load,
406                                 uint32_t LoadCommandIndex,
407                                 const char **SymtabLoadCmd,
408                                 std::list<MachOElement> &Elements) {
409   if (Load.C.cmdsize < sizeof(MachO::symtab_command))
410     return malformedError("load command " + Twine(LoadCommandIndex) +
411                           " LC_SYMTAB cmdsize too small");
412   if (*SymtabLoadCmd != nullptr)
413     return malformedError("more than one LC_SYMTAB command");
414   auto SymtabOrErr = getStructOrErr<MachO::symtab_command>(Obj, Load.Ptr);
415   if (!SymtabOrErr)
416     return SymtabOrErr.takeError();
417   MachO::symtab_command Symtab = SymtabOrErr.get();
418   if (Symtab.cmdsize != sizeof(MachO::symtab_command))
419     return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) +
420                           " has incorrect cmdsize");
421   uint64_t FileSize = Obj.getData().size();
422   if (Symtab.symoff > FileSize)
423     return malformedError("symoff field of LC_SYMTAB command " +
424                           Twine(LoadCommandIndex) + " extends past the end "
425                           "of the file");
426   uint64_t SymtabSize = Symtab.nsyms;
427   const char *struct_nlist_name;
428   if (Obj.is64Bit()) {
429     SymtabSize *= sizeof(MachO::nlist_64);
430     struct_nlist_name = "struct nlist_64";
431   } else {
432     SymtabSize *= sizeof(MachO::nlist);
433     struct_nlist_name = "struct nlist";
434   }
435   uint64_t BigSize = SymtabSize;
436   BigSize += Symtab.symoff;
437   if (BigSize > FileSize)
438     return malformedError("symoff field plus nsyms field times sizeof(" +
439                           Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
440                           Twine(LoadCommandIndex) + " extends past the end "
441                           "of the file");
442   if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize,
443                                           "symbol table"))
444     return Err;
445   if (Symtab.stroff > FileSize)
446     return malformedError("stroff field of LC_SYMTAB command " +
447                           Twine(LoadCommandIndex) + " extends past the end "
448                           "of the file");
449   BigSize = Symtab.stroff;
450   BigSize += Symtab.strsize;
451   if (BigSize > FileSize)
452     return malformedError("stroff field plus strsize field of LC_SYMTAB "
453                           "command " + Twine(LoadCommandIndex) + " extends "
454                           "past the end of the file");
455   if (Error Err = checkOverlappingElement(Elements, Symtab.stroff,
456                                           Symtab.strsize, "string table"))
457     return Err;
458   *SymtabLoadCmd = Load.Ptr;
459   return Error::success();
460 }
461 
462 static Error checkDysymtabCommand(const MachOObjectFile &Obj,
463                                   const MachOObjectFile::LoadCommandInfo &Load,
464                                   uint32_t LoadCommandIndex,
465                                   const char **DysymtabLoadCmd,
466                                   std::list<MachOElement> &Elements) {
467   if (Load.C.cmdsize < sizeof(MachO::dysymtab_command))
468     return malformedError("load command " + Twine(LoadCommandIndex) +
469                           " LC_DYSYMTAB cmdsize too small");
470   if (*DysymtabLoadCmd != nullptr)
471     return malformedError("more than one LC_DYSYMTAB command");
472   auto DysymtabOrErr =
473     getStructOrErr<MachO::dysymtab_command>(Obj, Load.Ptr);
474   if (!DysymtabOrErr)
475     return DysymtabOrErr.takeError();
476   MachO::dysymtab_command Dysymtab = DysymtabOrErr.get();
477   if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command))
478     return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) +
479                           " has incorrect cmdsize");
480   uint64_t FileSize = Obj.getData().size();
481   if (Dysymtab.tocoff > FileSize)
482     return malformedError("tocoff field of LC_DYSYMTAB command " +
483                           Twine(LoadCommandIndex) + " extends past the end of "
484                           "the file");
485   uint64_t BigSize = Dysymtab.ntoc;
486   BigSize *= sizeof(MachO::dylib_table_of_contents);
487   BigSize += Dysymtab.tocoff;
488   if (BigSize > FileSize)
489     return malformedError("tocoff field plus ntoc field times sizeof(struct "
490                           "dylib_table_of_contents) of LC_DYSYMTAB command " +
491                           Twine(LoadCommandIndex) + " extends past the end of "
492                           "the file");
493   if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff,
494                                           Dysymtab.ntoc * sizeof(struct
495                                           MachO::dylib_table_of_contents),
496                                           "table of contents"))
497     return Err;
498   if (Dysymtab.modtaboff > FileSize)
499     return malformedError("modtaboff field of LC_DYSYMTAB command " +
500                           Twine(LoadCommandIndex) + " extends past the end of "
501                           "the file");
502   BigSize = Dysymtab.nmodtab;
503   const char *struct_dylib_module_name;
504   uint64_t sizeof_modtab;
505   if (Obj.is64Bit()) {
506     sizeof_modtab = sizeof(MachO::dylib_module_64);
507     struct_dylib_module_name = "struct dylib_module_64";
508   } else {
509     sizeof_modtab = sizeof(MachO::dylib_module);
510     struct_dylib_module_name = "struct dylib_module";
511   }
512   BigSize *= sizeof_modtab;
513   BigSize += Dysymtab.modtaboff;
514   if (BigSize > FileSize)
515     return malformedError("modtaboff field plus nmodtab field times sizeof(" +
516                           Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
517                           "command " + Twine(LoadCommandIndex) + " extends "
518                           "past the end of the file");
519   if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff,
520                                           Dysymtab.nmodtab * sizeof_modtab,
521                                           "module table"))
522     return Err;
523   if (Dysymtab.extrefsymoff > FileSize)
524     return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
525                           Twine(LoadCommandIndex) + " extends past the end of "
526                           "the file");
527   BigSize = Dysymtab.nextrefsyms;
528   BigSize *= sizeof(MachO::dylib_reference);
529   BigSize += Dysymtab.extrefsymoff;
530   if (BigSize > FileSize)
531     return malformedError("extrefsymoff field plus nextrefsyms field times "
532                           "sizeof(struct dylib_reference) of LC_DYSYMTAB "
533                           "command " + Twine(LoadCommandIndex) + " extends "
534                           "past the end of the file");
535   if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff,
536                                           Dysymtab.nextrefsyms *
537                                               sizeof(MachO::dylib_reference),
538                                           "reference table"))
539     return Err;
540   if (Dysymtab.indirectsymoff > FileSize)
541     return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
542                           Twine(LoadCommandIndex) + " extends past the end of "
543                           "the file");
544   BigSize = Dysymtab.nindirectsyms;
545   BigSize *= sizeof(uint32_t);
546   BigSize += Dysymtab.indirectsymoff;
547   if (BigSize > FileSize)
548     return malformedError("indirectsymoff field plus nindirectsyms field times "
549                           "sizeof(uint32_t) of LC_DYSYMTAB command " +
550                           Twine(LoadCommandIndex) + " extends past the end of "
551                           "the file");
552   if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff,
553                                           Dysymtab.nindirectsyms *
554                                           sizeof(uint32_t),
555                                           "indirect table"))
556     return Err;
557   if (Dysymtab.extreloff > FileSize)
558     return malformedError("extreloff field of LC_DYSYMTAB command " +
559                           Twine(LoadCommandIndex) + " extends past the end of "
560                           "the file");
561   BigSize = Dysymtab.nextrel;
562   BigSize *= sizeof(MachO::relocation_info);
563   BigSize += Dysymtab.extreloff;
564   if (BigSize > FileSize)
565     return malformedError("extreloff field plus nextrel field times sizeof"
566                           "(struct relocation_info) of LC_DYSYMTAB command " +
567                           Twine(LoadCommandIndex) + " extends past the end of "
568                           "the file");
569   if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff,
570                                           Dysymtab.nextrel *
571                                               sizeof(MachO::relocation_info),
572                                           "external relocation table"))
573     return Err;
574   if (Dysymtab.locreloff > FileSize)
575     return malformedError("locreloff field of LC_DYSYMTAB command " +
576                           Twine(LoadCommandIndex) + " extends past the end of "
577                           "the file");
578   BigSize = Dysymtab.nlocrel;
579   BigSize *= sizeof(MachO::relocation_info);
580   BigSize += Dysymtab.locreloff;
581   if (BigSize > FileSize)
582     return malformedError("locreloff field plus nlocrel field times sizeof"
583                           "(struct relocation_info) of LC_DYSYMTAB command " +
584                           Twine(LoadCommandIndex) + " extends past the end of "
585                           "the file");
586   if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff,
587                                           Dysymtab.nlocrel *
588                                               sizeof(MachO::relocation_info),
589                                           "local relocation table"))
590     return Err;
591   *DysymtabLoadCmd = Load.Ptr;
592   return Error::success();
593 }
594 
595 static Error checkLinkeditDataCommand(const MachOObjectFile &Obj,
596                                  const MachOObjectFile::LoadCommandInfo &Load,
597                                  uint32_t LoadCommandIndex,
598                                  const char **LoadCmd, const char *CmdName,
599                                  std::list<MachOElement> &Elements,
600                                  const char *ElementName) {
601   if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command))
602     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
603                           CmdName + " cmdsize too small");
604   if (*LoadCmd != nullptr)
605     return malformedError("more than one " + Twine(CmdName) + " command");
606   auto LinkDataOrError =
607     getStructOrErr<MachO::linkedit_data_command>(Obj, Load.Ptr);
608   if (!LinkDataOrError)
609     return LinkDataOrError.takeError();
610   MachO::linkedit_data_command LinkData = LinkDataOrError.get();
611   if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command))
612     return malformedError(Twine(CmdName) + " command " +
613                           Twine(LoadCommandIndex) + " has incorrect cmdsize");
614   uint64_t FileSize = Obj.getData().size();
615   if (LinkData.dataoff > FileSize)
616     return malformedError("dataoff field of " + Twine(CmdName) + " command " +
617                           Twine(LoadCommandIndex) + " extends past the end of "
618                           "the file");
619   uint64_t BigSize = LinkData.dataoff;
620   BigSize += LinkData.datasize;
621   if (BigSize > FileSize)
622     return malformedError("dataoff field plus datasize field of " +
623                           Twine(CmdName) + " command " +
624                           Twine(LoadCommandIndex) + " extends past the end of "
625                           "the file");
626   if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff,
627                                           LinkData.datasize, ElementName))
628     return Err;
629   *LoadCmd = Load.Ptr;
630   return Error::success();
631 }
632 
633 static Error checkDyldInfoCommand(const MachOObjectFile &Obj,
634                                   const MachOObjectFile::LoadCommandInfo &Load,
635                                   uint32_t LoadCommandIndex,
636                                   const char **LoadCmd, const char *CmdName,
637                                   std::list<MachOElement> &Elements) {
638   if (Load.C.cmdsize < sizeof(MachO::dyld_info_command))
639     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
640                           CmdName + " cmdsize too small");
641   if (*LoadCmd != nullptr)
642     return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
643                           "command");
644   auto DyldInfoOrErr =
645     getStructOrErr<MachO::dyld_info_command>(Obj, Load.Ptr);
646   if (!DyldInfoOrErr)
647     return DyldInfoOrErr.takeError();
648   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
649   if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command))
650     return malformedError(Twine(CmdName) + " command " +
651                           Twine(LoadCommandIndex) + " has incorrect cmdsize");
652   uint64_t FileSize = Obj.getData().size();
653   if (DyldInfo.rebase_off > FileSize)
654     return malformedError("rebase_off field of " + Twine(CmdName) +
655                           " command " + Twine(LoadCommandIndex) + " extends "
656                           "past the end of the file");
657   uint64_t BigSize = DyldInfo.rebase_off;
658   BigSize += DyldInfo.rebase_size;
659   if (BigSize > FileSize)
660     return malformedError("rebase_off field plus rebase_size field of " +
661                           Twine(CmdName) + " command " +
662                           Twine(LoadCommandIndex) + " extends past the end of "
663                           "the file");
664   if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off,
665                                           DyldInfo.rebase_size,
666                                           "dyld rebase info"))
667     return Err;
668   if (DyldInfo.bind_off > FileSize)
669     return malformedError("bind_off field of " + Twine(CmdName) +
670                           " command " + Twine(LoadCommandIndex) + " extends "
671                           "past the end of the file");
672   BigSize = DyldInfo.bind_off;
673   BigSize += DyldInfo.bind_size;
674   if (BigSize > FileSize)
675     return malformedError("bind_off field plus bind_size field of " +
676                           Twine(CmdName) + " command " +
677                           Twine(LoadCommandIndex) + " extends past the end of "
678                           "the file");
679   if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off,
680                                           DyldInfo.bind_size,
681                                           "dyld bind info"))
682     return Err;
683   if (DyldInfo.weak_bind_off > FileSize)
684     return malformedError("weak_bind_off field of " + Twine(CmdName) +
685                           " command " + Twine(LoadCommandIndex) + " extends "
686                           "past the end of the file");
687   BigSize = DyldInfo.weak_bind_off;
688   BigSize += DyldInfo.weak_bind_size;
689   if (BigSize > FileSize)
690     return malformedError("weak_bind_off field plus weak_bind_size field of " +
691                           Twine(CmdName) + " command " +
692                           Twine(LoadCommandIndex) + " extends past the end of "
693                           "the file");
694   if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off,
695                                           DyldInfo.weak_bind_size,
696                                           "dyld weak bind info"))
697     return Err;
698   if (DyldInfo.lazy_bind_off > FileSize)
699     return malformedError("lazy_bind_off field of " + Twine(CmdName) +
700                           " command " + Twine(LoadCommandIndex) + " extends "
701                           "past the end of the file");
702   BigSize = DyldInfo.lazy_bind_off;
703   BigSize += DyldInfo.lazy_bind_size;
704   if (BigSize > FileSize)
705     return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
706                           Twine(CmdName) + " command " +
707                           Twine(LoadCommandIndex) + " extends past the end of "
708                           "the file");
709   if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off,
710                                           DyldInfo.lazy_bind_size,
711                                           "dyld lazy bind info"))
712     return Err;
713   if (DyldInfo.export_off > FileSize)
714     return malformedError("export_off field of " + Twine(CmdName) +
715                           " command " + Twine(LoadCommandIndex) + " extends "
716                           "past the end of the file");
717   BigSize = DyldInfo.export_off;
718   BigSize += DyldInfo.export_size;
719   if (BigSize > FileSize)
720     return malformedError("export_off field plus export_size field of " +
721                           Twine(CmdName) + " command " +
722                           Twine(LoadCommandIndex) + " extends past the end of "
723                           "the file");
724   if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off,
725                                           DyldInfo.export_size,
726                                           "dyld export info"))
727     return Err;
728   *LoadCmd = Load.Ptr;
729   return Error::success();
730 }
731 
732 static Error checkDylibCommand(const MachOObjectFile &Obj,
733                                const MachOObjectFile::LoadCommandInfo &Load,
734                                uint32_t LoadCommandIndex, const char *CmdName) {
735   if (Load.C.cmdsize < sizeof(MachO::dylib_command))
736     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
737                           CmdName + " cmdsize too small");
738   auto CommandOrErr = getStructOrErr<MachO::dylib_command>(Obj, Load.Ptr);
739   if (!CommandOrErr)
740     return CommandOrErr.takeError();
741   MachO::dylib_command D = CommandOrErr.get();
742   if (D.dylib.name < sizeof(MachO::dylib_command))
743     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
744                           CmdName + " name.offset field too small, not past "
745                           "the end of the dylib_command struct");
746   if (D.dylib.name >= D.cmdsize)
747     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
748                           CmdName + " name.offset field extends past the end "
749                           "of the load command");
750   // Make sure there is a null between the starting offset of the name and
751   // the end of the load command.
752   uint32_t i;
753   const char *P = (const char *)Load.Ptr;
754   for (i = D.dylib.name; i < D.cmdsize; i++)
755     if (P[i] == '\0')
756       break;
757   if (i >= D.cmdsize)
758     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
759                           CmdName + " library name extends past the end of the "
760                           "load command");
761   return Error::success();
762 }
763 
764 static Error checkDylibIdCommand(const MachOObjectFile &Obj,
765                                  const MachOObjectFile::LoadCommandInfo &Load,
766                                  uint32_t LoadCommandIndex,
767                                  const char **LoadCmd) {
768   if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex,
769                                      "LC_ID_DYLIB"))
770     return Err;
771   if (*LoadCmd != nullptr)
772     return malformedError("more than one LC_ID_DYLIB command");
773   if (Obj.getHeader().filetype != MachO::MH_DYLIB &&
774       Obj.getHeader().filetype != MachO::MH_DYLIB_STUB)
775     return malformedError("LC_ID_DYLIB load command in non-dynamic library "
776                           "file type");
777   *LoadCmd = Load.Ptr;
778   return Error::success();
779 }
780 
781 static Error checkDyldCommand(const MachOObjectFile &Obj,
782                               const MachOObjectFile::LoadCommandInfo &Load,
783                               uint32_t LoadCommandIndex, const char *CmdName) {
784   if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
785     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
786                           CmdName + " cmdsize too small");
787   auto CommandOrErr = getStructOrErr<MachO::dylinker_command>(Obj, Load.Ptr);
788   if (!CommandOrErr)
789     return CommandOrErr.takeError();
790   MachO::dylinker_command D = CommandOrErr.get();
791   if (D.name < sizeof(MachO::dylinker_command))
792     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
793                           CmdName + " name.offset field too small, not past "
794                           "the end of the dylinker_command struct");
795   if (D.name >= D.cmdsize)
796     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
797                           CmdName + " name.offset field extends past the end "
798                           "of the load command");
799   // Make sure there is a null between the starting offset of the name and
800   // the end of the load command.
801   uint32_t i;
802   const char *P = (const char *)Load.Ptr;
803   for (i = D.name; i < D.cmdsize; i++)
804     if (P[i] == '\0')
805       break;
806   if (i >= D.cmdsize)
807     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
808                           CmdName + " dyld name extends past the end of the "
809                           "load command");
810   return Error::success();
811 }
812 
813 static Error checkVersCommand(const MachOObjectFile &Obj,
814                               const MachOObjectFile::LoadCommandInfo &Load,
815                               uint32_t LoadCommandIndex,
816                               const char **LoadCmd, const char *CmdName) {
817   if (Load.C.cmdsize != sizeof(MachO::version_min_command))
818     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
819                           CmdName + " has incorrect cmdsize");
820   if (*LoadCmd != nullptr)
821     return malformedError("more than one LC_VERSION_MIN_MACOSX, "
822                           "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
823                           "LC_VERSION_MIN_WATCHOS command");
824   *LoadCmd = Load.Ptr;
825   return Error::success();
826 }
827 
828 static Error checkNoteCommand(const MachOObjectFile &Obj,
829                               const MachOObjectFile::LoadCommandInfo &Load,
830                               uint32_t LoadCommandIndex,
831                               std::list<MachOElement> &Elements) {
832   if (Load.C.cmdsize != sizeof(MachO::note_command))
833     return malformedError("load command " + Twine(LoadCommandIndex) +
834                           " LC_NOTE has incorrect cmdsize");
835   auto NoteCmdOrErr = getStructOrErr<MachO::note_command>(Obj, Load.Ptr);
836   if (!NoteCmdOrErr)
837     return NoteCmdOrErr.takeError();
838   MachO::note_command Nt = NoteCmdOrErr.get();
839   uint64_t FileSize = Obj.getData().size();
840   if (Nt.offset > FileSize)
841     return malformedError("offset field of LC_NOTE command " +
842                           Twine(LoadCommandIndex) + " extends "
843                           "past the end of the file");
844   uint64_t BigSize = Nt.offset;
845   BigSize += Nt.size;
846   if (BigSize > FileSize)
847     return malformedError("size field plus offset field of LC_NOTE command " +
848                           Twine(LoadCommandIndex) + " extends past the end of "
849                           "the file");
850   if (Error Err = checkOverlappingElement(Elements, Nt.offset, Nt.size,
851                                           "LC_NOTE data"))
852     return Err;
853   return Error::success();
854 }
855 
856 static Error
857 parseBuildVersionCommand(const MachOObjectFile &Obj,
858                          const MachOObjectFile::LoadCommandInfo &Load,
859                          SmallVectorImpl<const char*> &BuildTools,
860                          uint32_t LoadCommandIndex) {
861   auto BVCOrErr =
862     getStructOrErr<MachO::build_version_command>(Obj, Load.Ptr);
863   if (!BVCOrErr)
864     return BVCOrErr.takeError();
865   MachO::build_version_command BVC = BVCOrErr.get();
866   if (Load.C.cmdsize !=
867       sizeof(MachO::build_version_command) +
868           BVC.ntools * sizeof(MachO::build_tool_version))
869     return malformedError("load command " + Twine(LoadCommandIndex) +
870                           " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
871 
872   auto Start = Load.Ptr + sizeof(MachO::build_version_command);
873   BuildTools.resize(BVC.ntools);
874   for (unsigned i = 0; i < BVC.ntools; ++i)
875     BuildTools[i] = Start + i * sizeof(MachO::build_tool_version);
876 
877   return Error::success();
878 }
879 
880 static Error checkRpathCommand(const MachOObjectFile &Obj,
881                                const MachOObjectFile::LoadCommandInfo &Load,
882                                uint32_t LoadCommandIndex) {
883   if (Load.C.cmdsize < sizeof(MachO::rpath_command))
884     return malformedError("load command " + Twine(LoadCommandIndex) +
885                           " LC_RPATH cmdsize too small");
886   auto ROrErr = getStructOrErr<MachO::rpath_command>(Obj, Load.Ptr);
887   if (!ROrErr)
888     return ROrErr.takeError();
889   MachO::rpath_command R = ROrErr.get();
890   if (R.path < sizeof(MachO::rpath_command))
891     return malformedError("load command " + Twine(LoadCommandIndex) +
892                           " LC_RPATH path.offset field too small, not past "
893                           "the end of the rpath_command struct");
894   if (R.path >= R.cmdsize)
895     return malformedError("load command " + Twine(LoadCommandIndex) +
896                           " LC_RPATH path.offset field extends past the end "
897                           "of the load command");
898   // Make sure there is a null between the starting offset of the path and
899   // the end of the load command.
900   uint32_t i;
901   const char *P = (const char *)Load.Ptr;
902   for (i = R.path; i < R.cmdsize; i++)
903     if (P[i] == '\0')
904       break;
905   if (i >= R.cmdsize)
906     return malformedError("load command " + Twine(LoadCommandIndex) +
907                           " LC_RPATH library name extends past the end of the "
908                           "load command");
909   return Error::success();
910 }
911 
912 static Error checkEncryptCommand(const MachOObjectFile &Obj,
913                                  const MachOObjectFile::LoadCommandInfo &Load,
914                                  uint32_t LoadCommandIndex,
915                                  uint64_t cryptoff, uint64_t cryptsize,
916                                  const char **LoadCmd, const char *CmdName) {
917   if (*LoadCmd != nullptr)
918     return malformedError("more than one LC_ENCRYPTION_INFO and or "
919                           "LC_ENCRYPTION_INFO_64 command");
920   uint64_t FileSize = Obj.getData().size();
921   if (cryptoff > FileSize)
922     return malformedError("cryptoff field of " + Twine(CmdName) +
923                           " command " + Twine(LoadCommandIndex) + " extends "
924                           "past the end of the file");
925   uint64_t BigSize = cryptoff;
926   BigSize += cryptsize;
927   if (BigSize > FileSize)
928     return malformedError("cryptoff field plus cryptsize field of " +
929                           Twine(CmdName) + " command " +
930                           Twine(LoadCommandIndex) + " extends past the end of "
931                           "the file");
932   *LoadCmd = Load.Ptr;
933   return Error::success();
934 }
935 
936 static Error checkLinkerOptCommand(const MachOObjectFile &Obj,
937                                    const MachOObjectFile::LoadCommandInfo &Load,
938                                    uint32_t LoadCommandIndex) {
939   if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
940     return malformedError("load command " + Twine(LoadCommandIndex) +
941                           " LC_LINKER_OPTION cmdsize too small");
942   auto LinkOptionOrErr =
943     getStructOrErr<MachO::linker_option_command>(Obj, Load.Ptr);
944   if (!LinkOptionOrErr)
945     return LinkOptionOrErr.takeError();
946   MachO::linker_option_command L = LinkOptionOrErr.get();
947   // Make sure the count of strings is correct.
948   const char *string = (const char *)Load.Ptr +
949                        sizeof(struct MachO::linker_option_command);
950   uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
951   uint32_t i = 0;
952   while (left > 0) {
953     while (*string == '\0' && left > 0) {
954       string++;
955       left--;
956     }
957     if (left > 0) {
958       i++;
959       uint32_t NullPos = StringRef(string, left).find('\0');
960       if (0xffffffff == NullPos)
961         return malformedError("load command " + Twine(LoadCommandIndex) +
962                               " LC_LINKER_OPTION string #" + Twine(i) +
963                               " is not NULL terminated");
964       uint32_t len = std::min(NullPos, left) + 1;
965       string += len;
966       left -= len;
967     }
968   }
969   if (L.count != i)
970     return malformedError("load command " + Twine(LoadCommandIndex) +
971                           " LC_LINKER_OPTION string count " + Twine(L.count) +
972                           " does not match number of strings");
973   return Error::success();
974 }
975 
976 static Error checkSubCommand(const MachOObjectFile &Obj,
977                              const MachOObjectFile::LoadCommandInfo &Load,
978                              uint32_t LoadCommandIndex, const char *CmdName,
979                              size_t SizeOfCmd, const char *CmdStructName,
980                              uint32_t PathOffset, const char *PathFieldName) {
981   if (PathOffset < SizeOfCmd)
982     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
983                           CmdName + " " + PathFieldName + ".offset field too "
984                           "small, not past the end of the " + CmdStructName);
985   if (PathOffset >= Load.C.cmdsize)
986     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
987                           CmdName + " " + PathFieldName + ".offset field "
988                           "extends past the end of the load command");
989   // Make sure there is a null between the starting offset of the path and
990   // the end of the load command.
991   uint32_t i;
992   const char *P = (const char *)Load.Ptr;
993   for (i = PathOffset; i < Load.C.cmdsize; i++)
994     if (P[i] == '\0')
995       break;
996   if (i >= Load.C.cmdsize)
997     return malformedError("load command " + Twine(LoadCommandIndex) + " " +
998                           CmdName + " " + PathFieldName + " name extends past "
999                           "the end of the load command");
1000   return Error::success();
1001 }
1002 
1003 static Error checkThreadCommand(const MachOObjectFile &Obj,
1004                                 const MachOObjectFile::LoadCommandInfo &Load,
1005                                 uint32_t LoadCommandIndex,
1006                                 const char *CmdName) {
1007   if (Load.C.cmdsize < sizeof(MachO::thread_command))
1008     return malformedError("load command " + Twine(LoadCommandIndex) +
1009                           CmdName + " cmdsize too small");
1010   auto ThreadCommandOrErr =
1011     getStructOrErr<MachO::thread_command>(Obj, Load.Ptr);
1012   if (!ThreadCommandOrErr)
1013     return ThreadCommandOrErr.takeError();
1014   MachO::thread_command T = ThreadCommandOrErr.get();
1015   const char *state = Load.Ptr + sizeof(MachO::thread_command);
1016   const char *end = Load.Ptr + T.cmdsize;
1017   uint32_t nflavor = 0;
1018   uint32_t cputype = getCPUType(Obj);
1019   while (state < end) {
1020     if(state + sizeof(uint32_t) > end)
1021       return malformedError("load command " + Twine(LoadCommandIndex) +
1022                             "flavor in " + CmdName + " extends past end of "
1023                             "command");
1024     uint32_t flavor;
1025     memcpy(&flavor, state, sizeof(uint32_t));
1026     if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
1027       sys::swapByteOrder(flavor);
1028     state += sizeof(uint32_t);
1029 
1030     if(state + sizeof(uint32_t) > end)
1031       return malformedError("load command " + Twine(LoadCommandIndex) +
1032                             " count in " + CmdName + " extends past end of "
1033                             "command");
1034     uint32_t count;
1035     memcpy(&count, state, sizeof(uint32_t));
1036     if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
1037       sys::swapByteOrder(count);
1038     state += sizeof(uint32_t);
1039 
1040     if (cputype == MachO::CPU_TYPE_I386) {
1041       if (flavor == MachO::x86_THREAD_STATE32) {
1042         if (count != MachO::x86_THREAD_STATE32_COUNT)
1043           return malformedError("load command " + Twine(LoadCommandIndex) +
1044                                 " count not x86_THREAD_STATE32_COUNT for "
1045                                 "flavor number " + Twine(nflavor) + " which is "
1046                                 "a x86_THREAD_STATE32 flavor in " + CmdName +
1047                                 " command");
1048         if (state + sizeof(MachO::x86_thread_state32_t) > end)
1049           return malformedError("load command " + Twine(LoadCommandIndex) +
1050                                 " x86_THREAD_STATE32 extends past end of "
1051                                 "command in " + CmdName + " command");
1052         state += sizeof(MachO::x86_thread_state32_t);
1053       } else {
1054         return malformedError("load command " + Twine(LoadCommandIndex) +
1055                               " unknown flavor (" + Twine(flavor) + ") for "
1056                               "flavor number " + Twine(nflavor) + " in " +
1057                               CmdName + " command");
1058       }
1059     } else if (cputype == MachO::CPU_TYPE_X86_64) {
1060       if (flavor == MachO::x86_THREAD_STATE) {
1061         if (count != MachO::x86_THREAD_STATE_COUNT)
1062           return malformedError("load command " + Twine(LoadCommandIndex) +
1063                                 " count not x86_THREAD_STATE_COUNT for "
1064                                 "flavor number " + Twine(nflavor) + " which is "
1065                                 "a x86_THREAD_STATE flavor in " + CmdName +
1066                                 " command");
1067         if (state + sizeof(MachO::x86_thread_state_t) > end)
1068           return malformedError("load command " + Twine(LoadCommandIndex) +
1069                                 " x86_THREAD_STATE extends past end of "
1070                                 "command in " + CmdName + " command");
1071         state += sizeof(MachO::x86_thread_state_t);
1072       } else if (flavor == MachO::x86_FLOAT_STATE) {
1073         if (count != MachO::x86_FLOAT_STATE_COUNT)
1074           return malformedError("load command " + Twine(LoadCommandIndex) +
1075                                 " count not x86_FLOAT_STATE_COUNT for "
1076                                 "flavor number " + Twine(nflavor) + " which is "
1077                                 "a x86_FLOAT_STATE flavor in " + CmdName +
1078                                 " command");
1079         if (state + sizeof(MachO::x86_float_state_t) > end)
1080           return malformedError("load command " + Twine(LoadCommandIndex) +
1081                                 " x86_FLOAT_STATE extends past end of "
1082                                 "command in " + CmdName + " command");
1083         state += sizeof(MachO::x86_float_state_t);
1084       } else if (flavor == MachO::x86_EXCEPTION_STATE) {
1085         if (count != MachO::x86_EXCEPTION_STATE_COUNT)
1086           return malformedError("load command " + Twine(LoadCommandIndex) +
1087                                 " count not x86_EXCEPTION_STATE_COUNT for "
1088                                 "flavor number " + Twine(nflavor) + " which is "
1089                                 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1090                                 " command");
1091         if (state + sizeof(MachO::x86_exception_state_t) > end)
1092           return malformedError("load command " + Twine(LoadCommandIndex) +
1093                                 " x86_EXCEPTION_STATE extends past end of "
1094                                 "command in " + CmdName + " command");
1095         state += sizeof(MachO::x86_exception_state_t);
1096       } else if (flavor == MachO::x86_THREAD_STATE64) {
1097         if (count != MachO::x86_THREAD_STATE64_COUNT)
1098           return malformedError("load command " + Twine(LoadCommandIndex) +
1099                                 " count not x86_THREAD_STATE64_COUNT for "
1100                                 "flavor number " + Twine(nflavor) + " which is "
1101                                 "a x86_THREAD_STATE64 flavor in " + CmdName +
1102                                 " command");
1103         if (state + sizeof(MachO::x86_thread_state64_t) > end)
1104           return malformedError("load command " + Twine(LoadCommandIndex) +
1105                                 " x86_THREAD_STATE64 extends past end of "
1106                                 "command in " + CmdName + " command");
1107         state += sizeof(MachO::x86_thread_state64_t);
1108       } else if (flavor == MachO::x86_EXCEPTION_STATE64) {
1109         if (count != MachO::x86_EXCEPTION_STATE64_COUNT)
1110           return malformedError("load command " + Twine(LoadCommandIndex) +
1111                                 " count not x86_EXCEPTION_STATE64_COUNT for "
1112                                 "flavor number " + Twine(nflavor) + " which is "
1113                                 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1114                                 " command");
1115         if (state + sizeof(MachO::x86_exception_state64_t) > end)
1116           return malformedError("load command " + Twine(LoadCommandIndex) +
1117                                 " x86_EXCEPTION_STATE64 extends past end of "
1118                                 "command in " + CmdName + " command");
1119         state += sizeof(MachO::x86_exception_state64_t);
1120       } else {
1121         return malformedError("load command " + Twine(LoadCommandIndex) +
1122                               " unknown flavor (" + Twine(flavor) + ") for "
1123                               "flavor number " + Twine(nflavor) + " in " +
1124                               CmdName + " command");
1125       }
1126     } else if (cputype == MachO::CPU_TYPE_ARM) {
1127       if (flavor == MachO::ARM_THREAD_STATE) {
1128         if (count != MachO::ARM_THREAD_STATE_COUNT)
1129           return malformedError("load command " + Twine(LoadCommandIndex) +
1130                                 " count not ARM_THREAD_STATE_COUNT for "
1131                                 "flavor number " + Twine(nflavor) + " which is "
1132                                 "a ARM_THREAD_STATE flavor in " + CmdName +
1133                                 " command");
1134         if (state + sizeof(MachO::arm_thread_state32_t) > end)
1135           return malformedError("load command " + Twine(LoadCommandIndex) +
1136                                 " ARM_THREAD_STATE extends past end of "
1137                                 "command in " + CmdName + " command");
1138         state += sizeof(MachO::arm_thread_state32_t);
1139       } else {
1140         return malformedError("load command " + Twine(LoadCommandIndex) +
1141                               " unknown flavor (" + Twine(flavor) + ") for "
1142                               "flavor number " + Twine(nflavor) + " in " +
1143                               CmdName + " command");
1144       }
1145     } else if (cputype == MachO::CPU_TYPE_ARM64 ||
1146                cputype == MachO::CPU_TYPE_ARM64_32) {
1147       if (flavor == MachO::ARM_THREAD_STATE64) {
1148         if (count != MachO::ARM_THREAD_STATE64_COUNT)
1149           return malformedError("load command " + Twine(LoadCommandIndex) +
1150                                 " count not ARM_THREAD_STATE64_COUNT for "
1151                                 "flavor number " + Twine(nflavor) + " which is "
1152                                 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1153                                 " command");
1154         if (state + sizeof(MachO::arm_thread_state64_t) > end)
1155           return malformedError("load command " + Twine(LoadCommandIndex) +
1156                                 " ARM_THREAD_STATE64 extends past end of "
1157                                 "command in " + CmdName + " command");
1158         state += sizeof(MachO::arm_thread_state64_t);
1159       } else {
1160         return malformedError("load command " + Twine(LoadCommandIndex) +
1161                               " unknown flavor (" + Twine(flavor) + ") for "
1162                               "flavor number " + Twine(nflavor) + " in " +
1163                               CmdName + " command");
1164       }
1165     } else if (cputype == MachO::CPU_TYPE_POWERPC) {
1166       if (flavor == MachO::PPC_THREAD_STATE) {
1167         if (count != MachO::PPC_THREAD_STATE_COUNT)
1168           return malformedError("load command " + Twine(LoadCommandIndex) +
1169                                 " count not PPC_THREAD_STATE_COUNT for "
1170                                 "flavor number " + Twine(nflavor) + " which is "
1171                                 "a PPC_THREAD_STATE flavor in " + CmdName +
1172                                 " command");
1173         if (state + sizeof(MachO::ppc_thread_state32_t) > end)
1174           return malformedError("load command " + Twine(LoadCommandIndex) +
1175                                 " PPC_THREAD_STATE extends past end of "
1176                                 "command in " + CmdName + " command");
1177         state += sizeof(MachO::ppc_thread_state32_t);
1178       } else {
1179         return malformedError("load command " + Twine(LoadCommandIndex) +
1180                               " unknown flavor (" + Twine(flavor) + ") for "
1181                               "flavor number " + Twine(nflavor) + " in " +
1182                               CmdName + " command");
1183       }
1184     } else {
1185       return malformedError("unknown cputype (" + Twine(cputype) + ") load "
1186                             "command " + Twine(LoadCommandIndex) + " for " +
1187                             CmdName + " command can't be checked");
1188     }
1189     nflavor++;
1190   }
1191   return Error::success();
1192 }
1193 
1194 static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj,
1195                                        const MachOObjectFile::LoadCommandInfo
1196                                          &Load,
1197                                        uint32_t LoadCommandIndex,
1198                                        const char **LoadCmd,
1199                                        std::list<MachOElement> &Elements) {
1200   if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
1201     return malformedError("load command " + Twine(LoadCommandIndex) +
1202                           " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1203   if (*LoadCmd != nullptr)
1204     return malformedError("more than one LC_TWOLEVEL_HINTS command");
1205   auto HintsOrErr = getStructOrErr<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1206   if(!HintsOrErr)
1207     return HintsOrErr.takeError();
1208   MachO::twolevel_hints_command Hints = HintsOrErr.get();
1209   uint64_t FileSize = Obj.getData().size();
1210   if (Hints.offset > FileSize)
1211     return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1212                           Twine(LoadCommandIndex) + " extends past the end of "
1213                           "the file");
1214   uint64_t BigSize = Hints.nhints;
1215   BigSize *= sizeof(MachO::twolevel_hint);
1216   BigSize += Hints.offset;
1217   if (BigSize > FileSize)
1218     return malformedError("offset field plus nhints times sizeof(struct "
1219                           "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1220                           Twine(LoadCommandIndex) + " extends past the end of "
1221                           "the file");
1222   if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
1223                                           sizeof(MachO::twolevel_hint),
1224                                           "two level hints"))
1225     return Err;
1226   *LoadCmd = Load.Ptr;
1227   return Error::success();
1228 }
1229 
1230 // Returns true if the libObject code does not support the load command and its
1231 // contents.  The cmd value it is treated as an unknown load command but with
1232 // an error message that says the cmd value is obsolete.
1233 static bool isLoadCommandObsolete(uint32_t cmd) {
1234   if (cmd == MachO::LC_SYMSEG ||
1235       cmd == MachO::LC_LOADFVMLIB ||
1236       cmd == MachO::LC_IDFVMLIB ||
1237       cmd == MachO::LC_IDENT ||
1238       cmd == MachO::LC_FVMFILE ||
1239       cmd == MachO::LC_PREPAGE ||
1240       cmd == MachO::LC_PREBOUND_DYLIB ||
1241       cmd == MachO::LC_TWOLEVEL_HINTS ||
1242       cmd == MachO::LC_PREBIND_CKSUM)
1243     return true;
1244   return false;
1245 }
1246 
1247 Expected<std::unique_ptr<MachOObjectFile>>
1248 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
1249                         bool Is64Bits, uint32_t UniversalCputype,
1250                         uint32_t UniversalIndex) {
1251   Error Err = Error::success();
1252   std::unique_ptr<MachOObjectFile> Obj(
1253       new MachOObjectFile(std::move(Object), IsLittleEndian,
1254                           Is64Bits, Err, UniversalCputype,
1255                           UniversalIndex));
1256   if (Err)
1257     return std::move(Err);
1258   return std::move(Obj);
1259 }
1260 
1261 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1262                                  bool Is64bits, Error &Err,
1263                                  uint32_t UniversalCputype,
1264                                  uint32_t UniversalIndex)
1265     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
1266   ErrorAsOutParameter ErrAsOutParam(&Err);
1267   uint64_t SizeOfHeaders;
1268   uint32_t cputype;
1269   if (is64Bit()) {
1270     parseHeader(*this, Header64, Err);
1271     SizeOfHeaders = sizeof(MachO::mach_header_64);
1272     cputype = Header64.cputype;
1273   } else {
1274     parseHeader(*this, Header, Err);
1275     SizeOfHeaders = sizeof(MachO::mach_header);
1276     cputype = Header.cputype;
1277   }
1278   if (Err)
1279     return;
1280   SizeOfHeaders += getHeader().sizeofcmds;
1281   if (getData().data() + SizeOfHeaders > getData().end()) {
1282     Err = malformedError("load commands extend past the end of the file");
1283     return;
1284   }
1285   if (UniversalCputype != 0 && cputype != UniversalCputype) {
1286     Err = malformedError("universal header architecture: " +
1287                          Twine(UniversalIndex) + "'s cputype does not match "
1288                          "object file's mach header");
1289     return;
1290   }
1291   std::list<MachOElement> Elements;
1292   Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1293 
1294   uint32_t LoadCommandCount = getHeader().ncmds;
1295   LoadCommandInfo Load;
1296   if (LoadCommandCount != 0) {
1297     if (auto LoadOrErr = getFirstLoadCommandInfo(*this))
1298       Load = *LoadOrErr;
1299     else {
1300       Err = LoadOrErr.takeError();
1301       return;
1302     }
1303   }
1304 
1305   const char *DyldIdLoadCmd = nullptr;
1306   const char *SplitInfoLoadCmd = nullptr;
1307   const char *CodeSignDrsLoadCmd = nullptr;
1308   const char *CodeSignLoadCmd = nullptr;
1309   const char *VersLoadCmd = nullptr;
1310   const char *SourceLoadCmd = nullptr;
1311   const char *EntryPointLoadCmd = nullptr;
1312   const char *EncryptLoadCmd = nullptr;
1313   const char *RoutinesLoadCmd = nullptr;
1314   const char *UnixThreadLoadCmd = nullptr;
1315   const char *TwoLevelHintsLoadCmd = nullptr;
1316   for (unsigned I = 0; I < LoadCommandCount; ++I) {
1317     if (is64Bit()) {
1318       if (Load.C.cmdsize % 8 != 0) {
1319         // We have a hack here to allow 64-bit Mach-O core files to have
1320         // LC_THREAD commands that are only a multiple of 4 and not 8 to be
1321         // allowed since the macOS kernel produces them.
1322         if (getHeader().filetype != MachO::MH_CORE ||
1323             Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1324           Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1325                                "multiple of 8");
1326           return;
1327         }
1328       }
1329     } else {
1330       if (Load.C.cmdsize % 4 != 0) {
1331         Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1332                              "multiple of 4");
1333         return;
1334       }
1335     }
1336     LoadCommands.push_back(Load);
1337     if (Load.C.cmd == MachO::LC_SYMTAB) {
1338       if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1339         return;
1340     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1341       if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd,
1342                                       Elements)))
1343         return;
1344     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1345       if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd,
1346                                           "LC_DATA_IN_CODE", Elements,
1347                                           "data in code info")))
1348         return;
1349     } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1350       if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd,
1351                                           "LC_LINKER_OPTIMIZATION_HINT",
1352                                           Elements, "linker optimization "
1353                                           "hints")))
1354         return;
1355     } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1356       if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd,
1357                                           "LC_FUNCTION_STARTS", Elements,
1358                                           "function starts data")))
1359         return;
1360     } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1361       if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd,
1362                                           "LC_SEGMENT_SPLIT_INFO", Elements,
1363                                           "split info data")))
1364         return;
1365     } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1366       if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd,
1367                                           "LC_DYLIB_CODE_SIGN_DRS", Elements,
1368                                           "code signing RDs data")))
1369         return;
1370     } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1371       if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd,
1372                                           "LC_CODE_SIGNATURE", Elements,
1373                                           "code signature data")))
1374         return;
1375     } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1376       if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1377                                       "LC_DYLD_INFO", Elements)))
1378         return;
1379     } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1380       if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1381                                       "LC_DYLD_INFO_ONLY", Elements)))
1382         return;
1383     } else if (Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1384       if ((Err = checkLinkeditDataCommand(
1385                *this, Load, I, &DyldChainedFixupsLoadCmd,
1386                "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))
1387         return;
1388     } else if (Load.C.cmd == MachO::LC_UUID) {
1389       if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1390         Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1391                              "cmdsize");
1392         return;
1393       }
1394       if (UuidLoadCmd) {
1395         Err = malformedError("more than one LC_UUID command");
1396         return;
1397       }
1398       UuidLoadCmd = Load.Ptr;
1399     } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1400       if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
1401                                          MachO::section_64>(
1402                    *this, Load, Sections, HasPageZeroSegment, I,
1403                    "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1404         return;
1405     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1406       if ((Err = parseSegmentLoadCommand<MachO::segment_command,
1407                                          MachO::section>(
1408                    *this, Load, Sections, HasPageZeroSegment, I,
1409                    "LC_SEGMENT", SizeOfHeaders, Elements)))
1410         return;
1411     } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1412       if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1413         return;
1414     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1415       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1416         return;
1417       Libraries.push_back(Load.Ptr);
1418     } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1419       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1420         return;
1421       Libraries.push_back(Load.Ptr);
1422     } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1423       if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1424         return;
1425       Libraries.push_back(Load.Ptr);
1426     } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1427       if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1428         return;
1429       Libraries.push_back(Load.Ptr);
1430     } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1431       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1432         return;
1433       Libraries.push_back(Load.Ptr);
1434     } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1435       if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1436         return;
1437     } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1438       if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1439         return;
1440     } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1441       if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1442         return;
1443     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1444       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1445                                   "LC_VERSION_MIN_MACOSX")))
1446         return;
1447     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1448       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1449                                   "LC_VERSION_MIN_IPHONEOS")))
1450         return;
1451     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1452       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1453                                   "LC_VERSION_MIN_TVOS")))
1454         return;
1455     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1456       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1457                                   "LC_VERSION_MIN_WATCHOS")))
1458         return;
1459     } else if (Load.C.cmd == MachO::LC_NOTE) {
1460       if ((Err = checkNoteCommand(*this, Load, I, Elements)))
1461         return;
1462     } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1463       if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
1464         return;
1465     } else if (Load.C.cmd == MachO::LC_RPATH) {
1466       if ((Err = checkRpathCommand(*this, Load, I)))
1467         return;
1468     } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1469       if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1470         Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1471                              " has incorrect cmdsize");
1472         return;
1473       }
1474       if (SourceLoadCmd) {
1475         Err = malformedError("more than one LC_SOURCE_VERSION command");
1476         return;
1477       }
1478       SourceLoadCmd = Load.Ptr;
1479     } else if (Load.C.cmd == MachO::LC_MAIN) {
1480       if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1481         Err = malformedError("LC_MAIN command " + Twine(I) +
1482                              " has incorrect cmdsize");
1483         return;
1484       }
1485       if (EntryPointLoadCmd) {
1486         Err = malformedError("more than one LC_MAIN command");
1487         return;
1488       }
1489       EntryPointLoadCmd = Load.Ptr;
1490     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1491       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1492         Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1493                              " has incorrect cmdsize");
1494         return;
1495       }
1496       MachO::encryption_info_command E =
1497         getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1498       if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1499                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1500         return;
1501     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1502       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1503         Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1504                              " has incorrect cmdsize");
1505         return;
1506       }
1507       MachO::encryption_info_command_64 E =
1508         getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1509       if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1510                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1511         return;
1512     } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1513       if ((Err = checkLinkerOptCommand(*this, Load, I)))
1514         return;
1515     } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1516       if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1517         Err =  malformedError("load command " + Twine(I) +
1518                               " LC_SUB_FRAMEWORK cmdsize too small");
1519         return;
1520       }
1521       MachO::sub_framework_command S =
1522         getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1523       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1524                                  sizeof(MachO::sub_framework_command),
1525                                  "sub_framework_command", S.umbrella,
1526                                  "umbrella")))
1527         return;
1528     } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1529       if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1530         Err =  malformedError("load command " + Twine(I) +
1531                               " LC_SUB_UMBRELLA cmdsize too small");
1532         return;
1533       }
1534       MachO::sub_umbrella_command S =
1535         getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1536       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1537                                  sizeof(MachO::sub_umbrella_command),
1538                                  "sub_umbrella_command", S.sub_umbrella,
1539                                  "sub_umbrella")))
1540         return;
1541     } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1542       if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1543         Err =  malformedError("load command " + Twine(I) +
1544                               " LC_SUB_LIBRARY cmdsize too small");
1545         return;
1546       }
1547       MachO::sub_library_command S =
1548         getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1549       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1550                                  sizeof(MachO::sub_library_command),
1551                                  "sub_library_command", S.sub_library,
1552                                  "sub_library")))
1553         return;
1554     } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1555       if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1556         Err =  malformedError("load command " + Twine(I) +
1557                               " LC_SUB_CLIENT cmdsize too small");
1558         return;
1559       }
1560       MachO::sub_client_command S =
1561         getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1562       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1563                                  sizeof(MachO::sub_client_command),
1564                                  "sub_client_command", S.client, "client")))
1565         return;
1566     } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1567       if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1568         Err = malformedError("LC_ROUTINES command " + Twine(I) +
1569                              " has incorrect cmdsize");
1570         return;
1571       }
1572       if (RoutinesLoadCmd) {
1573         Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1574                              "command");
1575         return;
1576       }
1577       RoutinesLoadCmd = Load.Ptr;
1578     } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1579       if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1580         Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1581                              " has incorrect cmdsize");
1582         return;
1583       }
1584       if (RoutinesLoadCmd) {
1585         Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1586                              "command");
1587         return;
1588       }
1589       RoutinesLoadCmd = Load.Ptr;
1590     } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1591       if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1592         return;
1593       if (UnixThreadLoadCmd) {
1594         Err = malformedError("more than one LC_UNIXTHREAD command");
1595         return;
1596       }
1597       UnixThreadLoadCmd = Load.Ptr;
1598     } else if (Load.C.cmd == MachO::LC_THREAD) {
1599       if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1600         return;
1601     // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1602     } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1603       if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1604                                            &TwoLevelHintsLoadCmd, Elements)))
1605         return;
1606     } else if (Load.C.cmd == MachO::LC_IDENT) {
1607       // Note: LC_IDENT is ignored.
1608       continue;
1609     } else if (isLoadCommandObsolete(Load.C.cmd)) {
1610       Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1611                            Twine(Load.C.cmd) + " is obsolete and not "
1612                            "supported");
1613       return;
1614     }
1615     // TODO: generate a error for unknown load commands by default.  But still
1616     // need work out an approach to allow or not allow unknown values like this
1617     // as an option for some uses like lldb.
1618     if (I < LoadCommandCount - 1) {
1619       if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1620         Load = *LoadOrErr;
1621       else {
1622         Err = LoadOrErr.takeError();
1623         return;
1624       }
1625     }
1626   }
1627   if (!SymtabLoadCmd) {
1628     if (DysymtabLoadCmd) {
1629       Err = malformedError("contains LC_DYSYMTAB load command without a "
1630                            "LC_SYMTAB load command");
1631       return;
1632     }
1633   } else if (DysymtabLoadCmd) {
1634     MachO::symtab_command Symtab =
1635       getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1636     MachO::dysymtab_command Dysymtab =
1637       getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1638     if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1639       Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1640                            "extends past the end of the symbol table");
1641       return;
1642     }
1643     uint64_t BigSize = Dysymtab.ilocalsym;
1644     BigSize += Dysymtab.nlocalsym;
1645     if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1646       Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1647                            "command extends past the end of the symbol table");
1648       return;
1649     }
1650     if (Dysymtab.nextdefsym != 0 && Dysymtab.iextdefsym > Symtab.nsyms) {
1651       Err = malformedError("iextdefsym in LC_DYSYMTAB load command "
1652                            "extends past the end of the symbol table");
1653       return;
1654     }
1655     BigSize = Dysymtab.iextdefsym;
1656     BigSize += Dysymtab.nextdefsym;
1657     if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1658       Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1659                            "load command extends past the end of the symbol "
1660                            "table");
1661       return;
1662     }
1663     if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1664       Err = malformedError("iundefsym in LC_DYSYMTAB load command "
1665                            "extends past the end of the symbol table");
1666       return;
1667     }
1668     BigSize = Dysymtab.iundefsym;
1669     BigSize += Dysymtab.nundefsym;
1670     if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1671       Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1672                            " command extends past the end of the symbol table");
1673       return;
1674     }
1675   }
1676   if ((getHeader().filetype == MachO::MH_DYLIB ||
1677        getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1678        DyldIdLoadCmd == nullptr) {
1679     Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1680                          "filetype");
1681     return;
1682   }
1683   assert(LoadCommands.size() == LoadCommandCount);
1684 
1685   Err = Error::success();
1686 }
1687 
1688 Error MachOObjectFile::checkSymbolTable() const {
1689   uint32_t Flags = 0;
1690   if (is64Bit()) {
1691     MachO::mach_header_64 H_64 = MachOObjectFile::getHeader64();
1692     Flags = H_64.flags;
1693   } else {
1694     MachO::mach_header H = MachOObjectFile::getHeader();
1695     Flags = H.flags;
1696   }
1697   uint8_t NType = 0;
1698   uint8_t NSect = 0;
1699   uint16_t NDesc = 0;
1700   uint32_t NStrx = 0;
1701   uint64_t NValue = 0;
1702   uint32_t SymbolIndex = 0;
1703   MachO::symtab_command S = getSymtabLoadCommand();
1704   for (const SymbolRef &Symbol : symbols()) {
1705     DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1706     if (is64Bit()) {
1707       MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1708       NType = STE_64.n_type;
1709       NSect = STE_64.n_sect;
1710       NDesc = STE_64.n_desc;
1711       NStrx = STE_64.n_strx;
1712       NValue = STE_64.n_value;
1713     } else {
1714       MachO::nlist STE = getSymbolTableEntry(SymDRI);
1715       NType = STE.n_type;
1716       NSect = STE.n_sect;
1717       NDesc = STE.n_desc;
1718       NStrx = STE.n_strx;
1719       NValue = STE.n_value;
1720     }
1721     if ((NType & MachO::N_STAB) == 0) {
1722       if ((NType & MachO::N_TYPE) == MachO::N_SECT) {
1723         if (NSect == 0 || NSect > Sections.size())
1724           return malformedError("bad section index: " + Twine((int)NSect) +
1725                                 " for symbol at index " + Twine(SymbolIndex));
1726       }
1727       if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
1728         if (NValue >= S.strsize)
1729           return malformedError("bad n_value: " + Twine((int)NValue) + " past "
1730                                 "the end of string table, for N_INDR symbol at "
1731                                 "index " + Twine(SymbolIndex));
1732       }
1733       if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
1734           (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
1735            (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
1736             uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
1737             if (LibraryOrdinal != 0 &&
1738                 LibraryOrdinal != MachO::EXECUTABLE_ORDINAL &&
1739                 LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL &&
1740                 LibraryOrdinal - 1 >= Libraries.size() ) {
1741               return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) +
1742                                     " for symbol at index " + Twine(SymbolIndex));
1743             }
1744           }
1745     }
1746     if (NStrx >= S.strsize)
1747       return malformedError("bad string table index: " + Twine((int)NStrx) +
1748                             " past the end of string table, for symbol at "
1749                             "index " + Twine(SymbolIndex));
1750     SymbolIndex++;
1751   }
1752   return Error::success();
1753 }
1754 
1755 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
1756   unsigned SymbolTableEntrySize = is64Bit() ?
1757     sizeof(MachO::nlist_64) :
1758     sizeof(MachO::nlist);
1759   Symb.p += SymbolTableEntrySize;
1760 }
1761 
1762 Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
1763   StringRef StringTable = getStringTableData();
1764   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1765   if (Entry.n_strx == 0)
1766     // A n_strx value of 0 indicates that no name is associated with a
1767     // particular symbol table entry.
1768     return StringRef();
1769   const char *Start = &StringTable.data()[Entry.n_strx];
1770   if (Start < getData().begin() || Start >= getData().end()) {
1771     return malformedError("bad string index: " + Twine(Entry.n_strx) +
1772                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1773   }
1774   return StringRef(Start);
1775 }
1776 
1777 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
1778   DataRefImpl DRI = Sec.getRawDataRefImpl();
1779   uint32_t Flags = getSectionFlags(*this, DRI);
1780   return Flags & MachO::SECTION_TYPE;
1781 }
1782 
1783 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
1784   if (is64Bit()) {
1785     MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
1786     return Entry.n_value;
1787   }
1788   MachO::nlist Entry = getSymbolTableEntry(Sym);
1789   return Entry.n_value;
1790 }
1791 
1792 // getIndirectName() returns the name of the alias'ed symbol who's string table
1793 // index is in the n_value field.
1794 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
1795                                                  StringRef &Res) const {
1796   StringRef StringTable = getStringTableData();
1797   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1798   if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1799     return object_error::parse_failed;
1800   uint64_t NValue = getNValue(Symb);
1801   if (NValue >= StringTable.size())
1802     return object_error::parse_failed;
1803   const char *Start = &StringTable.data()[NValue];
1804   Res = StringRef(Start);
1805   return std::error_code();
1806 }
1807 
1808 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1809   return getNValue(Sym);
1810 }
1811 
1812 Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
1813   return getSymbolValue(Sym);
1814 }
1815 
1816 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
1817   uint32_t Flags = cantFail(getSymbolFlags(DRI));
1818   if (Flags & SymbolRef::SF_Common) {
1819     MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1820     return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1821   }
1822   return 0;
1823 }
1824 
1825 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
1826   return getNValue(DRI);
1827 }
1828 
1829 Expected<SymbolRef::Type>
1830 MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
1831   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1832   uint8_t n_type = Entry.n_type;
1833 
1834   // If this is a STAB debugging symbol, we can do nothing more.
1835   if (n_type & MachO::N_STAB)
1836     return SymbolRef::ST_Debug;
1837 
1838   switch (n_type & MachO::N_TYPE) {
1839     case MachO::N_UNDF :
1840       return SymbolRef::ST_Unknown;
1841     case MachO::N_SECT :
1842       Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1843       if (!SecOrError)
1844         return SecOrError.takeError();
1845       section_iterator Sec = *SecOrError;
1846       if (Sec == section_end())
1847         return SymbolRef::ST_Other;
1848       if (Sec->isData() || Sec->isBSS())
1849         return SymbolRef::ST_Data;
1850       return SymbolRef::ST_Function;
1851   }
1852   return SymbolRef::ST_Other;
1853 }
1854 
1855 Expected<uint32_t> MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
1856   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1857 
1858   uint8_t MachOType = Entry.n_type;
1859   uint16_t MachOFlags = Entry.n_desc;
1860 
1861   uint32_t Result = SymbolRef::SF_None;
1862 
1863   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1864     Result |= SymbolRef::SF_Indirect;
1865 
1866   if (MachOType & MachO::N_STAB)
1867     Result |= SymbolRef::SF_FormatSpecific;
1868 
1869   if (MachOType & MachO::N_EXT) {
1870     Result |= SymbolRef::SF_Global;
1871     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1872       if (getNValue(DRI))
1873         Result |= SymbolRef::SF_Common;
1874       else
1875         Result |= SymbolRef::SF_Undefined;
1876     }
1877 
1878     if (!(MachOType & MachO::N_PEXT))
1879       Result |= SymbolRef::SF_Exported;
1880   }
1881 
1882   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1883     Result |= SymbolRef::SF_Weak;
1884 
1885   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1886     Result |= SymbolRef::SF_Thumb;
1887 
1888   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1889     Result |= SymbolRef::SF_Absolute;
1890 
1891   return Result;
1892 }
1893 
1894 Expected<section_iterator>
1895 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
1896   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1897   uint8_t index = Entry.n_sect;
1898 
1899   if (index == 0)
1900     return section_end();
1901   DataRefImpl DRI;
1902   DRI.d.a = index - 1;
1903   if (DRI.d.a >= Sections.size()){
1904     return malformedError("bad section index: " + Twine((int)index) +
1905                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1906   }
1907   return section_iterator(SectionRef(DRI, this));
1908 }
1909 
1910 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
1911   MachO::nlist_base Entry =
1912       getSymbolTableEntryBase(*this, Sym.getRawDataRefImpl());
1913   return Entry.n_sect - 1;
1914 }
1915 
1916 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
1917   Sec.d.a++;
1918 }
1919 
1920 Expected<StringRef> MachOObjectFile::getSectionName(DataRefImpl Sec) const {
1921   ArrayRef<char> Raw = getSectionRawName(Sec);
1922   return parseSegmentOrSectionName(Raw.data());
1923 }
1924 
1925 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
1926   if (is64Bit())
1927     return getSection64(Sec).addr;
1928   return getSection(Sec).addr;
1929 }
1930 
1931 uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
1932   return Sec.d.a;
1933 }
1934 
1935 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
1936   // In the case if a malformed Mach-O file where the section offset is past
1937   // the end of the file or some part of the section size is past the end of
1938   // the file return a size of zero or a size that covers the rest of the file
1939   // but does not extend past the end of the file.
1940   uint32_t SectOffset, SectType;
1941   uint64_t SectSize;
1942 
1943   if (is64Bit()) {
1944     MachO::section_64 Sect = getSection64(Sec);
1945     SectOffset = Sect.offset;
1946     SectSize = Sect.size;
1947     SectType = Sect.flags & MachO::SECTION_TYPE;
1948   } else {
1949     MachO::section Sect = getSection(Sec);
1950     SectOffset = Sect.offset;
1951     SectSize = Sect.size;
1952     SectType = Sect.flags & MachO::SECTION_TYPE;
1953   }
1954   if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1955     return SectSize;
1956   uint64_t FileSize = getData().size();
1957   if (SectOffset > FileSize)
1958     return 0;
1959   if (FileSize - SectOffset < SectSize)
1960     return FileSize - SectOffset;
1961   return SectSize;
1962 }
1963 
1964 ArrayRef<uint8_t> MachOObjectFile::getSectionContents(uint32_t Offset,
1965                                                       uint64_t Size) const {
1966   return arrayRefFromStringRef(getData().substr(Offset, Size));
1967 }
1968 
1969 Expected<ArrayRef<uint8_t>>
1970 MachOObjectFile::getSectionContents(DataRefImpl Sec) const {
1971   uint32_t Offset;
1972   uint64_t Size;
1973 
1974   if (is64Bit()) {
1975     MachO::section_64 Sect = getSection64(Sec);
1976     Offset = Sect.offset;
1977     Size = Sect.size;
1978   } else {
1979     MachO::section Sect = getSection(Sec);
1980     Offset = Sect.offset;
1981     Size = Sect.size;
1982   }
1983 
1984   return getSectionContents(Offset, Size);
1985 }
1986 
1987 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
1988   uint32_t Align;
1989   if (is64Bit()) {
1990     MachO::section_64 Sect = getSection64(Sec);
1991     Align = Sect.align;
1992   } else {
1993     MachO::section Sect = getSection(Sec);
1994     Align = Sect.align;
1995   }
1996 
1997   return uint64_t(1) << Align;
1998 }
1999 
2000 Expected<SectionRef> MachOObjectFile::getSection(unsigned SectionIndex) const {
2001   if (SectionIndex < 1 || SectionIndex > Sections.size())
2002     return malformedError("bad section index: " + Twine((int)SectionIndex));
2003 
2004   DataRefImpl DRI;
2005   DRI.d.a = SectionIndex - 1;
2006   return SectionRef(DRI, this);
2007 }
2008 
2009 Expected<SectionRef> MachOObjectFile::getSection(StringRef SectionName) const {
2010   for (const SectionRef &Section : sections()) {
2011     auto NameOrErr = Section.getName();
2012     if (!NameOrErr)
2013       return NameOrErr.takeError();
2014     if (*NameOrErr == SectionName)
2015       return Section;
2016   }
2017   return errorCodeToError(object_error::parse_failed);
2018 }
2019 
2020 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
2021   return false;
2022 }
2023 
2024 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
2025   uint32_t Flags = getSectionFlags(*this, Sec);
2026   return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
2027 }
2028 
2029 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
2030   uint32_t Flags = getSectionFlags(*this, Sec);
2031   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2032   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
2033          !(SectionType == MachO::S_ZEROFILL ||
2034            SectionType == MachO::S_GB_ZEROFILL);
2035 }
2036 
2037 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
2038   uint32_t Flags = getSectionFlags(*this, Sec);
2039   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2040   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
2041          (SectionType == MachO::S_ZEROFILL ||
2042           SectionType == MachO::S_GB_ZEROFILL);
2043 }
2044 
2045 bool MachOObjectFile::isDebugSection(DataRefImpl Sec) const {
2046   Expected<StringRef> SectionNameOrErr = getSectionName(Sec);
2047   if (!SectionNameOrErr) {
2048     // TODO: Report the error message properly.
2049     consumeError(SectionNameOrErr.takeError());
2050     return false;
2051   }
2052   StringRef SectionName = SectionNameOrErr.get();
2053   return SectionName.startswith("__debug") ||
2054          SectionName.startswith("__zdebug") ||
2055          SectionName.startswith("__apple") || SectionName == "__gdb_index" ||
2056          SectionName == "__swift_ast";
2057 }
2058 
2059 namespace {
2060 template <typename LoadCommandType>
2061 ArrayRef<uint8_t> getSegmentContents(const MachOObjectFile &Obj,
2062                                      MachOObjectFile::LoadCommandInfo LoadCmd,
2063                                      StringRef SegmentName) {
2064   auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.Ptr);
2065   if (!SegmentOrErr) {
2066     consumeError(SegmentOrErr.takeError());
2067     return {};
2068   }
2069   auto &Segment = SegmentOrErr.get();
2070   if (StringRef(Segment.segname, 16).startswith(SegmentName))
2071     return arrayRefFromStringRef(Obj.getData().slice(
2072         Segment.fileoff, Segment.fileoff + Segment.filesize));
2073   return {};
2074 }
2075 } // namespace
2076 
2077 ArrayRef<uint8_t>
2078 MachOObjectFile::getSegmentContents(StringRef SegmentName) const {
2079   for (auto LoadCmd : load_commands()) {
2080     ArrayRef<uint8_t> Contents;
2081     switch (LoadCmd.C.cmd) {
2082     case MachO::LC_SEGMENT:
2083       Contents = ::getSegmentContents<MachO::segment_command>(*this, LoadCmd,
2084                                                               SegmentName);
2085       break;
2086     case MachO::LC_SEGMENT_64:
2087       Contents = ::getSegmentContents<MachO::segment_command_64>(*this, LoadCmd,
2088                                                                  SegmentName);
2089       break;
2090     default:
2091       continue;
2092     }
2093     if (!Contents.empty())
2094       return Contents;
2095   }
2096   return {};
2097 }
2098 
2099 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
2100   return Sec.getRawDataRefImpl().d.a;
2101 }
2102 
2103 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
2104   uint32_t Flags = getSectionFlags(*this, Sec);
2105   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2106   return SectionType == MachO::S_ZEROFILL ||
2107          SectionType == MachO::S_GB_ZEROFILL;
2108 }
2109 
2110 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
2111   StringRef SegmentName = getSectionFinalSegmentName(Sec);
2112   if (Expected<StringRef> NameOrErr = getSectionName(Sec))
2113     return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");
2114   return false;
2115 }
2116 
2117 bool MachOObjectFile::isSectionStripped(DataRefImpl Sec) const {
2118   if (is64Bit())
2119     return getSection64(Sec).offset == 0;
2120   return getSection(Sec).offset == 0;
2121 }
2122 
2123 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
2124   DataRefImpl Ret;
2125   Ret.d.a = Sec.d.a;
2126   Ret.d.b = 0;
2127   return relocation_iterator(RelocationRef(Ret, this));
2128 }
2129 
2130 relocation_iterator
2131 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
2132   uint32_t Num;
2133   if (is64Bit()) {
2134     MachO::section_64 Sect = getSection64(Sec);
2135     Num = Sect.nreloc;
2136   } else {
2137     MachO::section Sect = getSection(Sec);
2138     Num = Sect.nreloc;
2139   }
2140 
2141   DataRefImpl Ret;
2142   Ret.d.a = Sec.d.a;
2143   Ret.d.b = Num;
2144   return relocation_iterator(RelocationRef(Ret, this));
2145 }
2146 
2147 relocation_iterator MachOObjectFile::extrel_begin() const {
2148   DataRefImpl Ret;
2149   // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2150   Ret.d.a = 0; // Would normally be a section index.
2151   Ret.d.b = 0; // Index into the external relocations
2152   return relocation_iterator(RelocationRef(Ret, this));
2153 }
2154 
2155 relocation_iterator MachOObjectFile::extrel_end() const {
2156   MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2157   DataRefImpl Ret;
2158   // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2159   Ret.d.a = 0; // Would normally be a section index.
2160   Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
2161   return relocation_iterator(RelocationRef(Ret, this));
2162 }
2163 
2164 relocation_iterator MachOObjectFile::locrel_begin() const {
2165   DataRefImpl Ret;
2166   // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2167   Ret.d.a = 1; // Would normally be a section index.
2168   Ret.d.b = 0; // Index into the local relocations
2169   return relocation_iterator(RelocationRef(Ret, this));
2170 }
2171 
2172 relocation_iterator MachOObjectFile::locrel_end() const {
2173   MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2174   DataRefImpl Ret;
2175   // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2176   Ret.d.a = 1; // Would normally be a section index.
2177   Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations
2178   return relocation_iterator(RelocationRef(Ret, this));
2179 }
2180 
2181 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
2182   ++Rel.d.b;
2183 }
2184 
2185 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
2186   assert((getHeader().filetype == MachO::MH_OBJECT ||
2187           getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
2188          "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2189   MachO::any_relocation_info RE = getRelocation(Rel);
2190   return getAnyRelocationAddress(RE);
2191 }
2192 
2193 symbol_iterator
2194 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
2195   MachO::any_relocation_info RE = getRelocation(Rel);
2196   if (isRelocationScattered(RE))
2197     return symbol_end();
2198 
2199   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2200   bool isExtern = getPlainRelocationExternal(RE);
2201   if (!isExtern)
2202     return symbol_end();
2203 
2204   MachO::symtab_command S = getSymtabLoadCommand();
2205   unsigned SymbolTableEntrySize = is64Bit() ?
2206     sizeof(MachO::nlist_64) :
2207     sizeof(MachO::nlist);
2208   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
2209   DataRefImpl Sym;
2210   Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2211   return symbol_iterator(SymbolRef(Sym, this));
2212 }
2213 
2214 section_iterator
2215 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
2216   return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
2217 }
2218 
2219 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
2220   MachO::any_relocation_info RE = getRelocation(Rel);
2221   return getAnyRelocationType(RE);
2222 }
2223 
2224 void MachOObjectFile::getRelocationTypeName(
2225     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2226   StringRef res;
2227   uint64_t RType = getRelocationType(Rel);
2228 
2229   unsigned Arch = this->getArch();
2230 
2231   switch (Arch) {
2232     case Triple::x86: {
2233       static const char *const Table[] =  {
2234         "GENERIC_RELOC_VANILLA",
2235         "GENERIC_RELOC_PAIR",
2236         "GENERIC_RELOC_SECTDIFF",
2237         "GENERIC_RELOC_PB_LA_PTR",
2238         "GENERIC_RELOC_LOCAL_SECTDIFF",
2239         "GENERIC_RELOC_TLV" };
2240 
2241       if (RType > 5)
2242         res = "Unknown";
2243       else
2244         res = Table[RType];
2245       break;
2246     }
2247     case Triple::x86_64: {
2248       static const char *const Table[] =  {
2249         "X86_64_RELOC_UNSIGNED",
2250         "X86_64_RELOC_SIGNED",
2251         "X86_64_RELOC_BRANCH",
2252         "X86_64_RELOC_GOT_LOAD",
2253         "X86_64_RELOC_GOT",
2254         "X86_64_RELOC_SUBTRACTOR",
2255         "X86_64_RELOC_SIGNED_1",
2256         "X86_64_RELOC_SIGNED_2",
2257         "X86_64_RELOC_SIGNED_4",
2258         "X86_64_RELOC_TLV" };
2259 
2260       if (RType > 9)
2261         res = "Unknown";
2262       else
2263         res = Table[RType];
2264       break;
2265     }
2266     case Triple::arm: {
2267       static const char *const Table[] =  {
2268         "ARM_RELOC_VANILLA",
2269         "ARM_RELOC_PAIR",
2270         "ARM_RELOC_SECTDIFF",
2271         "ARM_RELOC_LOCAL_SECTDIFF",
2272         "ARM_RELOC_PB_LA_PTR",
2273         "ARM_RELOC_BR24",
2274         "ARM_THUMB_RELOC_BR22",
2275         "ARM_THUMB_32BIT_BRANCH",
2276         "ARM_RELOC_HALF",
2277         "ARM_RELOC_HALF_SECTDIFF" };
2278 
2279       if (RType > 9)
2280         res = "Unknown";
2281       else
2282         res = Table[RType];
2283       break;
2284     }
2285     case Triple::aarch64:
2286     case Triple::aarch64_32: {
2287       static const char *const Table[] = {
2288         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
2289         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
2290         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
2291         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2292         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2293         "ARM64_RELOC_ADDEND"
2294       };
2295 
2296       if (RType >= array_lengthof(Table))
2297         res = "Unknown";
2298       else
2299         res = Table[RType];
2300       break;
2301     }
2302     case Triple::ppc: {
2303       static const char *const Table[] =  {
2304         "PPC_RELOC_VANILLA",
2305         "PPC_RELOC_PAIR",
2306         "PPC_RELOC_BR14",
2307         "PPC_RELOC_BR24",
2308         "PPC_RELOC_HI16",
2309         "PPC_RELOC_LO16",
2310         "PPC_RELOC_HA16",
2311         "PPC_RELOC_LO14",
2312         "PPC_RELOC_SECTDIFF",
2313         "PPC_RELOC_PB_LA_PTR",
2314         "PPC_RELOC_HI16_SECTDIFF",
2315         "PPC_RELOC_LO16_SECTDIFF",
2316         "PPC_RELOC_HA16_SECTDIFF",
2317         "PPC_RELOC_JBSR",
2318         "PPC_RELOC_LO14_SECTDIFF",
2319         "PPC_RELOC_LOCAL_SECTDIFF" };
2320 
2321       if (RType > 15)
2322         res = "Unknown";
2323       else
2324         res = Table[RType];
2325       break;
2326     }
2327     case Triple::UnknownArch:
2328       res = "Unknown";
2329       break;
2330   }
2331   Result.append(res.begin(), res.end());
2332 }
2333 
2334 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
2335   MachO::any_relocation_info RE = getRelocation(Rel);
2336   return getAnyRelocationLength(RE);
2337 }
2338 
2339 //
2340 // guessLibraryShortName() is passed a name of a dynamic library and returns a
2341 // guess on what the short name is.  Then name is returned as a substring of the
2342 // StringRef Name passed in.  The name of the dynamic library is recognized as
2343 // a framework if it has one of the two following forms:
2344 //      Foo.framework/Versions/A/Foo
2345 //      Foo.framework/Foo
2346 // Where A and Foo can be any string.  And may contain a trailing suffix
2347 // starting with an underbar.  If the Name is recognized as a framework then
2348 // isFramework is set to true else it is set to false.  If the Name has a
2349 // suffix then Suffix is set to the substring in Name that contains the suffix
2350 // else it is set to a NULL StringRef.
2351 //
2352 // The Name of the dynamic library is recognized as a library name if it has
2353 // one of the two following forms:
2354 //      libFoo.A.dylib
2355 //      libFoo.dylib
2356 //
2357 // The library may have a suffix trailing the name Foo of the form:
2358 //      libFoo_profile.A.dylib
2359 //      libFoo_profile.dylib
2360 // These dyld image suffixes are separated from the short name by a '_'
2361 // character. Because the '_' character is commonly used to separate words in
2362 // filenames guessLibraryShortName() cannot reliably separate a dylib's short
2363 // name from an arbitrary image suffix; imagine if both the short name and the
2364 // suffix contains an '_' character! To better deal with this ambiguity,
2365 // guessLibraryShortName() will recognize only "_debug" and "_profile" as valid
2366 // Suffix values. Calling code needs to be tolerant of guessLibraryShortName()
2367 // guessing incorrectly.
2368 //
2369 // The Name of the dynamic library is also recognized as a library name if it
2370 // has the following form:
2371 //      Foo.qtx
2372 //
2373 // If the Name of the dynamic library is none of the forms above then a NULL
2374 // StringRef is returned.
2375 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
2376                                                  bool &isFramework,
2377                                                  StringRef &Suffix) {
2378   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2379   size_t a, b, c, d, Idx;
2380 
2381   isFramework = false;
2382   Suffix = StringRef();
2383 
2384   // Pull off the last component and make Foo point to it
2385   a = Name.rfind('/');
2386   if (a == Name.npos || a == 0)
2387     goto guess_library;
2388   Foo = Name.slice(a+1, Name.npos);
2389 
2390   // Look for a suffix starting with a '_'
2391   Idx = Foo.rfind('_');
2392   if (Idx != Foo.npos && Foo.size() >= 2) {
2393     Suffix = Foo.slice(Idx, Foo.npos);
2394     if (Suffix != "_debug" && Suffix != "_profile")
2395       Suffix = StringRef();
2396     else
2397       Foo = Foo.slice(0, Idx);
2398   }
2399 
2400   // First look for the form Foo.framework/Foo
2401   b = Name.rfind('/', a);
2402   if (b == Name.npos)
2403     Idx = 0;
2404   else
2405     Idx = b+1;
2406   F = Name.slice(Idx, Idx + Foo.size());
2407   DotFramework = Name.slice(Idx + Foo.size(),
2408                             Idx + Foo.size() + sizeof(".framework/")-1);
2409   if (F == Foo && DotFramework == ".framework/") {
2410     isFramework = true;
2411     return Foo;
2412   }
2413 
2414   // Next look for the form Foo.framework/Versions/A/Foo
2415   if (b == Name.npos)
2416     goto guess_library;
2417   c =  Name.rfind('/', b);
2418   if (c == Name.npos || c == 0)
2419     goto guess_library;
2420   V = Name.slice(c+1, Name.npos);
2421   if (!V.startswith("Versions/"))
2422     goto guess_library;
2423   d =  Name.rfind('/', c);
2424   if (d == Name.npos)
2425     Idx = 0;
2426   else
2427     Idx = d+1;
2428   F = Name.slice(Idx, Idx + Foo.size());
2429   DotFramework = Name.slice(Idx + Foo.size(),
2430                             Idx + Foo.size() + sizeof(".framework/")-1);
2431   if (F == Foo && DotFramework == ".framework/") {
2432     isFramework = true;
2433     return Foo;
2434   }
2435 
2436 guess_library:
2437   // pull off the suffix after the "." and make a point to it
2438   a = Name.rfind('.');
2439   if (a == Name.npos || a == 0)
2440     return StringRef();
2441   Dylib = Name.slice(a, Name.npos);
2442   if (Dylib != ".dylib")
2443     goto guess_qtx;
2444 
2445   // First pull off the version letter for the form Foo.A.dylib if any.
2446   if (a >= 3) {
2447     Dot = Name.slice(a-2, a-1);
2448     if (Dot == ".")
2449       a = a - 2;
2450   }
2451 
2452   b = Name.rfind('/', a);
2453   if (b == Name.npos)
2454     b = 0;
2455   else
2456     b = b+1;
2457   // ignore any suffix after an underbar like Foo_profile.A.dylib
2458   Idx = Name.rfind('_');
2459   if (Idx != Name.npos && Idx != b) {
2460     Lib = Name.slice(b, Idx);
2461     Suffix = Name.slice(Idx, a);
2462     if (Suffix != "_debug" && Suffix != "_profile") {
2463       Suffix = StringRef();
2464       Lib = Name.slice(b, a);
2465     }
2466   }
2467   else
2468     Lib = Name.slice(b, a);
2469   // There are incorrect library names of the form:
2470   // libATS.A_profile.dylib so check for these.
2471   if (Lib.size() >= 3) {
2472     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2473     if (Dot == ".")
2474       Lib = Lib.slice(0, Lib.size()-2);
2475   }
2476   return Lib;
2477 
2478 guess_qtx:
2479   Qtx = Name.slice(a, Name.npos);
2480   if (Qtx != ".qtx")
2481     return StringRef();
2482   b = Name.rfind('/', a);
2483   if (b == Name.npos)
2484     Lib = Name.slice(0, a);
2485   else
2486     Lib = Name.slice(b+1, a);
2487   // There are library names of the form: QT.A.qtx so check for these.
2488   if (Lib.size() >= 3) {
2489     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2490     if (Dot == ".")
2491       Lib = Lib.slice(0, Lib.size()-2);
2492   }
2493   return Lib;
2494 }
2495 
2496 // getLibraryShortNameByIndex() is used to get the short name of the library
2497 // for an undefined symbol in a linked Mach-O binary that was linked with the
2498 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
2499 // It is passed the index (0 - based) of the library as translated from
2500 // GET_LIBRARY_ORDINAL (1 - based).
2501 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
2502                                                          StringRef &Res) const {
2503   if (Index >= Libraries.size())
2504     return object_error::parse_failed;
2505 
2506   // If the cache of LibrariesShortNames is not built up do that first for
2507   // all the Libraries.
2508   if (LibrariesShortNames.size() == 0) {
2509     for (unsigned i = 0; i < Libraries.size(); i++) {
2510       auto CommandOrErr =
2511         getStructOrErr<MachO::dylib_command>(*this, Libraries[i]);
2512       if (!CommandOrErr)
2513         return object_error::parse_failed;
2514       MachO::dylib_command D = CommandOrErr.get();
2515       if (D.dylib.name >= D.cmdsize)
2516         return object_error::parse_failed;
2517       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2518       StringRef Name = StringRef(P);
2519       if (D.dylib.name+Name.size() >= D.cmdsize)
2520         return object_error::parse_failed;
2521       StringRef Suffix;
2522       bool isFramework;
2523       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2524       if (shortName.empty())
2525         LibrariesShortNames.push_back(Name);
2526       else
2527         LibrariesShortNames.push_back(shortName);
2528     }
2529   }
2530 
2531   Res = LibrariesShortNames[Index];
2532   return std::error_code();
2533 }
2534 
2535 uint32_t MachOObjectFile::getLibraryCount() const {
2536   return Libraries.size();
2537 }
2538 
2539 section_iterator
2540 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
2541   DataRefImpl Sec;
2542   Sec.d.a = Rel->getRawDataRefImpl().d.a;
2543   return section_iterator(SectionRef(Sec, this));
2544 }
2545 
2546 basic_symbol_iterator MachOObjectFile::symbol_begin() const {
2547   DataRefImpl DRI;
2548   MachO::symtab_command Symtab = getSymtabLoadCommand();
2549   if (!SymtabLoadCmd || Symtab.nsyms == 0)
2550     return basic_symbol_iterator(SymbolRef(DRI, this));
2551 
2552   return getSymbolByIndex(0);
2553 }
2554 
2555 basic_symbol_iterator MachOObjectFile::symbol_end() const {
2556   DataRefImpl DRI;
2557   MachO::symtab_command Symtab = getSymtabLoadCommand();
2558   if (!SymtabLoadCmd || Symtab.nsyms == 0)
2559     return basic_symbol_iterator(SymbolRef(DRI, this));
2560 
2561   unsigned SymbolTableEntrySize = is64Bit() ?
2562     sizeof(MachO::nlist_64) :
2563     sizeof(MachO::nlist);
2564   unsigned Offset = Symtab.symoff +
2565     Symtab.nsyms * SymbolTableEntrySize;
2566   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2567   return basic_symbol_iterator(SymbolRef(DRI, this));
2568 }
2569 
2570 symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
2571   MachO::symtab_command Symtab = getSymtabLoadCommand();
2572   if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2573     report_fatal_error("Requested symbol index is out of range.");
2574   unsigned SymbolTableEntrySize =
2575     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2576   DataRefImpl DRI;
2577   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2578   DRI.p += Index * SymbolTableEntrySize;
2579   return basic_symbol_iterator(SymbolRef(DRI, this));
2580 }
2581 
2582 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
2583   MachO::symtab_command Symtab = getSymtabLoadCommand();
2584   if (!SymtabLoadCmd)
2585     report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2586   unsigned SymbolTableEntrySize =
2587     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2588   DataRefImpl DRIstart;
2589   DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2590   uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2591   return Index;
2592 }
2593 
2594 section_iterator MachOObjectFile::section_begin() const {
2595   DataRefImpl DRI;
2596   return section_iterator(SectionRef(DRI, this));
2597 }
2598 
2599 section_iterator MachOObjectFile::section_end() const {
2600   DataRefImpl DRI;
2601   DRI.d.a = Sections.size();
2602   return section_iterator(SectionRef(DRI, this));
2603 }
2604 
2605 uint8_t MachOObjectFile::getBytesInAddress() const {
2606   return is64Bit() ? 8 : 4;
2607 }
2608 
2609 StringRef MachOObjectFile::getFileFormatName() const {
2610   unsigned CPUType = getCPUType(*this);
2611   if (!is64Bit()) {
2612     switch (CPUType) {
2613     case MachO::CPU_TYPE_I386:
2614       return "Mach-O 32-bit i386";
2615     case MachO::CPU_TYPE_ARM:
2616       return "Mach-O arm";
2617     case MachO::CPU_TYPE_ARM64_32:
2618       return "Mach-O arm64 (ILP32)";
2619     case MachO::CPU_TYPE_POWERPC:
2620       return "Mach-O 32-bit ppc";
2621     default:
2622       return "Mach-O 32-bit unknown";
2623     }
2624   }
2625 
2626   switch (CPUType) {
2627   case MachO::CPU_TYPE_X86_64:
2628     return "Mach-O 64-bit x86-64";
2629   case MachO::CPU_TYPE_ARM64:
2630     return "Mach-O arm64";
2631   case MachO::CPU_TYPE_POWERPC64:
2632     return "Mach-O 64-bit ppc64";
2633   default:
2634     return "Mach-O 64-bit unknown";
2635   }
2636 }
2637 
2638 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
2639   switch (CPUType) {
2640   case MachO::CPU_TYPE_I386:
2641     return Triple::x86;
2642   case MachO::CPU_TYPE_X86_64:
2643     return Triple::x86_64;
2644   case MachO::CPU_TYPE_ARM:
2645     return Triple::arm;
2646   case MachO::CPU_TYPE_ARM64:
2647     return Triple::aarch64;
2648   case MachO::CPU_TYPE_ARM64_32:
2649     return Triple::aarch64_32;
2650   case MachO::CPU_TYPE_POWERPC:
2651     return Triple::ppc;
2652   case MachO::CPU_TYPE_POWERPC64:
2653     return Triple::ppc64;
2654   default:
2655     return Triple::UnknownArch;
2656   }
2657 }
2658 
2659 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
2660                                       const char **McpuDefault,
2661                                       const char **ArchFlag) {
2662   if (McpuDefault)
2663     *McpuDefault = nullptr;
2664   if (ArchFlag)
2665     *ArchFlag = nullptr;
2666 
2667   switch (CPUType) {
2668   case MachO::CPU_TYPE_I386:
2669     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2670     case MachO::CPU_SUBTYPE_I386_ALL:
2671       if (ArchFlag)
2672         *ArchFlag = "i386";
2673       return Triple("i386-apple-darwin");
2674     default:
2675       return Triple();
2676     }
2677   case MachO::CPU_TYPE_X86_64:
2678     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2679     case MachO::CPU_SUBTYPE_X86_64_ALL:
2680       if (ArchFlag)
2681         *ArchFlag = "x86_64";
2682       return Triple("x86_64-apple-darwin");
2683     case MachO::CPU_SUBTYPE_X86_64_H:
2684       if (ArchFlag)
2685         *ArchFlag = "x86_64h";
2686       return Triple("x86_64h-apple-darwin");
2687     default:
2688       return Triple();
2689     }
2690   case MachO::CPU_TYPE_ARM:
2691     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2692     case MachO::CPU_SUBTYPE_ARM_V4T:
2693       if (ArchFlag)
2694         *ArchFlag = "armv4t";
2695       return Triple("armv4t-apple-darwin");
2696     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2697       if (ArchFlag)
2698         *ArchFlag = "armv5e";
2699       return Triple("armv5e-apple-darwin");
2700     case MachO::CPU_SUBTYPE_ARM_XSCALE:
2701       if (ArchFlag)
2702         *ArchFlag = "xscale";
2703       return Triple("xscale-apple-darwin");
2704     case MachO::CPU_SUBTYPE_ARM_V6:
2705       if (ArchFlag)
2706         *ArchFlag = "armv6";
2707       return Triple("armv6-apple-darwin");
2708     case MachO::CPU_SUBTYPE_ARM_V6M:
2709       if (McpuDefault)
2710         *McpuDefault = "cortex-m0";
2711       if (ArchFlag)
2712         *ArchFlag = "armv6m";
2713       return Triple("armv6m-apple-darwin");
2714     case MachO::CPU_SUBTYPE_ARM_V7:
2715       if (ArchFlag)
2716         *ArchFlag = "armv7";
2717       return Triple("armv7-apple-darwin");
2718     case MachO::CPU_SUBTYPE_ARM_V7EM:
2719       if (McpuDefault)
2720         *McpuDefault = "cortex-m4";
2721       if (ArchFlag)
2722         *ArchFlag = "armv7em";
2723       return Triple("thumbv7em-apple-darwin");
2724     case MachO::CPU_SUBTYPE_ARM_V7K:
2725       if (McpuDefault)
2726         *McpuDefault = "cortex-a7";
2727       if (ArchFlag)
2728         *ArchFlag = "armv7k";
2729       return Triple("armv7k-apple-darwin");
2730     case MachO::CPU_SUBTYPE_ARM_V7M:
2731       if (McpuDefault)
2732         *McpuDefault = "cortex-m3";
2733       if (ArchFlag)
2734         *ArchFlag = "armv7m";
2735       return Triple("thumbv7m-apple-darwin");
2736     case MachO::CPU_SUBTYPE_ARM_V7S:
2737       if (McpuDefault)
2738         *McpuDefault = "cortex-a7";
2739       if (ArchFlag)
2740         *ArchFlag = "armv7s";
2741       return Triple("armv7s-apple-darwin");
2742     default:
2743       return Triple();
2744     }
2745   case MachO::CPU_TYPE_ARM64:
2746     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2747     case MachO::CPU_SUBTYPE_ARM64_ALL:
2748       if (McpuDefault)
2749         *McpuDefault = "cyclone";
2750       if (ArchFlag)
2751         *ArchFlag = "arm64";
2752       return Triple("arm64-apple-darwin");
2753     case MachO::CPU_SUBTYPE_ARM64E:
2754       if (McpuDefault)
2755         *McpuDefault = "apple-a12";
2756       if (ArchFlag)
2757         *ArchFlag = "arm64e";
2758       return Triple("arm64e-apple-darwin");
2759     default:
2760       return Triple();
2761     }
2762   case MachO::CPU_TYPE_ARM64_32:
2763     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2764     case MachO::CPU_SUBTYPE_ARM64_32_V8:
2765       if (McpuDefault)
2766         *McpuDefault = "cyclone";
2767       if (ArchFlag)
2768         *ArchFlag = "arm64_32";
2769       return Triple("arm64_32-apple-darwin");
2770     default:
2771       return Triple();
2772     }
2773   case MachO::CPU_TYPE_POWERPC:
2774     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2775     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2776       if (ArchFlag)
2777         *ArchFlag = "ppc";
2778       return Triple("ppc-apple-darwin");
2779     default:
2780       return Triple();
2781     }
2782   case MachO::CPU_TYPE_POWERPC64:
2783     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2784     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2785       if (ArchFlag)
2786         *ArchFlag = "ppc64";
2787       return Triple("ppc64-apple-darwin");
2788     default:
2789       return Triple();
2790     }
2791   default:
2792     return Triple();
2793   }
2794 }
2795 
2796 Triple MachOObjectFile::getHostArch() {
2797   return Triple(sys::getDefaultTargetTriple());
2798 }
2799 
2800 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
2801   auto validArchs = getValidArchs();
2802   return llvm::is_contained(validArchs, ArchFlag);
2803 }
2804 
2805 ArrayRef<StringRef> MachOObjectFile::getValidArchs() {
2806   static const std::array<StringRef, 18> ValidArchs = {{
2807       "i386",
2808       "x86_64",
2809       "x86_64h",
2810       "armv4t",
2811       "arm",
2812       "armv5e",
2813       "armv6",
2814       "armv6m",
2815       "armv7",
2816       "armv7em",
2817       "armv7k",
2818       "armv7m",
2819       "armv7s",
2820       "arm64",
2821       "arm64e",
2822       "arm64_32",
2823       "ppc",
2824       "ppc64",
2825   }};
2826 
2827   return ValidArchs;
2828 }
2829 
2830 Triple::ArchType MachOObjectFile::getArch() const {
2831   return getArch(getCPUType(*this), getCPUSubType(*this));
2832 }
2833 
2834 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2835   return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2836 }
2837 
2838 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
2839   DataRefImpl DRI;
2840   DRI.d.a = Index;
2841   return section_rel_begin(DRI);
2842 }
2843 
2844 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
2845   DataRefImpl DRI;
2846   DRI.d.a = Index;
2847   return section_rel_end(DRI);
2848 }
2849 
2850 dice_iterator MachOObjectFile::begin_dices() const {
2851   DataRefImpl DRI;
2852   if (!DataInCodeLoadCmd)
2853     return dice_iterator(DiceRef(DRI, this));
2854 
2855   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2856   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2857   return dice_iterator(DiceRef(DRI, this));
2858 }
2859 
2860 dice_iterator MachOObjectFile::end_dices() const {
2861   DataRefImpl DRI;
2862   if (!DataInCodeLoadCmd)
2863     return dice_iterator(DiceRef(DRI, this));
2864 
2865   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2866   unsigned Offset = DicLC.dataoff + DicLC.datasize;
2867   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2868   return dice_iterator(DiceRef(DRI, this));
2869 }
2870 
2871 ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O,
2872                          ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {}
2873 
2874 void ExportEntry::moveToFirst() {
2875   ErrorAsOutParameter ErrAsOutParam(E);
2876   pushNode(0);
2877   if (*E)
2878     return;
2879   pushDownUntilBottom();
2880 }
2881 
2882 void ExportEntry::moveToEnd() {
2883   Stack.clear();
2884   Done = true;
2885 }
2886 
2887 bool ExportEntry::operator==(const ExportEntry &Other) const {
2888   // Common case, one at end, other iterating from begin.
2889   if (Done || Other.Done)
2890     return (Done == Other.Done);
2891   // Not equal if different stack sizes.
2892   if (Stack.size() != Other.Stack.size())
2893     return false;
2894   // Not equal if different cumulative strings.
2895   if (!CumulativeString.equals(Other.CumulativeString))
2896     return false;
2897   // Equal if all nodes in both stacks match.
2898   for (unsigned i=0; i < Stack.size(); ++i) {
2899     if (Stack[i].Start != Other.Stack[i].Start)
2900       return false;
2901   }
2902   return true;
2903 }
2904 
2905 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) {
2906   unsigned Count;
2907   uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error);
2908   Ptr += Count;
2909   if (Ptr > Trie.end())
2910     Ptr = Trie.end();
2911   return Result;
2912 }
2913 
2914 StringRef ExportEntry::name() const {
2915   return CumulativeString;
2916 }
2917 
2918 uint64_t ExportEntry::flags() const {
2919   return Stack.back().Flags;
2920 }
2921 
2922 uint64_t ExportEntry::address() const {
2923   return Stack.back().Address;
2924 }
2925 
2926 uint64_t ExportEntry::other() const {
2927   return Stack.back().Other;
2928 }
2929 
2930 StringRef ExportEntry::otherName() const {
2931   const char* ImportName = Stack.back().ImportName;
2932   if (ImportName)
2933     return StringRef(ImportName);
2934   return StringRef();
2935 }
2936 
2937 uint32_t ExportEntry::nodeOffset() const {
2938   return Stack.back().Start - Trie.begin();
2939 }
2940 
2941 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2942     : Start(Ptr), Current(Ptr) {}
2943 
2944 void ExportEntry::pushNode(uint64_t offset) {
2945   ErrorAsOutParameter ErrAsOutParam(E);
2946   const uint8_t *Ptr = Trie.begin() + offset;
2947   NodeState State(Ptr);
2948   const char *error;
2949   uint64_t ExportInfoSize = readULEB128(State.Current, &error);
2950   if (error) {
2951     *E = malformedError("export info size " + Twine(error) +
2952                         " in export trie data at node: 0x" +
2953                         Twine::utohexstr(offset));
2954     moveToEnd();
2955     return;
2956   }
2957   State.IsExportNode = (ExportInfoSize != 0);
2958   const uint8_t* Children = State.Current + ExportInfoSize;
2959   if (Children > Trie.end()) {
2960     *E = malformedError(
2961         "export info size: 0x" + Twine::utohexstr(ExportInfoSize) +
2962         " in export trie data at node: 0x" + Twine::utohexstr(offset) +
2963         " too big and extends past end of trie data");
2964     moveToEnd();
2965     return;
2966   }
2967   if (State.IsExportNode) {
2968     const uint8_t *ExportStart = State.Current;
2969     State.Flags = readULEB128(State.Current, &error);
2970     if (error) {
2971       *E = malformedError("flags " + Twine(error) +
2972                           " in export trie data at node: 0x" +
2973                           Twine::utohexstr(offset));
2974       moveToEnd();
2975       return;
2976     }
2977     uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK;
2978     if (State.Flags != 0 &&
2979         (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR &&
2980          Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE &&
2981          Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) {
2982       *E = malformedError(
2983           "unsupported exported symbol kind: " + Twine((int)Kind) +
2984           " in flags: 0x" + Twine::utohexstr(State.Flags) +
2985           " in export trie data at node: 0x" + Twine::utohexstr(offset));
2986       moveToEnd();
2987       return;
2988     }
2989     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2990       State.Address = 0;
2991       State.Other = readULEB128(State.Current, &error); // dylib ordinal
2992       if (error) {
2993         *E = malformedError("dylib ordinal of re-export " + Twine(error) +
2994                             " in export trie data at node: 0x" +
2995                             Twine::utohexstr(offset));
2996         moveToEnd();
2997         return;
2998       }
2999       if (O != nullptr) {
3000         // Only positive numbers represent library ordinals. Zero and negative
3001         // numbers have special meaning (see BindSpecialDylib).
3002         if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3003           *E = malformedError(
3004               "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3005               Twine((int)O->getLibraryCount()) +
3006               ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3007           moveToEnd();
3008           return;
3009         }
3010       }
3011       State.ImportName = reinterpret_cast<const char*>(State.Current);
3012       if (*State.ImportName == '\0') {
3013         State.Current++;
3014       } else {
3015         const uint8_t *End = State.Current + 1;
3016         if (End >= Trie.end()) {
3017           *E = malformedError("import name of re-export in export trie data at "
3018                               "node: 0x" +
3019                               Twine::utohexstr(offset) +
3020                               " starts past end of trie data");
3021           moveToEnd();
3022           return;
3023         }
3024         while(*End != '\0' && End < Trie.end())
3025           End++;
3026         if (*End != '\0') {
3027           *E = malformedError("import name of re-export in export trie data at "
3028                               "node: 0x" +
3029                               Twine::utohexstr(offset) +
3030                               " extends past end of trie data");
3031           moveToEnd();
3032           return;
3033         }
3034         State.Current = End + 1;
3035       }
3036     } else {
3037       State.Address = readULEB128(State.Current, &error);
3038       if (error) {
3039         *E = malformedError("address " + Twine(error) +
3040                             " in export trie data at node: 0x" +
3041                             Twine::utohexstr(offset));
3042         moveToEnd();
3043         return;
3044       }
3045       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
3046         State.Other = readULEB128(State.Current, &error);
3047         if (error) {
3048           *E = malformedError("resolver of stub and resolver " + Twine(error) +
3049                               " in export trie data at node: 0x" +
3050                               Twine::utohexstr(offset));
3051           moveToEnd();
3052           return;
3053         }
3054       }
3055     }
3056     if(ExportStart + ExportInfoSize != State.Current) {
3057       *E = malformedError(
3058           "inconsistant export info size: 0x" +
3059           Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3060           Twine::utohexstr(State.Current - ExportStart) +
3061           " in export trie data at node: 0x" + Twine::utohexstr(offset));
3062       moveToEnd();
3063       return;
3064     }
3065   }
3066   State.ChildCount = *Children;
3067   if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3068     *E = malformedError("byte for count of childern in export trie data at "
3069                         "node: 0x" +
3070                         Twine::utohexstr(offset) +
3071                         " extends past end of trie data");
3072     moveToEnd();
3073     return;
3074   }
3075   State.Current = Children + 1;
3076   State.NextChildIndex = 0;
3077   State.ParentStringLength = CumulativeString.size();
3078   Stack.push_back(State);
3079 }
3080 
3081 void ExportEntry::pushDownUntilBottom() {
3082   ErrorAsOutParameter ErrAsOutParam(E);
3083   const char *error;
3084   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3085     NodeState &Top = Stack.back();
3086     CumulativeString.resize(Top.ParentStringLength);
3087     for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3088       char C = *Top.Current;
3089       CumulativeString.push_back(C);
3090     }
3091     if (Top.Current >= Trie.end()) {
3092       *E = malformedError("edge sub-string in export trie data at node: 0x" +
3093                           Twine::utohexstr(Top.Start - Trie.begin()) +
3094                           " for child #" + Twine((int)Top.NextChildIndex) +
3095                           " extends past end of trie data");
3096       moveToEnd();
3097       return;
3098     }
3099     Top.Current += 1;
3100     uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3101     if (error) {
3102       *E = malformedError("child node offset " + Twine(error) +
3103                           " in export trie data at node: 0x" +
3104                           Twine::utohexstr(Top.Start - Trie.begin()));
3105       moveToEnd();
3106       return;
3107     }
3108     for (const NodeState &node : nodes()) {
3109       if (node.Start == Trie.begin() + childNodeIndex){
3110         *E = malformedError("loop in childern in export trie data at node: 0x" +
3111                             Twine::utohexstr(Top.Start - Trie.begin()) +
3112                             " back to node: 0x" +
3113                             Twine::utohexstr(childNodeIndex));
3114         moveToEnd();
3115         return;
3116       }
3117     }
3118     Top.NextChildIndex += 1;
3119     pushNode(childNodeIndex);
3120     if (*E)
3121       return;
3122   }
3123   if (!Stack.back().IsExportNode) {
3124     *E = malformedError("node is not an export node in export trie data at "
3125                         "node: 0x" +
3126                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3127     moveToEnd();
3128     return;
3129   }
3130 }
3131 
3132 // We have a trie data structure and need a way to walk it that is compatible
3133 // with the C++ iterator model. The solution is a non-recursive depth first
3134 // traversal where the iterator contains a stack of parent nodes along with a
3135 // string that is the accumulation of all edge strings along the parent chain
3136 // to this point.
3137 //
3138 // There is one "export" node for each exported symbol.  But because some
3139 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
3140 // node may have child nodes too.
3141 //
3142 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
3143 // child until hitting a node with no children (which is an export node or
3144 // else the trie is malformed). On the way down, each node is pushed on the
3145 // stack ivar.  If there is no more ways down, it pops up one and tries to go
3146 // down a sibling path until a childless node is reached.
3147 void ExportEntry::moveNext() {
3148   assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3149   if (!Stack.back().IsExportNode) {
3150     *E = malformedError("node is not an export node in export trie data at "
3151                         "node: 0x" +
3152                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3153     moveToEnd();
3154     return;
3155   }
3156 
3157   Stack.pop_back();
3158   while (!Stack.empty()) {
3159     NodeState &Top = Stack.back();
3160     if (Top.NextChildIndex < Top.ChildCount) {
3161       pushDownUntilBottom();
3162       // Now at the next export node.
3163       return;
3164     } else {
3165       if (Top.IsExportNode) {
3166         // This node has no children but is itself an export node.
3167         CumulativeString.resize(Top.ParentStringLength);
3168         return;
3169       }
3170       Stack.pop_back();
3171     }
3172   }
3173   Done = true;
3174 }
3175 
3176 iterator_range<export_iterator>
3177 MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie,
3178                          const MachOObjectFile *O) {
3179   ExportEntry Start(&E, O, Trie);
3180   if (Trie.empty())
3181     Start.moveToEnd();
3182   else
3183     Start.moveToFirst();
3184 
3185   ExportEntry Finish(&E, O, Trie);
3186   Finish.moveToEnd();
3187 
3188   return make_range(export_iterator(Start), export_iterator(Finish));
3189 }
3190 
3191 iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const {
3192   return exports(Err, getDyldInfoExportsTrie(), this);
3193 }
3194 
3195 MachOAbstractFixupEntry::MachOAbstractFixupEntry(Error *E,
3196                                                  const MachOObjectFile *O)
3197     : E(E), O(O) {
3198   // Cache the vmaddress of __TEXT
3199   for (const auto &Command : O->load_commands()) {
3200     if (Command.C.cmd == MachO::LC_SEGMENT) {
3201       MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
3202       if (StringRef(SLC.segname) == StringRef("__TEXT")) {
3203         TextAddress = SLC.vmaddr;
3204         break;
3205       }
3206     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3207       MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
3208       if (StringRef(SLC_64.segname) == StringRef("__TEXT")) {
3209         TextAddress = SLC_64.vmaddr;
3210         break;
3211       }
3212     }
3213   }
3214 }
3215 
3216 int32_t MachOAbstractFixupEntry::segmentIndex() const { return SegmentIndex; }
3217 
3218 uint64_t MachOAbstractFixupEntry::segmentOffset() const {
3219   return SegmentOffset;
3220 }
3221 
3222 uint64_t MachOAbstractFixupEntry::segmentAddress() const {
3223   return O->BindRebaseAddress(SegmentIndex, 0);
3224 }
3225 
3226 StringRef MachOAbstractFixupEntry::segmentName() const {
3227   return O->BindRebaseSegmentName(SegmentIndex);
3228 }
3229 
3230 StringRef MachOAbstractFixupEntry::sectionName() const {
3231   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3232 }
3233 
3234 uint64_t MachOAbstractFixupEntry::address() const {
3235   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3236 }
3237 
3238 StringRef MachOAbstractFixupEntry::symbolName() const { return SymbolName; }
3239 
3240 int64_t MachOAbstractFixupEntry::addend() const { return Addend; }
3241 
3242 uint32_t MachOAbstractFixupEntry::flags() const { return Flags; }
3243 
3244 int MachOAbstractFixupEntry::ordinal() const { return Ordinal; }
3245 
3246 StringRef MachOAbstractFixupEntry::typeName() const { return "unknown"; }
3247 
3248 void MachOAbstractFixupEntry::moveToFirst() {
3249   SegmentOffset = 0;
3250   SegmentIndex = -1;
3251   Ordinal = 0;
3252   Flags = 0;
3253   Addend = 0;
3254   Done = false;
3255 }
3256 
3257 void MachOAbstractFixupEntry::moveToEnd() { Done = true; }
3258 
3259 MachOChainedFixupEntry::MachOChainedFixupEntry(Error *E,
3260                                                const MachOObjectFile *O,
3261                                                bool Parse)
3262     : MachOAbstractFixupEntry(E, O) {
3263   ErrorAsOutParameter e(E);
3264   if (!Parse)
3265     return;
3266   if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets())
3267     FixupTargets = *FixupTargetsOrErr;
3268   else {
3269     *E = FixupTargetsOrErr.takeError();
3270     return;
3271   }
3272 }
3273 
3274 void MachOChainedFixupEntry::moveToFirst() {
3275   MachOAbstractFixupEntry::moveToFirst();
3276   FixupIndex = 0;
3277   moveNext();
3278 }
3279 
3280 void MachOChainedFixupEntry::moveToEnd() {
3281   MachOAbstractFixupEntry::moveToEnd();
3282 }
3283 
3284 void MachOChainedFixupEntry::moveNext() { Done = true; }
3285 
3286 bool MachOChainedFixupEntry::operator==(
3287     const MachOChainedFixupEntry &Other) const {
3288   if (Done == Other.Done)
3289     return true;
3290   if ((FixupIndex == Other.FixupIndex))
3291     return true;
3292   return false;
3293 }
3294 
3295 MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
3296                                    ArrayRef<uint8_t> Bytes, bool is64Bit)
3297     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3298       PointerSize(is64Bit ? 8 : 4) {}
3299 
3300 void MachORebaseEntry::moveToFirst() {
3301   Ptr = Opcodes.begin();
3302   moveNext();
3303 }
3304 
3305 void MachORebaseEntry::moveToEnd() {
3306   Ptr = Opcodes.end();
3307   RemainingLoopCount = 0;
3308   Done = true;
3309 }
3310 
3311 void MachORebaseEntry::moveNext() {
3312   ErrorAsOutParameter ErrAsOutParam(E);
3313   // If in the middle of some loop, move to next rebasing in loop.
3314   SegmentOffset += AdvanceAmount;
3315   if (RemainingLoopCount) {
3316     --RemainingLoopCount;
3317     return;
3318   }
3319   // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3320   // pointer size. Therefore it is possible to reach the end without ever having
3321   // seen REBASE_OPCODE_DONE.
3322   if (Ptr == Opcodes.end()) {
3323     Done = true;
3324     return;
3325   }
3326   bool More = true;
3327   while (More) {
3328     // Parse next opcode and set up next loop.
3329     const uint8_t *OpcodeStart = Ptr;
3330     uint8_t Byte = *Ptr++;
3331     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3332     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3333     uint32_t Count, Skip;
3334     const char *error = nullptr;
3335     switch (Opcode) {
3336     case MachO::REBASE_OPCODE_DONE:
3337       More = false;
3338       Done = true;
3339       moveToEnd();
3340       DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3341       break;
3342     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
3343       RebaseType = ImmValue;
3344       if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) {
3345         *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3346                             Twine((int)RebaseType) + " for opcode at: 0x" +
3347                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3348         moveToEnd();
3349         return;
3350       }
3351       DEBUG_WITH_TYPE(
3352           "mach-o-rebase",
3353           dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3354                  << "RebaseType=" << (int) RebaseType << "\n");
3355       break;
3356     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3357       SegmentIndex = ImmValue;
3358       SegmentOffset = readULEB128(&error);
3359       if (error) {
3360         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3361                             Twine(error) + " for opcode at: 0x" +
3362                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3363         moveToEnd();
3364         return;
3365       }
3366       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3367                                                PointerSize);
3368       if (error) {
3369         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3370                             Twine(error) + " for opcode at: 0x" +
3371                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3372         moveToEnd();
3373         return;
3374       }
3375       DEBUG_WITH_TYPE(
3376           "mach-o-rebase",
3377           dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3378                  << "SegmentIndex=" << SegmentIndex << ", "
3379                  << format("SegmentOffset=0x%06X", SegmentOffset)
3380                  << "\n");
3381       break;
3382     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
3383       SegmentOffset += readULEB128(&error);
3384       if (error) {
3385         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3386                             " for opcode at: 0x" +
3387                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3388         moveToEnd();
3389         return;
3390       }
3391       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3392                                                PointerSize);
3393       if (error) {
3394         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3395                             " for opcode at: 0x" +
3396                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3397         moveToEnd();
3398         return;
3399       }
3400       DEBUG_WITH_TYPE("mach-o-rebase",
3401                       dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3402                              << format("SegmentOffset=0x%06X",
3403                                        SegmentOffset) << "\n");
3404       break;
3405     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
3406       SegmentOffset += ImmValue * PointerSize;
3407       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3408                                                PointerSize);
3409       if (error) {
3410         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3411                             Twine(error) + " for opcode at: 0x" +
3412                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3413         moveToEnd();
3414         return;
3415       }
3416       DEBUG_WITH_TYPE("mach-o-rebase",
3417                       dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3418                              << format("SegmentOffset=0x%06X",
3419                                        SegmentOffset) << "\n");
3420       break;
3421     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
3422       AdvanceAmount = PointerSize;
3423       Skip = 0;
3424       Count = ImmValue;
3425       if (ImmValue != 0)
3426         RemainingLoopCount = ImmValue - 1;
3427       else
3428         RemainingLoopCount = 0;
3429       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3430                                                PointerSize, Count, Skip);
3431       if (error) {
3432         *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3433                             Twine(error) + " for opcode at: 0x" +
3434                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3435         moveToEnd();
3436         return;
3437       }
3438       DEBUG_WITH_TYPE(
3439           "mach-o-rebase",
3440           dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3441                  << format("SegmentOffset=0x%06X", SegmentOffset)
3442                  << ", AdvanceAmount=" << AdvanceAmount
3443                  << ", RemainingLoopCount=" << RemainingLoopCount
3444                  << "\n");
3445       return;
3446     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
3447       AdvanceAmount = PointerSize;
3448       Skip = 0;
3449       Count = readULEB128(&error);
3450       if (error) {
3451         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3452                             Twine(error) + " for opcode at: 0x" +
3453                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3454         moveToEnd();
3455         return;
3456       }
3457       if (Count != 0)
3458         RemainingLoopCount = Count - 1;
3459       else
3460         RemainingLoopCount = 0;
3461       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3462                                                PointerSize, Count, Skip);
3463       if (error) {
3464         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3465                             Twine(error) + " for opcode at: 0x" +
3466                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3467         moveToEnd();
3468         return;
3469       }
3470       DEBUG_WITH_TYPE(
3471           "mach-o-rebase",
3472           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3473                  << format("SegmentOffset=0x%06X", SegmentOffset)
3474                  << ", AdvanceAmount=" << AdvanceAmount
3475                  << ", RemainingLoopCount=" << RemainingLoopCount
3476                  << "\n");
3477       return;
3478     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
3479       Skip = readULEB128(&error);
3480       if (error) {
3481         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3482                             Twine(error) + " for opcode at: 0x" +
3483                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3484         moveToEnd();
3485         return;
3486       }
3487       AdvanceAmount = Skip + PointerSize;
3488       Count = 1;
3489       RemainingLoopCount = 0;
3490       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3491                                                PointerSize, Count, Skip);
3492       if (error) {
3493         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3494                             Twine(error) + " for opcode at: 0x" +
3495                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3496         moveToEnd();
3497         return;
3498       }
3499       DEBUG_WITH_TYPE(
3500           "mach-o-rebase",
3501           dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3502                  << format("SegmentOffset=0x%06X", SegmentOffset)
3503                  << ", AdvanceAmount=" << AdvanceAmount
3504                  << ", RemainingLoopCount=" << RemainingLoopCount
3505                  << "\n");
3506       return;
3507     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
3508       Count = readULEB128(&error);
3509       if (error) {
3510         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3511                             "ULEB " +
3512                             Twine(error) + " for opcode at: 0x" +
3513                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3514         moveToEnd();
3515         return;
3516       }
3517       if (Count != 0)
3518         RemainingLoopCount = Count - 1;
3519       else
3520         RemainingLoopCount = 0;
3521       Skip = readULEB128(&error);
3522       if (error) {
3523         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3524                             "ULEB " +
3525                             Twine(error) + " for opcode at: 0x" +
3526                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3527         moveToEnd();
3528         return;
3529       }
3530       AdvanceAmount = Skip + PointerSize;
3531 
3532       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3533                                                PointerSize, Count, Skip);
3534       if (error) {
3535         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3536                             "ULEB " +
3537                             Twine(error) + " for opcode at: 0x" +
3538                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3539         moveToEnd();
3540         return;
3541       }
3542       DEBUG_WITH_TYPE(
3543           "mach-o-rebase",
3544           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3545                  << format("SegmentOffset=0x%06X", SegmentOffset)
3546                  << ", AdvanceAmount=" << AdvanceAmount
3547                  << ", RemainingLoopCount=" << RemainingLoopCount
3548                  << "\n");
3549       return;
3550     default:
3551       *E = malformedError("bad rebase info (bad opcode value 0x" +
3552                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3553                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3554       moveToEnd();
3555       return;
3556     }
3557   }
3558 }
3559 
3560 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3561   unsigned Count;
3562   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3563   Ptr += Count;
3564   if (Ptr > Opcodes.end())
3565     Ptr = Opcodes.end();
3566   return Result;
3567 }
3568 
3569 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3570 
3571 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
3572 
3573 StringRef MachORebaseEntry::typeName() const {
3574   switch (RebaseType) {
3575   case MachO::REBASE_TYPE_POINTER:
3576     return "pointer";
3577   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
3578     return "text abs32";
3579   case MachO::REBASE_TYPE_TEXT_PCREL32:
3580     return "text rel32";
3581   }
3582   return "unknown";
3583 }
3584 
3585 // For use with the SegIndex of a checked Mach-O Rebase entry
3586 // to get the segment name.
3587 StringRef MachORebaseEntry::segmentName() const {
3588   return O->BindRebaseSegmentName(SegmentIndex);
3589 }
3590 
3591 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3592 // to get the section name.
3593 StringRef MachORebaseEntry::sectionName() const {
3594   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3595 }
3596 
3597 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3598 // to get the address.
3599 uint64_t MachORebaseEntry::address() const {
3600   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3601 }
3602 
3603 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
3604 #ifdef EXPENSIVE_CHECKS
3605   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3606 #else
3607   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3608 #endif
3609   return (Ptr == Other.Ptr) &&
3610          (RemainingLoopCount == Other.RemainingLoopCount) &&
3611          (Done == Other.Done);
3612 }
3613 
3614 iterator_range<rebase_iterator>
3615 MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O,
3616                              ArrayRef<uint8_t> Opcodes, bool is64) {
3617   if (O->BindRebaseSectionTable == nullptr)
3618     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3619   MachORebaseEntry Start(&Err, O, Opcodes, is64);
3620   Start.moveToFirst();
3621 
3622   MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3623   Finish.moveToEnd();
3624 
3625   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3626 }
3627 
3628 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) {
3629   return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3630 }
3631 
3632 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O,
3633                                ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3634     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3635       PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3636 
3637 void MachOBindEntry::moveToFirst() {
3638   Ptr = Opcodes.begin();
3639   moveNext();
3640 }
3641 
3642 void MachOBindEntry::moveToEnd() {
3643   Ptr = Opcodes.end();
3644   RemainingLoopCount = 0;
3645   Done = true;
3646 }
3647 
3648 void MachOBindEntry::moveNext() {
3649   ErrorAsOutParameter ErrAsOutParam(E);
3650   // If in the middle of some loop, move to next binding in loop.
3651   SegmentOffset += AdvanceAmount;
3652   if (RemainingLoopCount) {
3653     --RemainingLoopCount;
3654     return;
3655   }
3656   // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3657   // pointer size. Therefore it is possible to reach the end without ever having
3658   // seen BIND_OPCODE_DONE.
3659   if (Ptr == Opcodes.end()) {
3660     Done = true;
3661     return;
3662   }
3663   bool More = true;
3664   while (More) {
3665     // Parse next opcode and set up next loop.
3666     const uint8_t *OpcodeStart = Ptr;
3667     uint8_t Byte = *Ptr++;
3668     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3669     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3670     int8_t SignExtended;
3671     const uint8_t *SymStart;
3672     uint32_t Count, Skip;
3673     const char *error = nullptr;
3674     switch (Opcode) {
3675     case MachO::BIND_OPCODE_DONE:
3676       if (TableKind == Kind::Lazy) {
3677         // Lazying bindings have a DONE opcode between entries.  Need to ignore
3678         // it to advance to next entry.  But need not if this is last entry.
3679         bool NotLastEntry = false;
3680         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3681           if (*P) {
3682             NotLastEntry = true;
3683           }
3684         }
3685         if (NotLastEntry)
3686           break;
3687       }
3688       More = false;
3689       moveToEnd();
3690       DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3691       break;
3692     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
3693       if (TableKind == Kind::Weak) {
3694         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3695                             "weak bind table for opcode at: 0x" +
3696                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3697         moveToEnd();
3698         return;
3699       }
3700       Ordinal = ImmValue;
3701       LibraryOrdinalSet = true;
3702       if (ImmValue > O->getLibraryCount()) {
3703         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3704                             "library ordinal: " +
3705                             Twine((int)ImmValue) + " (max " +
3706                             Twine((int)O->getLibraryCount()) +
3707                             ") for opcode at: 0x" +
3708                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3709         moveToEnd();
3710         return;
3711       }
3712       DEBUG_WITH_TYPE(
3713           "mach-o-bind",
3714           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3715                  << "Ordinal=" << Ordinal << "\n");
3716       break;
3717     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
3718       if (TableKind == Kind::Weak) {
3719         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3720                             "weak bind table for opcode at: 0x" +
3721                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3722         moveToEnd();
3723         return;
3724       }
3725       Ordinal = readULEB128(&error);
3726       LibraryOrdinalSet = true;
3727       if (error) {
3728         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3729                             Twine(error) + " for opcode at: 0x" +
3730                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3731         moveToEnd();
3732         return;
3733       }
3734       if (Ordinal > (int)O->getLibraryCount()) {
3735         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3736                             "library ordinal: " +
3737                             Twine((int)Ordinal) + " (max " +
3738                             Twine((int)O->getLibraryCount()) +
3739                             ") for opcode at: 0x" +
3740                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3741         moveToEnd();
3742         return;
3743       }
3744       DEBUG_WITH_TYPE(
3745           "mach-o-bind",
3746           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3747                  << "Ordinal=" << Ordinal << "\n");
3748       break;
3749     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
3750       if (TableKind == Kind::Weak) {
3751         *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3752                             "weak bind table for opcode at: 0x" +
3753                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3754         moveToEnd();
3755         return;
3756       }
3757       if (ImmValue) {
3758         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3759         Ordinal = SignExtended;
3760         if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3761           *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3762                               "special ordinal: " +
3763                               Twine((int)Ordinal) + " for opcode at: 0x" +
3764                               Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3765           moveToEnd();
3766           return;
3767         }
3768       } else
3769         Ordinal = 0;
3770       LibraryOrdinalSet = true;
3771       DEBUG_WITH_TYPE(
3772           "mach-o-bind",
3773           dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3774                  << "Ordinal=" << Ordinal << "\n");
3775       break;
3776     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
3777       Flags = ImmValue;
3778       SymStart = Ptr;
3779       while (*Ptr && (Ptr < Opcodes.end())) {
3780         ++Ptr;
3781       }
3782       if (Ptr == Opcodes.end()) {
3783         *E = malformedError(
3784             "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3785             "symbol name extends past opcodes for opcode at: 0x" +
3786             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3787         moveToEnd();
3788         return;
3789       }
3790       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3791                              Ptr-SymStart);
3792       ++Ptr;
3793       DEBUG_WITH_TYPE(
3794           "mach-o-bind",
3795           dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3796                  << "SymbolName=" << SymbolName << "\n");
3797       if (TableKind == Kind::Weak) {
3798         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
3799           return;
3800       }
3801       break;
3802     case MachO::BIND_OPCODE_SET_TYPE_IMM:
3803       BindType = ImmValue;
3804       if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3805         *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3806                             Twine((int)ImmValue) + " for opcode at: 0x" +
3807                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3808         moveToEnd();
3809         return;
3810       }
3811       DEBUG_WITH_TYPE(
3812           "mach-o-bind",
3813           dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3814                  << "BindType=" << (int)BindType << "\n");
3815       break;
3816     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
3817       Addend = readSLEB128(&error);
3818       if (error) {
3819         *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3820                             " for opcode at: 0x" +
3821                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3822         moveToEnd();
3823         return;
3824       }
3825       DEBUG_WITH_TYPE(
3826           "mach-o-bind",
3827           dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3828                  << "Addend=" << Addend << "\n");
3829       break;
3830     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3831       SegmentIndex = ImmValue;
3832       SegmentOffset = readULEB128(&error);
3833       if (error) {
3834         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3835                             Twine(error) + " for opcode at: 0x" +
3836                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3837         moveToEnd();
3838         return;
3839       }
3840       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3841                                              PointerSize);
3842       if (error) {
3843         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3844                             Twine(error) + " for opcode at: 0x" +
3845                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3846         moveToEnd();
3847         return;
3848       }
3849       DEBUG_WITH_TYPE(
3850           "mach-o-bind",
3851           dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3852                  << "SegmentIndex=" << SegmentIndex << ", "
3853                  << format("SegmentOffset=0x%06X", SegmentOffset)
3854                  << "\n");
3855       break;
3856     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
3857       SegmentOffset += readULEB128(&error);
3858       if (error) {
3859         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3860                             " for opcode at: 0x" +
3861                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3862         moveToEnd();
3863         return;
3864       }
3865       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3866                                              PointerSize);
3867       if (error) {
3868         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3869                             " for opcode at: 0x" +
3870                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3871         moveToEnd();
3872         return;
3873       }
3874       DEBUG_WITH_TYPE("mach-o-bind",
3875                       dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3876                              << format("SegmentOffset=0x%06X",
3877                                        SegmentOffset) << "\n");
3878       break;
3879     case MachO::BIND_OPCODE_DO_BIND:
3880       AdvanceAmount = PointerSize;
3881       RemainingLoopCount = 0;
3882       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3883                                              PointerSize);
3884       if (error) {
3885         *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3886                             " for opcode at: 0x" +
3887                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3888         moveToEnd();
3889         return;
3890       }
3891       if (SymbolName == StringRef()) {
3892         *E = malformedError(
3893             "for BIND_OPCODE_DO_BIND missing preceding "
3894             "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3895             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3896         moveToEnd();
3897         return;
3898       }
3899       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3900         *E =
3901             malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3902                            "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3903                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3904         moveToEnd();
3905         return;
3906       }
3907       DEBUG_WITH_TYPE("mach-o-bind",
3908                       dbgs() << "BIND_OPCODE_DO_BIND: "
3909                              << format("SegmentOffset=0x%06X",
3910                                        SegmentOffset) << "\n");
3911       return;
3912      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
3913       if (TableKind == Kind::Lazy) {
3914         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3915                             "lazy bind table for opcode at: 0x" +
3916                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3917         moveToEnd();
3918         return;
3919       }
3920       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3921                                              PointerSize);
3922       if (error) {
3923         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3924                             Twine(error) + " for opcode at: 0x" +
3925                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3926         moveToEnd();
3927         return;
3928       }
3929       if (SymbolName == StringRef()) {
3930         *E = malformedError(
3931             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3932             "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3933             "at: 0x" +
3934             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3935         moveToEnd();
3936         return;
3937       }
3938       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3939         *E = malformedError(
3940             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3941             "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3942             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3943         moveToEnd();
3944         return;
3945       }
3946       AdvanceAmount = readULEB128(&error) + PointerSize;
3947       if (error) {
3948         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3949                             Twine(error) + " for opcode at: 0x" +
3950                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3951         moveToEnd();
3952         return;
3953       }
3954       // Note, this is not really an error until the next bind but make no sense
3955       // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3956       // bind operation.
3957       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
3958                                             AdvanceAmount, PointerSize);
3959       if (error) {
3960         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3961                             "ULEB) " +
3962                             Twine(error) + " for opcode at: 0x" +
3963                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3964         moveToEnd();
3965         return;
3966       }
3967       RemainingLoopCount = 0;
3968       DEBUG_WITH_TYPE(
3969           "mach-o-bind",
3970           dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3971                  << format("SegmentOffset=0x%06X", SegmentOffset)
3972                  << ", AdvanceAmount=" << AdvanceAmount
3973                  << ", RemainingLoopCount=" << RemainingLoopCount
3974                  << "\n");
3975       return;
3976     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
3977       if (TableKind == Kind::Lazy) {
3978         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3979                             "allowed in lazy bind table for opcode at: 0x" +
3980                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3981         moveToEnd();
3982         return;
3983       }
3984       if (SymbolName == StringRef()) {
3985         *E = malformedError(
3986             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3987             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3988             "opcode at: 0x" +
3989             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3990         moveToEnd();
3991         return;
3992       }
3993       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3994         *E = malformedError(
3995             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3996             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3997             "at: 0x" +
3998             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3999         moveToEnd();
4000         return;
4001       }
4002       AdvanceAmount = ImmValue * PointerSize + PointerSize;
4003       RemainingLoopCount = 0;
4004       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4005                                              AdvanceAmount, PointerSize);
4006       if (error) {
4007         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4008                             Twine(error) + " for opcode at: 0x" +
4009                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4010         moveToEnd();
4011         return;
4012       }
4013       DEBUG_WITH_TYPE("mach-o-bind",
4014                       dbgs()
4015                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4016                       << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4017       return;
4018     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
4019       if (TableKind == Kind::Lazy) {
4020         *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4021                             "allowed in lazy bind table for opcode at: 0x" +
4022                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4023         moveToEnd();
4024         return;
4025       }
4026       Count = readULEB128(&error);
4027       if (Count != 0)
4028         RemainingLoopCount = Count - 1;
4029       else
4030         RemainingLoopCount = 0;
4031       if (error) {
4032         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4033                             " (count value) " +
4034                             Twine(error) + " for opcode at: 0x" +
4035                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4036         moveToEnd();
4037         return;
4038       }
4039       Skip = readULEB128(&error);
4040       AdvanceAmount = Skip + PointerSize;
4041       if (error) {
4042         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4043                             " (skip value) " +
4044                             Twine(error) + " for opcode at: 0x" +
4045                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4046         moveToEnd();
4047         return;
4048       }
4049       if (SymbolName == StringRef()) {
4050         *E = malformedError(
4051             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4052             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4053             "opcode at: 0x" +
4054             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4055         moveToEnd();
4056         return;
4057       }
4058       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4059         *E = malformedError(
4060             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4061             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4062             "at: 0x" +
4063             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4064         moveToEnd();
4065         return;
4066       }
4067       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4068                                              PointerSize, Count, Skip);
4069       if (error) {
4070         *E =
4071             malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4072                            Twine(error) + " for opcode at: 0x" +
4073                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4074         moveToEnd();
4075         return;
4076       }
4077       DEBUG_WITH_TYPE(
4078           "mach-o-bind",
4079           dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4080                  << format("SegmentOffset=0x%06X", SegmentOffset)
4081                  << ", AdvanceAmount=" << AdvanceAmount
4082                  << ", RemainingLoopCount=" << RemainingLoopCount
4083                  << "\n");
4084       return;
4085     default:
4086       *E = malformedError("bad bind info (bad opcode value 0x" +
4087                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
4088                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4089       moveToEnd();
4090       return;
4091     }
4092   }
4093 }
4094 
4095 uint64_t MachOBindEntry::readULEB128(const char **error) {
4096   unsigned Count;
4097   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
4098   Ptr += Count;
4099   if (Ptr > Opcodes.end())
4100     Ptr = Opcodes.end();
4101   return Result;
4102 }
4103 
4104 int64_t MachOBindEntry::readSLEB128(const char **error) {
4105   unsigned Count;
4106   int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
4107   Ptr += Count;
4108   if (Ptr > Opcodes.end())
4109     Ptr = Opcodes.end();
4110   return Result;
4111 }
4112 
4113 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
4114 
4115 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
4116 
4117 StringRef MachOBindEntry::typeName() const {
4118   switch (BindType) {
4119   case MachO::BIND_TYPE_POINTER:
4120     return "pointer";
4121   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
4122     return "text abs32";
4123   case MachO::BIND_TYPE_TEXT_PCREL32:
4124     return "text rel32";
4125   }
4126   return "unknown";
4127 }
4128 
4129 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
4130 
4131 int64_t MachOBindEntry::addend() const { return Addend; }
4132 
4133 uint32_t MachOBindEntry::flags() const { return Flags; }
4134 
4135 int MachOBindEntry::ordinal() const { return Ordinal; }
4136 
4137 // For use with the SegIndex of a checked Mach-O Bind entry
4138 // to get the segment name.
4139 StringRef MachOBindEntry::segmentName() const {
4140   return O->BindRebaseSegmentName(SegmentIndex);
4141 }
4142 
4143 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4144 // to get the section name.
4145 StringRef MachOBindEntry::sectionName() const {
4146   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4147 }
4148 
4149 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4150 // to get the address.
4151 uint64_t MachOBindEntry::address() const {
4152   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4153 }
4154 
4155 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
4156 #ifdef EXPENSIVE_CHECKS
4157   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4158 #else
4159   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4160 #endif
4161   return (Ptr == Other.Ptr) &&
4162          (RemainingLoopCount == Other.RemainingLoopCount) &&
4163          (Done == Other.Done);
4164 }
4165 
4166 // Build table of sections so SegIndex/SegOffset pairs can be translated.
4167 BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
4168   uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4169   StringRef CurSegName;
4170   uint64_t CurSegAddress;
4171   for (const SectionRef &Section : Obj->sections()) {
4172     SectionInfo Info;
4173     Expected<StringRef> NameOrErr = Section.getName();
4174     if (!NameOrErr)
4175       consumeError(NameOrErr.takeError());
4176     else
4177       Info.SectionName = *NameOrErr;
4178     Info.Address = Section.getAddress();
4179     Info.Size = Section.getSize();
4180     Info.SegmentName =
4181         Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4182     if (!Info.SegmentName.equals(CurSegName)) {
4183       ++CurSegIndex;
4184       CurSegName = Info.SegmentName;
4185       CurSegAddress = Info.Address;
4186     }
4187     Info.SegmentIndex = CurSegIndex - 1;
4188     Info.OffsetInSegment = Info.Address - CurSegAddress;
4189     Info.SegmentStartAddress = CurSegAddress;
4190     Sections.push_back(Info);
4191   }
4192   MaxSegIndex = CurSegIndex;
4193 }
4194 
4195 // For use with a SegIndex, SegOffset, and PointerSize triple in
4196 // MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry.
4197 //
4198 // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
4199 // that fully contains a pointer at that location. Multiple fixups in a bind
4200 // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
4201 // be tested via the Count and Skip parameters.
4202 const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
4203                                                    uint64_t SegOffset,
4204                                                    uint8_t PointerSize,
4205                                                    uint32_t Count,
4206                                                    uint32_t Skip) {
4207   if (SegIndex == -1)
4208     return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4209   if (SegIndex >= MaxSegIndex)
4210     return "bad segIndex (too large)";
4211   for (uint32_t i = 0; i < Count; ++i) {
4212     uint32_t Start = SegOffset + i * (PointerSize + Skip);
4213     uint32_t End = Start + PointerSize;
4214     bool Found = false;
4215     for (const SectionInfo &SI : Sections) {
4216       if (SI.SegmentIndex != SegIndex)
4217         continue;
4218       if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4219         if (End <= SI.OffsetInSegment + SI.Size) {
4220           Found = true;
4221           break;
4222         }
4223         else
4224           return "bad offset, extends beyond section boundary";
4225       }
4226     }
4227     if (!Found)
4228       return "bad offset, not in section";
4229   }
4230   return nullptr;
4231 }
4232 
4233 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4234 // to get the segment name.
4235 StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) {
4236   for (const SectionInfo &SI : Sections) {
4237     if (SI.SegmentIndex == SegIndex)
4238       return SI.SegmentName;
4239   }
4240   llvm_unreachable("invalid SegIndex");
4241 }
4242 
4243 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4244 // to get the SectionInfo.
4245 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4246                                      int32_t SegIndex, uint64_t SegOffset) {
4247   for (const SectionInfo &SI : Sections) {
4248     if (SI.SegmentIndex != SegIndex)
4249       continue;
4250     if (SI.OffsetInSegment > SegOffset)
4251       continue;
4252     if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4253       continue;
4254     return SI;
4255   }
4256   llvm_unreachable("SegIndex and SegOffset not in any section");
4257 }
4258 
4259 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4260 // entry to get the section name.
4261 StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex,
4262                                          uint64_t SegOffset) {
4263   return findSection(SegIndex, SegOffset).SectionName;
4264 }
4265 
4266 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4267 // entry to get the address.
4268 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4269   const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4270   return SI.SegmentStartAddress + OffsetInSeg;
4271 }
4272 
4273 iterator_range<bind_iterator>
4274 MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O,
4275                            ArrayRef<uint8_t> Opcodes, bool is64,
4276                            MachOBindEntry::Kind BKind) {
4277   if (O->BindRebaseSectionTable == nullptr)
4278     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4279   MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4280   Start.moveToFirst();
4281 
4282   MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4283   Finish.moveToEnd();
4284 
4285   return make_range(bind_iterator(Start), bind_iterator(Finish));
4286 }
4287 
4288 iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) {
4289   return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4290                    MachOBindEntry::Kind::Regular);
4291 }
4292 
4293 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) {
4294   return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4295                    MachOBindEntry::Kind::Lazy);
4296 }
4297 
4298 iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
4299   return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4300                    MachOBindEntry::Kind::Weak);
4301 }
4302 
4303 iterator_range<fixup_iterator> MachOObjectFile::fixupTable(Error &Err) {
4304   MachOChainedFixupEntry Start(&Err, this, true);
4305   Start.moveToFirst();
4306 
4307   MachOChainedFixupEntry Finish(&Err, this, false);
4308   Finish.moveToEnd();
4309 
4310   return make_range(fixup_iterator(Start), fixup_iterator(Finish));
4311 }
4312 
4313 MachOObjectFile::load_command_iterator
4314 MachOObjectFile::begin_load_commands() const {
4315   return LoadCommands.begin();
4316 }
4317 
4318 MachOObjectFile::load_command_iterator
4319 MachOObjectFile::end_load_commands() const {
4320   return LoadCommands.end();
4321 }
4322 
4323 iterator_range<MachOObjectFile::load_command_iterator>
4324 MachOObjectFile::load_commands() const {
4325   return make_range(begin_load_commands(), end_load_commands());
4326 }
4327 
4328 StringRef
4329 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
4330   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4331   return parseSegmentOrSectionName(Raw.data());
4332 }
4333 
4334 ArrayRef<char>
4335 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
4336   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4337   const section_base *Base =
4338     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4339   return makeArrayRef(Base->sectname);
4340 }
4341 
4342 ArrayRef<char>
4343 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
4344   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4345   const section_base *Base =
4346     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4347   return makeArrayRef(Base->segname);
4348 }
4349 
4350 bool
4351 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
4352   const {
4353   if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4354     return false;
4355   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
4356 }
4357 
4358 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
4359     const MachO::any_relocation_info &RE) const {
4360   if (isLittleEndian())
4361     return RE.r_word1 & 0xffffff;
4362   return RE.r_word1 >> 8;
4363 }
4364 
4365 bool MachOObjectFile::getPlainRelocationExternal(
4366     const MachO::any_relocation_info &RE) const {
4367   if (isLittleEndian())
4368     return (RE.r_word1 >> 27) & 1;
4369   return (RE.r_word1 >> 4) & 1;
4370 }
4371 
4372 bool MachOObjectFile::getScatteredRelocationScattered(
4373     const MachO::any_relocation_info &RE) const {
4374   return RE.r_word0 >> 31;
4375 }
4376 
4377 uint32_t MachOObjectFile::getScatteredRelocationValue(
4378     const MachO::any_relocation_info &RE) const {
4379   return RE.r_word1;
4380 }
4381 
4382 uint32_t MachOObjectFile::getScatteredRelocationType(
4383     const MachO::any_relocation_info &RE) const {
4384   return (RE.r_word0 >> 24) & 0xf;
4385 }
4386 
4387 unsigned MachOObjectFile::getAnyRelocationAddress(
4388     const MachO::any_relocation_info &RE) const {
4389   if (isRelocationScattered(RE))
4390     return getScatteredRelocationAddress(RE);
4391   return getPlainRelocationAddress(RE);
4392 }
4393 
4394 unsigned MachOObjectFile::getAnyRelocationPCRel(
4395     const MachO::any_relocation_info &RE) const {
4396   if (isRelocationScattered(RE))
4397     return getScatteredRelocationPCRel(RE);
4398   return getPlainRelocationPCRel(*this, RE);
4399 }
4400 
4401 unsigned MachOObjectFile::getAnyRelocationLength(
4402     const MachO::any_relocation_info &RE) const {
4403   if (isRelocationScattered(RE))
4404     return getScatteredRelocationLength(RE);
4405   return getPlainRelocationLength(*this, RE);
4406 }
4407 
4408 unsigned
4409 MachOObjectFile::getAnyRelocationType(
4410                                    const MachO::any_relocation_info &RE) const {
4411   if (isRelocationScattered(RE))
4412     return getScatteredRelocationType(RE);
4413   return getPlainRelocationType(*this, RE);
4414 }
4415 
4416 SectionRef
4417 MachOObjectFile::getAnyRelocationSection(
4418                                    const MachO::any_relocation_info &RE) const {
4419   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4420     return *section_end();
4421   unsigned SecNum = getPlainRelocationSymbolNum(RE);
4422   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4423     return *section_end();
4424   DataRefImpl DRI;
4425   DRI.d.a = SecNum - 1;
4426   return SectionRef(DRI, this);
4427 }
4428 
4429 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
4430   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4431   return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4432 }
4433 
4434 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
4435   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4436   return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4437 }
4438 
4439 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
4440                                            unsigned Index) const {
4441   const char *Sec = getSectionPtr(*this, L, Index);
4442   return getStruct<MachO::section>(*this, Sec);
4443 }
4444 
4445 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
4446                                                 unsigned Index) const {
4447   const char *Sec = getSectionPtr(*this, L, Index);
4448   return getStruct<MachO::section_64>(*this, Sec);
4449 }
4450 
4451 MachO::nlist
4452 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
4453   const char *P = reinterpret_cast<const char *>(DRI.p);
4454   return getStruct<MachO::nlist>(*this, P);
4455 }
4456 
4457 MachO::nlist_64
4458 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
4459   const char *P = reinterpret_cast<const char *>(DRI.p);
4460   return getStruct<MachO::nlist_64>(*this, P);
4461 }
4462 
4463 MachO::linkedit_data_command
4464 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
4465   return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4466 }
4467 
4468 MachO::segment_command
4469 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
4470   return getStruct<MachO::segment_command>(*this, L.Ptr);
4471 }
4472 
4473 MachO::segment_command_64
4474 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
4475   return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4476 }
4477 
4478 MachO::linker_option_command
4479 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
4480   return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4481 }
4482 
4483 MachO::version_min_command
4484 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
4485   return getStruct<MachO::version_min_command>(*this, L.Ptr);
4486 }
4487 
4488 MachO::note_command
4489 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
4490   return getStruct<MachO::note_command>(*this, L.Ptr);
4491 }
4492 
4493 MachO::build_version_command
4494 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
4495   return getStruct<MachO::build_version_command>(*this, L.Ptr);
4496 }
4497 
4498 MachO::build_tool_version
4499 MachOObjectFile::getBuildToolVersion(unsigned index) const {
4500   return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4501 }
4502 
4503 MachO::dylib_command
4504 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
4505   return getStruct<MachO::dylib_command>(*this, L.Ptr);
4506 }
4507 
4508 MachO::dyld_info_command
4509 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
4510   return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4511 }
4512 
4513 MachO::dylinker_command
4514 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
4515   return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4516 }
4517 
4518 MachO::uuid_command
4519 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
4520   return getStruct<MachO::uuid_command>(*this, L.Ptr);
4521 }
4522 
4523 MachO::rpath_command
4524 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
4525   return getStruct<MachO::rpath_command>(*this, L.Ptr);
4526 }
4527 
4528 MachO::source_version_command
4529 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
4530   return getStruct<MachO::source_version_command>(*this, L.Ptr);
4531 }
4532 
4533 MachO::entry_point_command
4534 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
4535   return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4536 }
4537 
4538 MachO::encryption_info_command
4539 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
4540   return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4541 }
4542 
4543 MachO::encryption_info_command_64
4544 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
4545   return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4546 }
4547 
4548 MachO::sub_framework_command
4549 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
4550   return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4551 }
4552 
4553 MachO::sub_umbrella_command
4554 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
4555   return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4556 }
4557 
4558 MachO::sub_library_command
4559 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
4560   return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4561 }
4562 
4563 MachO::sub_client_command
4564 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
4565   return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4566 }
4567 
4568 MachO::routines_command
4569 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
4570   return getStruct<MachO::routines_command>(*this, L.Ptr);
4571 }
4572 
4573 MachO::routines_command_64
4574 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
4575   return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4576 }
4577 
4578 MachO::thread_command
4579 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
4580   return getStruct<MachO::thread_command>(*this, L.Ptr);
4581 }
4582 
4583 MachO::any_relocation_info
4584 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
4585   uint32_t Offset;
4586   if (getHeader().filetype == MachO::MH_OBJECT) {
4587     DataRefImpl Sec;
4588     Sec.d.a = Rel.d.a;
4589     if (is64Bit()) {
4590       MachO::section_64 Sect = getSection64(Sec);
4591       Offset = Sect.reloff;
4592     } else {
4593       MachO::section Sect = getSection(Sec);
4594       Offset = Sect.reloff;
4595     }
4596   } else {
4597     MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4598     if (Rel.d.a == 0)
4599       Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4600     else
4601       Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4602   }
4603 
4604   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4605       getPtr(*this, Offset)) + Rel.d.b;
4606   return getStruct<MachO::any_relocation_info>(
4607       *this, reinterpret_cast<const char *>(P));
4608 }
4609 
4610 MachO::data_in_code_entry
4611 MachOObjectFile::getDice(DataRefImpl Rel) const {
4612   const char *P = reinterpret_cast<const char *>(Rel.p);
4613   return getStruct<MachO::data_in_code_entry>(*this, P);
4614 }
4615 
4616 const MachO::mach_header &MachOObjectFile::getHeader() const {
4617   return Header;
4618 }
4619 
4620 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
4621   assert(is64Bit());
4622   return Header64;
4623 }
4624 
4625 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
4626                                              const MachO::dysymtab_command &DLC,
4627                                              unsigned Index) const {
4628   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4629   return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4630 }
4631 
4632 MachO::data_in_code_entry
4633 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
4634                                          unsigned Index) const {
4635   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4636   return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4637 }
4638 
4639 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
4640   if (SymtabLoadCmd)
4641     return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4642 
4643   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4644   MachO::symtab_command Cmd;
4645   Cmd.cmd = MachO::LC_SYMTAB;
4646   Cmd.cmdsize = sizeof(MachO::symtab_command);
4647   Cmd.symoff = 0;
4648   Cmd.nsyms = 0;
4649   Cmd.stroff = 0;
4650   Cmd.strsize = 0;
4651   return Cmd;
4652 }
4653 
4654 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
4655   if (DysymtabLoadCmd)
4656     return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4657 
4658   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4659   MachO::dysymtab_command Cmd;
4660   Cmd.cmd = MachO::LC_DYSYMTAB;
4661   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4662   Cmd.ilocalsym = 0;
4663   Cmd.nlocalsym = 0;
4664   Cmd.iextdefsym = 0;
4665   Cmd.nextdefsym = 0;
4666   Cmd.iundefsym = 0;
4667   Cmd.nundefsym = 0;
4668   Cmd.tocoff = 0;
4669   Cmd.ntoc = 0;
4670   Cmd.modtaboff = 0;
4671   Cmd.nmodtab = 0;
4672   Cmd.extrefsymoff = 0;
4673   Cmd.nextrefsyms = 0;
4674   Cmd.indirectsymoff = 0;
4675   Cmd.nindirectsyms = 0;
4676   Cmd.extreloff = 0;
4677   Cmd.nextrel = 0;
4678   Cmd.locreloff = 0;
4679   Cmd.nlocrel = 0;
4680   return Cmd;
4681 }
4682 
4683 MachO::linkedit_data_command
4684 MachOObjectFile::getDataInCodeLoadCommand() const {
4685   if (DataInCodeLoadCmd)
4686     return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4687 
4688   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4689   MachO::linkedit_data_command Cmd;
4690   Cmd.cmd = MachO::LC_DATA_IN_CODE;
4691   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4692   Cmd.dataoff = 0;
4693   Cmd.datasize = 0;
4694   return Cmd;
4695 }
4696 
4697 MachO::linkedit_data_command
4698 MachOObjectFile::getLinkOptHintsLoadCommand() const {
4699   if (LinkOptHintsLoadCmd)
4700     return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4701 
4702   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4703   // fields.
4704   MachO::linkedit_data_command Cmd;
4705   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4706   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4707   Cmd.dataoff = 0;
4708   Cmd.datasize = 0;
4709   return Cmd;
4710 }
4711 
4712 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
4713   if (!DyldInfoLoadCmd)
4714     return None;
4715 
4716   auto DyldInfoOrErr =
4717     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4718   if (!DyldInfoOrErr)
4719     return None;
4720   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4721   const uint8_t *Ptr =
4722       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4723   return makeArrayRef(Ptr, DyldInfo.rebase_size);
4724 }
4725 
4726 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
4727   if (!DyldInfoLoadCmd)
4728     return None;
4729 
4730   auto DyldInfoOrErr =
4731     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4732   if (!DyldInfoOrErr)
4733     return None;
4734   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4735   const uint8_t *Ptr =
4736       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4737   return makeArrayRef(Ptr, DyldInfo.bind_size);
4738 }
4739 
4740 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
4741   if (!DyldInfoLoadCmd)
4742     return None;
4743 
4744   auto DyldInfoOrErr =
4745     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4746   if (!DyldInfoOrErr)
4747     return None;
4748   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4749   const uint8_t *Ptr =
4750       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4751   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4752 }
4753 
4754 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
4755   if (!DyldInfoLoadCmd)
4756     return None;
4757 
4758   auto DyldInfoOrErr =
4759     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4760   if (!DyldInfoOrErr)
4761     return None;
4762   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4763   const uint8_t *Ptr =
4764       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4765   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4766 }
4767 
4768 Expected<Optional<MachO::dyld_chained_fixups_header>>
4769 MachOObjectFile::getChainedFixupsHeader() const {
4770   // Load the dyld chained fixups load command.
4771   if (!DyldChainedFixupsLoadCmd)
4772     return llvm::None;
4773   auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
4774       *this, DyldChainedFixupsLoadCmd);
4775   if (!DyldChainedFixupsOrErr)
4776     return DyldChainedFixupsOrErr.takeError();
4777   MachO::linkedit_data_command DyldChainedFixups = DyldChainedFixupsOrErr.get();
4778 
4779   // If the load command is present but the data offset has been zeroed out,
4780   // as is the case for dylib stubs, return None (no error).
4781   uint64_t CFHeaderOffset = DyldChainedFixups.dataoff;
4782   if (CFHeaderOffset == 0)
4783     return DyldChainedFixupsOrErr.takeError();
4784 
4785   // Load the dyld chained fixups header.
4786   const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
4787   auto CFHeaderOrErr =
4788       getStructOrErr<MachO::dyld_chained_fixups_header>(*this, CFHeaderPtr);
4789   if (!CFHeaderOrErr)
4790     return CFHeaderOrErr.takeError();
4791   MachO::dyld_chained_fixups_header CFHeader = CFHeaderOrErr.get();
4792 
4793   // Reject unknown chained fixup formats.
4794   if (CFHeader.fixups_version != 0)
4795     return malformedError(Twine("bad chained fixups: unknown version: ") +
4796                           Twine(CFHeader.fixups_version));
4797   if (CFHeader.imports_format < 1 || CFHeader.imports_format > 3)
4798     return malformedError(
4799         Twine("bad chained fixups: unknown imports format: ") +
4800         Twine(CFHeader.imports_format));
4801 
4802   // Validate the image format.
4803   //
4804   // Load the image starts.
4805   uint64_t CFImageStartsOffset = (CFHeaderOffset + CFHeader.starts_offset);
4806   if (CFHeader.starts_offset < sizeof(MachO::dyld_chained_fixups_header)) {
4807     return malformedError(Twine("bad chained fixups: image starts offset ") +
4808                           Twine(CFHeader.starts_offset) +
4809                           " overlaps with chained fixups header");
4810   }
4811   uint32_t EndOffset = DyldChainedFixups.dataoff + DyldChainedFixups.datasize;
4812   if (CFImageStartsOffset + sizeof(MachO::dyld_chained_starts_in_image) >
4813       EndOffset) {
4814     return malformedError(Twine("bad chained fixups: image starts end ") +
4815                           Twine(CFImageStartsOffset +
4816                                 sizeof(MachO::dyld_chained_starts_in_image)) +
4817                           " extends past end " + Twine(EndOffset));
4818   }
4819 
4820   return CFHeader;
4821 }
4822 
4823 Expected<std::vector<ChainedFixupTarget>>
4824 MachOObjectFile::getDyldChainedFixupTargets() const {
4825   auto CFHeaderOrErr = getChainedFixupsHeader();
4826   if (!CFHeaderOrErr)
4827     return CFHeaderOrErr.takeError();
4828   std::vector<ChainedFixupTarget> Targets;
4829   if (!(*CFHeaderOrErr))
4830     return Targets;
4831   return Targets;
4832 }
4833 
4834 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
4835   if (!DyldInfoLoadCmd)
4836     return None;
4837 
4838   auto DyldInfoOrErr =
4839     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4840   if (!DyldInfoOrErr)
4841     return None;
4842   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4843   const uint8_t *Ptr =
4844       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
4845   return makeArrayRef(Ptr, DyldInfo.export_size);
4846 }
4847 
4848 SmallVector<uint64_t> MachOObjectFile::getFunctionStarts() const {
4849   if (!FuncStartsLoadCmd)
4850     return {};
4851 
4852   auto InfoOrErr =
4853       getStructOrErr<MachO::linkedit_data_command>(*this, FuncStartsLoadCmd);
4854   if (!InfoOrErr)
4855     return {};
4856 
4857   MachO::linkedit_data_command Info = InfoOrErr.get();
4858   SmallVector<uint64_t, 8> FunctionStarts;
4859   this->ReadULEB128s(Info.dataoff, FunctionStarts);
4860   return std::move(FunctionStarts);
4861 }
4862 
4863 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
4864   if (!UuidLoadCmd)
4865     return None;
4866   // Returning a pointer is fine as uuid doesn't need endian swapping.
4867   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
4868   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4869 }
4870 
4871 StringRef MachOObjectFile::getStringTableData() const {
4872   MachO::symtab_command S = getSymtabLoadCommand();
4873   return getData().substr(S.stroff, S.strsize);
4874 }
4875 
4876 bool MachOObjectFile::is64Bit() const {
4877   return getType() == getMachOType(false, true) ||
4878     getType() == getMachOType(true, true);
4879 }
4880 
4881 void MachOObjectFile::ReadULEB128s(uint64_t Index,
4882                                    SmallVectorImpl<uint64_t> &Out) const {
4883   DataExtractor extractor(ObjectFile::getData(), true, 0);
4884 
4885   uint64_t offset = Index;
4886   uint64_t data = 0;
4887   while (uint64_t delta = extractor.getULEB128(&offset)) {
4888     data += delta;
4889     Out.push_back(data);
4890   }
4891 }
4892 
4893 bool MachOObjectFile::isRelocatableObject() const {
4894   return getHeader().filetype == MachO::MH_OBJECT;
4895 }
4896 
4897 Expected<std::unique_ptr<MachOObjectFile>>
4898 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
4899                                   uint32_t UniversalCputype,
4900                                   uint32_t UniversalIndex) {
4901   StringRef Magic = Buffer.getBuffer().slice(0, 4);
4902   if (Magic == "\xFE\xED\xFA\xCE")
4903     return MachOObjectFile::create(Buffer, false, false,
4904                                    UniversalCputype, UniversalIndex);
4905   if (Magic == "\xCE\xFA\xED\xFE")
4906     return MachOObjectFile::create(Buffer, true, false,
4907                                    UniversalCputype, UniversalIndex);
4908   if (Magic == "\xFE\xED\xFA\xCF")
4909     return MachOObjectFile::create(Buffer, false, true,
4910                                    UniversalCputype, UniversalIndex);
4911   if (Magic == "\xCF\xFA\xED\xFE")
4912     return MachOObjectFile::create(Buffer, true, true,
4913                                    UniversalCputype, UniversalIndex);
4914   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
4915                                         object_error::invalid_file_type);
4916 }
4917 
4918 StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
4919   return StringSwitch<StringRef>(Name)
4920       .Case("debug_str_offs", "debug_str_offsets")
4921       .Default(Name);
4922 }
4923 
4924 Expected<std::vector<std::string>>
4925 MachOObjectFile::findDsymObjectMembers(StringRef Path) {
4926   SmallString<256> BundlePath(Path);
4927   // Normalize input path. This is necessary to accept `bundle.dSYM/`.
4928   sys::path::remove_dots(BundlePath);
4929   if (!sys::fs::is_directory(BundlePath) ||
4930       sys::path::extension(BundlePath) != ".dSYM")
4931     return std::vector<std::string>();
4932   sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
4933   bool IsDir;
4934   auto EC = sys::fs::is_directory(BundlePath, IsDir);
4935   if (EC == errc::no_such_file_or_directory || (!EC && !IsDir))
4936     return createStringError(
4937         EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
4938         Path.str().c_str());
4939   if (EC)
4940     return createFileError(BundlePath, errorCodeToError(EC));
4941 
4942   std::vector<std::string> ObjectPaths;
4943   for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
4944        Dir != DirEnd && !EC; Dir.increment(EC)) {
4945     StringRef ObjectPath = Dir->path();
4946     sys::fs::file_status Status;
4947     if (auto EC = sys::fs::status(ObjectPath, Status))
4948       return createFileError(ObjectPath, errorCodeToError(EC));
4949     switch (Status.type()) {
4950     case sys::fs::file_type::regular_file:
4951     case sys::fs::file_type::symlink_file:
4952     case sys::fs::file_type::type_unknown:
4953       ObjectPaths.push_back(ObjectPath.str());
4954       break;
4955     default: /*ignore*/;
4956     }
4957   }
4958   if (EC)
4959     return createFileError(BundlePath, errorCodeToError(EC));
4960   if (ObjectPaths.empty())
4961     return createStringError(std::error_code(),
4962                              "%s: no objects found in dSYM bundle",
4963                              Path.str().c_str());
4964   return ObjectPaths;
4965 }
4966 
4967 llvm::binaryformat::Swift5ReflectionSectionKind
4968 MachOObjectFile::mapReflectionSectionNameToEnumValue(
4969     StringRef SectionName) const {
4970 #define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF)                           \
4971   .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
4972   return StringSwitch<llvm::binaryformat::Swift5ReflectionSectionKind>(
4973              SectionName)
4974 #include "llvm/BinaryFormat/Swift.def"
4975       .Default(llvm::binaryformat::Swift5ReflectionSectionKind::unknown);
4976 #undef HANDLE_SWIFT_SECTION
4977 }
4978 
4979 bool MachOObjectFile::isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
4980   switch (Arch) {
4981   case Triple::x86:
4982     return RelocType == MachO::GENERIC_RELOC_SECTDIFF ||
4983            RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF;
4984   case Triple::x86_64:
4985     return RelocType == MachO::X86_64_RELOC_SUBTRACTOR;
4986   case Triple::arm:
4987   case Triple::thumb:
4988     return RelocType == MachO::ARM_RELOC_SECTDIFF ||
4989            RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
4990            RelocType == MachO::ARM_RELOC_HALF ||
4991            RelocType == MachO::ARM_RELOC_HALF_SECTDIFF;
4992   case Triple::aarch64:
4993     return RelocType == MachO::ARM64_RELOC_SUBTRACTOR;
4994   default:
4995     return false;
4996   }
4997 }
4998