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