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