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