xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision 5e96cea1db0623a833d5376c9ea2ce4528771f97)
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_UUID) {
1390       if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1391         Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1392                              "cmdsize");
1393         return;
1394       }
1395       if (UuidLoadCmd) {
1396         Err = malformedError("more than one LC_UUID command");
1397         return;
1398       }
1399       UuidLoadCmd = Load.Ptr;
1400     } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1401       if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
1402                                          MachO::section_64>(
1403                    *this, Load, Sections, HasPageZeroSegment, I,
1404                    "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1405         return;
1406     } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1407       if ((Err = parseSegmentLoadCommand<MachO::segment_command,
1408                                          MachO::section>(
1409                    *this, Load, Sections, HasPageZeroSegment, I,
1410                    "LC_SEGMENT", SizeOfHeaders, Elements)))
1411         return;
1412     } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1413       if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1414         return;
1415     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1416       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1417         return;
1418       Libraries.push_back(Load.Ptr);
1419     } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1420       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1421         return;
1422       Libraries.push_back(Load.Ptr);
1423     } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1424       if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1425         return;
1426       Libraries.push_back(Load.Ptr);
1427     } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1428       if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1429         return;
1430       Libraries.push_back(Load.Ptr);
1431     } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1432       if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1433         return;
1434       Libraries.push_back(Load.Ptr);
1435     } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1436       if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1437         return;
1438     } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1439       if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1440         return;
1441     } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1442       if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1443         return;
1444     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1445       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1446                                   "LC_VERSION_MIN_MACOSX")))
1447         return;
1448     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1449       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1450                                   "LC_VERSION_MIN_IPHONEOS")))
1451         return;
1452     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1453       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1454                                   "LC_VERSION_MIN_TVOS")))
1455         return;
1456     } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1457       if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1458                                   "LC_VERSION_MIN_WATCHOS")))
1459         return;
1460     } else if (Load.C.cmd == MachO::LC_NOTE) {
1461       if ((Err = checkNoteCommand(*this, Load, I, Elements)))
1462         return;
1463     } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1464       if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
1465         return;
1466     } else if (Load.C.cmd == MachO::LC_RPATH) {
1467       if ((Err = checkRpathCommand(*this, Load, I)))
1468         return;
1469     } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1470       if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1471         Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1472                              " has incorrect cmdsize");
1473         return;
1474       }
1475       if (SourceLoadCmd) {
1476         Err = malformedError("more than one LC_SOURCE_VERSION command");
1477         return;
1478       }
1479       SourceLoadCmd = Load.Ptr;
1480     } else if (Load.C.cmd == MachO::LC_MAIN) {
1481       if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1482         Err = malformedError("LC_MAIN command " + Twine(I) +
1483                              " has incorrect cmdsize");
1484         return;
1485       }
1486       if (EntryPointLoadCmd) {
1487         Err = malformedError("more than one LC_MAIN command");
1488         return;
1489       }
1490       EntryPointLoadCmd = Load.Ptr;
1491     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1492       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1493         Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1494                              " has incorrect cmdsize");
1495         return;
1496       }
1497       MachO::encryption_info_command E =
1498         getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1499       if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1500                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1501         return;
1502     } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1503       if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1504         Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1505                              " has incorrect cmdsize");
1506         return;
1507       }
1508       MachO::encryption_info_command_64 E =
1509         getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1510       if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1511                                      &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1512         return;
1513     } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1514       if ((Err = checkLinkerOptCommand(*this, Load, I)))
1515         return;
1516     } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1517       if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1518         Err =  malformedError("load command " + Twine(I) +
1519                               " LC_SUB_FRAMEWORK cmdsize too small");
1520         return;
1521       }
1522       MachO::sub_framework_command S =
1523         getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1524       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1525                                  sizeof(MachO::sub_framework_command),
1526                                  "sub_framework_command", S.umbrella,
1527                                  "umbrella")))
1528         return;
1529     } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1530       if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1531         Err =  malformedError("load command " + Twine(I) +
1532                               " LC_SUB_UMBRELLA cmdsize too small");
1533         return;
1534       }
1535       MachO::sub_umbrella_command S =
1536         getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1537       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1538                                  sizeof(MachO::sub_umbrella_command),
1539                                  "sub_umbrella_command", S.sub_umbrella,
1540                                  "sub_umbrella")))
1541         return;
1542     } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1543       if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1544         Err =  malformedError("load command " + Twine(I) +
1545                               " LC_SUB_LIBRARY cmdsize too small");
1546         return;
1547       }
1548       MachO::sub_library_command S =
1549         getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1550       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1551                                  sizeof(MachO::sub_library_command),
1552                                  "sub_library_command", S.sub_library,
1553                                  "sub_library")))
1554         return;
1555     } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1556       if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1557         Err =  malformedError("load command " + Twine(I) +
1558                               " LC_SUB_CLIENT cmdsize too small");
1559         return;
1560       }
1561       MachO::sub_client_command S =
1562         getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1563       if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1564                                  sizeof(MachO::sub_client_command),
1565                                  "sub_client_command", S.client, "client")))
1566         return;
1567     } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1568       if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1569         Err = malformedError("LC_ROUTINES command " + Twine(I) +
1570                              " has incorrect cmdsize");
1571         return;
1572       }
1573       if (RoutinesLoadCmd) {
1574         Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1575                              "command");
1576         return;
1577       }
1578       RoutinesLoadCmd = Load.Ptr;
1579     } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1580       if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1581         Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1582                              " has incorrect cmdsize");
1583         return;
1584       }
1585       if (RoutinesLoadCmd) {
1586         Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1587                              "command");
1588         return;
1589       }
1590       RoutinesLoadCmd = Load.Ptr;
1591     } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1592       if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1593         return;
1594       if (UnixThreadLoadCmd) {
1595         Err = malformedError("more than one LC_UNIXTHREAD command");
1596         return;
1597       }
1598       UnixThreadLoadCmd = Load.Ptr;
1599     } else if (Load.C.cmd == MachO::LC_THREAD) {
1600       if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1601         return;
1602     // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1603     } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1604       if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1605                                            &TwoLevelHintsLoadCmd, Elements)))
1606         return;
1607     } else if (Load.C.cmd == MachO::LC_IDENT) {
1608       // Note: LC_IDENT is ignored.
1609       continue;
1610     } else if (isLoadCommandObsolete(Load.C.cmd)) {
1611       Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1612                            Twine(Load.C.cmd) + " is obsolete and not "
1613                            "supported");
1614       return;
1615     }
1616     // TODO: generate a error for unknown load commands by default.  But still
1617     // need work out an approach to allow or not allow unknown values like this
1618     // as an option for some uses like lldb.
1619     if (I < LoadCommandCount - 1) {
1620       if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1621         Load = *LoadOrErr;
1622       else {
1623         Err = LoadOrErr.takeError();
1624         return;
1625       }
1626     }
1627   }
1628   if (!SymtabLoadCmd) {
1629     if (DysymtabLoadCmd) {
1630       Err = malformedError("contains LC_DYSYMTAB load command without a "
1631                            "LC_SYMTAB load command");
1632       return;
1633     }
1634   } else if (DysymtabLoadCmd) {
1635     MachO::symtab_command Symtab =
1636       getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1637     MachO::dysymtab_command Dysymtab =
1638       getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1639     if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1640       Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1641                            "extends past the end of the symbol table");
1642       return;
1643     }
1644     uint64_t BigSize = Dysymtab.ilocalsym;
1645     BigSize += Dysymtab.nlocalsym;
1646     if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1647       Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1648                            "command extends past the end of the symbol table");
1649       return;
1650     }
1651     if (Dysymtab.nextdefsym != 0 && Dysymtab.iextdefsym > Symtab.nsyms) {
1652       Err = malformedError("iextdefsym in LC_DYSYMTAB load command "
1653                            "extends past the end of the symbol table");
1654       return;
1655     }
1656     BigSize = Dysymtab.iextdefsym;
1657     BigSize += Dysymtab.nextdefsym;
1658     if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1659       Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1660                            "load command extends past the end of the symbol "
1661                            "table");
1662       return;
1663     }
1664     if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1665       Err = malformedError("iundefsym in LC_DYSYMTAB load command "
1666                            "extends past the end of the symbol table");
1667       return;
1668     }
1669     BigSize = Dysymtab.iundefsym;
1670     BigSize += Dysymtab.nundefsym;
1671     if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1672       Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1673                            " command extends past the end of the symbol table");
1674       return;
1675     }
1676   }
1677   if ((getHeader().filetype == MachO::MH_DYLIB ||
1678        getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1679        DyldIdLoadCmd == nullptr) {
1680     Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1681                          "filetype");
1682     return;
1683   }
1684   assert(LoadCommands.size() == LoadCommandCount);
1685 
1686   Err = Error::success();
1687 }
1688 
1689 Error MachOObjectFile::checkSymbolTable() const {
1690   uint32_t Flags = 0;
1691   if (is64Bit()) {
1692     MachO::mach_header_64 H_64 = MachOObjectFile::getHeader64();
1693     Flags = H_64.flags;
1694   } else {
1695     MachO::mach_header H = MachOObjectFile::getHeader();
1696     Flags = H.flags;
1697   }
1698   uint8_t NType = 0;
1699   uint8_t NSect = 0;
1700   uint16_t NDesc = 0;
1701   uint32_t NStrx = 0;
1702   uint64_t NValue = 0;
1703   uint32_t SymbolIndex = 0;
1704   MachO::symtab_command S = getSymtabLoadCommand();
1705   for (const SymbolRef &Symbol : symbols()) {
1706     DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1707     if (is64Bit()) {
1708       MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1709       NType = STE_64.n_type;
1710       NSect = STE_64.n_sect;
1711       NDesc = STE_64.n_desc;
1712       NStrx = STE_64.n_strx;
1713       NValue = STE_64.n_value;
1714     } else {
1715       MachO::nlist STE = getSymbolTableEntry(SymDRI);
1716       NType = STE.n_type;
1717       NSect = STE.n_sect;
1718       NDesc = STE.n_desc;
1719       NStrx = STE.n_strx;
1720       NValue = STE.n_value;
1721     }
1722     if ((NType & MachO::N_STAB) == 0) {
1723       if ((NType & MachO::N_TYPE) == MachO::N_SECT) {
1724         if (NSect == 0 || NSect > Sections.size())
1725           return malformedError("bad section index: " + Twine((int)NSect) +
1726                                 " for symbol at index " + Twine(SymbolIndex));
1727       }
1728       if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
1729         if (NValue >= S.strsize)
1730           return malformedError("bad n_value: " + Twine((int)NValue) + " past "
1731                                 "the end of string table, for N_INDR symbol at "
1732                                 "index " + Twine(SymbolIndex));
1733       }
1734       if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
1735           (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
1736            (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
1737             uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
1738             if (LibraryOrdinal != 0 &&
1739                 LibraryOrdinal != MachO::EXECUTABLE_ORDINAL &&
1740                 LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL &&
1741                 LibraryOrdinal - 1 >= Libraries.size() ) {
1742               return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) +
1743                                     " for symbol at index " + Twine(SymbolIndex));
1744             }
1745           }
1746     }
1747     if (NStrx >= S.strsize)
1748       return malformedError("bad string table index: " + Twine((int)NStrx) +
1749                             " past the end of string table, for symbol at "
1750                             "index " + Twine(SymbolIndex));
1751     SymbolIndex++;
1752   }
1753   return Error::success();
1754 }
1755 
1756 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
1757   unsigned SymbolTableEntrySize = is64Bit() ?
1758     sizeof(MachO::nlist_64) :
1759     sizeof(MachO::nlist);
1760   Symb.p += SymbolTableEntrySize;
1761 }
1762 
1763 Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
1764   StringRef StringTable = getStringTableData();
1765   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1766   if (Entry.n_strx == 0)
1767     // A n_strx value of 0 indicates that no name is associated with a
1768     // particular symbol table entry.
1769     return StringRef();
1770   const char *Start = &StringTable.data()[Entry.n_strx];
1771   if (Start < getData().begin() || Start >= getData().end()) {
1772     return malformedError("bad string index: " + Twine(Entry.n_strx) +
1773                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1774   }
1775   return StringRef(Start);
1776 }
1777 
1778 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
1779   DataRefImpl DRI = Sec.getRawDataRefImpl();
1780   uint32_t Flags = getSectionFlags(*this, DRI);
1781   return Flags & MachO::SECTION_TYPE;
1782 }
1783 
1784 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
1785   if (is64Bit()) {
1786     MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
1787     return Entry.n_value;
1788   }
1789   MachO::nlist Entry = getSymbolTableEntry(Sym);
1790   return Entry.n_value;
1791 }
1792 
1793 // getIndirectName() returns the name of the alias'ed symbol who's string table
1794 // index is in the n_value field.
1795 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
1796                                                  StringRef &Res) const {
1797   StringRef StringTable = getStringTableData();
1798   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1799   if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1800     return object_error::parse_failed;
1801   uint64_t NValue = getNValue(Symb);
1802   if (NValue >= StringTable.size())
1803     return object_error::parse_failed;
1804   const char *Start = &StringTable.data()[NValue];
1805   Res = StringRef(Start);
1806   return std::error_code();
1807 }
1808 
1809 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1810   return getNValue(Sym);
1811 }
1812 
1813 Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
1814   return getSymbolValue(Sym);
1815 }
1816 
1817 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
1818   uint32_t Flags = cantFail(getSymbolFlags(DRI));
1819   if (Flags & SymbolRef::SF_Common) {
1820     MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1821     return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1822   }
1823   return 0;
1824 }
1825 
1826 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
1827   return getNValue(DRI);
1828 }
1829 
1830 Expected<SymbolRef::Type>
1831 MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
1832   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1833   uint8_t n_type = Entry.n_type;
1834 
1835   // If this is a STAB debugging symbol, we can do nothing more.
1836   if (n_type & MachO::N_STAB)
1837     return SymbolRef::ST_Debug;
1838 
1839   switch (n_type & MachO::N_TYPE) {
1840     case MachO::N_UNDF :
1841       return SymbolRef::ST_Unknown;
1842     case MachO::N_SECT :
1843       Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1844       if (!SecOrError)
1845         return SecOrError.takeError();
1846       section_iterator Sec = *SecOrError;
1847       if (Sec == section_end())
1848         return SymbolRef::ST_Other;
1849       if (Sec->isData() || Sec->isBSS())
1850         return SymbolRef::ST_Data;
1851       return SymbolRef::ST_Function;
1852   }
1853   return SymbolRef::ST_Other;
1854 }
1855 
1856 Expected<uint32_t> MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
1857   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1858 
1859   uint8_t MachOType = Entry.n_type;
1860   uint16_t MachOFlags = Entry.n_desc;
1861 
1862   uint32_t Result = SymbolRef::SF_None;
1863 
1864   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1865     Result |= SymbolRef::SF_Indirect;
1866 
1867   if (MachOType & MachO::N_STAB)
1868     Result |= SymbolRef::SF_FormatSpecific;
1869 
1870   if (MachOType & MachO::N_EXT) {
1871     Result |= SymbolRef::SF_Global;
1872     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1873       if (getNValue(DRI))
1874         Result |= SymbolRef::SF_Common;
1875       else
1876         Result |= SymbolRef::SF_Undefined;
1877     }
1878 
1879     if (!(MachOType & MachO::N_PEXT))
1880       Result |= SymbolRef::SF_Exported;
1881   }
1882 
1883   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1884     Result |= SymbolRef::SF_Weak;
1885 
1886   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1887     Result |= SymbolRef::SF_Thumb;
1888 
1889   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1890     Result |= SymbolRef::SF_Absolute;
1891 
1892   return Result;
1893 }
1894 
1895 Expected<section_iterator>
1896 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
1897   MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1898   uint8_t index = Entry.n_sect;
1899 
1900   if (index == 0)
1901     return section_end();
1902   DataRefImpl DRI;
1903   DRI.d.a = index - 1;
1904   if (DRI.d.a >= Sections.size()){
1905     return malformedError("bad section index: " + Twine((int)index) +
1906                           " for symbol at index " + Twine(getSymbolIndex(Symb)));
1907   }
1908   return section_iterator(SectionRef(DRI, this));
1909 }
1910 
1911 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
1912   MachO::nlist_base Entry =
1913       getSymbolTableEntryBase(*this, Sym.getRawDataRefImpl());
1914   return Entry.n_sect - 1;
1915 }
1916 
1917 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
1918   Sec.d.a++;
1919 }
1920 
1921 Expected<StringRef> MachOObjectFile::getSectionName(DataRefImpl Sec) const {
1922   ArrayRef<char> Raw = getSectionRawName(Sec);
1923   return parseSegmentOrSectionName(Raw.data());
1924 }
1925 
1926 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
1927   if (is64Bit())
1928     return getSection64(Sec).addr;
1929   return getSection(Sec).addr;
1930 }
1931 
1932 uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
1933   return Sec.d.a;
1934 }
1935 
1936 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
1937   // In the case if a malformed Mach-O file where the section offset is past
1938   // the end of the file or some part of the section size is past the end of
1939   // the file return a size of zero or a size that covers the rest of the file
1940   // but does not extend past the end of the file.
1941   uint32_t SectOffset, SectType;
1942   uint64_t SectSize;
1943 
1944   if (is64Bit()) {
1945     MachO::section_64 Sect = getSection64(Sec);
1946     SectOffset = Sect.offset;
1947     SectSize = Sect.size;
1948     SectType = Sect.flags & MachO::SECTION_TYPE;
1949   } else {
1950     MachO::section Sect = getSection(Sec);
1951     SectOffset = Sect.offset;
1952     SectSize = Sect.size;
1953     SectType = Sect.flags & MachO::SECTION_TYPE;
1954   }
1955   if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1956     return SectSize;
1957   uint64_t FileSize = getData().size();
1958   if (SectOffset > FileSize)
1959     return 0;
1960   if (FileSize - SectOffset < SectSize)
1961     return FileSize - SectOffset;
1962   return SectSize;
1963 }
1964 
1965 ArrayRef<uint8_t> MachOObjectFile::getSectionContents(uint32_t Offset,
1966                                                       uint64_t Size) const {
1967   return arrayRefFromStringRef(getData().substr(Offset, Size));
1968 }
1969 
1970 Expected<ArrayRef<uint8_t>>
1971 MachOObjectFile::getSectionContents(DataRefImpl Sec) const {
1972   uint32_t Offset;
1973   uint64_t Size;
1974 
1975   if (is64Bit()) {
1976     MachO::section_64 Sect = getSection64(Sec);
1977     Offset = Sect.offset;
1978     Size = Sect.size;
1979   } else {
1980     MachO::section Sect = getSection(Sec);
1981     Offset = Sect.offset;
1982     Size = Sect.size;
1983   }
1984 
1985   return getSectionContents(Offset, Size);
1986 }
1987 
1988 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
1989   uint32_t Align;
1990   if (is64Bit()) {
1991     MachO::section_64 Sect = getSection64(Sec);
1992     Align = Sect.align;
1993   } else {
1994     MachO::section Sect = getSection(Sec);
1995     Align = Sect.align;
1996   }
1997 
1998   return uint64_t(1) << Align;
1999 }
2000 
2001 Expected<SectionRef> MachOObjectFile::getSection(unsigned SectionIndex) const {
2002   if (SectionIndex < 1 || SectionIndex > Sections.size())
2003     return malformedError("bad section index: " + Twine((int)SectionIndex));
2004 
2005   DataRefImpl DRI;
2006   DRI.d.a = SectionIndex - 1;
2007   return SectionRef(DRI, this);
2008 }
2009 
2010 Expected<SectionRef> MachOObjectFile::getSection(StringRef SectionName) const {
2011   for (const SectionRef &Section : sections()) {
2012     auto NameOrErr = Section.getName();
2013     if (!NameOrErr)
2014       return NameOrErr.takeError();
2015     if (*NameOrErr == SectionName)
2016       return Section;
2017   }
2018   return errorCodeToError(object_error::parse_failed);
2019 }
2020 
2021 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
2022   return false;
2023 }
2024 
2025 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
2026   uint32_t Flags = getSectionFlags(*this, Sec);
2027   return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
2028 }
2029 
2030 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
2031   uint32_t Flags = getSectionFlags(*this, Sec);
2032   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2033   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
2034          !(SectionType == MachO::S_ZEROFILL ||
2035            SectionType == MachO::S_GB_ZEROFILL);
2036 }
2037 
2038 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
2039   uint32_t Flags = getSectionFlags(*this, Sec);
2040   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2041   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
2042          (SectionType == MachO::S_ZEROFILL ||
2043           SectionType == MachO::S_GB_ZEROFILL);
2044 }
2045 
2046 bool MachOObjectFile::isDebugSection(DataRefImpl Sec) const {
2047   Expected<StringRef> SectionNameOrErr = getSectionName(Sec);
2048   if (!SectionNameOrErr) {
2049     // TODO: Report the error message properly.
2050     consumeError(SectionNameOrErr.takeError());
2051     return false;
2052   }
2053   StringRef SectionName = SectionNameOrErr.get();
2054   return SectionName.startswith("__debug") ||
2055          SectionName.startswith("__zdebug") ||
2056          SectionName.startswith("__apple") || SectionName == "__gdb_index" ||
2057          SectionName == "__swift_ast";
2058 }
2059 
2060 namespace {
2061 template <typename LoadCommandType>
2062 ArrayRef<uint8_t> getSegmentContents(const MachOObjectFile &Obj,
2063                                      MachOObjectFile::LoadCommandInfo LoadCmd,
2064                                      StringRef SegmentName) {
2065   auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.Ptr);
2066   if (!SegmentOrErr) {
2067     consumeError(SegmentOrErr.takeError());
2068     return {};
2069   }
2070   auto &Segment = SegmentOrErr.get();
2071   if (StringRef(Segment.segname, 16).startswith(SegmentName))
2072     return arrayRefFromStringRef(Obj.getData().slice(
2073         Segment.fileoff, Segment.fileoff + Segment.filesize));
2074   return {};
2075 }
2076 
2077 template <typename LoadCommandType>
2078 ArrayRef<uint8_t> getSegmentContents(const MachOObjectFile &Obj,
2079                                      MachOObjectFile::LoadCommandInfo LoadCmd) {
2080   auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.Ptr);
2081   if (!SegmentOrErr) {
2082     consumeError(SegmentOrErr.takeError());
2083     return {};
2084   }
2085   auto &Segment = SegmentOrErr.get();
2086   return arrayRefFromStringRef(
2087       Obj.getData().slice(Segment.fileoff, Segment.fileoff + Segment.filesize));
2088 }
2089 } // namespace
2090 
2091 ArrayRef<uint8_t>
2092 MachOObjectFile::getSegmentContents(StringRef SegmentName) const {
2093   for (auto LoadCmd : load_commands()) {
2094     ArrayRef<uint8_t> Contents;
2095     switch (LoadCmd.C.cmd) {
2096     case MachO::LC_SEGMENT:
2097       Contents = ::getSegmentContents<MachO::segment_command>(*this, LoadCmd,
2098                                                               SegmentName);
2099       break;
2100     case MachO::LC_SEGMENT_64:
2101       Contents = ::getSegmentContents<MachO::segment_command_64>(*this, LoadCmd,
2102                                                                  SegmentName);
2103       break;
2104     default:
2105       continue;
2106     }
2107     if (!Contents.empty())
2108       return Contents;
2109   }
2110   return {};
2111 }
2112 
2113 ArrayRef<uint8_t>
2114 MachOObjectFile::getSegmentContents(size_t SegmentIndex) const {
2115   size_t Idx = 0;
2116   for (auto LoadCmd : load_commands()) {
2117     switch (LoadCmd.C.cmd) {
2118     case MachO::LC_SEGMENT:
2119       if (Idx == SegmentIndex)
2120         return ::getSegmentContents<MachO::segment_command>(*this, LoadCmd);
2121       ++Idx;
2122       break;
2123     case MachO::LC_SEGMENT_64:
2124       if (Idx == SegmentIndex)
2125         return ::getSegmentContents<MachO::segment_command_64>(*this, LoadCmd);
2126       ++Idx;
2127       break;
2128     default:
2129       continue;
2130     }
2131   }
2132   return {};
2133 }
2134 
2135 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
2136   return Sec.getRawDataRefImpl().d.a;
2137 }
2138 
2139 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
2140   uint32_t Flags = getSectionFlags(*this, Sec);
2141   unsigned SectionType = Flags & MachO::SECTION_TYPE;
2142   return SectionType == MachO::S_ZEROFILL ||
2143          SectionType == MachO::S_GB_ZEROFILL;
2144 }
2145 
2146 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
2147   StringRef SegmentName = getSectionFinalSegmentName(Sec);
2148   if (Expected<StringRef> NameOrErr = getSectionName(Sec))
2149     return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");
2150   return false;
2151 }
2152 
2153 bool MachOObjectFile::isSectionStripped(DataRefImpl Sec) const {
2154   if (is64Bit())
2155     return getSection64(Sec).offset == 0;
2156   return getSection(Sec).offset == 0;
2157 }
2158 
2159 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
2160   DataRefImpl Ret;
2161   Ret.d.a = Sec.d.a;
2162   Ret.d.b = 0;
2163   return relocation_iterator(RelocationRef(Ret, this));
2164 }
2165 
2166 relocation_iterator
2167 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
2168   uint32_t Num;
2169   if (is64Bit()) {
2170     MachO::section_64 Sect = getSection64(Sec);
2171     Num = Sect.nreloc;
2172   } else {
2173     MachO::section Sect = getSection(Sec);
2174     Num = Sect.nreloc;
2175   }
2176 
2177   DataRefImpl Ret;
2178   Ret.d.a = Sec.d.a;
2179   Ret.d.b = Num;
2180   return relocation_iterator(RelocationRef(Ret, this));
2181 }
2182 
2183 relocation_iterator MachOObjectFile::extrel_begin() const {
2184   DataRefImpl Ret;
2185   // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2186   Ret.d.a = 0; // Would normally be a section index.
2187   Ret.d.b = 0; // Index into the external relocations
2188   return relocation_iterator(RelocationRef(Ret, this));
2189 }
2190 
2191 relocation_iterator MachOObjectFile::extrel_end() const {
2192   MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2193   DataRefImpl Ret;
2194   // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2195   Ret.d.a = 0; // Would normally be a section index.
2196   Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
2197   return relocation_iterator(RelocationRef(Ret, this));
2198 }
2199 
2200 relocation_iterator MachOObjectFile::locrel_begin() const {
2201   DataRefImpl Ret;
2202   // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2203   Ret.d.a = 1; // Would normally be a section index.
2204   Ret.d.b = 0; // Index into the local relocations
2205   return relocation_iterator(RelocationRef(Ret, this));
2206 }
2207 
2208 relocation_iterator MachOObjectFile::locrel_end() const {
2209   MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2210   DataRefImpl Ret;
2211   // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2212   Ret.d.a = 1; // Would normally be a section index.
2213   Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations
2214   return relocation_iterator(RelocationRef(Ret, this));
2215 }
2216 
2217 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
2218   ++Rel.d.b;
2219 }
2220 
2221 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
2222   assert((getHeader().filetype == MachO::MH_OBJECT ||
2223           getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
2224          "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2225   MachO::any_relocation_info RE = getRelocation(Rel);
2226   return getAnyRelocationAddress(RE);
2227 }
2228 
2229 symbol_iterator
2230 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
2231   MachO::any_relocation_info RE = getRelocation(Rel);
2232   if (isRelocationScattered(RE))
2233     return symbol_end();
2234 
2235   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2236   bool isExtern = getPlainRelocationExternal(RE);
2237   if (!isExtern)
2238     return symbol_end();
2239 
2240   MachO::symtab_command S = getSymtabLoadCommand();
2241   unsigned SymbolTableEntrySize = is64Bit() ?
2242     sizeof(MachO::nlist_64) :
2243     sizeof(MachO::nlist);
2244   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
2245   DataRefImpl Sym;
2246   Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2247   return symbol_iterator(SymbolRef(Sym, this));
2248 }
2249 
2250 section_iterator
2251 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
2252   return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
2253 }
2254 
2255 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
2256   MachO::any_relocation_info RE = getRelocation(Rel);
2257   return getAnyRelocationType(RE);
2258 }
2259 
2260 void MachOObjectFile::getRelocationTypeName(
2261     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2262   StringRef res;
2263   uint64_t RType = getRelocationType(Rel);
2264 
2265   unsigned Arch = this->getArch();
2266 
2267   switch (Arch) {
2268     case Triple::x86: {
2269       static const char *const Table[] =  {
2270         "GENERIC_RELOC_VANILLA",
2271         "GENERIC_RELOC_PAIR",
2272         "GENERIC_RELOC_SECTDIFF",
2273         "GENERIC_RELOC_PB_LA_PTR",
2274         "GENERIC_RELOC_LOCAL_SECTDIFF",
2275         "GENERIC_RELOC_TLV" };
2276 
2277       if (RType > 5)
2278         res = "Unknown";
2279       else
2280         res = Table[RType];
2281       break;
2282     }
2283     case Triple::x86_64: {
2284       static const char *const Table[] =  {
2285         "X86_64_RELOC_UNSIGNED",
2286         "X86_64_RELOC_SIGNED",
2287         "X86_64_RELOC_BRANCH",
2288         "X86_64_RELOC_GOT_LOAD",
2289         "X86_64_RELOC_GOT",
2290         "X86_64_RELOC_SUBTRACTOR",
2291         "X86_64_RELOC_SIGNED_1",
2292         "X86_64_RELOC_SIGNED_2",
2293         "X86_64_RELOC_SIGNED_4",
2294         "X86_64_RELOC_TLV" };
2295 
2296       if (RType > 9)
2297         res = "Unknown";
2298       else
2299         res = Table[RType];
2300       break;
2301     }
2302     case Triple::arm: {
2303       static const char *const Table[] =  {
2304         "ARM_RELOC_VANILLA",
2305         "ARM_RELOC_PAIR",
2306         "ARM_RELOC_SECTDIFF",
2307         "ARM_RELOC_LOCAL_SECTDIFF",
2308         "ARM_RELOC_PB_LA_PTR",
2309         "ARM_RELOC_BR24",
2310         "ARM_THUMB_RELOC_BR22",
2311         "ARM_THUMB_32BIT_BRANCH",
2312         "ARM_RELOC_HALF",
2313         "ARM_RELOC_HALF_SECTDIFF" };
2314 
2315       if (RType > 9)
2316         res = "Unknown";
2317       else
2318         res = Table[RType];
2319       break;
2320     }
2321     case Triple::aarch64:
2322     case Triple::aarch64_32: {
2323       static const char *const Table[] = {
2324         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
2325         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
2326         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
2327         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2328         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2329         "ARM64_RELOC_ADDEND"
2330       };
2331 
2332       if (RType >= std::size(Table))
2333         res = "Unknown";
2334       else
2335         res = Table[RType];
2336       break;
2337     }
2338     case Triple::ppc: {
2339       static const char *const Table[] =  {
2340         "PPC_RELOC_VANILLA",
2341         "PPC_RELOC_PAIR",
2342         "PPC_RELOC_BR14",
2343         "PPC_RELOC_BR24",
2344         "PPC_RELOC_HI16",
2345         "PPC_RELOC_LO16",
2346         "PPC_RELOC_HA16",
2347         "PPC_RELOC_LO14",
2348         "PPC_RELOC_SECTDIFF",
2349         "PPC_RELOC_PB_LA_PTR",
2350         "PPC_RELOC_HI16_SECTDIFF",
2351         "PPC_RELOC_LO16_SECTDIFF",
2352         "PPC_RELOC_HA16_SECTDIFF",
2353         "PPC_RELOC_JBSR",
2354         "PPC_RELOC_LO14_SECTDIFF",
2355         "PPC_RELOC_LOCAL_SECTDIFF" };
2356 
2357       if (RType > 15)
2358         res = "Unknown";
2359       else
2360         res = Table[RType];
2361       break;
2362     }
2363     case Triple::UnknownArch:
2364       res = "Unknown";
2365       break;
2366   }
2367   Result.append(res.begin(), res.end());
2368 }
2369 
2370 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
2371   MachO::any_relocation_info RE = getRelocation(Rel);
2372   return getAnyRelocationLength(RE);
2373 }
2374 
2375 //
2376 // guessLibraryShortName() is passed a name of a dynamic library and returns a
2377 // guess on what the short name is.  Then name is returned as a substring of the
2378 // StringRef Name passed in.  The name of the dynamic library is recognized as
2379 // a framework if it has one of the two following forms:
2380 //      Foo.framework/Versions/A/Foo
2381 //      Foo.framework/Foo
2382 // Where A and Foo can be any string.  And may contain a trailing suffix
2383 // starting with an underbar.  If the Name is recognized as a framework then
2384 // isFramework is set to true else it is set to false.  If the Name has a
2385 // suffix then Suffix is set to the substring in Name that contains the suffix
2386 // else it is set to a NULL StringRef.
2387 //
2388 // The Name of the dynamic library is recognized as a library name if it has
2389 // one of the two following forms:
2390 //      libFoo.A.dylib
2391 //      libFoo.dylib
2392 //
2393 // The library may have a suffix trailing the name Foo of the form:
2394 //      libFoo_profile.A.dylib
2395 //      libFoo_profile.dylib
2396 // These dyld image suffixes are separated from the short name by a '_'
2397 // character. Because the '_' character is commonly used to separate words in
2398 // filenames guessLibraryShortName() cannot reliably separate a dylib's short
2399 // name from an arbitrary image suffix; imagine if both the short name and the
2400 // suffix contains an '_' character! To better deal with this ambiguity,
2401 // guessLibraryShortName() will recognize only "_debug" and "_profile" as valid
2402 // Suffix values. Calling code needs to be tolerant of guessLibraryShortName()
2403 // guessing incorrectly.
2404 //
2405 // The Name of the dynamic library is also recognized as a library name if it
2406 // has the following form:
2407 //      Foo.qtx
2408 //
2409 // If the Name of the dynamic library is none of the forms above then a NULL
2410 // StringRef is returned.
2411 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
2412                                                  bool &isFramework,
2413                                                  StringRef &Suffix) {
2414   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2415   size_t a, b, c, d, Idx;
2416 
2417   isFramework = false;
2418   Suffix = StringRef();
2419 
2420   // Pull off the last component and make Foo point to it
2421   a = Name.rfind('/');
2422   if (a == Name.npos || a == 0)
2423     goto guess_library;
2424   Foo = Name.slice(a+1, Name.npos);
2425 
2426   // Look for a suffix starting with a '_'
2427   Idx = Foo.rfind('_');
2428   if (Idx != Foo.npos && Foo.size() >= 2) {
2429     Suffix = Foo.slice(Idx, Foo.npos);
2430     if (Suffix != "_debug" && Suffix != "_profile")
2431       Suffix = StringRef();
2432     else
2433       Foo = Foo.slice(0, Idx);
2434   }
2435 
2436   // First look for the form Foo.framework/Foo
2437   b = Name.rfind('/', a);
2438   if (b == Name.npos)
2439     Idx = 0;
2440   else
2441     Idx = b+1;
2442   F = Name.slice(Idx, Idx + Foo.size());
2443   DotFramework = Name.slice(Idx + Foo.size(),
2444                             Idx + Foo.size() + sizeof(".framework/")-1);
2445   if (F == Foo && DotFramework == ".framework/") {
2446     isFramework = true;
2447     return Foo;
2448   }
2449 
2450   // Next look for the form Foo.framework/Versions/A/Foo
2451   if (b == Name.npos)
2452     goto guess_library;
2453   c =  Name.rfind('/', b);
2454   if (c == Name.npos || c == 0)
2455     goto guess_library;
2456   V = Name.slice(c+1, Name.npos);
2457   if (!V.startswith("Versions/"))
2458     goto guess_library;
2459   d =  Name.rfind('/', c);
2460   if (d == Name.npos)
2461     Idx = 0;
2462   else
2463     Idx = d+1;
2464   F = Name.slice(Idx, Idx + Foo.size());
2465   DotFramework = Name.slice(Idx + Foo.size(),
2466                             Idx + Foo.size() + sizeof(".framework/")-1);
2467   if (F == Foo && DotFramework == ".framework/") {
2468     isFramework = true;
2469     return Foo;
2470   }
2471 
2472 guess_library:
2473   // pull off the suffix after the "." and make a point to it
2474   a = Name.rfind('.');
2475   if (a == Name.npos || a == 0)
2476     return StringRef();
2477   Dylib = Name.slice(a, Name.npos);
2478   if (Dylib != ".dylib")
2479     goto guess_qtx;
2480 
2481   // First pull off the version letter for the form Foo.A.dylib if any.
2482   if (a >= 3) {
2483     Dot = Name.slice(a-2, a-1);
2484     if (Dot == ".")
2485       a = a - 2;
2486   }
2487 
2488   b = Name.rfind('/', a);
2489   if (b == Name.npos)
2490     b = 0;
2491   else
2492     b = b+1;
2493   // ignore any suffix after an underbar like Foo_profile.A.dylib
2494   Idx = Name.rfind('_');
2495   if (Idx != Name.npos && Idx != b) {
2496     Lib = Name.slice(b, Idx);
2497     Suffix = Name.slice(Idx, a);
2498     if (Suffix != "_debug" && Suffix != "_profile") {
2499       Suffix = StringRef();
2500       Lib = Name.slice(b, a);
2501     }
2502   }
2503   else
2504     Lib = Name.slice(b, a);
2505   // There are incorrect library names of the form:
2506   // libATS.A_profile.dylib so check for these.
2507   if (Lib.size() >= 3) {
2508     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2509     if (Dot == ".")
2510       Lib = Lib.slice(0, Lib.size()-2);
2511   }
2512   return Lib;
2513 
2514 guess_qtx:
2515   Qtx = Name.slice(a, Name.npos);
2516   if (Qtx != ".qtx")
2517     return StringRef();
2518   b = Name.rfind('/', a);
2519   if (b == Name.npos)
2520     Lib = Name.slice(0, a);
2521   else
2522     Lib = Name.slice(b+1, a);
2523   // There are library names of the form: QT.A.qtx so check for these.
2524   if (Lib.size() >= 3) {
2525     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2526     if (Dot == ".")
2527       Lib = Lib.slice(0, Lib.size()-2);
2528   }
2529   return Lib;
2530 }
2531 
2532 // getLibraryShortNameByIndex() is used to get the short name of the library
2533 // for an undefined symbol in a linked Mach-O binary that was linked with the
2534 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
2535 // It is passed the index (0 - based) of the library as translated from
2536 // GET_LIBRARY_ORDINAL (1 - based).
2537 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
2538                                                          StringRef &Res) const {
2539   if (Index >= Libraries.size())
2540     return object_error::parse_failed;
2541 
2542   // If the cache of LibrariesShortNames is not built up do that first for
2543   // all the Libraries.
2544   if (LibrariesShortNames.size() == 0) {
2545     for (unsigned i = 0; i < Libraries.size(); i++) {
2546       auto CommandOrErr =
2547         getStructOrErr<MachO::dylib_command>(*this, Libraries[i]);
2548       if (!CommandOrErr)
2549         return object_error::parse_failed;
2550       MachO::dylib_command D = CommandOrErr.get();
2551       if (D.dylib.name >= D.cmdsize)
2552         return object_error::parse_failed;
2553       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2554       StringRef Name = StringRef(P);
2555       if (D.dylib.name+Name.size() >= D.cmdsize)
2556         return object_error::parse_failed;
2557       StringRef Suffix;
2558       bool isFramework;
2559       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2560       if (shortName.empty())
2561         LibrariesShortNames.push_back(Name);
2562       else
2563         LibrariesShortNames.push_back(shortName);
2564     }
2565   }
2566 
2567   Res = LibrariesShortNames[Index];
2568   return std::error_code();
2569 }
2570 
2571 uint32_t MachOObjectFile::getLibraryCount() const {
2572   return Libraries.size();
2573 }
2574 
2575 section_iterator
2576 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
2577   DataRefImpl Sec;
2578   Sec.d.a = Rel->getRawDataRefImpl().d.a;
2579   return section_iterator(SectionRef(Sec, this));
2580 }
2581 
2582 basic_symbol_iterator MachOObjectFile::symbol_begin() const {
2583   DataRefImpl DRI;
2584   MachO::symtab_command Symtab = getSymtabLoadCommand();
2585   if (!SymtabLoadCmd || Symtab.nsyms == 0)
2586     return basic_symbol_iterator(SymbolRef(DRI, this));
2587 
2588   return getSymbolByIndex(0);
2589 }
2590 
2591 basic_symbol_iterator MachOObjectFile::symbol_end() const {
2592   DataRefImpl DRI;
2593   MachO::symtab_command Symtab = getSymtabLoadCommand();
2594   if (!SymtabLoadCmd || Symtab.nsyms == 0)
2595     return basic_symbol_iterator(SymbolRef(DRI, this));
2596 
2597   unsigned SymbolTableEntrySize = is64Bit() ?
2598     sizeof(MachO::nlist_64) :
2599     sizeof(MachO::nlist);
2600   unsigned Offset = Symtab.symoff +
2601     Symtab.nsyms * SymbolTableEntrySize;
2602   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2603   return basic_symbol_iterator(SymbolRef(DRI, this));
2604 }
2605 
2606 symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
2607   MachO::symtab_command Symtab = getSymtabLoadCommand();
2608   if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2609     report_fatal_error("Requested symbol index is out of range.");
2610   unsigned SymbolTableEntrySize =
2611     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2612   DataRefImpl DRI;
2613   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2614   DRI.p += Index * SymbolTableEntrySize;
2615   return basic_symbol_iterator(SymbolRef(DRI, this));
2616 }
2617 
2618 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
2619   MachO::symtab_command Symtab = getSymtabLoadCommand();
2620   if (!SymtabLoadCmd)
2621     report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2622   unsigned SymbolTableEntrySize =
2623     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2624   DataRefImpl DRIstart;
2625   DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2626   uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2627   return Index;
2628 }
2629 
2630 section_iterator MachOObjectFile::section_begin() const {
2631   DataRefImpl DRI;
2632   return section_iterator(SectionRef(DRI, this));
2633 }
2634 
2635 section_iterator MachOObjectFile::section_end() const {
2636   DataRefImpl DRI;
2637   DRI.d.a = Sections.size();
2638   return section_iterator(SectionRef(DRI, this));
2639 }
2640 
2641 uint8_t MachOObjectFile::getBytesInAddress() const {
2642   return is64Bit() ? 8 : 4;
2643 }
2644 
2645 StringRef MachOObjectFile::getFileFormatName() const {
2646   unsigned CPUType = getCPUType(*this);
2647   if (!is64Bit()) {
2648     switch (CPUType) {
2649     case MachO::CPU_TYPE_I386:
2650       return "Mach-O 32-bit i386";
2651     case MachO::CPU_TYPE_ARM:
2652       return "Mach-O arm";
2653     case MachO::CPU_TYPE_ARM64_32:
2654       return "Mach-O arm64 (ILP32)";
2655     case MachO::CPU_TYPE_POWERPC:
2656       return "Mach-O 32-bit ppc";
2657     default:
2658       return "Mach-O 32-bit unknown";
2659     }
2660   }
2661 
2662   switch (CPUType) {
2663   case MachO::CPU_TYPE_X86_64:
2664     return "Mach-O 64-bit x86-64";
2665   case MachO::CPU_TYPE_ARM64:
2666     return "Mach-O arm64";
2667   case MachO::CPU_TYPE_POWERPC64:
2668     return "Mach-O 64-bit ppc64";
2669   default:
2670     return "Mach-O 64-bit unknown";
2671   }
2672 }
2673 
2674 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
2675   switch (CPUType) {
2676   case MachO::CPU_TYPE_I386:
2677     return Triple::x86;
2678   case MachO::CPU_TYPE_X86_64:
2679     return Triple::x86_64;
2680   case MachO::CPU_TYPE_ARM:
2681     return Triple::arm;
2682   case MachO::CPU_TYPE_ARM64:
2683     return Triple::aarch64;
2684   case MachO::CPU_TYPE_ARM64_32:
2685     return Triple::aarch64_32;
2686   case MachO::CPU_TYPE_POWERPC:
2687     return Triple::ppc;
2688   case MachO::CPU_TYPE_POWERPC64:
2689     return Triple::ppc64;
2690   default:
2691     return Triple::UnknownArch;
2692   }
2693 }
2694 
2695 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
2696                                       const char **McpuDefault,
2697                                       const char **ArchFlag) {
2698   if (McpuDefault)
2699     *McpuDefault = nullptr;
2700   if (ArchFlag)
2701     *ArchFlag = nullptr;
2702 
2703   switch (CPUType) {
2704   case MachO::CPU_TYPE_I386:
2705     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2706     case MachO::CPU_SUBTYPE_I386_ALL:
2707       if (ArchFlag)
2708         *ArchFlag = "i386";
2709       return Triple("i386-apple-darwin");
2710     default:
2711       return Triple();
2712     }
2713   case MachO::CPU_TYPE_X86_64:
2714     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2715     case MachO::CPU_SUBTYPE_X86_64_ALL:
2716       if (ArchFlag)
2717         *ArchFlag = "x86_64";
2718       return Triple("x86_64-apple-darwin");
2719     case MachO::CPU_SUBTYPE_X86_64_H:
2720       if (ArchFlag)
2721         *ArchFlag = "x86_64h";
2722       return Triple("x86_64h-apple-darwin");
2723     default:
2724       return Triple();
2725     }
2726   case MachO::CPU_TYPE_ARM:
2727     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2728     case MachO::CPU_SUBTYPE_ARM_V4T:
2729       if (ArchFlag)
2730         *ArchFlag = "armv4t";
2731       return Triple("armv4t-apple-darwin");
2732     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2733       if (ArchFlag)
2734         *ArchFlag = "armv5e";
2735       return Triple("armv5e-apple-darwin");
2736     case MachO::CPU_SUBTYPE_ARM_XSCALE:
2737       if (ArchFlag)
2738         *ArchFlag = "xscale";
2739       return Triple("xscale-apple-darwin");
2740     case MachO::CPU_SUBTYPE_ARM_V6:
2741       if (ArchFlag)
2742         *ArchFlag = "armv6";
2743       return Triple("armv6-apple-darwin");
2744     case MachO::CPU_SUBTYPE_ARM_V6M:
2745       if (McpuDefault)
2746         *McpuDefault = "cortex-m0";
2747       if (ArchFlag)
2748         *ArchFlag = "armv6m";
2749       return Triple("armv6m-apple-darwin");
2750     case MachO::CPU_SUBTYPE_ARM_V7:
2751       if (ArchFlag)
2752         *ArchFlag = "armv7";
2753       return Triple("armv7-apple-darwin");
2754     case MachO::CPU_SUBTYPE_ARM_V7EM:
2755       if (McpuDefault)
2756         *McpuDefault = "cortex-m4";
2757       if (ArchFlag)
2758         *ArchFlag = "armv7em";
2759       return Triple("thumbv7em-apple-darwin");
2760     case MachO::CPU_SUBTYPE_ARM_V7K:
2761       if (McpuDefault)
2762         *McpuDefault = "cortex-a7";
2763       if (ArchFlag)
2764         *ArchFlag = "armv7k";
2765       return Triple("armv7k-apple-darwin");
2766     case MachO::CPU_SUBTYPE_ARM_V7M:
2767       if (McpuDefault)
2768         *McpuDefault = "cortex-m3";
2769       if (ArchFlag)
2770         *ArchFlag = "armv7m";
2771       return Triple("thumbv7m-apple-darwin");
2772     case MachO::CPU_SUBTYPE_ARM_V7S:
2773       if (McpuDefault)
2774         *McpuDefault = "cortex-a7";
2775       if (ArchFlag)
2776         *ArchFlag = "armv7s";
2777       return Triple("armv7s-apple-darwin");
2778     default:
2779       return Triple();
2780     }
2781   case MachO::CPU_TYPE_ARM64:
2782     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2783     case MachO::CPU_SUBTYPE_ARM64_ALL:
2784       if (McpuDefault)
2785         *McpuDefault = "cyclone";
2786       if (ArchFlag)
2787         *ArchFlag = "arm64";
2788       return Triple("arm64-apple-darwin");
2789     case MachO::CPU_SUBTYPE_ARM64E:
2790       if (McpuDefault)
2791         *McpuDefault = "apple-a12";
2792       if (ArchFlag)
2793         *ArchFlag = "arm64e";
2794       return Triple("arm64e-apple-darwin");
2795     default:
2796       return Triple();
2797     }
2798   case MachO::CPU_TYPE_ARM64_32:
2799     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2800     case MachO::CPU_SUBTYPE_ARM64_32_V8:
2801       if (McpuDefault)
2802         *McpuDefault = "cyclone";
2803       if (ArchFlag)
2804         *ArchFlag = "arm64_32";
2805       return Triple("arm64_32-apple-darwin");
2806     default:
2807       return Triple();
2808     }
2809   case MachO::CPU_TYPE_POWERPC:
2810     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2811     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2812       if (ArchFlag)
2813         *ArchFlag = "ppc";
2814       return Triple("ppc-apple-darwin");
2815     default:
2816       return Triple();
2817     }
2818   case MachO::CPU_TYPE_POWERPC64:
2819     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2820     case MachO::CPU_SUBTYPE_POWERPC_ALL:
2821       if (ArchFlag)
2822         *ArchFlag = "ppc64";
2823       return Triple("ppc64-apple-darwin");
2824     default:
2825       return Triple();
2826     }
2827   default:
2828     return Triple();
2829   }
2830 }
2831 
2832 Triple MachOObjectFile::getHostArch() {
2833   return Triple(sys::getDefaultTargetTriple());
2834 }
2835 
2836 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
2837   auto validArchs = getValidArchs();
2838   return llvm::is_contained(validArchs, ArchFlag);
2839 }
2840 
2841 ArrayRef<StringRef> MachOObjectFile::getValidArchs() {
2842   static const std::array<StringRef, 18> ValidArchs = {{
2843       "i386",
2844       "x86_64",
2845       "x86_64h",
2846       "armv4t",
2847       "arm",
2848       "armv5e",
2849       "armv6",
2850       "armv6m",
2851       "armv7",
2852       "armv7em",
2853       "armv7k",
2854       "armv7m",
2855       "armv7s",
2856       "arm64",
2857       "arm64e",
2858       "arm64_32",
2859       "ppc",
2860       "ppc64",
2861   }};
2862 
2863   return ValidArchs;
2864 }
2865 
2866 Triple::ArchType MachOObjectFile::getArch() const {
2867   return getArch(getCPUType(*this), getCPUSubType(*this));
2868 }
2869 
2870 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2871   return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2872 }
2873 
2874 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
2875   DataRefImpl DRI;
2876   DRI.d.a = Index;
2877   return section_rel_begin(DRI);
2878 }
2879 
2880 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
2881   DataRefImpl DRI;
2882   DRI.d.a = Index;
2883   return section_rel_end(DRI);
2884 }
2885 
2886 dice_iterator MachOObjectFile::begin_dices() const {
2887   DataRefImpl DRI;
2888   if (!DataInCodeLoadCmd)
2889     return dice_iterator(DiceRef(DRI, this));
2890 
2891   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2892   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2893   return dice_iterator(DiceRef(DRI, this));
2894 }
2895 
2896 dice_iterator MachOObjectFile::end_dices() const {
2897   DataRefImpl DRI;
2898   if (!DataInCodeLoadCmd)
2899     return dice_iterator(DiceRef(DRI, this));
2900 
2901   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2902   unsigned Offset = DicLC.dataoff + DicLC.datasize;
2903   DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2904   return dice_iterator(DiceRef(DRI, this));
2905 }
2906 
2907 ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O,
2908                          ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {}
2909 
2910 void ExportEntry::moveToFirst() {
2911   ErrorAsOutParameter ErrAsOutParam(E);
2912   pushNode(0);
2913   if (*E)
2914     return;
2915   pushDownUntilBottom();
2916 }
2917 
2918 void ExportEntry::moveToEnd() {
2919   Stack.clear();
2920   Done = true;
2921 }
2922 
2923 bool ExportEntry::operator==(const ExportEntry &Other) const {
2924   // Common case, one at end, other iterating from begin.
2925   if (Done || Other.Done)
2926     return (Done == Other.Done);
2927   // Not equal if different stack sizes.
2928   if (Stack.size() != Other.Stack.size())
2929     return false;
2930   // Not equal if different cumulative strings.
2931   if (!CumulativeString.equals(Other.CumulativeString))
2932     return false;
2933   // Equal if all nodes in both stacks match.
2934   for (unsigned i=0; i < Stack.size(); ++i) {
2935     if (Stack[i].Start != Other.Stack[i].Start)
2936       return false;
2937   }
2938   return true;
2939 }
2940 
2941 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) {
2942   unsigned Count;
2943   uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error);
2944   Ptr += Count;
2945   if (Ptr > Trie.end())
2946     Ptr = Trie.end();
2947   return Result;
2948 }
2949 
2950 StringRef ExportEntry::name() const {
2951   return CumulativeString;
2952 }
2953 
2954 uint64_t ExportEntry::flags() const {
2955   return Stack.back().Flags;
2956 }
2957 
2958 uint64_t ExportEntry::address() const {
2959   return Stack.back().Address;
2960 }
2961 
2962 uint64_t ExportEntry::other() const {
2963   return Stack.back().Other;
2964 }
2965 
2966 StringRef ExportEntry::otherName() const {
2967   const char* ImportName = Stack.back().ImportName;
2968   if (ImportName)
2969     return StringRef(ImportName);
2970   return StringRef();
2971 }
2972 
2973 uint32_t ExportEntry::nodeOffset() const {
2974   return Stack.back().Start - Trie.begin();
2975 }
2976 
2977 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2978     : Start(Ptr), Current(Ptr) {}
2979 
2980 void ExportEntry::pushNode(uint64_t offset) {
2981   ErrorAsOutParameter ErrAsOutParam(E);
2982   const uint8_t *Ptr = Trie.begin() + offset;
2983   NodeState State(Ptr);
2984   const char *error;
2985   uint64_t ExportInfoSize = readULEB128(State.Current, &error);
2986   if (error) {
2987     *E = malformedError("export info size " + Twine(error) +
2988                         " in export trie data at node: 0x" +
2989                         Twine::utohexstr(offset));
2990     moveToEnd();
2991     return;
2992   }
2993   State.IsExportNode = (ExportInfoSize != 0);
2994   const uint8_t* Children = State.Current + ExportInfoSize;
2995   if (Children > Trie.end()) {
2996     *E = malformedError(
2997         "export info size: 0x" + Twine::utohexstr(ExportInfoSize) +
2998         " in export trie data at node: 0x" + Twine::utohexstr(offset) +
2999         " too big and extends past end of trie data");
3000     moveToEnd();
3001     return;
3002   }
3003   if (State.IsExportNode) {
3004     const uint8_t *ExportStart = State.Current;
3005     State.Flags = readULEB128(State.Current, &error);
3006     if (error) {
3007       *E = malformedError("flags " + Twine(error) +
3008                           " in export trie data at node: 0x" +
3009                           Twine::utohexstr(offset));
3010       moveToEnd();
3011       return;
3012     }
3013     uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK;
3014     if (State.Flags != 0 &&
3015         (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR &&
3016          Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE &&
3017          Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) {
3018       *E = malformedError(
3019           "unsupported exported symbol kind: " + Twine((int)Kind) +
3020           " in flags: 0x" + Twine::utohexstr(State.Flags) +
3021           " in export trie data at node: 0x" + Twine::utohexstr(offset));
3022       moveToEnd();
3023       return;
3024     }
3025     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
3026       State.Address = 0;
3027       State.Other = readULEB128(State.Current, &error); // dylib ordinal
3028       if (error) {
3029         *E = malformedError("dylib ordinal of re-export " + Twine(error) +
3030                             " in export trie data at node: 0x" +
3031                             Twine::utohexstr(offset));
3032         moveToEnd();
3033         return;
3034       }
3035       if (O != nullptr) {
3036         // Only positive numbers represent library ordinals. Zero and negative
3037         // numbers have special meaning (see BindSpecialDylib).
3038         if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3039           *E = malformedError(
3040               "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3041               Twine((int)O->getLibraryCount()) +
3042               ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3043           moveToEnd();
3044           return;
3045         }
3046       }
3047       State.ImportName = reinterpret_cast<const char*>(State.Current);
3048       if (*State.ImportName == '\0') {
3049         State.Current++;
3050       } else {
3051         const uint8_t *End = State.Current + 1;
3052         if (End >= Trie.end()) {
3053           *E = malformedError("import name of re-export in export trie data at "
3054                               "node: 0x" +
3055                               Twine::utohexstr(offset) +
3056                               " starts past end of trie data");
3057           moveToEnd();
3058           return;
3059         }
3060         while(*End != '\0' && End < Trie.end())
3061           End++;
3062         if (*End != '\0') {
3063           *E = malformedError("import name of re-export in export trie data at "
3064                               "node: 0x" +
3065                               Twine::utohexstr(offset) +
3066                               " extends past end of trie data");
3067           moveToEnd();
3068           return;
3069         }
3070         State.Current = End + 1;
3071       }
3072     } else {
3073       State.Address = readULEB128(State.Current, &error);
3074       if (error) {
3075         *E = malformedError("address " + Twine(error) +
3076                             " in export trie data at node: 0x" +
3077                             Twine::utohexstr(offset));
3078         moveToEnd();
3079         return;
3080       }
3081       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
3082         State.Other = readULEB128(State.Current, &error);
3083         if (error) {
3084           *E = malformedError("resolver of stub and resolver " + Twine(error) +
3085                               " in export trie data at node: 0x" +
3086                               Twine::utohexstr(offset));
3087           moveToEnd();
3088           return;
3089         }
3090       }
3091     }
3092     if(ExportStart + ExportInfoSize != State.Current) {
3093       *E = malformedError(
3094           "inconsistant export info size: 0x" +
3095           Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3096           Twine::utohexstr(State.Current - ExportStart) +
3097           " in export trie data at node: 0x" + Twine::utohexstr(offset));
3098       moveToEnd();
3099       return;
3100     }
3101   }
3102   State.ChildCount = *Children;
3103   if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3104     *E = malformedError("byte for count of childern in export trie data at "
3105                         "node: 0x" +
3106                         Twine::utohexstr(offset) +
3107                         " extends past end of trie data");
3108     moveToEnd();
3109     return;
3110   }
3111   State.Current = Children + 1;
3112   State.NextChildIndex = 0;
3113   State.ParentStringLength = CumulativeString.size();
3114   Stack.push_back(State);
3115 }
3116 
3117 void ExportEntry::pushDownUntilBottom() {
3118   ErrorAsOutParameter ErrAsOutParam(E);
3119   const char *error;
3120   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3121     NodeState &Top = Stack.back();
3122     CumulativeString.resize(Top.ParentStringLength);
3123     for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3124       char C = *Top.Current;
3125       CumulativeString.push_back(C);
3126     }
3127     if (Top.Current >= Trie.end()) {
3128       *E = malformedError("edge sub-string in export trie data at node: 0x" +
3129                           Twine::utohexstr(Top.Start - Trie.begin()) +
3130                           " for child #" + Twine((int)Top.NextChildIndex) +
3131                           " extends past end of trie data");
3132       moveToEnd();
3133       return;
3134     }
3135     Top.Current += 1;
3136     uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3137     if (error) {
3138       *E = malformedError("child node offset " + Twine(error) +
3139                           " in export trie data at node: 0x" +
3140                           Twine::utohexstr(Top.Start - Trie.begin()));
3141       moveToEnd();
3142       return;
3143     }
3144     for (const NodeState &node : nodes()) {
3145       if (node.Start == Trie.begin() + childNodeIndex){
3146         *E = malformedError("loop in childern in export trie data at node: 0x" +
3147                             Twine::utohexstr(Top.Start - Trie.begin()) +
3148                             " back to node: 0x" +
3149                             Twine::utohexstr(childNodeIndex));
3150         moveToEnd();
3151         return;
3152       }
3153     }
3154     Top.NextChildIndex += 1;
3155     pushNode(childNodeIndex);
3156     if (*E)
3157       return;
3158   }
3159   if (!Stack.back().IsExportNode) {
3160     *E = malformedError("node is not an export node in export trie data at "
3161                         "node: 0x" +
3162                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3163     moveToEnd();
3164     return;
3165   }
3166 }
3167 
3168 // We have a trie data structure and need a way to walk it that is compatible
3169 // with the C++ iterator model. The solution is a non-recursive depth first
3170 // traversal where the iterator contains a stack of parent nodes along with a
3171 // string that is the accumulation of all edge strings along the parent chain
3172 // to this point.
3173 //
3174 // There is one "export" node for each exported symbol.  But because some
3175 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
3176 // node may have child nodes too.
3177 //
3178 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
3179 // child until hitting a node with no children (which is an export node or
3180 // else the trie is malformed). On the way down, each node is pushed on the
3181 // stack ivar.  If there is no more ways down, it pops up one and tries to go
3182 // down a sibling path until a childless node is reached.
3183 void ExportEntry::moveNext() {
3184   assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3185   if (!Stack.back().IsExportNode) {
3186     *E = malformedError("node is not an export node in export trie data at "
3187                         "node: 0x" +
3188                         Twine::utohexstr(Stack.back().Start - Trie.begin()));
3189     moveToEnd();
3190     return;
3191   }
3192 
3193   Stack.pop_back();
3194   while (!Stack.empty()) {
3195     NodeState &Top = Stack.back();
3196     if (Top.NextChildIndex < Top.ChildCount) {
3197       pushDownUntilBottom();
3198       // Now at the next export node.
3199       return;
3200     } else {
3201       if (Top.IsExportNode) {
3202         // This node has no children but is itself an export node.
3203         CumulativeString.resize(Top.ParentStringLength);
3204         return;
3205       }
3206       Stack.pop_back();
3207     }
3208   }
3209   Done = true;
3210 }
3211 
3212 iterator_range<export_iterator>
3213 MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie,
3214                          const MachOObjectFile *O) {
3215   ExportEntry Start(&E, O, Trie);
3216   if (Trie.empty())
3217     Start.moveToEnd();
3218   else
3219     Start.moveToFirst();
3220 
3221   ExportEntry Finish(&E, O, Trie);
3222   Finish.moveToEnd();
3223 
3224   return make_range(export_iterator(Start), export_iterator(Finish));
3225 }
3226 
3227 iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const {
3228   return exports(Err, getDyldInfoExportsTrie(), this);
3229 }
3230 
3231 MachOAbstractFixupEntry::MachOAbstractFixupEntry(Error *E,
3232                                                  const MachOObjectFile *O)
3233     : E(E), O(O) {
3234   // Cache the vmaddress of __TEXT
3235   for (const auto &Command : O->load_commands()) {
3236     if (Command.C.cmd == MachO::LC_SEGMENT) {
3237       MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
3238       if (StringRef(SLC.segname) == StringRef("__TEXT")) {
3239         TextAddress = SLC.vmaddr;
3240         break;
3241       }
3242     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3243       MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
3244       if (StringRef(SLC_64.segname) == StringRef("__TEXT")) {
3245         TextAddress = SLC_64.vmaddr;
3246         break;
3247       }
3248     }
3249   }
3250 }
3251 
3252 int32_t MachOAbstractFixupEntry::segmentIndex() const { return SegmentIndex; }
3253 
3254 uint64_t MachOAbstractFixupEntry::segmentOffset() const {
3255   return SegmentOffset;
3256 }
3257 
3258 uint64_t MachOAbstractFixupEntry::segmentAddress() const {
3259   return O->BindRebaseAddress(SegmentIndex, 0);
3260 }
3261 
3262 StringRef MachOAbstractFixupEntry::segmentName() const {
3263   return O->BindRebaseSegmentName(SegmentIndex);
3264 }
3265 
3266 StringRef MachOAbstractFixupEntry::sectionName() const {
3267   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3268 }
3269 
3270 uint64_t MachOAbstractFixupEntry::address() const {
3271   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3272 }
3273 
3274 StringRef MachOAbstractFixupEntry::symbolName() const { return SymbolName; }
3275 
3276 int64_t MachOAbstractFixupEntry::addend() const { return Addend; }
3277 
3278 uint32_t MachOAbstractFixupEntry::flags() const { return Flags; }
3279 
3280 int MachOAbstractFixupEntry::ordinal() const { return Ordinal; }
3281 
3282 StringRef MachOAbstractFixupEntry::typeName() const { return "unknown"; }
3283 
3284 void MachOAbstractFixupEntry::moveToFirst() {
3285   SegmentOffset = 0;
3286   SegmentIndex = -1;
3287   Ordinal = 0;
3288   Flags = 0;
3289   Addend = 0;
3290   Done = false;
3291 }
3292 
3293 void MachOAbstractFixupEntry::moveToEnd() { Done = true; }
3294 
3295 void MachOAbstractFixupEntry::moveNext() {}
3296 
3297 MachOChainedFixupEntry::MachOChainedFixupEntry(Error *E,
3298                                                const MachOObjectFile *O,
3299                                                bool Parse)
3300     : MachOAbstractFixupEntry(E, O) {
3301   ErrorAsOutParameter e(E);
3302   if (!Parse)
3303     return;
3304 
3305   if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets()) {
3306     FixupTargets = *FixupTargetsOrErr;
3307   } else {
3308     *E = FixupTargetsOrErr.takeError();
3309     return;
3310   }
3311 
3312   if (auto SegmentsOrErr = O->getChainedFixupsSegments()) {
3313     Segments = std::move(SegmentsOrErr->second);
3314   } else {
3315     *E = SegmentsOrErr.takeError();
3316     return;
3317   }
3318 }
3319 
3320 void MachOChainedFixupEntry::findNextPageWithFixups() {
3321   auto FindInSegment = [this]() {
3322     const ChainedFixupsSegment &SegInfo = Segments[InfoSegIndex];
3323     while (PageIndex < SegInfo.PageStarts.size() &&
3324            SegInfo.PageStarts[PageIndex] == MachO::DYLD_CHAINED_PTR_START_NONE)
3325       ++PageIndex;
3326     return PageIndex < SegInfo.PageStarts.size();
3327   };
3328 
3329   while (InfoSegIndex < Segments.size()) {
3330     if (FindInSegment()) {
3331       PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3332       SegmentData = O->getSegmentContents(Segments[InfoSegIndex].SegIdx);
3333       return;
3334     }
3335 
3336     InfoSegIndex++;
3337     PageIndex = 0;
3338   }
3339 }
3340 
3341 void MachOChainedFixupEntry::moveToFirst() {
3342   MachOAbstractFixupEntry::moveToFirst();
3343   if (Segments.empty()) {
3344     Done = true;
3345     return;
3346   }
3347 
3348   InfoSegIndex = 0;
3349   PageIndex = 0;
3350 
3351   findNextPageWithFixups();
3352   moveNext();
3353 }
3354 
3355 void MachOChainedFixupEntry::moveToEnd() {
3356   MachOAbstractFixupEntry::moveToEnd();
3357 }
3358 
3359 void MachOChainedFixupEntry::moveNext() {
3360   ErrorAsOutParameter ErrAsOutParam(E);
3361 
3362   if (InfoSegIndex == Segments.size()) {
3363     Done = true;
3364     return;
3365   }
3366 
3367   const ChainedFixupsSegment &SegInfo = Segments[InfoSegIndex];
3368   SegmentIndex = SegInfo.SegIdx;
3369   SegmentOffset = SegInfo.Header.page_size * PageIndex + PageOffset;
3370 
3371   // FIXME: Handle other pointer formats.
3372   uint16_t PointerFormat = SegInfo.Header.pointer_format;
3373   if (PointerFormat != MachO::DYLD_CHAINED_PTR_64 &&
3374       PointerFormat != MachO::DYLD_CHAINED_PTR_64_OFFSET) {
3375     *E = createError("segment " + Twine(SegmentIndex) +
3376                      " has unsupported chained fixup pointer_format " +
3377                      Twine(PointerFormat));
3378     moveToEnd();
3379     return;
3380   }
3381 
3382   Ordinal = 0;
3383   Flags = 0;
3384   Addend = 0;
3385   PointerValue = 0;
3386   SymbolName = {};
3387 
3388   if (SegmentOffset + sizeof(RawValue) > SegmentData.size()) {
3389     *E = malformedError("fixup in segment " + Twine(SegmentIndex) +
3390                         " at offset " + Twine(SegmentOffset) +
3391                         " extends past segment's end");
3392     moveToEnd();
3393     return;
3394   }
3395 
3396   static_assert(sizeof(RawValue) == sizeof(MachO::dyld_chained_import_addend));
3397   memcpy(&RawValue, SegmentData.data() + SegmentOffset, sizeof(RawValue));
3398   if (O->isLittleEndian() != sys::IsLittleEndianHost)
3399     sys::swapByteOrder(RawValue);
3400 
3401   // The bit extraction below assumes little-endian fixup entries.
3402   assert(O->isLittleEndian() && "big-endian object should have been rejected "
3403                                 "by getDyldChainedFixupTargets()");
3404   auto Field = [this](uint8_t Right, uint8_t Count) {
3405     return (RawValue >> Right) & ((1ULL << Count) - 1);
3406   };
3407 
3408   // The `bind` field (most significant bit) of the encoded fixup determines
3409   // whether it is dyld_chained_ptr_64_bind or dyld_chained_ptr_64_rebase.
3410   bool IsBind = Field(63, 1);
3411   Kind = IsBind ? FixupKind::Bind : FixupKind::Rebase;
3412   uint32_t Next = Field(51, 12);
3413   if (IsBind) {
3414     uint32_t ImportOrdinal = Field(0, 24);
3415     uint8_t InlineAddend = Field(24, 8);
3416 
3417     if (ImportOrdinal >= FixupTargets.size()) {
3418       *E = malformedError("fixup in segment " + Twine(SegmentIndex) +
3419                           " at offset " + Twine(SegmentOffset) +
3420                           "  has out-of range import ordinal " +
3421                           Twine(ImportOrdinal));
3422       moveToEnd();
3423       return;
3424     }
3425 
3426     ChainedFixupTarget &Target = FixupTargets[ImportOrdinal];
3427     Ordinal = Target.libOrdinal();
3428     Addend = InlineAddend ? InlineAddend : Target.addend();
3429     Flags = Target.weakImport() ? MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0;
3430     SymbolName = Target.symbolName();
3431   } else {
3432     uint64_t Target = Field(0, 36);
3433     uint64_t High8 = Field(36, 8);
3434 
3435     PointerValue = Target | (High8 << 56);
3436     if (PointerFormat == MachO::DYLD_CHAINED_PTR_64_OFFSET)
3437       PointerValue += textAddress();
3438   }
3439 
3440   // The stride is 4 bytes for DYLD_CHAINED_PTR_64(_OFFSET).
3441   if (Next != 0) {
3442     PageOffset += 4 * Next;
3443   } else {
3444     ++PageIndex;
3445     findNextPageWithFixups();
3446   }
3447 }
3448 
3449 bool MachOChainedFixupEntry::operator==(
3450     const MachOChainedFixupEntry &Other) const {
3451   if (Done && Other.Done)
3452     return true;
3453   if (Done != Other.Done)
3454     return false;
3455   return InfoSegIndex == Other.InfoSegIndex && PageIndex == Other.PageIndex &&
3456          PageOffset == Other.PageOffset;
3457 }
3458 
3459 MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
3460                                    ArrayRef<uint8_t> Bytes, bool is64Bit)
3461     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3462       PointerSize(is64Bit ? 8 : 4) {}
3463 
3464 void MachORebaseEntry::moveToFirst() {
3465   Ptr = Opcodes.begin();
3466   moveNext();
3467 }
3468 
3469 void MachORebaseEntry::moveToEnd() {
3470   Ptr = Opcodes.end();
3471   RemainingLoopCount = 0;
3472   Done = true;
3473 }
3474 
3475 void MachORebaseEntry::moveNext() {
3476   ErrorAsOutParameter ErrAsOutParam(E);
3477   // If in the middle of some loop, move to next rebasing in loop.
3478   SegmentOffset += AdvanceAmount;
3479   if (RemainingLoopCount) {
3480     --RemainingLoopCount;
3481     return;
3482   }
3483   // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3484   // pointer size. Therefore it is possible to reach the end without ever having
3485   // seen REBASE_OPCODE_DONE.
3486   if (Ptr == Opcodes.end()) {
3487     Done = true;
3488     return;
3489   }
3490   bool More = true;
3491   while (More) {
3492     // Parse next opcode and set up next loop.
3493     const uint8_t *OpcodeStart = Ptr;
3494     uint8_t Byte = *Ptr++;
3495     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3496     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3497     uint32_t Count, Skip;
3498     const char *error = nullptr;
3499     switch (Opcode) {
3500     case MachO::REBASE_OPCODE_DONE:
3501       More = false;
3502       Done = true;
3503       moveToEnd();
3504       DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3505       break;
3506     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
3507       RebaseType = ImmValue;
3508       if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) {
3509         *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3510                             Twine((int)RebaseType) + " for opcode at: 0x" +
3511                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3512         moveToEnd();
3513         return;
3514       }
3515       DEBUG_WITH_TYPE(
3516           "mach-o-rebase",
3517           dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3518                  << "RebaseType=" << (int) RebaseType << "\n");
3519       break;
3520     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3521       SegmentIndex = ImmValue;
3522       SegmentOffset = readULEB128(&error);
3523       if (error) {
3524         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3525                             Twine(error) + " for opcode at: 0x" +
3526                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3527         moveToEnd();
3528         return;
3529       }
3530       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3531                                                PointerSize);
3532       if (error) {
3533         *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3534                             Twine(error) + " for opcode at: 0x" +
3535                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3536         moveToEnd();
3537         return;
3538       }
3539       DEBUG_WITH_TYPE(
3540           "mach-o-rebase",
3541           dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3542                  << "SegmentIndex=" << SegmentIndex << ", "
3543                  << format("SegmentOffset=0x%06X", SegmentOffset)
3544                  << "\n");
3545       break;
3546     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
3547       SegmentOffset += readULEB128(&error);
3548       if (error) {
3549         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3550                             " for opcode at: 0x" +
3551                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3552         moveToEnd();
3553         return;
3554       }
3555       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3556                                                PointerSize);
3557       if (error) {
3558         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3559                             " for opcode at: 0x" +
3560                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3561         moveToEnd();
3562         return;
3563       }
3564       DEBUG_WITH_TYPE("mach-o-rebase",
3565                       dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3566                              << format("SegmentOffset=0x%06X",
3567                                        SegmentOffset) << "\n");
3568       break;
3569     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
3570       SegmentOffset += ImmValue * PointerSize;
3571       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3572                                                PointerSize);
3573       if (error) {
3574         *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3575                             Twine(error) + " for opcode at: 0x" +
3576                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3577         moveToEnd();
3578         return;
3579       }
3580       DEBUG_WITH_TYPE("mach-o-rebase",
3581                       dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3582                              << format("SegmentOffset=0x%06X",
3583                                        SegmentOffset) << "\n");
3584       break;
3585     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
3586       AdvanceAmount = PointerSize;
3587       Skip = 0;
3588       Count = ImmValue;
3589       if (ImmValue != 0)
3590         RemainingLoopCount = ImmValue - 1;
3591       else
3592         RemainingLoopCount = 0;
3593       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3594                                                PointerSize, Count, Skip);
3595       if (error) {
3596         *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3597                             Twine(error) + " for opcode at: 0x" +
3598                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3599         moveToEnd();
3600         return;
3601       }
3602       DEBUG_WITH_TYPE(
3603           "mach-o-rebase",
3604           dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3605                  << format("SegmentOffset=0x%06X", SegmentOffset)
3606                  << ", AdvanceAmount=" << AdvanceAmount
3607                  << ", RemainingLoopCount=" << RemainingLoopCount
3608                  << "\n");
3609       return;
3610     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
3611       AdvanceAmount = PointerSize;
3612       Skip = 0;
3613       Count = readULEB128(&error);
3614       if (error) {
3615         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3616                             Twine(error) + " for opcode at: 0x" +
3617                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3618         moveToEnd();
3619         return;
3620       }
3621       if (Count != 0)
3622         RemainingLoopCount = Count - 1;
3623       else
3624         RemainingLoopCount = 0;
3625       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3626                                                PointerSize, Count, Skip);
3627       if (error) {
3628         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3629                             Twine(error) + " for opcode at: 0x" +
3630                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3631         moveToEnd();
3632         return;
3633       }
3634       DEBUG_WITH_TYPE(
3635           "mach-o-rebase",
3636           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3637                  << format("SegmentOffset=0x%06X", SegmentOffset)
3638                  << ", AdvanceAmount=" << AdvanceAmount
3639                  << ", RemainingLoopCount=" << RemainingLoopCount
3640                  << "\n");
3641       return;
3642     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
3643       Skip = readULEB128(&error);
3644       if (error) {
3645         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3646                             Twine(error) + " for opcode at: 0x" +
3647                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3648         moveToEnd();
3649         return;
3650       }
3651       AdvanceAmount = Skip + PointerSize;
3652       Count = 1;
3653       RemainingLoopCount = 0;
3654       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3655                                                PointerSize, Count, Skip);
3656       if (error) {
3657         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3658                             Twine(error) + " for opcode at: 0x" +
3659                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3660         moveToEnd();
3661         return;
3662       }
3663       DEBUG_WITH_TYPE(
3664           "mach-o-rebase",
3665           dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3666                  << format("SegmentOffset=0x%06X", SegmentOffset)
3667                  << ", AdvanceAmount=" << AdvanceAmount
3668                  << ", RemainingLoopCount=" << RemainingLoopCount
3669                  << "\n");
3670       return;
3671     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
3672       Count = readULEB128(&error);
3673       if (error) {
3674         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3675                             "ULEB " +
3676                             Twine(error) + " for opcode at: 0x" +
3677                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3678         moveToEnd();
3679         return;
3680       }
3681       if (Count != 0)
3682         RemainingLoopCount = Count - 1;
3683       else
3684         RemainingLoopCount = 0;
3685       Skip = readULEB128(&error);
3686       if (error) {
3687         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3688                             "ULEB " +
3689                             Twine(error) + " for opcode at: 0x" +
3690                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3691         moveToEnd();
3692         return;
3693       }
3694       AdvanceAmount = Skip + PointerSize;
3695 
3696       error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3697                                                PointerSize, Count, Skip);
3698       if (error) {
3699         *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3700                             "ULEB " +
3701                             Twine(error) + " for opcode at: 0x" +
3702                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3703         moveToEnd();
3704         return;
3705       }
3706       DEBUG_WITH_TYPE(
3707           "mach-o-rebase",
3708           dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3709                  << format("SegmentOffset=0x%06X", SegmentOffset)
3710                  << ", AdvanceAmount=" << AdvanceAmount
3711                  << ", RemainingLoopCount=" << RemainingLoopCount
3712                  << "\n");
3713       return;
3714     default:
3715       *E = malformedError("bad rebase info (bad opcode value 0x" +
3716                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3717                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3718       moveToEnd();
3719       return;
3720     }
3721   }
3722 }
3723 
3724 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3725   unsigned Count;
3726   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3727   Ptr += Count;
3728   if (Ptr > Opcodes.end())
3729     Ptr = Opcodes.end();
3730   return Result;
3731 }
3732 
3733 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3734 
3735 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
3736 
3737 StringRef MachORebaseEntry::typeName() const {
3738   switch (RebaseType) {
3739   case MachO::REBASE_TYPE_POINTER:
3740     return "pointer";
3741   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
3742     return "text abs32";
3743   case MachO::REBASE_TYPE_TEXT_PCREL32:
3744     return "text rel32";
3745   }
3746   return "unknown";
3747 }
3748 
3749 // For use with the SegIndex of a checked Mach-O Rebase entry
3750 // to get the segment name.
3751 StringRef MachORebaseEntry::segmentName() const {
3752   return O->BindRebaseSegmentName(SegmentIndex);
3753 }
3754 
3755 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3756 // to get the section name.
3757 StringRef MachORebaseEntry::sectionName() const {
3758   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3759 }
3760 
3761 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3762 // to get the address.
3763 uint64_t MachORebaseEntry::address() const {
3764   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3765 }
3766 
3767 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
3768 #ifdef EXPENSIVE_CHECKS
3769   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3770 #else
3771   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3772 #endif
3773   return (Ptr == Other.Ptr) &&
3774          (RemainingLoopCount == Other.RemainingLoopCount) &&
3775          (Done == Other.Done);
3776 }
3777 
3778 iterator_range<rebase_iterator>
3779 MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O,
3780                              ArrayRef<uint8_t> Opcodes, bool is64) {
3781   if (O->BindRebaseSectionTable == nullptr)
3782     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3783   MachORebaseEntry Start(&Err, O, Opcodes, is64);
3784   Start.moveToFirst();
3785 
3786   MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3787   Finish.moveToEnd();
3788 
3789   return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3790 }
3791 
3792 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) {
3793   return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3794 }
3795 
3796 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O,
3797                                ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3798     : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3799       PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3800 
3801 void MachOBindEntry::moveToFirst() {
3802   Ptr = Opcodes.begin();
3803   moveNext();
3804 }
3805 
3806 void MachOBindEntry::moveToEnd() {
3807   Ptr = Opcodes.end();
3808   RemainingLoopCount = 0;
3809   Done = true;
3810 }
3811 
3812 void MachOBindEntry::moveNext() {
3813   ErrorAsOutParameter ErrAsOutParam(E);
3814   // If in the middle of some loop, move to next binding in loop.
3815   SegmentOffset += AdvanceAmount;
3816   if (RemainingLoopCount) {
3817     --RemainingLoopCount;
3818     return;
3819   }
3820   // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3821   // pointer size. Therefore it is possible to reach the end without ever having
3822   // seen BIND_OPCODE_DONE.
3823   if (Ptr == Opcodes.end()) {
3824     Done = true;
3825     return;
3826   }
3827   bool More = true;
3828   while (More) {
3829     // Parse next opcode and set up next loop.
3830     const uint8_t *OpcodeStart = Ptr;
3831     uint8_t Byte = *Ptr++;
3832     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3833     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3834     int8_t SignExtended;
3835     const uint8_t *SymStart;
3836     uint32_t Count, Skip;
3837     const char *error = nullptr;
3838     switch (Opcode) {
3839     case MachO::BIND_OPCODE_DONE:
3840       if (TableKind == Kind::Lazy) {
3841         // Lazying bindings have a DONE opcode between entries.  Need to ignore
3842         // it to advance to next entry.  But need not if this is last entry.
3843         bool NotLastEntry = false;
3844         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3845           if (*P) {
3846             NotLastEntry = true;
3847           }
3848         }
3849         if (NotLastEntry)
3850           break;
3851       }
3852       More = false;
3853       moveToEnd();
3854       DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3855       break;
3856     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
3857       if (TableKind == Kind::Weak) {
3858         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3859                             "weak bind table for opcode at: 0x" +
3860                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3861         moveToEnd();
3862         return;
3863       }
3864       Ordinal = ImmValue;
3865       LibraryOrdinalSet = true;
3866       if (ImmValue > O->getLibraryCount()) {
3867         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3868                             "library ordinal: " +
3869                             Twine((int)ImmValue) + " (max " +
3870                             Twine((int)O->getLibraryCount()) +
3871                             ") for opcode at: 0x" +
3872                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3873         moveToEnd();
3874         return;
3875       }
3876       DEBUG_WITH_TYPE(
3877           "mach-o-bind",
3878           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3879                  << "Ordinal=" << Ordinal << "\n");
3880       break;
3881     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
3882       if (TableKind == Kind::Weak) {
3883         *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3884                             "weak bind table for opcode at: 0x" +
3885                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3886         moveToEnd();
3887         return;
3888       }
3889       Ordinal = readULEB128(&error);
3890       LibraryOrdinalSet = true;
3891       if (error) {
3892         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3893                             Twine(error) + " for opcode at: 0x" +
3894                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3895         moveToEnd();
3896         return;
3897       }
3898       if (Ordinal > (int)O->getLibraryCount()) {
3899         *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3900                             "library ordinal: " +
3901                             Twine((int)Ordinal) + " (max " +
3902                             Twine((int)O->getLibraryCount()) +
3903                             ") for opcode at: 0x" +
3904                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3905         moveToEnd();
3906         return;
3907       }
3908       DEBUG_WITH_TYPE(
3909           "mach-o-bind",
3910           dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3911                  << "Ordinal=" << Ordinal << "\n");
3912       break;
3913     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
3914       if (TableKind == Kind::Weak) {
3915         *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3916                             "weak bind table for opcode at: 0x" +
3917                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3918         moveToEnd();
3919         return;
3920       }
3921       if (ImmValue) {
3922         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3923         Ordinal = SignExtended;
3924         if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3925           *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3926                               "special ordinal: " +
3927                               Twine((int)Ordinal) + " for opcode at: 0x" +
3928                               Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3929           moveToEnd();
3930           return;
3931         }
3932       } else
3933         Ordinal = 0;
3934       LibraryOrdinalSet = true;
3935       DEBUG_WITH_TYPE(
3936           "mach-o-bind",
3937           dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3938                  << "Ordinal=" << Ordinal << "\n");
3939       break;
3940     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
3941       Flags = ImmValue;
3942       SymStart = Ptr;
3943       while (*Ptr && (Ptr < Opcodes.end())) {
3944         ++Ptr;
3945       }
3946       if (Ptr == Opcodes.end()) {
3947         *E = malformedError(
3948             "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3949             "symbol name extends past opcodes for opcode at: 0x" +
3950             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3951         moveToEnd();
3952         return;
3953       }
3954       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3955                              Ptr-SymStart);
3956       ++Ptr;
3957       DEBUG_WITH_TYPE(
3958           "mach-o-bind",
3959           dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3960                  << "SymbolName=" << SymbolName << "\n");
3961       if (TableKind == Kind::Weak) {
3962         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
3963           return;
3964       }
3965       break;
3966     case MachO::BIND_OPCODE_SET_TYPE_IMM:
3967       BindType = ImmValue;
3968       if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3969         *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3970                             Twine((int)ImmValue) + " for opcode at: 0x" +
3971                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3972         moveToEnd();
3973         return;
3974       }
3975       DEBUG_WITH_TYPE(
3976           "mach-o-bind",
3977           dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3978                  << "BindType=" << (int)BindType << "\n");
3979       break;
3980     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
3981       Addend = readSLEB128(&error);
3982       if (error) {
3983         *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3984                             " for opcode at: 0x" +
3985                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3986         moveToEnd();
3987         return;
3988       }
3989       DEBUG_WITH_TYPE(
3990           "mach-o-bind",
3991           dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3992                  << "Addend=" << Addend << "\n");
3993       break;
3994     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3995       SegmentIndex = ImmValue;
3996       SegmentOffset = readULEB128(&error);
3997       if (error) {
3998         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3999                             Twine(error) + " for opcode at: 0x" +
4000                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4001         moveToEnd();
4002         return;
4003       }
4004       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4005                                              PointerSize);
4006       if (error) {
4007         *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4008                             Twine(error) + " for opcode at: 0x" +
4009                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4010         moveToEnd();
4011         return;
4012       }
4013       DEBUG_WITH_TYPE(
4014           "mach-o-bind",
4015           dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
4016                  << "SegmentIndex=" << SegmentIndex << ", "
4017                  << format("SegmentOffset=0x%06X", SegmentOffset)
4018                  << "\n");
4019       break;
4020     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
4021       SegmentOffset += readULEB128(&error);
4022       if (error) {
4023         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
4024                             " for opcode at: 0x" +
4025                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4026         moveToEnd();
4027         return;
4028       }
4029       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4030                                              PointerSize);
4031       if (error) {
4032         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
4033                             " for opcode at: 0x" +
4034                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4035         moveToEnd();
4036         return;
4037       }
4038       DEBUG_WITH_TYPE("mach-o-bind",
4039                       dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
4040                              << format("SegmentOffset=0x%06X",
4041                                        SegmentOffset) << "\n");
4042       break;
4043     case MachO::BIND_OPCODE_DO_BIND:
4044       AdvanceAmount = PointerSize;
4045       RemainingLoopCount = 0;
4046       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4047                                              PointerSize);
4048       if (error) {
4049         *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
4050                             " for opcode at: 0x" +
4051                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4052         moveToEnd();
4053         return;
4054       }
4055       if (SymbolName == StringRef()) {
4056         *E = malformedError(
4057             "for BIND_OPCODE_DO_BIND missing preceding "
4058             "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4059             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4060         moveToEnd();
4061         return;
4062       }
4063       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4064         *E =
4065             malformedError("for BIND_OPCODE_DO_BIND missing preceding "
4066                            "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4067                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4068         moveToEnd();
4069         return;
4070       }
4071       DEBUG_WITH_TYPE("mach-o-bind",
4072                       dbgs() << "BIND_OPCODE_DO_BIND: "
4073                              << format("SegmentOffset=0x%06X",
4074                                        SegmentOffset) << "\n");
4075       return;
4076      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
4077       if (TableKind == Kind::Lazy) {
4078         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
4079                             "lazy bind table for opcode at: 0x" +
4080                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4081         moveToEnd();
4082         return;
4083       }
4084       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4085                                              PointerSize);
4086       if (error) {
4087         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4088                             Twine(error) + " for opcode at: 0x" +
4089                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4090         moveToEnd();
4091         return;
4092       }
4093       if (SymbolName == StringRef()) {
4094         *E = malformedError(
4095             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4096             "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
4097             "at: 0x" +
4098             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4099         moveToEnd();
4100         return;
4101       }
4102       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4103         *E = malformedError(
4104             "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4105             "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4106             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4107         moveToEnd();
4108         return;
4109       }
4110       AdvanceAmount = readULEB128(&error) + PointerSize;
4111       if (error) {
4112         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4113                             Twine(error) + " for opcode at: 0x" +
4114                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4115         moveToEnd();
4116         return;
4117       }
4118       // Note, this is not really an error until the next bind but make no sense
4119       // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
4120       // bind operation.
4121       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4122                                             AdvanceAmount, PointerSize);
4123       if (error) {
4124         *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
4125                             "ULEB) " +
4126                             Twine(error) + " for opcode at: 0x" +
4127                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4128         moveToEnd();
4129         return;
4130       }
4131       RemainingLoopCount = 0;
4132       DEBUG_WITH_TYPE(
4133           "mach-o-bind",
4134           dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
4135                  << format("SegmentOffset=0x%06X", SegmentOffset)
4136                  << ", AdvanceAmount=" << AdvanceAmount
4137                  << ", RemainingLoopCount=" << RemainingLoopCount
4138                  << "\n");
4139       return;
4140     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
4141       if (TableKind == Kind::Lazy) {
4142         *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
4143                             "allowed in lazy bind table for opcode at: 0x" +
4144                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4145         moveToEnd();
4146         return;
4147       }
4148       if (SymbolName == StringRef()) {
4149         *E = malformedError(
4150             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4151             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4152             "opcode at: 0x" +
4153             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4154         moveToEnd();
4155         return;
4156       }
4157       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4158         *E = malformedError(
4159             "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4160             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4161             "at: 0x" +
4162             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4163         moveToEnd();
4164         return;
4165       }
4166       AdvanceAmount = ImmValue * PointerSize + PointerSize;
4167       RemainingLoopCount = 0;
4168       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4169                                              AdvanceAmount, PointerSize);
4170       if (error) {
4171         *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4172                             Twine(error) + " for opcode at: 0x" +
4173                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4174         moveToEnd();
4175         return;
4176       }
4177       DEBUG_WITH_TYPE("mach-o-bind",
4178                       dbgs()
4179                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4180                       << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4181       return;
4182     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
4183       if (TableKind == Kind::Lazy) {
4184         *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4185                             "allowed in lazy bind table for opcode at: 0x" +
4186                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4187         moveToEnd();
4188         return;
4189       }
4190       Count = readULEB128(&error);
4191       if (Count != 0)
4192         RemainingLoopCount = Count - 1;
4193       else
4194         RemainingLoopCount = 0;
4195       if (error) {
4196         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4197                             " (count value) " +
4198                             Twine(error) + " for opcode at: 0x" +
4199                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4200         moveToEnd();
4201         return;
4202       }
4203       Skip = readULEB128(&error);
4204       AdvanceAmount = Skip + PointerSize;
4205       if (error) {
4206         *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4207                             " (skip value) " +
4208                             Twine(error) + " for opcode at: 0x" +
4209                             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4210         moveToEnd();
4211         return;
4212       }
4213       if (SymbolName == StringRef()) {
4214         *E = malformedError(
4215             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4216             "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4217             "opcode at: 0x" +
4218             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4219         moveToEnd();
4220         return;
4221       }
4222       if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4223         *E = malformedError(
4224             "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4225             "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4226             "at: 0x" +
4227             Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4228         moveToEnd();
4229         return;
4230       }
4231       error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4232                                              PointerSize, Count, Skip);
4233       if (error) {
4234         *E =
4235             malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4236                            Twine(error) + " for opcode at: 0x" +
4237                            Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4238         moveToEnd();
4239         return;
4240       }
4241       DEBUG_WITH_TYPE(
4242           "mach-o-bind",
4243           dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4244                  << format("SegmentOffset=0x%06X", SegmentOffset)
4245                  << ", AdvanceAmount=" << AdvanceAmount
4246                  << ", RemainingLoopCount=" << RemainingLoopCount
4247                  << "\n");
4248       return;
4249     default:
4250       *E = malformedError("bad bind info (bad opcode value 0x" +
4251                           Twine::utohexstr(Opcode) + " for opcode at: 0x" +
4252                           Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4253       moveToEnd();
4254       return;
4255     }
4256   }
4257 }
4258 
4259 uint64_t MachOBindEntry::readULEB128(const char **error) {
4260   unsigned Count;
4261   uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
4262   Ptr += Count;
4263   if (Ptr > Opcodes.end())
4264     Ptr = Opcodes.end();
4265   return Result;
4266 }
4267 
4268 int64_t MachOBindEntry::readSLEB128(const char **error) {
4269   unsigned Count;
4270   int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
4271   Ptr += Count;
4272   if (Ptr > Opcodes.end())
4273     Ptr = Opcodes.end();
4274   return Result;
4275 }
4276 
4277 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
4278 
4279 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
4280 
4281 StringRef MachOBindEntry::typeName() const {
4282   switch (BindType) {
4283   case MachO::BIND_TYPE_POINTER:
4284     return "pointer";
4285   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
4286     return "text abs32";
4287   case MachO::BIND_TYPE_TEXT_PCREL32:
4288     return "text rel32";
4289   }
4290   return "unknown";
4291 }
4292 
4293 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
4294 
4295 int64_t MachOBindEntry::addend() const { return Addend; }
4296 
4297 uint32_t MachOBindEntry::flags() const { return Flags; }
4298 
4299 int MachOBindEntry::ordinal() const { return Ordinal; }
4300 
4301 // For use with the SegIndex of a checked Mach-O Bind entry
4302 // to get the segment name.
4303 StringRef MachOBindEntry::segmentName() const {
4304   return O->BindRebaseSegmentName(SegmentIndex);
4305 }
4306 
4307 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4308 // to get the section name.
4309 StringRef MachOBindEntry::sectionName() const {
4310   return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4311 }
4312 
4313 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4314 // to get the address.
4315 uint64_t MachOBindEntry::address() const {
4316   return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4317 }
4318 
4319 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
4320 #ifdef EXPENSIVE_CHECKS
4321   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4322 #else
4323   assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4324 #endif
4325   return (Ptr == Other.Ptr) &&
4326          (RemainingLoopCount == Other.RemainingLoopCount) &&
4327          (Done == Other.Done);
4328 }
4329 
4330 // Build table of sections so SegIndex/SegOffset pairs can be translated.
4331 BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
4332   uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4333   StringRef CurSegName;
4334   uint64_t CurSegAddress;
4335   for (const SectionRef &Section : Obj->sections()) {
4336     SectionInfo Info;
4337     Expected<StringRef> NameOrErr = Section.getName();
4338     if (!NameOrErr)
4339       consumeError(NameOrErr.takeError());
4340     else
4341       Info.SectionName = *NameOrErr;
4342     Info.Address = Section.getAddress();
4343     Info.Size = Section.getSize();
4344     Info.SegmentName =
4345         Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4346     if (!Info.SegmentName.equals(CurSegName)) {
4347       ++CurSegIndex;
4348       CurSegName = Info.SegmentName;
4349       CurSegAddress = Info.Address;
4350     }
4351     Info.SegmentIndex = CurSegIndex - 1;
4352     Info.OffsetInSegment = Info.Address - CurSegAddress;
4353     Info.SegmentStartAddress = CurSegAddress;
4354     Sections.push_back(Info);
4355   }
4356   MaxSegIndex = CurSegIndex;
4357 }
4358 
4359 // For use with a SegIndex, SegOffset, and PointerSize triple in
4360 // MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry.
4361 //
4362 // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
4363 // that fully contains a pointer at that location. Multiple fixups in a bind
4364 // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
4365 // be tested via the Count and Skip parameters.
4366 const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
4367                                                    uint64_t SegOffset,
4368                                                    uint8_t PointerSize,
4369                                                    uint32_t Count,
4370                                                    uint32_t Skip) {
4371   if (SegIndex == -1)
4372     return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4373   if (SegIndex >= MaxSegIndex)
4374     return "bad segIndex (too large)";
4375   for (uint32_t i = 0; i < Count; ++i) {
4376     uint32_t Start = SegOffset + i * (PointerSize + Skip);
4377     uint32_t End = Start + PointerSize;
4378     bool Found = false;
4379     for (const SectionInfo &SI : Sections) {
4380       if (SI.SegmentIndex != SegIndex)
4381         continue;
4382       if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4383         if (End <= SI.OffsetInSegment + SI.Size) {
4384           Found = true;
4385           break;
4386         }
4387         else
4388           return "bad offset, extends beyond section boundary";
4389       }
4390     }
4391     if (!Found)
4392       return "bad offset, not in section";
4393   }
4394   return nullptr;
4395 }
4396 
4397 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4398 // to get the segment name.
4399 StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) {
4400   for (const SectionInfo &SI : Sections) {
4401     if (SI.SegmentIndex == SegIndex)
4402       return SI.SegmentName;
4403   }
4404   llvm_unreachable("invalid SegIndex");
4405 }
4406 
4407 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4408 // to get the SectionInfo.
4409 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4410                                      int32_t SegIndex, uint64_t SegOffset) {
4411   for (const SectionInfo &SI : Sections) {
4412     if (SI.SegmentIndex != SegIndex)
4413       continue;
4414     if (SI.OffsetInSegment > SegOffset)
4415       continue;
4416     if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4417       continue;
4418     return SI;
4419   }
4420   llvm_unreachable("SegIndex and SegOffset not in any section");
4421 }
4422 
4423 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4424 // entry to get the section name.
4425 StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex,
4426                                          uint64_t SegOffset) {
4427   return findSection(SegIndex, SegOffset).SectionName;
4428 }
4429 
4430 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4431 // entry to get the address.
4432 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4433   const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4434   return SI.SegmentStartAddress + OffsetInSeg;
4435 }
4436 
4437 iterator_range<bind_iterator>
4438 MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O,
4439                            ArrayRef<uint8_t> Opcodes, bool is64,
4440                            MachOBindEntry::Kind BKind) {
4441   if (O->BindRebaseSectionTable == nullptr)
4442     O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4443   MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4444   Start.moveToFirst();
4445 
4446   MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4447   Finish.moveToEnd();
4448 
4449   return make_range(bind_iterator(Start), bind_iterator(Finish));
4450 }
4451 
4452 iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) {
4453   return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4454                    MachOBindEntry::Kind::Regular);
4455 }
4456 
4457 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) {
4458   return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4459                    MachOBindEntry::Kind::Lazy);
4460 }
4461 
4462 iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
4463   return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4464                    MachOBindEntry::Kind::Weak);
4465 }
4466 
4467 iterator_range<fixup_iterator> MachOObjectFile::fixupTable(Error &Err) {
4468   if (BindRebaseSectionTable == nullptr)
4469     BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(this);
4470 
4471   MachOChainedFixupEntry Start(&Err, this, true);
4472   Start.moveToFirst();
4473 
4474   MachOChainedFixupEntry Finish(&Err, this, false);
4475   Finish.moveToEnd();
4476 
4477   return make_range(fixup_iterator(Start), fixup_iterator(Finish));
4478 }
4479 
4480 MachOObjectFile::load_command_iterator
4481 MachOObjectFile::begin_load_commands() const {
4482   return LoadCommands.begin();
4483 }
4484 
4485 MachOObjectFile::load_command_iterator
4486 MachOObjectFile::end_load_commands() const {
4487   return LoadCommands.end();
4488 }
4489 
4490 iterator_range<MachOObjectFile::load_command_iterator>
4491 MachOObjectFile::load_commands() const {
4492   return make_range(begin_load_commands(), end_load_commands());
4493 }
4494 
4495 StringRef
4496 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
4497   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4498   return parseSegmentOrSectionName(Raw.data());
4499 }
4500 
4501 ArrayRef<char>
4502 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
4503   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4504   const section_base *Base =
4505     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4506   return makeArrayRef(Base->sectname);
4507 }
4508 
4509 ArrayRef<char>
4510 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
4511   assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4512   const section_base *Base =
4513     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4514   return makeArrayRef(Base->segname);
4515 }
4516 
4517 bool
4518 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
4519   const {
4520   if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4521     return false;
4522   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
4523 }
4524 
4525 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
4526     const MachO::any_relocation_info &RE) const {
4527   if (isLittleEndian())
4528     return RE.r_word1 & 0xffffff;
4529   return RE.r_word1 >> 8;
4530 }
4531 
4532 bool MachOObjectFile::getPlainRelocationExternal(
4533     const MachO::any_relocation_info &RE) const {
4534   if (isLittleEndian())
4535     return (RE.r_word1 >> 27) & 1;
4536   return (RE.r_word1 >> 4) & 1;
4537 }
4538 
4539 bool MachOObjectFile::getScatteredRelocationScattered(
4540     const MachO::any_relocation_info &RE) const {
4541   return RE.r_word0 >> 31;
4542 }
4543 
4544 uint32_t MachOObjectFile::getScatteredRelocationValue(
4545     const MachO::any_relocation_info &RE) const {
4546   return RE.r_word1;
4547 }
4548 
4549 uint32_t MachOObjectFile::getScatteredRelocationType(
4550     const MachO::any_relocation_info &RE) const {
4551   return (RE.r_word0 >> 24) & 0xf;
4552 }
4553 
4554 unsigned MachOObjectFile::getAnyRelocationAddress(
4555     const MachO::any_relocation_info &RE) const {
4556   if (isRelocationScattered(RE))
4557     return getScatteredRelocationAddress(RE);
4558   return getPlainRelocationAddress(RE);
4559 }
4560 
4561 unsigned MachOObjectFile::getAnyRelocationPCRel(
4562     const MachO::any_relocation_info &RE) const {
4563   if (isRelocationScattered(RE))
4564     return getScatteredRelocationPCRel(RE);
4565   return getPlainRelocationPCRel(*this, RE);
4566 }
4567 
4568 unsigned MachOObjectFile::getAnyRelocationLength(
4569     const MachO::any_relocation_info &RE) const {
4570   if (isRelocationScattered(RE))
4571     return getScatteredRelocationLength(RE);
4572   return getPlainRelocationLength(*this, RE);
4573 }
4574 
4575 unsigned
4576 MachOObjectFile::getAnyRelocationType(
4577                                    const MachO::any_relocation_info &RE) const {
4578   if (isRelocationScattered(RE))
4579     return getScatteredRelocationType(RE);
4580   return getPlainRelocationType(*this, RE);
4581 }
4582 
4583 SectionRef
4584 MachOObjectFile::getAnyRelocationSection(
4585                                    const MachO::any_relocation_info &RE) const {
4586   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4587     return *section_end();
4588   unsigned SecNum = getPlainRelocationSymbolNum(RE);
4589   if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4590     return *section_end();
4591   DataRefImpl DRI;
4592   DRI.d.a = SecNum - 1;
4593   return SectionRef(DRI, this);
4594 }
4595 
4596 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
4597   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4598   return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4599 }
4600 
4601 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
4602   assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4603   return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4604 }
4605 
4606 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
4607                                            unsigned Index) const {
4608   const char *Sec = getSectionPtr(*this, L, Index);
4609   return getStruct<MachO::section>(*this, Sec);
4610 }
4611 
4612 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
4613                                                 unsigned Index) const {
4614   const char *Sec = getSectionPtr(*this, L, Index);
4615   return getStruct<MachO::section_64>(*this, Sec);
4616 }
4617 
4618 MachO::nlist
4619 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
4620   const char *P = reinterpret_cast<const char *>(DRI.p);
4621   return getStruct<MachO::nlist>(*this, P);
4622 }
4623 
4624 MachO::nlist_64
4625 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
4626   const char *P = reinterpret_cast<const char *>(DRI.p);
4627   return getStruct<MachO::nlist_64>(*this, P);
4628 }
4629 
4630 MachO::linkedit_data_command
4631 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
4632   return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4633 }
4634 
4635 MachO::segment_command
4636 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
4637   return getStruct<MachO::segment_command>(*this, L.Ptr);
4638 }
4639 
4640 MachO::segment_command_64
4641 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
4642   return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4643 }
4644 
4645 MachO::linker_option_command
4646 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
4647   return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4648 }
4649 
4650 MachO::version_min_command
4651 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
4652   return getStruct<MachO::version_min_command>(*this, L.Ptr);
4653 }
4654 
4655 MachO::note_command
4656 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
4657   return getStruct<MachO::note_command>(*this, L.Ptr);
4658 }
4659 
4660 MachO::build_version_command
4661 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
4662   return getStruct<MachO::build_version_command>(*this, L.Ptr);
4663 }
4664 
4665 MachO::build_tool_version
4666 MachOObjectFile::getBuildToolVersion(unsigned index) const {
4667   return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4668 }
4669 
4670 MachO::dylib_command
4671 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
4672   return getStruct<MachO::dylib_command>(*this, L.Ptr);
4673 }
4674 
4675 MachO::dyld_info_command
4676 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
4677   return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4678 }
4679 
4680 MachO::dylinker_command
4681 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
4682   return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4683 }
4684 
4685 MachO::uuid_command
4686 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
4687   return getStruct<MachO::uuid_command>(*this, L.Ptr);
4688 }
4689 
4690 MachO::rpath_command
4691 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
4692   return getStruct<MachO::rpath_command>(*this, L.Ptr);
4693 }
4694 
4695 MachO::source_version_command
4696 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
4697   return getStruct<MachO::source_version_command>(*this, L.Ptr);
4698 }
4699 
4700 MachO::entry_point_command
4701 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
4702   return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4703 }
4704 
4705 MachO::encryption_info_command
4706 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
4707   return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4708 }
4709 
4710 MachO::encryption_info_command_64
4711 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
4712   return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4713 }
4714 
4715 MachO::sub_framework_command
4716 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
4717   return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4718 }
4719 
4720 MachO::sub_umbrella_command
4721 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
4722   return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4723 }
4724 
4725 MachO::sub_library_command
4726 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
4727   return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4728 }
4729 
4730 MachO::sub_client_command
4731 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
4732   return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4733 }
4734 
4735 MachO::routines_command
4736 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
4737   return getStruct<MachO::routines_command>(*this, L.Ptr);
4738 }
4739 
4740 MachO::routines_command_64
4741 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
4742   return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4743 }
4744 
4745 MachO::thread_command
4746 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
4747   return getStruct<MachO::thread_command>(*this, L.Ptr);
4748 }
4749 
4750 MachO::any_relocation_info
4751 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
4752   uint32_t Offset;
4753   if (getHeader().filetype == MachO::MH_OBJECT) {
4754     DataRefImpl Sec;
4755     Sec.d.a = Rel.d.a;
4756     if (is64Bit()) {
4757       MachO::section_64 Sect = getSection64(Sec);
4758       Offset = Sect.reloff;
4759     } else {
4760       MachO::section Sect = getSection(Sec);
4761       Offset = Sect.reloff;
4762     }
4763   } else {
4764     MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4765     if (Rel.d.a == 0)
4766       Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4767     else
4768       Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4769   }
4770 
4771   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4772       getPtr(*this, Offset)) + Rel.d.b;
4773   return getStruct<MachO::any_relocation_info>(
4774       *this, reinterpret_cast<const char *>(P));
4775 }
4776 
4777 MachO::data_in_code_entry
4778 MachOObjectFile::getDice(DataRefImpl Rel) const {
4779   const char *P = reinterpret_cast<const char *>(Rel.p);
4780   return getStruct<MachO::data_in_code_entry>(*this, P);
4781 }
4782 
4783 const MachO::mach_header &MachOObjectFile::getHeader() const {
4784   return Header;
4785 }
4786 
4787 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
4788   assert(is64Bit());
4789   return Header64;
4790 }
4791 
4792 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
4793                                              const MachO::dysymtab_command &DLC,
4794                                              unsigned Index) const {
4795   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4796   return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4797 }
4798 
4799 MachO::data_in_code_entry
4800 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
4801                                          unsigned Index) const {
4802   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4803   return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4804 }
4805 
4806 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
4807   if (SymtabLoadCmd)
4808     return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4809 
4810   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4811   MachO::symtab_command Cmd;
4812   Cmd.cmd = MachO::LC_SYMTAB;
4813   Cmd.cmdsize = sizeof(MachO::symtab_command);
4814   Cmd.symoff = 0;
4815   Cmd.nsyms = 0;
4816   Cmd.stroff = 0;
4817   Cmd.strsize = 0;
4818   return Cmd;
4819 }
4820 
4821 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
4822   if (DysymtabLoadCmd)
4823     return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4824 
4825   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4826   MachO::dysymtab_command Cmd;
4827   Cmd.cmd = MachO::LC_DYSYMTAB;
4828   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4829   Cmd.ilocalsym = 0;
4830   Cmd.nlocalsym = 0;
4831   Cmd.iextdefsym = 0;
4832   Cmd.nextdefsym = 0;
4833   Cmd.iundefsym = 0;
4834   Cmd.nundefsym = 0;
4835   Cmd.tocoff = 0;
4836   Cmd.ntoc = 0;
4837   Cmd.modtaboff = 0;
4838   Cmd.nmodtab = 0;
4839   Cmd.extrefsymoff = 0;
4840   Cmd.nextrefsyms = 0;
4841   Cmd.indirectsymoff = 0;
4842   Cmd.nindirectsyms = 0;
4843   Cmd.extreloff = 0;
4844   Cmd.nextrel = 0;
4845   Cmd.locreloff = 0;
4846   Cmd.nlocrel = 0;
4847   return Cmd;
4848 }
4849 
4850 MachO::linkedit_data_command
4851 MachOObjectFile::getDataInCodeLoadCommand() const {
4852   if (DataInCodeLoadCmd)
4853     return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4854 
4855   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4856   MachO::linkedit_data_command Cmd;
4857   Cmd.cmd = MachO::LC_DATA_IN_CODE;
4858   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4859   Cmd.dataoff = 0;
4860   Cmd.datasize = 0;
4861   return Cmd;
4862 }
4863 
4864 MachO::linkedit_data_command
4865 MachOObjectFile::getLinkOptHintsLoadCommand() const {
4866   if (LinkOptHintsLoadCmd)
4867     return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4868 
4869   // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4870   // fields.
4871   MachO::linkedit_data_command Cmd;
4872   Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4873   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4874   Cmd.dataoff = 0;
4875   Cmd.datasize = 0;
4876   return Cmd;
4877 }
4878 
4879 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
4880   if (!DyldInfoLoadCmd)
4881     return None;
4882 
4883   auto DyldInfoOrErr =
4884     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4885   if (!DyldInfoOrErr)
4886     return None;
4887   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4888   const uint8_t *Ptr =
4889       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4890   return makeArrayRef(Ptr, DyldInfo.rebase_size);
4891 }
4892 
4893 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
4894   if (!DyldInfoLoadCmd)
4895     return None;
4896 
4897   auto DyldInfoOrErr =
4898     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4899   if (!DyldInfoOrErr)
4900     return None;
4901   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4902   const uint8_t *Ptr =
4903       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4904   return makeArrayRef(Ptr, DyldInfo.bind_size);
4905 }
4906 
4907 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
4908   if (!DyldInfoLoadCmd)
4909     return None;
4910 
4911   auto DyldInfoOrErr =
4912     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4913   if (!DyldInfoOrErr)
4914     return None;
4915   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4916   const uint8_t *Ptr =
4917       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4918   return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4919 }
4920 
4921 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
4922   if (!DyldInfoLoadCmd)
4923     return None;
4924 
4925   auto DyldInfoOrErr =
4926       getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4927   if (!DyldInfoOrErr)
4928     return None;
4929   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
4930   const uint8_t *Ptr =
4931       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4932   return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4933 }
4934 
4935 Expected<Optional<MachO::linkedit_data_command>>
4936 MachOObjectFile::getChainedFixupsLoadCommand() const {
4937   // Load the dyld chained fixups load command.
4938   if (!DyldChainedFixupsLoadCmd)
4939     return llvm::None;
4940   auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
4941       *this, DyldChainedFixupsLoadCmd);
4942   if (!DyldChainedFixupsOrErr)
4943     return DyldChainedFixupsOrErr.takeError();
4944   const MachO::linkedit_data_command &DyldChainedFixups =
4945       *DyldChainedFixupsOrErr;
4946 
4947   // If the load command is present but the data offset has been zeroed out,
4948   // as is the case for dylib stubs, return None (no error).
4949   if (!DyldChainedFixups.dataoff)
4950     return llvm::None;
4951   return DyldChainedFixups;
4952 }
4953 
4954 Expected<Optional<MachO::dyld_chained_fixups_header>>
4955 MachOObjectFile::getChainedFixupsHeader() const {
4956   auto CFOrErr = getChainedFixupsLoadCommand();
4957   if (!CFOrErr)
4958     return CFOrErr.takeError();
4959   if (!CFOrErr->has_value())
4960     return llvm::None;
4961 
4962   const MachO::linkedit_data_command &DyldChainedFixups = **CFOrErr;
4963 
4964   uint64_t CFHeaderOffset = DyldChainedFixups.dataoff;
4965   uint64_t CFSize = DyldChainedFixups.datasize;
4966 
4967   // Load the dyld chained fixups header.
4968   const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
4969   auto CFHeaderOrErr =
4970       getStructOrErr<MachO::dyld_chained_fixups_header>(*this, CFHeaderPtr);
4971   if (!CFHeaderOrErr)
4972     return CFHeaderOrErr.takeError();
4973   MachO::dyld_chained_fixups_header CFHeader = CFHeaderOrErr.get();
4974 
4975   // Reject unknown chained fixup formats.
4976   if (CFHeader.fixups_version != 0)
4977     return malformedError(Twine("bad chained fixups: unknown version: ") +
4978                           Twine(CFHeader.fixups_version));
4979   if (CFHeader.imports_format < 1 || CFHeader.imports_format > 3)
4980     return malformedError(
4981         Twine("bad chained fixups: unknown imports format: ") +
4982         Twine(CFHeader.imports_format));
4983 
4984   // Validate the image format.
4985   //
4986   // Load the image starts.
4987   uint64_t CFImageStartsOffset = (CFHeaderOffset + CFHeader.starts_offset);
4988   if (CFHeader.starts_offset < sizeof(MachO::dyld_chained_fixups_header)) {
4989     return malformedError(Twine("bad chained fixups: image starts offset ") +
4990                           Twine(CFHeader.starts_offset) +
4991                           " overlaps with chained fixups header");
4992   }
4993   uint32_t EndOffset = CFHeaderOffset + CFSize;
4994   if (CFImageStartsOffset + sizeof(MachO::dyld_chained_starts_in_image) >
4995       EndOffset) {
4996     return malformedError(Twine("bad chained fixups: image starts end ") +
4997                           Twine(CFImageStartsOffset +
4998                                 sizeof(MachO::dyld_chained_starts_in_image)) +
4999                           " extends past end " + Twine(EndOffset));
5000   }
5001 
5002   return CFHeader;
5003 }
5004 
5005 Expected<std::pair<size_t, std::vector<ChainedFixupsSegment>>>
5006 MachOObjectFile::getChainedFixupsSegments() const {
5007   auto CFOrErr = getChainedFixupsLoadCommand();
5008   if (!CFOrErr)
5009     return CFOrErr.takeError();
5010 
5011   std::vector<ChainedFixupsSegment> Segments;
5012   if (!CFOrErr->has_value())
5013     return std::make_pair(0, Segments);
5014 
5015   const MachO::linkedit_data_command &DyldChainedFixups = **CFOrErr;
5016 
5017   auto HeaderOrErr = getChainedFixupsHeader();
5018   if (!HeaderOrErr)
5019     return HeaderOrErr.takeError();
5020   if (!HeaderOrErr->has_value())
5021     return std::make_pair(0, Segments);
5022   const MachO::dyld_chained_fixups_header &Header = **HeaderOrErr;
5023 
5024   const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);
5025 
5026   auto ImageStartsOrErr = getStructOrErr<MachO::dyld_chained_starts_in_image>(
5027       *this, Contents + Header.starts_offset);
5028   if (!ImageStartsOrErr)
5029     return ImageStartsOrErr.takeError();
5030   const MachO::dyld_chained_starts_in_image &ImageStarts = *ImageStartsOrErr;
5031 
5032   const char *SegOffsPtr =
5033       Contents + Header.starts_offset +
5034       offsetof(MachO::dyld_chained_starts_in_image, seg_info_offset);
5035   const char *SegOffsEnd =
5036       SegOffsPtr + ImageStarts.seg_count * sizeof(uint32_t);
5037   if (SegOffsEnd > Contents + DyldChainedFixups.datasize)
5038     return malformedError(
5039         "bad chained fixups: seg_info_offset extends past end");
5040 
5041   const char *LastSegEnd = nullptr;
5042   for (size_t I = 0, N = ImageStarts.seg_count; I < N; ++I) {
5043     auto OffOrErr =
5044         getStructOrErr<uint32_t>(*this, SegOffsPtr + I * sizeof(uint32_t));
5045     if (!OffOrErr)
5046       return OffOrErr.takeError();
5047     // seg_info_offset == 0 means there is no associated starts_in_segment
5048     // entry.
5049     if (!*OffOrErr)
5050       continue;
5051 
5052     auto Fail = [&](Twine Message) {
5053       return malformedError("bad chained fixups: segment info" + Twine(I) +
5054                             " at offset " + Twine(*OffOrErr) + Message);
5055     };
5056 
5057     const char *SegPtr = Contents + Header.starts_offset + *OffOrErr;
5058     if (LastSegEnd && SegPtr < LastSegEnd)
5059       return Fail(" overlaps with previous segment info");
5060 
5061     auto SegOrErr =
5062         getStructOrErr<MachO::dyld_chained_starts_in_segment>(*this, SegPtr);
5063     if (!SegOrErr)
5064       return SegOrErr.takeError();
5065     const MachO::dyld_chained_starts_in_segment &Seg = *SegOrErr;
5066 
5067     LastSegEnd = SegPtr + Seg.size;
5068     if (Seg.pointer_format < 1 || Seg.pointer_format > 12)
5069       return Fail(" has unknown pointer format: " + Twine(Seg.pointer_format));
5070 
5071     const char *PageStart =
5072         SegPtr + offsetof(MachO::dyld_chained_starts_in_segment, page_start);
5073     const char *PageEnd = PageStart + Seg.page_count * sizeof(uint16_t);
5074     if (PageEnd > SegPtr + Seg.size)
5075       return Fail(" : page_starts extend past seg_info size");
5076 
5077     // FIXME: This does not account for multiple offsets on a single page
5078     //        (DYLD_CHAINED_PTR_START_MULTI; 32-bit only).
5079     std::vector<uint16_t> PageStarts;
5080     for (size_t PageIdx = 0; PageIdx < Seg.page_count; ++PageIdx) {
5081       uint16_t Start;
5082       memcpy(&Start, PageStart + PageIdx * sizeof(uint16_t), sizeof(uint16_t));
5083       if (isLittleEndian() != sys::IsLittleEndianHost)
5084         sys::swapByteOrder(Start);
5085       PageStarts.push_back(Start);
5086     }
5087 
5088     Segments.emplace_back(I, *OffOrErr, Seg, std::move(PageStarts));
5089   }
5090 
5091   return std::make_pair(ImageStarts.seg_count, Segments);
5092 }
5093 
5094 // The special library ordinals have a negative value, but they are encoded in
5095 // an unsigned bitfield, so we need to sign extend the value.
5096 template <typename T> static int getEncodedOrdinal(T Value) {
5097   if (Value == static_cast<T>(MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE) ||
5098       Value == static_cast<T>(MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) ||
5099       Value == static_cast<T>(MachO::BIND_SPECIAL_DYLIB_WEAK_LOOKUP))
5100     return SignExtend32<sizeof(T) * CHAR_BIT>(Value);
5101   return Value;
5102 }
5103 
5104 template <typename T, unsigned N>
5105 static std::array<T, N> getArray(const MachOObjectFile &O, const void *Ptr) {
5106   std::array<T, N> RawValue;
5107   memcpy(RawValue.data(), Ptr, N * sizeof(T));
5108   if (O.isLittleEndian() != sys::IsLittleEndianHost)
5109     for (auto &Element : RawValue)
5110       sys::swapByteOrder(Element);
5111   return RawValue;
5112 }
5113 
5114 Expected<std::vector<ChainedFixupTarget>>
5115 MachOObjectFile::getDyldChainedFixupTargets() const {
5116   auto CFOrErr = getChainedFixupsLoadCommand();
5117   if (!CFOrErr)
5118     return CFOrErr.takeError();
5119 
5120   std::vector<ChainedFixupTarget> Targets;
5121   if (!CFOrErr->has_value())
5122     return Targets;
5123 
5124   const MachO::linkedit_data_command &DyldChainedFixups = **CFOrErr;
5125 
5126   auto CFHeaderOrErr = getChainedFixupsHeader();
5127   if (!CFHeaderOrErr)
5128     return CFHeaderOrErr.takeError();
5129   if (!(*CFHeaderOrErr))
5130     return Targets;
5131   const MachO::dyld_chained_fixups_header &Header = **CFHeaderOrErr;
5132 
5133   size_t ImportSize = 0;
5134   if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT)
5135     ImportSize = sizeof(MachO::dyld_chained_import);
5136   else if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT_ADDEND)
5137     ImportSize = sizeof(MachO::dyld_chained_import_addend);
5138   else if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT_ADDEND64)
5139     ImportSize = sizeof(MachO::dyld_chained_import_addend64);
5140   else
5141     return malformedError("bad chained fixups: unknown imports format: " +
5142                           Twine(Header.imports_format));
5143 
5144   const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);
5145   const char *Imports = Contents + Header.imports_offset;
5146   size_t ImportsEndOffset =
5147       Header.imports_offset + ImportSize * Header.imports_count;
5148   const char *ImportsEnd = Contents + ImportsEndOffset;
5149   const char *Symbols = Contents + Header.symbols_offset;
5150   const char *SymbolsEnd = Contents + DyldChainedFixups.datasize;
5151 
5152   if (ImportsEnd > Symbols)
5153     return malformedError("bad chained fixups: imports end " +
5154                           Twine(ImportsEndOffset) + " extends past end " +
5155                           Twine(DyldChainedFixups.datasize));
5156 
5157   if (ImportsEnd > Symbols)
5158     return malformedError("bad chained fixups: imports end " +
5159                           Twine(ImportsEndOffset) + " overlaps with symbols");
5160 
5161   // We use bit manipulation to extract data from the bitfields. This is correct
5162   // for both LE and BE hosts, but we assume that the object is little-endian.
5163   if (!isLittleEndian())
5164     return createError("parsing big-endian chained fixups is not implemented");
5165   for (const char *ImportPtr = Imports; ImportPtr < ImportsEnd;
5166        ImportPtr += ImportSize) {
5167     int LibOrdinal;
5168     bool WeakImport;
5169     uint32_t NameOffset;
5170     uint64_t Addend;
5171     if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT) {
5172       static_assert(sizeof(uint32_t) == sizeof(MachO::dyld_chained_import));
5173       auto RawValue = getArray<uint32_t, 1>(*this, ImportPtr);
5174 
5175       LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5176       WeakImport = (RawValue[0] >> 8) & 1;
5177       NameOffset = RawValue[0] >> 9;
5178       Addend = 0;
5179     } else if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT_ADDEND) {
5180       static_assert(sizeof(uint64_t) ==
5181                     sizeof(MachO::dyld_chained_import_addend));
5182       auto RawValue = getArray<uint32_t, 2>(*this, ImportPtr);
5183 
5184       LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5185       WeakImport = (RawValue[0] >> 8) & 1;
5186       NameOffset = RawValue[0] >> 9;
5187       Addend = bit_cast<int32_t>(RawValue[1]);
5188     } else if (Header.imports_format == MachO::DYLD_CHAINED_IMPORT_ADDEND64) {
5189       static_assert(2 * sizeof(uint64_t) ==
5190                     sizeof(MachO::dyld_chained_import_addend64));
5191       auto RawValue = getArray<uint64_t, 2>(*this, ImportPtr);
5192 
5193       LibOrdinal = getEncodedOrdinal<uint16_t>(RawValue[0] & 0xFFFF);
5194       NameOffset = (RawValue[0] >> 16) & 1;
5195       WeakImport = RawValue[0] >> 17;
5196       Addend = RawValue[1];
5197     } else {
5198       llvm_unreachable("Import format should have been checked");
5199     }
5200 
5201     const char *Str = Symbols + NameOffset;
5202     if (Str >= SymbolsEnd)
5203       return malformedError("bad chained fixups: symbol offset " +
5204                             Twine(NameOffset) + " extends past end " +
5205                             Twine(DyldChainedFixups.datasize));
5206     Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5207   }
5208 
5209   return std::move(Targets);
5210 }
5211 
5212 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
5213   if (!DyldInfoLoadCmd)
5214     return None;
5215 
5216   auto DyldInfoOrErr =
5217     getStructOrErr<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
5218   if (!DyldInfoOrErr)
5219     return None;
5220   MachO::dyld_info_command DyldInfo = DyldInfoOrErr.get();
5221   const uint8_t *Ptr =
5222       reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
5223   return makeArrayRef(Ptr, DyldInfo.export_size);
5224 }
5225 
5226 SmallVector<uint64_t> MachOObjectFile::getFunctionStarts() const {
5227   if (!FuncStartsLoadCmd)
5228     return {};
5229 
5230   auto InfoOrErr =
5231       getStructOrErr<MachO::linkedit_data_command>(*this, FuncStartsLoadCmd);
5232   if (!InfoOrErr)
5233     return {};
5234 
5235   MachO::linkedit_data_command Info = InfoOrErr.get();
5236   SmallVector<uint64_t, 8> FunctionStarts;
5237   this->ReadULEB128s(Info.dataoff, FunctionStarts);
5238   return std::move(FunctionStarts);
5239 }
5240 
5241 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
5242   if (!UuidLoadCmd)
5243     return None;
5244   // Returning a pointer is fine as uuid doesn't need endian swapping.
5245   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
5246   return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
5247 }
5248 
5249 StringRef MachOObjectFile::getStringTableData() const {
5250   MachO::symtab_command S = getSymtabLoadCommand();
5251   return getData().substr(S.stroff, S.strsize);
5252 }
5253 
5254 bool MachOObjectFile::is64Bit() const {
5255   return getType() == getMachOType(false, true) ||
5256     getType() == getMachOType(true, true);
5257 }
5258 
5259 void MachOObjectFile::ReadULEB128s(uint64_t Index,
5260                                    SmallVectorImpl<uint64_t> &Out) const {
5261   DataExtractor extractor(ObjectFile::getData(), true, 0);
5262 
5263   uint64_t offset = Index;
5264   uint64_t data = 0;
5265   while (uint64_t delta = extractor.getULEB128(&offset)) {
5266     data += delta;
5267     Out.push_back(data);
5268   }
5269 }
5270 
5271 bool MachOObjectFile::isRelocatableObject() const {
5272   return getHeader().filetype == MachO::MH_OBJECT;
5273 }
5274 
5275 Expected<std::unique_ptr<MachOObjectFile>>
5276 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
5277                                   uint32_t UniversalCputype,
5278                                   uint32_t UniversalIndex) {
5279   StringRef Magic = Buffer.getBuffer().slice(0, 4);
5280   if (Magic == "\xFE\xED\xFA\xCE")
5281     return MachOObjectFile::create(Buffer, false, false,
5282                                    UniversalCputype, UniversalIndex);
5283   if (Magic == "\xCE\xFA\xED\xFE")
5284     return MachOObjectFile::create(Buffer, true, false,
5285                                    UniversalCputype, UniversalIndex);
5286   if (Magic == "\xFE\xED\xFA\xCF")
5287     return MachOObjectFile::create(Buffer, false, true,
5288                                    UniversalCputype, UniversalIndex);
5289   if (Magic == "\xCF\xFA\xED\xFE")
5290     return MachOObjectFile::create(Buffer, true, true,
5291                                    UniversalCputype, UniversalIndex);
5292   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
5293                                         object_error::invalid_file_type);
5294 }
5295 
5296 StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
5297   return StringSwitch<StringRef>(Name)
5298       .Case("debug_str_offs", "debug_str_offsets")
5299       .Default(Name);
5300 }
5301 
5302 Expected<std::vector<std::string>>
5303 MachOObjectFile::findDsymObjectMembers(StringRef Path) {
5304   SmallString<256> BundlePath(Path);
5305   // Normalize input path. This is necessary to accept `bundle.dSYM/`.
5306   sys::path::remove_dots(BundlePath);
5307   if (!sys::fs::is_directory(BundlePath) ||
5308       sys::path::extension(BundlePath) != ".dSYM")
5309     return std::vector<std::string>();
5310   sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
5311   bool IsDir;
5312   auto EC = sys::fs::is_directory(BundlePath, IsDir);
5313   if (EC == errc::no_such_file_or_directory || (!EC && !IsDir))
5314     return createStringError(
5315         EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5316         Path.str().c_str());
5317   if (EC)
5318     return createFileError(BundlePath, errorCodeToError(EC));
5319 
5320   std::vector<std::string> ObjectPaths;
5321   for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
5322        Dir != DirEnd && !EC; Dir.increment(EC)) {
5323     StringRef ObjectPath = Dir->path();
5324     sys::fs::file_status Status;
5325     if (auto EC = sys::fs::status(ObjectPath, Status))
5326       return createFileError(ObjectPath, errorCodeToError(EC));
5327     switch (Status.type()) {
5328     case sys::fs::file_type::regular_file:
5329     case sys::fs::file_type::symlink_file:
5330     case sys::fs::file_type::type_unknown:
5331       ObjectPaths.push_back(ObjectPath.str());
5332       break;
5333     default: /*ignore*/;
5334     }
5335   }
5336   if (EC)
5337     return createFileError(BundlePath, errorCodeToError(EC));
5338   if (ObjectPaths.empty())
5339     return createStringError(std::error_code(),
5340                              "%s: no objects found in dSYM bundle",
5341                              Path.str().c_str());
5342   return ObjectPaths;
5343 }
5344 
5345 llvm::binaryformat::Swift5ReflectionSectionKind
5346 MachOObjectFile::mapReflectionSectionNameToEnumValue(
5347     StringRef SectionName) const {
5348 #define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF)                           \
5349   .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
5350   return StringSwitch<llvm::binaryformat::Swift5ReflectionSectionKind>(
5351              SectionName)
5352 #include "llvm/BinaryFormat/Swift.def"
5353       .Default(llvm::binaryformat::Swift5ReflectionSectionKind::unknown);
5354 #undef HANDLE_SWIFT_SECTION
5355 }
5356 
5357 bool MachOObjectFile::isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
5358   switch (Arch) {
5359   case Triple::x86:
5360     return RelocType == MachO::GENERIC_RELOC_SECTDIFF ||
5361            RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF;
5362   case Triple::x86_64:
5363     return RelocType == MachO::X86_64_RELOC_SUBTRACTOR;
5364   case Triple::arm:
5365   case Triple::thumb:
5366     return RelocType == MachO::ARM_RELOC_SECTDIFF ||
5367            RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
5368            RelocType == MachO::ARM_RELOC_HALF ||
5369            RelocType == MachO::ARM_RELOC_HALF_SECTDIFF;
5370   case Triple::aarch64:
5371     return RelocType == MachO::ARM64_RELOC_SUBTRACTOR;
5372   default:
5373     return false;
5374   }
5375 }
5376