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