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_STATE64) {
1015  if (count != MachO::x86_THREAD_STATE64_COUNT)
1016  return malformedError("load command " + Twine(LoadCommandIndex) +
1017  " count not x86_THREAD_STATE64_COUNT for "
1018  "flavor number " + Twine(nflavor) + " which is "
1019  "a x86_THREAD_STATE64 flavor in " + CmdName +
1020  " command");
1021  if (state + sizeof(MachO::x86_thread_state64_t) > end)
1022  return malformedError("load command " + Twine(LoadCommandIndex) +
1023  " x86_THREAD_STATE64 extends past end of "
1024  "command in " + CmdName + " command");
1025  state += sizeof(MachO::x86_thread_state64_t);
1026  } else {
1027  return malformedError("load command " + Twine(LoadCommandIndex) +
1028  " unknown flavor (" + Twine(flavor) + ") for "
1029  "flavor number " + Twine(nflavor) + " in " +
1030  CmdName + " command");
1031  }
1032  } else if (cputype == MachO::CPU_TYPE_ARM) {
1033  if (flavor == MachO::ARM_THREAD_STATE) {
1034  if (count != MachO::ARM_THREAD_STATE_COUNT)
1035  return malformedError("load command " + Twine(LoadCommandIndex) +
1036  " count not ARM_THREAD_STATE_COUNT for "
1037  "flavor number " + Twine(nflavor) + " which is "
1038  "a ARM_THREAD_STATE flavor in " + CmdName +
1039  " command");
1040  if (state + sizeof(MachO::arm_thread_state32_t) > end)
1041  return malformedError("load command " + Twine(LoadCommandIndex) +
1042  " ARM_THREAD_STATE extends past end of "
1043  "command in " + CmdName + " command");
1044  state += sizeof(MachO::arm_thread_state32_t);
1045  } else {
1046  return malformedError("load command " + Twine(LoadCommandIndex) +
1047  " unknown flavor (" + Twine(flavor) + ") for "
1048  "flavor number " + Twine(nflavor) + " in " +
1049  CmdName + " command");
1050  }
1051  } else if (cputype == MachO::CPU_TYPE_ARM64) {
1052  if (flavor == MachO::ARM_THREAD_STATE64) {
1053  if (count != MachO::ARM_THREAD_STATE64_COUNT)
1054  return malformedError("load command " + Twine(LoadCommandIndex) +
1055  " count not ARM_THREAD_STATE64_COUNT for "
1056  "flavor number " + Twine(nflavor) + " which is "
1057  "a ARM_THREAD_STATE64 flavor in " + CmdName +
1058  " command");
1059  if (state + sizeof(MachO::arm_thread_state64_t) > end)
1060  return malformedError("load command " + Twine(LoadCommandIndex) +
1061  " ARM_THREAD_STATE64 extends past end of "
1062  "command in " + CmdName + " command");
1063  state += sizeof(MachO::arm_thread_state64_t);
1064  } else {
1065  return malformedError("load command " + Twine(LoadCommandIndex) +
1066  " unknown flavor (" + Twine(flavor) + ") for "
1067  "flavor number " + Twine(nflavor) + " in " +
1068  CmdName + " command");
1069  }
1070  } else if (cputype == MachO::CPU_TYPE_POWERPC) {
1071  if (flavor == MachO::PPC_THREAD_STATE) {
1072  if (count != MachO::PPC_THREAD_STATE_COUNT)
1073  return malformedError("load command " + Twine(LoadCommandIndex) +
1074  " count not PPC_THREAD_STATE_COUNT for "
1075  "flavor number " + Twine(nflavor) + " which is "
1076  "a PPC_THREAD_STATE flavor in " + CmdName +
1077  " command");
1078  if (state + sizeof(MachO::ppc_thread_state32_t) > end)
1079  return malformedError("load command " + Twine(LoadCommandIndex) +
1080  " PPC_THREAD_STATE extends past end of "
1081  "command in " + CmdName + " command");
1082  state += sizeof(MachO::ppc_thread_state32_t);
1083  } else {
1084  return malformedError("load command " + Twine(LoadCommandIndex) +
1085  " unknown flavor (" + Twine(flavor) + ") for "
1086  "flavor number " + Twine(nflavor) + " in " +
1087  CmdName + " command");
1088  }
1089  } else {
1090  return malformedError("unknown cputype (" + Twine(cputype) + ") load "
1091  "command " + Twine(LoadCommandIndex) + " for " +
1092  CmdName + " command can't be checked");
1093  }
1094  nflavor++;
1095  }
1096  return Error::success();
1097 }
1098 
1099 static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj,
1100  const MachOObjectFile::LoadCommandInfo
1101  &Load,
1102  uint32_t LoadCommandIndex,
1103  const char **LoadCmd,
1104  std::list<MachOElement> &Elements) {
1105  if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
1106  return malformedError("load command " + Twine(LoadCommandIndex) +
1107  " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1108  if (*LoadCmd != nullptr)
1109  return malformedError("more than one LC_TWOLEVEL_HINTS command");
1111  getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1112  uint64_t FileSize = Obj.getData().size();
1113  if (Hints.offset > FileSize)
1114  return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1115  Twine(LoadCommandIndex) + " extends past the end of "
1116  "the file");
1117  uint64_t BigSize = Hints.nhints;
1118  BigSize *= sizeof(MachO::twolevel_hint);
1119  BigSize += Hints.offset;
1120  if (BigSize > FileSize)
1121  return malformedError("offset field plus nhints times sizeof(struct "
1122  "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1123  Twine(LoadCommandIndex) + " extends past the end of "
1124  "the file");
1125  if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
1126  sizeof(MachO::twolevel_hint),
1127  "two level hints"))
1128  return Err;
1129  *LoadCmd = Load.Ptr;
1130  return Error::success();
1131 }
1132 
1133 // Returns true if the libObject code does not support the load command and its
1134 // contents. The cmd value it is treated as an unknown load command but with
1135 // an error message that says the cmd value is obsolete.
1137  if (cmd == MachO::LC_SYMSEG ||
1138  cmd == MachO::LC_LOADFVMLIB ||
1139  cmd == MachO::LC_IDFVMLIB ||
1140  cmd == MachO::LC_IDENT ||
1141  cmd == MachO::LC_FVMFILE ||
1142  cmd == MachO::LC_PREPAGE ||
1143  cmd == MachO::LC_PREBOUND_DYLIB ||
1144  cmd == MachO::LC_TWOLEVEL_HINTS ||
1145  cmd == MachO::LC_PREBIND_CKSUM)
1146  return true;
1147  return false;
1148 }
1149 
1151 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
1152  bool Is64Bits, uint32_t UniversalCputype,
1153  uint32_t UniversalIndex) {
1154  Error Err = Error::success();
1155  std::unique_ptr<MachOObjectFile> Obj(
1156  new MachOObjectFile(std::move(Object), IsLittleEndian,
1157  Is64Bits, Err, UniversalCputype,
1158  UniversalIndex));
1159  if (Err)
1160  return std::move(Err);
1161  return std::move(Obj);
1162 }
1163 
1164 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1165  bool Is64bits, Error &Err,
1166  uint32_t UniversalCputype,
1167  uint32_t UniversalIndex)
1168  : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
1169  ErrorAsOutParameter ErrAsOutParam(&Err);
1170  uint64_t SizeOfHeaders;
1171  uint32_t cputype;
1172  if (is64Bit()) {
1173  parseHeader(*this, Header64, Err);
1174  SizeOfHeaders = sizeof(MachO::mach_header_64);
1175  cputype = Header64.cputype;
1176  } else {
1177  parseHeader(*this, Header, Err);
1178  SizeOfHeaders = sizeof(MachO::mach_header);
1179  cputype = Header.cputype;
1180  }
1181  if (Err)
1182  return;
1183  SizeOfHeaders += getHeader().sizeofcmds;
1184  if (getData().data() + SizeOfHeaders > getData().end()) {
1185  Err = malformedError("load commands extend past the end of the file");
1186  return;
1187  }
1188  if (UniversalCputype != 0 && cputype != UniversalCputype) {
1189  Err = malformedError("universal header architecture: " +
1190  Twine(UniversalIndex) + "'s cputype does not match "
1191  "object file's mach header");
1192  return;
1193  }
1194  std::list<MachOElement> Elements;
1195  Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1196 
1197  uint32_t LoadCommandCount = getHeader().ncmds;
1199  if (LoadCommandCount != 0) {
1200  if (auto LoadOrErr = getFirstLoadCommandInfo(*this))
1201  Load = *LoadOrErr;
1202  else {
1203  Err = LoadOrErr.takeError();
1204  return;
1205  }
1206  }
1207 
1208  const char *DyldIdLoadCmd = nullptr;
1209  const char *FuncStartsLoadCmd = nullptr;
1210  const char *SplitInfoLoadCmd = nullptr;
1211  const char *CodeSignDrsLoadCmd = nullptr;
1212  const char *CodeSignLoadCmd = nullptr;
1213  const char *VersLoadCmd = nullptr;
1214  const char *SourceLoadCmd = nullptr;
1215  const char *EntryPointLoadCmd = nullptr;
1216  const char *EncryptLoadCmd = nullptr;
1217  const char *RoutinesLoadCmd = nullptr;
1218  const char *UnixThreadLoadCmd = nullptr;
1219  const char *TwoLevelHintsLoadCmd = nullptr;
1220  for (unsigned I = 0; I < LoadCommandCount; ++I) {
1221  if (is64Bit()) {
1222  if (Load.C.cmdsize % 8 != 0) {
1223  // We have a hack here to allow 64-bit Mach-O core files to have
1224  // LC_THREAD commands that are only a multiple of 4 and not 8 to be
1225  // allowed since the macOS kernel produces them.
1226  if (getHeader().filetype != MachO::MH_CORE ||
1227  Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1228  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1229  "multiple of 8");
1230  return;
1231  }
1232  }
1233  } else {
1234  if (Load.C.cmdsize % 4 != 0) {
1235  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1236  "multiple of 4");
1237  return;
1238  }
1239  }
1240  LoadCommands.push_back(Load);
1241  if (Load.C.cmd == MachO::LC_SYMTAB) {
1242  if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1243  return;
1244  } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1245  if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd,
1246  Elements)))
1247  return;
1248  } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1249  if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd,
1250  "LC_DATA_IN_CODE", Elements,
1251  "data in code info")))
1252  return;
1253  } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1254  if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd,
1255  "LC_LINKER_OPTIMIZATION_HINT",
1256  Elements, "linker optimization "
1257  "hints")))
1258  return;
1259  } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1260  if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd,
1261  "LC_FUNCTION_STARTS", Elements,
1262  "function starts data")))
1263  return;
1264  } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1265  if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd,
1266  "LC_SEGMENT_SPLIT_INFO", Elements,
1267  "split info data")))
1268  return;
1269  } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1270  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd,
1271  "LC_DYLIB_CODE_SIGN_DRS", Elements,
1272  "code signing RDs data")))
1273  return;
1274  } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1275  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd,
1276  "LC_CODE_SIGNATURE", Elements,
1277  "code signature data")))
1278  return;
1279  } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1280  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1281  "LC_DYLD_INFO", Elements)))
1282  return;
1283  } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1284  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1285  "LC_DYLD_INFO_ONLY", Elements)))
1286  return;
1287  } else if (Load.C.cmd == MachO::LC_UUID) {
1288  if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1289  Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1290  "cmdsize");
1291  return;
1292  }
1293  if (UuidLoadCmd) {
1294  Err = malformedError("more than one LC_UUID command");
1295  return;
1296  }
1297  UuidLoadCmd = Load.Ptr;
1298  } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1301  *this, Load, Sections, HasPageZeroSegment, I,
1302  "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1303  return;
1304  } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1306  MachO::section>(
1307  *this, Load, Sections, HasPageZeroSegment, I,
1308  "LC_SEGMENT", SizeOfHeaders, Elements)))
1309  return;
1310  } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1311  if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1312  return;
1313  } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1314  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1315  return;
1316  Libraries.push_back(Load.Ptr);
1317  } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1318  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1319  return;
1320  Libraries.push_back(Load.Ptr);
1321  } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1322  if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1323  return;
1324  Libraries.push_back(Load.Ptr);
1325  } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1326  if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1327  return;
1328  Libraries.push_back(Load.Ptr);
1329  } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1330  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1331  return;
1332  Libraries.push_back(Load.Ptr);
1333  } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1334  if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1335  return;
1336  } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1337  if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1338  return;
1339  } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1340  if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1341  return;
1342  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1343  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1344  "LC_VERSION_MIN_MACOSX")))
1345  return;
1346  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1347  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1348  "LC_VERSION_MIN_IPHONEOS")))
1349  return;
1350  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1351  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1352  "LC_VERSION_MIN_TVOS")))
1353  return;
1354  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1355  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1356  "LC_VERSION_MIN_WATCHOS")))
1357  return;
1358  } else if (Load.C.cmd == MachO::LC_NOTE) {
1359  if ((Err = checkNoteCommand(*this, Load, I, Elements)))
1360  return;
1361  } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1362  if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
1363  return;
1364  } else if (Load.C.cmd == MachO::LC_RPATH) {
1365  if ((Err = checkRpathCommand(*this, Load, I)))
1366  return;
1367  } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1368  if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1369  Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1370  " has incorrect cmdsize");
1371  return;
1372  }
1373  if (SourceLoadCmd) {
1374  Err = malformedError("more than one LC_SOURCE_VERSION command");
1375  return;
1376  }
1377  SourceLoadCmd = Load.Ptr;
1378  } else if (Load.C.cmd == MachO::LC_MAIN) {
1379  if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1380  Err = malformedError("LC_MAIN command " + Twine(I) +
1381  " has incorrect cmdsize");
1382  return;
1383  }
1384  if (EntryPointLoadCmd) {
1385  Err = malformedError("more than one LC_MAIN command");
1386  return;
1387  }
1388  EntryPointLoadCmd = Load.Ptr;
1389  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1390  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1391  Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1392  " has incorrect cmdsize");
1393  return;
1394  }
1396  getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1397  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1398  &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1399  return;
1400  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1401  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1402  Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1403  " has incorrect cmdsize");
1404  return;
1405  }
1407  getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1408  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1409  &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1410  return;
1411  } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1412  if ((Err = checkLinkerOptCommand(*this, Load, I)))
1413  return;
1414  } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1415  if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1416  Err = malformedError("load command " + Twine(I) +
1417  " LC_SUB_FRAMEWORK cmdsize too small");
1418  return;
1419  }
1421  getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1422  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1424  "sub_framework_command", S.umbrella,
1425  "umbrella")))
1426  return;
1427  } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1428  if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1429  Err = malformedError("load command " + Twine(I) +
1430  " LC_SUB_UMBRELLA cmdsize too small");
1431  return;
1432  }
1434  getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1435  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1437  "sub_umbrella_command", S.sub_umbrella,
1438  "sub_umbrella")))
1439  return;
1440  } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1441  if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1442  Err = malformedError("load command " + Twine(I) +
1443  " LC_SUB_LIBRARY cmdsize too small");
1444  return;
1445  }
1447  getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1448  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1450  "sub_library_command", S.sub_library,
1451  "sub_library")))
1452  return;
1453  } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1454  if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1455  Err = malformedError("load command " + Twine(I) +
1456  " LC_SUB_CLIENT cmdsize too small");
1457  return;
1458  }
1460  getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1461  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1462  sizeof(MachO::sub_client_command),
1463  "sub_client_command", S.client, "client")))
1464  return;
1465  } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1466  if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1467  Err = malformedError("LC_ROUTINES command " + Twine(I) +
1468  " has incorrect cmdsize");
1469  return;
1470  }
1471  if (RoutinesLoadCmd) {
1472  Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1473  "command");
1474  return;
1475  }
1476  RoutinesLoadCmd = Load.Ptr;
1477  } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1478  if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1479  Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1480  " has incorrect cmdsize");
1481  return;
1482  }
1483  if (RoutinesLoadCmd) {
1484  Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1485  "command");
1486  return;
1487  }
1488  RoutinesLoadCmd = Load.Ptr;
1489  } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1490  if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1491  return;
1492  if (UnixThreadLoadCmd) {
1493  Err = malformedError("more than one LC_UNIXTHREAD command");
1494  return;
1495  }
1496  UnixThreadLoadCmd = Load.Ptr;
1497  } else if (Load.C.cmd == MachO::LC_THREAD) {
1498  if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1499  return;
1500  // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1501  } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1502  if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1503  &TwoLevelHintsLoadCmd, Elements)))
1504  return;
1505  } else if (isLoadCommandObsolete(Load.C.cmd)) {
1506  Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1507  Twine(Load.C.cmd) + " is obsolete and not "
1508  "supported");
1509  return;
1510  }
1511  // TODO: generate a error for unknown load commands by default. But still
1512  // need work out an approach to allow or not allow unknown values like this
1513  // as an option for some uses like lldb.
1514  if (I < LoadCommandCount - 1) {
1515  if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1516  Load = *LoadOrErr;
1517  else {
1518  Err = LoadOrErr.takeError();
1519  return;
1520  }
1521  }
1522  }
1523  if (!SymtabLoadCmd) {
1524  if (DysymtabLoadCmd) {
1525  Err = malformedError("contains LC_DYSYMTAB load command without a "
1526  "LC_SYMTAB load command");
1527  return;
1528  }
1529  } else if (DysymtabLoadCmd) {
1530  MachO::symtab_command Symtab =
1531  getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1532  MachO::dysymtab_command Dysymtab =
1533  getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1534  if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1535  Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1536  "extends past the end of the symbol table");
1537  return;
1538  }
1539  uint64_t BigSize = Dysymtab.ilocalsym;
1540  BigSize += Dysymtab.nlocalsym;
1541  if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1542  Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1543  "command extends past the end of the symbol table");
1544  return;
1545  }
1546  if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1547  Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
1548  "extends past the end of the symbol table");
1549  return;
1550  }
1551  BigSize = Dysymtab.iextdefsym;
1552  BigSize += Dysymtab.nextdefsym;
1553  if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1554  Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1555  "load command extends past the end of the symbol "
1556  "table");
1557  return;
1558  }
1559  if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1560  Err = malformedError("nundefsym in LC_DYSYMTAB load command "
1561  "extends past the end of the symbol table");
1562  return;
1563  }
1564  BigSize = Dysymtab.iundefsym;
1565  BigSize += Dysymtab.nundefsym;
1566  if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1567  Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1568  " command extends past the end of the symbol table");
1569  return;
1570  }
1571  }
1572  if ((getHeader().filetype == MachO::MH_DYLIB ||
1573  getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1574  DyldIdLoadCmd == nullptr) {
1575  Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1576  "filetype");
1577  return;
1578  }
1579  assert(LoadCommands.size() == LoadCommandCount);
1580 
1581  Err = Error::success();
1582 }
1583 
1585  uint32_t Flags = 0;
1586  if (is64Bit()) {
1588  Flags = H_64.flags;
1589  } else {
1591  Flags = H.flags;
1592  }
1593  uint8_t NType = 0;
1594  uint8_t NSect = 0;
1595  uint16_t NDesc = 0;
1596  uint32_t NStrx = 0;
1597  uint64_t NValue = 0;
1598  uint32_t SymbolIndex = 0;
1599  MachO::symtab_command S = getSymtabLoadCommand();
1600  for (const SymbolRef &Symbol : symbols()) {
1601  DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1602  if (is64Bit()) {
1603  MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1604  NType = STE_64.n_type;
1605  NSect = STE_64.n_sect;
1606  NDesc = STE_64.n_desc;
1607  NStrx = STE_64.n_strx;
1608  NValue = STE_64.n_value;
1609  } else {
1610  MachO::nlist STE = getSymbolTableEntry(SymDRI);
1611  NType = STE.n_type;
1612  NType = STE.n_type;
1613  NSect = STE.n_sect;
1614  NDesc = STE.n_desc;
1615  NStrx = STE.n_strx;
1616  NValue = STE.n_value;
1617  }
1618  if ((NType & MachO::N_STAB) == 0 &&
1619  (NType & MachO::N_TYPE) == MachO::N_SECT) {
1620  if (NSect == 0 || NSect > Sections.size())
1621  return malformedError("bad section index: " + Twine((int)NSect) +
1622  " for symbol at index " + Twine(SymbolIndex));
1623  }
1624  if ((NType & MachO::N_STAB) == 0 &&
1625  (NType & MachO::N_TYPE) == MachO::N_INDR) {
1626  if (NValue >= S.strsize)
1627  return malformedError("bad n_value: " + Twine((int)NValue) + " past "
1628  "the end of string table, for N_INDR symbol at "
1629  "index " + Twine(SymbolIndex));
1630  }
1631  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
1632  (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
1633  (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
1634  uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
1635  if (LibraryOrdinal != 0 &&
1636  LibraryOrdinal != MachO::EXECUTABLE_ORDINAL &&
1637  LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL &&
1638  LibraryOrdinal - 1 >= Libraries.size() ) {
1639  return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) +
1640  " for symbol at index " + Twine(SymbolIndex));
1641  }
1642  }
1643  if (NStrx >= S.strsize)
1644  return malformedError("bad string table index: " + Twine((int)NStrx) +
1645  " past the end of string table, for symbol at "
1646  "index " + Twine(SymbolIndex));
1647  SymbolIndex++;
1648  }
1649  return Error::success();
1650 }
1651 
1653  unsigned SymbolTableEntrySize = is64Bit() ?
1654  sizeof(MachO::nlist_64) :
1655  sizeof(MachO::nlist);
1656  Symb.p += SymbolTableEntrySize;
1657 }
1658 
1660  StringRef StringTable = getStringTableData();
1661  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1662  if (Entry.n_strx == 0)
1663  // A n_strx value of 0 indicates that no name is associated with a
1664  // particular symbol table entry.
1665  return StringRef();
1666  const char *Start = &StringTable.data()[Entry.n_strx];
1667  if (Start < getData().begin() || Start >= getData().end()) {
1668  return malformedError("bad string index: " + Twine(Entry.n_strx) +
1669  " for symbol at index " + Twine(getSymbolIndex(Symb)));
1670  }
1671  return StringRef(Start);
1672 }
1673 
1675  DataRefImpl DRI = Sec.getRawDataRefImpl();
1676  uint32_t Flags = getSectionFlags(*this, DRI);
1677  return Flags & MachO::SECTION_TYPE;
1678 }
1679 
1681  if (is64Bit()) {
1682  MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
1683  return Entry.n_value;
1684  }
1685  MachO::nlist Entry = getSymbolTableEntry(Sym);
1686  return Entry.n_value;
1687 }
1688 
1689 // getIndirectName() returns the name of the alias'ed symbol who's string table
1690 // index is in the n_value field.
1692  StringRef &Res) const {
1693  StringRef StringTable = getStringTableData();
1694  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1695  if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1697  uint64_t NValue = getNValue(Symb);
1698  if (NValue >= StringTable.size())
1700  const char *Start = &StringTable.data()[NValue];
1701  Res = StringRef(Start);
1702  return std::error_code();
1703 }
1704 
1705 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1706  return getNValue(Sym);
1707 }
1708 
1710  return getSymbolValue(Sym);
1711 }
1712 
1714  uint32_t flags = getSymbolFlags(DRI);
1715  if (flags & SymbolRef::SF_Common) {
1716  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1717  return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1718  }
1719  return 0;
1720 }
1721 
1723  return getNValue(DRI);
1724 }
1725 
1728  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1729  uint8_t n_type = Entry.n_type;
1730 
1731  // If this is a STAB debugging symbol, we can do nothing more.
1732  if (n_type & MachO::N_STAB)
1733  return SymbolRef::ST_Debug;
1734 
1735  switch (n_type & MachO::N_TYPE) {
1736  case MachO::N_UNDF :
1737  return SymbolRef::ST_Unknown;
1738  case MachO::N_SECT :
1739  Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1740  if (!SecOrError)
1741  return SecOrError.takeError();
1742  section_iterator Sec = *SecOrError;
1743  if (Sec->isData() || Sec->isBSS())
1744  return SymbolRef::ST_Data;
1745  return SymbolRef::ST_Function;
1746  }
1747  return SymbolRef::ST_Other;
1748 }
1749 
1751  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1752 
1753  uint8_t MachOType = Entry.n_type;
1754  uint16_t MachOFlags = Entry.n_desc;
1755 
1756  uint32_t Result = SymbolRef::SF_None;
1757 
1758  if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1759  Result |= SymbolRef::SF_Indirect;
1760 
1761  if (MachOType & MachO::N_STAB)
1762  Result |= SymbolRef::SF_FormatSpecific;
1763 
1764  if (MachOType & MachO::N_EXT) {
1765  Result |= SymbolRef::SF_Global;
1766  if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1767  if (getNValue(DRI))
1768  Result |= SymbolRef::SF_Common;
1769  else
1770  Result |= SymbolRef::SF_Undefined;
1771  }
1772 
1773  if (!(MachOType & MachO::N_PEXT))
1774  Result |= SymbolRef::SF_Exported;
1775  }
1776 
1777  if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1778  Result |= SymbolRef::SF_Weak;
1779 
1780  if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1781  Result |= SymbolRef::SF_Thumb;
1782 
1783  if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1784  Result |= SymbolRef::SF_Absolute;
1785 
1786  return Result;
1787 }
1788 
1791  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1792  uint8_t index = Entry.n_sect;
1793 
1794  if (index == 0)
1795  return section_end();
1796  DataRefImpl DRI;
1797  DRI.d.a = index - 1;
1798  if (DRI.d.a >= Sections.size()){
1799  return malformedError("bad section index: " + Twine((int)index) +
1800  " for symbol at index " + Twine(getSymbolIndex(Symb)));
1801  }
1802  return section_iterator(SectionRef(DRI, this));
1803 }
1804 
1806  MachO::nlist_base Entry =
1808  return Entry.n_sect - 1;
1809 }
1810 
1812  Sec.d.a++;
1813 }
1814 
1816  StringRef &Result) const {
1817  ArrayRef<char> Raw = getSectionRawName(Sec);
1818  Result = parseSegmentOrSectionName(Raw.data());
1819  return std::error_code();
1820 }
1821 
1823  if (is64Bit())
1824  return getSection64(Sec).addr;
1825  return getSection(Sec).addr;
1826 }
1827 
1829  return Sec.d.a;
1830 }
1831 
1833  // In the case if a malformed Mach-O file where the section offset is past
1834  // the end of the file or some part of the section size is past the end of
1835  // the file return a size of zero or a size that covers the rest of the file
1836  // but does not extend past the end of the file.
1837  uint32_t SectOffset, SectType;
1838  uint64_t SectSize;
1839 
1840  if (is64Bit()) {
1841  MachO::section_64 Sect = getSection64(Sec);
1842  SectOffset = Sect.offset;
1843  SectSize = Sect.size;
1844  SectType = Sect.flags & MachO::SECTION_TYPE;
1845  } else {
1846  MachO::section Sect = getSection(Sec);
1847  SectOffset = Sect.offset;
1848  SectSize = Sect.size;
1849  SectType = Sect.flags & MachO::SECTION_TYPE;
1850  }
1851  if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1852  return SectSize;
1853  uint64_t FileSize = getData().size();
1854  if (SectOffset > FileSize)
1855  return 0;
1856  if (FileSize - SectOffset < SectSize)
1857  return FileSize - SectOffset;
1858  return SectSize;
1859 }
1860 
1862  StringRef &Res) const {
1863  uint32_t Offset;
1864  uint64_t Size;
1865 
1866  if (is64Bit()) {
1867  MachO::section_64 Sect = getSection64(Sec);
1868  Offset = Sect.offset;
1869  Size = Sect.size;
1870  } else {
1871  MachO::section Sect = getSection(Sec);
1872  Offset = Sect.offset;
1873  Size = Sect.size;
1874  }
1875 
1876  Res = this->getData().substr(Offset, Size);
1877  return std::error_code();
1878 }
1879 
1881  uint32_t Align;
1882  if (is64Bit()) {
1883  MachO::section_64 Sect = getSection64(Sec);
1884  Align = Sect.align;
1885  } else {
1886  MachO::section Sect = getSection(Sec);
1887  Align = Sect.align;
1888  }
1889 
1890  return uint64_t(1) << Align;
1891 }
1892 
1894  return false;
1895 }
1896 
1898  uint32_t Flags = getSectionFlags(*this, Sec);
1899  return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
1900 }
1901 
1903  uint32_t Flags = getSectionFlags(*this, Sec);
1904  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1905  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1906  !(SectionType == MachO::S_ZEROFILL ||
1907  SectionType == MachO::S_GB_ZEROFILL);
1908 }
1909 
1911  uint32_t Flags = getSectionFlags(*this, Sec);
1912  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1913  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1914  (SectionType == MachO::S_ZEROFILL ||
1915  SectionType == MachO::S_GB_ZEROFILL);
1916 }
1917 
1919  return Sec.getRawDataRefImpl().d.a;
1920 }
1921 
1923  // FIXME: Unimplemented.
1924  return false;
1925 }
1926 
1928  StringRef SegmentName = getSectionFinalSegmentName(Sec);
1929  StringRef SectName;
1930  if (!getSectionName(Sec, SectName))
1931  return (SegmentName == "__LLVM" && SectName == "__bitcode");
1932  return false;
1933 }
1934 
1936  if (is64Bit())
1937  return getSection64(Sec).offset == 0;
1938  return getSection(Sec).offset == 0;
1939 }
1940 
1942  DataRefImpl Ret;
1943  Ret.d.a = Sec.d.a;
1944  Ret.d.b = 0;
1945  return relocation_iterator(RelocationRef(Ret, this));
1946 }
1947 
1950  uint32_t Num;
1951  if (is64Bit()) {
1952  MachO::section_64 Sect = getSection64(Sec);
1953  Num = Sect.nreloc;
1954  } else {
1955  MachO::section Sect = getSection(Sec);
1956  Num = Sect.nreloc;
1957  }
1958 
1959  DataRefImpl Ret;
1960  Ret.d.a = Sec.d.a;
1961  Ret.d.b = Num;
1962  return relocation_iterator(RelocationRef(Ret, this));
1963 }
1964 
1966  DataRefImpl Ret;
1967  // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
1968  Ret.d.a = 0; // Would normally be a section index.
1969  Ret.d.b = 0; // Index into the external relocations
1970  return relocation_iterator(RelocationRef(Ret, this));
1971 }
1972 
1974  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
1975  DataRefImpl Ret;
1976  // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
1977  Ret.d.a = 0; // Would normally be a section index.
1978  Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
1979  return relocation_iterator(RelocationRef(Ret, this));
1980 }
1981 
1983  DataRefImpl Ret;
1984  // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
1985  Ret.d.a = 1; // Would normally be a section index.
1986  Ret.d.b = 0; // Index into the local relocations
1987  return relocation_iterator(RelocationRef(Ret, this));
1988 }
1989 
1991  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
1992  DataRefImpl Ret;
1993  // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
1994  Ret.d.a = 1; // Would normally be a section index.
1995  Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations
1996  return relocation_iterator(RelocationRef(Ret, this));
1997 }
1998 
2000  ++Rel.d.b;
2001 }
2002 
2004  assert((getHeader().filetype == MachO::MH_OBJECT ||
2005  getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
2006  "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2007  MachO::any_relocation_info RE = getRelocation(Rel);
2008  return getAnyRelocationAddress(RE);
2009 }
2010 
2013  MachO::any_relocation_info RE = getRelocation(Rel);
2014  if (isRelocationScattered(RE))
2015  return symbol_end();
2016 
2017  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2018  bool isExtern = getPlainRelocationExternal(RE);
2019  if (!isExtern)
2020  return symbol_end();
2021 
2022  MachO::symtab_command S = getSymtabLoadCommand();
2023  unsigned SymbolTableEntrySize = is64Bit() ?
2024  sizeof(MachO::nlist_64) :
2025  sizeof(MachO::nlist);
2026  uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
2027  DataRefImpl Sym;
2028  Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2029  return symbol_iterator(SymbolRef(Sym, this));
2030 }
2031 
2034  return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
2035 }
2036 
2038  MachO::any_relocation_info RE = getRelocation(Rel);
2039  return getAnyRelocationType(RE);
2040 }
2041 
2043  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2044  StringRef res;
2045  uint64_t RType = getRelocationType(Rel);
2046 
2047  unsigned Arch = this->getArch();
2048 
2049  switch (Arch) {
2050  case Triple::x86: {
2051  static const char *const Table[] = {
2052  "GENERIC_RELOC_VANILLA",
2053  "GENERIC_RELOC_PAIR",
2054  "GENERIC_RELOC_SECTDIFF",
2055  "GENERIC_RELOC_PB_LA_PTR",
2056  "GENERIC_RELOC_LOCAL_SECTDIFF",
2057  "GENERIC_RELOC_TLV" };
2058 
2059  if (RType > 5)
2060  res = "Unknown";
2061  else
2062  res = Table[RType];
2063  break;
2064  }
2065  case Triple::x86_64: {
2066  static const char *const Table[] = {
2067  "X86_64_RELOC_UNSIGNED",
2068  "X86_64_RELOC_SIGNED",
2069  "X86_64_RELOC_BRANCH",
2070  "X86_64_RELOC_GOT_LOAD",
2071  "X86_64_RELOC_GOT",
2072  "X86_64_RELOC_SUBTRACTOR",
2073  "X86_64_RELOC_SIGNED_1",
2074  "X86_64_RELOC_SIGNED_2",
2075  "X86_64_RELOC_SIGNED_4",
2076  "X86_64_RELOC_TLV" };
2077 
2078  if (RType > 9)
2079  res = "Unknown";
2080  else
2081  res = Table[RType];
2082  break;
2083  }
2084  case Triple::arm: {
2085  static const char *const Table[] = {
2086  "ARM_RELOC_VANILLA",
2087  "ARM_RELOC_PAIR",
2088  "ARM_RELOC_SECTDIFF",
2089  "ARM_RELOC_LOCAL_SECTDIFF",
2090  "ARM_RELOC_PB_LA_PTR",
2091  "ARM_RELOC_BR24",
2092  "ARM_THUMB_RELOC_BR22",
2093  "ARM_THUMB_32BIT_BRANCH",
2094  "ARM_RELOC_HALF",
2095  "ARM_RELOC_HALF_SECTDIFF" };
2096 
2097  if (RType > 9)
2098  res = "Unknown";
2099  else
2100  res = Table[RType];
2101  break;
2102  }
2103  case Triple::aarch64: {
2104  static const char *const Table[] = {
2105  "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
2106  "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
2107  "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
2108  "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2109  "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2110  "ARM64_RELOC_ADDEND"
2111  };
2112 
2113  if (RType >= array_lengthof(Table))
2114  res = "Unknown";
2115  else
2116  res = Table[RType];
2117  break;
2118  }
2119  case Triple::ppc: {
2120  static const char *const Table[] = {
2121  "PPC_RELOC_VANILLA",
2122  "PPC_RELOC_PAIR",
2123  "PPC_RELOC_BR14",
2124  "PPC_RELOC_BR24",
2125  "PPC_RELOC_HI16",
2126  "PPC_RELOC_LO16",
2127  "PPC_RELOC_HA16",
2128  "PPC_RELOC_LO14",
2129  "PPC_RELOC_SECTDIFF",
2130  "PPC_RELOC_PB_LA_PTR",
2131  "PPC_RELOC_HI16_SECTDIFF",
2132  "PPC_RELOC_LO16_SECTDIFF",
2133  "PPC_RELOC_HA16_SECTDIFF",
2134  "PPC_RELOC_JBSR",
2135  "PPC_RELOC_LO14_SECTDIFF",
2136  "PPC_RELOC_LOCAL_SECTDIFF" };
2137 
2138  if (RType > 15)
2139  res = "Unknown";
2140  else
2141  res = Table[RType];
2142  break;
2143  }
2144  case Triple::UnknownArch:
2145  res = "Unknown";
2146  break;
2147  }
2148  Result.append(res.begin(), res.end());
2149 }
2150 
2152  MachO::any_relocation_info RE = getRelocation(Rel);
2153  return getAnyRelocationLength(RE);
2154 }
2155 
2156 //
2157 // guessLibraryShortName() is passed a name of a dynamic library and returns a
2158 // guess on what the short name is. Then name is returned as a substring of the
2159 // StringRef Name passed in. The name of the dynamic library is recognized as
2160 // a framework if it has one of the two following forms:
2161 // Foo.framework/Versions/A/Foo
2162 // Foo.framework/Foo
2163 // Where A and Foo can be any string. And may contain a trailing suffix
2164 // starting with an underbar. If the Name is recognized as a framework then
2165 // isFramework is set to true else it is set to false. If the Name has a
2166 // suffix then Suffix is set to the substring in Name that contains the suffix
2167 // else it is set to a NULL StringRef.
2168 //
2169 // The Name of the dynamic library is recognized as a library name if it has
2170 // one of the two following forms:
2171 // libFoo.A.dylib
2172 // libFoo.dylib
2173 // The library may have a suffix trailing the name Foo of the form:
2174 // libFoo_profile.A.dylib
2175 // libFoo_profile.dylib
2176 //
2177 // The Name of the dynamic library is also recognized as a library name if it
2178 // has the following form:
2179 // Foo.qtx
2180 //
2181 // If the Name of the dynamic library is none of the forms above then a NULL
2182 // StringRef is returned.
2183 //
2185  bool &isFramework,
2186  StringRef &Suffix) {
2187  StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2188  size_t a, b, c, d, Idx;
2189 
2190  isFramework = false;
2191  Suffix = StringRef();
2192 
2193  // Pull off the last component and make Foo point to it
2194  a = Name.rfind('/');
2195  if (a == Name.npos || a == 0)
2196  goto guess_library;
2197  Foo = Name.slice(a+1, Name.npos);
2198 
2199  // Look for a suffix starting with a '_'
2200  Idx = Foo.rfind('_');
2201  if (Idx != Foo.npos && Foo.size() >= 2) {
2202  Suffix = Foo.slice(Idx, Foo.npos);
2203  Foo = Foo.slice(0, Idx);
2204  }
2205 
2206  // First look for the form Foo.framework/Foo
2207  b = Name.rfind('/', a);
2208  if (b == Name.npos)
2209  Idx = 0;
2210  else
2211  Idx = b+1;
2212  F = Name.slice(Idx, Idx + Foo.size());
2213  DotFramework = Name.slice(Idx + Foo.size(),
2214  Idx + Foo.size() + sizeof(".framework/")-1);
2215  if (F == Foo && DotFramework == ".framework/") {
2216  isFramework = true;
2217  return Foo;
2218  }
2219 
2220  // Next look for the form Foo.framework/Versions/A/Foo
2221  if (b == Name.npos)
2222  goto guess_library;
2223  c = Name.rfind('/', b);
2224  if (c == Name.npos || c == 0)
2225  goto guess_library;
2226  V = Name.slice(c+1, Name.npos);
2227  if (!V.startswith("Versions/"))
2228  goto guess_library;
2229  d = Name.rfind('/', c);
2230  if (d == Name.npos)
2231  Idx = 0;
2232  else
2233  Idx = d+1;
2234  F = Name.slice(Idx, Idx + Foo.size());
2235  DotFramework = Name.slice(Idx + Foo.size(),
2236  Idx + Foo.size() + sizeof(".framework/")-1);
2237  if (F == Foo && DotFramework == ".framework/") {
2238  isFramework = true;
2239  return Foo;
2240  }
2241 
2242 guess_library:
2243  // pull off the suffix after the "." and make a point to it
2244  a = Name.rfind('.');
2245  if (a == Name.npos || a == 0)
2246  return StringRef();
2247  Dylib = Name.slice(a, Name.npos);
2248  if (Dylib != ".dylib")
2249  goto guess_qtx;
2250 
2251  // First pull off the version letter for the form Foo.A.dylib if any.
2252  if (a >= 3) {
2253  Dot = Name.slice(a-2, a-1);
2254  if (Dot == ".")
2255  a = a - 2;
2256  }
2257 
2258  b = Name.rfind('/', a);
2259  if (b == Name.npos)
2260  b = 0;
2261  else
2262  b = b+1;
2263  // ignore any suffix after an underbar like Foo_profile.A.dylib
2264  Idx = Name.find('_', b);
2265  if (Idx != Name.npos && Idx != b) {
2266  Lib = Name.slice(b, Idx);
2267  Suffix = Name.slice(Idx, a);
2268  }
2269  else
2270  Lib = Name.slice(b, a);
2271  // There are incorrect library names of the form:
2272  // libATS.A_profile.dylib so check for these.
2273  if (Lib.size() >= 3) {
2274  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2275  if (Dot == ".")
2276  Lib = Lib.slice(0, Lib.size()-2);
2277  }
2278  return Lib;
2279 
2280 guess_qtx:
2281  Qtx = Name.slice(a, Name.npos);
2282  if (Qtx != ".qtx")
2283  return StringRef();
2284  b = Name.rfind('/', a);
2285  if (b == Name.npos)
2286  Lib = Name.slice(0, a);
2287  else
2288  Lib = Name.slice(b+1, a);
2289  // There are library names of the form: QT.A.qtx so check for these.
2290  if (Lib.size() >= 3) {
2291  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2292  if (Dot == ".")
2293  Lib = Lib.slice(0, Lib.size()-2);
2294  }
2295  return Lib;
2296 }
2297 
2298 // getLibraryShortNameByIndex() is used to get the short name of the library
2299 // for an undefined symbol in a linked Mach-O binary that was linked with the
2300 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
2301 // It is passed the index (0 - based) of the library as translated from
2302 // GET_LIBRARY_ORDINAL (1 - based).
2304  StringRef &Res) const {
2305  if (Index >= Libraries.size())
2307 
2308  // If the cache of LibrariesShortNames is not built up do that first for
2309  // all the Libraries.
2310  if (LibrariesShortNames.size() == 0) {
2311  for (unsigned i = 0; i < Libraries.size(); i++) {
2313  getStruct<MachO::dylib_command>(*this, Libraries[i]);
2314  if (D.dylib.name >= D.cmdsize)
2316  const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2317  StringRef Name = StringRef(P);
2318  if (D.dylib.name+Name.size() >= D.cmdsize)
2320  StringRef Suffix;
2321  bool isFramework;
2322  StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2323  if (shortName.empty())
2324  LibrariesShortNames.push_back(Name);
2325  else
2326  LibrariesShortNames.push_back(shortName);
2327  }
2328  }
2329 
2330  Res = LibrariesShortNames[Index];
2331  return std::error_code();
2332 }
2333 
2335  return Libraries.size();
2336 }
2337 
2340  DataRefImpl Sec;
2341  Sec.d.a = Rel->getRawDataRefImpl().d.a;
2342  return section_iterator(SectionRef(Sec, this));
2343 }
2344 
2346  DataRefImpl DRI;
2347  MachO::symtab_command Symtab = getSymtabLoadCommand();
2348  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2349  return basic_symbol_iterator(SymbolRef(DRI, this));
2350 
2351  return getSymbolByIndex(0);
2352 }
2353 
2355  DataRefImpl DRI;
2356  MachO::symtab_command Symtab = getSymtabLoadCommand();
2357  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2358  return basic_symbol_iterator(SymbolRef(DRI, this));
2359 
2360  unsigned SymbolTableEntrySize = is64Bit() ?
2361  sizeof(MachO::nlist_64) :
2362  sizeof(MachO::nlist);
2363  unsigned Offset = Symtab.symoff +
2364  Symtab.nsyms * SymbolTableEntrySize;
2365  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2366  return basic_symbol_iterator(SymbolRef(DRI, this));
2367 }
2368 
2370  MachO::symtab_command Symtab = getSymtabLoadCommand();
2371  if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2372  report_fatal_error("Requested symbol index is out of range.");
2373  unsigned SymbolTableEntrySize =
2374  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2375  DataRefImpl DRI;
2376  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2377  DRI.p += Index * SymbolTableEntrySize;
2378  return basic_symbol_iterator(SymbolRef(DRI, this));
2379 }
2380 
2382  MachO::symtab_command Symtab = getSymtabLoadCommand();
2383  if (!SymtabLoadCmd)
2384  report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2385  unsigned SymbolTableEntrySize =
2386  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2387  DataRefImpl DRIstart;
2388  DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2389  uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2390  return Index;
2391 }
2392 
2394  DataRefImpl DRI;
2395  return section_iterator(SectionRef(DRI, this));
2396 }
2397 
2399  DataRefImpl DRI;
2400  DRI.d.a = Sections.size();
2401  return section_iterator(SectionRef(DRI, this));
2402 }
2403 
2405  return is64Bit() ? 8 : 4;
2406 }
2407 
2409  unsigned CPUType = getCPUType(*this);
2410  if (!is64Bit()) {
2411  switch (CPUType) {
2412  case MachO::CPU_TYPE_I386:
2413  return "Mach-O 32-bit i386";
2414  case MachO::CPU_TYPE_ARM:
2415  return "Mach-O arm";
2417  return "Mach-O 32-bit ppc";
2418  default:
2419  return "Mach-O 32-bit unknown";
2420  }
2421  }
2422 
2423  switch (CPUType) {
2425  return "Mach-O 64-bit x86-64";
2426  case MachO::CPU_TYPE_ARM64:
2427  return "Mach-O arm64";
2429  return "Mach-O 64-bit ppc64";
2430  default:
2431  return "Mach-O 64-bit unknown";
2432  }
2433 }
2434 
2436  switch (CPUType) {
2437  case MachO::CPU_TYPE_I386:
2438  return Triple::x86;
2440  return Triple::x86_64;
2441  case MachO::CPU_TYPE_ARM:
2442  return Triple::arm;
2443  case MachO::CPU_TYPE_ARM64:
2444  return Triple::aarch64;
2446  return Triple::ppc;
2448  return Triple::ppc64;
2449  default:
2450  return Triple::UnknownArch;
2451  }
2452 }
2453 
2455  const char **McpuDefault,
2456  const char **ArchFlag) {
2457  if (McpuDefault)
2458  *McpuDefault = nullptr;
2459  if (ArchFlag)
2460  *ArchFlag = nullptr;
2461 
2462  switch (CPUType) {
2463  case MachO::CPU_TYPE_I386:
2464  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2466  if (ArchFlag)
2467  *ArchFlag = "i386";
2468  return Triple("i386-apple-darwin");
2469  default:
2470  return Triple();
2471  }
2473  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2475  if (ArchFlag)
2476  *ArchFlag = "x86_64";
2477  return Triple("x86_64-apple-darwin");
2479  if (ArchFlag)
2480  *ArchFlag = "x86_64h";
2481  return Triple("x86_64h-apple-darwin");
2482  default:
2483  return Triple();
2484  }
2485  case MachO::CPU_TYPE_ARM:
2486  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2488  if (ArchFlag)
2489  *ArchFlag = "armv4t";
2490  return Triple("armv4t-apple-darwin");
2492  if (ArchFlag)
2493  *ArchFlag = "armv5e";
2494  return Triple("armv5e-apple-darwin");
2496  if (ArchFlag)
2497  *ArchFlag = "xscale";
2498  return Triple("xscale-apple-darwin");
2500  if (ArchFlag)
2501  *ArchFlag = "armv6";
2502  return Triple("armv6-apple-darwin");
2504  if (McpuDefault)
2505  *McpuDefault = "cortex-m0";
2506  if (ArchFlag)
2507  *ArchFlag = "armv6m";
2508  return Triple("armv6m-apple-darwin");
2510  if (ArchFlag)
2511  *ArchFlag = "armv7";
2512  return Triple("armv7-apple-darwin");
2514  if (McpuDefault)
2515  *McpuDefault = "cortex-m4";
2516  if (ArchFlag)
2517  *ArchFlag = "armv7em";
2518  return Triple("thumbv7em-apple-darwin");
2520  if (McpuDefault)
2521  *McpuDefault = "cortex-a7";
2522  if (ArchFlag)
2523  *ArchFlag = "armv7k";
2524  return Triple("armv7k-apple-darwin");
2526  if (McpuDefault)
2527  *McpuDefault = "cortex-m3";
2528  if (ArchFlag)
2529  *ArchFlag = "armv7m";
2530  return Triple("thumbv7m-apple-darwin");
2532  if (McpuDefault)
2533  *McpuDefault = "cortex-a7";
2534  if (ArchFlag)
2535  *ArchFlag = "armv7s";
2536  return Triple("armv7s-apple-darwin");
2537  default:
2538  return Triple();
2539  }
2540  case MachO::CPU_TYPE_ARM64:
2541  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2543  if (McpuDefault)
2544  *McpuDefault = "cyclone";
2545  if (ArchFlag)
2546  *ArchFlag = "arm64";
2547  return Triple("arm64-apple-darwin");
2548  default:
2549  return Triple();
2550  }
2552  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2554  if (ArchFlag)
2555  *ArchFlag = "ppc";
2556  return Triple("ppc-apple-darwin");
2557  default:
2558  return Triple();
2559  }
2561  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2563  if (ArchFlag)
2564  *ArchFlag = "ppc64";
2565  return Triple("ppc64-apple-darwin");
2566  default:
2567  return Triple();
2568  }
2569  default:
2570  return Triple();
2571  }
2572 }
2573 
2576 }
2577 
2579  return StringSwitch<bool>(ArchFlag)
2580  .Case("i386", true)
2581  .Case("x86_64", true)
2582  .Case("x86_64h", true)
2583  .Case("armv4t", true)
2584  .Case("arm", true)
2585  .Case("armv5e", true)
2586  .Case("armv6", true)
2587  .Case("armv6m", true)
2588  .Case("armv7", true)
2589  .Case("armv7em", true)
2590  .Case("armv7k", true)
2591  .Case("armv7m", true)
2592  .Case("armv7s", true)
2593  .Case("arm64", true)
2594  .Case("ppc", true)
2595  .Case("ppc64", true)
2596  .Default(false);
2597 }
2598 
2600  return getArch(getCPUType(*this));
2601 }
2602 
2603 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2604  return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2605 }
2606 
2608  DataRefImpl DRI;
2609  DRI.d.a = Index;
2610  return section_rel_begin(DRI);
2611 }
2612 
2614  DataRefImpl DRI;
2615  DRI.d.a = Index;
2616  return section_rel_end(DRI);
2617 }
2618 
2620  DataRefImpl DRI;
2621  if (!DataInCodeLoadCmd)
2622  return dice_iterator(DiceRef(DRI, this));
2623 
2624  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2625  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2626  return dice_iterator(DiceRef(DRI, this));
2627 }
2628 
2630  DataRefImpl DRI;
2631  if (!DataInCodeLoadCmd)
2632  return dice_iterator(DiceRef(DRI, this));
2633 
2634  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2635  unsigned Offset = DicLC.dataoff + DicLC.datasize;
2636  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2637  return dice_iterator(DiceRef(DRI, this));
2638 }
2639 
2641  ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {}
2642 
2643 void ExportEntry::moveToFirst() {
2644  ErrorAsOutParameter ErrAsOutParam(E);
2645  pushNode(0);
2646  if (*E)
2647  return;
2648  pushDownUntilBottom();
2649 }
2650 
2651 void ExportEntry::moveToEnd() {
2652  Stack.clear();
2653  Done = true;
2654 }
2655 
2657  // Common case, one at end, other iterating from begin.
2658  if (Done || Other.Done)
2659  return (Done == Other.Done);
2660  // Not equal if different stack sizes.
2661  if (Stack.size() != Other.Stack.size())
2662  return false;
2663  // Not equal if different cumulative strings.
2664  if (!CumulativeString.equals(Other.CumulativeString))
2665  return false;
2666  // Equal if all nodes in both stacks match.
2667  for (unsigned i=0; i < Stack.size(); ++i) {
2668  if (Stack[i].Start != Other.Stack[i].Start)
2669  return false;
2670  }
2671  return true;
2672 }
2673 
2674 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) {
2675  unsigned Count;
2676  uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error);
2677  Ptr += Count;
2678  if (Ptr > Trie.end())
2679  Ptr = Trie.end();
2680  return Result;
2681 }
2682 
2684  return CumulativeString;
2685 }
2686 
2687 uint64_t ExportEntry::flags() const {
2688  return Stack.back().Flags;
2689 }
2690 
2691 uint64_t ExportEntry::address() const {
2692  return Stack.back().Address;
2693 }
2694 
2695 uint64_t ExportEntry::other() const {
2696  return Stack.back().Other;
2697 }
2698 
2700  const char* ImportName = Stack.back().ImportName;
2701  if (ImportName)
2702  return StringRef(ImportName);
2703  return StringRef();
2704 }
2705 
2707  return Stack.back().Start - Trie.begin();
2708 }
2709 
2710 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2711  : Start(Ptr), Current(Ptr) {}
2712 
2713 void ExportEntry::pushNode(uint64_t offset) {
2714  ErrorAsOutParameter ErrAsOutParam(E);
2715  const uint8_t *Ptr = Trie.begin() + offset;
2716  NodeState State(Ptr);
2717  const char *error;
2718  uint64_t ExportInfoSize = readULEB128(State.Current, &error);
2719  if (error) {
2720  *E = malformedError("export info size " + Twine(error) +
2721  " in export trie data at node: 0x" +
2722  Twine::utohexstr(offset));
2723  moveToEnd();
2724  return;
2725  }
2726  State.IsExportNode = (ExportInfoSize != 0);
2727  const uint8_t* Children = State.Current + ExportInfoSize;
2728  if (Children > Trie.end()) {
2729  *E = malformedError(
2730  "export info size: 0x" + Twine::utohexstr(ExportInfoSize) +
2731  " in export trie data at node: 0x" + Twine::utohexstr(offset) +
2732  " too big and extends past end of trie data");
2733  moveToEnd();
2734  return;
2735  }
2736  if (State.IsExportNode) {
2737  const uint8_t *ExportStart = State.Current;
2738  State.Flags = readULEB128(State.Current, &error);
2739  if (error) {
2740  *E = malformedError("flags " + Twine(error) +
2741  " in export trie data at node: 0x" +
2742  Twine::utohexstr(offset));
2743  moveToEnd();
2744  return;
2745  }
2746  uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK;
2747  if (State.Flags != 0 &&
2751  *E = malformedError(
2752  "unsupported exported symbol kind: " + Twine((int)Kind) +
2753  " in flags: 0x" + Twine::utohexstr(State.Flags) +
2754  " in export trie data at node: 0x" + Twine::utohexstr(offset));
2755  moveToEnd();
2756  return;
2757  }
2758  if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2759  State.Address = 0;
2760  State.Other = readULEB128(State.Current, &error); // dylib ordinal
2761  if (error) {
2762  *E = malformedError("dylib ordinal of re-export " + Twine(error) +
2763  " in export trie data at node: 0x" +
2764  Twine::utohexstr(offset));
2765  moveToEnd();
2766  return;
2767  }
2768  if (O != nullptr) {
2769  if (State.Other > O->getLibraryCount()) {
2770  *E = malformedError(
2771  "bad library ordinal: " + Twine((int)State.Other) + " (max " +
2772  Twine((int)O->getLibraryCount()) +
2773  ") in export trie data at node: 0x" + Twine::utohexstr(offset));
2774  moveToEnd();
2775  return;
2776  }
2777  }
2778  State.ImportName = reinterpret_cast<const char*>(State.Current);
2779  if (*State.ImportName == '\0') {
2780  State.Current++;
2781  } else {
2782  const uint8_t *End = State.Current + 1;
2783  if (End >= Trie.end()) {
2784  *E = malformedError("import name of re-export in export trie data at "
2785  "node: 0x" +
2786  Twine::utohexstr(offset) +
2787  " starts past end of trie data");
2788  moveToEnd();
2789  return;
2790  }
2791  while(*End != '\0' && End < Trie.end())
2792  End++;
2793  if (*End != '\0') {
2794  *E = malformedError("import name of re-export in export trie data at "
2795  "node: 0x" +
2796  Twine::utohexstr(offset) +
2797  " extends past end of trie data");
2798  moveToEnd();
2799  return;
2800  }
2801  State.Current = End + 1;
2802  }
2803  } else {
2804  State.Address = readULEB128(State.Current, &error);
2805  if (error) {
2806  *E = malformedError("address " + Twine(error) +
2807  " in export trie data at node: 0x" +
2808  Twine::utohexstr(offset));
2809  moveToEnd();
2810  return;
2811  }
2813  State.Other = readULEB128(State.Current, &error);
2814  if (error) {
2815  *E = malformedError("resolver of stub and resolver " + Twine(error) +
2816  " in export trie data at node: 0x" +
2817  Twine::utohexstr(offset));
2818  moveToEnd();
2819  return;
2820  }
2821  }
2822  }
2823  if(ExportStart + ExportInfoSize != State.Current) {
2824  *E = malformedError(
2825  "inconsistant export info size: 0x" +
2826  Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
2827  Twine::utohexstr(State.Current - ExportStart) +
2828  " in export trie data at node: 0x" + Twine::utohexstr(offset));
2829  moveToEnd();
2830  return;
2831  }
2832  }
2833  State.ChildCount = *Children;
2834  if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
2835  *E = malformedError("byte for count of childern in export trie data at "
2836  "node: 0x" +
2837  Twine::utohexstr(offset) +
2838  " extends past end of trie data");
2839  moveToEnd();
2840  return;
2841  }
2842  State.Current = Children + 1;
2843  State.NextChildIndex = 0;
2844  State.ParentStringLength = CumulativeString.size();
2845  Stack.push_back(State);
2846 }
2847 
2848 void ExportEntry::pushDownUntilBottom() {
2849  ErrorAsOutParameter ErrAsOutParam(E);
2850  const char *error;
2851  while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2852  NodeState &Top = Stack.back();
2853  CumulativeString.resize(Top.ParentStringLength);
2854  for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
2855  char C = *Top.Current;
2856  CumulativeString.push_back(C);
2857  }
2858  if (Top.Current >= Trie.end()) {
2859  *E = malformedError("edge sub-string in export trie data at node: 0x" +
2860  Twine::utohexstr(Top.Start - Trie.begin()) +
2861  " for child #" + Twine((int)Top.NextChildIndex) +
2862  " extends past end of trie data");
2863  moveToEnd();
2864  return;
2865  }
2866  Top.Current += 1;
2867  uint64_t childNodeIndex = readULEB128(Top.Current, &error);
2868  if (error) {
2869  *E = malformedError("child node offset " + Twine(error) +
2870  " in export trie data at node: 0x" +
2871  Twine::utohexstr(Top.Start - Trie.begin()));
2872  moveToEnd();
2873  return;
2874  }
2875  for (const NodeState &node : nodes()) {
2876  if (node.Start == Trie.begin() + childNodeIndex){
2877  *E = malformedError("loop in childern in export trie data at node: 0x" +
2878  Twine::utohexstr(Top.Start - Trie.begin()) +
2879  " back to node: 0x" +
2880  Twine::utohexstr(childNodeIndex));
2881  moveToEnd();
2882  return;
2883  }
2884  }
2885  Top.NextChildIndex += 1;
2886  pushNode(childNodeIndex);
2887  if (*E)
2888  return;
2889  }
2890  if (!Stack.back().IsExportNode) {
2891  *E = malformedError("node is not an export node in export trie data at "
2892  "node: 0x" +
2893  Twine::utohexstr(Stack.back().Start - Trie.begin()));
2894  moveToEnd();
2895  return;
2896  }
2897 }
2898 
2899 // We have a trie data structure and need a way to walk it that is compatible
2900 // with the C++ iterator model. The solution is a non-recursive depth first
2901 // traversal where the iterator contains a stack of parent nodes along with a
2902 // string that is the accumulation of all edge strings along the parent chain
2903 // to this point.
2904 //
2905 // There is one "export" node for each exported symbol. But because some
2906 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
2907 // node may have child nodes too.
2908 //
2909 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
2910 // child until hitting a node with no children (which is an export node or
2911 // else the trie is malformed). On the way down, each node is pushed on the
2912 // stack ivar. If there is no more ways down, it pops up one and tries to go
2913 // down a sibling path until a childless node is reached.
2915  assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
2916  if (!Stack.back().IsExportNode) {
2917  *E = malformedError("node is not an export node in export trie data at "
2918  "node: 0x" +
2919  Twine::utohexstr(Stack.back().Start - Trie.begin()));
2920  moveToEnd();
2921  return;
2922  }
2923 
2924  Stack.pop_back();
2925  while (!Stack.empty()) {
2926  NodeState &Top = Stack.back();
2927  if (Top.NextChildIndex < Top.ChildCount) {
2928  pushDownUntilBottom();
2929  // Now at the next export node.
2930  return;
2931  } else {
2932  if (Top.IsExportNode) {
2933  // This node has no children but is itself an export node.
2934  CumulativeString.resize(Top.ParentStringLength);
2935  return;
2936  }
2937  Stack.pop_back();
2938  }
2939  }
2940  Done = true;
2941 }
2942 
2945  const MachOObjectFile *O) {
2946  ExportEntry Start(&E, O, Trie);
2947  if (Trie.empty())
2948  Start.moveToEnd();
2949  else
2950  Start.moveToFirst();
2951 
2952  ExportEntry Finish(&E, O, Trie);
2953  Finish.moveToEnd();
2954 
2955  return make_range(export_iterator(Start), export_iterator(Finish));
2956 }
2957 
2959  return exports(Err, getDyldInfoExportsTrie(), this);
2960 }
2961 
2963  ArrayRef<uint8_t> Bytes, bool is64Bit)
2964  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
2965  PointerSize(is64Bit ? 8 : 4) {}
2966 
2967 void MachORebaseEntry::moveToFirst() {
2968  Ptr = Opcodes.begin();
2969  moveNext();
2970 }
2971 
2972 void MachORebaseEntry::moveToEnd() {
2973  Ptr = Opcodes.end();
2974  RemainingLoopCount = 0;
2975  Done = true;
2976 }
2977 
2979  ErrorAsOutParameter ErrAsOutParam(E);
2980  // If in the middle of some loop, move to next rebasing in loop.
2981  SegmentOffset += AdvanceAmount;
2982  if (RemainingLoopCount) {
2983  --RemainingLoopCount;
2984  return;
2985  }
2986  // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
2987  // pointer size. Therefore it is possible to reach the end without ever having
2988  // seen REBASE_OPCODE_DONE.
2989  if (Ptr == Opcodes.end()) {
2990  Done = true;
2991  return;
2992  }
2993  bool More = true;
2994  while (More) {
2995  // Parse next opcode and set up next loop.
2996  const uint8_t *OpcodeStart = Ptr;
2997  uint8_t Byte = *Ptr++;
2998  uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
2999  uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3000  uint32_t Count, Skip;
3001  const char *error = nullptr;
3002  switch (Opcode) {
3004  More = false;
3005  Done = true;
3006  moveToEnd();
3007  DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3008  break;
3010  RebaseType = ImmValue;
3012  *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3013  Twine((int)RebaseType) + " for opcode at: 0x" +
3014  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3015  moveToEnd();
3016  return;
3017  }
3019  "mach-o-rebase",
3020  dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3021  << "RebaseType=" << (int) RebaseType << "\n");
3022  break;
3024  SegmentIndex = ImmValue;
3025  SegmentOffset = readULEB128(&error);
3026  if (error) {
3027  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3028  Twine(error) + " for opcode at: 0x" +
3029  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3030  moveToEnd();
3031  return;
3032  }
3033  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3034  true);
3035  if (error) {
3036  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3037  Twine(error) + " for opcode at: 0x" +
3038  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3039  moveToEnd();
3040  return;
3041  }
3043  "mach-o-rebase",
3044  dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3045  << "SegmentIndex=" << SegmentIndex << ", "
3046  << format("SegmentOffset=0x%06X", SegmentOffset)
3047  << "\n");
3048  break;
3050  SegmentOffset += readULEB128(&error);
3051  if (error) {
3052  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3053  " for opcode at: 0x" +
3054  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3055  moveToEnd();
3056  return;
3057  }
3058  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3059  true);
3060  if (error) {
3061  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3062  " for opcode at: 0x" +
3063  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3064  moveToEnd();
3065  return;
3066  }
3067  DEBUG_WITH_TYPE("mach-o-rebase",
3068  dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3069  << format("SegmentOffset=0x%06X",
3070  SegmentOffset) << "\n");
3071  break;
3073  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3074  true);
3075  if (error) {
3076  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3077  Twine(error) + " for opcode at: 0x" +
3078  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3079  moveToEnd();
3080  return;
3081  }
3082  SegmentOffset += ImmValue * PointerSize;
3083  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3084  false);
3085  if (error) {
3086  *E =
3087  malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED "
3088  " (after adding immediate times the pointer size) " +
3089  Twine(error) + " for opcode at: 0x" +
3090  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3091  moveToEnd();
3092  return;
3093  }
3094  DEBUG_WITH_TYPE("mach-o-rebase",
3095  dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3096  << format("SegmentOffset=0x%06X",
3097  SegmentOffset) << "\n");
3098  break;
3100  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3101  true);
3102  if (error) {
3103  *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3104  Twine(error) + " for opcode at: 0x" +
3105  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3106  moveToEnd();
3107  return;
3108  }
3109  AdvanceAmount = PointerSize;
3110  Skip = 0;
3111  Count = ImmValue;
3112  if (ImmValue != 0)
3113  RemainingLoopCount = ImmValue - 1;
3114  else
3115  RemainingLoopCount = 0;
3116  error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3117  SegmentIndex, SegmentOffset);
3118  if (error) {
3119  *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3120  Twine(error) + " for opcode at: 0x" +
3121  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3122  moveToEnd();
3123  return;
3124  }
3126  "mach-o-rebase",
3127  dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3128  << format("SegmentOffset=0x%06X", SegmentOffset)
3129  << ", AdvanceAmount=" << AdvanceAmount
3130  << ", RemainingLoopCount=" << RemainingLoopCount
3131  << "\n");
3132  return;
3134  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3135  true);
3136  if (error) {
3137  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3138  Twine(error) + " for opcode at: 0x" +
3139  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3140  moveToEnd();
3141  return;
3142  }
3143  AdvanceAmount = PointerSize;
3144  Skip = 0;
3145  Count = readULEB128(&error);
3146  if (error) {
3147  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3148  Twine(error) + " for opcode at: 0x" +
3149  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3150  moveToEnd();
3151  return;
3152  }
3153  if (Count != 0)
3154  RemainingLoopCount = Count - 1;
3155  else
3156  RemainingLoopCount = 0;
3157  error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3158  SegmentIndex, SegmentOffset);
3159  if (error) {
3160  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3161  Twine(error) + " for opcode at: 0x" +
3162  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3163  moveToEnd();
3164  return;
3165  }
3167  "mach-o-rebase",
3168  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3169  << format("SegmentOffset=0x%06X", SegmentOffset)
3170  << ", AdvanceAmount=" << AdvanceAmount
3171  << ", RemainingLoopCount=" << RemainingLoopCount
3172  << "\n");
3173  return;
3175  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3176  true);
3177  if (error) {
3178  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3179  Twine(error) + " for opcode at: 0x" +
3180  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3181  moveToEnd();
3182  return;
3183  }
3184  Skip = readULEB128(&error);
3185  if (error) {
3186  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3187  Twine(error) + " for opcode at: 0x" +
3188  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3189  moveToEnd();
3190  return;
3191  }
3192  AdvanceAmount = Skip + PointerSize;
3193  Count = 1;
3194  RemainingLoopCount = 0;
3195  error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3196  SegmentIndex, SegmentOffset);
3197  if (error) {
3198  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3199  Twine(error) + " for opcode at: 0x" +
3200  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3201  moveToEnd();
3202  return;
3203  }
3205  "mach-o-rebase",
3206  dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3207  << format("SegmentOffset=0x%06X", SegmentOffset)
3208  << ", AdvanceAmount=" << AdvanceAmount
3209  << ", RemainingLoopCount=" << RemainingLoopCount
3210  << "\n");
3211  return;
3213  error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3214  true);
3215  if (error) {
3216  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3217  "ULEB " +
3218  Twine(error) + " for opcode at: 0x" +
3219  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3220  moveToEnd();
3221  return;
3222  }
3223  Count = readULEB128(&error);
3224  if (error) {
3225  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3226  "ULEB " +
3227  Twine(error) + " for opcode at: 0x" +
3228  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3229  moveToEnd();
3230  return;
3231  }
3232  if (Count != 0)
3233  RemainingLoopCount = Count - 1;
3234  else
3235  RemainingLoopCount = 0;
3236  Skip = readULEB128(&error);
3237  if (error) {
3238  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3239  "ULEB " +
3240  Twine(error) + " for opcode at: 0x" +
3241  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3242  moveToEnd();
3243  return;
3244  }
3245  AdvanceAmount = Skip + PointerSize;
3246 
3247  error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3248  SegmentIndex, SegmentOffset);
3249  if (error) {
3250  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3251  "ULEB " +
3252  Twine(error) + " for opcode at: 0x" +
3253  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3254  moveToEnd();
3255  return;
3256  }
3258  "mach-o-rebase",
3259  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3260  << format("SegmentOffset=0x%06X", SegmentOffset)
3261  << ", AdvanceAmount=" << AdvanceAmount
3262  << ", RemainingLoopCount=" << RemainingLoopCount
3263  << "\n");
3264  return;
3265  default:
3266  *E = malformedError("bad rebase info (bad opcode value 0x" +
3267  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3268  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3269  moveToEnd();
3270  return;
3271  }
3272  }
3273 }
3274 
3275 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3276  unsigned Count;
3277  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3278  Ptr += Count;
3279  if (Ptr > Opcodes.end())
3280  Ptr = Opcodes.end();
3281  return Result;
3282 }
3283 
3284 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3285 
3287 
3289  switch (RebaseType) {
3291  return "pointer";
3293  return "text abs32";
3295  return "text rel32";
3296  }
3297  return "unknown";
3298 }
3299 
3300 // For use with the SegIndex of a checked Mach-O Rebase entry
3301 // to get the segment name.
3303  return O->BindRebaseSegmentName(SegmentIndex);
3304 }
3305 
3306 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3307 // to get the section name.
3309  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3310 }
3311 
3312 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3313 // to get the address.
3314 uint64_t MachORebaseEntry::address() const {
3315  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3316 }
3317 
3319 #ifdef EXPENSIVE_CHECKS
3320  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3321 #else
3322  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3323 #endif
3324  return (Ptr == Other.Ptr) &&
3325  (RemainingLoopCount == Other.RemainingLoopCount) &&
3326  (Done == Other.Done);
3327 }
3328 
3331  ArrayRef<uint8_t> Opcodes, bool is64) {
3332  if (O->BindRebaseSectionTable == nullptr)
3333  O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
3334  MachORebaseEntry Start(&Err, O, Opcodes, is64);
3335  Start.moveToFirst();
3336 
3337  MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3338  Finish.moveToEnd();
3339 
3340  return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3341 }
3342 
3344  return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3345 }
3346 
3348  ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3349  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3350  PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3351 
3352 void MachOBindEntry::moveToFirst() {
3353  Ptr = Opcodes.begin();
3354  moveNext();
3355 }
3356 
3357 void MachOBindEntry::moveToEnd() {
3358  Ptr = Opcodes.end();
3359  RemainingLoopCount = 0;
3360  Done = true;
3361 }
3362 
3364  ErrorAsOutParameter ErrAsOutParam(E);
3365  // If in the middle of some loop, move to next binding in loop.
3366  SegmentOffset += AdvanceAmount;
3367  if (RemainingLoopCount) {
3368  --RemainingLoopCount;
3369  return;
3370  }
3371  // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3372  // pointer size. Therefore it is possible to reach the end without ever having
3373  // seen BIND_OPCODE_DONE.
3374  if (Ptr == Opcodes.end()) {
3375  Done = true;
3376  return;
3377  }
3378  bool More = true;
3379  while (More) {
3380  // Parse next opcode and set up next loop.
3381  const uint8_t *OpcodeStart = Ptr;
3382  uint8_t Byte = *Ptr++;
3383  uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3384  uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3385  int8_t SignExtended;
3386  const uint8_t *SymStart;
3387  uint32_t Count, Skip;
3388  const char *error = nullptr;
3389  switch (Opcode) {
3391  if (TableKind == Kind::Lazy) {
3392  // Lazying bindings have a DONE opcode between entries. Need to ignore
3393  // it to advance to next entry. But need not if this is last entry.
3394  bool NotLastEntry = false;
3395  for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3396  if (*P) {
3397  NotLastEntry = true;
3398  }
3399  }
3400  if (NotLastEntry)
3401  break;
3402  }
3403  More = false;
3404  moveToEnd();
3405  DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3406  break;
3408  if (TableKind == Kind::Weak) {
3409  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3410  "weak bind table for opcode at: 0x" +
3411  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3412  moveToEnd();
3413  return;
3414  }
3415  Ordinal = ImmValue;
3416  LibraryOrdinalSet = true;
3417  if (ImmValue > O->getLibraryCount()) {
3418  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3419  "library ordinal: " +
3420  Twine((int)ImmValue) + " (max " +
3421  Twine((int)O->getLibraryCount()) +
3422  ") for opcode at: 0x" +
3423  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3424  moveToEnd();
3425  return;
3426  }
3428  "mach-o-bind",
3429  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3430  << "Ordinal=" << Ordinal << "\n");
3431  break;
3433  if (TableKind == Kind::Weak) {
3434  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3435  "weak bind table for opcode at: 0x" +
3436  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3437  moveToEnd();
3438  return;
3439  }
3440  Ordinal = readULEB128(&error);
3441  LibraryOrdinalSet = true;
3442  if (error) {
3443  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3444  Twine(error) + " for opcode at: 0x" +
3445  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3446  moveToEnd();
3447  return;
3448  }
3449  if (Ordinal > (int)O->getLibraryCount()) {
3450  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3451  "library ordinal: " +
3452  Twine((int)Ordinal) + " (max " +
3453  Twine((int)O->getLibraryCount()) +
3454  ") for opcode at: 0x" +
3455  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3456  moveToEnd();
3457  return;
3458  }
3460  "mach-o-bind",
3461  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3462  << "Ordinal=" << Ordinal << "\n");
3463  break;
3465  if (TableKind == Kind::Weak) {
3466  *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3467  "weak bind table for opcode at: 0x" +
3468  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3469  moveToEnd();
3470  return;
3471  }
3472  if (ImmValue) {
3473  SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3474  Ordinal = SignExtended;
3475  if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3476  *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3477  "special ordinal: " +
3478  Twine((int)Ordinal) + " for opcode at: 0x" +
3479  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3480  moveToEnd();
3481  return;
3482  }
3483  } else
3484  Ordinal = 0;
3485  LibraryOrdinalSet = true;
3487  "mach-o-bind",
3488  dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3489  << "Ordinal=" << Ordinal << "\n");
3490  break;
3492  Flags = ImmValue;
3493  SymStart = Ptr;
3494  while (*Ptr && (Ptr < Opcodes.end())) {
3495  ++Ptr;
3496  }
3497  if (Ptr == Opcodes.end()) {
3498  *E = malformedError(
3499  "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3500  "symbol name extends past opcodes for opcode at: 0x" +
3501  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3502  moveToEnd();
3503  return;
3504  }
3505  SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3506  Ptr-SymStart);
3507  ++Ptr;
3509  "mach-o-bind",
3510  dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3511  << "SymbolName=" << SymbolName << "\n");
3512  if (TableKind == Kind::Weak) {
3514  return;
3515  }
3516  break;
3518  BindType = ImmValue;
3519  if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3520  *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3521  Twine((int)ImmValue) + " for opcode at: 0x" +
3522  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3523  moveToEnd();
3524  return;
3525  }
3527  "mach-o-bind",
3528  dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3529  << "BindType=" << (int)BindType << "\n");
3530  break;
3532  Addend = readSLEB128(&error);
3533  if (error) {
3534  *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3535  " for opcode at: 0x" +
3536  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3537  moveToEnd();
3538  return;
3539  }
3541  "mach-o-bind",
3542  dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3543  << "Addend=" << Addend << "\n");
3544  break;
3546  SegmentIndex = ImmValue;
3547  SegmentOffset = readULEB128(&error);
3548  if (error) {
3549  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3550  Twine(error) + " for opcode at: 0x" +
3551  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3552  moveToEnd();
3553  return;
3554  }
3555  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3556  if (error) {
3557  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3558  Twine(error) + " for opcode at: 0x" +
3559  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3560  moveToEnd();
3561  return;
3562  }
3564  "mach-o-bind",
3565  dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3566  << "SegmentIndex=" << SegmentIndex << ", "
3567  << format("SegmentOffset=0x%06X", SegmentOffset)
3568  << "\n");
3569  break;
3571  SegmentOffset += readULEB128(&error);
3572  if (error) {
3573  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3574  " for opcode at: 0x" +
3575  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3576  moveToEnd();
3577  return;
3578  }
3579  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3580  if (error) {
3581  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3582  " for opcode at: 0x" +
3583  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3584  moveToEnd();
3585  return;
3586  }
3587  DEBUG_WITH_TYPE("mach-o-bind",
3588  dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3589  << format("SegmentOffset=0x%06X",
3590  SegmentOffset) << "\n");
3591  break;
3593  AdvanceAmount = PointerSize;
3594  RemainingLoopCount = 0;
3595  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3596  if (error) {
3597  *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3598  " for opcode at: 0x" +
3599  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3600  moveToEnd();
3601  return;
3602  }
3603  if (SymbolName == StringRef()) {
3604  *E = malformedError(
3605  "for BIND_OPCODE_DO_BIND missing preceding "
3606  "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3607  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3608  moveToEnd();
3609  return;
3610  }
3611  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3612  *E =
3613  malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3614  "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3615  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3616  moveToEnd();
3617  return;
3618  }
3619  DEBUG_WITH_TYPE("mach-o-bind",
3620  dbgs() << "BIND_OPCODE_DO_BIND: "
3621  << format("SegmentOffset=0x%06X",
3622  SegmentOffset) << "\n");
3623  return;
3625  if (TableKind == Kind::Lazy) {
3626  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3627  "lazy bind table for opcode at: 0x" +
3628  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3629  moveToEnd();
3630  return;
3631  }
3632  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3633  if (error) {
3634  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3635  Twine(error) + " for opcode at: 0x" +
3636  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3637  moveToEnd();
3638  return;
3639  }
3640  if (SymbolName == StringRef()) {
3641  *E = malformedError(
3642  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3643  "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3644  "at: 0x" +
3645  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3646  moveToEnd();
3647  return;
3648  }
3649  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3650  *E = malformedError(
3651  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3652  "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3653  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3654  moveToEnd();
3655  return;
3656  }
3657  AdvanceAmount = readULEB128(&error) + PointerSize;
3658  if (error) {
3659  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3660  Twine(error) + " for opcode at: 0x" +
3661  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3662  moveToEnd();
3663  return;
3664  }
3665  // Note, this is not really an error until the next bind but make no sense
3666  // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3667  // bind operation.
3668  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
3669  AdvanceAmount, false);
3670  if (error) {
3671  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3672  "ULEB) " +
3673  Twine(error) + " for opcode at: 0x" +
3674  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3675  moveToEnd();
3676  return;
3677  }
3678  RemainingLoopCount = 0;
3680  "mach-o-bind",
3681  dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3682  << format("SegmentOffset=0x%06X", SegmentOffset)
3683  << ", AdvanceAmount=" << AdvanceAmount
3684  << ", RemainingLoopCount=" << RemainingLoopCount
3685  << "\n");
3686  return;
3688  if (TableKind == Kind::Lazy) {
3689  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3690  "allowed in lazy bind table for opcode at: 0x" +
3691  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3692  moveToEnd();
3693  return;
3694  }
3695  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3696  if (error) {
3697  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
3698  Twine(error) + " for opcode at: 0x" +
3699  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3700  moveToEnd();
3701  return;
3702  }
3703  if (SymbolName == StringRef()) {
3704  *E = malformedError(
3705  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3706  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3707  "opcode at: 0x" +
3708  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3709  moveToEnd();
3710  return;
3711  }
3712  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3713  *E = malformedError(
3714  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3715  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3716  "at: 0x" +
3717  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3718  moveToEnd();
3719  return;
3720  }
3721  AdvanceAmount = ImmValue * PointerSize + PointerSize;
3722  RemainingLoopCount = 0;
3723  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
3724  AdvanceAmount, false);
3725  if (error) {
3726  *E =
3727  malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3728  " (after adding immediate times the pointer size) " +
3729  Twine(error) + " for opcode at: 0x" +
3730  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3731  moveToEnd();
3732  return;
3733  }
3734  DEBUG_WITH_TYPE("mach-o-bind",
3735  dbgs()
3736  << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
3737  << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
3738  return;
3740  if (TableKind == Kind::Lazy) {
3741  *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
3742  "allowed in lazy bind table for opcode at: 0x" +
3743  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3744  moveToEnd();
3745  return;
3746  }
3747  Count = readULEB128(&error);
3748  if (Count != 0)
3749  RemainingLoopCount = Count - 1;
3750  else
3751  RemainingLoopCount = 0;
3752  if (error) {
3753  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3754  " (count value) " +
3755  Twine(error) + " for opcode at: 0x" +
3756  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3757  moveToEnd();
3758  return;
3759  }
3760  Skip = readULEB128(&error);
3761  AdvanceAmount = Skip + PointerSize;
3762  if (error) {
3763  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3764  " (skip value) " +
3765  Twine(error) + " for opcode at: 0x" +
3766  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3767  moveToEnd();
3768  return;
3769  }
3770  error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3771  if (error) {
3772  *E =
3773  malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3774  Twine(error) + " for opcode at: 0x" +
3775  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3776  moveToEnd();
3777  return;
3778  }
3779  if (SymbolName == StringRef()) {
3780  *E = malformedError(
3781  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3782  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3783  "opcode at: 0x" +
3784  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3785  moveToEnd();
3786  return;
3787  }
3788  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3789  *E = malformedError(
3790  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3791  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3792  "at: 0x" +
3793  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3794  moveToEnd();
3795  return;
3796  }
3797  error = O->BindEntryCheckCountAndSkip(Count, Skip, PointerSize,
3798  SegmentIndex, SegmentOffset);
3799  if (error) {
3800  *E =
3801  malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3802  Twine(error) + " for opcode at: 0x" +
3803  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3804  moveToEnd();
3805  return;
3806  }
3808  "mach-o-bind",
3809  dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
3810  << format("SegmentOffset=0x%06X", SegmentOffset)
3811  << ", AdvanceAmount=" << AdvanceAmount
3812  << ", RemainingLoopCount=" << RemainingLoopCount
3813  << "\n");
3814  return;
3815  default:
3816  *E = malformedError("bad bind info (bad opcode value 0x" +
3817  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3818  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3819  moveToEnd();
3820  return;
3821  }
3822  }
3823 }
3824 
3825 uint64_t MachOBindEntry::readULEB128(const char **error) {
3826  unsigned Count;
3827  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3828  Ptr += Count;
3829  if (Ptr > Opcodes.end())
3830  Ptr = Opcodes.end();
3831  return Result;
3832 }
3833 
3834 int64_t MachOBindEntry::readSLEB128(const char **error) {
3835  unsigned Count;
3836  int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
3837  Ptr += Count;
3838  if (Ptr > Opcodes.end())
3839  Ptr = Opcodes.end();
3840  return Result;
3841 }
3842 
3843 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
3844 
3845 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
3846 
3848  switch (BindType) {
3850  return "pointer";
3852  return "text abs32";
3854  return "text rel32";
3855  }
3856  return "unknown";
3857 }
3858 
3860 
3861 int64_t MachOBindEntry::addend() const { return Addend; }
3862 
3863 uint32_t MachOBindEntry::flags() const { return Flags; }
3864 
3865 int MachOBindEntry::ordinal() const { return Ordinal; }
3866 
3867 // For use with the SegIndex of a checked Mach-O Bind entry
3868 // to get the segment name.
3870  return O->BindRebaseSegmentName(SegmentIndex);
3871 }
3872 
3873 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3874 // to get the section name.
3876  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3877 }
3878 
3879 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3880 // to get the address.
3881 uint64_t MachOBindEntry::address() const {
3882  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3883 }
3884 
3886 #ifdef EXPENSIVE_CHECKS
3887  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3888 #else
3889  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3890 #endif
3891  return (Ptr == Other.Ptr) &&
3892  (RemainingLoopCount == Other.RemainingLoopCount) &&
3893  (Done == Other.Done);
3894 }
3895 
3896 // Build table of sections so SegIndex/SegOffset pairs can be translated.
3898  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
3899  StringRef CurSegName;
3900  uint64_t CurSegAddress;
3901  for (const SectionRef &Section : Obj->sections()) {
3902  SectionInfo Info;
3903  Section.getName(Info.SectionName);
3904  Info.Address = Section.getAddress();
3905  Info.Size = Section.getSize();
3906  Info.SegmentName =
3907  Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
3908  if (!Info.SegmentName.equals(CurSegName)) {
3909  ++CurSegIndex;
3910  CurSegName = Info.SegmentName;
3911  CurSegAddress = Info.Address;
3912  }
3913  Info.SegmentIndex = CurSegIndex - 1;
3914  Info.OffsetInSegment = Info.Address - CurSegAddress;
3915  Info.SegmentStartAddress = CurSegAddress;
3916  Sections.push_back(Info);
3917  }
3918  MaxSegIndex = CurSegIndex;
3919 }
3920 
3921 // For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
3922 // validate a MachOBindEntry or MachORebaseEntry.
3923 const char * BindRebaseSegInfo::checkSegAndOffset(int32_t SegIndex,
3924  uint64_t SegOffset,
3925  bool endInvalid) {
3926  if (SegIndex == -1)
3927  return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
3928  if (SegIndex >= MaxSegIndex)
3929  return "bad segIndex (too large)";
3930  for (const SectionInfo &SI : Sections) {
3931  if (SI.SegmentIndex != SegIndex)
3932  continue;
3933  if (SI.OffsetInSegment > SegOffset)
3934  continue;
3935  if (SegOffset > (SI.OffsetInSegment + SI.Size))
3936  continue;
3937  if (endInvalid && SegOffset >= (SI.OffsetInSegment + SI.Size))
3938  continue;
3939  return nullptr;
3940  }
3941  return "bad segOffset, too large";
3942 }
3943 
3944 // For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
3945 // the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode and for use in
3946 // MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
3947 // REBASE_OPCODE_DO_*_TIMES* opcodes. The SegIndex and SegOffset must have
3948 // been already checked.
3950  uint8_t PointerSize,
3951  int32_t SegIndex,
3952  uint64_t SegOffset) {
3953  const SectionInfo &SI = findSection(SegIndex, SegOffset);
3954  uint64_t addr = SI.SegmentStartAddress + SegOffset;
3955  if (addr >= SI.Address + SI.Size)
3956  return "bad segOffset, too large";
3957  uint64_t i = 0;
3958  if (Count > 1)
3959  i = (Skip + PointerSize) * (Count - 1);
3960  else if (Count == 1)
3961  i = Skip + PointerSize;
3962  if (addr + i >= SI.Address + SI.Size) {
3963  // For rebase opcodes they can step from one section to another.
3964  uint64_t TrailingSegOffset = (addr + i) - SI.SegmentStartAddress;
3965  const char *error = checkSegAndOffset(SegIndex, TrailingSegOffset, false);
3966  if (error)
3967  return "bad count and skip, too large";
3968  }
3969  return nullptr;
3970 }
3971 
3972 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
3973 // to get the segment name.
3975  for (const SectionInfo &SI : Sections) {
3976  if (SI.SegmentIndex == SegIndex)
3977  return SI.SegmentName;
3978  }
3979  llvm_unreachable("invalid SegIndex");
3980 }
3981 
3982 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
3983 // to get the SectionInfo.
3984 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
3985  int32_t SegIndex, uint64_t SegOffset) {
3986  for (const SectionInfo &SI : Sections) {
3987  if (SI.SegmentIndex != SegIndex)
3988  continue;
3989  if (SI.OffsetInSegment > SegOffset)
3990  continue;
3991  if (SegOffset >= (SI.OffsetInSegment + SI.Size))
3992  continue;
3993  return SI;
3994  }
3995  llvm_unreachable("SegIndex and SegOffset not in any section");
3996 }
3997 
3998 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
3999 // entry to get the section name.
4001  uint64_t SegOffset) {
4002  return findSection(SegIndex, SegOffset).SectionName;
4003 }
4004 
4005 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4006 // entry to get the address.
4007 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4008  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4009  return SI.SegmentStartAddress + OffsetInSeg;
4010 }
4011 
4014  ArrayRef<uint8_t> Opcodes, bool is64,
4015  MachOBindEntry::Kind BKind) {
4016  if (O->BindRebaseSectionTable == nullptr)
4017  O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
4018  MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4019  Start.moveToFirst();
4020 
4021  MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4022  Finish.moveToEnd();
4023 
4024  return make_range(bind_iterator(Start), bind_iterator(Finish));
4025 }
4026 
4028  return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4030 }
4031 
4033  return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4035 }
4036 
4038  return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4040 }
4041 
4044  return LoadCommands.begin();
4045 }
4046 
4049  return LoadCommands.end();
4050 }
4051 
4054  return make_range(begin_load_commands(), end_load_commands());
4055 }
4056 
4057 StringRef
4059  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4060  return parseSegmentOrSectionName(Raw.data());
4061 }
4062 
4065  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4066  const section_base *Base =
4067  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4068  return makeArrayRef(Base->sectname);
4069 }
4070 
4073  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4074  const section_base *Base =
4075  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4076  return makeArrayRef(Base->segname);
4077 }
4078 
4079 bool
4081  const {
4082  if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4083  return false;
4085 }
4086 
4088  const MachO::any_relocation_info &RE) const {
4089  if (isLittleEndian())
4090  return RE.r_word1 & 0xffffff;
4091  return RE.r_word1 >> 8;
4092 }
4093 
4095  const MachO::any_relocation_info &RE) const {
4096  if (isLittleEndian())
4097  return (RE.r_word1 >> 27) & 1;
4098  return (RE.r_word1 >> 4) & 1;
4099 }
4100 
4102  const MachO::any_relocation_info &RE) const {
4103  return RE.r_word0 >> 31;
4104 }
4105 
4107  const MachO::any_relocation_info &RE) const {
4108  return RE.r_word1;
4109 }
4110 
4112  const MachO::any_relocation_info &RE) const {
4113  return (RE.r_word0 >> 24) & 0xf;
4114 }
4115 
4117  const MachO::any_relocation_info &RE) const {
4118  if (isRelocationScattered(RE))
4119  return getScatteredRelocationAddress(RE);
4120  return getPlainRelocationAddress(RE);
4121 }
4122 
4124  const MachO::any_relocation_info &RE) const {
4125  if (isRelocationScattered(RE))
4126  return getScatteredRelocationPCRel(RE);
4127  return getPlainRelocationPCRel(*this, RE);
4128 }
4129 
4131  const MachO::any_relocation_info &RE) const {
4132  if (isRelocationScattered(RE))
4133  return getScatteredRelocationLength(RE);
4134  return getPlainRelocationLength(*this, RE);
4135 }
4136 
4137 unsigned
4139  const MachO::any_relocation_info &RE) const {
4140  if (isRelocationScattered(RE))
4141  return getScatteredRelocationType(RE);
4142  return getPlainRelocationType(*this, RE);
4143 }
4144 
4145 SectionRef
4147  const MachO::any_relocation_info &RE) const {
4148  if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4149  return *section_end();
4150  unsigned SecNum = getPlainRelocationSymbolNum(RE);
4151  if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4152  return *section_end();
4153  DataRefImpl DRI;
4154  DRI.d.a = SecNum - 1;
4155  return SectionRef(DRI, this);
4156 }
4157 
4159  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4160  return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4161 }
4162 
4164  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4165  return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4166 }
4167 
4169  unsigned Index) const {
4170  const char *Sec = getSectionPtr(*this, L, Index);
4171  return getStruct<MachO::section>(*this, Sec);
4172 }
4173 
4175  unsigned Index) const {
4176  const char *Sec = getSectionPtr(*this, L, Index);
4177  return getStruct<MachO::section_64>(*this, Sec);
4178 }
4179 
4182  const char *P = reinterpret_cast<const char *>(DRI.p);
4183  return getStruct<MachO::nlist>(*this, P);
4184 }
4185 
4188  const char *P = reinterpret_cast<const char *>(DRI.p);
4189  return getStruct<MachO::nlist_64>(*this, P);
4190 }
4191 
4194  return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4195 }
4196 
4199  return getStruct<MachO::segment_command>(*this, L.Ptr);
4200 }
4201 
4204  return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4205 }
4206 
4209  return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4210 }
4211 
4214  return getStruct<MachO::version_min_command>(*this, L.Ptr);
4215 }
4216 
4219  return getStruct<MachO::note_command>(*this, L.Ptr);
4220 }
4221 
4224  return getStruct<MachO::build_version_command>(*this, L.Ptr);
4225 }
4226 
4229  return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4230 }
4231 
4234  return getStruct<MachO::dylib_command>(*this, L.Ptr);
4235 }
4236 
4239  return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4240 }
4241 
4244  return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4245 }
4246 
4249  return getStruct<MachO::uuid_command>(*this, L.Ptr);
4250 }
4251 
4254  return getStruct<MachO::rpath_command>(*this, L.Ptr);
4255 }
4256 
4259  return getStruct<MachO::source_version_command>(*this, L.Ptr);
4260 }
4261 
4264  return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4265 }
4266 
4269  return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4270 }
4271 
4274  return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4275 }
4276 
4279  return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4280 }
4281 
4284  return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4285 }
4286 
4289  return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4290 }
4291 
4294  return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4295 }
4296 
4299  return getStruct<MachO::routines_command>(*this, L.Ptr);
4300 }
4301 
4304  return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4305 }
4306 
4309  return getStruct<MachO::thread_command>(*this, L.Ptr);
4310 }
4311 
4314  uint32_t Offset;
4315  if (getHeader().filetype == MachO::MH_OBJECT) {
4316  DataRefImpl Sec;
4317  Sec.d.a = Rel.d.a;
4318  if (is64Bit()) {
4319  MachO::section_64 Sect = getSection64(Sec);
4320  Offset = Sect.reloff;
4321  } else {
4322  MachO::section Sect = getSection(Sec);
4323  Offset = Sect.reloff;
4324  }
4325  } else {
4326  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4327  if (Rel.d.a == 0)
4328  Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4329  else
4330  Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4331  }
4332 
4333  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4334  getPtr(*this, Offset)) + Rel.d.b;
4335  return getStruct<MachO::any_relocation_info>(
4336  *this, reinterpret_cast<const char *>(P));
4337 }
4338 
4341  const char *P = reinterpret_cast<const char *>(Rel.p);
4342  return getStruct<MachO::data_in_code_entry>(*this, P);
4343 }
4344 
4346  return Header;
4347 }
4348 
4350  assert(is64Bit());
4351  return Header64;
4352 }
4353 
4355  const MachO::dysymtab_command &DLC,
4356  unsigned Index) const {
4357  uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4358  return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4359 }
4360 
4363  unsigned Index) const {
4364  uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4365  return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4366 }
4367 
4369  if (SymtabLoadCmd)
4370  return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4371 
4372  // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4374  Cmd.cmd = MachO::LC_SYMTAB;
4375  Cmd.cmdsize = sizeof(MachO::symtab_command);
4376  Cmd.symoff = 0;
4377  Cmd.nsyms = 0;
4378  Cmd.stroff = 0;
4379  Cmd.strsize = 0;
4380  return Cmd;
4381 }
4382 
4384  if (DysymtabLoadCmd)
4385  return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4386 
4387  // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4389  Cmd.cmd = MachO::LC_DYSYMTAB;
4390  Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4391  Cmd.ilocalsym = 0;
4392  Cmd.nlocalsym = 0;
4393  Cmd.iextdefsym = 0;
4394  Cmd.nextdefsym = 0;
4395  Cmd.iundefsym = 0;
4396  Cmd.nundefsym = 0;
4397  Cmd.tocoff = 0;
4398  Cmd.ntoc = 0;
4399  Cmd.modtaboff = 0;
4400  Cmd.nmodtab = 0;
4401  Cmd.extrefsymoff = 0;
4402  Cmd.nextrefsyms = 0;
4403  Cmd.indirectsymoff = 0;
4404  Cmd.nindirectsyms = 0;
4405  Cmd.extreloff = 0;
4406  Cmd.nextrel = 0;
4407  Cmd.locreloff = 0;
4408  Cmd.nlocrel = 0;
4409  return Cmd;
4410 }
4411 
4414  if (DataInCodeLoadCmd)
4415  return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4416 
4417  // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4419  Cmd.cmd = MachO::LC_DATA_IN_CODE;
4420  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4421  Cmd.dataoff = 0;
4422  Cmd.datasize = 0;
4423  return Cmd;
4424 }
4425 
4428  if (LinkOptHintsLoadCmd)
4429  return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4430 
4431  // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4432  // fields.
4434  Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4435  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4436  Cmd.dataoff = 0;
4437  Cmd.datasize = 0;
4438  return Cmd;
4439 }
4440 
4442  if (!DyldInfoLoadCmd)
4443  return None;
4444 
4445  MachO::dyld_info_command DyldInfo =
4446  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4447  const uint8_t *Ptr =
4448  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4449  return makeArrayRef(Ptr, DyldInfo.rebase_size);
4450 }
4451 
4453  if (!DyldInfoLoadCmd)
4454  return None;
4455 
4456  MachO::dyld_info_command DyldInfo =
4457  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4458  const uint8_t *Ptr =
4459  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4460  return makeArrayRef(Ptr, DyldInfo.bind_size);
4461 }
4462 
4464  if (!DyldInfoLoadCmd)
4465  return None;
4466 
4467  MachO::dyld_info_command DyldInfo =
4468  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4469  const uint8_t *Ptr =
4470  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4471  return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4472 }
4473 
4475  if (!DyldInfoLoadCmd)
4476  return None;
4477 
4478  MachO::dyld_info_command DyldInfo =
4479  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4480  const uint8_t *Ptr =
4481  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4482  return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4483 }
4484 
4486  if (!DyldInfoLoadCmd)
4487  return None;
4488 
4489  MachO::dyld_info_command DyldInfo =
4490  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4491  const uint8_t *Ptr =
4492  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
4493  return makeArrayRef(Ptr, DyldInfo.export_size);
4494 }
4495 
4497  if (!UuidLoadCmd)
4498  return None;
4499  // Returning a pointer is fine as uuid doesn't need endian swapping.
4500  const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
4501  return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4502 }
4503 
4505  MachO::symtab_command S = getSymtabLoadCommand();
4506  return getData().substr(S.stroff, S.strsize);
4507 }
4508 
4510  return getType() == getMachOType(false, true) ||
4511  getType() == getMachOType(true, true);
4512 }
4513 
4515  SmallVectorImpl<uint64_t> &Out) const {
4516  DataExtractor extractor(ObjectFile::getData(), true, 0);
4517 
4518  uint32_t offset = Index;
4519  uint64_t data = 0;
4520  while (uint64_t delta = extractor.getULEB128(&offset)) {
4521  data += delta;
4522  Out.push_back(data);
4523  }
4524 }
4525 
4527  return getHeader().filetype == MachO::MH_OBJECT;
4528 }
4529 
4532  uint32_t UniversalCputype,
4533  uint32_t UniversalIndex) {
4534  StringRef Magic = Buffer.getBuffer().slice(0, 4);
4535  if (Magic == "\xFE\xED\xFA\xCE")
4536  return MachOObjectFile::create(Buffer, false, false,
4537  UniversalCputype, UniversalIndex);
4538  if (Magic == "\xCE\xFA\xED\xFE")
4539  return MachOObjectFile::create(Buffer, true, false,
4540  UniversalCputype, UniversalIndex);
4541  if (Magic == "\xFE\xED\xFA\xCF")
4542  return MachOObjectFile::create(Buffer, false, true,
4543  UniversalCputype, UniversalIndex);
4544  if (Magic == "\xCF\xFA\xED\xFE")
4545  return MachOObjectFile::create(Buffer, true, true,
4546  UniversalCputype, UniversalIndex);
4547  return make_error<GenericBinaryError>("Unrecognized MachO magic number",
4549 }
4550 
4553  .Case("debug_str_offs", "debug_str_offsets")
4554  .Default(Name);
4555 }
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:245
void swapStruct(fat_header &mh)
Definition: MachO.h:988
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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:236
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
uint32_t size
Definition: MachO.h:555
Error takeError()
Take ownership of the stored error.
Definition: Error.h:537
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
bool operator==(const MachOBindEntry &) const
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
uint8_t GET_COMM_ALIGN(uint16_t n_desc)
Definition: MachO.h:1384
dice_iterator begin_dices() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
bool isSectionBitcode(DataRefImpl Sec) const override
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
uint32_t name
Definition: MachO.h:594
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
uint64_t getSectionAddress(DataRefImpl Sec) const override
static Expected< MachOObjectFile::LoadComma