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