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