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