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  cputype == MachO::CPU_TYPE_ARM64_32) {
1105  if (flavor == MachO::ARM_THREAD_STATE64) {
1106  if (count != MachO::ARM_THREAD_STATE64_COUNT)
1107  return malformedError("load command " + Twine(LoadCommandIndex) +
1108  " count not ARM_THREAD_STATE64_COUNT for "
1109  "flavor number " + Twine(nflavor) + " which is "
1110  "a ARM_THREAD_STATE64 flavor in " + CmdName +
1111  " command");
1112  if (state + sizeof(MachO::arm_thread_state64_t) > end)
1113  return malformedError("load command " + Twine(LoadCommandIndex) +
1114  " ARM_THREAD_STATE64 extends past end of "
1115  "command in " + CmdName + " command");
1116  state += sizeof(MachO::arm_thread_state64_t);
1117  } else {
1118  return malformedError("load command " + Twine(LoadCommandIndex) +
1119  " unknown flavor (" + Twine(flavor) + ") for "
1120  "flavor number " + Twine(nflavor) + " in " +
1121  CmdName + " command");
1122  }
1123  } else if (cputype == MachO::CPU_TYPE_POWERPC) {
1124  if (flavor == MachO::PPC_THREAD_STATE) {
1125  if (count != MachO::PPC_THREAD_STATE_COUNT)
1126  return malformedError("load command " + Twine(LoadCommandIndex) +
1127  " count not PPC_THREAD_STATE_COUNT for "
1128  "flavor number " + Twine(nflavor) + " which is "
1129  "a PPC_THREAD_STATE flavor in " + CmdName +
1130  " command");
1131  if (state + sizeof(MachO::ppc_thread_state32_t) > end)
1132  return malformedError("load command " + Twine(LoadCommandIndex) +
1133  " PPC_THREAD_STATE extends past end of "
1134  "command in " + CmdName + " command");
1135  state += sizeof(MachO::ppc_thread_state32_t);
1136  } else {
1137  return malformedError("load command " + Twine(LoadCommandIndex) +
1138  " unknown flavor (" + Twine(flavor) + ") for "
1139  "flavor number " + Twine(nflavor) + " in " +
1140  CmdName + " command");
1141  }
1142  } else {
1143  return malformedError("unknown cputype (" + Twine(cputype) + ") load "
1144  "command " + Twine(LoadCommandIndex) + " for " +
1145  CmdName + " command can't be checked");
1146  }
1147  nflavor++;
1148  }
1149  return Error::success();
1150 }
1151 
1152 static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj,
1153  const MachOObjectFile::LoadCommandInfo
1154  &Load,
1155  uint32_t LoadCommandIndex,
1156  const char **LoadCmd,
1157  std::list<MachOElement> &Elements) {
1158  if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
1159  return malformedError("load command " + Twine(LoadCommandIndex) +
1160  " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1161  if (*LoadCmd != nullptr)
1162  return malformedError("more than one LC_TWOLEVEL_HINTS command");
1164  getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1165  uint64_t FileSize = Obj.getData().size();
1166  if (Hints.offset > FileSize)
1167  return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1168  Twine(LoadCommandIndex) + " extends past the end of "
1169  "the file");
1170  uint64_t BigSize = Hints.nhints;
1171  BigSize *= sizeof(MachO::twolevel_hint);
1172  BigSize += Hints.offset;
1173  if (BigSize > FileSize)
1174  return malformedError("offset field plus nhints times sizeof(struct "
1175  "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1176  Twine(LoadCommandIndex) + " extends past the end of "
1177  "the file");
1178  if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
1179  sizeof(MachO::twolevel_hint),
1180  "two level hints"))
1181  return Err;
1182  *LoadCmd = Load.Ptr;
1183  return Error::success();
1184 }
1185 
1186 // Returns true if the libObject code does not support the load command and its
1187 // contents. The cmd value it is treated as an unknown load command but with
1188 // an error message that says the cmd value is obsolete.
1190  if (cmd == MachO::LC_SYMSEG ||
1191  cmd == MachO::LC_LOADFVMLIB ||
1192  cmd == MachO::LC_IDFVMLIB ||
1193  cmd == MachO::LC_IDENT ||
1194  cmd == MachO::LC_FVMFILE ||
1195  cmd == MachO::LC_PREPAGE ||
1196  cmd == MachO::LC_PREBOUND_DYLIB ||
1197  cmd == MachO::LC_TWOLEVEL_HINTS ||
1198  cmd == MachO::LC_PREBIND_CKSUM)
1199  return true;
1200  return false;
1201 }
1202 
1204 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
1205  bool Is64Bits, uint32_t UniversalCputype,
1206  uint32_t UniversalIndex) {
1207  Error Err = Error::success();
1208  std::unique_ptr<MachOObjectFile> Obj(
1209  new MachOObjectFile(std::move(Object), IsLittleEndian,
1210  Is64Bits, Err, UniversalCputype,
1211  UniversalIndex));
1212  if (Err)
1213  return std::move(Err);
1214  return std::move(Obj);
1215 }
1216 
1217 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1218  bool Is64bits, Error &Err,
1219  uint32_t UniversalCputype,
1220  uint32_t UniversalIndex)
1221  : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
1222  ErrorAsOutParameter ErrAsOutParam(&Err);
1223  uint64_t SizeOfHeaders;
1224  uint32_t cputype;
1225  if (is64Bit()) {
1226  parseHeader(*this, Header64, Err);
1227  SizeOfHeaders = sizeof(MachO::mach_header_64);
1228  cputype = Header64.cputype;
1229  } else {
1230  parseHeader(*this, Header, Err);
1231  SizeOfHeaders = sizeof(MachO::mach_header);
1232  cputype = Header.cputype;
1233  }
1234  if (Err)
1235  return;
1236  SizeOfHeaders += getHeader().sizeofcmds;
1237  if (getData().data() + SizeOfHeaders > getData().end()) {
1238  Err = malformedError("load commands extend past the end of the file");
1239  return;
1240  }
1241  if (UniversalCputype != 0 && cputype != UniversalCputype) {
1242  Err = malformedError("universal header architecture: " +
1243  Twine(UniversalIndex) + "'s cputype does not match "
1244  "object file's mach header");
1245  return;
1246  }
1247  std::list<MachOElement> Elements;
1248  Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1249 
1250  uint32_t LoadCommandCount = getHeader().ncmds;
1252  if (LoadCommandCount != 0) {
1253  if (auto LoadOrErr = getFirstLoadCommandInfo(*this))
1254  Load = *LoadOrErr;
1255  else {
1256  Err = LoadOrErr.takeError();
1257  return;
1258  }
1259  }
1260 
1261  const char *DyldIdLoadCmd = nullptr;
1262  const char *FuncStartsLoadCmd = nullptr;
1263  const char *SplitInfoLoadCmd = nullptr;
1264  const char *CodeSignDrsLoadCmd = nullptr;
1265  const char *CodeSignLoadCmd = nullptr;
1266  const char *VersLoadCmd = nullptr;
1267  const char *SourceLoadCmd = nullptr;
1268  const char *EntryPointLoadCmd = nullptr;
1269  const char *EncryptLoadCmd = nullptr;
1270  const char *RoutinesLoadCmd = nullptr;
1271  const char *UnixThreadLoadCmd = nullptr;
1272  const char *TwoLevelHintsLoadCmd = nullptr;
1273  for (unsigned I = 0; I < LoadCommandCount; ++I) {
1274  if (is64Bit()) {
1275  if (Load.C.cmdsize % 8 != 0) {
1276  // We have a hack here to allow 64-bit Mach-O core files to have
1277  // LC_THREAD commands that are only a multiple of 4 and not 8 to be
1278  // allowed since the macOS kernel produces them.
1279  if (getHeader().filetype != MachO::MH_CORE ||
1280  Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1281  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1282  "multiple of 8");
1283  return;
1284  }
1285  }
1286  } else {
1287  if (Load.C.cmdsize % 4 != 0) {
1288  Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1289  "multiple of 4");
1290  return;
1291  }
1292  }
1293  LoadCommands.push_back(Load);
1294  if (Load.C.cmd == MachO::LC_SYMTAB) {
1295  if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1296  return;
1297  } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1298  if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd,
1299  Elements)))
1300  return;
1301  } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1302  if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd,
1303  "LC_DATA_IN_CODE", Elements,
1304  "data in code info")))
1305  return;
1306  } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1307  if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd,
1308  "LC_LINKER_OPTIMIZATION_HINT",
1309  Elements, "linker optimization "
1310  "hints")))
1311  return;
1312  } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1313  if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd,
1314  "LC_FUNCTION_STARTS", Elements,
1315  "function starts data")))
1316  return;
1317  } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1318  if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd,
1319  "LC_SEGMENT_SPLIT_INFO", Elements,
1320  "split info data")))
1321  return;
1322  } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1323  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd,
1324  "LC_DYLIB_CODE_SIGN_DRS", Elements,
1325  "code signing RDs data")))
1326  return;
1327  } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1328  if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd,
1329  "LC_CODE_SIGNATURE", Elements,
1330  "code signature data")))
1331  return;
1332  } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1333  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1334  "LC_DYLD_INFO", Elements)))
1335  return;
1336  } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1337  if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1338  "LC_DYLD_INFO_ONLY", Elements)))
1339  return;
1340  } else if (Load.C.cmd == MachO::LC_UUID) {
1341  if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1342  Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1343  "cmdsize");
1344  return;
1345  }
1346  if (UuidLoadCmd) {
1347  Err = malformedError("more than one LC_UUID command");
1348  return;
1349  }
1350  UuidLoadCmd = Load.Ptr;
1351  } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1354  *this, Load, Sections, HasPageZeroSegment, I,
1355  "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1356  return;
1357  } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1359  MachO::section>(
1360  *this, Load, Sections, HasPageZeroSegment, I,
1361  "LC_SEGMENT", SizeOfHeaders, Elements)))
1362  return;
1363  } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1364  if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1365  return;
1366  } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1367  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1368  return;
1369  Libraries.push_back(Load.Ptr);
1370  } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1371  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1372  return;
1373  Libraries.push_back(Load.Ptr);
1374  } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1375  if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1376  return;
1377  Libraries.push_back(Load.Ptr);
1378  } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1379  if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1380  return;
1381  Libraries.push_back(Load.Ptr);
1382  } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1383  if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1384  return;
1385  Libraries.push_back(Load.Ptr);
1386  } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1387  if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1388  return;
1389  } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1390  if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1391  return;
1392  } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1393  if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1394  return;
1395  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1396  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1397  "LC_VERSION_MIN_MACOSX")))
1398  return;
1399  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1400  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1401  "LC_VERSION_MIN_IPHONEOS")))
1402  return;
1403  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1404  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1405  "LC_VERSION_MIN_TVOS")))
1406  return;
1407  } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1408  if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1409  "LC_VERSION_MIN_WATCHOS")))
1410  return;
1411  } else if (Load.C.cmd == MachO::LC_NOTE) {
1412  if ((Err = checkNoteCommand(*this, Load, I, Elements)))
1413  return;
1414  } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1415  if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
1416  return;
1417  } else if (Load.C.cmd == MachO::LC_RPATH) {
1418  if ((Err = checkRpathCommand(*this, Load, I)))
1419  return;
1420  } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1421  if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1422  Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1423  " has incorrect cmdsize");
1424  return;
1425  }
1426  if (SourceLoadCmd) {
1427  Err = malformedError("more than one LC_SOURCE_VERSION command");
1428  return;
1429  }
1430  SourceLoadCmd = Load.Ptr;
1431  } else if (Load.C.cmd == MachO::LC_MAIN) {
1432  if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1433  Err = malformedError("LC_MAIN command " + Twine(I) +
1434  " has incorrect cmdsize");
1435  return;
1436  }
1437  if (EntryPointLoadCmd) {
1438  Err = malformedError("more than one LC_MAIN command");
1439  return;
1440  }
1441  EntryPointLoadCmd = Load.Ptr;
1442  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1443  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1444  Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1445  " has incorrect cmdsize");
1446  return;
1447  }
1449  getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1450  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1451  &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1452  return;
1453  } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1454  if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1455  Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1456  " has incorrect cmdsize");
1457  return;
1458  }
1460  getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1461  if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1462  &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1463  return;
1464  } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1465  if ((Err = checkLinkerOptCommand(*this, Load, I)))
1466  return;
1467  } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1468  if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1469  Err = malformedError("load command " + Twine(I) +
1470  " LC_SUB_FRAMEWORK cmdsize too small");
1471  return;
1472  }
1474  getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1475  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1477  "sub_framework_command", S.umbrella,
1478  "umbrella")))
1479  return;
1480  } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1481  if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1482  Err = malformedError("load command " + Twine(I) +
1483  " LC_SUB_UMBRELLA cmdsize too small");
1484  return;
1485  }
1487  getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1488  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1490  "sub_umbrella_command", S.sub_umbrella,
1491  "sub_umbrella")))
1492  return;
1493  } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1494  if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1495  Err = malformedError("load command " + Twine(I) +
1496  " LC_SUB_LIBRARY cmdsize too small");
1497  return;
1498  }
1500  getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1501  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1503  "sub_library_command", S.sub_library,
1504  "sub_library")))
1505  return;
1506  } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1507  if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1508  Err = malformedError("load command " + Twine(I) +
1509  " LC_SUB_CLIENT cmdsize too small");
1510  return;
1511  }
1513  getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1514  if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1515  sizeof(MachO::sub_client_command),
1516  "sub_client_command", S.client, "client")))
1517  return;
1518  } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1519  if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1520  Err = malformedError("LC_ROUTINES command " + Twine(I) +
1521  " has incorrect cmdsize");
1522  return;
1523  }
1524  if (RoutinesLoadCmd) {
1525  Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1526  "command");
1527  return;
1528  }
1529  RoutinesLoadCmd = Load.Ptr;
1530  } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1531  if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1532  Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1533  " has incorrect cmdsize");
1534  return;
1535  }
1536  if (RoutinesLoadCmd) {
1537  Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1538  "command");
1539  return;
1540  }
1541  RoutinesLoadCmd = Load.Ptr;
1542  } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1543  if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1544  return;
1545  if (UnixThreadLoadCmd) {
1546  Err = malformedError("more than one LC_UNIXTHREAD command");
1547  return;
1548  }
1549  UnixThreadLoadCmd = Load.Ptr;
1550  } else if (Load.C.cmd == MachO::LC_THREAD) {
1551  if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1552  return;
1553  // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1554  } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1555  if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1556  &TwoLevelHintsLoadCmd, Elements)))
1557  return;
1558  } else if (isLoadCommandObsolete(Load.C.cmd)) {
1559  Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1560  Twine(Load.C.cmd) + " is obsolete and not "
1561  "supported");
1562  return;
1563  }
1564  // TODO: generate a error for unknown load commands by default. But still
1565  // need work out an approach to allow or not allow unknown values like this
1566  // as an option for some uses like lldb.
1567  if (I < LoadCommandCount - 1) {
1568  if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1569  Load = *LoadOrErr;
1570  else {
1571  Err = LoadOrErr.takeError();
1572  return;
1573  }
1574  }
1575  }
1576  if (!SymtabLoadCmd) {
1577  if (DysymtabLoadCmd) {
1578  Err = malformedError("contains LC_DYSYMTAB load command without a "
1579  "LC_SYMTAB load command");
1580  return;
1581  }
1582  } else if (DysymtabLoadCmd) {
1583  MachO::symtab_command Symtab =
1584  getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1585  MachO::dysymtab_command Dysymtab =
1586  getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1587  if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1588  Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1589  "extends past the end of the symbol table");
1590  return;
1591  }
1592  uint64_t BigSize = Dysymtab.ilocalsym;
1593  BigSize += Dysymtab.nlocalsym;
1594  if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1595  Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1596  "command extends past the end of the symbol table");
1597  return;
1598  }
1599  if (Dysymtab.nextdefsym != 0 && Dysymtab.iextdefsym > Symtab.nsyms) {
1600  Err = malformedError("iextdefsym in LC_DYSYMTAB load command "
1601  "extends past the end of the symbol table");
1602  return;
1603  }
1604  BigSize = Dysymtab.iextdefsym;
1605  BigSize += Dysymtab.nextdefsym;
1606  if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1607  Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1608  "load command extends past the end of the symbol "
1609  "table");
1610  return;
1611  }
1612  if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1613  Err = malformedError("iundefsym in LC_DYSYMTAB load command "
1614  "extends past the end of the symbol table");
1615  return;
1616  }
1617  BigSize = Dysymtab.iundefsym;
1618  BigSize += Dysymtab.nundefsym;
1619  if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1620  Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1621  " command extends past the end of the symbol table");
1622  return;
1623  }
1624  }
1625  if ((getHeader().filetype == MachO::MH_DYLIB ||
1626  getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1627  DyldIdLoadCmd == nullptr) {
1628  Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1629  "filetype");
1630  return;
1631  }
1632  assert(LoadCommands.size() == LoadCommandCount);
1633 
1634  Err = Error::success();
1635 }
1636 
1638  uint32_t Flags = 0;
1639  if (is64Bit()) {
1641  Flags = H_64.flags;
1642  } else {
1644  Flags = H.flags;
1645  }
1646  uint8_t NType = 0;
1647  uint8_t NSect = 0;
1648  uint16_t NDesc = 0;
1649  uint32_t NStrx = 0;
1650  uint64_t NValue = 0;
1651  uint32_t SymbolIndex = 0;
1652  MachO::symtab_command S = getSymtabLoadCommand();
1653  for (const SymbolRef &Symbol : symbols()) {
1654  DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1655  if (is64Bit()) {
1656  MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1657  NType = STE_64.n_type;
1658  NSect = STE_64.n_sect;
1659  NDesc = STE_64.n_desc;
1660  NStrx = STE_64.n_strx;
1661  NValue = STE_64.n_value;
1662  } else {
1663  MachO::nlist STE = getSymbolTableEntry(SymDRI);
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();
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();
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) {
1769  return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1770  }
1771  return 0;
1772 }
1773 
1775  return getNValue(DRI);
1776 }
1777 
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 
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 
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 
1860  return Entry.n_sect - 1;
1861 }
1862 
1864  Sec.d.a++;
1865 }
1866 
1868  ArrayRef<char> Raw = getSectionRawName(Sec);
1869  return parseSegmentOrSectionName(Raw.data());
1870 }
1871 
1873  if (is64Bit())
1874  return getSection64(Sec).addr;
1875  return getSection(Sec).addr;
1876 }
1877 
1879  return Sec.d.a;
1880 }
1881 
1883  // In the case if a malformed Mach-O file where the section offset is past
1884  // the end of the file or some part of the section size is past the end of
1885  // the file return a size of zero or a size that covers the rest of the file
1886  // but does not extend past the end of the file.
1887  uint32_t SectOffset, SectType;
1888  uint64_t SectSize;
1889 
1890  if (is64Bit()) {
1891  MachO::section_64 Sect = getSection64(Sec);
1892  SectOffset = Sect.offset;
1893  SectSize = Sect.size;
1894  SectType = Sect.flags & MachO::SECTION_TYPE;
1895  } else {
1896  MachO::section Sect = getSection(Sec);
1897  SectOffset = Sect.offset;
1898  SectSize = Sect.size;
1899  SectType = Sect.flags & MachO::SECTION_TYPE;
1900  }
1901  if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1902  return SectSize;
1903  uint64_t FileSize = getData().size();
1904  if (SectOffset > FileSize)
1905  return 0;
1906  if (FileSize - SectOffset < SectSize)
1907  return FileSize - SectOffset;
1908  return SectSize;
1909 }
1910 
1913  uint32_t Offset;
1914  uint64_t Size;
1915 
1916  if (is64Bit()) {
1917  MachO::section_64 Sect = getSection64(Sec);
1918  Offset = Sect.offset;
1919  Size = Sect.size;
1920  } else {
1921  MachO::section Sect = getSection(Sec);
1922  Offset = Sect.offset;
1923  Size = Sect.size;
1924  }
1925 
1926  return arrayRefFromStringRef(getData().substr(Offset, Size));
1927 }
1928 
1930  uint32_t Align;
1931  if (is64Bit()) {
1932  MachO::section_64 Sect = getSection64(Sec);
1933  Align = Sect.align;
1934  } else {
1935  MachO::section Sect = getSection(Sec);
1936  Align = Sect.align;
1937  }
1938 
1939  return uint64_t(1) << Align;
1940 }
1941 
1943  if (SectionIndex < 1 || SectionIndex > Sections.size())
1944  return malformedError("bad section index: " + Twine((int)SectionIndex));
1945 
1946  DataRefImpl DRI;
1947  DRI.d.a = SectionIndex - 1;
1948  return SectionRef(DRI, this);
1949 }
1950 
1952  StringRef SecName;
1953  for (const SectionRef &Section : sections()) {
1954  if (std::error_code E = Section.getName(SecName))
1955  return errorCodeToError(E);
1956  if (SecName == SectionName) {
1957  return Section;
1958  }
1959  }
1961 }
1962 
1964  return false;
1965 }
1966 
1968  uint32_t Flags = getSectionFlags(*this, Sec);
1969  return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
1970 }
1971 
1973  uint32_t Flags = getSectionFlags(*this, Sec);
1974  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1975  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1976  !(SectionType == MachO::S_ZEROFILL ||
1977  SectionType == MachO::S_GB_ZEROFILL);
1978 }
1979 
1981  uint32_t Flags = getSectionFlags(*this, Sec);
1982  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1983  return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1984  (SectionType == MachO::S_ZEROFILL ||
1985  SectionType == MachO::S_GB_ZEROFILL);
1986 }
1987 
1989  return Sec.getRawDataRefImpl().d.a;
1990 }
1991 
1993  uint32_t Flags = getSectionFlags(*this, Sec);
1994  unsigned SectionType = Flags & MachO::SECTION_TYPE;
1995  return SectionType == MachO::S_ZEROFILL ||
1996  SectionType == MachO::S_GB_ZEROFILL;
1997 }
1998 
2000  StringRef SegmentName = getSectionFinalSegmentName(Sec);
2001  if (Expected<StringRef> NameOrErr = getSectionName(Sec))
2002  return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");
2003  return false;
2004 }
2005 
2007  if (is64Bit())
2008  return getSection64(Sec).offset == 0;
2009  return getSection(Sec).offset == 0;
2010 }
2011 
2013  DataRefImpl Ret;
2014  Ret.d.a = Sec.d.a;
2015  Ret.d.b = 0;
2016  return relocation_iterator(RelocationRef(Ret, this));
2017 }
2018 
2021  uint32_t Num;
2022  if (is64Bit()) {
2023  MachO::section_64 Sect = getSection64(Sec);
2024  Num = Sect.nreloc;
2025  } else {
2026  MachO::section Sect = getSection(Sec);
2027  Num = Sect.nreloc;
2028  }
2029 
2030  DataRefImpl Ret;
2031  Ret.d.a = Sec.d.a;
2032  Ret.d.b = Num;
2033  return relocation_iterator(RelocationRef(Ret, this));
2034 }
2035 
2037  DataRefImpl Ret;
2038  // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2039  Ret.d.a = 0; // Would normally be a section index.
2040  Ret.d.b = 0; // Index into the external relocations
2041  return relocation_iterator(RelocationRef(Ret, this));
2042 }
2043 
2045  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2046  DataRefImpl Ret;
2047  // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2048  Ret.d.a = 0; // Would normally be a section index.
2049  Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
2050  return relocation_iterator(RelocationRef(Ret, this));
2051 }
2052 
2054  DataRefImpl Ret;
2055  // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2056  Ret.d.a = 1; // Would normally be a section index.
2057  Ret.d.b = 0; // Index into the local relocations
2058  return relocation_iterator(RelocationRef(Ret, this));
2059 }
2060 
2062  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2063  DataRefImpl Ret;
2064  // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2065  Ret.d.a = 1; // Would normally be a section index.
2066  Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations
2067  return relocation_iterator(RelocationRef(Ret, this));
2068 }
2069 
2071  ++Rel.d.b;
2072 }
2073 
2075  assert((getHeader().filetype == MachO::MH_OBJECT ||
2076  getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
2077  "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2078  MachO::any_relocation_info RE = getRelocation(Rel);
2079  return getAnyRelocationAddress(RE);
2080 }
2081 
2084  MachO::any_relocation_info RE = getRelocation(Rel);
2085  if (isRelocationScattered(RE))
2086  return symbol_end();
2087 
2088  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2089  bool isExtern = getPlainRelocationExternal(RE);
2090  if (!isExtern)
2091  return symbol_end();
2092 
2093  MachO::symtab_command S = getSymtabLoadCommand();
2094  unsigned SymbolTableEntrySize = is64Bit() ?
2095  sizeof(MachO::nlist_64) :
2096  sizeof(MachO::nlist);
2097  uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
2098  DataRefImpl Sym;
2099  Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2100  return symbol_iterator(SymbolRef(Sym, this));
2101 }
2102 
2105  return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
2106 }
2107 
2109  MachO::any_relocation_info RE = getRelocation(Rel);
2110  return getAnyRelocationType(RE);
2111 }
2112 
2114  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2115  StringRef res;
2116  uint64_t RType = getRelocationType(Rel);
2117 
2118  unsigned Arch = this->getArch();
2119 
2120  switch (Arch) {
2121  case Triple::x86: {
2122  static const char *const Table[] = {
2123  "GENERIC_RELOC_VANILLA",
2124  "GENERIC_RELOC_PAIR",
2125  "GENERIC_RELOC_SECTDIFF",
2126  "GENERIC_RELOC_PB_LA_PTR",
2127  "GENERIC_RELOC_LOCAL_SECTDIFF",
2128  "GENERIC_RELOC_TLV" };
2129 
2130  if (RType > 5)
2131  res = "Unknown";
2132  else
2133  res = Table[RType];
2134  break;
2135  }
2136  case Triple::x86_64: {
2137  static const char *const Table[] = {
2138  "X86_64_RELOC_UNSIGNED",
2139  "X86_64_RELOC_SIGNED",
2140  "X86_64_RELOC_BRANCH",
2141  "X86_64_RELOC_GOT_LOAD",
2142  "X86_64_RELOC_GOT",
2143  "X86_64_RELOC_SUBTRACTOR",
2144  "X86_64_RELOC_SIGNED_1",
2145  "X86_64_RELOC_SIGNED_2",
2146  "X86_64_RELOC_SIGNED_4",
2147  "X86_64_RELOC_TLV" };
2148 
2149  if (RType > 9)
2150  res = "Unknown";
2151  else
2152  res = Table[RType];
2153  break;
2154  }
2155  case Triple::arm: {
2156  static const char *const Table[] = {
2157  "ARM_RELOC_VANILLA",
2158  "ARM_RELOC_PAIR",
2159  "ARM_RELOC_SECTDIFF",
2160  "ARM_RELOC_LOCAL_SECTDIFF",
2161  "ARM_RELOC_PB_LA_PTR",
2162  "ARM_RELOC_BR24",
2163  "ARM_THUMB_RELOC_BR22",
2164  "ARM_THUMB_32BIT_BRANCH",
2165  "ARM_RELOC_HALF",
2166  "ARM_RELOC_HALF_SECTDIFF" };
2167 
2168  if (RType > 9)
2169  res = "Unknown";
2170  else
2171  res = Table[RType];
2172  break;
2173  }
2174  case Triple::aarch64:
2175  case Triple::aarch64_32: {
2176  static const char *const Table[] = {
2177  "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
2178  "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
2179  "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
2180  "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2181  "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2182  "ARM64_RELOC_ADDEND"
2183  };
2184 
2185  if (RType >= array_lengthof(Table))
2186  res = "Unknown";
2187  else
2188  res = Table[RType];
2189  break;
2190  }
2191  case Triple::ppc: {
2192  static const char *const Table[] = {
2193  "PPC_RELOC_VANILLA",
2194  "PPC_RELOC_PAIR",
2195  "PPC_RELOC_BR14",
2196  "PPC_RELOC_BR24",
2197  "PPC_RELOC_HI16",
2198  "PPC_RELOC_LO16",
2199  "PPC_RELOC_HA16",
2200  "PPC_RELOC_LO14",
2201  "PPC_RELOC_SECTDIFF",
2202  "PPC_RELOC_PB_LA_PTR",
2203  "PPC_RELOC_HI16_SECTDIFF",
2204  "PPC_RELOC_LO16_SECTDIFF",
2205  "PPC_RELOC_HA16_SECTDIFF",
2206  "PPC_RELOC_JBSR",
2207  "PPC_RELOC_LO14_SECTDIFF",
2208  "PPC_RELOC_LOCAL_SECTDIFF" };
2209 
2210  if (RType > 15)
2211  res = "Unknown";
2212  else
2213  res = Table[RType];
2214  break;
2215  }
2216  case Triple::UnknownArch:
2217  res = "Unknown";
2218  break;
2219  }
2220  Result.append(res.begin(), res.end());
2221 }
2222 
2224  MachO::any_relocation_info RE = getRelocation(Rel);
2225  return getAnyRelocationLength(RE);
2226 }
2227 
2228 //
2229 // guessLibraryShortName() is passed a name of a dynamic library and returns a
2230 // guess on what the short name is. Then name is returned as a substring of the
2231 // StringRef Name passed in. The name of the dynamic library is recognized as
2232 // a framework if it has one of the two following forms:
2233 // Foo.framework/Versions/A/Foo
2234 // Foo.framework/Foo
2235 // Where A and Foo can be any string. And may contain a trailing suffix
2236 // starting with an underbar. If the Name is recognized as a framework then
2237 // isFramework is set to true else it is set to false. If the Name has a
2238 // suffix then Suffix is set to the substring in Name that contains the suffix
2239 // else it is set to a NULL StringRef.
2240 //
2241 // The Name of the dynamic library is recognized as a library name if it has
2242 // one of the two following forms:
2243 // libFoo.A.dylib
2244 // libFoo.dylib
2245 //
2246 // The library may have a suffix trailing the name Foo of the form:
2247 // libFoo_profile.A.dylib
2248 // libFoo_profile.dylib
2249 // These dyld image suffixes are separated from the short name by a '_'
2250 // character. Because the '_' character is commonly used to separate words in
2251 // filenames guessLibraryShortName() cannot reliably separate a dylib's short
2252 // name from an arbitrary image suffix; imagine if both the short name and the
2253 // suffix contains an '_' character! To better deal with this ambiguity,
2254 // guessLibraryShortName() will recognize only "_debug" and "_profile" as valid
2255 // Suffix values. Calling code needs to be tolerant of guessLibraryShortName()
2256 // guessing incorrectly.
2257 //
2258 // The Name of the dynamic library is also recognized as a library name if it
2259 // has the following form:
2260 // Foo.qtx
2261 //
2262 // If the Name of the dynamic library is none of the forms above then a NULL
2263 // StringRef is returned.
2265  bool &isFramework,
2266  StringRef &Suffix) {
2267  StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2268  size_t a, b, c, d, Idx;
2269 
2270  isFramework = false;
2271  Suffix = StringRef();
2272 
2273  // Pull off the last component and make Foo point to it
2274  a = Name.rfind('/');
2275  if (a == Name.npos || a == 0)
2276  goto guess_library;
2277  Foo = Name.slice(a+1, Name.npos);
2278 
2279  // Look for a suffix starting with a '_'
2280  Idx = Foo.rfind('_');
2281  if (Idx != Foo.npos && Foo.size() >= 2) {
2282  Suffix = Foo.slice(Idx, Foo.npos);
2283  if (Suffix != "_debug" && Suffix != "_profile")
2284  Suffix = StringRef();
2285  else
2286  Foo = Foo.slice(0, Idx);
2287  }
2288 
2289  // First look for the form Foo.framework/Foo
2290  b = Name.rfind('/', a);
2291  if (b == Name.npos)
2292  Idx = 0;
2293  else
2294  Idx = b+1;
2295  F = Name.slice(Idx, Idx + Foo.size());
2296  DotFramework = Name.slice(Idx + Foo.size(),
2297  Idx + Foo.size() + sizeof(".framework/")-1);
2298  if (F == Foo && DotFramework == ".framework/") {
2299  isFramework = true;
2300  return Foo;
2301  }
2302 
2303  // Next look for the form Foo.framework/Versions/A/Foo
2304  if (b == Name.npos)
2305  goto guess_library;
2306  c = Name.rfind('/', b);
2307  if (c == Name.npos || c == 0)
2308  goto guess_library;
2309  V = Name.slice(c+1, Name.npos);
2310  if (!V.startswith("Versions/"))
2311  goto guess_library;
2312  d = Name.rfind('/', c);
2313  if (d == Name.npos)
2314  Idx = 0;
2315  else
2316  Idx = d+1;
2317  F = Name.slice(Idx, Idx + Foo.size());
2318  DotFramework = Name.slice(Idx + Foo.size(),
2319  Idx + Foo.size() + sizeof(".framework/")-1);
2320  if (F == Foo && DotFramework == ".framework/") {
2321  isFramework = true;
2322  return Foo;
2323  }
2324 
2325 guess_library:
2326  // pull off the suffix after the "." and make a point to it
2327  a = Name.rfind('.');
2328  if (a == Name.npos || a == 0)
2329  return StringRef();
2330  Dylib = Name.slice(a, Name.npos);
2331  if (Dylib != ".dylib")
2332  goto guess_qtx;
2333 
2334  // First pull off the version letter for the form Foo.A.dylib if any.
2335  if (a >= 3) {
2336  Dot = Name.slice(a-2, a-1);
2337  if (Dot == ".")
2338  a = a - 2;
2339  }
2340 
2341  b = Name.rfind('/', a);
2342  if (b == Name.npos)
2343  b = 0;
2344  else
2345  b = b+1;
2346  // ignore any suffix after an underbar like Foo_profile.A.dylib
2347  Idx = Name.rfind('_');
2348  if (Idx != Name.npos && Idx != b) {
2349  Lib = Name.slice(b, Idx);
2350  Suffix = Name.slice(Idx, a);
2351  if (Suffix != "_debug" && Suffix != "_profile") {
2352  Suffix = StringRef();
2353  Lib = Name.slice(b, a);
2354  }
2355  }
2356  else
2357  Lib = Name.slice(b, a);
2358  // There are incorrect library names of the form:
2359  // libATS.A_profile.dylib so check for these.
2360  if (Lib.size() >= 3) {
2361  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2362  if (Dot == ".")
2363  Lib = Lib.slice(0, Lib.size()-2);
2364  }
2365  return Lib;
2366 
2367 guess_qtx:
2368  Qtx = Name.slice(a, Name.npos);
2369  if (Qtx != ".qtx")
2370  return StringRef();
2371  b = Name.rfind('/', a);
2372  if (b == Name.npos)
2373  Lib = Name.slice(0, a);
2374  else
2375  Lib = Name.slice(b+1, a);
2376  // There are library names of the form: QT.A.qtx so check for these.
2377  if (Lib.size() >= 3) {
2378  Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2379  if (Dot == ".")
2380  Lib = Lib.slice(0, Lib.size()-2);
2381  }
2382  return Lib;
2383 }
2384 
2385 // getLibraryShortNameByIndex() is used to get the short name of the library
2386 // for an undefined symbol in a linked Mach-O binary that was linked with the
2387 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
2388 // It is passed the index (0 - based) of the library as translated from
2389 // GET_LIBRARY_ORDINAL (1 - based).
2391  StringRef &Res) const {
2392  if (Index >= Libraries.size())
2394 
2395  // If the cache of LibrariesShortNames is not built up do that first for
2396  // all the Libraries.
2397  if (LibrariesShortNames.size() == 0) {
2398  for (unsigned i = 0; i < Libraries.size(); i++) {
2400  getStruct<MachO::dylib_command>(*this, Libraries[i]);
2401  if (D.dylib.name >= D.cmdsize)
2403  const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2404  StringRef Name = StringRef(P);
2405  if (D.dylib.name+Name.size() >= D.cmdsize)
2407  StringRef Suffix;
2408  bool isFramework;
2409  StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2410  if (shortName.empty())
2411  LibrariesShortNames.push_back(Name);
2412  else
2413  LibrariesShortNames.push_back(shortName);
2414  }
2415  }
2416 
2417  Res = LibrariesShortNames[Index];
2418  return std::error_code();
2419 }
2420 
2422  return Libraries.size();
2423 }
2424 
2427  DataRefImpl Sec;
2428  Sec.d.a = Rel->getRawDataRefImpl().d.a;
2429  return section_iterator(SectionRef(Sec, this));
2430 }
2431 
2433  DataRefImpl DRI;
2434  MachO::symtab_command Symtab = getSymtabLoadCommand();
2435  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2436  return basic_symbol_iterator(SymbolRef(DRI, this));
2437 
2438  return getSymbolByIndex(0);
2439 }
2440 
2442  DataRefImpl DRI;
2443  MachO::symtab_command Symtab = getSymtabLoadCommand();
2444  if (!SymtabLoadCmd || Symtab.nsyms == 0)
2445  return basic_symbol_iterator(SymbolRef(DRI, this));
2446 
2447  unsigned SymbolTableEntrySize = is64Bit() ?
2448  sizeof(MachO::nlist_64) :
2449  sizeof(MachO::nlist);
2450  unsigned Offset = Symtab.symoff +
2451  Symtab.nsyms * SymbolTableEntrySize;
2452  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2453  return basic_symbol_iterator(SymbolRef(DRI, this));
2454 }
2455 
2457  MachO::symtab_command Symtab = getSymtabLoadCommand();
2458  if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2459  report_fatal_error("Requested symbol index is out of range.");
2460  unsigned SymbolTableEntrySize =
2461  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2462  DataRefImpl DRI;
2463  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2464  DRI.p += Index * SymbolTableEntrySize;
2465  return basic_symbol_iterator(SymbolRef(DRI, this));
2466 }
2467 
2469  MachO::symtab_command Symtab = getSymtabLoadCommand();
2470  if (!SymtabLoadCmd)
2471  report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2472  unsigned SymbolTableEntrySize =
2473  is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2474  DataRefImpl DRIstart;
2475  DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2476  uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2477  return Index;
2478 }
2479 
2481  DataRefImpl DRI;
2482  return section_iterator(SectionRef(DRI, this));
2483 }
2484 
2486  DataRefImpl DRI;
2487  DRI.d.a = Sections.size();
2488  return section_iterator(SectionRef(DRI, this));
2489 }
2490 
2492  return is64Bit() ? 8 : 4;
2493 }
2494 
2496  unsigned CPUType = getCPUType(*this);
2497  if (!is64Bit()) {
2498  switch (CPUType) {
2499  case MachO::CPU_TYPE_I386:
2500  return "Mach-O 32-bit i386";
2501  case MachO::CPU_TYPE_ARM:
2502  return "Mach-O arm";
2504  return "Mach-O arm64 (ILP32)";
2506  return "Mach-O 32-bit ppc";
2507  default:
2508  return "Mach-O 32-bit unknown";
2509  }
2510  }
2511 
2512  switch (CPUType) {
2514  return "Mach-O 64-bit x86-64";
2515  case MachO::CPU_TYPE_ARM64:
2516  return "Mach-O arm64";
2518  return "Mach-O 64-bit ppc64";
2519  default:
2520  return "Mach-O 64-bit unknown";
2521  }
2522 }
2523 
2525  switch (CPUType) {
2526  case MachO::CPU_TYPE_I386:
2527  return Triple::x86;
2529  return Triple::x86_64;
2530  case MachO::CPU_TYPE_ARM:
2531  return Triple::arm;
2532  case MachO::CPU_TYPE_ARM64:
2533  return Triple::aarch64;
2535  return Triple::aarch64_32;
2537  return Triple::ppc;
2539  return Triple::ppc64;
2540  default:
2541  return Triple::UnknownArch;
2542  }
2543 }
2544 
2546  const char **McpuDefault,
2547  const char **ArchFlag) {
2548  if (McpuDefault)
2549  *McpuDefault = nullptr;
2550  if (ArchFlag)
2551  *ArchFlag = nullptr;
2552 
2553  switch (CPUType) {
2554  case MachO::CPU_TYPE_I386:
2555  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2557  if (ArchFlag)
2558  *ArchFlag = "i386";
2559  return Triple("i386-apple-darwin");
2560  default:
2561  return Triple();
2562  }
2564  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2566  if (ArchFlag)
2567  *ArchFlag = "x86_64";
2568  return Triple("x86_64-apple-darwin");
2570  if (ArchFlag)
2571  *ArchFlag = "x86_64h";
2572  return Triple("x86_64h-apple-darwin");
2573  default:
2574  return Triple();
2575  }
2576  case MachO::CPU_TYPE_ARM:
2577  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2579  if (ArchFlag)
2580  *ArchFlag = "armv4t";
2581  return Triple("armv4t-apple-darwin");
2583  if (ArchFlag)
2584  *ArchFlag = "armv5e";
2585  return Triple("armv5e-apple-darwin");
2587  if (ArchFlag)
2588  *ArchFlag = "xscale";
2589  return Triple("xscale-apple-darwin");
2591  if (ArchFlag)
2592  *ArchFlag = "armv6";
2593  return Triple("armv6-apple-darwin");
2595  if (McpuDefault)
2596  *McpuDefault = "cortex-m0";
2597  if (ArchFlag)
2598  *ArchFlag = "armv6m";
2599  return Triple("armv6m-apple-darwin");
2601  if (ArchFlag)
2602  *ArchFlag = "armv7";
2603  return Triple("armv7-apple-darwin");
2605  if (McpuDefault)
2606  *McpuDefault = "cortex-m4";
2607  if (ArchFlag)
2608  *ArchFlag = "armv7em";
2609  return Triple("thumbv7em-apple-darwin");
2611  if (McpuDefault)
2612  *McpuDefault = "cortex-a7";
2613  if (ArchFlag)
2614  *ArchFlag = "armv7k";
2615  return Triple("armv7k-apple-darwin");
2617  if (McpuDefault)
2618  *McpuDefault = "cortex-m3";
2619  if (ArchFlag)
2620  *ArchFlag = "armv7m";
2621  return Triple("thumbv7m-apple-darwin");
2623  if (McpuDefault)
2624  *McpuDefault = "cortex-a7";
2625  if (ArchFlag)
2626  *ArchFlag = "armv7s";
2627  return Triple("armv7s-apple-darwin");
2628  default:
2629  return Triple();
2630  }
2631  case MachO::CPU_TYPE_ARM64:
2632  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2634  if (McpuDefault)
2635  *McpuDefault = "cyclone";
2636  if (ArchFlag)
2637  *ArchFlag = "arm64";
2638  return Triple("arm64-apple-darwin");
2639  default:
2640  return Triple();
2641  }
2643  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2645  if (McpuDefault)
2646  *McpuDefault = "cyclone";
2647  if (ArchFlag)
2648  *ArchFlag = "arm64_32";
2649  return Triple("arm64_32-apple-darwin");
2650  default:
2651  return Triple();
2652  }
2654  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2656  if (ArchFlag)
2657  *ArchFlag = "ppc";
2658  return Triple("ppc-apple-darwin");
2659  default:
2660  return Triple();
2661  }
2663  switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2665  if (ArchFlag)
2666  *ArchFlag = "ppc64";
2667  return Triple("ppc64-apple-darwin");
2668  default:
2669  return Triple();
2670  }
2671  default:
2672  return Triple();
2673  }
2674 }
2675 
2678 }
2679 
2681  return StringSwitch<bool>(ArchFlag)
2682  .Case("i386", true)
2683  .Case("x86_64", true)
2684  .Case("x86_64h", true)
2685  .Case("armv4t", true)
2686  .Case("arm", true)
2687  .Case("armv5e", true)
2688  .Case("armv6", true)
2689  .Case("armv6m", true)
2690  .Case("armv7", true)
2691  .Case("armv7em", true)
2692  .Case("armv7k", true)
2693  .Case("armv7m", true)
2694  .Case("armv7s", true)
2695  .Case("arm64", true)
2696  .Case("arm64_32", true)
2697  .Case("ppc", true)
2698  .Case("ppc64", true)
2699  .Default(false);
2700 }
2701 
2703  return getArch(getCPUType(*this));
2704 }
2705 
2706 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2707  return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2708 }
2709 
2711  DataRefImpl DRI;
2712  DRI.d.a = Index;
2713  return section_rel_begin(DRI);
2714 }
2715 
2717  DataRefImpl DRI;
2718  DRI.d.a = Index;
2719  return section_rel_end(DRI);
2720 }
2721 
2723  DataRefImpl DRI;
2724  if (!DataInCodeLoadCmd)
2725  return dice_iterator(DiceRef(DRI, this));
2726 
2727  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2728  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2729  return dice_iterator(DiceRef(DRI, this));
2730 }
2731 
2733  DataRefImpl DRI;
2734  if (!DataInCodeLoadCmd)
2735  return dice_iterator(DiceRef(DRI, this));
2736 
2737  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2738  unsigned Offset = DicLC.dataoff + DicLC.datasize;
2739  DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2740  return dice_iterator(DiceRef(DRI, this));
2741 }
2742 
2744  ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {}
2745 
2746 void ExportEntry::moveToFirst() {
2747  ErrorAsOutParameter ErrAsOutParam(E);
2748  pushNode(0);
2749  if (*E)
2750  return;
2751  pushDownUntilBottom();
2752 }
2753 
2754 void ExportEntry::moveToEnd() {
2755  Stack.clear();
2756  Done = true;
2757 }
2758 
2760  // Common case, one at end, other iterating from begin.
2761  if (Done || Other.Done)
2762  return (Done == Other.Done);
2763  // Not equal if different stack sizes.
2764  if (Stack.size() != Other.Stack.size())
2765  return false;
2766  // Not equal if different cumulative strings.
2767  if (!CumulativeString.equals(Other.CumulativeString))
2768  return false;
2769  // Equal if all nodes in both stacks match.
2770  for (unsigned i=0; i < Stack.size(); ++i) {
2771  if (Stack[i].Start != Other.Stack[i].Start)
2772  return false;
2773  }
2774  return true;
2775 }
2776 
2777 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) {
2778  unsigned Count;
2779  uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error);
2780  Ptr += Count;
2781  if (Ptr > Trie.end())
2782  Ptr = Trie.end();
2783  return Result;
2784 }
2785 
2787  return CumulativeString;
2788 }
2789 
2790 uint64_t ExportEntry::flags() const {
2791  return Stack.back().Flags;
2792 }
2793 
2794 uint64_t ExportEntry::address() const {
2795  return Stack.back().Address;
2796 }
2797 
2798 uint64_t ExportEntry::other() const {
2799  return Stack.back().Other;
2800 }
2801 
2803  const char* ImportName = Stack.back().ImportName;
2804  if (ImportName)
2805  return StringRef(ImportName);
2806  return StringRef();
2807 }
2808 
2810  return Stack.back().Start - Trie.begin();
2811 }
2812 
2813 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2814  : Start(Ptr), Current(Ptr) {}
2815 
2816 void ExportEntry::pushNode(uint64_t offset) {
2817  ErrorAsOutParameter ErrAsOutParam(E);
2818  const uint8_t *Ptr = Trie.begin() + offset;
2819  NodeState State(Ptr);
2820  const char *error;
2821  uint64_t ExportInfoSize = readULEB128(State.Current, &error);
2822  if (error) {
2823  *E = malformedError("export info size " + Twine(error) +
2824  " in export trie data at node: 0x" +
2825  Twine::utohexstr(offset));
2826  moveToEnd();
2827  return;
2828  }
2829  State.IsExportNode = (ExportInfoSize != 0);
2830  const uint8_t* Children = State.Current + ExportInfoSize;
2831  if (Children > Trie.end()) {
2832  *E = malformedError(
2833  "export info size: 0x" + Twine::utohexstr(ExportInfoSize) +
2834  " in export trie data at node: 0x" + Twine::utohexstr(offset) +
2835  " too big and extends past end of trie data");
2836  moveToEnd();
2837  return;
2838  }
2839  if (State.IsExportNode) {
2840  const uint8_t *ExportStart = State.Current;
2841  State.Flags = readULEB128(State.Current, &error);
2842  if (error) {
2843  *E = malformedError("flags " + Twine(error) +
2844  " in export trie data at node: 0x" +
2845  Twine::utohexstr(offset));
2846  moveToEnd();
2847  return;
2848  }
2849  uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK;
2850  if (State.Flags != 0 &&
2854  *E = malformedError(
2855  "unsupported exported symbol kind: " + Twine((int)Kind) +
2856  " in flags: 0x" + Twine::utohexstr(State.Flags) +
2857  " in export trie data at node: 0x" + Twine::utohexstr(offset));
2858  moveToEnd();
2859  return;
2860  }
2861  if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2862  State.Address = 0;
2863  State.Other = readULEB128(State.Current, &error); // dylib ordinal
2864  if (error) {
2865  *E = malformedError("dylib ordinal of re-export " + Twine(error) +
2866  " in export trie data at node: 0x" +
2867  Twine::utohexstr(offset));
2868  moveToEnd();
2869  return;
2870  }
2871  if (O != nullptr) {
2872  if (State.Other > O->getLibraryCount()) {
2873  *E = malformedError(
2874  "bad library ordinal: " + Twine((int)State.Other) + " (max " +
2875  Twine((int)O->getLibraryCount()) +
2876  ") in export trie data at node: 0x" + Twine::utohexstr(offset));
2877  moveToEnd();
2878  return;
2879  }
2880  }
2881  State.ImportName = reinterpret_cast<const char*>(State.Current);
2882  if (*State.ImportName == '\0') {
2883  State.Current++;
2884  } else {
2885  const uint8_t *End = State.Current + 1;
2886  if (End >= Trie.end()) {
2887  *E = malformedError("import name of re-export in export trie data at "
2888  "node: 0x" +
2889  Twine::utohexstr(offset) +
2890  " starts past end of trie data");
2891  moveToEnd();
2892  return;
2893  }
2894  while(*End != '\0' && End < Trie.end())
2895  End++;
2896  if (*End != '\0') {
2897  *E = malformedError("import name of re-export in export trie data at "
2898  "node: 0x" +
2899  Twine::utohexstr(offset) +
2900  " extends past end of trie data");
2901  moveToEnd();
2902  return;
2903  }
2904  State.Current = End + 1;
2905  }
2906  } else {
2907  State.Address = readULEB128(State.Current, &error);
2908  if (error) {
2909  *E = malformedError("address " + Twine(error) +
2910  " in export trie data at node: 0x" +
2911  Twine::utohexstr(offset));
2912  moveToEnd();
2913  return;
2914  }
2916  State.Other = readULEB128(State.Current, &error);
2917  if (error) {
2918  *E = malformedError("resolver of stub and resolver " + Twine(error) +
2919  " in export trie data at node: 0x" +
2920  Twine::utohexstr(offset));
2921  moveToEnd();
2922  return;
2923  }
2924  }
2925  }
2926  if(ExportStart + ExportInfoSize != State.Current) {
2927  *E = malformedError(
2928  "inconsistant export info size: 0x" +
2929  Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
2930  Twine::utohexstr(State.Current - ExportStart) +
2931  " in export trie data at node: 0x" + Twine::utohexstr(offset));
2932  moveToEnd();
2933  return;
2934  }
2935  }
2936  State.ChildCount = *Children;
2937  if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
2938  *E = malformedError("byte for count of childern in export trie data at "
2939  "node: 0x" +
2940  Twine::utohexstr(offset) +
2941  " extends past end of trie data");
2942  moveToEnd();
2943  return;
2944  }
2945  State.Current = Children + 1;
2946  State.NextChildIndex = 0;
2947  State.ParentStringLength = CumulativeString.size();
2948  Stack.push_back(State);
2949 }
2950 
2951 void ExportEntry::pushDownUntilBottom() {
2952  ErrorAsOutParameter ErrAsOutParam(E);
2953  const char *error;
2954  while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2955  NodeState &Top = Stack.back();
2956  CumulativeString.resize(Top.ParentStringLength);
2957  for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
2958  char C = *Top.Current;
2959  CumulativeString.push_back(C);
2960  }
2961  if (Top.Current >= Trie.end()) {
2962  *E = malformedError("edge sub-string in export trie data at node: 0x" +
2963  Twine::utohexstr(Top.Start - Trie.begin()) +
2964  " for child #" + Twine((int)Top.NextChildIndex) +
2965  " extends past end of trie data");
2966  moveToEnd();
2967  return;
2968  }
2969  Top.Current += 1;
2970  uint64_t childNodeIndex = readULEB128(Top.Current, &error);
2971  if (error) {
2972  *E = malformedError("child node offset " + Twine(error) +
2973  " in export trie data at node: 0x" +
2974  Twine::utohexstr(Top.Start - Trie.begin()));
2975  moveToEnd();
2976  return;
2977  }
2978  for (const NodeState &node : nodes()) {
2979  if (node.Start == Trie.begin() + childNodeIndex){
2980  *E = malformedError("loop in childern in export trie data at node: 0x" +
2981  Twine::utohexstr(Top.Start - Trie.begin()) +
2982  " back to node: 0x" +
2983  Twine::utohexstr(childNodeIndex));
2984  moveToEnd();
2985  return;
2986  }
2987  }
2988  Top.NextChildIndex += 1;
2989  pushNode(childNodeIndex);
2990  if (*E)
2991  return;
2992  }
2993  if (!Stack.back().IsExportNode) {
2994  *E = malformedError("node is not an export node in export trie data at "
2995  "node: 0x" +
2996  Twine::utohexstr(Stack.back().Start - Trie.begin()));
2997  moveToEnd();
2998  return;
2999  }
3000 }
3001 
3002 // We have a trie data structure and need a way to walk it that is compatible
3003 // with the C++ iterator model. The solution is a non-recursive depth first
3004 // traversal where the iterator contains a stack of parent nodes along with a
3005 // string that is the accumulation of all edge strings along the parent chain
3006 // to this point.
3007 //
3008 // There is one "export" node for each exported symbol. But because some
3009 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
3010 // node may have child nodes too.
3011 //
3012 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
3013 // child until hitting a node with no children (which is an export node or
3014 // else the trie is malformed). On the way down, each node is pushed on the
3015 // stack ivar. If there is no more ways down, it pops up one and tries to go
3016 // down a sibling path until a childless node is reached.
3018  assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3019  if (!Stack.back().IsExportNode) {
3020  *E = malformedError("node is not an export node in export trie data at "
3021  "node: 0x" +
3022  Twine::utohexstr(Stack.back().Start - Trie.begin()));
3023  moveToEnd();
3024  return;
3025  }
3026 
3027  Stack.pop_back();
3028  while (!Stack.empty()) {
3029  NodeState &Top = Stack.back();
3030  if (Top.NextChildIndex < Top.ChildCount) {
3031  pushDownUntilBottom();
3032  // Now at the next export node.
3033  return;
3034  } else {
3035  if (Top.IsExportNode) {
3036  // This node has no children but is itself an export node.
3037  CumulativeString.resize(Top.ParentStringLength);
3038  return;
3039  }
3040  Stack.pop_back();
3041  }
3042  }
3043  Done = true;
3044 }
3045 
3048  const MachOObjectFile *O) {
3049  ExportEntry Start(&E, O, Trie);
3050  if (Trie.empty())
3051  Start.moveToEnd();
3052  else
3053  Start.moveToFirst();
3054 
3055  ExportEntry Finish(&E, O, Trie);
3056  Finish.moveToEnd();
3057 
3058  return make_range(export_iterator(Start), export_iterator(Finish));
3059 }
3060 
3062  return exports(Err, getDyldInfoExportsTrie(), this);
3063 }
3064 
3066  ArrayRef<uint8_t> Bytes, bool is64Bit)
3067  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3068  PointerSize(is64Bit ? 8 : 4) {}
3069 
3070 void MachORebaseEntry::moveToFirst() {
3071  Ptr = Opcodes.begin();
3072  moveNext();
3073 }
3074 
3075 void MachORebaseEntry::moveToEnd() {
3076  Ptr = Opcodes.end();
3077  RemainingLoopCount = 0;
3078  Done = true;
3079 }
3080 
3082  ErrorAsOutParameter ErrAsOutParam(E);
3083  // If in the middle of some loop, move to next rebasing in loop.
3084  SegmentOffset += AdvanceAmount;
3085  if (RemainingLoopCount) {
3086  --RemainingLoopCount;
3087  return;
3088  }
3089  // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3090  // pointer size. Therefore it is possible to reach the end without ever having
3091  // seen REBASE_OPCODE_DONE.
3092  if (Ptr == Opcodes.end()) {
3093  Done = true;
3094  return;
3095  }
3096  bool More = true;
3097  while (More) {
3098  // Parse next opcode and set up next loop.
3099  const uint8_t *OpcodeStart = Ptr;
3100  uint8_t Byte = *Ptr++;
3101  uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3102  uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3103  uint32_t Count, Skip;
3104  const char *error = nullptr;
3105  switch (Opcode) {
3107  More = false;
3108  Done = true;
3109  moveToEnd();
3110  DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n");
3111  break;
3113  RebaseType = ImmValue;
3115  *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3116  Twine((int)RebaseType) + " for opcode at: 0x" +
3117  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3118  moveToEnd();
3119  return;
3120  }
3122  "mach-o-rebase",
3123  dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3124  << "RebaseType=" << (int) RebaseType << "\n");
3125  break;
3127  SegmentIndex = ImmValue;
3128  SegmentOffset = readULEB128(&error);
3129  if (error) {
3130  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3131  Twine(error) + " for opcode at: 0x" +
3132  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3133  moveToEnd();
3134  return;
3135  }
3136  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3137  PointerSize);
3138  if (error) {
3139  *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3140  Twine(error) + " for opcode at: 0x" +
3141  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3142  moveToEnd();
3143  return;
3144  }
3146  "mach-o-rebase",
3147  dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3148  << "SegmentIndex=" << SegmentIndex << ", "
3149  << format("SegmentOffset=0x%06X", SegmentOffset)
3150  << "\n");
3151  break;
3153  SegmentOffset += readULEB128(&error);
3154  if (error) {
3155  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3156  " for opcode at: 0x" +
3157  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3158  moveToEnd();
3159  return;
3160  }
3161  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3162  PointerSize);
3163  if (error) {
3164  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3165  " for opcode at: 0x" +
3166  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3167  moveToEnd();
3168  return;
3169  }
3170  DEBUG_WITH_TYPE("mach-o-rebase",
3171  dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3172  << format("SegmentOffset=0x%06X",
3173  SegmentOffset) << "\n");
3174  break;
3176  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3177  PointerSize);
3178  if (error) {
3179  *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3180  Twine(error) + " for opcode at: 0x" +
3181  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3182  moveToEnd();
3183  return;
3184  }
3185  SegmentOffset += ImmValue * PointerSize;
3186  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3187  PointerSize);
3188  if (error) {
3189  *E =
3190  malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED "
3191  " (after adding immediate times the pointer size) " +
3192  Twine(error) + " for opcode at: 0x" +
3193  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3194  moveToEnd();
3195  return;
3196  }
3197  DEBUG_WITH_TYPE("mach-o-rebase",
3198  dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3199  << format("SegmentOffset=0x%06X",
3200  SegmentOffset) << "\n");
3201  break;
3203  AdvanceAmount = PointerSize;
3204  Skip = 0;
3205  Count = ImmValue;
3206  if (ImmValue != 0)
3207  RemainingLoopCount = ImmValue - 1;
3208  else
3209  RemainingLoopCount = 0;
3210  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3211  PointerSize, Count, Skip);
3212  if (error) {
3213  *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3214  Twine(error) + " for opcode at: 0x" +
3215  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3216  moveToEnd();
3217  return;
3218  }
3220  "mach-o-rebase",
3221  dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3222  << format("SegmentOffset=0x%06X", SegmentOffset)
3223  << ", AdvanceAmount=" << AdvanceAmount
3224  << ", RemainingLoopCount=" << RemainingLoopCount
3225  << "\n");
3226  return;
3228  AdvanceAmount = PointerSize;
3229  Skip = 0;
3230  Count = readULEB128(&error);
3231  if (error) {
3232  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3233  Twine(error) + " for opcode at: 0x" +
3234  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3235  moveToEnd();
3236  return;
3237  }
3238  if (Count != 0)
3239  RemainingLoopCount = Count - 1;
3240  else
3241  RemainingLoopCount = 0;
3242  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3243  PointerSize, Count, Skip);
3244  if (error) {
3245  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3246  Twine(error) + " for opcode at: 0x" +
3247  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3248  moveToEnd();
3249  return;
3250  }
3252  "mach-o-rebase",
3253  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3254  << format("SegmentOffset=0x%06X", SegmentOffset)
3255  << ", AdvanceAmount=" << AdvanceAmount
3256  << ", RemainingLoopCount=" << RemainingLoopCount
3257  << "\n");
3258  return;
3260  Skip = readULEB128(&error);
3261  if (error) {
3262  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3263  Twine(error) + " for opcode at: 0x" +
3264  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3265  moveToEnd();
3266  return;
3267  }
3268  AdvanceAmount = Skip + PointerSize;
3269  Count = 1;
3270  RemainingLoopCount = 0;
3271  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3272  PointerSize, Count, Skip);
3273  if (error) {
3274  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3275  Twine(error) + " for opcode at: 0x" +
3276  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3277  moveToEnd();
3278  return;
3279  }
3281  "mach-o-rebase",
3282  dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3283  << format("SegmentOffset=0x%06X", SegmentOffset)
3284  << ", AdvanceAmount=" << AdvanceAmount
3285  << ", RemainingLoopCount=" << RemainingLoopCount
3286  << "\n");
3287  return;
3289  Count = readULEB128(&error);
3290  if (error) {
3291  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3292  "ULEB " +
3293  Twine(error) + " for opcode at: 0x" +
3294  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3295  moveToEnd();
3296  return;
3297  }
3298  if (Count != 0)
3299  RemainingLoopCount = Count - 1;
3300  else
3301  RemainingLoopCount = 0;
3302  Skip = readULEB128(&error);
3303  if (error) {
3304  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3305  "ULEB " +
3306  Twine(error) + " for opcode at: 0x" +
3307  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3308  moveToEnd();
3309  return;
3310  }
3311  AdvanceAmount = Skip + PointerSize;
3312 
3313  error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3314  PointerSize, Count, Skip);
3315  if (error) {
3316  *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3317  "ULEB " +
3318  Twine(error) + " for opcode at: 0x" +
3319  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3320  moveToEnd();
3321  return;
3322  }
3324  "mach-o-rebase",
3325  dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3326  << format("SegmentOffset=0x%06X", SegmentOffset)
3327  << ", AdvanceAmount=" << AdvanceAmount
3328  << ", RemainingLoopCount=" << RemainingLoopCount
3329  << "\n");
3330  return;
3331  default:
3332  *E = malformedError("bad rebase info (bad opcode value 0x" +
3333  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3334  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3335  moveToEnd();
3336  return;
3337  }
3338  }
3339 }
3340 
3341 uint64_t MachORebaseEntry::readULEB128(const char **error) {
3342  unsigned Count;
3343  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3344  Ptr += Count;
3345  if (Ptr > Opcodes.end())
3346  Ptr = Opcodes.end();
3347  return Result;
3348 }
3349 
3350 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3351 
3353 
3355  switch (RebaseType) {
3357  return "pointer";
3359  return "text abs32";
3361  return "text rel32";
3362  }
3363  return "unknown";
3364 }
3365 
3366 // For use with the SegIndex of a checked Mach-O Rebase entry
3367 // to get the segment name.
3369  return O->BindRebaseSegmentName(SegmentIndex);
3370 }
3371 
3372 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3373 // to get the section name.
3375  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3376 }
3377 
3378 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3379 // to get the address.
3380 uint64_t MachORebaseEntry::address() const {
3381  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3382 }
3383 
3385 #ifdef EXPENSIVE_CHECKS
3386  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3387 #else
3388  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3389 #endif
3390  return (Ptr == Other.Ptr) &&
3391  (RemainingLoopCount == Other.RemainingLoopCount) &&
3392  (Done == Other.Done);
3393 }
3394 
3397  ArrayRef<uint8_t> Opcodes, bool is64) {
3398  if (O->BindRebaseSectionTable == nullptr)
3399  O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
3400  MachORebaseEntry Start(&Err, O, Opcodes, is64);
3401  Start.moveToFirst();
3402 
3403  MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3404  Finish.moveToEnd();
3405 
3406  return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3407 }
3408 
3410  return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3411 }
3412 
3414  ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3415  : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3416  PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3417 
3418 void MachOBindEntry::moveToFirst() {
3419  Ptr = Opcodes.begin();
3420  moveNext();
3421 }
3422 
3423 void MachOBindEntry::moveToEnd() {
3424  Ptr = Opcodes.end();
3425  RemainingLoopCount = 0;
3426  Done = true;
3427 }
3428 
3430  ErrorAsOutParameter ErrAsOutParam(E);
3431  // If in the middle of some loop, move to next binding in loop.
3432  SegmentOffset += AdvanceAmount;
3433  if (RemainingLoopCount) {
3434  --RemainingLoopCount;
3435  return;
3436  }
3437  // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3438  // pointer size. Therefore it is possible to reach the end without ever having
3439  // seen BIND_OPCODE_DONE.
3440  if (Ptr == Opcodes.end()) {
3441  Done = true;
3442  return;
3443  }
3444  bool More = true;
3445  while (More) {
3446  // Parse next opcode and set up next loop.
3447  const uint8_t *OpcodeStart = Ptr;
3448  uint8_t Byte = *Ptr++;
3449  uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3450  uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3451  int8_t SignExtended;
3452  const uint8_t *SymStart;
3453  uint32_t Count, Skip;
3454  const char *error = nullptr;
3455  switch (Opcode) {
3457  if (TableKind == Kind::Lazy) {
3458  // Lazying bindings have a DONE opcode between entries. Need to ignore
3459  // it to advance to next entry. But need not if this is last entry.
3460  bool NotLastEntry = false;
3461  for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3462  if (*P) {
3463  NotLastEntry = true;
3464  }
3465  }
3466  if (NotLastEntry)
3467  break;
3468  }
3469  More = false;
3470  moveToEnd();
3471  DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n");
3472  break;
3474  if (TableKind == Kind::Weak) {
3475  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3476  "weak bind table for opcode at: 0x" +
3477  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3478  moveToEnd();
3479  return;
3480  }
3481  Ordinal = ImmValue;
3482  LibraryOrdinalSet = true;
3483  if (ImmValue > O->getLibraryCount()) {
3484  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3485  "library ordinal: " +
3486  Twine((int)ImmValue) + " (max " +
3487  Twine((int)O->getLibraryCount()) +
3488  ") for opcode at: 0x" +
3489  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3490  moveToEnd();
3491  return;
3492  }
3494  "mach-o-bind",
3495  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3496  << "Ordinal=" << Ordinal << "\n");
3497  break;
3499  if (TableKind == Kind::Weak) {
3500  *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3501  "weak bind table for opcode at: 0x" +
3502  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3503  moveToEnd();
3504  return;
3505  }
3506  Ordinal = readULEB128(&error);
3507  LibraryOrdinalSet = true;
3508  if (error) {
3509  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3510  Twine(error) + " for opcode at: 0x" +
3511  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3512  moveToEnd();
3513  return;
3514  }
3515  if (Ordinal > (int)O->getLibraryCount()) {
3516  *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3517  "library ordinal: " +
3518  Twine((int)Ordinal) + " (max " +
3519  Twine((int)O->getLibraryCount()) +
3520  ") for opcode at: 0x" +
3521  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3522  moveToEnd();
3523  return;
3524  }
3526  "mach-o-bind",
3527  dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3528  << "Ordinal=" << Ordinal << "\n");
3529  break;
3531  if (TableKind == Kind::Weak) {
3532  *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3533  "weak bind table for opcode at: 0x" +
3534  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3535  moveToEnd();
3536  return;
3537  }
3538  if (ImmValue) {
3539  SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3540  Ordinal = SignExtended;
3541  if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3542  *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3543  "special ordinal: " +
3544  Twine((int)Ordinal) + " for opcode at: 0x" +
3545  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3546  moveToEnd();
3547  return;
3548  }
3549  } else
3550  Ordinal = 0;
3551  LibraryOrdinalSet = true;
3553  "mach-o-bind",
3554  dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3555  << "Ordinal=" << Ordinal << "\n");
3556  break;
3558  Flags = ImmValue;
3559  SymStart = Ptr;
3560  while (*Ptr && (Ptr < Opcodes.end())) {
3561  ++Ptr;
3562  }
3563  if (Ptr == Opcodes.end()) {
3564  *E = malformedError(
3565  "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3566  "symbol name extends past opcodes for opcode at: 0x" +
3567  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3568  moveToEnd();
3569  return;
3570  }
3571  SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3572  Ptr-SymStart);
3573  ++Ptr;
3575  "mach-o-bind",
3576  dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3577  << "SymbolName=" << SymbolName << "\n");
3578  if (TableKind == Kind::Weak) {
3580  return;
3581  }
3582  break;
3584  BindType = ImmValue;
3585  if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3586  *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3587  Twine((int)ImmValue) + " for opcode at: 0x" +
3588  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3589  moveToEnd();
3590  return;
3591  }
3593  "mach-o-bind",
3594  dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
3595  << "BindType=" << (int)BindType << "\n");
3596  break;
3598  Addend = readSLEB128(&error);
3599  if (error) {
3600  *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3601  " for opcode at: 0x" +
3602  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3603  moveToEnd();
3604  return;
3605  }
3607  "mach-o-bind",
3608  dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
3609  << "Addend=" << Addend << "\n");
3610  break;
3612  SegmentIndex = ImmValue;
3613  SegmentOffset = readULEB128(&error);
3614  if (error) {
3615  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3616  Twine(error) + " for opcode at: 0x" +
3617  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3618  moveToEnd();
3619  return;
3620  }
3621  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3622  PointerSize);
3623  if (error) {
3624  *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3625  Twine(error) + " for opcode at: 0x" +
3626  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3627  moveToEnd();
3628  return;
3629  }
3631  "mach-o-bind",
3632  dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3633  << "SegmentIndex=" << SegmentIndex << ", "
3634  << format("SegmentOffset=0x%06X", SegmentOffset)
3635  << "\n");
3636  break;
3638  SegmentOffset += readULEB128(&error);
3639  if (error) {
3640  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3641  " for opcode at: 0x" +
3642  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3643  moveToEnd();
3644  return;
3645  }
3646  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3647  PointerSize);
3648  if (error) {
3649  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3650  " for opcode at: 0x" +
3651  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3652  moveToEnd();
3653  return;
3654  }
3655  DEBUG_WITH_TYPE("mach-o-bind",
3656  dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
3657  << format("SegmentOffset=0x%06X",
3658  SegmentOffset) << "\n");
3659  break;
3661  AdvanceAmount = PointerSize;
3662  RemainingLoopCount = 0;
3663  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3664  PointerSize);
3665  if (error) {
3666  *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3667  " for opcode at: 0x" +
3668  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3669  moveToEnd();
3670  return;
3671  }
3672  if (SymbolName == StringRef()) {
3673  *E = malformedError(
3674  "for BIND_OPCODE_DO_BIND missing preceding "
3675  "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3676  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3677  moveToEnd();
3678  return;
3679  }
3680  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3681  *E =
3682  malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3683  "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3684  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3685  moveToEnd();
3686  return;
3687  }
3688  DEBUG_WITH_TYPE("mach-o-bind",
3689  dbgs() << "BIND_OPCODE_DO_BIND: "
3690  << format("SegmentOffset=0x%06X",
3691  SegmentOffset) << "\n");
3692  return;
3694  if (TableKind == Kind::Lazy) {
3695  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3696  "lazy bind table for opcode at: 0x" +
3697  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3698  moveToEnd();
3699  return;
3700  }
3701  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3702  PointerSize);
3703  if (error) {
3704  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3705  Twine(error) + " for opcode at: 0x" +
3706  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3707  moveToEnd();
3708  return;
3709  }
3710  if (SymbolName == StringRef()) {
3711  *E = malformedError(
3712  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3713  "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3714  "at: 0x" +
3715  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3716  moveToEnd();
3717  return;
3718  }
3719  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3720  *E = malformedError(
3721  "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3722  "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3723  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3724  moveToEnd();
3725  return;
3726  }
3727  AdvanceAmount = readULEB128(&error) + PointerSize;
3728  if (error) {
3729  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3730  Twine(error) + " for opcode at: 0x" +
3731  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3732  moveToEnd();
3733  return;
3734  }
3735  // Note, this is not really an error until the next bind but make no sense
3736  // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3737  // bind operation.
3738  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
3739  AdvanceAmount, PointerSize);
3740  if (error) {
3741  *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3742  "ULEB) " +
3743  Twine(error) + " for opcode at: 0x" +
3744  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3745  moveToEnd();
3746  return;
3747  }
3748  RemainingLoopCount = 0;
3750  "mach-o-bind",
3751  dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
3752  << format("SegmentOffset=0x%06X", SegmentOffset)
3753  << ", AdvanceAmount=" << AdvanceAmount
3754  << ", RemainingLoopCount=" << RemainingLoopCount
3755  << "\n");
3756  return;
3758  if (TableKind == Kind::Lazy) {
3759  *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3760  "allowed in lazy bind table for opcode at: 0x" +
3761  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3762  moveToEnd();
3763  return;
3764  }
3765  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3766  PointerSize);
3767  if (error) {
3768  *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
3769  Twine(error) + " for opcode at: 0x" +
3770  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3771  moveToEnd();
3772  return;
3773  }
3774  if (SymbolName == StringRef()) {
3775  *E = malformedError(
3776  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3777  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3778  "opcode at: 0x" +
3779  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3780  moveToEnd();
3781  return;
3782  }
3783  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3784  *E = malformedError(
3785  "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3786  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3787  "at: 0x" +
3788  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3789  moveToEnd();
3790  return;
3791  }
3792  AdvanceAmount = ImmValue * PointerSize + PointerSize;
3793  RemainingLoopCount = 0;
3794  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
3795  AdvanceAmount, PointerSize);
3796  if (error) {
3797  *E =
3798  malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3799  " (after adding immediate times the pointer size) " +
3800  Twine(error) + " for opcode at: 0x" +
3801  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3802  moveToEnd();
3803  return;
3804  }
3805  DEBUG_WITH_TYPE("mach-o-bind",
3806  dbgs()
3807  << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
3808  << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
3809  return;
3811  if (TableKind == Kind::Lazy) {
3812  *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
3813  "allowed in lazy bind table for opcode at: 0x" +
3814  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3815  moveToEnd();
3816  return;
3817  }
3818  Count = readULEB128(&error);
3819  if (Count != 0)
3820  RemainingLoopCount = Count - 1;
3821  else
3822  RemainingLoopCount = 0;
3823  if (error) {
3824  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3825  " (count value) " +
3826  Twine(error) + " for opcode at: 0x" +
3827  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3828  moveToEnd();
3829  return;
3830  }
3831  Skip = readULEB128(&error);
3832  AdvanceAmount = Skip + PointerSize;
3833  if (error) {
3834  *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3835  " (skip value) " +
3836  Twine(error) + " for opcode at: 0x" +
3837  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3838  moveToEnd();
3839  return;
3840  }
3841  if (SymbolName == StringRef()) {
3842  *E = malformedError(
3843  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3844  "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3845  "opcode at: 0x" +
3846  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3847  moveToEnd();
3848  return;
3849  }
3850  if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3851  *E = malformedError(
3852  "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3853  "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3854  "at: 0x" +
3855  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3856  moveToEnd();
3857  return;
3858  }
3859  error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3860  PointerSize, Count, Skip);
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  }
3870  "mach-o-bind",
3871  dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
3872  << format("SegmentOffset=0x%06X", SegmentOffset)
3873  << ", AdvanceAmount=" << AdvanceAmount
3874  << ", RemainingLoopCount=" << RemainingLoopCount
3875  << "\n");
3876  return;
3877  default:
3878  *E = malformedError("bad bind info (bad opcode value 0x" +
3879  Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3880  Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3881  moveToEnd();
3882  return;
3883  }
3884  }
3885 }
3886 
3887 uint64_t MachOBindEntry::readULEB128(const char **error) {
3888  unsigned Count;
3889  uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3890  Ptr += Count;
3891  if (Ptr > Opcodes.end())
3892  Ptr = Opcodes.end();
3893  return Result;
3894 }
3895 
3896 int64_t MachOBindEntry::readSLEB128(const char **error) {
3897  unsigned Count;
3898  int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
3899  Ptr += Count;
3900  if (Ptr > Opcodes.end())
3901  Ptr = Opcodes.end();
3902  return Result;
3903 }
3904 
3905 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
3906 
3907 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
3908 
3910  switch (BindType) {
3912  return "pointer";
3914  return "text abs32";
3916  return "text rel32";
3917  }
3918  return "unknown";
3919 }
3920 
3922 
3923 int64_t MachOBindEntry::addend() const { return Addend; }
3924 
3925 uint32_t MachOBindEntry::flags() const { return Flags; }
3926 
3927 int MachOBindEntry::ordinal() const { return Ordinal; }
3928 
3929 // For use with the SegIndex of a checked Mach-O Bind entry
3930 // to get the segment name.
3932  return O->BindRebaseSegmentName(SegmentIndex);
3933 }
3934 
3935 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3936 // to get the section name.
3938  return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3939 }
3940 
3941 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3942 // to get the address.
3943 uint64_t MachOBindEntry::address() const {
3944  return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3945 }
3946 
3948 #ifdef EXPENSIVE_CHECKS
3949  assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3950 #else
3951  assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3952 #endif
3953  return (Ptr == Other.Ptr) &&
3954  (RemainingLoopCount == Other.RemainingLoopCount) &&
3955  (Done == Other.Done);
3956 }
3957 
3958 // Build table of sections so SegIndex/SegOffset pairs can be translated.
3960  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
3961  StringRef CurSegName;
3962  uint64_t CurSegAddress;
3963  for (const SectionRef &Section : Obj->sections()) {
3964  SectionInfo Info;
3965  Section.getName(Info.SectionName);
3966  Info.Address = Section.getAddress();
3967  Info.Size = Section.getSize();
3968  Info.SegmentName =
3969  Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
3970  if (!Info.SegmentName.equals(CurSegName)) {
3971  ++CurSegIndex;
3972  CurSegName = Info.SegmentName;
3973  CurSegAddress = Info.Address;
3974  }
3975  Info.SegmentIndex = CurSegIndex - 1;
3976  Info.OffsetInSegment = Info.Address - CurSegAddress;
3977  Info.SegmentStartAddress = CurSegAddress;
3978  Sections.push_back(Info);
3979  }
3980  MaxSegIndex = CurSegIndex;
3981 }
3982 
3983 // For use with a SegIndex, SegOffset, and PointerSize triple in
3984 // MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry.
3985 //
3986 // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
3987 // that fully contains a pointer at that location. Multiple fixups in a bind
3988 // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
3989 // be tested via the Count and Skip parameters.
3990 const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
3991  uint64_t SegOffset,
3992  uint8_t PointerSize,
3993  uint32_t Count,
3994  uint32_t Skip) {
3995  if (SegIndex == -1)
3996  return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
3997  if (SegIndex >= MaxSegIndex)
3998  return "bad segIndex (too large)";
3999  for (uint32_t i = 0; i < Count; ++i) {
4000  uint32_t Start = SegOffset + i * (PointerSize + Skip);
4001  uint32_t End = Start + PointerSize;
4002  bool Found = false;
4003  for (const SectionInfo &SI : Sections) {
4004  if (SI.SegmentIndex != SegIndex)
4005  continue;
4006  if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4007  if (End <= SI.OffsetInSegment + SI.Size) {
4008  Found = true;
4009  break;
4010  }
4011  else
4012  return "bad offset, extends beyond section boundary";
4013  }
4014  }
4015  if (!Found)
4016  return "bad offset, not in section";
4017  }
4018  return nullptr;
4019 }
4020 
4021 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4022 // to get the segment name.
4024  for (const SectionInfo &SI : Sections) {
4025  if (SI.SegmentIndex == SegIndex)
4026  return SI.SegmentName;
4027  }
4028  llvm_unreachable("invalid SegIndex");
4029 }
4030 
4031 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4032 // to get the SectionInfo.
4033 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4034  int32_t SegIndex, uint64_t SegOffset) {
4035  for (const SectionInfo &SI : Sections) {
4036  if (SI.SegmentIndex != SegIndex)
4037  continue;
4038  if (SI.OffsetInSegment > SegOffset)
4039  continue;
4040  if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4041  continue;
4042  return SI;
4043  }
4044  llvm_unreachable("SegIndex and SegOffset not in any section");
4045 }
4046 
4047 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4048 // entry to get the section name.
4050  uint64_t SegOffset) {
4051  return findSection(SegIndex, SegOffset).SectionName;
4052 }
4053 
4054 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4055 // entry to get the address.
4056 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4057  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4058  return SI.SegmentStartAddress + OffsetInSeg;
4059 }
4060 
4063  ArrayRef<uint8_t> Opcodes, bool is64,
4064  MachOBindEntry::Kind BKind) {
4065  if (O->BindRebaseSectionTable == nullptr)
4066  O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
4067  MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4068  Start.moveToFirst();
4069 
4070  MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4071  Finish.moveToEnd();
4072 
4073  return make_range(bind_iterator(Start), bind_iterator(Finish));
4074 }
4075 
4077  return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4079 }
4080 
4082  return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4084 }
4085 
4087  return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
4089 }
4090 
4093  return LoadCommands.begin();
4094 }
4095 
4098  return LoadCommands.end();
4099 }
4100 
4103  return make_range(begin_load_commands(), end_load_commands());
4104 }
4105 
4106 StringRef
4108  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4109  return parseSegmentOrSectionName(Raw.data());
4110 }
4111 
4114  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4115  const section_base *Base =
4116  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4117  return makeArrayRef(Base->sectname);
4118 }
4119 
4122  assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4123  const section_base *Base =
4124  reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4125  return makeArrayRef(Base->segname);
4126 }
4127 
4128 bool
4130  const {
4131  if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4132  return false;
4134 }
4135 
4137  const MachO::any_relocation_info &RE) const {
4138  if (isLittleEndian())
4139  return RE.r_word1 & 0xffffff;
4140  return RE.r_word1 >> 8;
4141 }
4142 
4144  const MachO::any_relocation_info &RE) const {
4145  if (isLittleEndian())
4146  return (RE.r_word1 >> 27) & 1;
4147  return (RE.r_word1 >> 4) & 1;
4148 }
4149 
4151  const MachO::any_relocation_info &RE) const {
4152  return RE.r_word0 >> 31;
4153 }
4154 
4156  const MachO::any_relocation_info &RE) const {
4157  return RE.r_word1;
4158 }
4159 
4161  const MachO::any_relocation_info &RE) const {
4162  return (RE.r_word0 >> 24) & 0xf;
4163 }
4164 
4166  const MachO::any_relocation_info &RE) const {
4167  if (isRelocationScattered(RE))
4168  return getScatteredRelocationAddress(RE);
4169  return getPlainRelocationAddress(RE);
4170 }
4171 
4173  const MachO::any_relocation_info &RE) const {
4174  if (isRelocationScattered(RE))
4175  return getScatteredRelocationPCRel(RE);
4176  return getPlainRelocationPCRel(*this, RE);
4177 }
4178 
4180  const MachO::any_relocation_info &RE) const {
4181  if (isRelocationScattered(RE))
4182  return getScatteredRelocationLength(RE);
4183  return getPlainRelocationLength(*this, RE);
4184 }
4185 
4186 unsigned
4188  const MachO::any_relocation_info &RE) const {
4189  if (isRelocationScattered(RE))
4190  return getScatteredRelocationType(RE);
4191  return getPlainRelocationType(*this, RE);
4192 }
4193 
4194 SectionRef
4196  const MachO::any_relocation_info &RE) const {
4197  if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4198  return *section_end();
4199  unsigned SecNum = getPlainRelocationSymbolNum(RE);
4200  if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4201  return *section_end();
4202  DataRefImpl DRI;
4203  DRI.d.a = SecNum - 1;
4204  return SectionRef(DRI, this);
4205 }
4206 
4208  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4209  return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4210 }
4211 
4213  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4214  return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4215 }
4216 
4218  unsigned Index) const {
4219  const char *Sec = getSectionPtr(*this, L, Index);
4220  return getStruct<MachO::section>(*this, Sec);
4221 }
4222 
4224  unsigned Index) const {
4225  const char *Sec = getSectionPtr(*this, L, Index);
4226  return getStruct<MachO::section_64>(*this, Sec);
4227 }
4228 
4231  const char *P = reinterpret_cast<const char *>(DRI.p);
4232  return getStruct<MachO::nlist>(*this, P);
4233 }
4234 
4237  const char *P = reinterpret_cast<const char *>(DRI.p);
4238  return getStruct<MachO::nlist_64>(*this, P);
4239 }
4240 
4243  return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4244 }
4245 
4248  return getStruct<MachO::segment_command>(*this, L.Ptr);
4249 }
4250 
4253  return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4254 }
4255 
4258  return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4259 }
4260 
4263  return getStruct<MachO::version_min_command>(*this, L.Ptr);
4264 }
4265 
4268  return getStruct<MachO::note_command>(*this, L.Ptr);
4269 }
4270 
4273  return getStruct<MachO::build_version_command>(*this, L.Ptr);
4274 }
4275 
4278  return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4279 }
4280 
4283  return getStruct<MachO::dylib_command>(*this, L.Ptr);
4284 }
4285 
4288  return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4289 }
4290 
4293  return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4294 }
4295 
4298  return getStruct<MachO::uuid_command>(*this, L.Ptr);
4299 }
4300 
4303  return getStruct<MachO::rpath_command>(*this, L.Ptr);
4304 }
4305 
4308  return getStruct<MachO::source_version_command>(*this, L.Ptr);
4309 }
4310 
4313  return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4314 }
4315 
4318  return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4319 }
4320 
4323  return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4324 }
4325 
4328  return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4329 }
4330 
4333  return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4334 }
4335 
4338  return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4339 }
4340 
4343  return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4344 }
4345 
4348  return getStruct<MachO::routines_command>(*this, L.Ptr);
4349 }
4350 
4353  return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4354 }
4355 
4358  return getStruct<MachO::thread_command>(*this, L.Ptr);
4359 }
4360 
4363  uint32_t Offset;
4364  if (getHeader().filetype == MachO::MH_OBJECT) {
4365  DataRefImpl Sec;
4366  Sec.d.a = Rel.d.a;
4367  if (is64Bit()) {
4368  MachO::section_64 Sect = getSection64(Sec);
4369  Offset = Sect.reloff;
4370  } else {
4371  MachO::section Sect = getSection(Sec);
4372  Offset = Sect.reloff;
4373  }
4374  } else {
4375  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4376  if (Rel.d.a == 0)
4377  Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4378  else
4379  Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4380  }
4381 
4382  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4383  getPtr(*this, Offset)) + Rel.d.b;
4384  return getStruct<MachO::any_relocation_info>(
4385  *this, reinterpret_cast<const char *>(P));
4386 }
4387 
4390  const char *P = reinterpret_cast<const char *>(Rel.p);
4391  return getStruct<MachO::data_in_code_entry>(*this, P);
4392 }
4393 
4395  return Header;
4396 }
4397 
4399  assert(is64Bit());
4400  return Header64;
4401 }
4402 
4404  const MachO::dysymtab_command &DLC,
4405  unsigned Index) const {
4406  uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4407  return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4408 }
4409 
4412  unsigned Index) const {
4413  uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4414  return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4415 }
4416 
4418  if (SymtabLoadCmd)
4419  return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4420 
4421  // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4423  Cmd.cmd = MachO::LC_SYMTAB;
4424  Cmd.cmdsize = sizeof(MachO::symtab_command);
4425  Cmd.symoff = 0;
4426  Cmd.nsyms = 0;
4427  Cmd.stroff = 0;
4428  Cmd.strsize = 0;
4429  return Cmd;
4430 }
4431 
4433  if (DysymtabLoadCmd)
4434  return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4435 
4436  // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4438  Cmd.cmd = MachO::LC_DYSYMTAB;
4439  Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4440  Cmd.ilocalsym = 0;
4441  Cmd.nlocalsym = 0;
4442  Cmd.iextdefsym = 0;
4443  Cmd.nextdefsym = 0;
4444  Cmd.iundefsym = 0;
4445  Cmd.nundefsym = 0;
4446  Cmd.tocoff = 0;
4447  Cmd.ntoc = 0;
4448  Cmd.modtaboff = 0;
4449  Cmd.nmodtab = 0;
4450  Cmd.extrefsymoff = 0;
4451  Cmd.nextrefsyms = 0;
4452  Cmd.indirectsymoff = 0;
4453  Cmd.nindirectsyms = 0;
4454  Cmd.extreloff = 0;
4455  Cmd.nextrel = 0;
4456  Cmd.locreloff = 0;
4457  Cmd.nlocrel = 0;
4458  return Cmd;
4459 }
4460 
4463  if (DataInCodeLoadCmd)
4464  return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4465 
4466  // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4468  Cmd.cmd = MachO::LC_DATA_IN_CODE;
4469  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4470  Cmd.dataoff = 0;
4471  Cmd.datasize = 0;
4472  return Cmd;
4473 }
4474 
4477  if (LinkOptHintsLoadCmd)
4478  return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4479 
4480  // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4481  // fields.
4483  Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4484  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4485  Cmd.dataoff = 0;
4486  Cmd.datasize = 0;
4487  return Cmd;
4488 }
4489 
4491  if (!DyldInfoLoadCmd)
4492  return None;
4493 
4494  MachO::dyld_info_command DyldInfo =
4495  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4496  const uint8_t *Ptr =
4497  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4498  return makeArrayRef(Ptr, DyldInfo.rebase_size);
4499 }
4500 
4502  if (!DyldInfoLoadCmd)
4503  return None;
4504 
4505  MachO::dyld_info_command DyldInfo =
4506  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4507  const uint8_t *Ptr =
4508  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4509  return makeArrayRef(Ptr, DyldInfo.bind_size);
4510 }
4511 
4513  if (!DyldInfoLoadCmd)
4514  return None;
4515 
4516  MachO::dyld_info_command DyldInfo =
4517  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4518  const uint8_t *Ptr =
4519  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4520  return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4521 }
4522 
4524  if (!DyldInfoLoadCmd)
4525  return None;
4526 
4527  MachO::dyld_info_command DyldInfo =
4528  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4529  const uint8_t *Ptr =
4530  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4531  return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4532 }
4533 
4535  if (!DyldInfoLoadCmd)
4536  return None;
4537 
4538  MachO::dyld_info_command DyldInfo =
4539  getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4540  const uint8_t *Ptr =
4541  reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
4542  return makeArrayRef(Ptr, DyldInfo.export_size);
4543 }
4544 
4546  if (!UuidLoadCmd)
4547  return None;
4548  // Returning a pointer is fine as uuid doesn't need endian swapping.
4549  const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
4550  return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4551 }
4552 
4554  MachO::symtab_command S = getSymtabLoadCommand();
4555  return getData().substr(S.stroff, S.strsize);
4556 }
4557 
4559  return getType() == getMachOType(false, true) ||
4560  getType() == getMachOType(true, true);
4561 }
4562 
4564  SmallVectorImpl<uint64_t> &Out) const {
4565  DataExtractor extractor(ObjectFile::getData(), true, 0);
4566 
4567  uint32_t offset = Index;
4568  uint64_t data = 0;
4569  while (uint64_t delta = extractor.getULEB128(&offset)) {
4570  data += delta;
4571  Out.push_back(data);
4572  }
4573 }
4574 
4576  return getHeader().filetype == MachO::MH_OBJECT;
4577 }
4578 
4581  uint32_t UniversalCputype,
4582  uint32_t UniversalIndex) {
4583  StringRef Magic = Buffer.getBuffer().slice(0, 4);
4584  if (Magic == "\xFE\xED\xFA\xCE")
4585  return MachOObjectFile::create(Buffer, false, false,
4586  UniversalCputype, UniversalIndex);
4587  if (Magic == "\xCE\xFA\xED\xFE")
4588  return MachOObjectFile::create(Buffer, true, false,
4589  UniversalCputype, UniversalIndex);
4590  if (Magic == "\xFE\xED\xFA\xCF")
4591  return MachOObjectFile::create(Buffer, false, true,
4592  UniversalCputype, UniversalIndex);
4593  if (Magic == "\xCF\xFA\xED\xFE")
4594  return MachOObjectFile::create(Buffer, true, true,
4595  UniversalCputype, UniversalIndex);
4596  return make_error<GenericBinaryError>("Unrecognized MachO magic number",
4598 }
4599 
4602  .Case("debug_str_offs", "debug_str_offsets")
4603  .Default(Name);
4604 }
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
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:233
void swapStruct(fat_header &mh)
Definition: MachO.h:996
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
const uint32_t x86_FLOAT_STATE_COUNT
Definition: MachO.h:1785
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:991
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:442
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:224
const uint32_t x86_EXCEPTION_STATE64_COUNT
Definition: MachO.h:1780
uint8_t n_sect
Definition: MachO.h:981
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
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).
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)
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
bool hasPageZeroSegment() const
Definition: MachO.h:580
Expected< SectionRef > getSection(unsigned SectionIndex) const
This class is the base class for all object file types.
Definition: ObjectFile.h:226
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
uint64_t getRelocationType(DataRefImpl Rel) const override
ArrayRef< uint8_t > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
Definition: StringExtras.h:60
#define error(X)
static StringRef parseSegmentOrSectionName(const char *P)
unsigned getSectionType(SectionRef Sec) const
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
Definition: MachO.h:1384
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
Definition: MachO.h:167
uint64_t getSectionAlignment(DataRefImpl Sec) const override
F(f)
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
Definition