xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision 105ddd0fdca0e585db6be05ee8f4a1941d113ca2)
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         if (State.Other > O->getLibraryCount()) {
3001           *E = malformedError(
3002               "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3003               Twine((int)O->getLibraryCount()) +
3004               ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3005           moveToEnd();
3006           return;
3007         }
3008       }
3009       State.ImportName = reinterpret_cast<const char*>(State.Current);
3010       if (*State.ImportName == '\0') {
3011         State.Current++;
3012       } else {
3013         const uint8_t *End = State.Current + 1;
3014         if (End >= Trie.end()) {
3015           *E = malformedError("import name of re-export in export trie data at "
3016                               "node: 0x" +
3017                               Twine::utohexstr(offset) +
3018                               " starts past end of trie data");
3019           moveToEnd();
3020           return;
3021         }
3022         while(*End != '\0' && End < Trie.end())
3023           End++;
3024         if (*End != '\0') {
3025           *E = malformedError("import name of re-export in export trie data at "
3026                               "node: 0x" +
3027                               Twine::utohexstr(offset) +
3028                               " extends past end of trie data");
3029           moveToEnd();
3030           return;
3031         }
3032         State.Current = End + 1;
3033       }
3034     } else {
3035       State.Address = readULEB128(State.Current, &error);
3036       if (error) {
3037         *E = malformedError("address " + Twine(error) +
3038                             " in export trie data at node: 0x" +
3039                             Twine::utohexstr(offset));
3040         moveToEnd();
3041         return;
3042       }
3043       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
3044         State.Other = readULEB128(State.Current, &error);
3045         if (error) {
3046           *E = malformedError("resolver of stub and resolver " + Twine(error) +
3047                               " in export trie data at node: 0x" +
3048                               Twine::utohexstr(offset));
3049           moveToEnd();
3050           return;
3051         }
3052       }
3053     }
3054     if(ExportStart + ExportInfoSize != State.Current) {
3055       *E = malformedError(
3056           "inconsistant export info size: 0x" +
3057           Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3058           Twine::utohexstr(State.Current - ExportStart) +
3059           " in export trie data at node: 0x" + Twine::utohexstr(offset));
3060       moveToEnd();
3061       return;
3062     }
3063   }
3064   State.ChildCount = *Children;
3065   if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3066     *E = malformedError("byte for count of childern in export trie data at "
3067                         "node: 0x" +
3068                         Twine::utohexstr(offset) +
3069                         " extends past end of trie data");
3070     moveToEnd();
3071     return;
3072   }
3073   State.Current = Children + 1;
3074   State.NextChildIndex = 0;
3075   State.ParentStringLength = CumulativeString.size();
3076   Stack.push_back(State);
3077 }
3078 
3079 void ExportEntry::pushDownUntilBottom() {
3080   ErrorAsOutParameter ErrAsOutParam(E);
3081   const char *error;
3082   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3083     NodeState &Top = Stack.back();
3084     CumulativeString.resize(Top.ParentStringLength);
3085     for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3086       char C = *Top.Current;
3087       CumulativeString.push_back(C);
3088     }
3089     if (Top.Current >= Trie.end()) {
3090       *E = malformedError("edge sub-string in export trie data at node: 0x" +
3091                           Twine::utohexstr(Top.Start - Trie.begin()) +
3092                           " for child #" + Twine((int)Top.NextChildIndex) +
3093                           " extends past end of trie data");
3094       moveToEnd();
3095       return;
3096     }
3097     Top.Current += 1;
3098     uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3099     if (error) {
3100       *E = malformedError("child node offset " + Twine(error) +
3101                           " in export trie data at node: 0x" +
3102                           Twine::utohexstr(Top.Start - Trie.begin()));
3103       moveToEnd();
3104       return;
3105     }
3106     for (const NodeState &node : nodes()) {
3107       if (node.Start == Trie.begin() + childNodeIndex){
3108         *E = malformedError("loop in childern in export trie data at node: 0x" +
3109                             Twine::utohexstr(Top.Start - Trie.begin()) +
3110                             " back to node: 0x" +
3111                             Twine::utohexstr(childNodeIndex));
3112         moveToEnd();
3113         return;
3114       }
3115     }
3116     Top.NextChildIndex += 1;
3117     pushNode(childNodeIndex);
3118     if (*E)
3119       return;
3120   }
3121   if (!Stack.back().IsExportNode) {
3122     *E = malformedError("node is not an export node in export trie data at "
3123                         "node: 0x" +
3124                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3125     moveToEnd();
3126     return;
3127   }
3128 }
3129 
3130 // We have a trie data structure and need a way to walk it that is compatible
3131 // with the C++ iterator model. The solution is a non-recursive depth first
3132 // traversal where the iterator contains a stack of parent nodes along with a
3133 // string that is the accumulation of all edge strings along the parent chain
3134 // to this point.
3135 //
3136 // There is one "export" node for each exported symbol.  But because some
3137 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
3138 // node may have child nodes too.
3139 //
3140 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
3141 // child until hitting a node with no children (which is an export node or
3142 // else the trie is malformed). On the way down, each node is pushed on the
3143 // stack ivar.  If there is no more ways down, it pops up one and tries to go
3144 // down a sibling path until a childless node is reached.
3145 void ExportEntry::moveNext() {
3146   assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3147   if (!Stack.back().IsExportNode) {
3148     *E = malformedError("node is not an export node in export trie data at "
3149                         "node: 0x" +
3150                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3151     moveToEnd();
3152     return;
3153   }
3154 
3155   Stack.pop_back();
3156   while (!Stack.empty()) {
3157     NodeState &Top = Stack.back();
3158     if (Top.NextChildIndex < Top.ChildCount) {
3159       pushDownUntilBottom();
3160       // Now at the next export node.
3161       return;
3162     } else {
3163       if (Top.IsExportNode) {
3164         // This node has no children but is itself an export node.
3165         CumulativeString.resize(Top.ParentStringLength);
3166         return;
3167       }
3168       Stack.pop_back();
3169     }
3170   }
3171   Done = true;
3172 }
3173 
3174 iterator_range<export_iterator>
3175 MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie,
3176                          const MachOObjectFile *O) {
3177   ExportEntry Start(&E, O, Trie);
3178   if (Trie.empty())
3179     Start.moveToEnd();
3180   else
3181     Start.moveToFirst();
3182 
3183   ExportEntry Finish(&E, O, Trie);
3184   Finish.moveToEnd();
3185 
3186   return make_range(export_iterator(Start), export_iterator(Finish));
3187 }
3188 
3189 iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const {
3190   return exports(Err, getDyldInfoExportsTrie(), this);
3191 }
3192 
3193 MachOAbstractFixupEntry::MachOAbstractFixupEntry(Error *E,
3194                                                  const MachOObjectFile *O)
3195     : E(E), O(O) {
3196   // Cache the vmaddress of __TEXT
3197   for (const auto &Command : O->load_commands()) {
3198     if (Command.C.cmd == MachO::LC_SEGMENT) {
3199       MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
3200       if (StringRef(SLC.segname) == StringRef("__TEXT")) {
3201         TextAddress = SLC.vmaddr;
3202         break;
3203       }
3204     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3205       MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
3206       if (StringRef(SLC_64.segname) == StringRef("__TEXT")) {
3207         TextAddress = SLC_64.vmaddr;
3208         break;
3209       }
3210     }
3211   }
3212 }
3213 
3214 int32_t MachOAbstractFixupEntry::segmentIndex() const { return SegmentIndex; }
3215 
3216 uint64_t MachOAbstractFixupEntry::segmentOffset() const {
3217   return SegmentOffset;
3218 }
3219 
3220 uint64_t MachOAbstractFixupEntry::segmentAddress() const {
3221   return O->BindRebaseAddress(SegmentIndex, 0);
3222 }
3223 
3224 StringRef MachOAbstractFixupEntry::segmentName() const {
3225   return O->BindRebaseSegmentName(SegmentIndex);
3226 }
3227 
3228 StringRef MachOAbstractFixupEntry::sectionName() const {
3229   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3230 }
3231 
3232 uint64_t MachOAbstractFixupEntry::address() const {
3233   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3234 }
3235 
3236 StringRef MachOAbstractFixupEntry::symbolName() const { return SymbolName; }
3237 
3238 int64_t MachOAbstractFixupEntry::addend() const { return Addend; }
3239 
3240 uint32_t MachOAbstractFixupEntry::flags() const { return Flags; }
3241 
3242 int MachOAbstractFixupEntry::ordinal() const { return Ordinal; }
3243 
3244 StringRef MachOAbstractFixupEntry::typeName() const { return "unknown"; }
3245 
3246 void MachOAbstractFixupEntry::moveToFirst() {
3247   SegmentOffset = 0;
3248   SegmentIndex = -1;
3249   Ordinal = 0;
3250   Flags = 0;
3251   Addend = 0;
3252   Done = false;
3253 }
3254 
3255 void MachOAbstractFixupEntry::moveToEnd() { Done = true; }
3256 
3257 MachOChainedFixupEntry::MachOChainedFixupEntry(Error *E,
3258                                                const MachOObjectFile *O,
3259                                                bool Parse)
3260     : MachOAbstractFixupEntry(E, O) {
3261   ErrorAsOutParameter e(E);
3262   if (Parse) {
3263     if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets())
3264       FixupTargets = *FixupTargetsOrErr;
3265     else {
3266       *E = FixupTargetsOrErr.takeError();
3267       return;
3268     }
3269   }
3270 }
3271 
3272 void MachOChainedFixupEntry::moveToFirst() {
3273   MachOAbstractFixupEntry::moveToFirst();
3274   FixupIndex = 0;
3275   moveNext();
3276 }
3277 
3278 void MachOChainedFixupEntry::moveToEnd() {
3279   MachOAbstractFixupEntry::moveToEnd();
3280 }
3281 
3282 void MachOChainedFixupEntry::moveNext() { Done = true; }
3283 
3284 bool MachOChainedFixupEntry::operator==(
3285     const MachOChainedFixupEntry &Other) const {
3286   if (Done == Other.Done)
3287     return true;
3288   if ((FixupIndex == Other.FixupIndex))
3289     return true;
3290   return false;
3291 }
3292 
3293 MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
3294                                    ArrayRef<uint8_t> Bytes, bool is64Bit)
3295     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3296       PointerSize(is64Bit ? 8 : 4) {}
3297 
3298 void MachORebaseEntry::moveToFirst() {
3299   Ptr = Opcodes.begin();
3300   moveNext();
3301 }
3302 
3303 void MachORebaseEntry::moveToEnd() {
3304   Ptr = Opcodes.end();
3305   RemainingLoopCount = 0;
3306   Done = true;
3307 }
3308 
3309 void MachORebaseEntry::moveNext() {
3310   ErrorAsOutParameter ErrAsOutParam(E);
3311   // If in the middle of some loop, move to next rebasing in loop.
3312   SegmentOffset += AdvanceAmount;
3313   if (RemainingLoopCount) {
3314     --RemainingLoopCount;
3315     return;
3316   }
3317   // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3318   // pointer size. Therefore it is possible to reach the end without ever having
3319   // seen REBASE_OPCODE_DONE.
3320   if (Ptr == Opcodes.end()) {
3321     Done = true;
3322     return;
3323   }
3324   bool More = true;
3325   while (More) {
3326     // Parse next opcode and set up next loop.
3327     const uint8_t *OpcodeStart = Ptr;
3328     uint8_t Byte = *Ptr++;
3329     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3330     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3331     uint32_t Count, Skip;
3332     const char *error = nullptr;
3333     switch (Opcode) {
3334     case MachO::REBASE_OPCODE_DONE:
3335       More = false;
3336       Done = true;
3337       moveToEnd();
3338       DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3339       break;
3340     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
3341       RebaseType = ImmValue;
3342       if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) {
3343         *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3344                             Twine((int)RebaseType) + " for opcode at: 0x" +
3345                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3346         moveToEnd();
3347         return;
3348       }
3349       DEBUG_WITH_TYPE(
3350           "mach-o-rebase",
3351           dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3352                  << "RebaseType=" << (int) RebaseType << "\n");
3353       break;
3354     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3355       SegmentIndex = ImmValue;
3356       SegmentOffset = readULEB128(&error);
3357       if (error) {
3358         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3359                             Twine(error) + " for opcode at: 0x" +
3360                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3361         moveToEnd();
3362         return;
3363       }
3364       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3365                                                PointerSize);
3366       if (error) {
3367         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3368                             Twine(error) + " for opcode at: 0x" +
3369                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3370         moveToEnd();
3371         return;
3372       }
3373       DEBUG_WITH_TYPE(
3374           "mach-o-rebase",
3375           dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3376                  << "SegmentIndex=" << SegmentIndex << ", "
3377                  << format("SegmentOffset=0x%06X", SegmentOffset)
3378                  << "\n");
3379       break;
3380     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
3381       SegmentOffset += readULEB128(&error);
3382       if (error) {
3383         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3384                             " for opcode at: 0x" +
3385                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3386         moveToEnd();
3387         return;
3388       }
3389       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3390                                                PointerSize);
3391       if (error) {
3392         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3393                             " for opcode at: 0x" +
3394                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3395         moveToEnd();
3396         return;
3397       }
3398       DEBUG_WITH_TYPE("mach-o-rebase",
3399                       dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3400                              << format("SegmentOffset=0x%06X",
3401                                        SegmentOffset) << "\n");
3402       break;
3403     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
3404       SegmentOffset += ImmValue * PointerSize;
3405       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3406                                                PointerSize);
3407       if (error) {
3408         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3409                             Twine(error) + " for opcode at: 0x" +
3410                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3411         moveToEnd();
3412         return;
3413       }
3414       DEBUG_WITH_TYPE("mach-o-rebase",
3415                       dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3416                              << format("SegmentOffset=0x%06X",
3417                                        SegmentOffset) << "\n");
3418       break;
3419     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
3420       AdvanceAmount = PointerSize;
3421       Skip = 0;
3422       Count = ImmValue;
3423       if (ImmValue != 0)
3424         RemainingLoopCount = ImmValue - 1;
3425       else
3426         RemainingLoopCount = 0;
3427       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3428                                                PointerSize, Count, Skip);
3429       if (error) {
3430         *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3431                             Twine(error) + " for opcode at: 0x" +
3432                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3433         moveToEnd();
3434         return;
3435       }
3436       DEBUG_WITH_TYPE(
3437           "mach-o-rebase",
3438           dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3439                  << format("SegmentOffset=0x%06X", SegmentOffset)
3440                  << ", AdvanceAmount=" << AdvanceAmount
3441                  << ", RemainingLoopCount=" << RemainingLoopCount
3442                  << "\n");
3443       return;
3444     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
3445       AdvanceAmount = PointerSize;
3446       Skip = 0;
3447       Count = readULEB128(&error);
3448       if (error) {
3449         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3450                             Twine(error) + " for opcode at: 0x" +
3451                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3452         moveToEnd();
3453         return;
3454       }
3455       if (Count != 0)
3456         RemainingLoopCount = Count - 1;
3457       else
3458         RemainingLoopCount = 0;
3459       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3460                                                PointerSize, Count, Skip);
3461       if (error) {
3462         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3463                             Twine(error) + " for opcode at: 0x" +
3464                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3465         moveToEnd();
3466         return;
3467       }
3468       DEBUG_WITH_TYPE(
3469           "mach-o-rebase",
3470           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3471                  << format("SegmentOffset=0x%06X", SegmentOffset)
3472                  << ", AdvanceAmount=" << AdvanceAmount
3473                  << ", RemainingLoopCount=" << RemainingLoopCount
3474                  << "\n");
3475       return;
3476     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
3477       Skip = readULEB128(&error);
3478       if (error) {
3479         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3480                             Twine(error) + " for opcode at: 0x" +
3481                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3482         moveToEnd();
3483         return;
3484       }
3485       AdvanceAmount = Skip + PointerSize;
3486       Count = 1;
3487       RemainingLoopCount = 0;
3488       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3489                                                PointerSize, Count, Skip);
3490       if (error) {
3491         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3492                             Twine(error) + " for opcode at: 0x" +
3493                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3494         moveToEnd();
3495         return;
3496       }
3497       DEBUG_WITH_TYPE(
3498           "mach-o-rebase",
3499           dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3500                  << format("SegmentOffset=0x%06X", SegmentOffset)
3501                  << ", AdvanceAmount=" << AdvanceAmount
3502                  << ", RemainingLoopCount=" << RemainingLoopCount
3503                  << "\n");
3504       return;
3505     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
3506       Count = readULEB128(&error);
3507       if (error) {
3508         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3509                             "ULEB " +
3510                             Twine(error) + " for opcode at: 0x" +
3511                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3512         moveToEnd();
3513         return;
3514       }
3515       if (Count != 0)
3516         RemainingLoopCount = Count - 1;
3517       else
3518         RemainingLoopCount = 0;
3519       Skip = readULEB128(&error);
3520       if (error) {
3521         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3522                             "ULEB " +
3523                             Twine(error) + " for opcode at: 0x" +
3524                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3525         moveToEnd();
3526         return;
3527       }
3528       AdvanceAmount = Skip + PointerSize;
3529 
3530       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3531                                                PointerSize, Count, Skip);
3532       if (error) {
3533         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3534                             "ULEB " +
3535                             Twine(error) + " for opcode at: 0x" +
3536                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3537         moveToEnd();
3538         return;
3539       }
3540       DEBUG_WITH_TYPE(
3541           "mach-o-rebase",
3542           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3543                  << format("SegmentOffset=0x%06X", SegmentOffset)
3544                  << ", AdvanceAmount=" << AdvanceAmount
3545                  << ", RemainingLoopCount=" << RemainingLoopCount
3546                  << "\n");
3547       return;
3548     default:
3549       *E = malformedError("bad rebase info (bad opcode value 0x" +
3550                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3551                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3552       moveToEnd();
3553       return;
3554     }
3555   }
3556 }
3557 
3558 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3559   unsigned Count;
3560   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3561   Ptr += Count;
3562   if (Ptr > Opcodes.end())
3563     Ptr = Opcodes.end();
3564   return Result;
3565 }
3566 
3567 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3568 
3569 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
3570 
3571 StringRef MachORebaseEntry::typeName() const {
3572   switch (RebaseType) {
3573   case MachO::REBASE_TYPE_POINTER:
3574     return "pointer";
3575   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
3576     return "text abs32";
3577   case MachO::REBASE_TYPE_TEXT_PCREL32:
3578     return "text rel32";
3579   }
3580   return "unknown";
3581 }
3582 
3583 // For use with the SegIndex of a checked Mach-O Rebase entry
3584 // to get the segment name.
3585 StringRef MachORebaseEntry::segmentName() const {
3586   return O->BindRebaseSegmentName(SegmentIndex);
3587 }
3588 
3589 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3590 // to get the section name.
3591 StringRef MachORebaseEntry::sectionName() const {
3592   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3593 }
3594 
3595 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3596 // to get the address.
3597 uint64_t MachORebaseEntry::address() const {
3598   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3599 }
3600 
3601 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
3602 #ifdef EXPENSIVE_CHECKS
3603   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3604 #else
3605   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3606 #endif
3607   return (Ptr == Other.Ptr) &&
3608          (RemainingLoopCount == Other.RemainingLoopCount) &&
3609          (Done == Other.Done);
3610 }
3611 
3612 iterator_range<rebase_iterator>
3613 MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O,
3614                              ArrayRef<uint8_t> Opcodes, bool is64) {
3615   if (O->BindRebaseSectionTable == nullptr)
3616     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3617   MachORebaseEntry Start(&Err, O, Opcodes, is64);
3618   Start.moveToFirst();
3619 
3620   MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3621   Finish.moveToEnd();
3622 
3623   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3624 }
3625 
3626 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) {
3627   return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3628 }
3629 
3630 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O,
3631                                ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3632     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3633       PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3634 
3635 void MachOBindEntry::moveToFirst() {
3636   Ptr = Opcodes.begin();
3637   moveNext();
3638 }
3639 
3640 void MachOBindEntry::moveToEnd() {
3641   Ptr = Opcodes.end();
3642   RemainingLoopCount = 0;
3643   Done = true;
3644 }
3645 
3646 void MachOBindEntry::moveNext() {
3647   ErrorAsOutParameter ErrAsOutParam(E);
3648   // If in the middle of some loop, move to next binding in loop.
3649   SegmentOffset += AdvanceAmount;
3650   if (RemainingLoopCount) {
3651     --RemainingLoopCount;
3652     return;
3653   }
3654   // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3655   // pointer size. Therefore it is possible to reach the end without ever having
3656   // seen BIND_OPCODE_DONE.
3657   if (Ptr == Opcodes.end()) {
3658     Done = true;
3659     return;
3660   }
3661   bool More = true;
3662   while (More) {
3663     // Parse next opcode and set up next loop.
3664     const uint8_t *OpcodeStart = Ptr;
3665     uint8_t Byte = *Ptr++;
3666     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3667     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3668     int8_t SignExtended;
3669     const uint8_t *SymStart;
3670     uint32_t Count, Skip;
3671     const char *error = nullptr;
3672     switch (Opcode) {
3673     case MachO::BIND_OPCODE_DONE:
3674       if (TableKind == Kind::Lazy) {
3675         // Lazying bindings have a DONE opcode between entries.  Need to ignore
3676         // it to advance to next entry.  But need not if this is last entry.
3677         bool NotLastEntry = false;
3678         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3679           if (*P) {
3680             NotLastEntry = true;
3681           }
3682         }
3683         if (NotLastEntry)
3684           break;
3685       }
3686       More = false;
3687       moveToEnd();
3688       DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3689       break;
3690     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
3691       if (TableKind == Kind::Weak) {
3692         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3693                             "weak bind table for opcode at: 0x" +
3694                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3695         moveToEnd();
3696         return;
3697       }
3698       Ordinal = ImmValue;
3699       LibraryOrdinalSet = true;
3700       if (ImmValue > O->getLibraryCount()) {
3701         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3702                             "library ordinal: " +
3703                             Twine((int)ImmValue) + " (max " +
3704                             Twine((int)O->getLibraryCount()) +
3705                             ") for opcode at: 0x" +
3706                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3707         moveToEnd();
3708         return;
3709       }
3710       DEBUG_WITH_TYPE(
3711           "mach-o-bind",
3712           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3713                  << "Ordinal=" << Ordinal << "\n");
3714       break;
3715     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
3716       if (TableKind == Kind::Weak) {
3717         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3718                             "weak bind table for opcode at: 0x" +
3719                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3720         moveToEnd();
3721         return;
3722       }
3723       Ordinal = readULEB128(&error);
3724       LibraryOrdinalSet = true;
3725       if (error) {
3726         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3727                             Twine(error) + " for opcode at: 0x" +
3728                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3729         moveToEnd();
3730         return;
3731       }
3732       if (Ordinal > (int)O->getLibraryCount()) {
3733         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3734                             "library ordinal: " +
3735                             Twine((int)Ordinal) + " (max " +
3736                             Twine((int)O->getLibraryCount()) +
3737                             ") for opcode at: 0x" +
3738                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3739         moveToEnd();
3740         return;
3741       }
3742       DEBUG_WITH_TYPE(
3743           "mach-o-bind",
3744           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3745                  << "Ordinal=" << Ordinal << "\n");
3746       break;
3747     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
3748       if (TableKind == Kind::Weak) {
3749         *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3750                             "weak bind table for opcode at: 0x" +
3751                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3752         moveToEnd();
3753         return;
3754       }
3755       if (ImmValue) {
3756         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3757         Ordinal = SignExtended;
3758         if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3759           *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3760                               "special ordinal: " +
3761                               Twine((int)Ordinal) + " for opcode at: 0x" +
3762                               Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3763           moveToEnd();
3764           return;
3765         }
3766       } else
3767         Ordinal = 0;
3768       LibraryOrdinalSet = true;
3769       DEBUG_WITH_TYPE(
3770           "mach-o-bind",
3771           dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3772                  << "Ordinal=" << Ordinal << "\n");
3773       break;
3774     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
3775       Flags = ImmValue;
3776       SymStart = Ptr;
3777       while (*Ptr && (Ptr < Opcodes.end())) {
3778         ++Ptr;
3779       }
3780       if (Ptr == Opcodes.end()) {
3781         *E = malformedError(
3782             "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3783             "symbol name extends past opcodes for opcode at: 0x" +
3784             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3785         moveToEnd();
3786         return;
3787       }
3788       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3789                              Ptr-SymStart);
3790       ++Ptr;
3791       DEBUG_WITH_TYPE(
3792           "mach-o-bind",
3793           dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3794                  << "SymbolName=" << SymbolName << "\n");
3795       if (TableKind == Kind::Weak) {
3796         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
3797           return;
3798       }
3799       break;
3800     case MachO::BIND_OPCODE_SET_TYPE_IMM:
3801       BindType = ImmValue;
3802       if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3803         *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3804                             Twine((int)ImmValue) + " for opcode at: 0x" +
3805                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3806         moveToEnd();
3807         return;
3808       }
3809       DEBUG_WITH_TYPE(
3810           "mach-o-bind",
3811           dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3812                  << "BindType=" << (int)BindType << "\n");
3813       break;
3814     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
3815       Addend = readSLEB128(&error);
3816       if (error) {
3817         *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3818                             " for opcode at: 0x" +
3819                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3820         moveToEnd();
3821         return;
3822       }
3823       DEBUG_WITH_TYPE(
3824           "mach-o-bind",
3825           dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3826                  << "Addend=" << Addend << "\n");
3827       break;
3828     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3829       SegmentIndex = ImmValue;
3830       SegmentOffset = readULEB128(&error);
3831       if (error) {
3832         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3833                             Twine(error) + " for opcode at: 0x" +
3834                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3835         moveToEnd();
3836         return;
3837       }
3838       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3839                                              PointerSize);
3840       if (error) {
3841         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3842                             Twine(error) + " for opcode at: 0x" +
3843                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3844         moveToEnd();
3845         return;
3846       }
3847       DEBUG_WITH_TYPE(
3848           "mach-o-bind",
3849           dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3850                  << "SegmentIndex=" << SegmentIndex << ", "
3851                  << format("SegmentOffset=0x%06X", SegmentOffset)
3852                  << "\n");
3853       break;
3854     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
3855       SegmentOffset += readULEB128(&error);
3856       if (error) {
3857         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3858                             " for opcode at: 0x" +
3859                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3860         moveToEnd();
3861         return;
3862       }
3863       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3864                                              PointerSize);
3865       if (error) {
3866         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3867                             " for opcode at: 0x" +
3868                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3869         moveToEnd();
3870         return;
3871       }
3872       DEBUG_WITH_TYPE("mach-o-bind",
3873                       dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3874                              << format("SegmentOffset=0x%06X",
3875                                        SegmentOffset) << "\n");
3876       break;
3877     case MachO::BIND_OPCODE_DO_BIND:
3878       AdvanceAmount = PointerSize;
3879       RemainingLoopCount = 0;
3880       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3881                                              PointerSize);
3882       if (error) {
3883         *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3884                             " for opcode at: 0x" +
3885                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3886         moveToEnd();
3887         return;
3888       }
3889       if (SymbolName == StringRef()) {
3890         *E = malformedError(
3891             "for BIND_OPCODE_DO_BIND missing preceding "
3892             "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3893             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3894         moveToEnd();
3895         return;
3896       }
3897       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3898         *E =
3899             malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3900                            "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3901                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3902         moveToEnd();
3903         return;
3904       }
3905       DEBUG_WITH_TYPE("mach-o-bind",
3906                       dbgs() << "BIND_OPCODE_DO_BIND: "
3907                              << format("SegmentOffset=0x%06X",
3908                                        SegmentOffset) << "\n");
3909       return;
3910      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
3911       if (TableKind == Kind::Lazy) {
3912         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3913                             "lazy bind table for opcode at: 0x" +
3914                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3915         moveToEnd();
3916         return;
3917       }
3918       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3919                                              PointerSize);
3920       if (error) {
3921         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3922                             Twine(error) + " for opcode at: 0x" +
3923                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3924         moveToEnd();
3925         return;
3926       }
3927       if (SymbolName == StringRef()) {
3928         *E = malformedError(
3929             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3930             "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3931             "at: 0x" +
3932             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3933         moveToEnd();
3934         return;
3935       }
3936       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3937         *E = malformedError(
3938             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3939             "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3940             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3941         moveToEnd();
3942         return;
3943       }
3944       AdvanceAmount = readULEB128(&error) + PointerSize;
3945       if (error) {
3946         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3947                             Twine(error) + " for opcode at: 0x" +
3948                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3949         moveToEnd();
3950         return;
3951       }
3952       // Note, this is not really an error until the next bind but make no sense
3953       // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3954       // bind operation.
3955       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
3956                                             AdvanceAmount, PointerSize);
3957       if (error) {
3958         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3959                             "ULEB) " +
3960                             Twine(error) + " for opcode at: 0x" +
3961                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3962         moveToEnd();
3963         return;
3964       }
3965       RemainingLoopCount = 0;
3966       DEBUG_WITH_TYPE(
3967           "mach-o-bind",
3968           dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3969                  << format("SegmentOffset=0x%06X", SegmentOffset)
3970                  << ", AdvanceAmount=" << AdvanceAmount
3971                  << ", RemainingLoopCount=" << RemainingLoopCount
3972                  << "\n");
3973       return;
3974     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
3975       if (TableKind == Kind::Lazy) {
3976         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3977                             "allowed in lazy bind table for opcode at: 0x" +
3978                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3979         moveToEnd();
3980         return;
3981       }
3982       if (SymbolName == StringRef()) {
3983         *E = malformedError(
3984             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3985             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3986             "opcode at: 0x" +
3987             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3988         moveToEnd();
3989         return;
3990       }
3991       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3992         *E = malformedError(
3993             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3994             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3995             "at: 0x" +
3996             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3997         moveToEnd();
3998         return;
3999       }
4000       AdvanceAmount = ImmValue * PointerSize + PointerSize;
4001       RemainingLoopCount = 0;
4002       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4003                                              AdvanceAmount, PointerSize);
4004       if (error) {
4005         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4006                             Twine(error) + " for opcode at: 0x" +
4007                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4008         moveToEnd();
4009         return;
4010       }
4011       DEBUG_WITH_TYPE("mach-o-bind",
4012                       dbgs()
4013                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4014                       << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4015       return;
4016     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
4017       if (TableKind == Kind::Lazy) {
4018         *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4019                             "allowed in lazy bind table for opcode at: 0x" +
4020                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4021         moveToEnd();
4022         return;
4023       }
4024       Count = readULEB128(&error);
4025       if (Count != 0)
4026         RemainingLoopCount = Count - 1;
4027       else
4028         RemainingLoopCount = 0;
4029       if (error) {
4030         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4031                             " (count value) " +
4032                             Twine(error) + " for opcode at: 0x" +
4033                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4034         moveToEnd();
4035         return;
4036       }
4037       Skip = readULEB128(&error);
4038       AdvanceAmount = Skip + PointerSize;
4039       if (error) {
4040         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4041                             " (skip value) " +
4042                             Twine(error) + " for opcode at: 0x" +
4043                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4044         moveToEnd();
4045         return;
4046       }
4047       if (SymbolName == StringRef()) {
4048         *E = malformedError(
4049             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4050             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4051             "opcode at: 0x" +
4052             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4053         moveToEnd();
4054         return;
4055       }
4056       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4057         *E = malformedError(
4058             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4059             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4060             "at: 0x" +
4061             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4062         moveToEnd();
4063         return;
4064       }
4065       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4066                                              PointerSize, Count, Skip);
4067       if (error) {
4068         *E =
4069             malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4070                            Twine(error) + " for opcode at: 0x" +
4071                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4072         moveToEnd();
4073         return;
4074       }
4075       DEBUG_WITH_TYPE(
4076           "mach-o-bind",
4077           dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4078                  << format("SegmentOffset=0x%06X", SegmentOffset)
4079                  << ", AdvanceAmount=" << AdvanceAmount
4080                  << ", RemainingLoopCount=" << RemainingLoopCount
4081                  << "\n");
4082       return;
4083     default:
4084       *E = malformedError("bad bind info (bad opcode value 0x" +
4085                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
4086                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4087       moveToEnd();
4088       return;
4089     }
4090   }
4091 }
4092 
4093 uint64_t MachOBindEntry::readULEB128(const char **error) {
4094   unsigned Count;
4095   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
4096   Ptr += Count;
4097   if (Ptr > Opcodes.end())
4098     Ptr = Opcodes.end();
4099   return Result;
4100 }
4101 
4102 int64_t MachOBindEntry::readSLEB128(const char **error) {
4103   unsigned Count;
4104   int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
4105   Ptr += Count;
4106   if (Ptr > Opcodes.end())
4107     Ptr = Opcodes.end();
4108   return Result;
4109 }
4110 
4111 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
4112 
4113 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
4114 
4115 StringRef MachOBindEntry::typeName() const {
4116   switch (BindType) {
4117   case MachO::BIND_TYPE_POINTER:
4118     return "pointer";
4119   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
4120     return "text abs32";
4121   case MachO::BIND_TYPE_TEXT_PCREL32:
4122     return "text rel32";
4123   }
4124   return "unknown";
4125 }
4126 
4127 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
4128 
4129 int64_t MachOBindEntry::addend() const { return Addend; }
4130 
4131 uint32_t MachOBindEntry::flags() const { return Flags; }
4132 
4133 int MachOBindEntry::ordinal() const { return Ordinal; }
4134 
4135 // For use with the SegIndex of a checked Mach-O Bind entry
4136 // to get the segment name.
4137 StringRef MachOBindEntry::segmentName() const {
4138   return O->BindRebaseSegmentName(SegmentIndex);
4139 }
4140 
4141 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4142 // to get the section name.
4143 StringRef MachOBindEntry::sectionName() const {
4144   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4145 }
4146 
4147 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4148 // to get the address.
4149 uint64_t MachOBindEntry::address() const {
4150   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4151 }
4152 
4153 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
4154 #ifdef EXPENSIVE_CHECKS
4155   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4156 #else
4157   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4158 #endif
4159   return (Ptr == Other.Ptr) &&
4160          (RemainingLoopCount == Other.RemainingLoopCount) &&
4161          (Done == Other.Done);
4162 }
4163 
4164 // Build table of sections so SegIndex/SegOffset pairs can be translated.
4165 BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
4166   uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4167   StringRef CurSegName;
4168   uint64_t CurSegAddress;
4169   for (const SectionRef &Section : Obj->sections()) {
4170     SectionInfo Info;
4171     Expected<StringRef> NameOrErr = Section.getName();
4172     if (!NameOrErr)
4173       consumeError(NameOrErr.takeError());
4174     else
4175       Info.SectionName = *NameOrErr;
4176     Info.Address = Section.getAddress();
4177     Info.Size = Section.getSize();
4178     Info.SegmentName =
4179         Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4180     if (!Info.SegmentName.equals(CurSegName)) {
4181       ++CurSegIndex;
4182       CurSegName = Info.SegmentName;
4183       CurSegAddress = Info.Address;
4184     }
4185     Info.SegmentIndex = CurSegIndex - 1;
4186     Info.OffsetInSegment = Info.Address - CurSegAddress;
4187     Info.SegmentStartAddress = CurSegAddress;
4188     Sections.push_back(Info);
4189   }
4190   MaxSegIndex = CurSegIndex;
4191 }
4192 
4193 // For use with a SegIndex, SegOffset, and PointerSize triple in
4194 // MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry.
4195 //
4196 // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
4197 // that fully contains a pointer at that location. Multiple fixups in a bind
4198 // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
4199 // be tested via the Count and Skip parameters.
4200 const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
4201                                                    uint64_t SegOffset,
4202                                                    uint8_t PointerSize,
4203                                                    uint32_t Count,
4204                                                    uint32_t Skip) {
4205   if (SegIndex == -1)
4206     return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4207   if (SegIndex >= MaxSegIndex)
4208     return "bad segIndex (too large)";
4209   for (uint32_t i = 0; i < Count; ++i) {
4210     uint32_t Start = SegOffset + i * (PointerSize + Skip);
4211     uint32_t End = Start + PointerSize;
4212     bool Found = false;
4213     for (const SectionInfo &SI : Sections) {
4214       if (SI.SegmentIndex != SegIndex)
4215         continue;
4216       if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4217         if (End <= SI.OffsetInSegment + SI.Size) {
4218           Found = true;
4219           break;
4220         }
4221         else
4222           return "bad offset, extends beyond section boundary";
4223       }
4224     }
4225     if (!Found)
4226       return "bad offset, not in section";
4227   }
4228   return nullptr;
4229 }
4230 
4231 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4232 // to get the segment name.
4233 StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) {
4234   for (const SectionInfo &SI : Sections) {
4235     if (SI.SegmentIndex == SegIndex)
4236       return SI.SegmentName;
4237   }
4238   llvm_unreachable("invalid SegIndex");
4239 }
4240 
4241 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4242 // to get the SectionInfo.
4243 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4244                                      int32_t SegIndex, uint64_t SegOffset) {
4245   for (const SectionInfo &SI : Sections) {
4246     if (SI.SegmentIndex != SegIndex)
4247       continue;
4248     if (SI.OffsetInSegment > SegOffset)
4249       continue;
4250     if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4251       continue;
4252     return SI;
4253   }
4254   llvm_unreachable("SegIndex and SegOffset not in any section");
4255 }
4256 
4257 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4258 // entry to get the section name.
4259 StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex,
4260                                          uint64_t SegOffset) {
4261   return findSection(SegIndex, SegOffset).SectionName;
4262 }
4263 
4264 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4265 // entry to get the address.
4266 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4267   const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4268   return SI.SegmentStartAddress + OffsetInSeg;
4269 }
4270 
4271 iterator_range<bind_iterator>
4272 MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O,
4273                            ArrayRef<uint8_t> Opcodes, bool is64,
4274                            MachOBindEntry::Kind BKind) {
4275   if (O->BindRebaseSectionTable == nullptr)
4276     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4277   MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4278   Start.moveToFirst();
4279 
4280   MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4281   Finish.moveToEnd();
4282 
4283   return make_range(bind_iterator(Start), bind_iterator(Finish));
4284 }
4285 
4286 iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) {
4287   return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4288                    MachOBindEntry::Kind::Regular);
4289 }
4290 
4291 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) {
4292   return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4293                    MachOBindEntry::Kind::Lazy);
4294 }
4295 
4296 iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
4297   return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4298                    MachOBindEntry::Kind::Weak);
4299 }
4300 
4301 iterator_range<fixup_iterator> MachOObjectFile::fixupTable(Error &Err) {
4302   MachOChainedFixupEntry Start(&Err, this, true);
4303   Start.moveToFirst();
4304 
4305   MachOChainedFixupEntry Finish(&Err, this, false);
4306   Finish.moveToEnd();
4307 
4308   return make_range(fixup_iterator(Start), fixup_iterator(Finish));
4309 }
4310 
4311 MachOObjectFile::load_command_iterator
4312 MachOObjectFile::begin_load_commands() const {
4313   return LoadCommands.begin();
4314 }
4315 
4316 MachOObjectFile::load_command_iterator
4317 MachOObjectFile::end_load_commands() const {
4318   return LoadCommands.end();
4319 }
4320 
4321 iterator_range<MachOObjectFile::load_command_iterator>
4322 MachOObjectFile::load_commands() const {
4323   return make_range(begin_load_commands(), end_load_commands());
4324 }
4325 
4326 StringRef
4327 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
4328   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4329   return parseSegmentOrSectionName(Raw.data());
4330 }
4331 
4332 ArrayRef<char>
4333 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
4334   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4335   const section_base *Base =
4336     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4337   return makeArrayRef(Base->sectname);
4338 }
4339 
4340 ArrayRef<char>
4341 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
4342   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4343   const section_base *Base =
4344     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4345   return makeArrayRef(Base->segname);
4346 }
4347 
4348 bool
4349 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
4350   const {
4351   if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4352     return false;
4353   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
4354 }
4355 
4356 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
4357     const MachO::any_relocation_info &RE) const {
4358   if (isLittleEndian())
4359     return RE.r_word1 & 0xffffff;
4360   return RE.r_word1 >> 8;
4361 }
4362 
4363 bool MachOObjectFile::getPlainRelocationExternal(
4364     const MachO::any_relocation_info &RE) const {
4365   if (isLittleEndian())
4366     return (RE.r_word1 >> 27) & 1;
4367   return (RE.r_word1 >> 4) & 1;
4368 }
4369 
4370 bool MachOObjectFile::getScatteredRelocationScattered(
4371     const MachO::any_relocation_info &RE) const {
4372   return RE.r_word0 >> 31;
4373 }
4374 
4375 uint32_t MachOObjectFile::getScatteredRelocationValue(
4376     const MachO::any_relocation_info &RE) const {
4377   return RE.r_word1;
4378 }
4379 
4380 uint32_t MachOObjectFile::getScatteredRelocationType(
4381     const MachO::any_relocation_info &RE) const {
4382   return (RE.r_word0 >> 24) & 0xf;
4383 }
4384 
4385 unsigned MachOObjectFile::getAnyRelocationAddress(
4386     const MachO::any_relocation_info &RE) const {
4387   if (isRelocationScattered(RE))
4388     return getScatteredRelocationAddress(RE);
4389   return getPlainRelocationAddress(RE);
4390 }
4391 
4392 unsigned MachOObjectFile::getAnyRelocationPCRel(
4393     const MachO::any_relocation_info &RE) const {
4394   if (isRelocationScattered(RE))
4395     return getScatteredRelocationPCRel(RE);
4396   return getPlainRelocationPCRel(*this, RE);
4397 }
4398 
4399 unsigned MachOObjectFile::getAnyRelocationLength(
4400     const MachO::any_relocation_info &RE) const {
4401   if (isRelocationScattered(RE))
4402     return getScatteredRelocationLength(RE);
4403   return getPlainRelocationLength(*this, RE);
4404 }
4405 
4406 unsigned
4407 MachOObjectFile::getAnyRelocationType(
4408                                    const MachO::any_relocation_info &RE) const {
4409   if (isRelocationScattered(RE))
4410     return getScatteredRelocationType(RE);
4411   return getPlainRelocationType(*this, RE);
4412 }
4413 
4414 SectionRef
4415 MachOObjectFile::getAnyRelocationSection(
4416                                    const MachO::any_relocation_info &RE) const {
4417   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4418     return *section_end();
4419   unsigned SecNum = getPlainRelocationSymbolNum(RE);
4420   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4421     return *section_end();
4422   DataRefImpl DRI;
4423   DRI.d.a = SecNum - 1;
4424   return SectionRef(DRI, this);
4425 }
4426 
4427 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
4428   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4429   return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4430 }
4431 
4432 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
4433   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4434   return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4435 }
4436 
4437 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
4438                                            unsigned Index) const {
4439   const char *Sec = getSectionPtr(*this, L, Index);
4440   return getStruct<MachO::section>(*this, Sec);
4441 }
4442 
4443 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
4444                                                 unsigned Index) const {
4445   const char *Sec = getSectionPtr(*this, L, Index);
4446   return getStruct<MachO::section_64>(*this, Sec);
4447 }
4448 
4449 MachO::nlist
4450 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
4451   const char *P = reinterpret_cast<const char *>(DRI.p);
4452   return getStruct<MachO::nlist>(*this, P);
4453 }
4454 
4455 MachO::nlist_64
4456 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
4457   const char *P = reinterpret_cast<const char *>(DRI.p);
4458   return getStruct<MachO::nlist_64>(*this, P);
4459 }
4460 
4461 MachO::linkedit_data_command
4462 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
4463   return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4464 }
4465 
4466 MachO::segment_command
4467 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
4468   return getStruct<MachO::segment_command>(*this, L.Ptr);
4469 }
4470 
4471 MachO::segment_command_64
4472 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
4473   return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4474 }
4475 
4476 MachO::linker_option_command
4477 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
4478   return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4479 }
4480 
4481 MachO::version_min_command
4482 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
4483   return getStruct<MachO::version_min_command>(*this, L.Ptr);
4484 }
4485 
4486 MachO::note_command
4487 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
4488   return getStruct<MachO::note_command>(*this, L.Ptr);
4489 }
4490 
4491 MachO::build_version_command
4492 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
4493   return getStruct<MachO::build_version_command>(*this, L.Ptr);
4494 }
4495 
4496 MachO::build_tool_version
4497 MachOObjectFile::getBuildToolVersion(unsigned index) const {
4498   return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4499 }
4500 
4501 MachO::dylib_command
4502 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
4503   return getStruct<MachO::dylib_command>(*this, L.Ptr);
4504 }
4505 
4506 MachO::dyld_info_command
4507 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
4508   return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4509 }
4510 
4511 MachO::dylinker_command
4512 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
4513   return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4514 }
4515 
4516 MachO::uuid_command
4517 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
4518   return getStruct<MachO::uuid_command>(*this, L.Ptr);
4519 }
4520 
4521 MachO::rpath_command
4522 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
4523   return getStruct<MachO::rpath_command>(*this, L.Ptr);
4524 }
4525 
4526 MachO::source_version_command
4527 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
4528   return getStruct<MachO::source_version_command>(*this, L.Ptr);
4529 }
4530 
4531 MachO::entry_point_command
4532 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
4533   return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4534 }
4535 
4536 MachO::encryption_info_command
4537 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
4538   return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4539 }
4540 
4541 MachO::encryption_info_command_64
4542 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
4543   return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4544 }
4545 
4546 MachO::sub_framework_command
4547 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
4548   return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4549 }
4550 
4551 MachO::sub_umbrella_command
4552 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
4553   return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4554 }
4555 
4556 MachO::sub_library_command
4557 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
4558   return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4559 }
4560 
4561 MachO::sub_client_command
4562 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
4563   return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4564 }
4565 
4566 MachO::routines_command
4567 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
4568   return getStruct<MachO::routines_command>(*this, L.Ptr);
4569 }
4570 
4571 MachO::routines_command_64
4572 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
4573   return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4574 }
4575 
4576 MachO::thread_command
4577 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
4578   return getStruct<MachO::thread_command>(*this, L.Ptr);
4579 }
4580 
4581 MachO::any_relocation_info
4582 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
4583   uint32_t Offset;
4584   if (getHeader().filetype == MachO::MH_OBJECT) {
4585     DataRefImpl Sec;
4586     Sec.d.a = Rel.d.a;
4587     if (is64Bit()) {
4588       MachO::section_64 Sect = getSection64(Sec);
4589       Offset = Sect.reloff;
4590     } else {
4591       MachO::section Sect = getSection(Sec);
4592       Offset = Sect.reloff;
4593     }
4594   } else {
4595     MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4596     if (Rel.d.a == 0)
4597       Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4598     else
4599       Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4600   }
4601 
4602   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4603       getPtr(*this, Offset)) + Rel.d.b;
4604   return getStruct<MachO::any_relocation_info>(
4605       *this, reinterpret_cast<const char *>(P));
4606 }
4607 
4608 MachO::data_in_code_entry
4609 MachOObjectFile::getDice(DataRefImpl Rel) const {
4610   const char *P = reinterpret_cast<const char *>(Rel.p);
4611   return getStruct<MachO::data_in_code_entry>(*this, P);
4612 }
4613 
4614 const MachO::mach_header &MachOObjectFile::getHeader() const {
4615   return Header;
4616 }
4617 
4618 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
4619   assert(is64Bit());
4620   return Header64;
4621 }
4622 
4623 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
4624                                              const MachO::dysymtab_command &DLC,
4625                                              unsigned Index) const {
4626   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4627   return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4628 }
4629 
4630 MachO::data_in_code_entry
4631 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
4632                                          unsigned Index) const {
4633   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4634   return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4635 }
4636 
4637 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
4638   if (SymtabLoadCmd)
4639     return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4640 
4641   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4642   MachO::symtab_command Cmd;
4643   Cmd.cmd = MachO::LC_SYMTAB;
4644   Cmd.cmdsize = sizeof(MachO::symtab_command);
4645   Cmd.symoff = 0;
4646   Cmd.nsyms = 0;
4647   Cmd.stroff = 0;
4648   Cmd.strsize = 0;
4649   return Cmd;
4650 }
4651 
4652 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
4653   if (DysymtabLoadCmd)
4654     return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4655 
4656   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4657   MachO::dysymtab_command Cmd;
4658   Cmd.cmd = MachO::LC_DYSYMTAB;
4659   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4660   Cmd.ilocalsym = 0;
4661   Cmd.nlocalsym = 0;
4662   Cmd.iextdefsym = 0;
4663   Cmd.nextdefsym = 0;
4664   Cmd.iundefsym = 0;
4665   Cmd.nundefsym = 0;
4666   Cmd.tocoff = 0;
4667   Cmd.ntoc = 0;
4668   Cmd.modtaboff = 0;
4669   Cmd.nmodtab = 0;
4670   Cmd.extrefsymoff = 0;
4671   Cmd.nextrefsyms = 0;
4672   Cmd.indirectsymoff = 0;
4673   Cmd.nindirectsyms = 0;
4674   Cmd.extreloff = 0;
4675   Cmd.nextrel = 0;
4676   Cmd.locreloff = 0;
4677   Cmd.nlocrel = 0;
4678   return Cmd;
4679 }
4680 
4681 MachO::linkedit_data_command
4682 MachOObjectFile::getDataInCodeLoadCommand() const {
4683   if (DataInCodeLoadCmd)
4684     return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4685 
4686   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4687   MachO::linkedit_data_command Cmd;
4688   Cmd.cmd = MachO::LC_DATA_IN_CODE;
4689   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4690   Cmd.dataoff = 0;
4691   Cmd.datasize = 0;
4692   return Cmd;
4693 }
4694 
4695 MachO::linkedit_data_command
4696 MachOObjectFile::getLinkOptHintsLoadCommand() const {
4697   if (LinkOptHintsLoadCmd)
4698     return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4699 
4700   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4701   // fields.
4702   MachO::linkedit_data_command Cmd;
4703   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4704   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4705   Cmd.dataoff = 0;
4706   Cmd.datasize = 0;
4707   return Cmd;
4708 }
4709 
4710 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
4711   if (!DyldInfoLoadCmd)
4712     return None;
4713 
4714   auto DyldInfoOrErr =
4715     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4716   if (!DyldInfoOrErr)
4717     return None;
4718   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4719   const uint8_t *Ptr =
4720       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4721   return makeArrayRef(Ptr, DyldInfo.rebase_size);
4722 }
4723 
4724 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
4725   if (!DyldInfoLoadCmd)
4726     return None;
4727 
4728   auto DyldInfoOrErr =
4729     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4730   if (!DyldInfoOrErr)
4731     return None;
4732   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4733   const uint8_t *Ptr =
4734       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4735   return makeArrayRef(Ptr, DyldInfo.bind_size);
4736 }
4737 
4738 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
4739   if (!DyldInfoLoadCmd)
4740     return None;
4741 
4742   auto DyldInfoOrErr =
4743     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4744   if (!DyldInfoOrErr)
4745     return None;
4746   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4747   const uint8_t *Ptr =
4748       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4749   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4750 }
4751 
4752 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
4753   if (!DyldInfoLoadCmd)
4754     return None;
4755 
4756   auto DyldInfoOrErr =
4757     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4758   if (!DyldInfoOrErr)
4759     return None;
4760   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4761   const uint8_t *Ptr =
4762       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4763   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4764 }
4765 
4766 Expected<std::vector<ChainedFixupTarget>>
4767 MachOObjectFile::getDyldChainedFixupTargets() const {
4768   // Load the dyld chained fixups load command.
4769   if (!DyldChainedFixupsLoadCmd)
4770     return std::vector<ChainedFixupTarget>();
4771   auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
4772       *this, DyldChainedFixupsLoadCmd);
4773   if (!DyldChainedFixupsOrErr)
4774     return DyldChainedFixupsOrErr.takeError();
4775   MachO::linkedit_data_command DyldChainedFixups = DyldChainedFixupsOrErr.get();
4776 
4777   // If the load command is present but the data offset has been zeroed out,
4778   // as is the case for dylib stubs, return an empty list of targets.
4779   uint64_t CFHeaderOffset = DyldChainedFixups.dataoff;
4780   std::vector<ChainedFixupTarget> Targets;
4781   if (CFHeaderOffset == 0)
4782     return Targets;
4783 
4784   // Load the dyld chained fixups header.
4785   const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
4786   auto CFHeaderOrErr =
4787       getStructOrErr<MachO::dyld_chained_fixups_header>(*this, CFHeaderPtr);
4788   if (!CFHeaderOrErr)
4789     return CFHeaderOrErr.takeError();
4790   MachO::dyld_chained_fixups_header CFHeader = CFHeaderOrErr.get();
4791 
4792   // Reject unknown chained fixup formats.
4793   if (CFHeader.fixups_version != 0)
4794     return malformedError(Twine("bad chained fixups: unknown version: ") +
4795                           Twine(CFHeader.fixups_version));
4796   if (CFHeader.imports_format < 1 || CFHeader.imports_format > 3)
4797     return malformedError(
4798         Twine("bad chained fixups: unknown imports format: ") +
4799         Twine(CFHeader.imports_format));
4800 
4801   return Targets;
4802 }
4803 
4804 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
4805   if (!DyldInfoLoadCmd)
4806     return None;
4807 
4808   auto DyldInfoOrErr =
4809     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4810   if (!DyldInfoOrErr)
4811     return None;
4812   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4813   const uint8_t *Ptr =
4814       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
4815   return makeArrayRef(Ptr, DyldInfo.export_size);
4816 }
4817 
4818 SmallVector<uint64_t> MachOObjectFile::getFunctionStarts() const {
4819   if (!FuncStartsLoadCmd)
4820     return {};
4821 
4822   auto InfoOrErr =
4823       getStructOrErr<MachO::linkedit_data_command>(*this, FuncStartsLoadCmd);
4824   if (!InfoOrErr)
4825     return {};
4826 
4827   MachO::linkedit_data_command Info = InfoOrErr.get();
4828   SmallVector<uint64_t, 8> FunctionStarts;
4829   this->ReadULEB128s(Info.dataoff, FunctionStarts);
4830   return std::move(FunctionStarts);
4831 }
4832 
4833 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
4834   if (!UuidLoadCmd)
4835     return None;
4836   // Returning a pointer is fine as uuid doesn't need endian swapping.
4837   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
4838   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4839 }
4840 
4841 StringRef MachOObjectFile::getStringTableData() const {
4842   MachO::symtab_command S = getSymtabLoadCommand();
4843   return getData().substr(S.stroff, S.strsize);
4844 }
4845 
4846 bool MachOObjectFile::is64Bit() const {
4847   return getType() == getMachOType(false, true) ||
4848     getType() == getMachOType(true, true);
4849 }
4850 
4851 void MachOObjectFile::ReadULEB128s(uint64_t Index,
4852                                    SmallVectorImpl<uint64_t> &Out) const {
4853   DataExtractor extractor(ObjectFile::getData(), true, 0);
4854 
4855   uint64_t offset = Index;
4856   uint64_t data = 0;
4857   while (uint64_t delta = extractor.getULEB128(&offset)) {
4858     data += delta;
4859     Out.push_back(data);
4860   }
4861 }
4862 
4863 bool MachOObjectFile::isRelocatableObject() const {
4864   return getHeader().filetype == MachO::MH_OBJECT;
4865 }
4866 
4867 Expected<std::unique_ptr<MachOObjectFile>>
4868 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
4869                                   uint32_t UniversalCputype,
4870                                   uint32_t UniversalIndex) {
4871   StringRef Magic = Buffer.getBuffer().slice(0, 4);
4872   if (Magic == "\xFE\xED\xFA\xCE")
4873     return MachOObjectFile::create(Buffer, false, false,
4874                                    UniversalCputype, UniversalIndex);
4875   if (Magic == "\xCE\xFA\xED\xFE")
4876     return MachOObjectFile::create(Buffer, true, false,
4877                                    UniversalCputype, UniversalIndex);
4878   if (Magic == "\xFE\xED\xFA\xCF")
4879     return MachOObjectFile::create(Buffer, false, true,
4880                                    UniversalCputype, UniversalIndex);
4881   if (Magic == "\xCF\xFA\xED\xFE")
4882     return MachOObjectFile::create(Buffer, true, true,
4883                                    UniversalCputype, UniversalIndex);
4884   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
4885                                         object_error::invalid_file_type);
4886 }
4887 
4888 StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
4889   return StringSwitch<StringRef>(Name)
4890       .Case("debug_str_offs", "debug_str_offsets")
4891       .Default(Name);
4892 }
4893 
4894 Expected<std::vector<std::string>>
4895 MachOObjectFile::findDsymObjectMembers(StringRef Path) {
4896   SmallString<256> BundlePath(Path);
4897   // Normalize input path. This is necessary to accept `bundle.dSYM/`.
4898   sys::path::remove_dots(BundlePath);
4899   if (!sys::fs::is_directory(BundlePath) ||
4900       sys::path::extension(BundlePath) != ".dSYM")
4901     return std::vector<std::string>();
4902   sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
4903   bool IsDir;
4904   auto EC = sys::fs::is_directory(BundlePath, IsDir);
4905   if (EC == errc::no_such_file_or_directory || (!EC && !IsDir))
4906     return createStringError(
4907         EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
4908         Path.str().c_str());
4909   if (EC)
4910     return createFileError(BundlePath, errorCodeToError(EC));
4911 
4912   std::vector<std::string> ObjectPaths;
4913   for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
4914        Dir != DirEnd && !EC; Dir.increment(EC)) {
4915     StringRef ObjectPath = Dir->path();
4916     sys::fs::file_status Status;
4917     if (auto EC = sys::fs::status(ObjectPath, Status))
4918       return createFileError(ObjectPath, errorCodeToError(EC));
4919     switch (Status.type()) {
4920     case sys::fs::file_type::regular_file:
4921     case sys::fs::file_type::symlink_file:
4922     case sys::fs::file_type::type_unknown:
4923       ObjectPaths.push_back(ObjectPath.str());
4924       break;
4925     default: /*ignore*/;
4926     }
4927   }
4928   if (EC)
4929     return createFileError(BundlePath, errorCodeToError(EC));
4930   if (ObjectPaths.empty())
4931     return createStringError(std::error_code(),
4932                              "%s: no objects found in dSYM bundle",
4933                              Path.str().c_str());
4934   return ObjectPaths;
4935 }
4936 
4937 llvm::binaryformat::Swift5ReflectionSectionKind
4938 MachOObjectFile::mapReflectionSectionNameToEnumValue(
4939     StringRef SectionName) const {
4940 #define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF)                           \
4941   .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
4942   return StringSwitch<llvm::binaryformat::Swift5ReflectionSectionKind>(
4943              SectionName)
4944 #include "llvm/BinaryFormat/Swift.def"
4945       .Default(llvm::binaryformat::Swift5ReflectionSectionKind::unknown);
4946 #undef HANDLE_SWIFT_SECTION
4947 }
4948