1//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the MachOObjectFile class, which binds the MachOObject
11// class to the generic ObjectFile wrapper.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Object/MachO.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/Triple.h"
18#include "llvm/Support/DataExtractor.h"
19#include "llvm/Support/Format.h"
20#include "llvm/Support/Host.h"
21#include "llvm/Support/MemoryBuffer.h"
22#include "llvm/Support/raw_ostream.h"
23#include <cctype>
24#include <cstring>
25#include <limits>
26
27using namespace llvm;
28using namespace object;
29
30namespace llvm {
31
32namespace object {
33
34struct nlist_base {
35  uint32_t n_strx;
36  uint8_t n_type;
37  uint8_t n_sect;
38  uint16_t n_desc;
39};
40
41struct section_base {
42  char sectname[16];
43  char segname[16];
44};
45
46template<typename T>
47static void SwapStruct(T &Value);
48
49template<>
50void SwapStruct(MachO::any_relocation_info &H) {
51  sys::swapByteOrder(H.r_word0);
52  sys::swapByteOrder(H.r_word1);
53}
54
55template<>
56void SwapStruct(MachO::load_command &L) {
57  sys::swapByteOrder(L.cmd);
58  sys::swapByteOrder(L.cmdsize);
59}
60
61template<>
62void SwapStruct(nlist_base &S) {
63  sys::swapByteOrder(S.n_strx);
64  sys::swapByteOrder(S.n_desc);
65}
66
67template<>
68void SwapStruct(MachO::section &S) {
69  sys::swapByteOrder(S.addr);
70  sys::swapByteOrder(S.size);
71  sys::swapByteOrder(S.offset);
72  sys::swapByteOrder(S.align);
73  sys::swapByteOrder(S.reloff);
74  sys::swapByteOrder(S.nreloc);
75  sys::swapByteOrder(S.flags);
76  sys::swapByteOrder(S.reserved1);
77  sys::swapByteOrder(S.reserved2);
78}
79
80template<>
81void SwapStruct(MachO::section_64 &S) {
82  sys::swapByteOrder(S.addr);
83  sys::swapByteOrder(S.size);
84  sys::swapByteOrder(S.offset);
85  sys::swapByteOrder(S.align);
86  sys::swapByteOrder(S.reloff);
87  sys::swapByteOrder(S.nreloc);
88  sys::swapByteOrder(S.flags);
89  sys::swapByteOrder(S.reserved1);
90  sys::swapByteOrder(S.reserved2);
91  sys::swapByteOrder(S.reserved3);
92}
93
94template<>
95void SwapStruct(MachO::nlist &S) {
96  sys::swapByteOrder(S.n_strx);
97  sys::swapByteOrder(S.n_desc);
98  sys::swapByteOrder(S.n_value);
99}
100
101template<>
102void SwapStruct(MachO::nlist_64 &S) {
103  sys::swapByteOrder(S.n_strx);
104  sys::swapByteOrder(S.n_desc);
105  sys::swapByteOrder(S.n_value);
106}
107
108template<>
109void SwapStruct(MachO::mach_header &H) {
110  sys::swapByteOrder(H.magic);
111  sys::swapByteOrder(H.cputype);
112  sys::swapByteOrder(H.cpusubtype);
113  sys::swapByteOrder(H.filetype);
114  sys::swapByteOrder(H.ncmds);
115  sys::swapByteOrder(H.sizeofcmds);
116  sys::swapByteOrder(H.flags);
117}
118
119template<>
120void SwapStruct(MachO::mach_header_64 &H) {
121  sys::swapByteOrder(H.magic);
122  sys::swapByteOrder(H.cputype);
123  sys::swapByteOrder(H.cpusubtype);
124  sys::swapByteOrder(H.filetype);
125  sys::swapByteOrder(H.ncmds);
126  sys::swapByteOrder(H.sizeofcmds);
127  sys::swapByteOrder(H.flags);
128  sys::swapByteOrder(H.reserved);
129}
130
131template<>
132void SwapStruct(MachO::symtab_command &C) {
133  sys::swapByteOrder(C.cmd);
134  sys::swapByteOrder(C.cmdsize);
135  sys::swapByteOrder(C.symoff);
136  sys::swapByteOrder(C.nsyms);
137  sys::swapByteOrder(C.stroff);
138  sys::swapByteOrder(C.strsize);
139}
140
141template<>
142void SwapStruct(MachO::dysymtab_command &C) {
143  sys::swapByteOrder(C.cmd);
144  sys::swapByteOrder(C.cmdsize);
145  sys::swapByteOrder(C.ilocalsym);
146  sys::swapByteOrder(C.nlocalsym);
147  sys::swapByteOrder(C.iextdefsym);
148  sys::swapByteOrder(C.nextdefsym);
149  sys::swapByteOrder(C.iundefsym);
150  sys::swapByteOrder(C.nundefsym);
151  sys::swapByteOrder(C.tocoff);
152  sys::swapByteOrder(C.ntoc);
153  sys::swapByteOrder(C.modtaboff);
154  sys::swapByteOrder(C.nmodtab);
155  sys::swapByteOrder(C.extrefsymoff);
156  sys::swapByteOrder(C.nextrefsyms);
157  sys::swapByteOrder(C.indirectsymoff);
158  sys::swapByteOrder(C.nindirectsyms);
159  sys::swapByteOrder(C.extreloff);
160  sys::swapByteOrder(C.nextrel);
161  sys::swapByteOrder(C.locreloff);
162  sys::swapByteOrder(C.nlocrel);
163}
164
165template<>
166void SwapStruct(MachO::linkedit_data_command &C) {
167  sys::swapByteOrder(C.cmd);
168  sys::swapByteOrder(C.cmdsize);
169  sys::swapByteOrder(C.dataoff);
170  sys::swapByteOrder(C.datasize);
171}
172
173template<>
174void SwapStruct(MachO::segment_command &C) {
175  sys::swapByteOrder(C.cmd);
176  sys::swapByteOrder(C.cmdsize);
177  sys::swapByteOrder(C.vmaddr);
178  sys::swapByteOrder(C.vmsize);
179  sys::swapByteOrder(C.fileoff);
180  sys::swapByteOrder(C.filesize);
181  sys::swapByteOrder(C.maxprot);
182  sys::swapByteOrder(C.initprot);
183  sys::swapByteOrder(C.nsects);
184  sys::swapByteOrder(C.flags);
185}
186
187template<>
188void SwapStruct(MachO::segment_command_64 &C) {
189  sys::swapByteOrder(C.cmd);
190  sys::swapByteOrder(C.cmdsize);
191  sys::swapByteOrder(C.vmaddr);
192  sys::swapByteOrder(C.vmsize);
193  sys::swapByteOrder(C.fileoff);
194  sys::swapByteOrder(C.filesize);
195  sys::swapByteOrder(C.maxprot);
196  sys::swapByteOrder(C.initprot);
197  sys::swapByteOrder(C.nsects);
198  sys::swapByteOrder(C.flags);
199}
200
201template<>
202void SwapStruct(uint32_t &C) {
203  sys::swapByteOrder(C);
204}
205
206template<>
207void SwapStruct(MachO::linker_options_command &C) {
208  sys::swapByteOrder(C.cmd);
209  sys::swapByteOrder(C.cmdsize);
210  sys::swapByteOrder(C.count);
211}
212
213template<>
214void SwapStruct(MachO::version_min_command&C) {
215  sys::swapByteOrder(C.cmd);
216  sys::swapByteOrder(C.cmdsize);
217  sys::swapByteOrder(C.version);
218  sys::swapByteOrder(C.reserved);
219}
220
221template<>
222void SwapStruct(MachO::dylib_command&C) {
223  sys::swapByteOrder(C.cmd);
224  sys::swapByteOrder(C.cmdsize);
225  sys::swapByteOrder(C.dylib.name);
226  sys::swapByteOrder(C.dylib.timestamp);
227  sys::swapByteOrder(C.dylib.current_version);
228  sys::swapByteOrder(C.dylib.compatibility_version);
229}
230
231template<>
232void SwapStruct(MachO::data_in_code_entry &C) {
233  sys::swapByteOrder(C.offset);
234  sys::swapByteOrder(C.length);
235  sys::swapByteOrder(C.kind);
236}
237
238template<typename T>
239T getStruct(const MachOObjectFile *O, const char *P) {
240  T Cmd;
241  memcpy(&Cmd, P, sizeof(T));
242  if (O->isLittleEndian() != sys::IsLittleEndianHost)
243    SwapStruct(Cmd);
244  return Cmd;
245}
246
247static uint32_t
248getSegmentLoadCommandNumSections(const MachOObjectFile *O,
249                                 const MachOObjectFile::LoadCommandInfo &L) {
250  if (O->is64Bit()) {
251    MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
252    return S.nsects;
253  }
254  MachO::segment_command S = O->getSegmentLoadCommand(L);
255  return S.nsects;
256}
257
258static const char *
259getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
260              unsigned Sec) {
261  uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
262
263  bool Is64 = O->is64Bit();
264  unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
265                                    sizeof(MachO::segment_command);
266  unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
267                                sizeof(MachO::section);
268
269  uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
270  return reinterpret_cast<const char*>(SectionAddr);
271}
272
273static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
274  return O->getData().substr(Offset, 1).data();
275}
276
277static nlist_base
278getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
279  const char *P = reinterpret_cast<const char *>(DRI.p);
280  return getStruct<nlist_base>(O, P);
281}
282
283static StringRef parseSegmentOrSectionName(const char *P) {
284  if (P[15] == 0)
285    // Null terminated.
286    return P;
287  // Not null terminated, so this is a 16 char string.
288  return StringRef(P, 16);
289}
290
291// Helper to advance a section or symbol iterator multiple increments at a time.
292template<class T>
293static void advance(T &it, size_t Val) {
294  while (Val--)
295    ++it;
296}
297
298static unsigned getCPUType(const MachOObjectFile *O) {
299  return O->getHeader().cputype;
300}
301
302static void printRelocationTargetName(const MachOObjectFile *O,
303                                      const MachO::any_relocation_info &RE,
304                                      raw_string_ostream &fmt) {
305  bool IsScattered = O->isRelocationScattered(RE);
306
307  // Target of a scattered relocation is an address.  In the interest of
308  // generating pretty output, scan through the symbol table looking for a
309  // symbol that aligns with that address.  If we find one, print it.
310  // Otherwise, we just print the hex address of the target.
311  if (IsScattered) {
312    uint32_t Val = O->getPlainRelocationSymbolNum(RE);
313
314    for (const SymbolRef &Symbol : O->symbols()) {
315      std::error_code ec;
316      uint64_t Addr;
317      StringRef Name;
318
319      if ((ec = Symbol.getAddress(Addr)))
320        report_fatal_error(ec.message());
321      if (Addr != Val)
322        continue;
323      if ((ec = Symbol.getName(Name)))
324        report_fatal_error(ec.message());
325      fmt << Name;
326      return;
327    }
328
329    // If we couldn't find a symbol that this relocation refers to, try
330    // to find a section beginning instead.
331    for (const SectionRef &Section : O->sections()) {
332      std::error_code ec;
333      uint64_t Addr;
334      StringRef Name;
335
336      if ((ec = Section.getAddress(Addr)))
337        report_fatal_error(ec.message());
338      if (Addr != Val)
339        continue;
340      if ((ec = Section.getName(Name)))
341        report_fatal_error(ec.message());
342      fmt << Name;
343      return;
344    }
345
346    fmt << format("0x%x", Val);
347    return;
348  }
349
350  StringRef S;
351  bool isExtern = O->getPlainRelocationExternal(RE);
352  uint64_t Val = O->getPlainRelocationSymbolNum(RE);
353
354  if (isExtern) {
355    symbol_iterator SI = O->symbol_begin();
356    advance(SI, Val);
357    SI->getName(S);
358  } else {
359    section_iterator SI = O->section_begin();
360    // Adjust for the fact that sections are 1-indexed.
361    advance(SI, Val - 1);
362    SI->getName(S);
363  }
364
365  fmt << S;
366}
367
368static uint32_t
369getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
370  return RE.r_word0;
371}
372
373static unsigned
374getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
375  return RE.r_word0 & 0xffffff;
376}
377
378static bool getPlainRelocationPCRel(const MachOObjectFile *O,
379                                    const MachO::any_relocation_info &RE) {
380  if (O->isLittleEndian())
381    return (RE.r_word1 >> 24) & 1;
382  return (RE.r_word1 >> 7) & 1;
383}
384
385static bool
386getScatteredRelocationPCRel(const MachOObjectFile *O,
387                            const MachO::any_relocation_info &RE) {
388  return (RE.r_word0 >> 30) & 1;
389}
390
391static unsigned getPlainRelocationLength(const MachOObjectFile *O,
392                                         const MachO::any_relocation_info &RE) {
393  if (O->isLittleEndian())
394    return (RE.r_word1 >> 25) & 3;
395  return (RE.r_word1 >> 5) & 3;
396}
397
398static unsigned
399getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
400  return (RE.r_word0 >> 28) & 3;
401}
402
403static unsigned getPlainRelocationType(const MachOObjectFile *O,
404                                       const MachO::any_relocation_info &RE) {
405  if (O->isLittleEndian())
406    return RE.r_word1 >> 28;
407  return RE.r_word1 & 0xf;
408}
409
410static unsigned
411getScatteredRelocationType(const MachO::any_relocation_info &RE) {
412  return (RE.r_word0 >> 24) & 0xf;
413}
414
415static uint32_t getSectionFlags(const MachOObjectFile *O,
416                                DataRefImpl Sec) {
417  if (O->is64Bit()) {
418    MachO::section_64 Sect = O->getSection64(Sec);
419    return Sect.flags;
420  }
421  MachO::section Sect = O->getSection(Sec);
422  return Sect.flags;
423}
424
425MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object,
426                                 bool IsLittleEndian, bool Is64bits,
427                                 std::error_code &EC)
428    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)),
429      SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
430      DataInCodeLoadCmd(nullptr) {
431  uint32_t LoadCommandCount = this->getHeader().ncmds;
432  MachO::LoadCommandType SegmentLoadType = is64Bit() ?
433    MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
434
435  MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
436  for (unsigned I = 0; ; ++I) {
437    if (Load.C.cmd == MachO::LC_SYMTAB) {
438      assert(!SymtabLoadCmd && "Multiple symbol tables");
439      SymtabLoadCmd = Load.Ptr;
440    } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
441      assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
442      DysymtabLoadCmd = Load.Ptr;
443    } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
444      assert(!DataInCodeLoadCmd && "Multiple data in code tables");
445      DataInCodeLoadCmd = Load.Ptr;
446    } else if (Load.C.cmd == SegmentLoadType) {
447      uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
448      for (unsigned J = 0; J < NumSections; ++J) {
449        const char *Sec = getSectionPtr(this, Load, J);
450        Sections.push_back(Sec);
451      }
452    } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
453               Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
454               Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
455               Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
456               Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
457      Libraries.push_back(Load.Ptr);
458    }
459
460    if (I == LoadCommandCount - 1)
461      break;
462    else
463      Load = getNextLoadCommandInfo(Load);
464  }
465}
466
467void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
468  unsigned SymbolTableEntrySize = is64Bit() ?
469    sizeof(MachO::nlist_64) :
470    sizeof(MachO::nlist);
471  Symb.p += SymbolTableEntrySize;
472}
473
474std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
475                                               StringRef &Res) const {
476  StringRef StringTable = getStringTableData();
477  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
478  const char *Start = &StringTable.data()[Entry.n_strx];
479  Res = StringRef(Start);
480  return object_error::success;
481}
482
483// getIndirectName() returns the name of the alias'ed symbol who's string table
484// index is in the n_value field.
485std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
486                                                 StringRef &Res) const {
487  StringRef StringTable = getStringTableData();
488  uint64_t NValue;
489  if (is64Bit()) {
490    MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
491    NValue = Entry.n_value;
492    if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
493      return object_error::parse_failed;
494  } else {
495    MachO::nlist Entry = getSymbolTableEntry(Symb);
496    NValue = Entry.n_value;
497    if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
498      return object_error::parse_failed;
499  }
500  if (NValue >= StringTable.size())
501    return object_error::parse_failed;
502  const char *Start = &StringTable.data()[NValue];
503  Res = StringRef(Start);
504  return object_error::success;
505}
506
507std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
508                                                  uint64_t &Res) const {
509  if (is64Bit()) {
510    MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
511    if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
512        Entry.n_value == 0)
513      Res = UnknownAddressOrSize;
514    else
515      Res = Entry.n_value;
516  } else {
517    MachO::nlist Entry = getSymbolTableEntry(Symb);
518    if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
519        Entry.n_value == 0)
520      Res = UnknownAddressOrSize;
521    else
522      Res = Entry.n_value;
523  }
524  return object_error::success;
525}
526
527std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
528                                                    uint32_t &Result) const {
529  uint32_t flags = getSymbolFlags(DRI);
530  if (flags & SymbolRef::SF_Common) {
531    nlist_base Entry = getSymbolTableEntryBase(this, DRI);
532    Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
533  } else {
534    Result = 0;
535  }
536  return object_error::success;
537}
538
539std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
540                                               uint64_t &Result) const {
541  uint64_t BeginOffset;
542  uint64_t EndOffset = 0;
543  uint8_t SectionIndex;
544
545  nlist_base Entry = getSymbolTableEntryBase(this, DRI);
546  uint64_t Value;
547  getSymbolAddress(DRI, Value);
548  if (Value == UnknownAddressOrSize) {
549    Result = UnknownAddressOrSize;
550    return object_error::success;
551  }
552
553  BeginOffset = Value;
554
555  SectionIndex = Entry.n_sect;
556  if (!SectionIndex) {
557    uint32_t flags = getSymbolFlags(DRI);
558    if (flags & SymbolRef::SF_Common)
559      Result = Value;
560    else
561      Result = UnknownAddressOrSize;
562    return object_error::success;
563  }
564  // Unfortunately symbols are unsorted so we need to touch all
565  // symbols from load command
566  for (const SymbolRef &Symbol : symbols()) {
567    DataRefImpl DRI = Symbol.getRawDataRefImpl();
568    Entry = getSymbolTableEntryBase(this, DRI);
569    getSymbolAddress(DRI, Value);
570    if (Value == UnknownAddressOrSize)
571      continue;
572    if (Entry.n_sect == SectionIndex && Value > BeginOffset)
573      if (!EndOffset || Value < EndOffset)
574        EndOffset = Value;
575  }
576  if (!EndOffset) {
577    uint64_t Size;
578    DataRefImpl Sec;
579    Sec.d.a = SectionIndex-1;
580    getSectionSize(Sec, Size);
581    getSectionAddress(Sec, EndOffset);
582    EndOffset += Size;
583  }
584  Result = EndOffset - BeginOffset;
585  return object_error::success;
586}
587
588std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
589                                               SymbolRef::Type &Res) const {
590  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
591  uint8_t n_type = Entry.n_type;
592
593  Res = SymbolRef::ST_Other;
594
595  // If this is a STAB debugging symbol, we can do nothing more.
596  if (n_type & MachO::N_STAB) {
597    Res = SymbolRef::ST_Debug;
598    return object_error::success;
599  }
600
601  switch (n_type & MachO::N_TYPE) {
602    case MachO::N_UNDF :
603      Res = SymbolRef::ST_Unknown;
604      break;
605    case MachO::N_SECT :
606      Res = SymbolRef::ST_Function;
607      break;
608  }
609  return object_error::success;
610}
611
612uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
613  nlist_base Entry = getSymbolTableEntryBase(this, DRI);
614
615  uint8_t MachOType = Entry.n_type;
616  uint16_t MachOFlags = Entry.n_desc;
617
618  uint32_t Result = SymbolRef::SF_None;
619
620  if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
621    Result |= SymbolRef::SF_Undefined;
622
623  if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
624    Result |= SymbolRef::SF_Indirect;
625
626  if (MachOType & MachO::N_STAB)
627    Result |= SymbolRef::SF_FormatSpecific;
628
629  if (MachOType & MachO::N_EXT) {
630    Result |= SymbolRef::SF_Global;
631    if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
632      uint64_t Value;
633      getSymbolAddress(DRI, Value);
634      if (Value && Value != UnknownAddressOrSize)
635        Result |= SymbolRef::SF_Common;
636    }
637  }
638
639  if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
640    Result |= SymbolRef::SF_Weak;
641
642  if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
643    Result |= SymbolRef::SF_Absolute;
644
645  return Result;
646}
647
648std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
649                                                  section_iterator &Res) const {
650  nlist_base Entry = getSymbolTableEntryBase(this, Symb);
651  uint8_t index = Entry.n_sect;
652
653  if (index == 0) {
654    Res = section_end();
655  } else {
656    DataRefImpl DRI;
657    DRI.d.a = index - 1;
658    Res = section_iterator(SectionRef(DRI, this));
659  }
660
661  return object_error::success;
662}
663
664void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
665  Sec.d.a++;
666}
667
668std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
669                                                StringRef &Result) const {
670  ArrayRef<char> Raw = getSectionRawName(Sec);
671  Result = parseSegmentOrSectionName(Raw.data());
672  return object_error::success;
673}
674
675std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
676                                                   uint64_t &Res) const {
677  if (is64Bit()) {
678    MachO::section_64 Sect = getSection64(Sec);
679    Res = Sect.addr;
680  } else {
681    MachO::section Sect = getSection(Sec);
682    Res = Sect.addr;
683  }
684  return object_error::success;
685}
686
687std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
688                                                uint64_t &Res) const {
689  if (is64Bit()) {
690    MachO::section_64 Sect = getSection64(Sec);
691    Res = Sect.size;
692  } else {
693    MachO::section Sect = getSection(Sec);
694    Res = Sect.size;
695  }
696
697  return object_error::success;
698}
699
700std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
701                                                    StringRef &Res) const {
702  uint32_t Offset;
703  uint64_t Size;
704
705  if (is64Bit()) {
706    MachO::section_64 Sect = getSection64(Sec);
707    Offset = Sect.offset;
708    Size = Sect.size;
709  } else {
710    MachO::section Sect = getSection(Sec);
711    Offset = Sect.offset;
712    Size = Sect.size;
713  }
714
715  Res = this->getData().substr(Offset, Size);
716  return object_error::success;
717}
718
719std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
720                                                     uint64_t &Res) const {
721  uint32_t Align;
722  if (is64Bit()) {
723    MachO::section_64 Sect = getSection64(Sec);
724    Align = Sect.align;
725  } else {
726    MachO::section Sect = getSection(Sec);
727    Align = Sect.align;
728  }
729
730  Res = uint64_t(1) << Align;
731  return object_error::success;
732}
733
734std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
735                                               bool &Res) const {
736  uint32_t Flags = getSectionFlags(this, Sec);
737  Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
738  return object_error::success;
739}
740
741std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
742                                               bool &Result) const {
743  uint32_t Flags = getSectionFlags(this, Sec);
744  unsigned SectionType = Flags & MachO::SECTION_TYPE;
745  Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
746           !(SectionType == MachO::S_ZEROFILL ||
747             SectionType == MachO::S_GB_ZEROFILL);
748  return object_error::success;
749}
750
751std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
752                                              bool &Result) const {
753  uint32_t Flags = getSectionFlags(this, Sec);
754  unsigned SectionType = Flags & MachO::SECTION_TYPE;
755  Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
756           (SectionType == MachO::S_ZEROFILL ||
757            SectionType == MachO::S_GB_ZEROFILL);
758  return object_error::success;
759}
760
761std::error_code
762MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
763                                               bool &Result) const {
764  // FIXME: Unimplemented.
765  Result = true;
766  return object_error::success;
767}
768
769std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
770                                                  bool &Result) const {
771  // FIXME: Unimplemented.
772  Result = false;
773  return object_error::success;
774}
775
776std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
777                                                   bool &Res) const {
778  uint32_t Flags = getSectionFlags(this, Sec);
779  unsigned SectionType = Flags & MachO::SECTION_TYPE;
780  Res = SectionType == MachO::S_ZEROFILL ||
781    SectionType == MachO::S_GB_ZEROFILL;
782  return object_error::success;
783}
784
785std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
786                                                       bool &Result) const {
787  // Consider using the code from isSectionText to look for __const sections.
788  // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
789  // to use section attributes to distinguish code from data.
790
791  // FIXME: Unimplemented.
792  Result = false;
793  return object_error::success;
794}
795
796std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
797                                                       DataRefImpl Symb,
798                                                       bool &Result) const {
799  SymbolRef::Type ST;
800  this->getSymbolType(Symb, ST);
801  if (ST == SymbolRef::ST_Unknown) {
802    Result = false;
803    return object_error::success;
804  }
805
806  uint64_t SectBegin, SectEnd;
807  getSectionAddress(Sec, SectBegin);
808  getSectionSize(Sec, SectEnd);
809  SectEnd += SectBegin;
810
811  uint64_t SymAddr;
812  getSymbolAddress(Symb, SymAddr);
813  Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
814
815  return object_error::success;
816}
817
818relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
819  DataRefImpl Ret;
820  Ret.d.a = Sec.d.a;
821  Ret.d.b = 0;
822  return relocation_iterator(RelocationRef(Ret, this));
823}
824
825relocation_iterator
826MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
827  uint32_t Num;
828  if (is64Bit()) {
829    MachO::section_64 Sect = getSection64(Sec);
830    Num = Sect.nreloc;
831  } else {
832    MachO::section Sect = getSection(Sec);
833    Num = Sect.nreloc;
834  }
835
836  DataRefImpl Ret;
837  Ret.d.a = Sec.d.a;
838  Ret.d.b = Num;
839  return relocation_iterator(RelocationRef(Ret, this));
840}
841
842void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
843  ++Rel.d.b;
844}
845
846std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
847                                                      uint64_t &Res) const {
848  uint64_t Offset;
849  getRelocationOffset(Rel, Offset);
850
851  DataRefImpl Sec;
852  Sec.d.a = Rel.d.a;
853  uint64_t SecAddress;
854  getSectionAddress(Sec, SecAddress);
855  Res = SecAddress + Offset;
856  return object_error::success;
857}
858
859std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
860                                                     uint64_t &Res) const {
861  assert(getHeader().filetype == MachO::MH_OBJECT &&
862         "Only implemented for MH_OBJECT");
863  MachO::any_relocation_info RE = getRelocation(Rel);
864  Res = getAnyRelocationAddress(RE);
865  return object_error::success;
866}
867
868symbol_iterator
869MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
870  MachO::any_relocation_info RE = getRelocation(Rel);
871  if (isRelocationScattered(RE))
872    return symbol_end();
873
874  uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
875  bool isExtern = getPlainRelocationExternal(RE);
876  if (!isExtern)
877    return symbol_end();
878
879  MachO::symtab_command S = getSymtabLoadCommand();
880  unsigned SymbolTableEntrySize = is64Bit() ?
881    sizeof(MachO::nlist_64) :
882    sizeof(MachO::nlist);
883  uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
884  DataRefImpl Sym;
885  Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
886  return symbol_iterator(SymbolRef(Sym, this));
887}
888
889std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
890                                                   uint64_t &Res) const {
891  MachO::any_relocation_info RE = getRelocation(Rel);
892  Res = getAnyRelocationType(RE);
893  return object_error::success;
894}
895
896std::error_code
897MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
898                                       SmallVectorImpl<char> &Result) const {
899  StringRef res;
900  uint64_t RType;
901  getRelocationType(Rel, RType);
902
903  unsigned Arch = this->getArch();
904
905  switch (Arch) {
906    case Triple::x86: {
907      static const char *const Table[] =  {
908        "GENERIC_RELOC_VANILLA",
909        "GENERIC_RELOC_PAIR",
910        "GENERIC_RELOC_SECTDIFF",
911        "GENERIC_RELOC_PB_LA_PTR",
912        "GENERIC_RELOC_LOCAL_SECTDIFF",
913        "GENERIC_RELOC_TLV" };
914
915      if (RType > 5)
916        res = "Unknown";
917      else
918        res = Table[RType];
919      break;
920    }
921    case Triple::x86_64: {
922      static const char *const Table[] =  {
923        "X86_64_RELOC_UNSIGNED",
924        "X86_64_RELOC_SIGNED",
925        "X86_64_RELOC_BRANCH",
926        "X86_64_RELOC_GOT_LOAD",
927        "X86_64_RELOC_GOT",
928        "X86_64_RELOC_SUBTRACTOR",
929        "X86_64_RELOC_SIGNED_1",
930        "X86_64_RELOC_SIGNED_2",
931        "X86_64_RELOC_SIGNED_4",
932        "X86_64_RELOC_TLV" };
933
934      if (RType > 9)
935        res = "Unknown";
936      else
937        res = Table[RType];
938      break;
939    }
940    case Triple::arm: {
941      static const char *const Table[] =  {
942        "ARM_RELOC_VANILLA",
943        "ARM_RELOC_PAIR",
944        "ARM_RELOC_SECTDIFF",
945        "ARM_RELOC_LOCAL_SECTDIFF",
946        "ARM_RELOC_PB_LA_PTR",
947        "ARM_RELOC_BR24",
948        "ARM_THUMB_RELOC_BR22",
949        "ARM_THUMB_32BIT_BRANCH",
950        "ARM_RELOC_HALF",
951        "ARM_RELOC_HALF_SECTDIFF" };
952
953      if (RType > 9)
954        res = "Unknown";
955      else
956        res = Table[RType];
957      break;
958    }
959    case Triple::arm64:
960    case Triple::aarch64: {
961      static const char *const Table[] = {
962        "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
963        "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
964        "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
965        "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
966        "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
967        "ARM64_RELOC_ADDEND"
968      };
969
970      if (RType >= array_lengthof(Table))
971        res = "Unknown";
972      else
973        res = Table[RType];
974      break;
975    }
976    case Triple::ppc: {
977      static const char *const Table[] =  {
978        "PPC_RELOC_VANILLA",
979        "PPC_RELOC_PAIR",
980        "PPC_RELOC_BR14",
981        "PPC_RELOC_BR24",
982        "PPC_RELOC_HI16",
983        "PPC_RELOC_LO16",
984        "PPC_RELOC_HA16",
985        "PPC_RELOC_LO14",
986        "PPC_RELOC_SECTDIFF",
987        "PPC_RELOC_PB_LA_PTR",
988        "PPC_RELOC_HI16_SECTDIFF",
989        "PPC_RELOC_LO16_SECTDIFF",
990        "PPC_RELOC_HA16_SECTDIFF",
991        "PPC_RELOC_JBSR",
992        "PPC_RELOC_LO14_SECTDIFF",
993        "PPC_RELOC_LOCAL_SECTDIFF" };
994
995      if (RType > 15)
996        res = "Unknown";
997      else
998        res = Table[RType];
999      break;
1000    }
1001    case Triple::UnknownArch:
1002      res = "Unknown";
1003      break;
1004  }
1005  Result.append(res.begin(), res.end());
1006  return object_error::success;
1007}
1008
1009std::error_code
1010MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
1011                                          SmallVectorImpl<char> &Result) const {
1012  MachO::any_relocation_info RE = getRelocation(Rel);
1013
1014  unsigned Arch = this->getArch();
1015
1016  std::string fmtbuf;
1017  raw_string_ostream fmt(fmtbuf);
1018  unsigned Type = this->getAnyRelocationType(RE);
1019  bool IsPCRel = this->getAnyRelocationPCRel(RE);
1020
1021  // Determine any addends that should be displayed with the relocation.
1022  // These require decoding the relocation type, which is triple-specific.
1023
1024  // X86_64 has entirely custom relocation types.
1025  if (Arch == Triple::x86_64) {
1026    bool isPCRel = getAnyRelocationPCRel(RE);
1027
1028    switch (Type) {
1029      case MachO::X86_64_RELOC_GOT_LOAD:
1030      case MachO::X86_64_RELOC_GOT: {
1031        printRelocationTargetName(this, RE, fmt);
1032        fmt << "@GOT";
1033        if (isPCRel) fmt << "PCREL";
1034        break;
1035      }
1036      case MachO::X86_64_RELOC_SUBTRACTOR: {
1037        DataRefImpl RelNext = Rel;
1038        moveRelocationNext(RelNext);
1039        MachO::any_relocation_info RENext = getRelocation(RelNext);
1040
1041        // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
1042        // X86_64_RELOC_UNSIGNED.
1043        // NOTE: Scattered relocations don't exist on x86_64.
1044        unsigned RType = getAnyRelocationType(RENext);
1045        if (RType != MachO::X86_64_RELOC_UNSIGNED)
1046          report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1047                             "X86_64_RELOC_SUBTRACTOR.");
1048
1049        // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
1050        // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
1051        printRelocationTargetName(this, RENext, fmt);
1052        fmt << "-";
1053        printRelocationTargetName(this, RE, fmt);
1054        break;
1055      }
1056      case MachO::X86_64_RELOC_TLV:
1057        printRelocationTargetName(this, RE, fmt);
1058        fmt << "@TLV";
1059        if (isPCRel) fmt << "P";
1060        break;
1061      case MachO::X86_64_RELOC_SIGNED_1:
1062        printRelocationTargetName(this, RE, fmt);
1063        fmt << "-1";
1064        break;
1065      case MachO::X86_64_RELOC_SIGNED_2:
1066        printRelocationTargetName(this, RE, fmt);
1067        fmt << "-2";
1068        break;
1069      case MachO::X86_64_RELOC_SIGNED_4:
1070        printRelocationTargetName(this, RE, fmt);
1071        fmt << "-4";
1072        break;
1073      default:
1074        printRelocationTargetName(this, RE, fmt);
1075        break;
1076    }
1077  // X86 and ARM share some relocation types in common.
1078  } else if (Arch == Triple::x86 || Arch == Triple::arm ||
1079             Arch == Triple::ppc) {
1080    // Generic relocation types...
1081    switch (Type) {
1082      case MachO::GENERIC_RELOC_PAIR: // prints no info
1083        return object_error::success;
1084      case MachO::GENERIC_RELOC_SECTDIFF: {
1085        DataRefImpl RelNext = Rel;
1086        moveRelocationNext(RelNext);
1087        MachO::any_relocation_info RENext = getRelocation(RelNext);
1088
1089        // X86 sect diff's must be followed by a relocation of type
1090        // GENERIC_RELOC_PAIR.
1091        unsigned RType = getAnyRelocationType(RENext);
1092
1093        if (RType != MachO::GENERIC_RELOC_PAIR)
1094          report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1095                             "GENERIC_RELOC_SECTDIFF.");
1096
1097        printRelocationTargetName(this, RE, fmt);
1098        fmt << "-";
1099        printRelocationTargetName(this, RENext, fmt);
1100        break;
1101      }
1102    }
1103
1104    if (Arch == Triple::x86 || Arch == Triple::ppc) {
1105      switch (Type) {
1106        case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
1107          DataRefImpl RelNext = Rel;
1108          moveRelocationNext(RelNext);
1109          MachO::any_relocation_info RENext = getRelocation(RelNext);
1110
1111          // X86 sect diff's must be followed by a relocation of type
1112          // GENERIC_RELOC_PAIR.
1113          unsigned RType = getAnyRelocationType(RENext);
1114          if (RType != MachO::GENERIC_RELOC_PAIR)
1115            report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1116                               "GENERIC_RELOC_LOCAL_SECTDIFF.");
1117
1118          printRelocationTargetName(this, RE, fmt);
1119          fmt << "-";
1120          printRelocationTargetName(this, RENext, fmt);
1121          break;
1122        }
1123        case MachO::GENERIC_RELOC_TLV: {
1124          printRelocationTargetName(this, RE, fmt);
1125          fmt << "@TLV";
1126          if (IsPCRel) fmt << "P";
1127          break;
1128        }
1129        default:
1130          printRelocationTargetName(this, RE, fmt);
1131      }
1132    } else { // ARM-specific relocations
1133      switch (Type) {
1134        case MachO::ARM_RELOC_HALF:
1135        case MachO::ARM_RELOC_HALF_SECTDIFF: {
1136          // Half relocations steal a bit from the length field to encode
1137          // whether this is an upper16 or a lower16 relocation.
1138          bool isUpper = getAnyRelocationLength(RE) >> 1;
1139
1140          if (isUpper)
1141            fmt << ":upper16:(";
1142          else
1143            fmt << ":lower16:(";
1144          printRelocationTargetName(this, RE, fmt);
1145
1146          DataRefImpl RelNext = Rel;
1147          moveRelocationNext(RelNext);
1148          MachO::any_relocation_info RENext = getRelocation(RelNext);
1149
1150          // ARM half relocs must be followed by a relocation of type
1151          // ARM_RELOC_PAIR.
1152          unsigned RType = getAnyRelocationType(RENext);
1153          if (RType != MachO::ARM_RELOC_PAIR)
1154            report_fatal_error("Expected ARM_RELOC_PAIR after "
1155                               "ARM_RELOC_HALF");
1156
1157          // NOTE: The half of the target virtual address is stashed in the
1158          // address field of the secondary relocation, but we can't reverse
1159          // engineer the constant offset from it without decoding the movw/movt
1160          // instruction to find the other half in its immediate field.
1161
1162          // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1163          // symbol/section pointer of the follow-on relocation.
1164          if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1165            fmt << "-";
1166            printRelocationTargetName(this, RENext, fmt);
1167          }
1168
1169          fmt << ")";
1170          break;
1171        }
1172        default: {
1173          printRelocationTargetName(this, RE, fmt);
1174        }
1175      }
1176    }
1177  } else
1178    printRelocationTargetName(this, RE, fmt);
1179
1180  fmt.flush();
1181  Result.append(fmtbuf.begin(), fmtbuf.end());
1182  return object_error::success;
1183}
1184
1185std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
1186                                                     bool &Result) const {
1187  unsigned Arch = getArch();
1188  uint64_t Type;
1189  getRelocationType(Rel, Type);
1190
1191  Result = false;
1192
1193  // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1194  // is always hidden.
1195  if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
1196    if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
1197  } else if (Arch == Triple::x86_64) {
1198    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1199    // an X86_64_RELOC_SUBTRACTOR.
1200    if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1201      DataRefImpl RelPrev = Rel;
1202      RelPrev.d.a--;
1203      uint64_t PrevType;
1204      getRelocationType(RelPrev, PrevType);
1205      if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1206        Result = true;
1207    }
1208  }
1209
1210  return object_error::success;
1211}
1212
1213std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1214                                                LibraryRef &Res) const {
1215  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1216}
1217
1218std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1219                                                StringRef &Res) const {
1220  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1221}
1222
1223//
1224// guessLibraryShortName() is passed a name of a dynamic library and returns a
1225// guess on what the short name is.  Then name is returned as a substring of the
1226// StringRef Name passed in.  The name of the dynamic library is recognized as
1227// a framework if it has one of the two following forms:
1228//      Foo.framework/Versions/A/Foo
1229//      Foo.framework/Foo
1230// Where A and Foo can be any string.  And may contain a trailing suffix
1231// starting with an underbar.  If the Name is recognized as a framework then
1232// isFramework is set to true else it is set to false.  If the Name has a
1233// suffix then Suffix is set to the substring in Name that contains the suffix
1234// else it is set to a NULL StringRef.
1235//
1236// The Name of the dynamic library is recognized as a library name if it has
1237// one of the two following forms:
1238//      libFoo.A.dylib
1239//      libFoo.dylib
1240// The library may have a suffix trailing the name Foo of the form:
1241//      libFoo_profile.A.dylib
1242//      libFoo_profile.dylib
1243//
1244// The Name of the dynamic library is also recognized as a library name if it
1245// has the following form:
1246//      Foo.qtx
1247//
1248// If the Name of the dynamic library is none of the forms above then a NULL
1249// StringRef is returned.
1250//
1251StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1252                                                 bool &isFramework,
1253                                                 StringRef &Suffix) {
1254  StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1255  size_t a, b, c, d, Idx;
1256
1257  isFramework = false;
1258  Suffix = StringRef();
1259
1260  // Pull off the last component and make Foo point to it
1261  a = Name.rfind('/');
1262  if (a == Name.npos || a == 0)
1263    goto guess_library;
1264  Foo = Name.slice(a+1, Name.npos);
1265
1266  // Look for a suffix starting with a '_'
1267  Idx = Foo.rfind('_');
1268  if (Idx != Foo.npos && Foo.size() >= 2) {
1269    Suffix = Foo.slice(Idx, Foo.npos);
1270    Foo = Foo.slice(0, Idx);
1271  }
1272
1273  // First look for the form Foo.framework/Foo
1274  b = Name.rfind('/', a);
1275  if (b == Name.npos)
1276    Idx = 0;
1277  else
1278    Idx = b+1;
1279  F = Name.slice(Idx, Idx + Foo.size());
1280  DotFramework = Name.slice(Idx + Foo.size(),
1281                            Idx + Foo.size() + sizeof(".framework/")-1);
1282  if (F == Foo && DotFramework == ".framework/") {
1283    isFramework = true;
1284    return Foo;
1285  }
1286
1287  // Next look for the form Foo.framework/Versions/A/Foo
1288  if (b == Name.npos)
1289    goto guess_library;
1290  c =  Name.rfind('/', b);
1291  if (c == Name.npos || c == 0)
1292    goto guess_library;
1293  V = Name.slice(c+1, Name.npos);
1294  if (!V.startswith("Versions/"))
1295    goto guess_library;
1296  d =  Name.rfind('/', c);
1297  if (d == Name.npos)
1298    Idx = 0;
1299  else
1300    Idx = d+1;
1301  F = Name.slice(Idx, Idx + Foo.size());
1302  DotFramework = Name.slice(Idx + Foo.size(),
1303                            Idx + Foo.size() + sizeof(".framework/")-1);
1304  if (F == Foo && DotFramework == ".framework/") {
1305    isFramework = true;
1306    return Foo;
1307  }
1308
1309guess_library:
1310  // pull off the suffix after the "." and make a point to it
1311  a = Name.rfind('.');
1312  if (a == Name.npos || a == 0)
1313    return StringRef();
1314  Dylib = Name.slice(a, Name.npos);
1315  if (Dylib != ".dylib")
1316    goto guess_qtx;
1317
1318  // First pull off the version letter for the form Foo.A.dylib if any.
1319  if (a >= 3) {
1320    Dot = Name.slice(a-2, a-1);
1321    if (Dot == ".")
1322      a = a - 2;
1323  }
1324
1325  b = Name.rfind('/', a);
1326  if (b == Name.npos)
1327    b = 0;
1328  else
1329    b = b+1;
1330  // ignore any suffix after an underbar like Foo_profile.A.dylib
1331  Idx = Name.find('_', b);
1332  if (Idx != Name.npos && Idx != b) {
1333    Lib = Name.slice(b, Idx);
1334    Suffix = Name.slice(Idx, a);
1335  }
1336  else
1337    Lib = Name.slice(b, a);
1338  // There are incorrect library names of the form:
1339  // libATS.A_profile.dylib so check for these.
1340  if (Lib.size() >= 3) {
1341    Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1342    if (Dot == ".")
1343      Lib = Lib.slice(0, Lib.size()-2);
1344  }
1345  return Lib;
1346
1347guess_qtx:
1348  Qtx = Name.slice(a, Name.npos);
1349  if (Qtx != ".qtx")
1350    return StringRef();
1351  b = Name.rfind('/', a);
1352  if (b == Name.npos)
1353    Lib = Name.slice(0, a);
1354  else
1355    Lib = Name.slice(b+1, a);
1356  // There are library names of the form: QT.A.qtx so check for these.
1357  if (Lib.size() >= 3) {
1358    Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1359    if (Dot == ".")
1360      Lib = Lib.slice(0, Lib.size()-2);
1361  }
1362  return Lib;
1363}
1364
1365// getLibraryShortNameByIndex() is used to get the short name of the library
1366// for an undefined symbol in a linked Mach-O binary that was linked with the
1367// normal two-level namespace default (that is MH_TWOLEVEL in the header).
1368// It is passed the index (0 - based) of the library as translated from
1369// GET_LIBRARY_ORDINAL (1 - based).
1370std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1371                                                            StringRef &Res) {
1372  if (Index >= Libraries.size())
1373    return object_error::parse_failed;
1374
1375  MachO::dylib_command D =
1376    getStruct<MachO::dylib_command>(this, Libraries[Index]);
1377  if (D.dylib.name >= D.cmdsize)
1378    return object_error::parse_failed;
1379
1380  // If the cache of LibrariesShortNames is not built up do that first for
1381  // all the Libraries.
1382  if (LibrariesShortNames.size() == 0) {
1383    for (unsigned i = 0; i < Libraries.size(); i++) {
1384      MachO::dylib_command D =
1385        getStruct<MachO::dylib_command>(this, Libraries[i]);
1386      if (D.dylib.name >= D.cmdsize) {
1387        LibrariesShortNames.push_back(StringRef());
1388        continue;
1389      }
1390      const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1391      StringRef Name = StringRef(P);
1392      StringRef Suffix;
1393      bool isFramework;
1394      StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1395      if (shortName == StringRef())
1396        LibrariesShortNames.push_back(Name);
1397      else
1398        LibrariesShortNames.push_back(shortName);
1399    }
1400  }
1401
1402  Res = LibrariesShortNames[Index];
1403  return object_error::success;
1404}
1405
1406basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1407  return getSymbolByIndex(0);
1408}
1409
1410basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1411  DataRefImpl DRI;
1412  if (!SymtabLoadCmd)
1413    return basic_symbol_iterator(SymbolRef(DRI, this));
1414
1415  MachO::symtab_command Symtab = getSymtabLoadCommand();
1416  unsigned SymbolTableEntrySize = is64Bit() ?
1417    sizeof(MachO::nlist_64) :
1418    sizeof(MachO::nlist);
1419  unsigned Offset = Symtab.symoff +
1420    Symtab.nsyms * SymbolTableEntrySize;
1421  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1422  return basic_symbol_iterator(SymbolRef(DRI, this));
1423}
1424
1425basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1426  DataRefImpl DRI;
1427  if (!SymtabLoadCmd)
1428    return basic_symbol_iterator(SymbolRef(DRI, this));
1429
1430  MachO::symtab_command Symtab = getSymtabLoadCommand();
1431  assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1432  unsigned SymbolTableEntrySize =
1433    is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1434  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1435  DRI.p += Index * SymbolTableEntrySize;
1436  return basic_symbol_iterator(SymbolRef(DRI, this));
1437}
1438
1439section_iterator MachOObjectFile::section_begin() const {
1440  DataRefImpl DRI;
1441  return section_iterator(SectionRef(DRI, this));
1442}
1443
1444section_iterator MachOObjectFile::section_end() const {
1445  DataRefImpl DRI;
1446  DRI.d.a = Sections.size();
1447  return section_iterator(SectionRef(DRI, this));
1448}
1449
1450library_iterator MachOObjectFile::needed_library_begin() const {
1451  // TODO: implement
1452  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1453}
1454
1455library_iterator MachOObjectFile::needed_library_end() const {
1456  // TODO: implement
1457  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1458}
1459
1460uint8_t MachOObjectFile::getBytesInAddress() const {
1461  return is64Bit() ? 8 : 4;
1462}
1463
1464StringRef MachOObjectFile::getFileFormatName() const {
1465  unsigned CPUType = getCPUType(this);
1466  if (!is64Bit()) {
1467    switch (CPUType) {
1468    case llvm::MachO::CPU_TYPE_I386:
1469      return "Mach-O 32-bit i386";
1470    case llvm::MachO::CPU_TYPE_ARM:
1471      return "Mach-O arm";
1472    case llvm::MachO::CPU_TYPE_POWERPC:
1473      return "Mach-O 32-bit ppc";
1474    default:
1475      assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1476             "64-bit object file when we're not 64-bit?");
1477      return "Mach-O 32-bit unknown";
1478    }
1479  }
1480
1481  // Make sure the cpu type has the correct mask.
1482  assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1483         == llvm::MachO::CPU_ARCH_ABI64 &&
1484         "32-bit object file when we're 64-bit?");
1485
1486  switch (CPUType) {
1487  case llvm::MachO::CPU_TYPE_X86_64:
1488    return "Mach-O 64-bit x86-64";
1489  case llvm::MachO::CPU_TYPE_ARM64:
1490    return "Mach-O arm64";
1491  case llvm::MachO::CPU_TYPE_POWERPC64:
1492    return "Mach-O 64-bit ppc64";
1493  default:
1494    return "Mach-O 64-bit unknown";
1495  }
1496}
1497
1498Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1499  switch (CPUType) {
1500  case llvm::MachO::CPU_TYPE_I386:
1501    return Triple::x86;
1502  case llvm::MachO::CPU_TYPE_X86_64:
1503    return Triple::x86_64;
1504  case llvm::MachO::CPU_TYPE_ARM:
1505    return Triple::arm;
1506  case llvm::MachO::CPU_TYPE_ARM64:
1507    return Triple::arm64;
1508  case llvm::MachO::CPU_TYPE_POWERPC:
1509    return Triple::ppc;
1510  case llvm::MachO::CPU_TYPE_POWERPC64:
1511    return Triple::ppc64;
1512  default:
1513    return Triple::UnknownArch;
1514  }
1515}
1516
1517Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
1518  switch (CPUType) {
1519  case MachO::CPU_TYPE_I386:
1520    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1521    case MachO::CPU_SUBTYPE_I386_ALL:
1522      return Triple("i386-apple-darwin");
1523    default:
1524      return Triple();
1525    }
1526  case MachO::CPU_TYPE_X86_64:
1527    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1528    case MachO::CPU_SUBTYPE_X86_64_ALL:
1529      return Triple("x86_64-apple-darwin");
1530    case MachO::CPU_SUBTYPE_X86_64_H:
1531      return Triple("x86_64h-apple-darwin");
1532    default:
1533      return Triple();
1534    }
1535  case MachO::CPU_TYPE_ARM:
1536    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1537    case MachO::CPU_SUBTYPE_ARM_V4T:
1538      return Triple("armv4t-apple-darwin");
1539    case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1540      return Triple("armv5e-apple-darwin");
1541    case MachO::CPU_SUBTYPE_ARM_V6:
1542      return Triple("armv6-apple-darwin");
1543    case MachO::CPU_SUBTYPE_ARM_V6M:
1544      return Triple("armv6m-apple-darwin");
1545    case MachO::CPU_SUBTYPE_ARM_V7EM:
1546      return Triple("armv7em-apple-darwin");
1547    case MachO::CPU_SUBTYPE_ARM_V7K:
1548      return Triple("armv7k-apple-darwin");
1549    case MachO::CPU_SUBTYPE_ARM_V7M:
1550      return Triple("armv7m-apple-darwin");
1551    case MachO::CPU_SUBTYPE_ARM_V7S:
1552      return Triple("armv7s-apple-darwin");
1553    default:
1554      return Triple();
1555    }
1556  case MachO::CPU_TYPE_ARM64:
1557    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1558    case MachO::CPU_SUBTYPE_ARM64_ALL:
1559      return Triple("arm64-apple-darwin");
1560    default:
1561      return Triple();
1562    }
1563  case MachO::CPU_TYPE_POWERPC:
1564    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1565    case MachO::CPU_SUBTYPE_POWERPC_ALL:
1566      return Triple("ppc-apple-darwin");
1567    default:
1568      return Triple();
1569    }
1570  case MachO::CPU_TYPE_POWERPC64:
1571    switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1572    case MachO::CPU_SUBTYPE_POWERPC_ALL:
1573      return Triple("ppc64-apple-darwin");
1574    default:
1575      return Triple();
1576    }
1577  default:
1578    return Triple();
1579  }
1580}
1581
1582Triple MachOObjectFile::getHostArch() {
1583  return Triple(sys::getDefaultTargetTriple());
1584}
1585
1586Triple MachOObjectFile::getArch(StringRef ArchFlag) {
1587  if (ArchFlag == "i386")
1588    return Triple("i386-apple-darwin");
1589  else if (ArchFlag == "x86_64")
1590    return Triple("x86_64-apple-darwin");
1591  else if (ArchFlag == "x86_64h")
1592    return Triple("x86_64h-apple-darwin");
1593  else if (ArchFlag == "armv4t" || ArchFlag == "arm")
1594    return Triple("armv4t-apple-darwin");
1595  else if (ArchFlag == "armv5e")
1596    return Triple("armv5e-apple-darwin");
1597  else if (ArchFlag == "armv6")
1598    return Triple("armv6-apple-darwin");
1599  else if (ArchFlag == "armv6m")
1600    return Triple("armv6m-apple-darwin");
1601  else if (ArchFlag == "armv7em")
1602    return Triple("armv7em-apple-darwin");
1603  else if (ArchFlag == "armv7k")
1604    return Triple("armv7k-apple-darwin");
1605  else if (ArchFlag == "armv7k")
1606    return Triple("armv7m-apple-darwin");
1607  else if (ArchFlag == "armv7s")
1608    return Triple("armv7s-apple-darwin");
1609  else if (ArchFlag == "arm64")
1610    return Triple("arm64-apple-darwin");
1611  else if (ArchFlag == "ppc")
1612    return Triple("ppc-apple-darwin");
1613  else if (ArchFlag == "ppc64")
1614    return Triple("ppc64-apple-darwin");
1615  else
1616    return Triple();
1617}
1618
1619unsigned MachOObjectFile::getArch() const {
1620  return getArch(getCPUType(this));
1621}
1622
1623StringRef MachOObjectFile::getLoadName() const {
1624  // TODO: Implement
1625  report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1626}
1627
1628relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1629  DataRefImpl DRI;
1630  DRI.d.a = Index;
1631  return section_rel_begin(DRI);
1632}
1633
1634relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1635  DataRefImpl DRI;
1636  DRI.d.a = Index;
1637  return section_rel_end(DRI);
1638}
1639
1640dice_iterator MachOObjectFile::begin_dices() const {
1641  DataRefImpl DRI;
1642  if (!DataInCodeLoadCmd)
1643    return dice_iterator(DiceRef(DRI, this));
1644
1645  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1646  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1647  return dice_iterator(DiceRef(DRI, this));
1648}
1649
1650dice_iterator MachOObjectFile::end_dices() const {
1651  DataRefImpl DRI;
1652  if (!DataInCodeLoadCmd)
1653    return dice_iterator(DiceRef(DRI, this));
1654
1655  MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1656  unsigned Offset = DicLC.dataoff + DicLC.datasize;
1657  DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1658  return dice_iterator(DiceRef(DRI, this));
1659}
1660
1661StringRef
1662MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1663  ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1664  return parseSegmentOrSectionName(Raw.data());
1665}
1666
1667ArrayRef<char>
1668MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1669  const section_base *Base =
1670    reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1671  return ArrayRef<char>(Base->sectname);
1672}
1673
1674ArrayRef<char>
1675MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1676  const section_base *Base =
1677    reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1678  return ArrayRef<char>(Base->segname);
1679}
1680
1681bool
1682MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1683  const {
1684  if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1685    return false;
1686  return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1687}
1688
1689unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1690    const MachO::any_relocation_info &RE) const {
1691  if (isLittleEndian())
1692    return RE.r_word1 & 0xffffff;
1693  return RE.r_word1 >> 8;
1694}
1695
1696bool MachOObjectFile::getPlainRelocationExternal(
1697    const MachO::any_relocation_info &RE) const {
1698  if (isLittleEndian())
1699    return (RE.r_word1 >> 27) & 1;
1700  return (RE.r_word1 >> 4) & 1;
1701}
1702
1703bool MachOObjectFile::getScatteredRelocationScattered(
1704    const MachO::any_relocation_info &RE) const {
1705  return RE.r_word0 >> 31;
1706}
1707
1708uint32_t MachOObjectFile::getScatteredRelocationValue(
1709    const MachO::any_relocation_info &RE) const {
1710  return RE.r_word1;
1711}
1712
1713unsigned MachOObjectFile::getAnyRelocationAddress(
1714    const MachO::any_relocation_info &RE) const {
1715  if (isRelocationScattered(RE))
1716    return getScatteredRelocationAddress(RE);
1717  return getPlainRelocationAddress(RE);
1718}
1719
1720unsigned MachOObjectFile::getAnyRelocationPCRel(
1721    const MachO::any_relocation_info &RE) const {
1722  if (isRelocationScattered(RE))
1723    return getScatteredRelocationPCRel(this, RE);
1724  return getPlainRelocationPCRel(this, RE);
1725}
1726
1727unsigned MachOObjectFile::getAnyRelocationLength(
1728    const MachO::any_relocation_info &RE) const {
1729  if (isRelocationScattered(RE))
1730    return getScatteredRelocationLength(RE);
1731  return getPlainRelocationLength(this, RE);
1732}
1733
1734unsigned
1735MachOObjectFile::getAnyRelocationType(
1736                                   const MachO::any_relocation_info &RE) const {
1737  if (isRelocationScattered(RE))
1738    return getScatteredRelocationType(RE);
1739  return getPlainRelocationType(this, RE);
1740}
1741
1742SectionRef
1743MachOObjectFile::getRelocationSection(
1744                                   const MachO::any_relocation_info &RE) const {
1745  if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1746    return *section_end();
1747  unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1748  DataRefImpl DRI;
1749  DRI.d.a = SecNum;
1750  return SectionRef(DRI, this);
1751}
1752
1753MachOObjectFile::LoadCommandInfo
1754MachOObjectFile::getFirstLoadCommandInfo() const {
1755  MachOObjectFile::LoadCommandInfo Load;
1756
1757  unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1758                                    sizeof(MachO::mach_header);
1759  Load.Ptr = getPtr(this, HeaderSize);
1760  Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1761  return Load;
1762}
1763
1764MachOObjectFile::LoadCommandInfo
1765MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1766  MachOObjectFile::LoadCommandInfo Next;
1767  Next.Ptr = L.Ptr + L.C.cmdsize;
1768  Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1769  return Next;
1770}
1771
1772MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1773  return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1774}
1775
1776MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1777  return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1778}
1779
1780MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1781                                           unsigned Index) const {
1782  const char *Sec = getSectionPtr(this, L, Index);
1783  return getStruct<MachO::section>(this, Sec);
1784}
1785
1786MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1787                                                unsigned Index) const {
1788  const char *Sec = getSectionPtr(this, L, Index);
1789  return getStruct<MachO::section_64>(this, Sec);
1790}
1791
1792MachO::nlist
1793MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1794  const char *P = reinterpret_cast<const char *>(DRI.p);
1795  return getStruct<MachO::nlist>(this, P);
1796}
1797
1798MachO::nlist_64
1799MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1800  const char *P = reinterpret_cast<const char *>(DRI.p);
1801  return getStruct<MachO::nlist_64>(this, P);
1802}
1803
1804MachO::linkedit_data_command
1805MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1806  return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1807}
1808
1809MachO::segment_command
1810MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1811  return getStruct<MachO::segment_command>(this, L.Ptr);
1812}
1813
1814MachO::segment_command_64
1815MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1816  return getStruct<MachO::segment_command_64>(this, L.Ptr);
1817}
1818
1819MachO::linker_options_command
1820MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1821  return getStruct<MachO::linker_options_command>(this, L.Ptr);
1822}
1823
1824MachO::version_min_command
1825MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1826  return getStruct<MachO::version_min_command>(this, L.Ptr);
1827}
1828
1829MachO::dylib_command
1830MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1831  return getStruct<MachO::dylib_command>(this, L.Ptr);
1832}
1833
1834
1835MachO::any_relocation_info
1836MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1837  DataRefImpl Sec;
1838  Sec.d.a = Rel.d.a;
1839  uint32_t Offset;
1840  if (is64Bit()) {
1841    MachO::section_64 Sect = getSection64(Sec);
1842    Offset = Sect.reloff;
1843  } else {
1844    MachO::section Sect = getSection(Sec);
1845    Offset = Sect.reloff;
1846  }
1847
1848  auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1849      getPtr(this, Offset)) + Rel.d.b;
1850  return getStruct<MachO::any_relocation_info>(
1851      this, reinterpret_cast<const char *>(P));
1852}
1853
1854MachO::data_in_code_entry
1855MachOObjectFile::getDice(DataRefImpl Rel) const {
1856  const char *P = reinterpret_cast<const char *>(Rel.p);
1857  return getStruct<MachO::data_in_code_entry>(this, P);
1858}
1859
1860MachO::mach_header MachOObjectFile::getHeader() const {
1861  return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1862}
1863
1864MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1865  return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1866}
1867
1868uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1869                                             const MachO::dysymtab_command &DLC,
1870                                             unsigned Index) const {
1871  uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1872  return getStruct<uint32_t>(this, getPtr(this, Offset));
1873}
1874
1875MachO::data_in_code_entry
1876MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1877                                         unsigned Index) const {
1878  uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1879  return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1880}
1881
1882MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1883  return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1884}
1885
1886MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1887  return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1888}
1889
1890MachO::linkedit_data_command
1891MachOObjectFile::getDataInCodeLoadCommand() const {
1892  if (DataInCodeLoadCmd)
1893    return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1894
1895  // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1896  MachO::linkedit_data_command Cmd;
1897  Cmd.cmd = MachO::LC_DATA_IN_CODE;
1898  Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1899  Cmd.dataoff = 0;
1900  Cmd.datasize = 0;
1901  return Cmd;
1902}
1903
1904StringRef MachOObjectFile::getStringTableData() const {
1905  MachO::symtab_command S = getSymtabLoadCommand();
1906  return getData().substr(S.stroff, S.strsize);
1907}
1908
1909bool MachOObjectFile::is64Bit() const {
1910  return getType() == getMachOType(false, true) ||
1911         getType() == getMachOType(true, true);
1912}
1913
1914void MachOObjectFile::ReadULEB128s(uint64_t Index,
1915                                   SmallVectorImpl<uint64_t> &Out) const {
1916  DataExtractor extractor(ObjectFile::getData(), true, 0);
1917
1918  uint32_t offset = Index;
1919  uint64_t data = 0;
1920  while (uint64_t delta = extractor.getULEB128(&offset)) {
1921    data += delta;
1922    Out.push_back(data);
1923  }
1924}
1925
1926const char *MachOObjectFile::getSectionPointer(DataRefImpl Rel) const {
1927  return Sections[Rel.d.a];
1928}
1929
1930ErrorOr<ObjectFile *>
1931ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1932  StringRef Magic = Buffer->getBuffer().slice(0, 4);
1933  std::error_code EC;
1934  std::unique_ptr<MachOObjectFile> Ret;
1935  if (Magic == "\xFE\xED\xFA\xCE")
1936    Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1937  else if (Magic == "\xCE\xFA\xED\xFE")
1938    Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1939  else if (Magic == "\xFE\xED\xFA\xCF")
1940    Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1941  else if (Magic == "\xCF\xFA\xED\xFE")
1942    Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1943  else
1944    return object_error::parse_failed;
1945
1946  if (EC)
1947    return EC;
1948  return Ret.release();
1949}
1950
1951} // end namespace object
1952} // end namespace llvm
1953