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