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