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