LLVM  4.0.0
MachOObjectFile.cpp
Go to the documentation of this file.
1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
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/Object/MachO.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
27 #include <cctype>
28 #include <cstring>
29 #include <limits>
30 #include <list>
31 
32 using namespace llvm;
33 using namespace object;
34 
35 namespace {
36  struct section_base {
37  char sectname[16];
38  char segname[16];
39  };
40 }
41 
42 static Error
44  std::string StringMsg = "truncated or malformed object (" + Msg.str() + ")";
45  return make_error<GenericBinaryError>(std::move(StringMsg),
47 }
48 
49 // FIXME: Replace all uses of this function with getStructOrErr.
50 template <typename T>
51 static T getStruct(const MachOObjectFile &O, const char *P) {
52  // Don't read before the beginning or past the end of the file
53  if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
54  report_fatal_error("Malformed MachO file.");
55 
56  T Cmd;
57  memcpy(&Cmd, P, sizeof(T));
58  if (O.isLittleEndian() != sys::IsLittleEndianHost)
59  MachO::swapStruct(Cmd);
60  return Cmd;
61 }
62 
63 template <typename T>
64 static Expected<T> getStructOrErr(const MachOObjectFile &O, const char *P) {
65  // Don't read before the beginning or past the end of the file
66  if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
67  return malformedError("Structure read out-of-range");
68 
69  T Cmd;
70  memcpy(&Cmd, P, sizeof(T));
71  if (O.isLittleEndian() != sys::IsLittleEndianHost)
72  MachO::swapStruct(Cmd);
73  return Cmd;
74 }
75 
76 static const char *
78  unsigned Sec) {
79  uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
80 
81  bool Is64 = O.is64Bit();
82  unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
83  sizeof(MachO::segment_command);
84  unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
85  sizeof(MachO::section);
86 
87  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
88  return reinterpret_cast<const char*>(SectionAddr);
89 }
90 
91 static const char *getPtr(const MachOObjectFile &O, size_t Offset) {
92  return O.getData().substr(Offset, 1).data();
93 }
94 
95 static MachO::nlist_base
96 getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI) {
97  const char *P = reinterpret_cast<const char *>(DRI.p);
98  return getStruct<MachO::nlist_base>(O, P);
99 }
100 
101 static StringRef parseSegmentOrSectionName(const char *P) {
102  if (P[15] == 0)
103  // Null terminated.
104  return P;
105  // Not null terminated, so this is a 16 char string.
106  return StringRef(P, 16);
107 }
108 
109 // Helper to advance a section or symbol iterator multiple increments at a time.
110 template<class T>
111 static void advance(T &it, size_t Val) {
112  while (Val--)
113  ++it;
114 }
115 
116 static unsigned getCPUType(const MachOObjectFile &O) {
117  return O.getHeader().cputype;
118 }
119 
120 static uint32_t
122  return RE.r_word0;
123 }
124 
125 static unsigned
127  return RE.r_word0 & 0xffffff;
128 }
129 
130 static bool getPlainRelocationPCRel(const MachOObjectFile &O,
131  const MachO::any_relocation_info &RE) {
132  if (O.isLittleEndian())
133  return (RE.r_word1 >> 24) & 1;
134  return (RE.r_word1 >> 7) & 1;
135 }
136 
137 static bool
139  return (RE.r_word0 >> 30) & 1;
140 }
141 
142 static unsigned getPlainRelocationLength(const MachOObjectFile &O,
143  const MachO::any_relocation_info &RE) {
144  if (O.isLittleEndian())
145  return (RE.r_word1 >> 25) & 3;
146  return (RE.r_word1 >> 5) & 3;
147 }
148 
149 static unsigned
151  return (RE.r_word0 >> 28) & 3;
152 }
153 
154 static unsigned getPlainRelocationType(const MachOObjectFile &O,
155  const MachO::any_relocation_info &RE) {
156  if (O.isLittleEndian())
157  return RE.r_word1 >> 28;
158  return RE.r_word1 & 0xf;
159 }
160 
161 static uint32_t getSectionFlags(const MachOObjectFile &O,
162  DataRefImpl Sec) {
163  if (O.is64Bit()) {
164  MachO::section_64 Sect = O.getSection64(Sec);
165  return Sect.flags;
166  }
167  MachO::section Sect = O.getSection(Sec);
168  return Sect.flags;
169 }
170 
172 getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr,
173  uint32_t LoadCommandIndex) {
174  if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
175  if (CmdOrErr->cmdsize < 8)
176  return malformedError("load command " + Twine(LoadCommandIndex) +
177  " with size less than 8 bytes");
178  return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
179  } else
180  return CmdOrErr.takeError();
181 }
182 
184 getFirstLoadCommandInfo(const MachOObjectFile &Obj) {
185  unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
186  : sizeof(MachO::mach_header);
187  if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds)
188  return malformedError("load command 0 extends past the end all load "
189  "commands in the file");
190  return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
191 }
192 
194 getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex,
196  unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
197  : sizeof(MachO::mach_header);
198  if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
199  Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
200  return malformedError("load command " + Twine(LoadCommandIndex + 1) +
201  " extends past the end all load commands in the file");
202  return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
203 }
204 
205 template <typename T>
206 static void parseHeader(const MachOObjectFile &Obj, T &Header,
207  Error &Err) {
208  if (sizeof(T) > Obj.getData().size()) {
209  Err = malformedError("the mach header extends past the end of the "
210  "file");
211  return;
212  }
213  if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
214  Header = *HeaderOrErr;
215  else
216  Err = HeaderOrErr.takeError();
217 }
218 
219 // This is used to check for overlapping of Mach-O elements.
220 struct MachOElement {
221  uint64_t Offset;
222  uint64_t Size;
223  const char *Name;
224 };
225 
226 static Error checkOverlappingElement(std::list<MachOElement> &Elements,
227  uint64_t Offset, uint64_t Size,
228  const char *Name) {
229  if (Size == 0)
230  return Error::success();
231 
232  for (auto it=Elements.begin() ; it != Elements.end(); ++it) {
233  auto E = *it;
234  if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
235  (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) ||
236  (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
237  return malformedError(Twine(Name) + " at offset " + Twine(Offset) +
238  " with a size of " + Twine(Size) + ", overlaps " +
239  E.Name + " at offset " + Twine(E.Offset) + " with "
240  "a size of " + Twine(E.Size));
241  auto nt = it;
242  nt++;
243  if (nt != Elements.end()) {
244  auto N = *nt;
245  if (Offset + Size <= N.Offset) {
246  Elements.insert(nt, {Offset, Size, Name});
247  return Error::success();
248  }
249  }
250  }
251  Elements.push_back({Offset, Size, Name});
252  return Error::success();
253 }
254 
255 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
256 // sections to \param Sections, and optionally sets
257 // \param IsPageZeroSegment to true.
258 template <typename Segment, typename Section>
260  const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load,
261  SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
262  uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
263  std::list<MachOElement> &Elements) {
264  const unsigned SegmentLoadSize = sizeof(Segment);
265  if (Load.C.cmdsize < SegmentLoadSize)
266  return malformedError("load command " + Twine(LoadCommandIndex) +
267  " " + CmdName + " cmdsize too small");
268  if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
269  Segment S = SegOrErr.get();
270  const unsigned SectionSize = sizeof(Section);
271  uint64_t FileSize = Obj.getData().size();
272  if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
273  S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
274  return malformedError("load command " + Twine(LoadCommandIndex) +
275  " inconsistent cmdsize in " + CmdName +
276  " for the number of sections");
277  for (unsigned J = 0; J < S.nsects; ++J) {
278  const char *Sec = getSectionPtr(Obj, Load, J);
279  Sections.push_back(Sec);
280  Section s = getStruct<Section>(Obj, Sec);
281  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
282  Obj.getHeader().filetype != MachO::MH_DSYM &&
283  s.flags != MachO::S_ZEROFILL &&
284  s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
285  s.offset > FileSize)
286  return malformedError("offset field of section " + Twine(J) + " in " +
287  CmdName + " command " + Twine(LoadCommandIndex) +
288  " extends past the end of the file");
289  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
290  Obj.getHeader().filetype != MachO::MH_DSYM &&
291  s.flags != MachO::S_ZEROFILL &&
292  s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 &&
293  s.offset < SizeOfHeaders && s.size != 0)
294  return malformedError("offset field of section " + Twine(J) + " in " +
295  CmdName + " command " + Twine(LoadCommandIndex) +
296  " not past the headers of the file");
297  uint64_t BigSize = s.offset;
298  BigSize += s.size;
299  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
300  Obj.getHeader().filetype != MachO::MH_DSYM &&
301  s.flags != MachO::S_ZEROFILL &&
302  s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
303  BigSize > FileSize)
304  return malformedError("offset field plus size field of section " +
305  Twine(J) + " in " + CmdName + " command " +
306  Twine(LoadCommandIndex) +
307  " extends past the end of the file");
308  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
309  Obj.getHeader().filetype != MachO::MH_DSYM &&
310  s.flags != MachO::S_ZEROFILL &&
311  s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
312  s.size > S.filesize)
313  return malformedError("size field of section " +
314  Twine(J) + " in " + CmdName + " command " +
315  Twine(LoadCommandIndex) +
316  " greater than the segment");
317  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
318  Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
319  s.addr < S.vmaddr)
320  return malformedError("addr field of section " + Twine(J) + " in " +
321  CmdName + " command " + Twine(LoadCommandIndex) +
322  " less than the segment's vmaddr");
323  BigSize = s.addr;
324  BigSize += s.size;
325  uint64_t BigEnd = S.vmaddr;
326  BigEnd += S.vmsize;
327  if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
328  return malformedError("addr field plus size of section " + Twine(J) +
329  " in " + CmdName + " command " +
330  Twine(LoadCommandIndex) +
331  " greater than than "
332  "the segment's vmaddr plus vmsize");
333  if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
334  Obj.getHeader().filetype != MachO::MH_DSYM &&
335  s.flags != MachO::S_ZEROFILL &&
337  if (Error Err = checkOverlappingElement(Elements, s.offset, s.size,
338  "section contents"))
339  return Err;
340  if (s.reloff > FileSize)
341  return malformedError("reloff field of section " + Twine(J) + " in " +
342  CmdName + " command " + Twine(LoadCommandIndex) +
343  " extends past the end of the file");
344  BigSize = s.nreloc;
345  BigSize *= sizeof(struct MachO::relocation_info);
346  BigSize += s.reloff;
347  if (BigSize > FileSize)
348  return malformedError("reloff field plus nreloc field times sizeof("
349  "struct relocation_info) of section " +
350  Twine(J) + " in " + CmdName + " command " +
351  Twine(LoadCommandIndex) +
352  " extends past the end of the file");
353  if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc *
354  sizeof(struct
356  "section relocation entries"))
357  return Err;
358  }
359  if (S.fileoff > FileSize)
360  return malformedError("load command " + Twine(LoadCommandIndex) +
361  " fileoff field in " + CmdName +
362  " extends past the end of the file");
363  uint64_t BigSize = S.fileoff;
364  BigSize += S.filesize;
365  if (BigSize > FileSize)
366  return malformedError("load command " + Twine(LoadCommandIndex) +
367  " fileoff field plus filesize field in " +
368  CmdName + " extends past the end of the file");
369  if (S.vmsize != 0 && S.filesize > S.vmsize)
370  return malformedError("load command " + Twine(LoadCommandIndex) +
371  " fileoff field in " + CmdName +
372  " greater than vmsize field");
373  IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
374  } else
375  return SegOrErr.takeError();
376 
377  return Error::success();
378 }
379 
380 static Error checkSymtabCommand(const MachOObjectFile &Obj,
382  uint32_t LoadCommandIndex,
383  const char **SymtabLoadCmd,
384  std::list<MachOElement> &Elements) {
385  if (Load.C.cmdsize < sizeof(MachO::symtab_command))
386  return malformedError("load command " + Twine(LoadCommandIndex) +
387  " LC_SYMTAB cmdsize too small");
388  if (*SymtabLoadCmd != nullptr)
389  return malformedError("more than one LC_SYMTAB command");
390  MachO::symtab_command Symtab =
391  getStruct<MachO::symtab_command>(Obj, Load.Ptr);
392  if (Symtab.cmdsize != sizeof(MachO::symtab_command))
393  return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) +
394  " has incorrect cmdsize");
395  uint64_t FileSize = Obj.getData().size();
396  if (Symtab.symoff > FileSize)
397  return malformedError("symoff field of LC_SYMTAB command " +
398  Twine(LoadCommandIndex) + " extends past the end "
399  "of the file");
400  uint64_t SymtabSize = Symtab.nsyms;
401  const char *struct_nlist_name;
402  if (Obj.is64Bit()) {
403  SymtabSize *= sizeof(MachO::nlist_64);
404  struct_nlist_name = "struct nlist_64";
405  } else {
406  SymtabSize *= sizeof(MachO::nlist);
407  struct_nlist_name = "struct nlist";
408  }
409  uint64_t BigSize = SymtabSize;
410  BigSize += Symtab.symoff;
411  if (BigSize > FileSize)
412  return malformedError("symoff field plus nsyms field times sizeof(" +
413  Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
414  Twine(LoadCommandIndex) + " extends past the end "
415  "of the file");
416  if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize,
417  "symbol table"))
418  return Err;
419  if (Symtab.stroff > FileSize)
420  return malformedError("stroff field of LC_SYMTAB command " +
421  Twine(LoadCommandIndex) + " extends past the end "
422  "of the file");
423  BigSize = Symtab.stroff;
424  BigSize += Symtab.strsize;
425  if (BigSize > FileSize)
426  return malformedError("stroff field plus strsize field of LC_SYMTAB "
427  "command " + Twine(LoadCommandIndex) + " extends "
428  "past the end of the file");
429  if (Error Err = checkOverlappingElement(Elements, Symtab.stroff,
430  Symtab.strsize, "string table"))
431  return Err;
432  *SymtabLoadCmd = Load.Ptr;
433  return Error::success();
434 }
435 
436 static Error checkDysymtabCommand(const MachOObjectFile &Obj,
438  uint32_t LoadCommandIndex,
439  const char **DysymtabLoadCmd,
440  std::list<MachOElement> &Elements) {
441  if (Load.C.cmdsize < sizeof(MachO::dysymtab_command))
442  return malformedError("load command " + Twine(LoadCommandIndex) +
443  " LC_DYSYMTAB cmdsize too small");
444  if (*DysymtabLoadCmd != nullptr)
445  return malformedError("more than one LC_DYSYMTAB command");
446  MachO::dysymtab_command Dysymtab =
447  getStruct<MachO::dysymtab_command>(Obj, Load.Ptr);
448  if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command))
449  return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) +
450  " has incorrect cmdsize");
451  uint64_t FileSize = Obj.getData().size();
452  if (Dysymtab.tocoff > FileSize)
453  return malformedError("tocoff field of LC_DYSYMTAB command " +
454  Twine(LoadCommandIndex) + " extends past the end of "
455  "the file");
456  uint64_t BigSize = Dysymtab.ntoc;
457  BigSize *= sizeof(MachO::dylib_table_of_contents);
458  BigSize += Dysymtab.tocoff;
459  if (BigSize > FileSize)
460  return malformedError("tocoff field plus ntoc field times sizeof(struct "
461  "dylib_table_of_contents) of LC_DYSYMTAB command " +
462  Twine(LoadCommandIndex) + " extends past the end of "
463  "the file");
464  if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff,
465  Dysymtab.ntoc * sizeof(struct
467  "table of contents"))
468  return Err;
469  if (Dysymtab.modtaboff > FileSize)
470  return malformedError("modtaboff field of LC_DYSYMTAB command " +
471  Twine(LoadCommandIndex) + " extends past the end of "
472  "the file");
473  BigSize = Dysymtab.nmodtab;
474  const char *struct_dylib_module_name;
475  uint64_t sizeof_modtab;
476  if (Obj.is64Bit()) {
477  sizeof_modtab = sizeof(MachO::dylib_module_64);
478  struct_dylib_module_name = "struct dylib_module_64";
479  } else {
480  sizeof_modtab = sizeof(MachO::dylib_module);
481  struct_dylib_module_name = "struct dylib_module";
482  }
483  BigSize *= sizeof_modtab;
484  BigSize += Dysymtab.modtaboff;
485  if (BigSize > FileSize)
486  return malformedError("modtaboff field plus nmodtab field times sizeof(" +
487  Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
488  "command " + Twine(LoadCommandIndex) + " extends "
489  "past the end of the file");
490  if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff,
491  Dysymtab.nmodtab * sizeof_modtab,
492  "module table"))
493  return Err;
494  if (Dysymtab.extrefsymoff > FileSize)
495  return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
496  Twine(LoadCommandIndex) + " extends past the end of "
497  "the file");
498  BigSize = Dysymtab.nextrefsyms;
499  BigSize *= sizeof(MachO::dylib_reference);
500  BigSize += Dysymtab.extrefsymoff;
501  if (BigSize > FileSize)
502  return malformedError("extrefsymoff field plus nextrefsyms field times "
503  "sizeof(struct dylib_reference) of LC_DYSYMTAB "
504  "command " + Twine(LoadCommandIndex) + " extends "
505  "past the end of the file");
506  if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff,
507  Dysymtab.nextrefsyms *
508  sizeof(MachO::dylib_reference),
509  "reference table"))
510  return Err;
511  if (Dysymtab.indirectsymoff > FileSize)
512  return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
513  Twine(LoadCommandIndex) + " extends past the end of "
514  "the file");
515  BigSize = Dysymtab.nindirectsyms;
516  BigSize *= sizeof(uint32_t);
517  BigSize += Dysymtab.indirectsymoff;
518  if (BigSize > FileSize)
519  return malformedError("indirectsymoff field plus nindirectsyms field times "
520  "sizeof(uint32_t) of LC_DYSYMTAB command " +
521  Twine(LoadCommandIndex) + " extends past the end of "
522  "the file");
523  if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff,
524  Dysymtab.nindirectsyms *
525  sizeof(uint32_t),
526  "indirect table"))
527  return Err;
528  if (Dysymtab.extreloff > FileSize)
529  return malformedError("extreloff field of LC_DYSYMTAB command " +
530  Twine(LoadCommandIndex) + " extends past the end of "
531  "the file");
532  BigSize = Dysymtab.nextrel;
533  BigSize *= sizeof(MachO::relocation_info);
534  BigSize += Dysymtab.extreloff;
535  if (BigSize > FileSize)
536  return malformedError("extreloff field plus nextrel field times sizeof"
537  "(struct relocation_info) of LC_DYSYMTAB command " +
538  Twine(LoadCommandIndex) + " extends past the end of "
539  "the file");
540  if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff,
541  Dysymtab.nextrel *
542  sizeof(MachO::relocation_info),
543  "external relocation table"))
544  return Err;
545  if (Dysymtab.locreloff > FileSize)
546  return malformedError("locreloff field of LC_DYSYMTAB command " +
547  Twine(LoadCommandIndex) + " extends past the end of "
548  "the file");
549  BigSize = Dysymtab.nlocrel;
550  BigSize *= sizeof(MachO::relocation_info);
551  BigSize += Dysymtab.locreloff;
552  if (BigSize > FileSize)
553  return malformedError("locreloff field plus nlocrel field times sizeof"
554  "(struct relocation_info) of LC_DYSYMTAB command " +
555  Twine(LoadCommandIndex) + " extends past the end of "
556  "the file");
557  if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff,
558  Dysymtab.nlocrel *
559  sizeof(MachO::relocation_info),
560  "local relocation table"))
561  return Err;
562  *DysymtabLoadCmd = Load.Ptr;
563  return Error::success();
564 }
565 
566 static Error checkLinkeditDataCommand(const MachOObjectFile &Obj,
568  uint32_t LoadCommandIndex,
569  const char **LoadCmd, const char *CmdName,
570  std::list<MachOElement> &Elements,
571  const char *ElementName) {
572  if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command))
573  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
574  CmdName + " cmdsize too small");
575  if (*LoadCmd != nullptr)
576  return malformedError("more than one " + Twine(CmdName) + " command");
578  getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr);
579  if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command))
580  return malformedError(Twine(CmdName) + " command " +
581  Twine(LoadCommandIndex) + " has incorrect cmdsize");
582  uint64_t FileSize = Obj.getData().size();
583  if (LinkData.dataoff > FileSize)
584  return malformedError("dataoff field of " + Twine(CmdName) + " command " +
585  Twine(LoadCommandIndex) + " extends past the end of "
586  "the file");
587  uint64_t BigSize = LinkData.dataoff;
588  BigSize += LinkData.datasize;
589  if (BigSize > FileSize)
590  return malformedError("dataoff field plus datasize field of " +
591  Twine(CmdName) + " command " +
592  Twine(LoadCommandIndex) + " extends past the end of "
593  "the file");
594  if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff,
595  LinkData.datasize, ElementName))
596  return Err;
597  *LoadCmd = Load.Ptr;
598  return Error::success();
599 }
600 
601 static Error checkDyldInfoCommand(const MachOObjectFile &Obj,
603  uint32_t LoadCommandIndex,
604  const char **LoadCmd, const char *CmdName,
605  std::list<MachOElement> &Elements) {
606  if (Load.C.cmdsize < sizeof(MachO::dyld_info_command))
607  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
608  CmdName + " cmdsize too small");
609  if (*LoadCmd != nullptr)
610  return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
611  "command");
612  MachO::dyld_info_command DyldInfo =
613  getStruct<MachO::dyld_info_command>(Obj, Load.Ptr);
614  if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command))
615  return malformedError(Twine(CmdName) + " command " +
616  Twine(LoadCommandIndex) + " has incorrect cmdsize");
617  uint64_t FileSize = Obj.getData().size();
618  if (DyldInfo.rebase_off > FileSize)
619  return malformedError("rebase_off field of " + Twine(CmdName) +
620  " command " + Twine(LoadCommandIndex) + " extends "
621  "past the end of the file");
622  uint64_t BigSize = DyldInfo.rebase_off;
623  BigSize += DyldInfo.rebase_size;
624  if (BigSize > FileSize)
625  return malformedError("rebase_off field plus rebase_size field of " +
626  Twine(CmdName) + " command " +
627  Twine(LoadCommandIndex) + " extends past the end of "
628  "the file");
629  if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off,
630  DyldInfo.rebase_size,
631  "dyld rebase info"))
632  return Err;
633  if (DyldInfo.bind_off > FileSize)
634  return malformedError("bind_off field of " + Twine(CmdName) +
635  " command " + Twine(LoadCommandIndex) + " extends "
636  "past the end of the file");
637  BigSize = DyldInfo.bind_off;
638  BigSize += DyldInfo.bind_size;
639  if (BigSize > FileSize)
640  return malformedError("bind_off field plus bind_size field of " +
641  Twine(CmdName) + " command " +
642  Twine(LoadCommandIndex) + " extends past the end of "
643  "the file");
644  if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off,
645  DyldInfo.bind_size,
646  "dyld bind info"))
647  return Err;
648  if (DyldInfo.weak_bind_off > FileSize)
649  return malformedError("weak_bind_off field of " + Twine(CmdName) +
650  " command " + Twine(LoadCommandIndex) + " extends "
651  "past the end of the file");
652  BigSize = DyldInfo.weak_bind_off;
653  BigSize += DyldInfo.weak_bind_size;
654  if (BigSize > FileSize)
655  return malformedError("weak_bind_off field plus weak_bind_size field of " +
656  Twine(CmdName) + " command " +
657  Twine(LoadCommandIndex) + " extends past the end of "
658  "the file");
659  if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off,
660  DyldInfo.weak_bind_size,
661  "dyld weak bind info"))
662  return Err;
663  if (DyldInfo.lazy_bind_off > FileSize)
664  return malformedError("lazy_bind_off field of " + Twine(CmdName) +
665  " command " + Twine(LoadCommandIndex) + " extends "
666  "past the end of the file");
667  BigSize = DyldInfo.lazy_bind_off;
668  BigSize += DyldInfo.lazy_bind_size;
669  if (BigSize > FileSize)
670  return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
671  Twine(CmdName) + " command " +
672  Twine(LoadCommandIndex) + " extends past the end of "
673  "the file");
674  if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off,
675  DyldInfo.lazy_bind_size,
676  "dyld lazy bind info"))
677  return Err;
678  if (DyldInfo.export_off > FileSize)
679  return malformedError("export_off field of " + Twine(CmdName) +
680  " command " + Twine(LoadCommandIndex) + " extends "
681  "past the end of the file");
682  BigSize = DyldInfo.export_off;
683  BigSize += DyldInfo.export_size;
684  if (BigSize > FileSize)
685  return malformedError("export_off field plus export_size field of " +
686  Twine(CmdName) + " command " +
687  Twine(LoadCommandIndex) + " extends past the end of "
688  "the file");
689  if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off,
690  DyldInfo.export_size,
691  "dyld export info"))
692  return Err;
693  *LoadCmd = Load.Ptr;
694  return Error::success();
695 }
696 
697 static Error checkDylibCommand(const MachOObjectFile &Obj,
699  uint32_t LoadCommandIndex, const char *CmdName) {
700  if (Load.C.cmdsize < sizeof(MachO::dylib_command))
701  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
702  CmdName + " cmdsize too small");
703  MachO::dylib_command D = getStruct<MachO::dylib_command>(Obj, Load.Ptr);
704  if (D.dylib.name < sizeof(MachO::dylib_command))
705  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
706  CmdName + " name.offset field too small, not past "
707  "the end of the dylib_command struct");
708  if (D.dylib.name >= D.cmdsize)
709  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
710  CmdName + " name.offset field extends past the end "
711  "of the load command");
712  // Make sure there is a null between the starting offset of the name and
713  // the end of the load command.
714  uint32_t i;
715  const char *P = (const char *)Load.Ptr;
716  for (i = D.dylib.name; i < D.cmdsize; i++)
717  if (P[i] == '\0')
718  break;
719  if (i >= D.cmdsize)
720  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
721  CmdName + " library name extends past the end of the "
722  "load command");
723  return Error::success();
724 }
725 
726 static Error checkDylibIdCommand(const MachOObjectFile &Obj,
728  uint32_t LoadCommandIndex,
729  const char **LoadCmd) {
730  if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex,
731  "LC_ID_DYLIB"))
732  return Err;
733  if (*LoadCmd != nullptr)
734  return malformedError("more than one LC_ID_DYLIB command");
735  if (Obj.getHeader().filetype != MachO::MH_DYLIB &&
736  Obj.getHeader().filetype != MachO::MH_DYLIB_STUB)
737  return malformedError("LC_ID_DYLIB load command in non-dynamic library "
738  "file type");
739  *LoadCmd = Load.Ptr;
740  return Error::success();
741 }
742 
743 static Error checkDyldCommand(const MachOObjectFile &Obj,
745  uint32_t LoadCommandIndex, const char *CmdName) {
746  if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
747  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
748  CmdName + " cmdsize too small");
749  MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr);
750  if (D.name < sizeof(MachO::dylinker_command))
751  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
752  CmdName + " name.offset field too small, not past "
753  "the end of the dylinker_command struct");
754  if (D.name >= D.cmdsize)
755  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
756  CmdName + " name.offset field extends past the end "
757  "of the load command");
758  // Make sure there is a null between the starting offset of the name and
759  // the end of the load command.
760  uint32_t i;
761  const char *P = (const char *)Load.Ptr;
762  for (i = D.name; i < D.cmdsize; i++)
763  if (P[i] == '\0')
764  break;
765  if (i >= D.cmdsize)
766  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
767  CmdName + " dyld name extends past the end of the "
768  "load command");
769  return Error::success();
770 }
771 
772 static Error checkVersCommand(const MachOObjectFile &Obj,
774  uint32_t LoadCommandIndex,
775  const char **LoadCmd, const char *CmdName) {
776  if (Load.C.cmdsize != sizeof(MachO::version_min_command))
777  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
778  CmdName + " has incorrect cmdsize");
779  if (*LoadCmd != nullptr)
780  return malformedError("more than one LC_VERSION_MIN_MACOSX, "
781  "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
782  "LC_VERSION_MIN_WATCHOS command");
783  *LoadCmd = Load.Ptr;
784  return Error::success();
785 }
786 
787 static Error checkRpathCommand(const MachOObjectFile &Obj,
789  uint32_t LoadCommandIndex) {
790  if (Load.C.cmdsize < sizeof(MachO::rpath_command))
791  return malformedError("load command " + Twine(LoadCommandIndex) +
792  " LC_RPATH cmdsize too small");
793  MachO::rpath_command R = getStruct<MachO::rpath_command>(Obj, Load.Ptr);
794  if (R.path < sizeof(MachO::rpath_command))
795  return malformedError("load command " + Twine(LoadCommandIndex) +
796  " LC_RPATH path.offset field too small, not past "
797  "the end of the rpath_command struct");
798  if (R.path >= R.cmdsize)
799  return malformedError("load command " + Twine(LoadCommandIndex) +
800  " LC_RPATH path.offset field extends past the end "
801  "of the load command");
802  // Make sure there is a null between the starting offset of the path and
803  // the end of the load command.
804  uint32_t i;
805  const char *P = (const char *)Load.Ptr;
806  for (i = R.path; i < R.cmdsize; i++)
807  if (P[i] == '\0')
808  break;
809  if (i >= R.cmdsize)
810  return malformedError("load command " + Twine(LoadCommandIndex) +
811  " LC_RPATH library name extends past the end of the "
812  "load command");
813  return Error::success();
814 }
815 
816 static Error checkEncryptCommand(const MachOObjectFile &Obj,
818  uint32_t LoadCommandIndex,
819  uint64_t cryptoff, uint64_t cryptsize,
820  const char **LoadCmd, const char *CmdName) {
821  if (*LoadCmd != nullptr)
822  return malformedError("more than one LC_ENCRYPTION_INFO and or "
823  "LC_ENCRYPTION_INFO_64 command");
824  uint64_t FileSize = Obj.getData().size();
825  if (cryptoff > FileSize)
826  return malformedError("cryptoff field of " + Twine(CmdName) +
827  " command " + Twine(LoadCommandIndex) + " extends "
828  "past the end of the file");
829  uint64_t BigSize = cryptoff;
830  BigSize += cryptsize;
831  if (BigSize > FileSize)
832  return malformedError("cryptoff field plus cryptsize field of " +
833  Twine(CmdName) + " command " +
834  Twine(LoadCommandIndex) + " extends past the end of "
835  "the file");
836  *LoadCmd = Load.Ptr;
837  return Error::success();
838 }
839 
840 static Error checkLinkerOptCommand(const MachOObjectFile &Obj,
842  uint32_t LoadCommandIndex) {
843  if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
844  return malformedError("load command " + Twine(LoadCommandIndex) +
845  " LC_LINKER_OPTION cmdsize too small");
847  getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
848  // Make sure the count of strings is correct.
849  const char *string = (const char *)Load.Ptr +
850  sizeof(struct MachO::linker_option_command);
851  uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
852  uint32_t i = 0;
853  while (left > 0) {
854  while (*string == '\0' && left > 0) {
855  string++;
856  left--;
857  }
858  if (left > 0) {
859  i++;
860  uint32_t NullPos = StringRef(string, left).find('\0');
861  uint32_t len = std::min(NullPos, left) + 1;
862  string += len;
863  left -= len;
864  }
865  }
866  if (L.count != i)
867  return malformedError("load command " + Twine(LoadCommandIndex) +
868  " LC_LINKER_OPTION string count " + Twine(L.count) +
869  " does not match number of strings");
870  return Error::success();
871 }
872 
873 static Error checkSubCommand(const MachOObjectFile &Obj,
875  uint32_t LoadCommandIndex, const char *CmdName,
876  size_t SizeOfCmd, const char *CmdStructName,
877  uint32_t PathOffset, const char *PathFieldName) {
878  if (PathOffset < SizeOfCmd)
879  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
880  CmdName + " " + PathFieldName + ".offset field too "
881  "small, not past the end of the " + CmdStructName);
882  if (PathOffset >= Load.C.cmdsize)
883  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
884  CmdName + " " + PathFieldName + ".offset field "
885  "extends past the end of the load command");
886  // Make sure there is a null between the starting offset of the path and
887  // the end of the load command.
888  uint32_t i;
889  const char *P = (const char *)Load.Ptr;
890  for (i = PathOffset; i < Load.C.cmdsize; i++)
891  if (P[i] == '\0')
892  break;
893  if (i >= Load.C.cmdsize)
894  return malformedError("load command " + Twine(LoadCommandIndex) + " " +
895  CmdName + " " + PathFieldName + " name extends past "
896  "the end of the load command");
897  return Error::success();
898 }
899 
900 static Error checkThreadCommand(const MachOObjectFile &Obj,
902  uint32_t LoadCommandIndex,
903  const char *CmdName) {
904  if (Load.C.cmdsize < sizeof(MachO::thread_command))
905  return malformedError("load command " + Twine(LoadCommandIndex) +
906  CmdName + " cmdsize too small");
908  getStruct<MachO::thread_command>(Obj, Load.Ptr);
909  const char *state = Load.Ptr + sizeof(MachO::thread_command);
910  const char *end = Load.Ptr + T.cmdsize;
911  uint32_t nflavor = 0;
912  uint32_t cputype = getCPUType(Obj);
913  while (state < end) {
914  if(state + sizeof(uint32_t) > end)
915  return malformedError("load command " + Twine(LoadCommandIndex) +
916  "flavor in " + CmdName + " extends past end of "
917  "command");
918  uint32_t flavor;
919  memcpy(&flavor, state, sizeof(uint32_t));
920  if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
921  sys::swapByteOrder(flavor);
922  state += sizeof(uint32_t);
923 
924  if(state + sizeof(uint32_t) > end)
925  return malformedError("load command " + Twine(LoadCommandIndex) +
926  " count in " + CmdName + " extends past end of "
927  "command");
928  uint32_t count;
929  memcpy(&count, state, sizeof(uint32_t));
930  if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
931  sys::swapByteOrder(count);
932  state += sizeof(uint32_t);
933 
934  if (cputype == MachO::CPU_TYPE_X86_64) {
935  if (flavor == MachO::x86_THREAD_STATE64) {
936  if (count != MachO::x86_THREAD_STATE64_COUNT)
937  return malformedError("load command " + Twine(LoadCommandIndex) +
938  " count not x86_THREAD_STATE64_COUNT for "
939  "flavor number " + Twine(nflavor) + " which is "
940  "a x86_THREAD_STATE64 flavor in " + CmdName +
941  " command");
942  if (state + sizeof(MachO::x86_thread_state64_t) > end)
943  return malformedError("load command " + Twine(LoadCommandIndex) +
944  " x86_THREAD_STATE64 extends past end of "
945  "command in " + CmdName + " command");
946  state += sizeof(MachO::x86_thread_state64_t);
947  } else {
948  return malformedError("load command " + Twine(LoadCommandIndex) +
949  " unknown flavor (" + Twine(flavor) + ") for "
950  "flavor number " + Twine(nflavor) + " in " +
951  CmdName + " command");
952  }
953  } else if (cputype == MachO::CPU_TYPE_ARM) {
954  if (flavor == MachO::ARM_THREAD_STATE) {
955  if (count != MachO::ARM_THREAD_STATE_COUNT)
956  return malformedError("load command " + Twine(LoadCommandIndex) +
957  " count not ARM_THREAD_STATE_COUNT for "
958  "flavor number " + Twine(nflavor) + " which is "
959  "a ARM_THREAD_STATE flavor in " + CmdName +
960  " command");
961  if (state + sizeof(MachO::arm_thread_state32_t) > end)
962  return malformedError("load command " + Twine(LoadCommandIndex) +
963  " ARM_THREAD_STATE extends past end of "
964  "command in " + CmdName + " command");
965  state += sizeof(MachO::arm_thread_state32_t);
966  } else {
967  return malformedError("load command " + Twine(LoadCommandIndex) +
968  " unknown flavor (" + Twine(flavor) + ") for "
969  "flavor number " + Twine(nflavor) + " in " +
970  CmdName + " command");
971  }
972  } else if (cputype == MachO::CPU_TYPE_ARM64) {
973  if (flavor == MachO::ARM_THREAD_STATE64) {
974  if (count != MachO::ARM_THREAD_STATE64_COUNT)
975  return malformedError("load command " + Twine(LoadCommandIndex) +
976  " count not ARM_THREAD_STATE64_COUNT for "
977  "flavor number " + Twine(nflavor) + " which is "
978  "a ARM_THREAD_STATE64 flavor in " + CmdName +
979  " command");
980  if (state + sizeof(MachO::arm_thread_state64_t) > end)
981  return malformedError("load command " + Twine(LoadCommandIndex) +
982  " ARM_THREAD_STATE64 extends past end of "
983  "command in " + CmdName + " command");
984  state += sizeof(MachO::arm_thread_state64_t);
985  } else {
986  return malformedError("load command " + Twine(LoadCommandIndex) +
987  " unknown flavor (" + Twine(flavor) + ") for "
988  "flavor number " + Twine(nflavor) + " in " +
989  CmdName + " command");
990  }
991  } else if (cputype == MachO::CPU_TYPE_POWERPC) {
992  if (flavor == MachO::PPC_THREAD_STATE) {
993  if (count != MachO::PPC_THREAD_STATE_COUNT)
994  return malformedError("load command " + Twine(LoadCommandIndex) +
995  " count not PPC_THREAD_STATE_COUNT for "
996  "flavor number " + Twine(nflavor) + " which is "
997  "a PPC_THREAD_STATE flavor in " + CmdName +
998  " command");
999  if (state + sizeof(MachO::ppc_thread_state32_t) > end)
1000  return malformedError("load command " + Twine(LoadCommandIndex) +
1001  " PPC_THREAD_STATE extends past end of "
1002  "command in " + CmdName + " command");
1003  state += sizeof(MachO::ppc_thread_state32_t);
1004  } else {
1005  return malformedError("load command " + Twine(LoadCommandIndex) +
1006  " unknown flavor (" + Twine(flavor) + ") for "
1007  "flavor number " + Twine(nflavor) + " in " +
1008  CmdName + " command");
1009  }
1010  } else {
1011  return malformedError("unknown cputype (" + Twine(cputype) + ") load "
1012  "command " + Twine(LoadCommandIndex) + " for " +
1013  CmdName + " command can't be checked");
1014  }
1015  nflavor++;
1016  }
1017  return Error::success();
1018 }
1019 
1020 static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj,
1022  &Load,
1023  uint32_t LoadCommandIndex,
1024  const char **LoadCmd,
1025  std::list<MachOElement> &Elements) {
1026  if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
1027  return malformedError("load command " + Twine(LoadCommandIndex) +
1028  " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1029  if (*LoadCmd != nullptr)
1030  return malformedError("more than one LC_TWOLEVEL_HINTS command");
1032  getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1033  uint64_t FileSize = Obj.getData().size();
1034  if (Hints.offset > FileSize)
1035  return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1036  Twine(LoadCommandIndex) + " extends past the end of "
1037  "the file");
1038  uint64_t BigSize = Hints.nhints;
1039  BigSize *= Hints.nhints * sizeof(MachO::twolevel_hint);
1040  BigSize += Hints.offset;
1041  if (BigSize > FileSize)
1042  return malformedError("offset field plus nhints times sizeof(struct "
1043  "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1044  Twine(LoadCommandIndex) + " extends past the end of "
1045  "the file");
1046  if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
1047  sizeof(MachO::twolevel_hint),
1048  "two level hints"))
1049  return Err;
1050  *LoadCmd = Load.Ptr;
1051  return Error::success();
1052 }
1053 
1054 // Returns true if the libObject code does not support the load command and its
1055 // contents. The cmd value it is treated as an unknown load command but with
1056 // an error message that says the cmd value is obsolete.
1058  if (cmd == MachO::LC_SYMSEG ||
1059  cmd == MachO::LC_LOADFVMLIB ||
1060  cmd == MachO::LC_IDFVMLIB ||
1061  cmd == MachO::LC_IDENT ||
1062  cmd == MachO::LC_FVMFILE ||
1063  cmd == MachO::LC_PREPAGE ||
1064  cmd == MachO::LC_PREBOUND_DYLIB ||
1065  cmd == MachO::LC_TWOLEVEL_HINTS ||
1066  cmd == MachO::LC_PREBIND_CKSUM)
1067  return true;
1068  return false;
1069 }
1070 
1072 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
1073  bool Is64Bits, uint32_t UniversalCputype,
1074  uint32_t UniversalIndex) {
1075  Error Err = Error::success();
1076  std::unique_ptr<MachOObjectFile> Obj(
1077  new MachOObjectFile(std::move(Object), IsLittleEndian,
1078  Is64Bits, Err, UniversalCputype,
1079  UniversalIndex));
1080  if (Err)
1081  return std::move(Err);
1082  return std::move(Obj);
1083 }
1084 
1085 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1086  bool Is64bits, Error &Err,
1087  uint32_t UniversalCputype,
1088  uint32_t UniversalIndex)
1089  : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1090  SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
1091  DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
1092  DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
1093  HasPageZeroSegment(false) {
1094  ErrorAsOutParameter ErrAsOutParam(&Err);
1095  uint64_t SizeOfHeaders;
1096  uint32_t cputype;
1097  if (is64Bit()) {
1098  parseHeader(*this, Header64, Err);
1099  SizeOfHeaders = sizeof(MachO::mach_header_64);
1100  cputype = Header64.cputype;
1101  } else {
1102  parseHeader(*this, Header, Err);
1103  SizeOfHeaders = sizeof(MachO::mach_header);
1104  cputype = Header.cputype;
1105  }
1106  if (Err)
1107  return;
1108  SizeOfHeaders += getHeader().sizeofcmds;
1109  if (getData().data() + SizeOfHeaders > getData().end()) {
1110  Err = malformedError("load commands extend past the end of the file");
1111  return;
1112  }
1113  if (UniversalCputype != 0 && cputype != UniversalCputype) {
1114  Err = malformedError("universal header architecture: " +
1115  Twine(UniversalIndex) + "'s cputype does not match "
1116  "object file's mach header");
1117  return;
1118  }
1119  std::list<MachOElement> Elements;
1120  Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1121 
1122  uint32_t LoadCommandCount = getHeader().ncmds;
1123  LoadCommandInfo Load;
1124  if (LoadCommandCount != 0) {
1125  if (auto LoadOrErr = getFirstLoadCommandInfo(*this))
1126  Load = *LoadOrErr;
1127  else {
1128  Err = LoadOrErr.takeError();
1129  return;
1130  }
1131  }
1132 
1133  const char *DyldIdLoadCmd = nullptr;
1134  const char *FuncStartsLoadCmd = nullptr;
1135  const char *SplitInfoLoadCmd = nullptr;
1136  const char *CodeSignDrsLoadCmd = nullptr;
1137  const char *CodeSignLoadCmd = nullptr;
1138  const char *VersLoadCmd = nullptr;
1139  const char *SourceLoadCmd = nullptr;
1140  const char *EntryPointLoadCmd = nullptr;
1141  const char *EncryptLoadCmd = nullptr;
1142  const char *RoutinesLoadCmd = nullptr;
1143  const char *UnixThreadLoadCmd = nullptr;
1144  const char *TwoLevelHintsLoadCmd = nullptr;
1145  for (unsigned I = 0; I < LoadCommandCount; ++I) {
1146  if (is64Bit()) {
1147  if (Load.C.cmdsize % 8 != 0) {
1148  // We have a hack here to allow 64-bit Mach-O core files to have
1149  // LC_THREAD commands that are only a multiple of 4 and not 8 to be
1150  // allowed since the macOS kernel produces them.
1151  if (getHeader().filetype != MachO::MH_CORE ||
1152  Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1153  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1154  "multiple of 8");
1155  return;
1156  }
1157  }
1158  } else {
1159  if (Load.C.cmdsize % 4 != 0) {
1160  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1161  "multiple of 4");
1162  return;
1163  }
1164  }
1165  LoadCommands.push_back(Load);
1166  if (Load.C.cmd == MachO::LC_SYMTAB) {
1167  if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1168  return;
1169  } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1170  if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd,
1171  Elements)))
1172  return;
1173  } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1174  if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd,
1175  "LC_DATA_IN_CODE", Elements,
1176  "data in code info")))
1177  return;
1178  } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1179  if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd,
1180  "LC_LINKER_OPTIMIZATION_HINT",
1181  Elements, "linker optimization "
1182  "hints")))
1183  return;
1184  } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1185  if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd,
1186  "LC_FUNCTION_STARTS", Elements,
1187  "function starts data")))
1188  return;
1189  } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1190  if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd,
1191  "LC_SEGMENT_SPLIT_INFO", Elements,
1192  "split info data")))
1193  return;
1194  } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1195  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd,
1196  "LC_DYLIB_CODE_SIGN_DRS", Elements,
1197  "code signing RDs data")))
1198  return;
1199  } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1200  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd,
1201  "LC_CODE_SIGNATURE", Elements,
1202  "code signature data")))
1203  return;
1204  } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1205  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1206  "LC_DYLD_INFO", Elements)))
1207  return;
1208  } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1209  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1210  "LC_DYLD_INFO_ONLY", Elements)))
1211  return;
1212  } else if (Load.C.cmd == MachO::LC_UUID) {
1213  if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1214  Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1215  "cmdsize");
1216  return;
1217  }
1218  if (UuidLoadCmd) {
1219  Err = malformedError("more than one LC_UUID command");
1220  return;
1221  }
1222  UuidLoadCmd = Load.Ptr;
1223  } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1226  *this, Load, Sections, HasPageZeroSegment, I,
1227  "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1228  return;
1229  } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1231  MachO::section>(
1232  *this, Load, Sections, HasPageZeroSegment, I,
1233  "LC_SEGMENT", SizeOfHeaders, Elements)))
1234  return;
1235  } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1236  if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1237  return;
1238  } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1239  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1240  return;
1241  Libraries.push_back(Load.Ptr);
1242  } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1243  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1244  return;
1245  Libraries.push_back(Load.Ptr);
1246  } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1247  if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1248  return;
1249  Libraries.push_back(Load.Ptr);
1250  } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1251  if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1252  return;
1253  Libraries.push_back(Load.Ptr);
1254  } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1255  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1256  return;
1257  Libraries.push_back(Load.Ptr);
1258  } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1259  if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1260  return;
1261  } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1262  if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1263  return;
1264  } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1265  if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1266  return;
1267  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1268  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1269  "LC_VERSION_MIN_MACOSX")))
1270  return;
1271  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1272  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1273  "LC_VERSION_MIN_IPHONEOS")))
1274  return;
1275  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1276  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1277  "LC_VERSION_MIN_TVOS")))
1278  return;
1279  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1280  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1281  "LC_VERSION_MIN_WATCHOS")))
1282  return;
1283  } else if (Load.C.cmd == MachO::LC_RPATH) {
1284  if ((Err = checkRpathCommand(*this, Load, I)))
1285  return;
1286  } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1287  if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1288  Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1289  " has incorrect cmdsize");
1290  return;
1291  }
1292  if (SourceLoadCmd) {
1293  Err = malformedError("more than one LC_SOURCE_VERSION command");
1294  return;
1295  }
1296  SourceLoadCmd = Load.Ptr;
1297  } else if (Load.C.cmd == MachO::LC_MAIN) {
1298  if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1299  Err = malformedError("LC_MAIN command " + Twine(I) +
1300  " has incorrect cmdsize");
1301  return;
1302  }
1303  if (EntryPointLoadCmd) {
1304  Err = malformedError("more than one LC_MAIN command");
1305  return;
1306  }
1307  EntryPointLoadCmd = Load.Ptr;
1308  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1309  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1310  Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1311  " has incorrect cmdsize");
1312  return;
1313  }
1315  getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1316  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1317  &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1318  return;
1319  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1320  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1321  Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1322  " has incorrect cmdsize");
1323  return;
1324  }
1326  getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1327  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1328  &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1329  return;
1330  } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1331  if ((Err = checkLinkerOptCommand(*this, Load, I)))
1332  return;
1333  } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1334  if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1335  Err = malformedError("load command " + Twine(I) +
1336  " LC_SUB_FRAMEWORK cmdsize too small");
1337  return;
1338  }
1340  getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1341  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1343  "sub_framework_command", S.umbrella,
1344  "umbrella")))
1345  return;
1346  } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1347  if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1348  Err = malformedError("load command " + Twine(I) +
1349  " LC_SUB_UMBRELLA cmdsize too small");
1350  return;
1351  }
1353  getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1354  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1356  "sub_umbrella_command", S.sub_umbrella,
1357  "sub_umbrella")))
1358  return;
1359  } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1360  if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1361  Err = malformedError("load command " + Twine(I) +
1362  " LC_SUB_LIBRARY cmdsize too small");
1363  return;
1364  }
1366  getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1367  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1369  "sub_library_command", S.sub_library,
1370  "sub_library")))
1371  return;
1372  } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1373  if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1374  Err = malformedError("load command " + Twine(I) +
1375  " LC_SUB_CLIENT cmdsize too small");
1376  return;
1377  }
1379  getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1380  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1381  sizeof(MachO::sub_client_command),
1382  "sub_client_command", S.client, "client")))
1383  return;
1384  } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1385  if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1386  Err = malformedError("LC_ROUTINES command " + Twine(I) +
1387  " has incorrect cmdsize");
1388  return;
1389  }
1390  if (RoutinesLoadCmd) {
1391  Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1392  "command");
1393  return;
1394  }
1395  RoutinesLoadCmd = Load.Ptr;
1396  } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1397  if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1398  Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1399  " has incorrect cmdsize");
1400  return;
1401  }
1402  if (RoutinesLoadCmd) {
1403  Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1404  "command");
1405  return;
1406  }
1407  RoutinesLoadCmd = Load.Ptr;
1408  } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1409  if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1410  return;
1411  if (UnixThreadLoadCmd) {
1412  Err = malformedError("more than one LC_UNIXTHREAD command");
1413  return;
1414  }
1415  UnixThreadLoadCmd = Load.Ptr;
1416  } else if (Load.C.cmd == MachO::LC_THREAD) {
1417  if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1418  return;
1419  // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1420  } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1421  if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1422  &TwoLevelHintsLoadCmd, Elements)))
1423  return;
1424  } else if (isLoadCommandObsolete(Load.C.cmd)) {
1425  Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1426  Twine(Load.C.cmd) + " is obsolete and not "
1427  "supported");
1428  return;
1429  }
1430  // TODO: generate a error for unknown load commands by default. But still
1431  // need work out an approach to allow or not allow unknown values like this
1432  // as an option for some uses like lldb.
1433  if (I < LoadCommandCount - 1) {
1434  if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1435  Load = *LoadOrErr;
1436  else {
1437  Err = LoadOrErr.takeError();
1438  return;
1439  }
1440  }
1441  }
1442  if (!SymtabLoadCmd) {
1443  if (DysymtabLoadCmd) {
1444  Err = malformedError("contains LC_DYSYMTAB load command without a "
1445  "LC_SYMTAB load command");
1446  return;
1447  }
1448  } else if (DysymtabLoadCmd) {
1449  MachO::symtab_command Symtab =
1450  getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1451  MachO::dysymtab_command Dysymtab =
1452  getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1453  if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1454  Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1455  "extends past the end of the symbol table");
1456  return;
1457  }
1458  uint64_t BigSize = Dysymtab.ilocalsym;
1459  BigSize += Dysymtab.nlocalsym;
1460  if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1461  Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1462  "command extends past the end of the symbol table");
1463  return;
1464  }
1465  if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1466  Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
1467  "extends past the end of the symbol table");
1468  return;
1469  }
1470  BigSize = Dysymtab.iextdefsym;
1471  BigSize += Dysymtab.nextdefsym;
1472  if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1473  Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1474  "load command extends past the end of the symbol "
1475  "table");
1476  return;
1477  }
1478  if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1479  Err = malformedError("nundefsym in LC_DYSYMTAB load command "
1480  "extends past the end of the symbol table");
1481  return;
1482  }
1483  BigSize = Dysymtab.iundefsym;
1484  BigSize += Dysymtab.nundefsym;
1485  if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1486  Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1487  " command extends past the end of the symbol table");
1488  return;
1489  }
1490  }
1491  if ((getHeader().filetype == MachO::MH_DYLIB ||
1492  getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1493  DyldIdLoadCmd == nullptr) {
1494  Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1495  "filetype");
1496  return;
1497  }
1498  assert(LoadCommands.size() == LoadCommandCount);
1499 
1500  Err = Error::success();
1501 }
1502 
1504  uint32_t Flags = 0;
1505  if (is64Bit()) {
1507  Flags = H_64.flags;
1508  } else {
1510  Flags = H.flags;
1511  }
1512  uint8_t NType = 0;
1513  uint8_t NSect = 0;
1514  uint16_t NDesc = 0;
1515  uint32_t NStrx = 0;
1516  uint64_t NValue = 0;
1517  uint32_t SymbolIndex = 0;
1519  for (const SymbolRef &Symbol : symbols()) {
1520  DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1521  if (is64Bit()) {
1522  MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1523  NType = STE_64.n_type;
1524  NSect = STE_64.n_sect;
1525  NDesc = STE_64.n_desc;
1526  NStrx = STE_64.n_strx;
1527  NValue = STE_64.n_value;
1528  } else {
1529  MachO::nlist STE = getSymbolTableEntry(SymDRI);
1530  NType = STE.n_type;
1531  NType = STE.n_type;
1532  NSect = STE.n_sect;
1533  NDesc = STE.n_desc;
1534  NStrx = STE.n_strx;
1535  NValue = STE.n_value;
1536  }
1537  if ((NType & MachO::N_STAB) == 0 &&
1538  (NType & MachO::N_TYPE) == MachO::N_SECT) {
1539  if (NSect == 0 || NSect > Sections.size())
1540  return malformedError("bad section index: " + Twine((int)NSect) +
1541  " for symbol at index " + Twine(SymbolIndex));
1542  }
1543  if ((NType & MachO::N_STAB) == 0 &&
1544  (NType & MachO::N_TYPE) == MachO::N_INDR) {
1545  if (NValue >= S.strsize)
1546  return malformedError("bad n_value: " + Twine((int)NValue) + " past "
1547  "the end of string table, for N_INDR symbol at "
1548  "index " + Twine(SymbolIndex));
1549  }
1550  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
1551  (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
1552  (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
1553  uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
1554  if (LibraryOrdinal != 0 &&
1555  LibraryOrdinal != MachO::EXECUTABLE_ORDINAL &&
1556  LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL &&
1557  LibraryOrdinal - 1 >= Libraries.size() ) {
1558  return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) +
1559  " for symbol at index " + Twine(SymbolIndex));
1560  }
1561  }
1562  if (NStrx >= S.strsize)
1563  return malformedError("bad string table index: " + Twine((int)NStrx) +
1564  " past the end of string table, for symbol at "
1565  "index " + Twine(SymbolIndex));
1566  SymbolIndex++;
1567  }
1568  return Error::success();
1569 }
1570 
1572  unsigned SymbolTableEntrySize = is64Bit() ?
1573  sizeof(MachO::nlist_64) :
1574  sizeof(MachO::nlist);
1575  Symb.p += SymbolTableEntrySize;
1576 }
1577 
1579  StringRef StringTable = getStringTableData();
1580  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1581  const char *Start = &StringTable.data()[Entry.n_strx];
1582  if (Start < getData().begin() || Start >= getData().end()) {
1583  return malformedError("bad string index: " + Twine(Entry.n_strx) +
1584  " for symbol at index " + Twine(getSymbolIndex(Symb)));
1585  }
1586  return StringRef(Start);
1587 }
1588 
1590  DataRefImpl DRI = Sec.getRawDataRefImpl();
1591  uint32_t Flags = getSectionFlags(*this, DRI);
1592  return Flags & MachO::SECTION_TYPE;
1593 }
1594 
1596  if (is64Bit()) {
1598  return Entry.n_value;
1599  }
1600  MachO::nlist Entry = getSymbolTableEntry(Sym);
1601  return Entry.n_value;
1602 }
1603 
1604 // getIndirectName() returns the name of the alias'ed symbol who's string table
1605 // index is in the n_value field.
1607  StringRef &Res) const {
1608  StringRef StringTable = getStringTableData();
1609  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1610  if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1612  uint64_t NValue = getNValue(Symb);
1613  if (NValue >= StringTable.size())
1615  const char *Start = &StringTable.data()[NValue];
1616  Res = StringRef(Start);
1617  return std::error_code();
1618 }
1619 
1620 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1621  return getNValue(Sym);
1622 }
1623 
1625  return getSymbolValue(Sym);
1626 }
1627 
1629  uint32_t flags = getSymbolFlags(DRI);
1630  if (flags & SymbolRef::SF_Common) {
1631  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1632  return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1633  }
1634  return 0;
1635 }
1636 
1638  return getNValue(DRI);
1639 }
1640 
1643  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1644  uint8_t n_type = Entry.n_type;
1645 
1646  // If this is a STAB debugging symbol, we can do nothing more.
1647  if (n_type & MachO::N_STAB)
1648  return SymbolRef::ST_Debug;
1649 
1650  switch (n_type & MachO::N_TYPE) {
1651  case MachO::N_UNDF :
1652  return SymbolRef::ST_Unknown;
1653  case MachO::N_SECT :
1654  Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1655  if (!SecOrError)
1656  return SecOrError.takeError();
1657  section_iterator Sec = *SecOrError;
1658  if (Sec->isData() || Sec->isBSS())
1659  return SymbolRef::ST_Data;
1660  return SymbolRef::ST_Function;
1661  }
1662  return SymbolRef::ST_Other;
1663 }
1664 
1666  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1667 
1668  uint8_t MachOType = Entry.n_type;
1669  uint16_t MachOFlags = Entry.n_desc;
1670 
1671  uint32_t Result = SymbolRef::SF_None;
1672 
1673  if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1674  Result |= SymbolRef::SF_Indirect;
1675 
1676  if (MachOType & MachO::N_STAB)
1677  Result |= SymbolRef::SF_FormatSpecific;
1678 
1679  if (MachOType & MachO::N_EXT) {
1680  Result |= SymbolRef::SF_Global;
1681  if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1682  if (getNValue(DRI))
1683  Result |= SymbolRef::SF_Common;
1684  else
1685  Result |= SymbolRef::SF_Undefined;
1686  }
1687 
1688  if (!(MachOType & MachO::N_PEXT))
1689  Result |= SymbolRef::SF_Exported;
1690  }
1691 
1692  if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1693  Result |= SymbolRef::SF_Weak;
1694 
1695  if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1696  Result |= SymbolRef::SF_Thumb;
1697 
1698  if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1699  Result |= SymbolRef::SF_Absolute;
1700 
1701  return Result;
1702 }
1703 
1706  MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1707  uint8_t index = Entry.n_sect;
1708 
1709  if (index == 0)
1710  return section_end();
1711  DataRefImpl DRI;
1712  DRI.d.a = index - 1;
1713  if (DRI.d.a >= Sections.size()){
1714  return malformedError("bad section index: " + Twine((int)index) +
1715  " for symbol at index " + Twine(getSymbolIndex(Symb)));
1716  }
1717  return section_iterator(SectionRef(DRI, this));
1718 }
1719 
1721  MachO::nlist_base Entry =
1723  return Entry.n_sect - 1;
1724 }
1725 
1727  Sec.d.a++;
1728 }
1729 
1731  StringRef &Result) const {
1732  ArrayRef<char> Raw = getSectionRawName(Sec);
1733  Result = parseSegmentOrSectionName(Raw.data());
1734  return std::error_code();
1735 }
1736 
1738  if (is64Bit())
1739  return getSection64(Sec).addr;
1740  return getSection(Sec).addr;
1741 }
1742 
1744  // In the case if a malformed Mach-O file where the section offset is past
1745  // the end of the file or some part of the section size is past the end of
1746  // the file return a size of zero or a size that covers the rest of the file
1747  // but does not extend past the end of the file.
1748  uint32_t SectOffset, SectType;
1749  uint64_t SectSize;
1750 
1751  if (is64Bit()) {
1752  MachO::section_64 Sect = getSection64(Sec);
1753  SectOffset = Sect.offset;
1754  SectSize = Sect.size;
1755  SectType = Sect.flags & MachO::SECTION_TYPE;
1756  } else {
1757  MachO::section Sect = getSection(Sec);
1758  SectOffset = Sect.offset;
1759  SectSize = Sect.size;
1760  SectType = Sect.flags & MachO::SECTION_TYPE;
1761  }
1762  if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1763  return SectSize;
1764  uint64_t FileSize = getData().size();
1765  if (SectOffset > FileSize)
1766  return 0;
1767  if (FileSize - SectOffset < SectSize)
1768  return FileSize - SectOffset;
1769  return SectSize;
1770 }
1771 
1773  StringRef &Res) const {
1774  uint32_t Offset;
1775  uint64_t Size;
1776 
1777  if (is64Bit()) {
1778  MachO::section_64 Sect = getSection64(Sec);
1779  Offset = Sect.offset;
1780  Size = Sect.size;
1781  } else {
1782  MachO::section Sect = getSection(Sec);
1783  Offset = Sect.offset;
1784  Size = Sect.size;
1785  }
1786 
1787  Res = this->getData().substr(Offset, Size);
1788  return std::error_code();
1789 }
1790 
1792  uint32_t Align;
1793  if (is64Bit()) {
1794  MachO::section_64 Sect = getSection64(Sec);
1795  Align = Sect.align;
1796  } else {
1797  MachO::section Sect = getSection(Sec);
1798  Align = Sect.align;
1799  }
1800 
1801  return uint64_t(1) << Align;
1802 }
1803 
1805  return false;
1806 }
1807 
1809  uint32_t Flags = getSectionFlags(*this, Sec);
1810  return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
1811 }
1812 
1814  uint32_t Flags = getSectionFlags(*this, Sec);
1815  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1816  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1817  !(SectionType == MachO::S_ZEROFILL ||
1818  SectionType == MachO::S_GB_ZEROFILL);
1819 }
1820 
1822  uint32_t Flags = getSectionFlags(*this, Sec);
1823  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1824  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1825  (SectionType == MachO::S_ZEROFILL ||
1826  SectionType == MachO::S_GB_ZEROFILL);
1827 }
1828 
1830  return Sec.getRawDataRefImpl().d.a;
1831 }
1832 
1834  // FIXME: Unimplemented.
1835  return false;
1836 }
1837 
1839  StringRef SegmentName = getSectionFinalSegmentName(Sec);
1840  StringRef SectName;
1841  if (!getSectionName(Sec, SectName))
1842  return (SegmentName == "__LLVM" && SectName == "__bitcode");
1843  return false;
1844 }
1845 
1847  DataRefImpl Ret;
1848  Ret.d.a = Sec.d.a;
1849  Ret.d.b = 0;
1850  return relocation_iterator(RelocationRef(Ret, this));
1851 }
1852 
1855  uint32_t Num;
1856  if (is64Bit()) {
1857  MachO::section_64 Sect = getSection64(Sec);
1858  Num = Sect.nreloc;
1859  } else {
1860  MachO::section Sect = getSection(Sec);
1861  Num = Sect.nreloc;
1862  }
1863 
1864  DataRefImpl Ret;
1865  Ret.d.a = Sec.d.a;
1866  Ret.d.b = Num;
1867  return relocation_iterator(RelocationRef(Ret, this));
1868 }
1869 
1871  ++Rel.d.b;
1872 }
1873 
1875  assert(getHeader().filetype == MachO::MH_OBJECT &&
1876  "Only implemented for MH_OBJECT");
1878  return getAnyRelocationAddress(RE);
1879 }
1880 
1884  if (isRelocationScattered(RE))
1885  return symbol_end();
1886 
1887  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
1888  bool isExtern = getPlainRelocationExternal(RE);
1889  if (!isExtern)
1890  return symbol_end();
1891 
1893  unsigned SymbolTableEntrySize = is64Bit() ?
1894  sizeof(MachO::nlist_64) :
1895  sizeof(MachO::nlist);
1896  uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
1897  DataRefImpl Sym;
1898  Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
1899  return symbol_iterator(SymbolRef(Sym, this));
1900 }
1901 
1905 }
1906 
1909  return getAnyRelocationType(RE);
1910 }
1911 
1913  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1914  StringRef res;
1915  uint64_t RType = getRelocationType(Rel);
1916 
1917  unsigned Arch = this->getArch();
1918 
1919  switch (Arch) {
1920  case Triple::x86: {
1921  static const char *const Table[] = {
1922  "GENERIC_RELOC_VANILLA",
1923  "GENERIC_RELOC_PAIR",
1924  "GENERIC_RELOC_SECTDIFF",
1925  "GENERIC_RELOC_PB_LA_PTR",
1926  "GENERIC_RELOC_LOCAL_SECTDIFF",
1927  "GENERIC_RELOC_TLV" };
1928 
1929  if (RType > 5)
1930  res = "Unknown";
1931  else
1932  res = Table[RType];
1933  break;
1934  }
1935  case Triple::x86_64: {
1936  static const char *const Table[] = {
1937  "X86_64_RELOC_UNSIGNED",
1938  "X86_64_RELOC_SIGNED",
1939  "X86_64_RELOC_BRANCH",
1940  "X86_64_RELOC_GOT_LOAD",
1941  "X86_64_RELOC_GOT",
1942  "X86_64_RELOC_SUBTRACTOR",
1943  "X86_64_RELOC_SIGNED_1",
1944  "X86_64_RELOC_SIGNED_2",
1945  "X86_64_RELOC_SIGNED_4",
1946  "X86_64_RELOC_TLV" };
1947 
1948  if (RType > 9)
1949  res = "Unknown";
1950  else
1951  res = Table[RType];
1952  break;
1953  }
1954  case Triple::arm: {
1955  static const char *const Table[] = {
1956  "ARM_RELOC_VANILLA",
1957  "ARM_RELOC_PAIR",
1958  "ARM_RELOC_SECTDIFF",
1959  "ARM_RELOC_LOCAL_SECTDIFF",
1960  "ARM_RELOC_PB_LA_PTR",
1961  "ARM_RELOC_BR24",
1962  "ARM_THUMB_RELOC_BR22",
1963  "ARM_THUMB_32BIT_BRANCH",
1964  "ARM_RELOC_HALF",
1965  "ARM_RELOC_HALF_SECTDIFF" };
1966 
1967  if (RType > 9)
1968  res = "Unknown";
1969  else
1970  res = Table[RType];
1971  break;
1972  }
1973  case Triple::aarch64: {
1974  static const char *const Table[] = {
1975  "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
1976  "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
1977  "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
1978  "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
1979  "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
1980  "ARM64_RELOC_ADDEND"
1981  };
1982 
1983  if (RType >= array_lengthof(Table))
1984  res = "Unknown";
1985  else
1986  res = Table[RType];
1987  break;
1988  }
1989  case Triple::ppc: {
1990  static const char *const Table[] = {
1991  "PPC_RELOC_VANILLA",
1992  "PPC_RELOC_PAIR",
1993  "PPC_RELOC_BR14",
1994  "PPC_RELOC_BR24",
1995  "PPC_RELOC_HI16",
1996  "PPC_RELOC_LO16",
1997  "PPC_RELOC_HA16",
1998  "PPC_RELOC_LO14",
1999  "PPC_RELOC_SECTDIFF",
2000  "PPC_RELOC_PB_LA_PTR",
2001  "PPC_RELOC_HI16_SECTDIFF",
2002  "PPC_RELOC_LO16_SECTDIFF",
2003  "PPC_RELOC_HA16_SECTDIFF",
2004  "PPC_RELOC_JBSR",
2005  "PPC_RELOC_LO14_SECTDIFF",
2006  "PPC_RELOC_LOCAL_SECTDIFF" };
2007 
2008  if (RType > 15)
2009  res = "Unknown";
2010  else
2011  res = Table[RType];
2012  break;
2013  }
2014  case Triple::UnknownArch:
2015  res = "Unknown";
2016  break;
2017  }
2018  Result.append(res.begin(), res.end());
2019 }
2020 
2023  return getAnyRelocationLength(RE);
2024 }
2025 
2026 //
2027 // guessLibraryShortName() is passed a name of a dynamic library and returns a
2028 // guess on what the short name is. Then name is returned as a substring of the
2029 // StringRef Name passed in. The name of the dynamic library is recognized as
2030 // a framework if it has one of the two following forms:
2031 // Foo.framework/Versions/A/Foo
2032 // Foo.framework/Foo
2033 // Where A and Foo can be any string. And may contain a trailing suffix
2034 // starting with an underbar. If the Name is recognized as a framework then
2035 // isFramework is set to true else it is set to false. If the Name has a
2036 // suffix then Suffix is set to the substring in Name that contains the suffix
2037 // else it is set to a NULL StringRef.
2038 //
2039 // The Name of the dynamic library is recognized as a library name if it has
2040 // one of the two following forms:
2041 // libFoo.A.dylib
2042 // libFoo.dylib
2043 // The library may have a suffix trailing the name Foo of the form:
2044 // libFoo_profile.A.dylib
2045 // libFoo_profile.dylib
2046 //
2047 // The Name of the dynamic library is also recognized as a library name if it
2048 // has the following form:
2049 // Foo.qtx
2050 //
2051 // If the Name of the dynamic library is none of the forms above then a NULL
2052 // StringRef is returned.
2053 //
2055  bool &isFramework,
2056  StringRef &Suffix) {
2057  StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2058  size_t a, b, c, d, Idx;
2059 
2060  isFramework = false;
2061  Suffix = StringRef();
2062 
2063  // Pull off the last component and make Foo point to it
2064  a = Name.rfind('/');
2065  if (a == Name.npos || a == 0)
2066  goto guess_library;
2067  Foo = Name.slice(a+1, Name.npos);
2068 
2069  // Look for a suffix starting with a '_'
2070  Idx = Foo.rfind('_');
2071  if (Idx != Foo.npos && Foo.size() >= 2) {
2072  Suffix = Foo.slice(Idx, Foo.npos);
2073  Foo = Foo.slice(0, Idx);
2074  }
2075 
2076  // First look for the form Foo.framework/Foo
2077  b = Name.rfind('/', a);
2078  if (b == Name.npos)
2079  Idx = 0;
2080  else
2081  Idx = b+1;
2082  F = Name.slice(Idx, Idx + Foo.size());
2083  DotFramework = Name.slice(Idx + Foo.size(),
2084  Idx + Foo.size() + sizeof(".framework/")-1);
2085  if (F == Foo && DotFramework == ".framework/") {
2086  isFramework = true;
2087  return Foo;
2088  }
2089 
2090  // Next look for the form Foo.framework/Versions/A/Foo
2091  if (b == Name.npos)
2092  goto guess_library;
2093  c = Name.rfind('/', b);
2094  if (c == Name.npos || c == 0)
2095  goto guess_library;
2096  V = Name.slice(c+1, Name.npos);
2097  if (!V.startswith("Versions/"))
2098  goto guess_library;
2099  d = Name.rfind('/', c);
2100  if (d == Name.npos)
2101  Idx = 0;
2102  else
2103  Idx = d+1;
2104  F = Name.slice(Idx, Idx + Foo.size());
2105  DotFramework = Name.slice(Idx + Foo.size(),
2106  Idx + Foo.size() + sizeof(".framework/")-1);
2107  if (F == Foo && DotFramework == ".framework/") {
2108  isFramework = true;
2109  return Foo;
2110  }
2111 
2112 guess_library:
2113  // pull off the suffix after the "." and make a point to it
2114  a = Name.rfind('.');
2115  if (a == Name.npos || a == 0)
2116  return StringRef();
2117  Dylib = Name.slice(a, Name.npos);
2118  if (Dylib != ".dylib")
2119  goto guess_qtx;
2120 
2121  // First pull off the version letter for the form Foo.A.dylib if any.
2122  if (a >= 3) {
2123  Dot = Name.slice(a-2, a-1);
2124  if (Dot == ".")
2125  a = a - 2;
2126  }
2127 
2128  b = Name.rfind('/', a);
2129  if (b == Name.npos)
2130  b = 0;
2131  else
2132  b = b+1;
2133  // ignore any suffix after an underbar like Foo_profile.A.dylib
2134  Idx = Name.find('_', b);
2135  if (Idx != Name.npos && Idx != b) {
2136  Lib = Name.slice(b, Idx);
2137  Suffix = Name.slice(Idx, a);
2138  }
2139  else
2140  Lib = Name.slice(b, a);
2141  // There are incorrect library names of the form:
2142  // libATS.A_profile.dylib so check for these.
2143  if (Lib.size() >= 3) {
2144  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2145  if (Dot == ".")
2146  Lib = Lib.slice(0, Lib.size()-2);
2147  }
2148  return Lib;
2149 
2150 guess_qtx:
2151  Qtx = Name.slice(a, Name.npos);
2152  if (Qtx != ".qtx")
2153  return StringRef();
2154  b = Name.rfind('/', a);
2155  if (b == Name.npos)
2156  Lib = Name.slice(0, a);
2157  else
2158  Lib = Name.slice(b+1, a);
2159  // There are library names of the form: QT.A.qtx so check for these.
2160  if (Lib.size() >= 3) {
2161  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2162  if (Dot == ".")
2163  Lib = Lib.slice(0, Lib.size()-2);
2164  }
2165  return Lib;
2166 }
2167 
2168 // getLibraryShortNameByIndex() is used to get the short name of the library
2169 // for an undefined symbol in a linked Mach-O binary that was linked with the
2170 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
2171 // It is passed the index (0 - based) of the library as translated from
2172 // GET_LIBRARY_ORDINAL (1 - based).
2173 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
2174  StringRef &Res) const {
2175  if (Index >= Libraries.size())
2177 
2178  // If the cache of LibrariesShortNames is not built up do that first for
2179  // all the Libraries.
2180  if (LibrariesShortNames.size() == 0) {
2181  for (unsigned i = 0; i < Libraries.size(); i++) {
2183  getStruct<MachO::dylib_command>(*this, Libraries[i]);
2184  if (D.dylib.name >= D.cmdsize)
2186  const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2187  StringRef Name = StringRef(P);
2188  if (D.dylib.name+Name.size() >= D.cmdsize)
2190  StringRef Suffix;
2191  bool isFramework;
2192  StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2193  if (shortName.empty())
2194  LibrariesShortNames.push_back(Name);
2195  else
2196  LibrariesShortNames.push_back(shortName);
2197  }
2198  }
2199 
2200  Res = LibrariesShortNames[Index];
2201  return std::error_code();
2202 }
2203 
2206  DataRefImpl Sec;
2207  Sec.d.a = Rel->getRawDataRefImpl().d.a;
2208  return section_iterator(SectionRef(Sec, this));
2209 }
2210 
2212  DataRefImpl DRI;
2214  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2215  return basic_symbol_iterator(SymbolRef(DRI, this));
2216 
2217  return getSymbolByIndex(0);
2218 }
2219 
2221  DataRefImpl DRI;
2223  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2224  return basic_symbol_iterator(SymbolRef(DRI, this));
2225 
2226  unsigned SymbolTableEntrySize = is64Bit() ?
2227  sizeof(MachO::nlist_64) :
2228  sizeof(MachO::nlist);
2229  unsigned Offset = Symtab.symoff +
2230  Symtab.nsyms * SymbolTableEntrySize;
2231  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2232  return basic_symbol_iterator(SymbolRef(DRI, this));
2233 }
2234 
2237  if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2238  report_fatal_error("Requested symbol index is out of range.");
2239  unsigned SymbolTableEntrySize =
2240  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2241  DataRefImpl DRI;
2242  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2243  DRI.p += Index * SymbolTableEntrySize;
2244  return basic_symbol_iterator(SymbolRef(DRI, this));
2245 }
2246 
2249  if (!SymtabLoadCmd)
2250  report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2251  unsigned SymbolTableEntrySize =
2252  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2253  DataRefImpl DRIstart;
2254  DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2255  uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2256  return Index;
2257 }
2258 
2260  DataRefImpl DRI;
2261  return section_iterator(SectionRef(DRI, this));
2262 }
2263 
2265  DataRefImpl DRI;
2266  DRI.d.a = Sections.size();
2267  return section_iterator(SectionRef(DRI, this));
2268 }
2269 
2271  return is64Bit() ? 8 : 4;
2272 }
2273 
2275  unsigned CPUType = getCPUType(*this);
2276  if (!is64Bit()) {
2277  switch (CPUType) {
2279  return "Mach-O 32-bit i386";
2281  return "Mach-O arm";
2283  return "Mach-O 32-bit ppc";
2284  default:
2285  return "Mach-O 32-bit unknown";
2286  }
2287  }
2288 
2289  switch (CPUType) {
2291  return "Mach-O 64-bit x86-64";
2293  return "Mach-O arm64";
2295  return "Mach-O 64-bit ppc64";
2296  default:
2297  return "Mach-O 64-bit unknown";
2298  }
2299 }
2300 
2302  switch (CPUType) {
2304  return Triple::x86;
2306  return Triple::x86_64;
2308  return Triple::arm;
2310  return Triple::aarch64;
2312  return Triple::ppc;
2314  return Triple::ppc64;
2315  default:
2316  return Triple::UnknownArch;
2317  }
2318 }
2319 
2321  const char **McpuDefault,
2322  const char **ArchFlag) {
2323  if (McpuDefault)
2324  *McpuDefault = nullptr;
2325  if (ArchFlag)
2326  *ArchFlag = nullptr;
2327 
2328  switch (CPUType) {
2329  case MachO::CPU_TYPE_I386:
2330  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2332  if (ArchFlag)
2333  *ArchFlag = "i386";
2334  return Triple("i386-apple-darwin");
2335  default:
2336  return Triple();
2337  }
2339  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2341  if (ArchFlag)
2342  *ArchFlag = "x86_64";
2343  return Triple("x86_64-apple-darwin");
2345  if (ArchFlag)
2346  *ArchFlag = "x86_64h";
2347  return Triple("x86_64h-apple-darwin");
2348  default:
2349  return Triple();
2350  }
2351  case MachO::CPU_TYPE_ARM:
2352  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2354  if (ArchFlag)
2355  *ArchFlag = "armv4t";
2356  return Triple("armv4t-apple-darwin");
2358  if (ArchFlag)
2359  *ArchFlag = "armv5e";
2360  return Triple("armv5e-apple-darwin");
2362  if (ArchFlag)
2363  *ArchFlag = "xscale";
2364  return Triple("xscale-apple-darwin");
2366  if (ArchFlag)
2367  *ArchFlag = "armv6";
2368  return Triple("armv6-apple-darwin");
2370  if (McpuDefault)
2371  *McpuDefault = "cortex-m0";
2372  if (ArchFlag)
2373  *ArchFlag = "armv6m";
2374  return Triple("armv6m-apple-darwin");
2376  if (ArchFlag)
2377  *ArchFlag = "armv7";
2378  return Triple("armv7-apple-darwin");
2380  if (McpuDefault)
2381  *McpuDefault = "cortex-m4";
2382  if (ArchFlag)
2383  *ArchFlag = "armv7em";
2384  return Triple("thumbv7em-apple-darwin");
2386  if (ArchFlag)
2387  *ArchFlag = "armv7k";
2388  return Triple("armv7k-apple-darwin");
2390  if (McpuDefault)
2391  *McpuDefault = "cortex-m3";
2392  if (ArchFlag)
2393  *ArchFlag = "armv7m";
2394  return Triple("thumbv7m-apple-darwin");
2396  if (ArchFlag)
2397  *ArchFlag = "armv7s";
2398  return Triple("armv7s-apple-darwin");
2399  default:
2400  return Triple();
2401  }
2402  case MachO::CPU_TYPE_ARM64:
2403  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2405  if (ArchFlag)
2406  *ArchFlag = "arm64";
2407  return Triple("arm64-apple-darwin");
2408  default:
2409  return Triple();
2410  }
2412  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2414  if (ArchFlag)
2415  *ArchFlag = "ppc";
2416  return Triple("ppc-apple-darwin");
2417  default:
2418  return Triple();
2419  }
2421  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2423  if (ArchFlag)
2424  *ArchFlag = "ppc64";
2425  return Triple("ppc64-apple-darwin");
2426  default:
2427  return Triple();
2428  }
2429  default:
2430  return Triple();
2431  }
2432 }
2433 
2436 }
2437 
2439  return StringSwitch<bool>(ArchFlag)
2440  .Case("i386", true)
2441  .Case("x86_64", true)
2442  .Case("x86_64h", true)
2443  .Case("armv4t", true)
2444  .Case("arm", true)
2445  .Case("armv5e", true)
2446  .Case("armv6", true)
2447  .Case("armv6m", true)
2448  .Case("armv7", true)
2449  .Case("armv7em", true)
2450  .Case("armv7k", true)
2451  .Case("armv7m", true)
2452  .Case("armv7s", true)
2453  .Case("arm64", true)
2454  .Case("ppc", true)
2455  .Case("ppc64", true)
2456  .Default(false);
2457 }
2458 
2459 unsigned MachOObjectFile::getArch() const {
2460  return getArch(getCPUType(*this));
2461 }
2462 
2463 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2464  return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2465 }
2466 
2468  DataRefImpl DRI;
2469  DRI.d.a = Index;
2470  return section_rel_begin(DRI);
2471 }
2472 
2474  DataRefImpl DRI;
2475  DRI.d.a = Index;
2476  return section_rel_end(DRI);
2477 }
2478 
2480  DataRefImpl DRI;
2481  if (!DataInCodeLoadCmd)
2482  return dice_iterator(DiceRef(DRI, this));
2483 
2485  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2486  return dice_iterator(DiceRef(DRI, this));
2487 }
2488 
2490  DataRefImpl DRI;
2491  if (!DataInCodeLoadCmd)
2492  return dice_iterator(DiceRef(DRI, this));
2493 
2495  unsigned Offset = DicLC.dataoff + DicLC.datasize;
2496  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2497  return dice_iterator(DiceRef(DRI, this));
2498 }
2499 
2501  : Trie(T), Malformed(false), Done(false) {}
2502 
2503 void ExportEntry::moveToFirst() {
2504  pushNode(0);
2505  pushDownUntilBottom();
2506 }
2507 
2508 void ExportEntry::moveToEnd() {
2509  Stack.clear();
2510  Done = true;
2511 }
2512 
2514  // Common case, one at end, other iterating from begin.
2515  if (Done || Other.Done)
2516  return (Done == Other.Done);
2517  // Not equal if different stack sizes.
2518  if (Stack.size() != Other.Stack.size())
2519  return false;
2520  // Not equal if different cumulative strings.
2521  if (!CumulativeString.equals(Other.CumulativeString))
2522  return false;
2523  // Equal if all nodes in both stacks match.
2524  for (unsigned i=0; i < Stack.size(); ++i) {
2525  if (Stack[i].Start != Other.Stack[i].Start)
2526  return false;
2527  }
2528  return true;
2529 }
2530 
2531 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
2532  unsigned Count;
2533  uint64_t Result = decodeULEB128(Ptr, &Count);
2534  Ptr += Count;
2535  if (Ptr > Trie.end()) {
2536  Ptr = Trie.end();
2537  Malformed = true;
2538  }
2539  return Result;
2540 }
2541 
2543  return CumulativeString;
2544 }
2545 
2546 uint64_t ExportEntry::flags() const {
2547  return Stack.back().Flags;
2548 }
2549 
2550 uint64_t ExportEntry::address() const {
2551  return Stack.back().Address;
2552 }
2553 
2554 uint64_t ExportEntry::other() const {
2555  return Stack.back().Other;
2556 }
2557 
2559  const char* ImportName = Stack.back().ImportName;
2560  if (ImportName)
2561  return StringRef(ImportName);
2562  return StringRef();
2563 }
2564 
2566  return Stack.back().Start - Trie.begin();
2567 }
2568 
2569 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2570  : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
2571  ImportName(nullptr), ChildCount(0), NextChildIndex(0),
2572  ParentStringLength(0), IsExportNode(false) {}
2573 
2574 void ExportEntry::pushNode(uint64_t offset) {
2575  const uint8_t *Ptr = Trie.begin() + offset;
2576  NodeState State(Ptr);
2577  uint64_t ExportInfoSize = readULEB128(State.Current);
2578  State.IsExportNode = (ExportInfoSize != 0);
2579  const uint8_t* Children = State.Current + ExportInfoSize;
2580  if (State.IsExportNode) {
2581  State.Flags = readULEB128(State.Current);
2582  if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2583  State.Address = 0;
2584  State.Other = readULEB128(State.Current); // dylib ordinal
2585  State.ImportName = reinterpret_cast<const char*>(State.Current);
2586  } else {
2587  State.Address = readULEB128(State.Current);
2589  State.Other = readULEB128(State.Current);
2590  }
2591  }
2592  State.ChildCount = *Children;
2593  State.Current = Children + 1;
2594  State.NextChildIndex = 0;
2595  State.ParentStringLength = CumulativeString.size();
2596  Stack.push_back(State);
2597 }
2598 
2599 void ExportEntry::pushDownUntilBottom() {
2600  while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2601  NodeState &Top = Stack.back();
2602  CumulativeString.resize(Top.ParentStringLength);
2603  for (;*Top.Current != 0; Top.Current++) {
2604  char C = *Top.Current;
2605  CumulativeString.push_back(C);
2606  }
2607  Top.Current += 1;
2608  uint64_t childNodeIndex = readULEB128(Top.Current);
2609  Top.NextChildIndex += 1;
2610  pushNode(childNodeIndex);
2611  }
2612  if (!Stack.back().IsExportNode) {
2613  Malformed = true;
2614  moveToEnd();
2615  }
2616 }
2617 
2618 // We have a trie data structure and need a way to walk it that is compatible
2619 // with the C++ iterator model. The solution is a non-recursive depth first
2620 // traversal where the iterator contains a stack of parent nodes along with a
2621 // string that is the accumulation of all edge strings along the parent chain
2622 // to this point.
2623 //
2624 // There is one "export" node for each exported symbol. But because some
2625 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
2626 // node may have child nodes too.
2627 //
2628 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
2629 // child until hitting a node with no children (which is an export node or
2630 // else the trie is malformed). On the way down, each node is pushed on the
2631 // stack ivar. If there is no more ways down, it pops up one and tries to go
2632 // down a sibling path until a childless node is reached.
2634  if (Stack.empty() || !Stack.back().IsExportNode) {
2635  Malformed = true;
2636  moveToEnd();
2637  return;
2638  }
2639 
2640  Stack.pop_back();
2641  while (!Stack.empty()) {
2642  NodeState &Top = Stack.back();
2643  if (Top.NextChildIndex < Top.ChildCount) {
2644  pushDownUntilBottom();
2645  // Now at the next export node.
2646  return;
2647  } else {
2648  if (Top.IsExportNode) {
2649  // This node has no children but is itself an export node.
2650  CumulativeString.resize(Top.ParentStringLength);
2651  return;
2652  }
2653  Stack.pop_back();
2654  }
2655  }
2656  Done = true;
2657 }
2658 
2661  ExportEntry Start(Trie);
2662  if (Trie.size() == 0)
2663  Start.moveToEnd();
2664  else
2665  Start.moveToFirst();
2666 
2667  ExportEntry Finish(Trie);
2668  Finish.moveToEnd();
2669 
2670  return make_range(export_iterator(Start), export_iterator(Finish));
2671 }
2672 
2674  return exports(getDyldInfoExportsTrie());
2675 }
2676 
2678  : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2679  RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
2680  PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
2681 
2682 void MachORebaseEntry::moveToFirst() {
2683  Ptr = Opcodes.begin();
2684  moveNext();
2685 }
2686 
2687 void MachORebaseEntry::moveToEnd() {
2688  Ptr = Opcodes.end();
2689  RemainingLoopCount = 0;
2690  Done = true;
2691 }
2692 
2694  // If in the middle of some loop, move to next rebasing in loop.
2695  SegmentOffset += AdvanceAmount;
2696  if (RemainingLoopCount) {
2697  --RemainingLoopCount;
2698  return;
2699  }
2700  if (Ptr == Opcodes.end()) {
2701  Done = true;
2702  return;
2703  }
2704  bool More = true;
2705  while (More && !Malformed) {
2706  // Parse next opcode and set up next loop.
2707  uint8_t Byte = *Ptr++;
2708  uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
2709  uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
2710  switch (Opcode) {
2712  More = false;
2713  Done = true;
2714  moveToEnd();
2715  DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
2716  break;
2718  RebaseType = ImmValue;
2720  "mach-o-rebase",
2721  llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
2722  << "RebaseType=" << (int) RebaseType << "\n");
2723  break;
2725  SegmentIndex = ImmValue;
2726  SegmentOffset = readULEB128();
2728  "mach-o-rebase",
2729  llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2730  << "SegmentIndex=" << SegmentIndex << ", "
2731  << format("SegmentOffset=0x%06X", SegmentOffset)
2732  << "\n");
2733  break;
2735  SegmentOffset += readULEB128();
2736  DEBUG_WITH_TYPE("mach-o-rebase",
2737  llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
2738  << format("SegmentOffset=0x%06X",
2739  SegmentOffset) << "\n");
2740  break;
2742  SegmentOffset += ImmValue * PointerSize;
2743  DEBUG_WITH_TYPE("mach-o-rebase",
2744  llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
2745  << format("SegmentOffset=0x%06X",
2746  SegmentOffset) << "\n");
2747  break;
2749  AdvanceAmount = PointerSize;
2750  RemainingLoopCount = ImmValue - 1;
2752  "mach-o-rebase",
2753  llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
2754  << format("SegmentOffset=0x%06X", SegmentOffset)
2755  << ", AdvanceAmount=" << AdvanceAmount
2756  << ", RemainingLoopCount=" << RemainingLoopCount
2757  << "\n");
2758  return;
2760  AdvanceAmount = PointerSize;
2761  RemainingLoopCount = readULEB128() - 1;
2763  "mach-o-rebase",
2764  llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
2765  << format("SegmentOffset=0x%06X", SegmentOffset)
2766  << ", AdvanceAmount=" << AdvanceAmount
2767  << ", RemainingLoopCount=" << RemainingLoopCount
2768  << "\n");
2769  return;
2771  AdvanceAmount = readULEB128() + PointerSize;
2772  RemainingLoopCount = 0;
2774  "mach-o-rebase",
2775  llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
2776  << format("SegmentOffset=0x%06X", SegmentOffset)
2777  << ", AdvanceAmount=" << AdvanceAmount
2778  << ", RemainingLoopCount=" << RemainingLoopCount
2779  << "\n");
2780  return;
2782  RemainingLoopCount = readULEB128() - 1;
2783  AdvanceAmount = readULEB128() + PointerSize;
2785  "mach-o-rebase",
2786  llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
2787  << format("SegmentOffset=0x%06X", SegmentOffset)
2788  << ", AdvanceAmount=" << AdvanceAmount
2789  << ", RemainingLoopCount=" << RemainingLoopCount
2790  << "\n");
2791  return;
2792  default:
2793  Malformed = true;
2794  }
2795  }
2796 }
2797 
2798 uint64_t MachORebaseEntry::readULEB128() {
2799  unsigned Count;
2800  uint64_t Result = decodeULEB128(Ptr, &Count);
2801  Ptr += Count;
2802  if (Ptr > Opcodes.end()) {
2803  Ptr = Opcodes.end();
2804  Malformed = true;
2805  }
2806  return Result;
2807 }
2808 
2809 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
2810 
2811 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
2812 
2814  switch (RebaseType) {
2816  return "pointer";
2818  return "text abs32";
2820  return "text rel32";
2821  }
2822  return "unknown";
2823 }
2824 
2826 #ifdef EXPENSIVE_CHECKS
2827  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2828 #else
2829  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
2830 #endif
2831  return (Ptr == Other.Ptr) &&
2832  (RemainingLoopCount == Other.RemainingLoopCount) &&
2833  (Done == Other.Done);
2834 }
2835 
2838  MachORebaseEntry Start(Opcodes, is64);
2839  Start.moveToFirst();
2840 
2841  MachORebaseEntry Finish(Opcodes, is64);
2842  Finish.moveToEnd();
2843 
2844  return make_range(rebase_iterator(Start), rebase_iterator(Finish));
2845 }
2846 
2849 }
2850 
2852  : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
2853  Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
2854  BindType(0), PointerSize(is64Bit ? 8 : 4),
2855  TableKind(BK), Malformed(false), Done(false) {}
2856 
2857 void MachOBindEntry::moveToFirst() {
2858  Ptr = Opcodes.begin();
2859  moveNext();
2860 }
2861 
2862 void MachOBindEntry::moveToEnd() {
2863  Ptr = Opcodes.end();
2864  RemainingLoopCount = 0;
2865  Done = true;
2866 }
2867 
2869  // If in the middle of some loop, move to next binding in loop.
2870  SegmentOffset += AdvanceAmount;
2871  if (RemainingLoopCount) {
2872  --RemainingLoopCount;
2873  return;
2874  }
2875  if (Ptr == Opcodes.end()) {
2876  Done = true;
2877  return;
2878  }
2879  bool More = true;
2880  while (More && !Malformed) {
2881  // Parse next opcode and set up next loop.
2882  uint8_t Byte = *Ptr++;
2883  uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
2884  uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
2885  int8_t SignExtended;
2886  const uint8_t *SymStart;
2887  switch (Opcode) {
2889  if (TableKind == Kind::Lazy) {
2890  // Lazying bindings have a DONE opcode between entries. Need to ignore
2891  // it to advance to next entry. But need not if this is last entry.
2892  bool NotLastEntry = false;
2893  for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
2894  if (*P) {
2895  NotLastEntry = true;
2896  }
2897  }
2898  if (NotLastEntry)
2899  break;
2900  }
2901  More = false;
2902  Done = true;
2903  moveToEnd();
2904  DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
2905  break;
2907  Ordinal = ImmValue;
2909  "mach-o-bind",
2910  llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
2911  << "Ordinal=" << Ordinal << "\n");
2912  break;
2914  Ordinal = readULEB128();
2916  "mach-o-bind",
2917  llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
2918  << "Ordinal=" << Ordinal << "\n");
2919  break;
2921  if (ImmValue) {
2922  SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
2923  Ordinal = SignExtended;
2924  } else
2925  Ordinal = 0;
2927  "mach-o-bind",
2928  llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
2929  << "Ordinal=" << Ordinal << "\n");
2930  break;
2932  Flags = ImmValue;
2933  SymStart = Ptr;
2934  while (*Ptr) {
2935  ++Ptr;
2936  }
2937  SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
2938  Ptr-SymStart);
2939  ++Ptr;
2941  "mach-o-bind",
2942  llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
2943  << "SymbolName=" << SymbolName << "\n");
2944  if (TableKind == Kind::Weak) {
2946  return;
2947  }
2948  break;
2950  BindType = ImmValue;
2952  "mach-o-bind",
2953  llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
2954  << "BindType=" << (int)BindType << "\n");
2955  break;
2957  Addend = readSLEB128();
2958  if (TableKind == Kind::Lazy)
2959  Malformed = true;
2961  "mach-o-bind",
2962  llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
2963  << "Addend=" << Addend << "\n");
2964  break;
2966  SegmentIndex = ImmValue;
2967  SegmentOffset = readULEB128();
2969  "mach-o-bind",
2970  llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2971  << "SegmentIndex=" << SegmentIndex << ", "
2972  << format("SegmentOffset=0x%06X", SegmentOffset)
2973  << "\n");
2974  break;
2976  SegmentOffset += readULEB128();
2977  DEBUG_WITH_TYPE("mach-o-bind",
2978  llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
2979  << format("SegmentOffset=0x%06X",
2980  SegmentOffset) << "\n");
2981  break;
2983  AdvanceAmount = PointerSize;
2984  RemainingLoopCount = 0;
2985  DEBUG_WITH_TYPE("mach-o-bind",
2986  llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
2987  << format("SegmentOffset=0x%06X",
2988  SegmentOffset) << "\n");
2989  return;
2991  AdvanceAmount = readULEB128() + PointerSize;
2992  RemainingLoopCount = 0;
2993  if (TableKind == Kind::Lazy)
2994  Malformed = true;
2996  "mach-o-bind",
2997  llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
2998  << format("SegmentOffset=0x%06X", SegmentOffset)
2999  << ", AdvanceAmount=" << AdvanceAmount
3000  << ", RemainingLoopCount=" << RemainingLoopCount
3001  << "\n");
3002  return;
3004  AdvanceAmount = ImmValue * PointerSize + PointerSize;
3005  RemainingLoopCount = 0;
3006  if (TableKind == Kind::Lazy)
3007  Malformed = true;
3008  DEBUG_WITH_TYPE("mach-o-bind",
3009  llvm::dbgs()
3010  << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
3011  << format("SegmentOffset=0x%06X",
3012  SegmentOffset) << "\n");
3013  return;
3015  RemainingLoopCount = readULEB128() - 1;
3016  AdvanceAmount = readULEB128() + PointerSize;
3017  if (TableKind == Kind::Lazy)
3018  Malformed = true;
3020  "mach-o-bind",
3021  llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
3022  << format("SegmentOffset=0x%06X", SegmentOffset)
3023  << ", AdvanceAmount=" << AdvanceAmount
3024  << ", RemainingLoopCount=" << RemainingLoopCount
3025  << "\n");
3026  return;
3027  default:
3028  Malformed = true;
3029  }
3030  }
3031 }
3032 
3033 uint64_t MachOBindEntry::readULEB128() {
3034  unsigned Count;
3035  uint64_t Result = decodeULEB128(Ptr, &Count);
3036  Ptr += Count;
3037  if (Ptr > Opcodes.end()) {
3038  Ptr = Opcodes.end();
3039  Malformed = true;
3040  }
3041  return Result;
3042 }
3043 
3044 int64_t MachOBindEntry::readSLEB128() {
3045  unsigned Count;
3046  int64_t Result = decodeSLEB128(Ptr, &Count);
3047  Ptr += Count;
3048  if (Ptr > Opcodes.end()) {
3049  Ptr = Opcodes.end();
3050  Malformed = true;
3051  }
3052  return Result;
3053 }
3054 
3055 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
3056 
3057 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
3058 
3060  switch (BindType) {
3062  return "pointer";
3064  return "text abs32";
3066  return "text rel32";
3067  }
3068  return "unknown";
3069 }
3070 
3071 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
3072 
3073 int64_t MachOBindEntry::addend() const { return Addend; }
3074 
3076 
3077 int MachOBindEntry::ordinal() const { return Ordinal; }
3078 
3080 #ifdef EXPENSIVE_CHECKS
3081  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3082 #else
3083  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3084 #endif
3085  return (Ptr == Other.Ptr) &&
3086  (RemainingLoopCount == Other.RemainingLoopCount) &&
3087  (Done == Other.Done);
3088 }
3089 
3092  MachOBindEntry::Kind BKind) {
3093  MachOBindEntry Start(Opcodes, is64, BKind);
3094  Start.moveToFirst();
3095 
3096  MachOBindEntry Finish(Opcodes, is64, BKind);
3097  Finish.moveToEnd();
3098 
3099  return make_range(bind_iterator(Start), bind_iterator(Finish));
3100 }
3101 
3105 }
3106 
3110 }
3111 
3115 }
3116 
3119  return LoadCommands.begin();
3120 }
3121 
3124  return LoadCommands.end();
3125 }
3126 
3130 }
3131 
3132 StringRef
3135  return parseSegmentOrSectionName(Raw.data());
3136 }
3137 
3140  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
3141  const section_base *Base =
3142  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
3143  return makeArrayRef(Base->sectname);
3144 }
3145 
3148  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
3149  const section_base *Base =
3150  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
3151  return makeArrayRef(Base->segname);
3152 }
3153 
3154 bool
3156  const {
3157  if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
3158  return false;
3160 }
3161 
3163  const MachO::any_relocation_info &RE) const {
3164  if (isLittleEndian())
3165  return RE.r_word1 & 0xffffff;
3166  return RE.r_word1 >> 8;
3167 }
3168 
3170  const MachO::any_relocation_info &RE) const {
3171  if (isLittleEndian())
3172  return (RE.r_word1 >> 27) & 1;
3173  return (RE.r_word1 >> 4) & 1;
3174 }
3175 
3177  const MachO::any_relocation_info &RE) const {
3178  return RE.r_word0 >> 31;
3179 }
3180 
3182  const MachO::any_relocation_info &RE) const {
3183  return RE.r_word1;
3184 }
3185 
3187  const MachO::any_relocation_info &RE) const {
3188  return (RE.r_word0 >> 24) & 0xf;
3189 }
3190 
3192  const MachO::any_relocation_info &RE) const {
3193  if (isRelocationScattered(RE))
3194  return getScatteredRelocationAddress(RE);
3195  return getPlainRelocationAddress(RE);
3196 }
3197 
3199  const MachO::any_relocation_info &RE) const {
3200  if (isRelocationScattered(RE))
3201  return getScatteredRelocationPCRel(RE);
3202  return getPlainRelocationPCRel(*this, RE);
3203 }
3204 
3206  const MachO::any_relocation_info &RE) const {
3207  if (isRelocationScattered(RE))
3208  return getScatteredRelocationLength(RE);
3209  return getPlainRelocationLength(*this, RE);
3210 }
3211 
3212 unsigned
3214  const MachO::any_relocation_info &RE) const {
3215  if (isRelocationScattered(RE))
3216  return getScatteredRelocationType(RE);
3217  return getPlainRelocationType(*this, RE);
3218 }
3219 
3220 SectionRef
3222  const MachO::any_relocation_info &RE) const {
3224  return *section_end();
3225  unsigned SecNum = getPlainRelocationSymbolNum(RE);
3226  if (SecNum == MachO::R_ABS || SecNum > Sections.size())
3227  return *section_end();
3228  DataRefImpl DRI;
3229  DRI.d.a = SecNum - 1;
3230  return SectionRef(DRI, this);
3231 }
3232 
3234  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
3235  return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
3236 }
3237 
3239  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
3240  return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
3241 }
3242 
3243 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
3244  unsigned Index) const {
3245  const char *Sec = getSectionPtr(*this, L, Index);
3246  return getStruct<MachO::section>(*this, Sec);
3247 }
3248 
3249 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
3250  unsigned Index) const {
3251  const char *Sec = getSectionPtr(*this, L, Index);
3252  return getStruct<MachO::section_64>(*this, Sec);
3253 }
3254 
3257  const char *P = reinterpret_cast<const char *>(DRI.p);
3258  return getStruct<MachO::nlist>(*this, P);
3259 }
3260 
3263  const char *P = reinterpret_cast<const char *>(DRI.p);
3264  return getStruct<MachO::nlist_64>(*this, P);
3265 }
3266 
3269  return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
3270 }
3271 
3274  return getStruct<MachO::segment_command>(*this, L.Ptr);
3275 }
3276 
3279  return getStruct<MachO::segment_command_64>(*this, L.Ptr);
3280 }
3281 
3284  return getStruct<MachO::linker_option_command>(*this, L.Ptr);
3285 }
3286 
3289  return getStruct<MachO::version_min_command>(*this, L.Ptr);
3290 }
3291 
3294  return getStruct<MachO::dylib_command>(*this, L.Ptr);
3295 }
3296 
3299  return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
3300 }
3301 
3304  return getStruct<MachO::dylinker_command>(*this, L.Ptr);
3305 }
3306 
3309  return getStruct<MachO::uuid_command>(*this, L.Ptr);
3310 }
3311 
3314  return getStruct<MachO::rpath_command>(*this, L.Ptr);
3315 }
3316 
3319  return getStruct<MachO::source_version_command>(*this, L.Ptr);
3320 }
3321 
3324  return getStruct<MachO::entry_point_command>(*this, L.Ptr);
3325 }
3326 
3329  return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
3330 }
3331 
3334  return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
3335 }
3336 
3339  return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
3340 }
3341 
3344  return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
3345 }
3346 
3349  return getStruct<MachO::sub_library_command>(*this, L.Ptr);
3350 }
3351 
3354  return getStruct<MachO::sub_client_command>(*this, L.Ptr);
3355 }
3356 
3359  return getStruct<MachO::routines_command>(*this, L.Ptr);
3360 }
3361 
3364  return getStruct<MachO::routines_command_64>(*this, L.Ptr);
3365 }
3366 
3369  return getStruct<MachO::thread_command>(*this, L.Ptr);
3370 }
3371 
3374  DataRefImpl Sec;
3375  Sec.d.a = Rel.d.a;
3376  uint32_t Offset;
3377  if (is64Bit()) {
3378  MachO::section_64 Sect = getSection64(Sec);
3379  Offset = Sect.reloff;
3380  } else {
3381  MachO::section Sect = getSection(Sec);
3382  Offset = Sect.reloff;
3383  }
3384 
3385  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
3386  getPtr(*this, Offset)) + Rel.d.b;
3387  return getStruct<MachO::any_relocation_info>(
3388  *this, reinterpret_cast<const char *>(P));
3389 }
3390 
3393  const char *P = reinterpret_cast<const char *>(Rel.p);
3394  return getStruct<MachO::data_in_code_entry>(*this, P);
3395 }
3396 
3398  return Header;
3399 }
3400 
3402  assert(is64Bit());
3403  return Header64;
3404 }
3405 
3407  const MachO::dysymtab_command &DLC,
3408  unsigned Index) const {
3409  uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
3410  return getStruct<uint32_t>(*this, getPtr(*this, Offset));
3411 }
3412 
3415  unsigned Index) const {
3416  uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
3417  return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
3418 }
3419 
3421  if (SymtabLoadCmd)
3422  return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
3423 
3424  // If there is no SymtabLoadCmd return a load command with zero'ed fields.
3426  Cmd.cmd = MachO::LC_SYMTAB;
3427  Cmd.cmdsize = sizeof(MachO::symtab_command);
3428  Cmd.symoff = 0;
3429  Cmd.nsyms = 0;
3430  Cmd.stroff = 0;
3431  Cmd.strsize = 0;
3432  return Cmd;
3433 }
3434 
3436  if (DysymtabLoadCmd)
3437  return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
3438 
3439  // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
3441  Cmd.cmd = MachO::LC_DYSYMTAB;
3442  Cmd.cmdsize = sizeof(MachO::dysymtab_command);
3443  Cmd.ilocalsym = 0;
3444  Cmd.nlocalsym = 0;
3445  Cmd.iextdefsym = 0;
3446  Cmd.nextdefsym = 0;
3447  Cmd.iundefsym = 0;
3448  Cmd.nundefsym = 0;
3449  Cmd.tocoff = 0;
3450  Cmd.ntoc = 0;
3451  Cmd.modtaboff = 0;
3452  Cmd.nmodtab = 0;
3453  Cmd.extrefsymoff = 0;
3454  Cmd.nextrefsyms = 0;
3455  Cmd.indirectsymoff = 0;
3456  Cmd.nindirectsyms = 0;
3457  Cmd.extreloff = 0;
3458  Cmd.nextrel = 0;
3459  Cmd.locreloff = 0;
3460  Cmd.nlocrel = 0;
3461  return Cmd;
3462 }
3463 
3466  if (DataInCodeLoadCmd)
3467  return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
3468 
3469  // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
3471  Cmd.cmd = MachO::LC_DATA_IN_CODE;
3472  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3473  Cmd.dataoff = 0;
3474  Cmd.datasize = 0;
3475  return Cmd;
3476 }
3477 
3480  if (LinkOptHintsLoadCmd)
3481  return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
3482 
3483  // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
3484  // fields.
3486  Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
3487  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
3488  Cmd.dataoff = 0;
3489  Cmd.datasize = 0;
3490  return Cmd;
3491 }
3492 
3494  if (!DyldInfoLoadCmd)
3495  return None;
3496 
3497  MachO::dyld_info_command DyldInfo =
3498  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3499  const uint8_t *Ptr =
3500  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
3501  return makeArrayRef(Ptr, DyldInfo.rebase_size);
3502 }
3503 
3505  if (!DyldInfoLoadCmd)
3506  return None;
3507 
3508  MachO::dyld_info_command DyldInfo =
3509  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3510  const uint8_t *Ptr =
3511  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
3512  return makeArrayRef(Ptr, DyldInfo.bind_size);
3513 }
3514 
3516  if (!DyldInfoLoadCmd)
3517  return None;
3518 
3519  MachO::dyld_info_command DyldInfo =
3520  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3521  const uint8_t *Ptr =
3522  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
3523  return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
3524 }
3525 
3527  if (!DyldInfoLoadCmd)
3528  return None;
3529 
3530  MachO::dyld_info_command DyldInfo =
3531  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3532  const uint8_t *Ptr =
3533  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
3534  return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
3535 }
3536 
3538  if (!DyldInfoLoadCmd)
3539  return None;
3540 
3541  MachO::dyld_info_command DyldInfo =
3542  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
3543  const uint8_t *Ptr =
3544  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
3545  return makeArrayRef(Ptr, DyldInfo.export_size);
3546 }
3547 
3549  if (!UuidLoadCmd)
3550  return None;
3551  // Returning a pointer is fine as uuid doesn't need endian swapping.
3552  const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
3553  return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
3554 }
3555 
3558  return getData().substr(S.stroff, S.strsize);
3559 }
3560 
3562  return getType() == getMachOType(false, true) ||
3563  getType() == getMachOType(true, true);
3564 }
3565 
3566 void MachOObjectFile::ReadULEB128s(uint64_t Index,
3567  SmallVectorImpl<uint64_t> &Out) const {
3568  DataExtractor extractor(ObjectFile::getData(), true, 0);
3569 
3570  uint32_t offset = Index;
3571  uint64_t data = 0;
3572  while (uint64_t delta = extractor.getULEB128(&offset)) {
3573  data += delta;
3574  Out.push_back(data);
3575  }
3576 }
3577 
3579  return getHeader().filetype == MachO::MH_OBJECT;
3580 }
3581 
3584  uint32_t UniversalCputype,
3585  uint32_t UniversalIndex) {
3586  StringRef Magic = Buffer.getBuffer().slice(0, 4);
3587  if (Magic == "\xFE\xED\xFA\xCE")
3588  return MachOObjectFile::create(Buffer, false, false,
3589  UniversalCputype, UniversalIndex);
3590  if (Magic == "\xCE\xFA\xED\xFE")
3591  return MachOObjectFile::create(Buffer, true, false,
3592  UniversalCputype, UniversalIndex);
3593  if (Magic == "\xFE\xED\xFA\xCF")
3594  return MachOObjectFile::create(Buffer, false, true,
3595  UniversalCputype, UniversalIndex);
3596  if (Magic == "\xCF\xFA\xED\xFE")
3597  return MachOObjectFile::create(Buffer, true, true,
3598  UniversalCputype, UniversalIndex);
3599  return make_error<GenericBinaryError>("Unrecognized MachO magic number",
3601 }
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
MachineLoop * L
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
void push_back(const T &Elt)
Definition: SmallVector.h:211
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
void swapStruct(fat_header &mh)
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
iterator_range< export_iterator > exports() const
For use iterating over all exported symbols.
static unsigned int getMachOType(bool isLE, bool is64Bits)
Definition: Binary.h:74
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
void swapByteOrder(T &Value)
load_command_iterator end_load_commands() const
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:192
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
StringRef getStringTableData() const
friend class SymbolRef
Definition: ObjectFile.h:198
size_t i
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
StringRef getFileFormatName() const override
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool isSectionVirtual(DataRefImpl Sec) const override
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
friend class SectionRef
Definition: ObjectFile.h:211
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: Object/MachO.h:57
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
iterator end() const
Definition: ArrayRef.h:130
symbol_iterator_range symbols() const
Definition: ObjectFile.h:249
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
static const char * getPtr(const MachOObjectFile &O, size_t Offset)
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const
uint8_t getRelocationLength(DataRefImpl Rel) const
This class is the base class for all object file types.
Definition: ObjectFile.h:178
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
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
StringRef otherName() const
static StringRef parseSegmentOrSectionName(const char *P)
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
Definition: Object/MachO.h:108
uint64_t getSectionAlignment(DataRefImpl Sec) const override
struct llvm::object::DataRefImpl::@119 d
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
Error takeError()
Take ownership of the stored error.
load_command_iterator begin_load_commands() const
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:428
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
bool operator==(const MachORebaseEntry &) const
iterator_range< rebase_iterator > rebaseTable() const
For use iterating over all rebase table entries.
bool isSectionBitcode(DataRefImpl Sec) const override
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:69
uint64_t getSectionAddress(DataRefImpl Sec) const override
content_iterator< ExportEntry > export_iterator
Definition: Object/MachO.h:101
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
basic_symbol_iterator symbol_begin() const override
bool operator==(const ExportEntry &) const
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
const uint32_t ARM_THREAD_STATE_COUNT
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
bool isSectionText(DataRefImpl Sec) const override
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
static void advance(T &it, size_t Val)
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
StringRef getData() const
Definition: Binary.cpp:33
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:166
bool equals(StringRef RHS) const
Check for string equality.
Definition: SmallString.h:99
uint64_t getSymbolIndex(DataRefImpl Symb) const
Tagged union holding either a T or a Error.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
Definition: Object/MachO.h:144
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:662
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
dice_iterator end_dices() const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
static const bool IsLittleEndianHost
Definition: Host.h:40
#define F(x, y, z)
Definition: MD5.cpp:51
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
unsigned getArch() const override
static unsigned getCPUType(const MachOObjectFile &O)
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
#define T
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
ExportEntry(ArrayRef< uint8_t > Trie)
Function Alias Analysis false
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:699
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
const MachO::mach_header & getHeader() const
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:791
basic_symbol_iterator symbol_end() const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
MachO::section_64 getSection64(DataRefImpl DRI) const
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
static bool isLoadCommandObsolete(uint32_t cmd)
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:80
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
iterator begin() const
Definition: StringRef.h:103
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
void moveSectionNext(DataRefImpl &Sec) const override
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:36
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
static uint8_t GET_COMM_ALIGN(uint16_t n_desc)
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
#define P(N)
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
bool isSectionCompressed(DataRefImpl Sec) const override
unsigned int getType() const
Definition: Binary.h:89
unsigned getSectionID(SectionRef Sec) const
const MachO::mach_header_64 & getHeader64() const
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:295
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getUuid() const
iterator_range< load_command_iterator > load_commands() const
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
MachO::section getSection(DataRefImpl DRI) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
static bool is64Bit(const char *name)
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
const uint32_t x86_THREAD_STATE64_COUNT
#define H(x, y, z)
Definition: MD5.cpp:53
static Error checkEncryptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, uint64_t cryptoff, uint64_t cryptsize, const char **LoadCmd, const char *CmdName)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
static Error checkSubCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName, size_t SizeOfCmd, const char *CmdStructName, uint32_t PathOffset, const char *PathFieldName)
uint32_t Offset
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
iterator begin() const
Definition: ArrayRef.h:129
MachO::linkedit_data_command getDataInCodeLoadCommand() const
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
static T getStruct(const MachOObjectFile &O, const char *P)
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
Definition: Object/MachO.h:29
MachORebaseEntry(ArrayRef< uint8_t > opcodes, bool is64Bit)
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
content_iterator< MachOBindEntry > bind_iterator
Definition: Object/MachO.h:185
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
bool operator==(const MachOBindEntry &) const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:66
static Error malformedError(Twine Msg)
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
uint64_t getNValue(DataRefImpl Sym) const
static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements, const char *ElementName)
static uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:94
section_iterator getRelocationSection(DataRefImpl Rel) const
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:357
static const char *const Magic
Definition: Archive.cpp:25
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:126
Triple getArchTriple(const char **McpuDefault=nullptr) const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
void moveSymbolNext(DataRefImpl &Symb) const override
static ErrorSuccess success()
Create a success value.
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
friend class RelocationRef
Definition: ObjectFile.h:232
unsigned getSymbolSectionID(SymbolRef Symb) const
bool isSectionData(DataRefImpl Sec) const override
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
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 Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
StringRef getBuffer() const
Definition: MemoryBuffer.h:169
const char * Name
content_iterator< DiceRef > dice_iterator
Definition: Object/MachO.h:50
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn...
Definition: CodeView.h:73
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:649
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
uint32_t getSymbolFlags(DataRefImpl Symb) const override
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
A range adaptor for a pair of iterators.
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
Helper for Errors used as out-parameters.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: ObjectFile.h:116
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
MachO::mach_header_64 Header64
Definition: Object/MachO.h:456
MachOBindEntry(ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
static const size_t npos
Definition: StringRef.h:51
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
bool isSectionBSS(DataRefImpl Sec) const override
MachO::symtab_command getSymtabLoadCommand() const
uint64_t getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:42
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
basic_symbol_iterator getSymbolByIndex(unsigned Index) const
bool isLittleEndian() const
Definition: Binary.h:132
dice_iterator begin_dices() const
section_iterator section_begin() const override
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
static bool isValidArch(StringRef ArchFlag)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
MachO::dysymtab_command getDysymtabLoadCommand() const
MachO::mach_header Header
Definition: Object/MachO.h:457
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
unsigned getSectionType(SectionRef Sec) const
Lightweight error class with error context and mandatory checking.
const uint32_t ARM_THREAD_STATE64_COUNT
section_iterator section_end() const override
iterator_range< bind_iterator > lazyBindTable() const
For use iterating over all lazy bind table entries.
iterator end() const
Definition: StringRef.h:105
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:125
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
S_ZEROFILL - Zero fill on demand section.
int * Ptr
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
SectionType
These are the section type and attributes fields.
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
const T * data() const
Definition: ArrayRef.h:138
content_iterator< MachORebaseEntry > rebase_iterator
Definition: Object/MachO.h:137
iterator_range< bind_iterator > bindTable() const
For use iterating over all bind table entries.
iterator_range< bind_iterator > weakBindTable() const
For use iterating over all lazy bind table entries.
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
const uint32_t PPC_THREAD_STATE_COUNT
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:70
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
uint64_t getSectionSize(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
void resize(size_type N)
Definition: SmallVector.h:352