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).
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  // Only positive numbers represent library ordinals. Zero and negative
3001  // numbers have special meaning (see BindSpecialDylib).
3002  if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3003  *E = malformedError(
3004  "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3005  Twine((int)O->getLibraryCount()) +
3006  ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3007  moveToEnd();
3008  return;
3009  }
3010  }
3011  State.ImportName = reinterpret_cast<const char*>(State.Current);
3012  if (*State.ImportName == '\0') {
3013  State.Current++;
3014  } else {
3015  const uint8_t *End = State.Current + 1;
3016  if (End >= Trie.end()) {
3017  *E = malformedError("import name of re-export in export trie data at "
3018  "node: 0x" +
3019  Twine::utohexstr(offset) +
3020  " starts past end of trie data");
3021  moveToEnd();
3022  return;
3023  }
3024  while(*End != '\0' && End < Trie.end())
3025  End++;
3026  if (*End != '\0') {
3027  *E = malformedError("import name of re-export in export trie data at "
3028  "node: 0x" +
3029  Twine::utohexstr(offset) +
3030  " extends past end of trie data");
3031  moveToEnd();
3032  return;
3033  }
3034  State.Current = End + 1;
3035  }
3036  } else {
3037  State.Address = readULEB128(State.Current, &error);
3038  if (error) {
3039  *E = malformedError("address " + Twine(error) +
3040  " in export trie data at node: 0x" +
3041  Twine::utohexstr(offset));
3042  moveToEnd();
3043  return;
3044  }
3046  State.Other = readULEB128(State.Current, &error);
3047  if (error) {
3048  *E = malformedError("resolver of stub and resolver " + Twine(error) +
3049  " in export trie data at node: 0x" +
3050  Twine::utohexstr(offset));
3051  moveToEnd();
3052  return;
3053  }
3054  }
3055  }
3056  if(ExportStart + ExportInfoSize != State.Current) {
3057  *E = malformedError(
3058  "inconsistant export info size: 0x" +
3059  Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3060  Twine::utohexstr(State.Current - ExportStart) +
3061  " in export trie data at node: 0x" + Twine::utohexstr(offset));
3062  moveToEnd();
3063  return;
3064  }
3065  }
3066  State.ChildCount = *Children;
3067  if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3068  *E = malformedError("byte for count of childern in export trie data at "
3069  "node: 0x" +
3070  Twine::utohexstr(offset) +
3071  " extends past end of trie data");
3072  moveToEnd();
3073  return;
3074  }
3075  State.Current = Children + 1;
3076  State.NextChildIndex = 0;
3077  State.ParentStringLength = CumulativeString.size();
3078  Stack.push_back(State);
3079 }
3080 
3081 void ExportEntry::pushDownUntilBottom() {
3082  ErrorAsOutParameter ErrAsOutParam(E);
3083  const char *error;
3084  while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3085  NodeState &Top = Stack.back();
3086  CumulativeString.resize(Top.ParentStringLength);
3087  for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3088  char C = *Top.Current;
3089  CumulativeString.push_back(C);
3090  }
3091  if (Top.Current >= Trie.end()) {
3092  *E = malformedError("edge sub-string in export trie data at node: 0x" +
3093  Twine::utohexstr(Top.Start - Trie.begin()) +
3094  " for child #" + Twine((int)Top.NextChildIndex) +
3095  " extends past end of trie data");
3096  moveToEnd();
3097  return;
3098  }
3099  Top.Current += 1;
3100  uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3101  if (error) {
3102  *E = malformedError("child node offset " + Twine(error) +
3103  " in export trie data at node: 0x" +
3104  Twine::utohexstr(Top.Start - Trie.begin()));
3105  moveToEnd();
3106  return;
3107  }
3108  for (const NodeState &node : nodes()) {
3109  if (node.Start == Trie.begin() + childNodeIndex){
3110  *E = malformedError("loop in childern in export trie data at node: 0x" +
3111  Twine::utohexstr(Top.Start - Trie.begin()) +
3112  " back to node: 0x" +
3113  Twine::utohexstr(childNodeIndex));
3114  moveToEnd();
3115  return;
3116  }
3117  }
3118  Top.NextChildIndex += 1;
3119  pushNode(childNodeIndex);
3120  if (*E)
3121  return;
3122  }
3123  if (!Stack.back().IsExportNode) {
3124  *E = malformedError("node is not an export node in export trie data at "
3125  "node: 0x" +
3126  Twine::utohexstr(Stack.back().Start - Trie.begin()));
3127  moveToEnd();
3128  return;
3129  }
3130 }
3131 
3132 // We have a trie data structure and need a way to walk it that is compatible
3133 // with the C++ iterator model. The solution is a non-recursive depth first
3134 // traversal where the iterator contains a stack of parent nodes along with a
3135 // string that is the accumulation of all edge strings along the parent chain
3136 // to this point.
3137 //
3138 // There is one "export" node for each exported symbol. But because some
3139 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
3140 // node may have child nodes too.
3141 //
3142 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
3143 // child until hitting a node with no children (which is an export node or
3144 // else the trie is malformed). On the way down, each node is pushed on the
3145 // stack ivar. If there is no more ways down, it pops up one and tries to go
3146 // down a sibling path until a childless node is reached.
3148  assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3149  if (!Stack.back().IsExportNode) {
3150  *E = malformedError("node is not an export node in export trie data at "
3151  "node: 0x" +
3152  Twine::utohexstr(Stack.back().Start - Trie.begin()));
3153  moveToEnd();
3154  return;
3155  }
3156 
3157  Stack.pop_back();
3158  while (!Stack.empty()) {
3159  NodeState &Top = Stack.back();
3160  if (Top.NextChildIndex < Top.ChildCount) {
3161  pushDownUntilBottom();
3162  // Now at the next export node.
3163  return;
3164  } else {
3165  if (Top.IsExportNode) {
3166  // This node has no children but is itself an export node.
3167  CumulativeString.resize(Top.ParentStringLength);
3168  return;
3169  }
3170  Stack.pop_back();
3171  }
3172  }
3173  Done = true;
3174 }
3175 
3178  const MachOObjectFile *O) {
3179  ExportEntry Start(&E, O, Trie);
3180  if (Trie.empty())
3181  Start.moveToEnd();
3182  else
3183  Start.moveToFirst();
3184 
3185  ExportEntry Finish(&E, O, Trie);
3186  Finish.moveToEnd();
3187 
3188  return make_range(export_iterator(Start), export_iterator(Finish));
3189 }
3190 
3192  return exports(Err, getDyldInfoExportsTrie(), this);
3193 }
3194 
3196  const MachOObjectFile *O)
3197  : E(E), O(O) {
3198  // Cache the vmaddress of __TEXT
3199  for (const auto &Command : O->load_commands()) {
3200  if (Command.C.cmd == MachO::LC_SEGMENT) {
3202  if (StringRef(SLC.segname) == StringRef("__TEXT")) {
3203  TextAddress = SLC.vmaddr;
3204  break;
3205  }
3206  } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3208  if (StringRef(SLC_64.segname) == StringRef("__TEXT")) {
3209  TextAddress = SLC_64.vmaddr;
3210  break;
3211  }
3212  }
3213  }
3214 }
3215 
3217 
3219  return SegmentOffset;
3220 }
3221 
3223  return O->BindRebaseAddress(SegmentIndex, 0);
3224 }
3225 
3228 }
3229 
3232 }
3233 
3236 }
3237 
3239 
3240 int64_t MachOAbstractFixupEntry::addend() const { return Addend; }
3241 
3243 
3245 
3246 StringRef MachOAbstractFixupEntry::typeName() const { return "unknown"; }
3247 
3249  SegmentOffset = 0;
3250  SegmentIndex = -1;
3251  Ordinal = 0;
3252  Flags = 0;
3253  Addend = 0;
3254  Done = false;
3255 }
3256 
3258 
3260  const MachOObjectFile *O,
3261  bool Parse)
3264  if (!Parse)
3265  return;
3266  if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets())
3267  FixupTargets = *FixupTargetsOrErr;
3268  else {
3269  *E = FixupTargetsOrErr.takeError();
3270  return;
3271  }
3272 }
3273 
3276  FixupIndex = 0;
3277  moveNext();
3278 }
3279 
3282 }
3283 
3285 
3287  const MachOChainedFixupEntry &Other) const {
3288  if (Done == Other.Done)
3289  return true;
3290  if ((FixupIndex == Other.FixupIndex))
3291  return true;
3292  return false;
3293 }
3294 
3296  ArrayRef<uint8_t> Bytes, bool is64Bit)
3297  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3298  PointerSize(is64Bit ? 8 : 4) {}
3299 
3300 void MachORebaseEntry::moveToFirst() {
3301  Ptr = Opcodes.begin();
3302  moveNext();
3303 }
3304 
3305 void MachORebaseEntry::moveToEnd() {
3306  Ptr = Opcodes.end();
3307  RemainingLoopCount = 0;
3308  Done = true;
3309 }
3310 
3312  ErrorAsOutParameter ErrAsOutParam(E);
3313  // If in the middle of some loop, move to next rebasing in loop.
3314  SegmentOffset += AdvanceAmount;
3315  if (RemainingLoopCount) {
3316  --RemainingLoopCount;
3317  return;
3318  }
3319  // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3320  // pointer size. Therefore it is possible to reach the end without ever having
3321  // seen REBASE_OPCODE_DONE.
3322  if (Ptr == Opcodes.end()) {
3323  Done = true;
3324  return;
3325  }
3326  bool More = true;
3327  while (More) {
3328  // Parse next opcode and set up next loop.
3329  const uint8_t *OpcodeStart = Ptr;
3330  uint8_t Byte = *Ptr++;
3331  uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3332  uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3333  uint32_t Count, Skip;
3334  const char *error = nullptr;
3335  switch (Opcode) {
3337  More = false;
3338  Done = true;
3339  moveToEnd();
3340  DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3341  break;
3343  RebaseType = ImmValue;
3344  if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) {
3345  *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3346  Twine((int)RebaseType) + " for opcode at: 0x" +
3347  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3348  moveToEnd();
3349  return;
3350  }
3352  "mach-o-rebase",
3353  dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3354  << "RebaseType=" << (int) RebaseType << "\n");
3355  break;
3357  SegmentIndex = ImmValue;
3358  SegmentOffset = readULEB128(&error);
3359  if (error) {
3360  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3361  Twine(error) + " for opcode at: 0x" +
3362  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3363  moveToEnd();
3364  return;
3365  }
3366  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3367  PointerSize);
3368  if (error) {
3369  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3370  Twine(error) + " for opcode at: 0x" +
3371  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3372  moveToEnd();
3373  return;
3374  }
3376  "mach-o-rebase",
3377  dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3378  << "SegmentIndex=" << SegmentIndex << ", "
3379  << format("SegmentOffset=0x%06X", SegmentOffset)
3380  << "\n");
3381  break;
3383  SegmentOffset += readULEB128(&error);
3384  if (error) {
3385  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3386  " for opcode at: 0x" +
3387  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3388  moveToEnd();
3389  return;
3390  }
3391  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3392  PointerSize);
3393  if (error) {
3394  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3395  " for opcode at: 0x" +
3396  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3397  moveToEnd();
3398  return;
3399  }
3400  DEBUG_WITH_TYPE("mach-o-rebase",
3401  dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3402  << format("SegmentOffset=0x%06X",
3403  SegmentOffset) << "\n");
3404  break;
3406  SegmentOffset += ImmValue * PointerSize;
3407  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3408  PointerSize);
3409  if (error) {
3410  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3411  Twine(error) + " for opcode at: 0x" +
3412  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3413  moveToEnd();
3414  return;
3415  }
3416  DEBUG_WITH_TYPE("mach-o-rebase",
3417  dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3418  << format("SegmentOffset=0x%06X",
3419  SegmentOffset) << "\n");
3420  break;
3422  AdvanceAmount = PointerSize;
3423  Skip = 0;
3424  Count = ImmValue;
3425  if (ImmValue != 0)
3426  RemainingLoopCount = ImmValue - 1;
3427  else
3428  RemainingLoopCount = 0;
3429  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3430  PointerSize, Count, Skip);
3431  if (error) {
3432  *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3433  Twine(error) + " for opcode at: 0x" +
3434  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3435  moveToEnd();
3436  return;
3437  }
3439  "mach-o-rebase",
3440  dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3441  << format("SegmentOffset=0x%06X", SegmentOffset)
3442  << ", AdvanceAmount=" << AdvanceAmount
3443  << ", RemainingLoopCount=" << RemainingLoopCount
3444  << "\n");
3445  return;
3447  AdvanceAmount = PointerSize;
3448  Skip = 0;
3449  Count = readULEB128(&error);
3450  if (error) {
3451  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3452  Twine(error) + " for opcode at: 0x" +
3453  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3454  moveToEnd();
3455  return;
3456  }
3457  if (Count != 0)
3458  RemainingLoopCount = Count - 1;
3459  else
3460  RemainingLoopCount = 0;
3461  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3462  PointerSize, Count, Skip);
3463  if (error) {
3464  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3465  Twine(error) + " for opcode at: 0x" +
3466  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3467  moveToEnd();
3468  return;
3469  }
3471  "mach-o-rebase",
3472  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3473  << format("SegmentOffset=0x%06X", SegmentOffset)
3474  << ", AdvanceAmount=" << AdvanceAmount
3475  << ", RemainingLoopCount=" << RemainingLoopCount
3476  << "\n");
3477  return;
3479  Skip = readULEB128(&error);
3480  if (error) {
3481  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3482  Twine(error) + " for opcode at: 0x" +
3483  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3484  moveToEnd();
3485  return;
3486  }
3487  AdvanceAmount = Skip + PointerSize;
3488  Count = 1;
3489  RemainingLoopCount = 0;
3490  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3491  PointerSize, Count, Skip);
3492  if (error) {
3493  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3494  Twine(error) + " for opcode at: 0x" +
3495  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3496  moveToEnd();
3497  return;
3498  }
3500  "mach-o-rebase",
3501  dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3502  << format("SegmentOffset=0x%06X", SegmentOffset)
3503  << ", AdvanceAmount=" << AdvanceAmount
3504  << ", RemainingLoopCount=" << RemainingLoopCount
3505  << "\n");
3506  return;
3508  Count = readULEB128(&error);
3509  if (error) {
3510  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3511  "ULEB " +
3512  Twine(error) + " for opcode at: 0x" +
3513  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3514  moveToEnd();
3515  return;
3516  }
3517  if (Count != 0)
3518  RemainingLoopCount = Count - 1;
3519  else
3520  RemainingLoopCount = 0;
3521  Skip = readULEB128(&error);
3522  if (error) {
3523  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3524  "ULEB " +
3525  Twine(error) + " for opcode at: 0x" +
3526  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3527  moveToEnd();
3528  return;
3529  }
3530  AdvanceAmount = Skip + PointerSize;
3531 
3532  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3533  PointerSize, Count, Skip);
3534  if (error) {
3535  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3536  "ULEB " +
3537  Twine(error) + " for opcode at: 0x" +
3538  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3539  moveToEnd();
3540  return;
3541  }
3543  "mach-o-rebase",
3544  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3545  << format("SegmentOffset=0x%06X", SegmentOffset)
3546  << ", AdvanceAmount=" << AdvanceAmount
3547  << ", RemainingLoopCount=" << RemainingLoopCount
3548  << "\n");
3549  return;
3550  default:
3551  *E = malformedError("bad rebase info (bad opcode value 0x" +
3552  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3553  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3554  moveToEnd();
3555  return;
3556  }
3557  }
3558 }
3559 
3560 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3561  unsigned Count;
3562  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3563  Ptr += Count;
3564  if (Ptr > Opcodes.end())
3565  Ptr = Opcodes.end();
3566  return Result;
3567 }
3568 
3569 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3570 
3571 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
3572 
3574  switch (RebaseType) {
3576  return "pointer";
3578  return "text abs32";
3580  return "text rel32";
3581  }
3582  return "unknown";
3583 }
3584 
3585 // For use with the SegIndex of a checked Mach-O Rebase entry
3586 // to get the segment name.
3588  return O->BindRebaseSegmentName(SegmentIndex);
3589 }
3590 
3591 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3592 // to get the section name.
3594  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3595 }
3596 
3597 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3598 // to get the address.
3600  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3601 }
3602 
3604 #ifdef EXPENSIVE_CHECKS
3605  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3606 #else
3607  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3608 #endif
3609  return (Ptr == Other.Ptr) &&
3610  (RemainingLoopCount == Other.RemainingLoopCount) &&
3611  (Done == Other.Done);
3612 }
3613 
3616  ArrayRef<uint8_t> Opcodes, bool is64) {
3617  if (O->BindRebaseSectionTable == nullptr)
3618  O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3619  MachORebaseEntry Start(&Err, O, Opcodes, is64);
3620  Start.moveToFirst();
3621 
3622  MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3623  Finish.moveToEnd();
3624 
3625  return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3626 }
3627 
3629  return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3630 }
3631 
3633  ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3634  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3635  PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3636 
3637 void MachOBindEntry::moveToFirst() {
3638  Ptr = Opcodes.begin();
3639  moveNext();
3640 }
3641 
3642 void MachOBindEntry::moveToEnd() {
3643  Ptr = Opcodes.end();
3644  RemainingLoopCount = 0;
3645  Done = true;
3646 }
3647 
3649  ErrorAsOutParameter ErrAsOutParam(E);
3650  // If in the middle of some loop, move to next binding in loop.
3651  SegmentOffset += AdvanceAmount;
3652  if (RemainingLoopCount) {
3653  --RemainingLoopCount;
3654  return;
3655  }
3656  // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3657  // pointer size. Therefore it is possible to reach the end without ever having
3658  // seen BIND_OPCODE_DONE.
3659  if (Ptr == Opcodes.end()) {
3660  Done = true;
3661  return;
3662  }
3663  bool More = true;
3664  while (More) {
3665  // Parse next opcode and set up next loop.
3666  const uint8_t *OpcodeStart = Ptr;
3667  uint8_t Byte = *Ptr++;
3668  uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3669  uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3670  int8_t SignExtended;
3671  const uint8_t *SymStart;
3672  uint32_t Count, Skip;
3673  const char *error = nullptr;
3674  switch (Opcode) {
3676  if (TableKind == Kind::Lazy) {
3677  // Lazying bindings have a DONE opcode between entries. Need to ignore
3678  // it to advance to next entry. But need not if this is last entry.
3679  bool NotLastEntry = false;
3680  for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3681  if (*P) {
3682  NotLastEntry = true;
3683  }
3684  }
3685  if (NotLastEntry)
3686  break;
3687  }
3688  More = false;
3689  moveToEnd();
3690  DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3691  break;
3693  if (TableKind == Kind::Weak) {
3694  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3695  "weak bind table for opcode at: 0x" +
3696  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3697  moveToEnd();
3698  return;
3699  }
3700  Ordinal = ImmValue;
3701  LibraryOrdinalSet = true;
3702  if (ImmValue > O->getLibraryCount()) {
3703  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3704  "library ordinal: " +
3705  Twine((int)ImmValue) + " (max " +
3706  Twine((int)O->getLibraryCount()) +
3707  ") for opcode at: 0x" +
3708  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3709  moveToEnd();
3710  return;
3711  }
3713  "mach-o-bind",
3714  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3715  << "Ordinal=" << Ordinal << "\n");
3716  break;
3718  if (TableKind == Kind::Weak) {
3719  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3720  "weak bind table for opcode at: 0x" +
3721  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3722  moveToEnd();
3723  return;
3724  }
3725  Ordinal = readULEB128(&error);
3726  LibraryOrdinalSet = true;
3727  if (error) {
3728  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3729  Twine(error) + " for opcode at: 0x" +
3730  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3731  moveToEnd();
3732  return;
3733  }
3734  if (Ordinal > (int)O->getLibraryCount()) {
3735  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3736  "library ordinal: " +
3737  Twine((int)Ordinal) + " (max " +
3738  Twine((int)O->getLibraryCount()) +
3739  ") for opcode at: 0x" +
3740  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3741  moveToEnd();
3742  return;
3743  }
3745  "mach-o-bind",
3746  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3747  << "Ordinal=" << Ordinal << "\n");
3748  break;
3750  if (TableKind == Kind::Weak) {
3751  *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3752  "weak bind table for opcode at: 0x" +
3753  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3754  moveToEnd();
3755  return;
3756  }
3757  if (ImmValue) {
3758  SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3759  Ordinal = SignExtended;
3760  if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3761  *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3762  "special ordinal: " +
3763  Twine((int)Ordinal) + " for opcode at: 0x" +
3764  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3765  moveToEnd();
3766  return;
3767  }
3768  } else
3769  Ordinal = 0;
3770  LibraryOrdinalSet = true;
3772  "mach-o-bind",
3773  dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3774  << "Ordinal=" << Ordinal << "\n");
3775  break;
3777  Flags = ImmValue;
3778  SymStart = Ptr;
3779  while (*Ptr && (Ptr < Opcodes.end())) {
3780  ++Ptr;
3781  }
3782  if (Ptr == Opcodes.end()) {
3783  *E = malformedError(
3784  "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3785  "symbol name extends past opcodes for opcode at: 0x" +
3786  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3787  moveToEnd();
3788  return;
3789  }
3790  SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3791  Ptr-SymStart);
3792  ++Ptr;
3794  "mach-o-bind",
3795  dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3796  << "SymbolName=" << SymbolName << "\n");
3797  if (TableKind == Kind::Weak) {
3799  return;
3800  }
3801  break;
3803  BindType = ImmValue;
3804  if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3805  *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3806  Twine((int)ImmValue) + " for opcode at: 0x" +
3807  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3808  moveToEnd();
3809  return;
3810  }
3812  "mach-o-bind",
3813  dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3814  << "BindType=" << (int)BindType << "\n");
3815  break;
3817  Addend = readSLEB128(&error);
3818  if (error) {
3819  *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3820  " for opcode at: 0x" +
3821  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3822  moveToEnd();
3823  return;
3824  }
3826  "mach-o-bind",
3827  dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3828  << "Addend=" << Addend << "\n");
3829  break;
3831  SegmentIndex = ImmValue;
3832  SegmentOffset = readULEB128(&error);
3833  if (error) {
3834  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3835  Twine(error) + " for opcode at: 0x" +
3836  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3837  moveToEnd();
3838  return;
3839  }
3840  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3841  PointerSize);
3842  if (error) {
3843  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3844  Twine(error) + " for opcode at: 0x" +
3845  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3846  moveToEnd();
3847  return;
3848  }
3850  "mach-o-bind",
3851  dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3852  << "SegmentIndex=" << SegmentIndex << ", "
3853  << format("SegmentOffset=0x%06X", SegmentOffset)
3854  << "\n");
3855  break;
3857  SegmentOffset += readULEB128(&error);
3858  if (error) {
3859  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3860  " for opcode at: 0x" +
3861  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3862  moveToEnd();
3863  return;
3864  }
3865  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3866  PointerSize);
3867  if (error) {
3868  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3869  " for opcode at: 0x" +
3870  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3871  moveToEnd();
3872  return;
3873  }
3874  DEBUG_WITH_TYPE("mach-o-bind",
3875  dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3876  << format("SegmentOffset=0x%06X",
3877  SegmentOffset) << "\n");
3878  break;
3880  AdvanceAmount = PointerSize;
3881  RemainingLoopCount = 0;
3882  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3883  PointerSize);
3884  if (error) {
3885  *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3886  " for opcode at: 0x" +
3887  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3888  moveToEnd();
3889  return;
3890  }
3891  if (SymbolName == StringRef()) {
3892  *E = malformedError(
3893  "for BIND_OPCODE_DO_BIND missing preceding "
3894  "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3895  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3896  moveToEnd();
3897  return;
3898  }
3899  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3900  *E =
3901  malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3902  "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3903  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3904  moveToEnd();
3905  return;
3906  }
3907  DEBUG_WITH_TYPE("mach-o-bind",
3908  dbgs() << "BIND_OPCODE_DO_BIND: "
3909  << format("SegmentOffset=0x%06X",
3910  SegmentOffset) << "\n");
3911  return;
3913  if (TableKind == Kind::Lazy) {
3914  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3915  "lazy bind table for opcode at: 0x" +
3916  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3917  moveToEnd();
3918  return;
3919  }
3920  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3921  PointerSize);
3922  if (error) {
3923  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3924  Twine(error) + " for opcode at: 0x" +
3925  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3926  moveToEnd();
3927  return;
3928  }
3929  if (SymbolName == StringRef()) {
3930  *E = malformedError(
3931  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3932  "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3933  "at: 0x" +
3934  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3935  moveToEnd();
3936  return;
3937  }
3938  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3939  *E = malformedError(
3940  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3941  "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3942  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3943  moveToEnd();
3944  return;
3945  }
3946  AdvanceAmount = readULEB128(&error) + PointerSize;
3947  if (error) {
3948  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3949  Twine(error) + " for opcode at: 0x" +
3950  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3951  moveToEnd();
3952  return;
3953  }
3954  // Note, this is not really an error until the next bind but make no sense
3955  // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3956  // bind operation.
3957  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
3958  AdvanceAmount, PointerSize);
3959  if (error) {
3960  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3961  "ULEB) " +
3962  Twine(error) + " for opcode at: 0x" +
3963  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3964  moveToEnd();
3965  return;
3966  }
3967  RemainingLoopCount = 0;
3969  "mach-o-bind",
3970  dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3971  << format("SegmentOffset=0x%06X", SegmentOffset)
3972  << ", AdvanceAmount=" << AdvanceAmount
3973  << ", RemainingLoopCount=" << RemainingLoopCount
3974  << "\n");
3975  return;
3977  if (TableKind == Kind::Lazy) {
3978  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3979  "allowed in lazy bind table for opcode at: 0x" +
3980  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3981  moveToEnd();
3982  return;
3983  }
3984  if (SymbolName == StringRef()) {
3985  *E = malformedError(
3986  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3987  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3988  "opcode at: 0x" +
3989  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3990  moveToEnd();
3991  return;
3992  }
3993  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3994  *E = malformedError(
3995  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3996  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3997  "at: 0x" +
3998  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3999  moveToEnd();
4000  return;
4001  }
4002  AdvanceAmount = ImmValue * PointerSize + PointerSize;
4003  RemainingLoopCount = 0;
4004  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4005  AdvanceAmount, PointerSize);
4006  if (error) {
4007  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4008  Twine(error) + " for opcode at: 0x" +
4009  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4010  moveToEnd();
4011  return;
4012  }
4013  DEBUG_WITH_TYPE("mach-o-bind",
4014  dbgs()
4015  << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4016  << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4017  return;
4019  if (TableKind == Kind::Lazy) {
4020  *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4021  "allowed in lazy bind table for opcode at: 0x" +
4022  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4023  moveToEnd();
4024  return;
4025  }
4026  Count = readULEB128(&error);
4027  if (Count != 0)
4028  RemainingLoopCount = Count - 1;
4029  else
4030  RemainingLoopCount = 0;
4031  if (error) {
4032  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4033  " (count value) " +
4034  Twine(error) + " for opcode at: 0x" +
4035  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4036  moveToEnd();
4037  return;
4038  }
4039  Skip = readULEB128(&error);
4040  AdvanceAmount = Skip + PointerSize;
4041  if (error) {
4042  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4043  " (skip value) " +
4044  Twine(error) + " for opcode at: 0x" +
4045  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4046  moveToEnd();
4047  return;
4048  }
4049  if (SymbolName == StringRef()) {
4050  *E = malformedError(
4051  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4052  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4053  "opcode at: 0x" +
4054  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4055  moveToEnd();
4056  return;
4057  }
4058  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4059  *E = malformedError(
4060  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4061  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4062  "at: 0x" +
4063  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4064  moveToEnd();
4065  return;
4066  }
4067  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4068  PointerSize, Count, Skip);
4069  if (error) {
4070  *E =
4071  malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4072  Twine(error) + " for opcode at: 0x" +
4073  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4074  moveToEnd();
4075  return;
4076  }
4078  "mach-o-bind",
4079  dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4080  << format("SegmentOffset=0x%06X", SegmentOffset)
4081  << ", AdvanceAmount=" << AdvanceAmount
4082  << ", RemainingLoopCount=" << RemainingLoopCount
4083  << "\n");
4084  return;
4085  default:
4086  *E = malformedError("bad bind info (bad opcode value 0x" +
4087  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
4088  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
4089  moveToEnd();
4090  return;
4091  }
4092  }
4093 }
4094 
4095 uint64_t MachOBindEntry::readULEB128(const char **error) {
4096  unsigned Count;
4097  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
4098  Ptr += Count;
4099  if (Ptr > Opcodes.end())
4100  Ptr = Opcodes.end();
4101  return Result;
4102 }
4103 
4104 int64_t MachOBindEntry::readSLEB128(const char **error) {
4105  unsigned Count;
4106  int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
4107  Ptr += Count;
4108  if (Ptr > Opcodes.end())
4109  Ptr = Opcodes.end();
4110  return Result;
4111 }
4112 
4113 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
4114 
4115 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
4116 
4118  switch (BindType) {
4120  return "pointer";
4122  return "text abs32";
4124  return "text rel32";
4125  }
4126  return "unknown";
4127 }
4128 
4129 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
4130 
4131 int64_t MachOBindEntry::addend() const { return Addend; }
4132 
4133 uint32_t MachOBindEntry::flags() const { return Flags; }
4134 
4135 int MachOBindEntry::ordinal() const { return Ordinal; }
4136 
4137 // For use with the SegIndex of a checked Mach-O Bind entry
4138 // to get the segment name.
4140  return O->BindRebaseSegmentName(SegmentIndex);
4141 }
4142 
4143 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4144 // to get the section name.
4146  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4147 }
4148 
4149 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
4150 // to get the address.
4152  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4153 }
4154 
4155 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
4156 #ifdef EXPENSIVE_CHECKS
4157  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4158 #else
4159  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4160 #endif
4161  return (Ptr == Other.Ptr) &&
4162  (RemainingLoopCount == Other.RemainingLoopCount) &&
4163  (Done == Other.Done);
4164 }
4165 
4166 // Build table of sections so SegIndex/SegOffset pairs can be translated.
4168  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4169  StringRef CurSegName;
4170  uint64_t CurSegAddress;
4171  for (const SectionRef &Section : Obj->sections()) {
4172  SectionInfo Info;
4173  Expected<StringRef> NameOrErr = Section.getName();
4174  if (!NameOrErr)
4175  consumeError(NameOrErr.takeError());
4176  else
4177  Info.SectionName = *NameOrErr;
4178  Info.Address = Section.getAddress();
4179  Info.Size = Section.getSize();
4180  Info.SegmentName =
4181  Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4182  if (!Info.SegmentName.equals(CurSegName)) {
4183  ++CurSegIndex;
4184  CurSegName = Info.SegmentName;
4185  CurSegAddress = Info.Address;
4186  }
4187  Info.SegmentIndex = CurSegIndex - 1;
4188  Info.OffsetInSegment = Info.Address - CurSegAddress;
4189  Info.SegmentStartAddress = CurSegAddress;
4190  Sections.push_back(Info);
4191  }
4192  MaxSegIndex = CurSegIndex;
4193 }
4194 
4195 // For use with a SegIndex, SegOffset, and PointerSize triple in
4196 // MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry.
4197 //
4198 // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
4199 // that fully contains a pointer at that location. Multiple fixups in a bind
4200 // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
4201 // be tested via the Count and Skip parameters.
4202 const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
4203  uint64_t SegOffset,
4204  uint8_t PointerSize,
4205  uint32_t Count,
4206  uint32_t Skip) {
4207  if (SegIndex == -1)
4208  return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4209  if (SegIndex >= MaxSegIndex)
4210  return "bad segIndex (too large)";
4211  for (uint32_t i = 0; i < Count; ++i) {
4212  uint32_t Start = SegOffset + i * (PointerSize + Skip);
4213  uint32_t End = Start + PointerSize;
4214  bool Found = false;
4215  for (const SectionInfo &SI : Sections) {
4216  if (SI.SegmentIndex != SegIndex)
4217  continue;
4218  if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4219  if (End <= SI.OffsetInSegment + SI.Size) {
4220  Found = true;
4221  break;
4222  }
4223  else
4224  return "bad offset, extends beyond section boundary";
4225  }
4226  }
4227  if (!Found)
4228  return "bad offset, not in section";
4229  }
4230  return nullptr;
4231 }
4232 
4233 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4234 // to get the segment name.
4236  for (const SectionInfo &SI : Sections) {
4237  if (SI.SegmentIndex == SegIndex)
4238  return SI.SegmentName;
4239  }
4240  llvm_unreachable("invalid SegIndex");
4241 }
4242 
4243 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4244 // to get the SectionInfo.
4245 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4246  int32_t SegIndex, uint64_t SegOffset) {
4247  for (const SectionInfo &SI : Sections) {
4248  if (SI.SegmentIndex != SegIndex)
4249  continue;
4250  if (SI.OffsetInSegment > SegOffset)
4251  continue;
4252  if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4253  continue;
4254  return SI;
4255  }
4256  llvm_unreachable("SegIndex and SegOffset not in any section");
4257 }
4258 
4259 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4260 // entry to get the section name.
4262  uint64_t SegOffset) {
4263  return findSection(SegIndex, SegOffset).SectionName;
4264 }
4265 
4266 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4267 // entry to get the address.
4269  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4270  return SI.SegmentStartAddress + OffsetInSeg;
4271 }
4272 
4275  ArrayRef<uint8_t> Opcodes, bool is64,
4276  MachOBindEntry::Kind BKind) {
4277  if (O->BindRebaseSectionTable == nullptr)
4278  O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4279  MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4280  Start.moveToFirst();
4281 
4282  MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4283  Finish.moveToEnd();
4284 
4285  return make_range(bind_iterator(Start), bind_iterator(Finish));
4286 }
4287 
4289  return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4291 }
4292 
4294  return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4296 }
4297 
4299  return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4301 }
4302 
4304  MachOChainedFixupEntry Start(&Err, this, true);
4305  Start.moveToFirst();
4306 
4307  MachOChainedFixupEntry Finish(&Err, this, false);
4308  Finish.moveToEnd();
4309 
4310  return make_range(fixup_iterator(Start), fixup_iterator(Finish));
4311 }
4312 
4315  return LoadCommands.begin();
4316 }
4317 
4320  return LoadCommands.end();
4321 }
4322 
4326 }
4327 
4328 StringRef
4331  return parseSegmentOrSectionName(Raw.data());
4332 }
4333 
4336  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4337  const section_base *Base =
4338  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4339  return makeArrayRef(Base->sectname);
4340 }
4341 
4344  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4345  const section_base *Base =
4346  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4347  return makeArrayRef(Base->segname);
4348 }
4349 
4350 bool
4352  const {
4353  if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4354  return false;
4356 }
4357 
4359  const MachO::any_relocation_info &RE) const {
4360  if (isLittleEndian())
4361  return RE.r_word1 & 0xffffff;
4362  return RE.r_word1 >> 8;
4363 }
4364 
4366  const MachO::any_relocation_info &RE) const {
4367  if (isLittleEndian())
4368  return (RE.r_word1 >> 27) & 1;
4369  return (RE.r_word1 >> 4) & 1;
4370 }
4371 
4373  const MachO::any_relocation_info &RE) const {
4374  return RE.r_word0 >> 31;
4375 }
4376 
4378  const MachO::any_relocation_info &RE) const {
4379  return RE.r_word1;
4380 }
4381 
4383  const MachO::any_relocation_info &RE) const {
4384  return (RE.r_word0 >> 24) & 0xf;
4385 }
4386 
4388  const MachO::any_relocation_info &RE) const {
4389  if (isRelocationScattered(RE))
4390  return getScatteredRelocationAddress(RE);
4391  return getPlainRelocationAddress(RE);
4392 }
4393 
4395  const MachO::any_relocation_info &RE) const {
4396  if (isRelocationScattered(RE))
4397  return getScatteredRelocationPCRel(RE);
4398  return getPlainRelocationPCRel(*this, RE);
4399 }
4400 
4402  const MachO::any_relocation_info &RE) const {
4403  if (isRelocationScattered(RE))
4404  return getScatteredRelocationLength(RE);
4405  return getPlainRelocationLength(*this, RE);
4406 }
4407 
4408 unsigned
4410  const MachO::any_relocation_info &RE) const {
4411  if (isRelocationScattered(RE))
4412  return getScatteredRelocationType(RE);
4413  return getPlainRelocationType(*this, RE);
4414 }
4415 
4416 SectionRef
4418  const MachO::any_relocation_info &RE) const {
4420  return *section_end();
4421  unsigned SecNum = getPlainRelocationSymbolNum(RE);
4422  if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4423  return *section_end();
4424  DataRefImpl DRI;
4425  DRI.d.a = SecNum - 1;
4426  return SectionRef(DRI, this);
4427 }
4428 
4430  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4431  return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4432 }
4433 
4435  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4436  return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4437 }
4438 
4440  unsigned Index) const {
4441  const char *Sec = getSectionPtr(*this, L, Index);
4442  return getStruct<MachO::section>(*this, Sec);
4443 }
4444 
4446  unsigned Index) const {
4447  const char *Sec = getSectionPtr(*this, L, Index);
4448  return getStruct<MachO::section_64>(*this, Sec);
4449 }
4450 
4453  const char *P = reinterpret_cast<const char *>(DRI.p);
4454  return getStruct<MachO::nlist>(*this, P);
4455 }
4456 
4459  const char *P = reinterpret_cast<const char *>(DRI.p);
4460  return getStruct<MachO::nlist_64>(*this, P);
4461 }
4462 
4465  return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4466 }
4467 
4470  return getStruct<MachO::segment_command>(*this, L.Ptr);
4471 }
4472 
4475  return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4476 }
4477 
4480  return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4481 }
4482 
4485  return getStruct<MachO::version_min_command>(*this, L.Ptr);
4486 }
4487 
4490  return getStruct<MachO::note_command>(*this, L.Ptr);
4491 }
4492 
4495  return getStruct<MachO::build_version_command>(*this, L.Ptr);
4496 }
4497 
4500  return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4501 }
4502 
4505  return getStruct<MachO::dylib_command>(*this, L.Ptr);
4506 }
4507 
4510  return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4511 }
4512 
4515  return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4516 }
4517 
4520  return getStruct<MachO::uuid_command>(*this, L.Ptr);
4521 }
4522 
4525  return getStruct<MachO::rpath_command>(*this, L.Ptr);
4526 }
4527 
4530  return getStruct<MachO::source_version_command>(*this, L.Ptr);
4531 }
4532 
4535  return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4536 }
4537 
4540  return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4541 }
4542 
4545  return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4546 }
4547 
4550  return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4551 }
4552 
4555  return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4556 }
4557 
4560  return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4561 }
4562 
4565  return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4566 }
4567 
4570  return getStruct<MachO::routines_command>(*this, L.Ptr);
4571 }
4572 
4575  return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4576 }
4577 
4580  return getStruct<MachO::thread_command>(*this, L.Ptr);
4581 }
4582 
4585  uint32_t Offset;
4586  if (getHeader().filetype == MachO::MH_OBJECT) {
4587  DataRefImpl Sec;
4588  Sec.d.a = Rel.d.a;
4589  if (is64Bit()) {
4590  MachO::section_64 Sect = getSection64(Sec);
4591  Offset = Sect.reloff;
4592  } else {
4593  MachO::section Sect = getSection(Sec);
4594  Offset = Sect.reloff;
4595  }
4596  } else {
4597  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4598  if (Rel.d.a == 0)
4599  Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4600  else
4601  Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4602  }
4603 
4604  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4605