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