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