Teach ScalarEvolution to sharpen range information.
[oota-llvm.git] / lib / Object / MachOObjectFile.cpp
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/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include <cctype>
28 #include <cstring>
29 #include <limits>
30
31 using namespace llvm;
32 using namespace object;
33
34 namespace {
35   struct section_base {
36     char sectname[16];
37     char segname[16];
38   };
39 }
40
41 template<typename T>
42 static T getStruct(const MachOObjectFile *O, const char *P) {
43   T Cmd;
44   memcpy(&Cmd, P, sizeof(T));
45   if (O->isLittleEndian() != sys::IsLittleEndianHost)
46     MachO::swapStruct(Cmd);
47   return Cmd;
48 }
49
50 static uint32_t
51 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
52                                  const MachOObjectFile::LoadCommandInfo &L) {
53   if (O->is64Bit()) {
54     MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
55     return S.nsects;
56   }
57   MachO::segment_command S = O->getSegmentLoadCommand(L);
58   return S.nsects;
59 }
60
61 static bool isPageZeroSegment(const MachOObjectFile *O,
62                               const MachOObjectFile::LoadCommandInfo &L) {
63   if (O->is64Bit()) {
64     MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
65     return StringRef("__PAGEZERO").equals(S.segname);
66   }
67   MachO::segment_command S = O->getSegmentLoadCommand(L);
68   return StringRef("__PAGEZERO").equals(S.segname);
69 }
70
71
72 static const char *
73 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
74               unsigned Sec) {
75   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
76
77   bool Is64 = O->is64Bit();
78   unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
79                                     sizeof(MachO::segment_command);
80   unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
81                                 sizeof(MachO::section);
82
83   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
84   return reinterpret_cast<const char*>(SectionAddr);
85 }
86
87 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
88   return O->getData().substr(Offset, 1).data();
89 }
90
91 static MachO::nlist_base
92 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
93   const char *P = reinterpret_cast<const char *>(DRI.p);
94   return getStruct<MachO::nlist_base>(O, P);
95 }
96
97 static StringRef parseSegmentOrSectionName(const char *P) {
98   if (P[15] == 0)
99     // Null terminated.
100     return P;
101   // Not null terminated, so this is a 16 char string.
102   return StringRef(P, 16);
103 }
104
105 // Helper to advance a section or symbol iterator multiple increments at a time.
106 template<class T>
107 static void advance(T &it, size_t Val) {
108   while (Val--)
109     ++it;
110 }
111
112 static unsigned getCPUType(const MachOObjectFile *O) {
113   return O->getHeader().cputype;
114 }
115
116 static void printRelocationTargetName(const MachOObjectFile *O,
117                                       const MachO::any_relocation_info &RE,
118                                       raw_string_ostream &fmt) {
119   bool IsScattered = O->isRelocationScattered(RE);
120
121   // Target of a scattered relocation is an address.  In the interest of
122   // generating pretty output, scan through the symbol table looking for a
123   // symbol that aligns with that address.  If we find one, print it.
124   // Otherwise, we just print the hex address of the target.
125   if (IsScattered) {
126     uint32_t Val = O->getPlainRelocationSymbolNum(RE);
127
128     for (const SymbolRef &Symbol : O->symbols()) {
129       std::error_code ec;
130       uint64_t Addr;
131       StringRef Name;
132
133       if ((ec = Symbol.getAddress(Addr)))
134         report_fatal_error(ec.message());
135       if (Addr != Val)
136         continue;
137       if ((ec = Symbol.getName(Name)))
138         report_fatal_error(ec.message());
139       fmt << Name;
140       return;
141     }
142
143     // If we couldn't find a symbol that this relocation refers to, try
144     // to find a section beginning instead.
145     for (const SectionRef &Section : O->sections()) {
146       std::error_code ec;
147
148       StringRef Name;
149       uint64_t Addr = Section.getAddress();
150       if (Addr != Val)
151         continue;
152       if ((ec = Section.getName(Name)))
153         report_fatal_error(ec.message());
154       fmt << Name;
155       return;
156     }
157
158     fmt << format("0x%x", Val);
159     return;
160   }
161
162   StringRef S;
163   bool isExtern = O->getPlainRelocationExternal(RE);
164   uint64_t Val = O->getPlainRelocationSymbolNum(RE);
165
166   if (isExtern) {
167     symbol_iterator SI = O->symbol_begin();
168     advance(SI, Val);
169     SI->getName(S);
170   } else {
171     section_iterator SI = O->section_begin();
172     // Adjust for the fact that sections are 1-indexed.
173     advance(SI, Val - 1);
174     SI->getName(S);
175   }
176
177   fmt << S;
178 }
179
180 static uint32_t
181 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
182   return RE.r_word0;
183 }
184
185 static unsigned
186 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
187   return RE.r_word0 & 0xffffff;
188 }
189
190 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
191                                     const MachO::any_relocation_info &RE) {
192   if (O->isLittleEndian())
193     return (RE.r_word1 >> 24) & 1;
194   return (RE.r_word1 >> 7) & 1;
195 }
196
197 static bool
198 getScatteredRelocationPCRel(const MachOObjectFile *O,
199                             const MachO::any_relocation_info &RE) {
200   return (RE.r_word0 >> 30) & 1;
201 }
202
203 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
204                                          const MachO::any_relocation_info &RE) {
205   if (O->isLittleEndian())
206     return (RE.r_word1 >> 25) & 3;
207   return (RE.r_word1 >> 5) & 3;
208 }
209
210 static unsigned
211 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
212   return (RE.r_word0 >> 28) & 3;
213 }
214
215 static unsigned getPlainRelocationType(const MachOObjectFile *O,
216                                        const MachO::any_relocation_info &RE) {
217   if (O->isLittleEndian())
218     return RE.r_word1 >> 28;
219   return RE.r_word1 & 0xf;
220 }
221
222 static uint32_t getSectionFlags(const MachOObjectFile *O,
223                                 DataRefImpl Sec) {
224   if (O->is64Bit()) {
225     MachO::section_64 Sect = O->getSection64(Sec);
226     return Sect.flags;
227   }
228   MachO::section Sect = O->getSection(Sec);
229   return Sect.flags;
230 }
231
232 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
233                                  bool Is64bits, std::error_code &EC)
234     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
235       SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
236       DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
237       UuidLoadCmd(nullptr), HasPageZeroSegment(false) {
238   uint32_t LoadCommandCount = this->getHeader().ncmds;
239   MachO::LoadCommandType SegmentLoadType = is64Bit() ?
240     MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
241
242   MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
243   for (unsigned I = 0; ; ++I) {
244     if (Load.C.cmd == MachO::LC_SYMTAB) {
245       assert(!SymtabLoadCmd && "Multiple symbol tables");
246       SymtabLoadCmd = Load.Ptr;
247     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
248       assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
249       DysymtabLoadCmd = Load.Ptr;
250     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
251       assert(!DataInCodeLoadCmd && "Multiple data in code tables");
252       DataInCodeLoadCmd = Load.Ptr;
253     } else if (Load.C.cmd == MachO::LC_DYLD_INFO || 
254                Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
255       assert(!DyldInfoLoadCmd && "Multiple dyldinfo load commands");
256       DyldInfoLoadCmd = Load.Ptr;
257     } else if (Load.C.cmd == MachO::LC_UUID) {
258       assert(!UuidLoadCmd && "Multiple UUID load commands");
259       UuidLoadCmd = Load.Ptr;
260     } else if (Load.C.cmd == SegmentLoadType) {
261       uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
262       for (unsigned J = 0; J < NumSections; ++J) {
263         const char *Sec = getSectionPtr(this, Load, J);
264         Sections.push_back(Sec);
265       }
266       if (isPageZeroSegment(this, Load))
267         HasPageZeroSegment = true;
268     } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
269                Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
270                Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
271                Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
272                Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
273       Libraries.push_back(Load.Ptr);
274     }
275
276     if (I == LoadCommandCount - 1)
277       break;
278     else
279       Load = getNextLoadCommandInfo(Load);
280   }
281 }
282
283 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
284   unsigned SymbolTableEntrySize = is64Bit() ?
285     sizeof(MachO::nlist_64) :
286     sizeof(MachO::nlist);
287   Symb.p += SymbolTableEntrySize;
288 }
289
290 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
291                                                StringRef &Res) const {
292   StringRef StringTable = getStringTableData();
293   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
294   const char *Start = &StringTable.data()[Entry.n_strx];
295   Res = StringRef(Start);
296   return object_error::success;
297 }
298
299 // getIndirectName() returns the name of the alias'ed symbol who's string table
300 // index is in the n_value field.
301 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
302                                                  StringRef &Res) const {
303   StringRef StringTable = getStringTableData();
304   uint64_t NValue;
305   if (is64Bit()) {
306     MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
307     NValue = Entry.n_value;
308     if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
309       return object_error::parse_failed;
310   } else {
311     MachO::nlist Entry = getSymbolTableEntry(Symb);
312     NValue = Entry.n_value;
313     if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
314       return object_error::parse_failed;
315   }
316   if (NValue >= StringTable.size())
317     return object_error::parse_failed;
318   const char *Start = &StringTable.data()[NValue];
319   Res = StringRef(Start);
320   return object_error::success;
321 }
322
323 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
324                                                   uint64_t &Res) const {
325   if (is64Bit()) {
326     MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
327     if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
328         Entry.n_value == 0)
329       Res = UnknownAddressOrSize;
330     else
331       Res = Entry.n_value;
332   } else {
333     MachO::nlist Entry = getSymbolTableEntry(Symb);
334     if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
335         Entry.n_value == 0)
336       Res = UnknownAddressOrSize;
337     else
338       Res = Entry.n_value;
339   }
340   return object_error::success;
341 }
342
343 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
344                                                     uint32_t &Result) const {
345   uint32_t flags = getSymbolFlags(DRI);
346   if (flags & SymbolRef::SF_Common) {
347     MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
348     Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
349   } else {
350     Result = 0;
351   }
352   return object_error::success;
353 }
354
355 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
356                                                uint64_t &Result) const {
357   uint64_t BeginOffset;
358   uint64_t EndOffset = 0;
359   uint8_t SectionIndex;
360
361   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
362   uint64_t Value;
363   getSymbolAddress(DRI, Value);
364   if (Value == UnknownAddressOrSize) {
365     Result = UnknownAddressOrSize;
366     return object_error::success;
367   }
368
369   BeginOffset = Value;
370
371   SectionIndex = Entry.n_sect;
372   if (!SectionIndex) {
373     uint32_t flags = getSymbolFlags(DRI);
374     if (flags & SymbolRef::SF_Common)
375       Result = Value;
376     else
377       Result = UnknownAddressOrSize;
378     return object_error::success;
379   }
380   // Unfortunately symbols are unsorted so we need to touch all
381   // symbols from load command
382   for (const SymbolRef &Symbol : symbols()) {
383     DataRefImpl DRI = Symbol.getRawDataRefImpl();
384     Entry = getSymbolTableEntryBase(this, DRI);
385     getSymbolAddress(DRI, Value);
386     if (Value == UnknownAddressOrSize)
387       continue;
388     if (Entry.n_sect == SectionIndex && Value > BeginOffset)
389       if (!EndOffset || Value < EndOffset)
390         EndOffset = Value;
391   }
392   if (!EndOffset) {
393     DataRefImpl Sec;
394     Sec.d.a = SectionIndex-1;
395     uint64_t Size = getSectionSize(Sec);
396     EndOffset = getSectionAddress(Sec);
397     EndOffset += Size;
398   }
399   Result = EndOffset - BeginOffset;
400   return object_error::success;
401 }
402
403 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
404                                                SymbolRef::Type &Res) const {
405   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
406   uint8_t n_type = Entry.n_type;
407
408   Res = SymbolRef::ST_Other;
409
410   // If this is a STAB debugging symbol, we can do nothing more.
411   if (n_type & MachO::N_STAB) {
412     Res = SymbolRef::ST_Debug;
413     return object_error::success;
414   }
415
416   switch (n_type & MachO::N_TYPE) {
417     case MachO::N_UNDF :
418       Res = SymbolRef::ST_Unknown;
419       break;
420     case MachO::N_SECT :
421       Res = SymbolRef::ST_Function;
422       break;
423   }
424   return object_error::success;
425 }
426
427 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
428   MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
429
430   uint8_t MachOType = Entry.n_type;
431   uint16_t MachOFlags = Entry.n_desc;
432
433   uint32_t Result = SymbolRef::SF_None;
434
435   if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
436     Result |= SymbolRef::SF_Undefined;
437
438   if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
439     Result |= SymbolRef::SF_Indirect;
440
441   if (MachOType & MachO::N_STAB)
442     Result |= SymbolRef::SF_FormatSpecific;
443
444   if (MachOType & MachO::N_EXT) {
445     Result |= SymbolRef::SF_Global;
446     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
447       uint64_t Value;
448       getSymbolAddress(DRI, Value);
449       if (Value && Value != UnknownAddressOrSize)
450         Result |= SymbolRef::SF_Common;
451     }
452   }
453
454   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
455     Result |= SymbolRef::SF_Weak;
456
457   if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
458     Result |= SymbolRef::SF_Thumb;
459
460   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
461     Result |= SymbolRef::SF_Absolute;
462
463   return Result;
464 }
465
466 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
467                                                   section_iterator &Res) const {
468   MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
469   uint8_t index = Entry.n_sect;
470
471   if (index == 0) {
472     Res = section_end();
473   } else {
474     DataRefImpl DRI;
475     DRI.d.a = index - 1;
476     Res = section_iterator(SectionRef(DRI, this));
477   }
478
479   return object_error::success;
480 }
481
482 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
483   Sec.d.a++;
484 }
485
486 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
487                                                 StringRef &Result) const {
488   ArrayRef<char> Raw = getSectionRawName(Sec);
489   Result = parseSegmentOrSectionName(Raw.data());
490   return object_error::success;
491 }
492
493 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
494   if (is64Bit())
495     return getSection64(Sec).addr;
496   return getSection(Sec).addr;
497 }
498
499 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
500   if (is64Bit())
501     return getSection64(Sec).size;
502   return getSection(Sec).size;
503 }
504
505 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
506                                                     StringRef &Res) const {
507   uint32_t Offset;
508   uint64_t Size;
509
510   if (is64Bit()) {
511     MachO::section_64 Sect = getSection64(Sec);
512     Offset = Sect.offset;
513     Size = Sect.size;
514   } else {
515     MachO::section Sect = getSection(Sec);
516     Offset = Sect.offset;
517     Size = Sect.size;
518   }
519
520   Res = this->getData().substr(Offset, Size);
521   return object_error::success;
522 }
523
524 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
525   uint32_t Align;
526   if (is64Bit()) {
527     MachO::section_64 Sect = getSection64(Sec);
528     Align = Sect.align;
529   } else {
530     MachO::section Sect = getSection(Sec);
531     Align = Sect.align;
532   }
533
534   return uint64_t(1) << Align;
535 }
536
537 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
538   uint32_t Flags = getSectionFlags(this, Sec);
539   return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
540 }
541
542 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
543   uint32_t Flags = getSectionFlags(this, Sec);
544   unsigned SectionType = Flags & MachO::SECTION_TYPE;
545   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
546          !(SectionType == MachO::S_ZEROFILL ||
547            SectionType == MachO::S_GB_ZEROFILL);
548 }
549
550 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
551   uint32_t Flags = getSectionFlags(this, Sec);
552   unsigned SectionType = Flags & MachO::SECTION_TYPE;
553   return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
554          (SectionType == MachO::S_ZEROFILL ||
555           SectionType == MachO::S_GB_ZEROFILL);
556 }
557
558 bool MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sect) const {
559   // FIXME: Unimplemented.
560   return true;
561 }
562
563 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
564   // FIXME: Unimplemented.
565   return false;
566 }
567
568 bool MachOObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
569   uint32_t Flags = getSectionFlags(this, Sec);
570   unsigned SectionType = Flags & MachO::SECTION_TYPE;
571   return SectionType == MachO::S_ZEROFILL ||
572          SectionType == MachO::S_GB_ZEROFILL;
573 }
574
575 bool MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const {
576   // Consider using the code from isSectionText to look for __const sections.
577   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
578   // to use section attributes to distinguish code from data.
579
580   // FIXME: Unimplemented.
581   return false;
582 }
583
584 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
585                                             DataRefImpl Symb) const {
586   SymbolRef::Type ST;
587   this->getSymbolType(Symb, ST);
588   if (ST == SymbolRef::ST_Unknown)
589     return false;
590
591   uint64_t SectBegin = getSectionAddress(Sec);
592   uint64_t SectEnd = getSectionSize(Sec);
593   SectEnd += SectBegin;
594
595   uint64_t SymAddr;
596   getSymbolAddress(Symb, SymAddr);
597   return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
598 }
599
600 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
601   DataRefImpl Ret;
602   Ret.d.a = Sec.d.a;
603   Ret.d.b = 0;
604   return relocation_iterator(RelocationRef(Ret, this));
605 }
606
607 relocation_iterator
608 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
609   uint32_t Num;
610   if (is64Bit()) {
611     MachO::section_64 Sect = getSection64(Sec);
612     Num = Sect.nreloc;
613   } else {
614     MachO::section Sect = getSection(Sec);
615     Num = Sect.nreloc;
616   }
617
618   DataRefImpl Ret;
619   Ret.d.a = Sec.d.a;
620   Ret.d.b = Num;
621   return relocation_iterator(RelocationRef(Ret, this));
622 }
623
624 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
625   ++Rel.d.b;
626 }
627
628 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
629                                                       uint64_t &Res) const {
630   uint64_t Offset;
631   getRelocationOffset(Rel, Offset);
632
633   DataRefImpl Sec;
634   Sec.d.a = Rel.d.a;
635   uint64_t SecAddress = getSectionAddress(Sec);
636   Res = SecAddress + Offset;
637   return object_error::success;
638 }
639
640 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
641                                                      uint64_t &Res) const {
642   assert(getHeader().filetype == MachO::MH_OBJECT &&
643          "Only implemented for MH_OBJECT");
644   MachO::any_relocation_info RE = getRelocation(Rel);
645   Res = getAnyRelocationAddress(RE);
646   return object_error::success;
647 }
648
649 symbol_iterator
650 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
651   MachO::any_relocation_info RE = getRelocation(Rel);
652   if (isRelocationScattered(RE))
653     return symbol_end();
654
655   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
656   bool isExtern = getPlainRelocationExternal(RE);
657   if (!isExtern)
658     return symbol_end();
659
660   MachO::symtab_command S = getSymtabLoadCommand();
661   unsigned SymbolTableEntrySize = is64Bit() ?
662     sizeof(MachO::nlist_64) :
663     sizeof(MachO::nlist);
664   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
665   DataRefImpl Sym;
666   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
667   return symbol_iterator(SymbolRef(Sym, this));
668 }
669
670 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
671                                                    uint64_t &Res) const {
672   MachO::any_relocation_info RE = getRelocation(Rel);
673   Res = getAnyRelocationType(RE);
674   return object_error::success;
675 }
676
677 std::error_code
678 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
679                                        SmallVectorImpl<char> &Result) const {
680   StringRef res;
681   uint64_t RType;
682   getRelocationType(Rel, RType);
683
684   unsigned Arch = this->getArch();
685
686   switch (Arch) {
687     case Triple::x86: {
688       static const char *const Table[] =  {
689         "GENERIC_RELOC_VANILLA",
690         "GENERIC_RELOC_PAIR",
691         "GENERIC_RELOC_SECTDIFF",
692         "GENERIC_RELOC_PB_LA_PTR",
693         "GENERIC_RELOC_LOCAL_SECTDIFF",
694         "GENERIC_RELOC_TLV" };
695
696       if (RType > 5)
697         res = "Unknown";
698       else
699         res = Table[RType];
700       break;
701     }
702     case Triple::x86_64: {
703       static const char *const Table[] =  {
704         "X86_64_RELOC_UNSIGNED",
705         "X86_64_RELOC_SIGNED",
706         "X86_64_RELOC_BRANCH",
707         "X86_64_RELOC_GOT_LOAD",
708         "X86_64_RELOC_GOT",
709         "X86_64_RELOC_SUBTRACTOR",
710         "X86_64_RELOC_SIGNED_1",
711         "X86_64_RELOC_SIGNED_2",
712         "X86_64_RELOC_SIGNED_4",
713         "X86_64_RELOC_TLV" };
714
715       if (RType > 9)
716         res = "Unknown";
717       else
718         res = Table[RType];
719       break;
720     }
721     case Triple::arm: {
722       static const char *const Table[] =  {
723         "ARM_RELOC_VANILLA",
724         "ARM_RELOC_PAIR",
725         "ARM_RELOC_SECTDIFF",
726         "ARM_RELOC_LOCAL_SECTDIFF",
727         "ARM_RELOC_PB_LA_PTR",
728         "ARM_RELOC_BR24",
729         "ARM_THUMB_RELOC_BR22",
730         "ARM_THUMB_32BIT_BRANCH",
731         "ARM_RELOC_HALF",
732         "ARM_RELOC_HALF_SECTDIFF" };
733
734       if (RType > 9)
735         res = "Unknown";
736       else
737         res = Table[RType];
738       break;
739     }
740     case Triple::aarch64: {
741       static const char *const Table[] = {
742         "ARM64_RELOC_UNSIGNED",           "ARM64_RELOC_SUBTRACTOR",
743         "ARM64_RELOC_BRANCH26",           "ARM64_RELOC_PAGE21",
744         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
745         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
746         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
747         "ARM64_RELOC_ADDEND"
748       };
749
750       if (RType >= array_lengthof(Table))
751         res = "Unknown";
752       else
753         res = Table[RType];
754       break;
755     }
756     case Triple::ppc: {
757       static const char *const Table[] =  {
758         "PPC_RELOC_VANILLA",
759         "PPC_RELOC_PAIR",
760         "PPC_RELOC_BR14",
761         "PPC_RELOC_BR24",
762         "PPC_RELOC_HI16",
763         "PPC_RELOC_LO16",
764         "PPC_RELOC_HA16",
765         "PPC_RELOC_LO14",
766         "PPC_RELOC_SECTDIFF",
767         "PPC_RELOC_PB_LA_PTR",
768         "PPC_RELOC_HI16_SECTDIFF",
769         "PPC_RELOC_LO16_SECTDIFF",
770         "PPC_RELOC_HA16_SECTDIFF",
771         "PPC_RELOC_JBSR",
772         "PPC_RELOC_LO14_SECTDIFF",
773         "PPC_RELOC_LOCAL_SECTDIFF" };
774
775       if (RType > 15)
776         res = "Unknown";
777       else
778         res = Table[RType];
779       break;
780     }
781     case Triple::UnknownArch:
782       res = "Unknown";
783       break;
784   }
785   Result.append(res.begin(), res.end());
786   return object_error::success;
787 }
788
789 std::error_code
790 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
791                                           SmallVectorImpl<char> &Result) const {
792   MachO::any_relocation_info RE = getRelocation(Rel);
793
794   unsigned Arch = this->getArch();
795
796   std::string fmtbuf;
797   raw_string_ostream fmt(fmtbuf);
798   unsigned Type = this->getAnyRelocationType(RE);
799   bool IsPCRel = this->getAnyRelocationPCRel(RE);
800
801   // Determine any addends that should be displayed with the relocation.
802   // These require decoding the relocation type, which is triple-specific.
803
804   // X86_64 has entirely custom relocation types.
805   if (Arch == Triple::x86_64) {
806     bool isPCRel = getAnyRelocationPCRel(RE);
807
808     switch (Type) {
809       case MachO::X86_64_RELOC_GOT_LOAD:
810       case MachO::X86_64_RELOC_GOT: {
811         printRelocationTargetName(this, RE, fmt);
812         fmt << "@GOT";
813         if (isPCRel) fmt << "PCREL";
814         break;
815       }
816       case MachO::X86_64_RELOC_SUBTRACTOR: {
817         DataRefImpl RelNext = Rel;
818         moveRelocationNext(RelNext);
819         MachO::any_relocation_info RENext = getRelocation(RelNext);
820
821         // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
822         // X86_64_RELOC_UNSIGNED.
823         // NOTE: Scattered relocations don't exist on x86_64.
824         unsigned RType = getAnyRelocationType(RENext);
825         if (RType != MachO::X86_64_RELOC_UNSIGNED)
826           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
827                              "X86_64_RELOC_SUBTRACTOR.");
828
829         // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
830         // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
831         printRelocationTargetName(this, RENext, fmt);
832         fmt << "-";
833         printRelocationTargetName(this, RE, fmt);
834         break;
835       }
836       case MachO::X86_64_RELOC_TLV:
837         printRelocationTargetName(this, RE, fmt);
838         fmt << "@TLV";
839         if (isPCRel) fmt << "P";
840         break;
841       case MachO::X86_64_RELOC_SIGNED_1:
842         printRelocationTargetName(this, RE, fmt);
843         fmt << "-1";
844         break;
845       case MachO::X86_64_RELOC_SIGNED_2:
846         printRelocationTargetName(this, RE, fmt);
847         fmt << "-2";
848         break;
849       case MachO::X86_64_RELOC_SIGNED_4:
850         printRelocationTargetName(this, RE, fmt);
851         fmt << "-4";
852         break;
853       default:
854         printRelocationTargetName(this, RE, fmt);
855         break;
856     }
857   // X86 and ARM share some relocation types in common.
858   } else if (Arch == Triple::x86 || Arch == Triple::arm ||
859              Arch == Triple::ppc) {
860     // Generic relocation types...
861     switch (Type) {
862       case MachO::GENERIC_RELOC_PAIR: // prints no info
863         return object_error::success;
864       case MachO::GENERIC_RELOC_SECTDIFF: {
865         DataRefImpl RelNext = Rel;
866         moveRelocationNext(RelNext);
867         MachO::any_relocation_info RENext = getRelocation(RelNext);
868
869         // X86 sect diff's must be followed by a relocation of type
870         // GENERIC_RELOC_PAIR.
871         unsigned RType = getAnyRelocationType(RENext);
872
873         if (RType != MachO::GENERIC_RELOC_PAIR)
874           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
875                              "GENERIC_RELOC_SECTDIFF.");
876
877         printRelocationTargetName(this, RE, fmt);
878         fmt << "-";
879         printRelocationTargetName(this, RENext, fmt);
880         break;
881       }
882     }
883
884     if (Arch == Triple::x86 || Arch == Triple::ppc) {
885       switch (Type) {
886         case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
887           DataRefImpl RelNext = Rel;
888           moveRelocationNext(RelNext);
889           MachO::any_relocation_info RENext = getRelocation(RelNext);
890
891           // X86 sect diff's must be followed by a relocation of type
892           // GENERIC_RELOC_PAIR.
893           unsigned RType = getAnyRelocationType(RENext);
894           if (RType != MachO::GENERIC_RELOC_PAIR)
895             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
896                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
897
898           printRelocationTargetName(this, RE, fmt);
899           fmt << "-";
900           printRelocationTargetName(this, RENext, fmt);
901           break;
902         }
903         case MachO::GENERIC_RELOC_TLV: {
904           printRelocationTargetName(this, RE, fmt);
905           fmt << "@TLV";
906           if (IsPCRel) fmt << "P";
907           break;
908         }
909         default:
910           printRelocationTargetName(this, RE, fmt);
911       }
912     } else { // ARM-specific relocations
913       switch (Type) {
914         case MachO::ARM_RELOC_HALF:
915         case MachO::ARM_RELOC_HALF_SECTDIFF: {
916           // Half relocations steal a bit from the length field to encode
917           // whether this is an upper16 or a lower16 relocation.
918           bool isUpper = getAnyRelocationLength(RE) >> 1;
919
920           if (isUpper)
921             fmt << ":upper16:(";
922           else
923             fmt << ":lower16:(";
924           printRelocationTargetName(this, RE, fmt);
925
926           DataRefImpl RelNext = Rel;
927           moveRelocationNext(RelNext);
928           MachO::any_relocation_info RENext = getRelocation(RelNext);
929
930           // ARM half relocs must be followed by a relocation of type
931           // ARM_RELOC_PAIR.
932           unsigned RType = getAnyRelocationType(RENext);
933           if (RType != MachO::ARM_RELOC_PAIR)
934             report_fatal_error("Expected ARM_RELOC_PAIR after "
935                                "ARM_RELOC_HALF");
936
937           // NOTE: The half of the target virtual address is stashed in the
938           // address field of the secondary relocation, but we can't reverse
939           // engineer the constant offset from it without decoding the movw/movt
940           // instruction to find the other half in its immediate field.
941
942           // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
943           // symbol/section pointer of the follow-on relocation.
944           if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
945             fmt << "-";
946             printRelocationTargetName(this, RENext, fmt);
947           }
948
949           fmt << ")";
950           break;
951         }
952         default: {
953           printRelocationTargetName(this, RE, fmt);
954         }
955       }
956     }
957   } else
958     printRelocationTargetName(this, RE, fmt);
959
960   fmt.flush();
961   Result.append(fmtbuf.begin(), fmtbuf.end());
962   return object_error::success;
963 }
964
965 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
966                                                      bool &Result) const {
967   unsigned Arch = getArch();
968   uint64_t Type;
969   getRelocationType(Rel, Type);
970
971   Result = false;
972
973   // On arches that use the generic relocations, GENERIC_RELOC_PAIR
974   // is always hidden.
975   if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
976     if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
977   } else if (Arch == Triple::x86_64) {
978     // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
979     // an X86_64_RELOC_SUBTRACTOR.
980     if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
981       DataRefImpl RelPrev = Rel;
982       RelPrev.d.a--;
983       uint64_t PrevType;
984       getRelocationType(RelPrev, PrevType);
985       if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
986         Result = true;
987     }
988   }
989
990   return object_error::success;
991 }
992
993 //
994 // guessLibraryShortName() is passed a name of a dynamic library and returns a
995 // guess on what the short name is.  Then name is returned as a substring of the
996 // StringRef Name passed in.  The name of the dynamic library is recognized as
997 // a framework if it has one of the two following forms:
998 //      Foo.framework/Versions/A/Foo
999 //      Foo.framework/Foo
1000 // Where A and Foo can be any string.  And may contain a trailing suffix
1001 // starting with an underbar.  If the Name is recognized as a framework then
1002 // isFramework is set to true else it is set to false.  If the Name has a
1003 // suffix then Suffix is set to the substring in Name that contains the suffix
1004 // else it is set to a NULL StringRef.
1005 //
1006 // The Name of the dynamic library is recognized as a library name if it has
1007 // one of the two following forms:
1008 //      libFoo.A.dylib
1009 //      libFoo.dylib
1010 // The library may have a suffix trailing the name Foo of the form:
1011 //      libFoo_profile.A.dylib
1012 //      libFoo_profile.dylib
1013 //
1014 // The Name of the dynamic library is also recognized as a library name if it
1015 // has the following form:
1016 //      Foo.qtx
1017 //
1018 // If the Name of the dynamic library is none of the forms above then a NULL
1019 // StringRef is returned.
1020 //
1021 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1022                                                  bool &isFramework,
1023                                                  StringRef &Suffix) {
1024   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1025   size_t a, b, c, d, Idx;
1026
1027   isFramework = false;
1028   Suffix = StringRef();
1029
1030   // Pull off the last component and make Foo point to it
1031   a = Name.rfind('/');
1032   if (a == Name.npos || a == 0)
1033     goto guess_library;
1034   Foo = Name.slice(a+1, Name.npos);
1035
1036   // Look for a suffix starting with a '_'
1037   Idx = Foo.rfind('_');
1038   if (Idx != Foo.npos && Foo.size() >= 2) {
1039     Suffix = Foo.slice(Idx, Foo.npos);
1040     Foo = Foo.slice(0, Idx);
1041   }
1042
1043   // First look for the form Foo.framework/Foo
1044   b = Name.rfind('/', a);
1045   if (b == Name.npos)
1046     Idx = 0;
1047   else
1048     Idx = b+1;
1049   F = Name.slice(Idx, Idx + Foo.size());
1050   DotFramework = Name.slice(Idx + Foo.size(),
1051                             Idx + Foo.size() + sizeof(".framework/")-1);
1052   if (F == Foo && DotFramework == ".framework/") {
1053     isFramework = true;
1054     return Foo;
1055   }
1056
1057   // Next look for the form Foo.framework/Versions/A/Foo
1058   if (b == Name.npos)
1059     goto guess_library;
1060   c =  Name.rfind('/', b);
1061   if (c == Name.npos || c == 0)
1062     goto guess_library;
1063   V = Name.slice(c+1, Name.npos);
1064   if (!V.startswith("Versions/"))
1065     goto guess_library;
1066   d =  Name.rfind('/', c);
1067   if (d == Name.npos)
1068     Idx = 0;
1069   else
1070     Idx = d+1;
1071   F = Name.slice(Idx, Idx + Foo.size());
1072   DotFramework = Name.slice(Idx + Foo.size(),
1073                             Idx + Foo.size() + sizeof(".framework/")-1);
1074   if (F == Foo && DotFramework == ".framework/") {
1075     isFramework = true;
1076     return Foo;
1077   }
1078
1079 guess_library:
1080   // pull off the suffix after the "." and make a point to it
1081   a = Name.rfind('.');
1082   if (a == Name.npos || a == 0)
1083     return StringRef();
1084   Dylib = Name.slice(a, Name.npos);
1085   if (Dylib != ".dylib")
1086     goto guess_qtx;
1087
1088   // First pull off the version letter for the form Foo.A.dylib if any.
1089   if (a >= 3) {
1090     Dot = Name.slice(a-2, a-1);
1091     if (Dot == ".")
1092       a = a - 2;
1093   }
1094
1095   b = Name.rfind('/', a);
1096   if (b == Name.npos)
1097     b = 0;
1098   else
1099     b = b+1;
1100   // ignore any suffix after an underbar like Foo_profile.A.dylib
1101   Idx = Name.find('_', b);
1102   if (Idx != Name.npos && Idx != b) {
1103     Lib = Name.slice(b, Idx);
1104     Suffix = Name.slice(Idx, a);
1105   }
1106   else
1107     Lib = Name.slice(b, a);
1108   // There are incorrect library names of the form:
1109   // libATS.A_profile.dylib so check for these.
1110   if (Lib.size() >= 3) {
1111     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1112     if (Dot == ".")
1113       Lib = Lib.slice(0, Lib.size()-2);
1114   }
1115   return Lib;
1116
1117 guess_qtx:
1118   Qtx = Name.slice(a, Name.npos);
1119   if (Qtx != ".qtx")
1120     return StringRef();
1121   b = Name.rfind('/', a);
1122   if (b == Name.npos)
1123     Lib = Name.slice(0, a);
1124   else
1125     Lib = Name.slice(b+1, a);
1126   // There are library names of the form: QT.A.qtx so check for these.
1127   if (Lib.size() >= 3) {
1128     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1129     if (Dot == ".")
1130       Lib = Lib.slice(0, Lib.size()-2);
1131   }
1132   return Lib;
1133 }
1134
1135 // getLibraryShortNameByIndex() is used to get the short name of the library
1136 // for an undefined symbol in a linked Mach-O binary that was linked with the
1137 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1138 // It is passed the index (0 - based) of the library as translated from
1139 // GET_LIBRARY_ORDINAL (1 - based).
1140 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1141                                                          StringRef &Res) const {
1142   if (Index >= Libraries.size())
1143     return object_error::parse_failed;
1144
1145   // If the cache of LibrariesShortNames is not built up do that first for
1146   // all the Libraries.
1147   if (LibrariesShortNames.size() == 0) {
1148     for (unsigned i = 0; i < Libraries.size(); i++) {
1149       MachO::dylib_command D =
1150         getStruct<MachO::dylib_command>(this, Libraries[i]);
1151       if (D.dylib.name >= D.cmdsize)
1152         return object_error::parse_failed;
1153       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1154       StringRef Name = StringRef(P);
1155       if (D.dylib.name+Name.size() >= D.cmdsize)
1156         return object_error::parse_failed;
1157       StringRef Suffix;
1158       bool isFramework;
1159       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1160       if (shortName.empty())
1161         LibrariesShortNames.push_back(Name);
1162       else
1163         LibrariesShortNames.push_back(shortName);
1164     }
1165   }
1166
1167   Res = LibrariesShortNames[Index];
1168   return object_error::success;
1169 }
1170
1171 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1172   return getSymbolByIndex(0);
1173 }
1174
1175 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1176   DataRefImpl DRI;
1177   if (!SymtabLoadCmd)
1178     return basic_symbol_iterator(SymbolRef(DRI, this));
1179
1180   MachO::symtab_command Symtab = getSymtabLoadCommand();
1181   unsigned SymbolTableEntrySize = is64Bit() ?
1182     sizeof(MachO::nlist_64) :
1183     sizeof(MachO::nlist);
1184   unsigned Offset = Symtab.symoff +
1185     Symtab.nsyms * SymbolTableEntrySize;
1186   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1187   return basic_symbol_iterator(SymbolRef(DRI, this));
1188 }
1189
1190 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1191   DataRefImpl DRI;
1192   if (!SymtabLoadCmd)
1193     return basic_symbol_iterator(SymbolRef(DRI, this));
1194
1195   MachO::symtab_command Symtab = getSymtabLoadCommand();
1196   assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1197   unsigned SymbolTableEntrySize =
1198     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1199   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1200   DRI.p += Index * SymbolTableEntrySize;
1201   return basic_symbol_iterator(SymbolRef(DRI, this));
1202 }
1203
1204 section_iterator MachOObjectFile::section_begin() const {
1205   DataRefImpl DRI;
1206   return section_iterator(SectionRef(DRI, this));
1207 }
1208
1209 section_iterator MachOObjectFile::section_end() const {
1210   DataRefImpl DRI;
1211   DRI.d.a = Sections.size();
1212   return section_iterator(SectionRef(DRI, this));
1213 }
1214
1215 uint8_t MachOObjectFile::getBytesInAddress() const {
1216   return is64Bit() ? 8 : 4;
1217 }
1218
1219 StringRef MachOObjectFile::getFileFormatName() const {
1220   unsigned CPUType = getCPUType(this);
1221   if (!is64Bit()) {
1222     switch (CPUType) {
1223     case llvm::MachO::CPU_TYPE_I386:
1224       return "Mach-O 32-bit i386";
1225     case llvm::MachO::CPU_TYPE_ARM:
1226       return "Mach-O arm";
1227     case llvm::MachO::CPU_TYPE_POWERPC:
1228       return "Mach-O 32-bit ppc";
1229     default:
1230       assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1231              "64-bit object file when we're not 64-bit?");
1232       return "Mach-O 32-bit unknown";
1233     }
1234   }
1235
1236   // Make sure the cpu type has the correct mask.
1237   assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1238          == llvm::MachO::CPU_ARCH_ABI64 &&
1239          "32-bit object file when we're 64-bit?");
1240
1241   switch (CPUType) {
1242   case llvm::MachO::CPU_TYPE_X86_64:
1243     return "Mach-O 64-bit x86-64";
1244   case llvm::MachO::CPU_TYPE_ARM64:
1245     return "Mach-O arm64";
1246   case llvm::MachO::CPU_TYPE_POWERPC64:
1247     return "Mach-O 64-bit ppc64";
1248   default:
1249     return "Mach-O 64-bit unknown";
1250   }
1251 }
1252
1253 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1254   switch (CPUType) {
1255   case llvm::MachO::CPU_TYPE_I386:
1256     return Triple::x86;
1257   case llvm::MachO::CPU_TYPE_X86_64:
1258     return Triple::x86_64;
1259   case llvm::MachO::CPU_TYPE_ARM:
1260     return Triple::arm;
1261   case llvm::MachO::CPU_TYPE_ARM64:
1262     return Triple::aarch64;
1263   case llvm::MachO::CPU_TYPE_POWERPC:
1264     return Triple::ppc;
1265   case llvm::MachO::CPU_TYPE_POWERPC64:
1266     return Triple::ppc64;
1267   default:
1268     return Triple::UnknownArch;
1269   }
1270 }
1271
1272 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1273                                 const char **McpuDefault) {
1274   if (McpuDefault)
1275     *McpuDefault = nullptr;
1276
1277   switch (CPUType) {
1278   case MachO::CPU_TYPE_I386:
1279     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1280     case MachO::CPU_SUBTYPE_I386_ALL:
1281       return Triple("i386-apple-darwin");
1282     default:
1283       return Triple();
1284     }
1285   case MachO::CPU_TYPE_X86_64:
1286     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1287     case MachO::CPU_SUBTYPE_X86_64_ALL:
1288       return Triple("x86_64-apple-darwin");
1289     case MachO::CPU_SUBTYPE_X86_64_H:
1290       return Triple("x86_64h-apple-darwin");
1291     default:
1292       return Triple();
1293     }
1294   case MachO::CPU_TYPE_ARM:
1295     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1296     case MachO::CPU_SUBTYPE_ARM_V4T:
1297       return Triple("armv4t-apple-darwin");
1298     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1299       return Triple("armv5e-apple-darwin");
1300     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1301       return Triple("xscale-apple-darwin");
1302     case MachO::CPU_SUBTYPE_ARM_V6:
1303       return Triple("armv6-apple-darwin");
1304     case MachO::CPU_SUBTYPE_ARM_V6M:
1305       if (McpuDefault)
1306         *McpuDefault = "cortex-m0";
1307       return Triple("armv6m-apple-darwin");
1308     case MachO::CPU_SUBTYPE_ARM_V7:
1309       return Triple("armv7-apple-darwin");
1310     case MachO::CPU_SUBTYPE_ARM_V7EM:
1311       if (McpuDefault)
1312         *McpuDefault = "cortex-m4";
1313       return Triple("armv7em-apple-darwin");
1314     case MachO::CPU_SUBTYPE_ARM_V7K:
1315       return Triple("armv7k-apple-darwin");
1316     case MachO::CPU_SUBTYPE_ARM_V7M:
1317       if (McpuDefault)
1318         *McpuDefault = "cortex-m3";
1319       return Triple("armv7m-apple-darwin");
1320     case MachO::CPU_SUBTYPE_ARM_V7S:
1321       return Triple("armv7s-apple-darwin");
1322     default:
1323       return Triple();
1324     }
1325   case MachO::CPU_TYPE_ARM64:
1326     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1327     case MachO::CPU_SUBTYPE_ARM64_ALL:
1328       return Triple("arm64-apple-darwin");
1329     default:
1330       return Triple();
1331     }
1332   case MachO::CPU_TYPE_POWERPC:
1333     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1334     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1335       return Triple("ppc-apple-darwin");
1336     default:
1337       return Triple();
1338     }
1339   case MachO::CPU_TYPE_POWERPC64:
1340     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1341     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1342       return Triple("ppc64-apple-darwin");
1343     default:
1344       return Triple();
1345     }
1346   default:
1347     return Triple();
1348   }
1349 }
1350
1351 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1352                                      const char **McpuDefault) {
1353   if (McpuDefault)
1354     *McpuDefault = nullptr;
1355
1356   switch (CPUType) {
1357   case MachO::CPU_TYPE_ARM:
1358     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1359     case MachO::CPU_SUBTYPE_ARM_V4T:
1360       return Triple("thumbv4t-apple-darwin");
1361     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1362       return Triple("thumbv5e-apple-darwin");
1363     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1364       return Triple("xscale-apple-darwin");
1365     case MachO::CPU_SUBTYPE_ARM_V6:
1366       return Triple("thumbv6-apple-darwin");
1367     case MachO::CPU_SUBTYPE_ARM_V6M:
1368       if (McpuDefault)
1369         *McpuDefault = "cortex-m0";
1370       return Triple("thumbv6m-apple-darwin");
1371     case MachO::CPU_SUBTYPE_ARM_V7:
1372       return Triple("thumbv7-apple-darwin");
1373     case MachO::CPU_SUBTYPE_ARM_V7EM:
1374       if (McpuDefault)
1375         *McpuDefault = "cortex-m4";
1376       return Triple("thumbv7em-apple-darwin");
1377     case MachO::CPU_SUBTYPE_ARM_V7K:
1378       return Triple("thumbv7k-apple-darwin");
1379     case MachO::CPU_SUBTYPE_ARM_V7M:
1380       if (McpuDefault)
1381         *McpuDefault = "cortex-m3";
1382       return Triple("thumbv7m-apple-darwin");
1383     case MachO::CPU_SUBTYPE_ARM_V7S:
1384       return Triple("thumbv7s-apple-darwin");
1385     default:
1386       return Triple();
1387     }
1388   default:
1389     return Triple();
1390   }
1391 }
1392
1393 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1394                                 const char **McpuDefault,
1395                                 Triple *ThumbTriple) {
1396   Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1397   *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1398                                                McpuDefault);
1399   return T;
1400 }
1401
1402 Triple MachOObjectFile::getHostArch() {
1403   return Triple(sys::getDefaultTargetTriple());
1404 }
1405
1406 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1407   return StringSwitch<bool>(ArchFlag)
1408       .Case("i386", true)
1409       .Case("x86_64", true)
1410       .Case("x86_64h", true)
1411       .Case("armv4t", true)
1412       .Case("arm", true)
1413       .Case("armv5e", true)
1414       .Case("armv6", true)
1415       .Case("armv6m", true)
1416       .Case("armv7em", true)
1417       .Case("armv7k", true)
1418       .Case("armv7m", true)
1419       .Case("armv7s", true)
1420       .Case("arm64", true)
1421       .Case("ppc", true)
1422       .Case("ppc64", true)
1423       .Default(false);
1424 }
1425
1426 unsigned MachOObjectFile::getArch() const {
1427   return getArch(getCPUType(this));
1428 }
1429
1430 Triple MachOObjectFile::getArch(const char **McpuDefault,
1431                                 Triple *ThumbTriple) const {
1432   Triple T;
1433   if (is64Bit()) {
1434     MachO::mach_header_64 H_64;
1435     H_64 = getHeader64();
1436     T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
1437     *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
1438                                                  McpuDefault);
1439   } else {
1440     MachO::mach_header H;
1441     H = getHeader();
1442     T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
1443     *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
1444                                                  McpuDefault);
1445   }
1446   return T;
1447 }
1448
1449 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1450   DataRefImpl DRI;
1451   DRI.d.a = Index;
1452   return section_rel_begin(DRI);
1453 }
1454
1455 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1456   DataRefImpl DRI;
1457   DRI.d.a = Index;
1458   return section_rel_end(DRI);
1459 }
1460
1461 dice_iterator MachOObjectFile::begin_dices() const {
1462   DataRefImpl DRI;
1463   if (!DataInCodeLoadCmd)
1464     return dice_iterator(DiceRef(DRI, this));
1465
1466   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1467   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1468   return dice_iterator(DiceRef(DRI, this));
1469 }
1470
1471 dice_iterator MachOObjectFile::end_dices() const {
1472   DataRefImpl DRI;
1473   if (!DataInCodeLoadCmd)
1474     return dice_iterator(DiceRef(DRI, this));
1475
1476   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1477   unsigned Offset = DicLC.dataoff + DicLC.datasize;
1478   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1479   return dice_iterator(DiceRef(DRI, this));
1480 }
1481
1482 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 
1483   : Trie(T), Malformed(false), Done(false) { }
1484
1485 void ExportEntry::moveToFirst() {
1486   pushNode(0);
1487   pushDownUntilBottom();
1488 }
1489
1490 void ExportEntry::moveToEnd() {
1491   Stack.clear();
1492   Done = true;
1493 }
1494
1495 bool ExportEntry::operator==(const ExportEntry &Other) const {
1496   // Common case, one at end, other iterating from begin. 
1497   if (Done || Other.Done)
1498     return (Done == Other.Done);
1499   // Not equal if different stack sizes.
1500   if (Stack.size() != Other.Stack.size())
1501     return false;
1502   // Not equal if different cumulative strings.
1503   if (!CumulativeString.str().equals(Other.CumulativeString.str()))
1504     return false;
1505   // Equal if all nodes in both stacks match.
1506   for (unsigned i=0; i < Stack.size(); ++i) {
1507     if (Stack[i].Start != Other.Stack[i].Start)
1508       return false;
1509   }
1510   return true;  
1511 }
1512
1513 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1514   unsigned Count;
1515   uint64_t Result = decodeULEB128(Ptr, &Count);
1516   Ptr += Count;
1517   if (Ptr > Trie.end()) {
1518     Ptr = Trie.end();
1519     Malformed = true;
1520   }
1521   return Result;
1522 }
1523
1524 StringRef ExportEntry::name() const {
1525   return CumulativeString.str();
1526 }
1527
1528 uint64_t ExportEntry::flags() const {
1529   return Stack.back().Flags;
1530 }
1531
1532 uint64_t ExportEntry::address() const {
1533   return Stack.back().Address;
1534 }
1535
1536 uint64_t ExportEntry::other() const {
1537   return Stack.back().Other;
1538 }
1539
1540 StringRef ExportEntry::otherName() const {
1541   const char* ImportName = Stack.back().ImportName;
1542   if (ImportName)
1543     return StringRef(ImportName);
1544   return StringRef();
1545 }
1546
1547 uint32_t ExportEntry::nodeOffset() const {
1548   return Stack.back().Start - Trie.begin();
1549 }
1550
1551 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 
1552   : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 
1553     ImportName(nullptr), ChildCount(0), NextChildIndex(0),  
1554     ParentStringLength(0), IsExportNode(false) {
1555 }
1556
1557 void ExportEntry::pushNode(uint64_t offset) {
1558   const uint8_t *Ptr = Trie.begin() + offset;
1559   NodeState State(Ptr);
1560   uint64_t ExportInfoSize = readULEB128(State.Current);
1561   State.IsExportNode = (ExportInfoSize != 0);
1562   const uint8_t* Children = State.Current + ExportInfoSize;
1563   if (State.IsExportNode) {
1564     State.Flags = readULEB128(State.Current);
1565     if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1566       State.Address = 0;
1567       State.Other = readULEB128(State.Current); // dylib ordinal
1568       State.ImportName = reinterpret_cast<const char*>(State.Current);
1569     } else {
1570       State.Address = readULEB128(State.Current);
1571       if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1572         State.Other = readULEB128(State.Current); 
1573     }
1574   }
1575   State.ChildCount = *Children;
1576   State.Current = Children + 1;
1577   State.NextChildIndex = 0;
1578   State.ParentStringLength = CumulativeString.size();
1579   Stack.push_back(State);
1580 }
1581
1582 void ExportEntry::pushDownUntilBottom() {
1583   while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1584     NodeState &Top = Stack.back();
1585     CumulativeString.resize(Top.ParentStringLength);
1586     for (;*Top.Current != 0; Top.Current++) {
1587       char C = *Top.Current;
1588       CumulativeString.push_back(C);
1589     }
1590     Top.Current += 1;
1591     uint64_t childNodeIndex = readULEB128(Top.Current);
1592     Top.NextChildIndex += 1;
1593     pushNode(childNodeIndex);
1594   }
1595   if (!Stack.back().IsExportNode) {
1596     Malformed = true;
1597     moveToEnd();
1598   }
1599 }
1600
1601 // We have a trie data structure and need a way to walk it that is compatible
1602 // with the C++ iterator model. The solution is a non-recursive depth first
1603 // traversal where the iterator contains a stack of parent nodes along with a
1604 // string that is the accumulation of all edge strings along the parent chain
1605 // to this point.
1606 //
1607 // There is one "export" node for each exported symbol.  But because some
1608 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1609 // node may have child nodes too.  
1610 //
1611 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1612 // child until hitting a node with no children (which is an export node or
1613 // else the trie is malformed). On the way down, each node is pushed on the
1614 // stack ivar.  If there is no more ways down, it pops up one and tries to go
1615 // down a sibling path until a childless node is reached.
1616 void ExportEntry::moveNext() {
1617   if (Stack.empty() || !Stack.back().IsExportNode) {
1618     Malformed = true;
1619     moveToEnd();
1620     return;
1621   }
1622
1623   Stack.pop_back();
1624   while (!Stack.empty()) {
1625     NodeState &Top = Stack.back();
1626     if (Top.NextChildIndex < Top.ChildCount) {
1627       pushDownUntilBottom();
1628       // Now at the next export node.
1629       return;
1630     } else {
1631       if (Top.IsExportNode) {
1632         // This node has no children but is itself an export node.
1633         CumulativeString.resize(Top.ParentStringLength);
1634         return;
1635       }
1636       Stack.pop_back();
1637     }
1638   }
1639   Done = true;
1640 }
1641
1642 iterator_range<export_iterator> 
1643 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1644   ExportEntry Start(Trie);
1645   Start.moveToFirst();
1646
1647   ExportEntry Finish(Trie);
1648   Finish.moveToEnd();
1649
1650   return iterator_range<export_iterator>(export_iterator(Start), 
1651                                          export_iterator(Finish));
1652 }
1653
1654 iterator_range<export_iterator> MachOObjectFile::exports() const {
1655   return exports(getDyldInfoExportsTrie());
1656 }
1657
1658
1659 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1660     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1661       RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1662       PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1663
1664 void MachORebaseEntry::moveToFirst() {
1665   Ptr = Opcodes.begin();
1666   moveNext();
1667 }
1668
1669 void MachORebaseEntry::moveToEnd() {
1670   Ptr = Opcodes.end();
1671   RemainingLoopCount = 0;
1672   Done = true;
1673 }
1674
1675 void MachORebaseEntry::moveNext() {
1676   // If in the middle of some loop, move to next rebasing in loop.
1677   SegmentOffset += AdvanceAmount;
1678   if (RemainingLoopCount) {
1679     --RemainingLoopCount;
1680     return;
1681   }
1682   if (Ptr == Opcodes.end()) {
1683     Done = true;
1684     return;
1685   }
1686   bool More = true;
1687   while (More && !Malformed) {
1688     // Parse next opcode and set up next loop.
1689     uint8_t Byte = *Ptr++;
1690     uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1691     uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1692     switch (Opcode) {
1693     case MachO::REBASE_OPCODE_DONE:
1694       More = false;
1695       Done = true;
1696       moveToEnd();
1697       DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1698       break;
1699     case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1700       RebaseType = ImmValue;
1701       DEBUG_WITH_TYPE(
1702           "mach-o-rebase",
1703           llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1704                        << "RebaseType=" << (int) RebaseType << "\n");
1705       break;
1706     case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1707       SegmentIndex = ImmValue;
1708       SegmentOffset = readULEB128();
1709       DEBUG_WITH_TYPE(
1710           "mach-o-rebase",
1711           llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1712                        << "SegmentIndex=" << SegmentIndex << ", "
1713                        << format("SegmentOffset=0x%06X", SegmentOffset)
1714                        << "\n");
1715       break;
1716     case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1717       SegmentOffset += readULEB128();
1718       DEBUG_WITH_TYPE("mach-o-rebase",
1719                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1720                                    << format("SegmentOffset=0x%06X",
1721                                              SegmentOffset) << "\n");
1722       break;
1723     case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1724       SegmentOffset += ImmValue * PointerSize;
1725       DEBUG_WITH_TYPE("mach-o-rebase",
1726                       llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1727                                    << format("SegmentOffset=0x%06X",
1728                                              SegmentOffset) << "\n");
1729       break;
1730     case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1731       AdvanceAmount = PointerSize;
1732       RemainingLoopCount = ImmValue - 1;
1733       DEBUG_WITH_TYPE(
1734           "mach-o-rebase",
1735           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1736                        << format("SegmentOffset=0x%06X", SegmentOffset)
1737                        << ", AdvanceAmount=" << AdvanceAmount
1738                        << ", RemainingLoopCount=" << RemainingLoopCount
1739                        << "\n");
1740       return;
1741     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1742       AdvanceAmount = PointerSize;
1743       RemainingLoopCount = readULEB128() - 1;
1744       DEBUG_WITH_TYPE(
1745           "mach-o-rebase",
1746           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1747                        << format("SegmentOffset=0x%06X", SegmentOffset)
1748                        << ", AdvanceAmount=" << AdvanceAmount
1749                        << ", RemainingLoopCount=" << RemainingLoopCount
1750                        << "\n");
1751       return;
1752     case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1753       AdvanceAmount = readULEB128() + PointerSize;
1754       RemainingLoopCount = 0;
1755       DEBUG_WITH_TYPE(
1756           "mach-o-rebase",
1757           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1758                        << format("SegmentOffset=0x%06X", SegmentOffset)
1759                        << ", AdvanceAmount=" << AdvanceAmount
1760                        << ", RemainingLoopCount=" << RemainingLoopCount
1761                        << "\n");
1762       return;
1763     case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1764       RemainingLoopCount = readULEB128() - 1;
1765       AdvanceAmount = readULEB128() + PointerSize;
1766       DEBUG_WITH_TYPE(
1767           "mach-o-rebase",
1768           llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1769                        << format("SegmentOffset=0x%06X", SegmentOffset)
1770                        << ", AdvanceAmount=" << AdvanceAmount
1771                        << ", RemainingLoopCount=" << RemainingLoopCount
1772                        << "\n");
1773       return;
1774     default:
1775       Malformed = true;
1776     }
1777   }
1778 }
1779
1780 uint64_t MachORebaseEntry::readULEB128() {
1781   unsigned Count;
1782   uint64_t Result = decodeULEB128(Ptr, &Count);
1783   Ptr += Count;
1784   if (Ptr > Opcodes.end()) {
1785     Ptr = Opcodes.end();
1786     Malformed = true;
1787   }
1788   return Result;
1789 }
1790
1791 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1792
1793 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1794
1795 StringRef MachORebaseEntry::typeName() const {
1796   switch (RebaseType) {
1797   case MachO::REBASE_TYPE_POINTER:
1798     return "pointer";
1799   case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1800     return "text abs32";
1801   case MachO::REBASE_TYPE_TEXT_PCREL32:
1802     return "text rel32";
1803   }
1804   return "unknown";
1805 }
1806
1807 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1808   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1809   return (Ptr == Other.Ptr) &&
1810          (RemainingLoopCount == Other.RemainingLoopCount) &&
1811          (Done == Other.Done);
1812 }
1813
1814 iterator_range<rebase_iterator>
1815 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1816   MachORebaseEntry Start(Opcodes, is64);
1817   Start.moveToFirst();
1818
1819   MachORebaseEntry Finish(Opcodes, is64);
1820   Finish.moveToEnd();
1821
1822   return iterator_range<rebase_iterator>(rebase_iterator(Start),
1823                                          rebase_iterator(Finish));
1824 }
1825
1826 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1827   return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1828 }
1829
1830
1831 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1832                                Kind BK)
1833     : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1834       Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1835       BindType(0), PointerSize(is64Bit ? 8 : 4),
1836       TableKind(BK), Malformed(false), Done(false) {}
1837
1838 void MachOBindEntry::moveToFirst() {
1839   Ptr = Opcodes.begin();
1840   moveNext();
1841 }
1842
1843 void MachOBindEntry::moveToEnd() {
1844   Ptr = Opcodes.end();
1845   RemainingLoopCount = 0;
1846   Done = true;
1847 }
1848
1849 void MachOBindEntry::moveNext() {
1850   // If in the middle of some loop, move to next binding in loop.
1851   SegmentOffset += AdvanceAmount;
1852   if (RemainingLoopCount) {
1853     --RemainingLoopCount;
1854     return;
1855   }
1856   if (Ptr == Opcodes.end()) {
1857     Done = true;
1858     return;
1859   }
1860   bool More = true;
1861   while (More && !Malformed) {
1862     // Parse next opcode and set up next loop.
1863     uint8_t Byte = *Ptr++;
1864     uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1865     uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1866     int8_t SignExtended;
1867     const uint8_t *SymStart;
1868     switch (Opcode) {
1869     case MachO::BIND_OPCODE_DONE:
1870       if (TableKind == Kind::Lazy) {
1871         // Lazying bindings have a DONE opcode between entries.  Need to ignore
1872         // it to advance to next entry.  But need not if this is last entry.
1873         bool NotLastEntry = false;
1874         for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1875           if (*P) {
1876             NotLastEntry = true;
1877           }
1878         }
1879         if (NotLastEntry)
1880           break;
1881       }
1882       More = false;
1883       Done = true;
1884       moveToEnd();
1885       DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1886       break;
1887     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1888       Ordinal = ImmValue;
1889       DEBUG_WITH_TYPE(
1890           "mach-o-bind",
1891           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1892                        << "Ordinal=" << Ordinal << "\n");
1893       break;
1894     case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1895       Ordinal = readULEB128();
1896       DEBUG_WITH_TYPE(
1897           "mach-o-bind",
1898           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1899                        << "Ordinal=" << Ordinal << "\n");
1900       break;
1901     case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1902       if (ImmValue) {
1903         SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1904         Ordinal = SignExtended;
1905       } else
1906         Ordinal = 0;
1907       DEBUG_WITH_TYPE(
1908           "mach-o-bind",
1909           llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1910                        << "Ordinal=" << Ordinal << "\n");
1911       break;
1912     case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1913       Flags = ImmValue;
1914       SymStart = Ptr;
1915       while (*Ptr) {
1916         ++Ptr;
1917       }
1918       SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1919                              Ptr-SymStart);
1920       ++Ptr;
1921       DEBUG_WITH_TYPE(
1922           "mach-o-bind",
1923           llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1924                        << "SymbolName=" << SymbolName << "\n");
1925       if (TableKind == Kind::Weak) {
1926         if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1927           return;
1928       }
1929       break;
1930     case MachO::BIND_OPCODE_SET_TYPE_IMM:
1931       BindType = ImmValue;
1932       DEBUG_WITH_TYPE(
1933           "mach-o-bind",
1934           llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1935                        << "BindType=" << (int)BindType << "\n");
1936       break;
1937     case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1938       Addend = readSLEB128();
1939       if (TableKind == Kind::Lazy)
1940         Malformed = true;
1941       DEBUG_WITH_TYPE(
1942           "mach-o-bind",
1943           llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1944                        << "Addend=" << Addend << "\n");
1945       break;
1946     case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1947       SegmentIndex = ImmValue;
1948       SegmentOffset = readULEB128();
1949       DEBUG_WITH_TYPE(
1950           "mach-o-bind",
1951           llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1952                        << "SegmentIndex=" << SegmentIndex << ", "
1953                        << format("SegmentOffset=0x%06X", SegmentOffset)
1954                        << "\n");
1955       break;
1956     case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1957       SegmentOffset += readULEB128();
1958       DEBUG_WITH_TYPE("mach-o-bind",
1959                       llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1960                                    << format("SegmentOffset=0x%06X",
1961                                              SegmentOffset) << "\n");
1962       break;
1963     case MachO::BIND_OPCODE_DO_BIND:
1964       AdvanceAmount = PointerSize;
1965       RemainingLoopCount = 0;
1966       DEBUG_WITH_TYPE("mach-o-bind",
1967                       llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1968                                    << format("SegmentOffset=0x%06X",
1969                                              SegmentOffset) << "\n");
1970       return;
1971      case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1972       AdvanceAmount = readULEB128() + PointerSize;
1973       RemainingLoopCount = 0;
1974       if (TableKind == Kind::Lazy)
1975         Malformed = true;
1976       DEBUG_WITH_TYPE(
1977           "mach-o-bind",
1978           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1979                        << format("SegmentOffset=0x%06X", SegmentOffset)
1980                        << ", AdvanceAmount=" << AdvanceAmount
1981                        << ", RemainingLoopCount=" << RemainingLoopCount
1982                        << "\n");
1983       return;
1984     case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1985       AdvanceAmount = ImmValue * PointerSize + PointerSize;
1986       RemainingLoopCount = 0;
1987       if (TableKind == Kind::Lazy)
1988         Malformed = true;
1989       DEBUG_WITH_TYPE("mach-o-bind",
1990                       llvm::dbgs()
1991                       << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1992                       << format("SegmentOffset=0x%06X",
1993                                              SegmentOffset) << "\n");
1994       return;
1995     case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1996       RemainingLoopCount = readULEB128() - 1;
1997       AdvanceAmount = readULEB128() + PointerSize;
1998       if (TableKind == Kind::Lazy)
1999         Malformed = true;
2000       DEBUG_WITH_TYPE(
2001           "mach-o-bind",
2002           llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
2003                        << format("SegmentOffset=0x%06X", SegmentOffset)
2004                        << ", AdvanceAmount=" << AdvanceAmount
2005                        << ", RemainingLoopCount=" << RemainingLoopCount
2006                        << "\n");
2007       return;
2008     default:
2009       Malformed = true;
2010     }
2011   }
2012 }
2013
2014 uint64_t MachOBindEntry::readULEB128() {
2015   unsigned Count;
2016   uint64_t Result = decodeULEB128(Ptr, &Count);
2017   Ptr += Count;
2018   if (Ptr > Opcodes.end()) {
2019     Ptr = Opcodes.end();
2020     Malformed = true;
2021   }
2022   return Result;
2023 }
2024
2025 int64_t MachOBindEntry::readSLEB128() {
2026   unsigned Count;
2027   int64_t Result = decodeSLEB128(Ptr, &Count);
2028   Ptr += Count;
2029   if (Ptr > Opcodes.end()) {
2030     Ptr = Opcodes.end();
2031     Malformed = true;
2032   }
2033   return Result;
2034 }
2035
2036
2037 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
2038
2039 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
2040
2041 StringRef MachOBindEntry::typeName() const {
2042   switch (BindType) {
2043   case MachO::BIND_TYPE_POINTER:
2044     return "pointer";
2045   case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
2046     return "text abs32";
2047   case MachO::BIND_TYPE_TEXT_PCREL32:
2048     return "text rel32";
2049   }
2050   return "unknown";
2051 }
2052
2053 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
2054
2055 int64_t MachOBindEntry::addend() const { return Addend; }
2056
2057 uint32_t MachOBindEntry::flags() const { return Flags; }
2058
2059 int MachOBindEntry::ordinal() const { return Ordinal; }
2060
2061 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
2062   assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2063   return (Ptr == Other.Ptr) &&
2064          (RemainingLoopCount == Other.RemainingLoopCount) &&
2065          (Done == Other.Done);
2066 }
2067
2068 iterator_range<bind_iterator>
2069 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
2070                            MachOBindEntry::Kind BKind) {
2071   MachOBindEntry Start(Opcodes, is64, BKind);
2072   Start.moveToFirst();
2073
2074   MachOBindEntry Finish(Opcodes, is64, BKind);
2075   Finish.moveToEnd();
2076
2077   return iterator_range<bind_iterator>(bind_iterator(Start),
2078                                        bind_iterator(Finish));
2079 }
2080
2081 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
2082   return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
2083                    MachOBindEntry::Kind::Regular);
2084 }
2085
2086 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
2087   return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
2088                    MachOBindEntry::Kind::Lazy);
2089 }
2090
2091 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
2092   return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
2093                    MachOBindEntry::Kind::Weak);
2094 }
2095
2096 StringRef
2097 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
2098   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
2099   return parseSegmentOrSectionName(Raw.data());
2100 }
2101
2102 ArrayRef<char>
2103 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
2104   const section_base *Base =
2105     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2106   return makeArrayRef(Base->sectname);
2107 }
2108
2109 ArrayRef<char>
2110 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
2111   const section_base *Base =
2112     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2113   return makeArrayRef(Base->segname);
2114 }
2115
2116 bool
2117 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
2118   const {
2119   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
2120     return false;
2121   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
2122 }
2123
2124 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
2125     const MachO::any_relocation_info &RE) const {
2126   if (isLittleEndian())
2127     return RE.r_word1 & 0xffffff;
2128   return RE.r_word1 >> 8;
2129 }
2130
2131 bool MachOObjectFile::getPlainRelocationExternal(
2132     const MachO::any_relocation_info &RE) const {
2133   if (isLittleEndian())
2134     return (RE.r_word1 >> 27) & 1;
2135   return (RE.r_word1 >> 4) & 1;
2136 }
2137
2138 bool MachOObjectFile::getScatteredRelocationScattered(
2139     const MachO::any_relocation_info &RE) const {
2140   return RE.r_word0 >> 31;
2141 }
2142
2143 uint32_t MachOObjectFile::getScatteredRelocationValue(
2144     const MachO::any_relocation_info &RE) const {
2145   return RE.r_word1;
2146 }
2147
2148 uint32_t MachOObjectFile::getScatteredRelocationType(
2149     const MachO::any_relocation_info &RE) const {
2150   return (RE.r_word0 >> 24) & 0xf;
2151 }
2152
2153 unsigned MachOObjectFile::getAnyRelocationAddress(
2154     const MachO::any_relocation_info &RE) const {
2155   if (isRelocationScattered(RE))
2156     return getScatteredRelocationAddress(RE);
2157   return getPlainRelocationAddress(RE);
2158 }
2159
2160 unsigned MachOObjectFile::getAnyRelocationPCRel(
2161     const MachO::any_relocation_info &RE) const {
2162   if (isRelocationScattered(RE))
2163     return getScatteredRelocationPCRel(this, RE);
2164   return getPlainRelocationPCRel(this, RE);
2165 }
2166
2167 unsigned MachOObjectFile::getAnyRelocationLength(
2168     const MachO::any_relocation_info &RE) const {
2169   if (isRelocationScattered(RE))
2170     return getScatteredRelocationLength(RE);
2171   return getPlainRelocationLength(this, RE);
2172 }
2173
2174 unsigned
2175 MachOObjectFile::getAnyRelocationType(
2176                                    const MachO::any_relocation_info &RE) const {
2177   if (isRelocationScattered(RE))
2178     return getScatteredRelocationType(RE);
2179   return getPlainRelocationType(this, RE);
2180 }
2181
2182 SectionRef
2183 MachOObjectFile::getRelocationSection(
2184                                    const MachO::any_relocation_info &RE) const {
2185   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2186     return *section_end();
2187   unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
2188   DataRefImpl DRI;
2189   DRI.d.a = SecNum;
2190   return SectionRef(DRI, this);
2191 }
2192
2193 MachOObjectFile::LoadCommandInfo
2194 MachOObjectFile::getFirstLoadCommandInfo() const {
2195   MachOObjectFile::LoadCommandInfo Load;
2196
2197   unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
2198                                     sizeof(MachO::mach_header);
2199   Load.Ptr = getPtr(this, HeaderSize);
2200   Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
2201   return Load;
2202 }
2203
2204 MachOObjectFile::LoadCommandInfo
2205 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
2206   MachOObjectFile::LoadCommandInfo Next;
2207   Next.Ptr = L.Ptr + L.C.cmdsize;
2208   Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
2209   return Next;
2210 }
2211
2212 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2213   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2214 }
2215
2216 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2217   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2218 }
2219
2220 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2221                                            unsigned Index) const {
2222   const char *Sec = getSectionPtr(this, L, Index);
2223   return getStruct<MachO::section>(this, Sec);
2224 }
2225
2226 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2227                                                 unsigned Index) const {
2228   const char *Sec = getSectionPtr(this, L, Index);
2229   return getStruct<MachO::section_64>(this, Sec);
2230 }
2231
2232 MachO::nlist
2233 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2234   const char *P = reinterpret_cast<const char *>(DRI.p);
2235   return getStruct<MachO::nlist>(this, P);
2236 }
2237
2238 MachO::nlist_64
2239 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2240   const char *P = reinterpret_cast<const char *>(DRI.p);
2241   return getStruct<MachO::nlist_64>(this, P);
2242 }
2243
2244 MachO::linkedit_data_command
2245 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2246   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2247 }
2248
2249 MachO::segment_command
2250 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2251   return getStruct<MachO::segment_command>(this, L.Ptr);
2252 }
2253
2254 MachO::segment_command_64
2255 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2256   return getStruct<MachO::segment_command_64>(this, L.Ptr);
2257 }
2258
2259 MachO::linker_options_command
2260 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
2261   return getStruct<MachO::linker_options_command>(this, L.Ptr);
2262 }
2263
2264 MachO::version_min_command
2265 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2266   return getStruct<MachO::version_min_command>(this, L.Ptr);
2267 }
2268
2269 MachO::dylib_command
2270 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2271   return getStruct<MachO::dylib_command>(this, L.Ptr);
2272 }
2273
2274 MachO::dyld_info_command
2275 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2276   return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2277 }
2278
2279 MachO::dylinker_command
2280 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2281   return getStruct<MachO::dylinker_command>(this, L.Ptr);
2282 }
2283
2284 MachO::uuid_command
2285 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2286   return getStruct<MachO::uuid_command>(this, L.Ptr);
2287 }
2288
2289 MachO::source_version_command
2290 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2291   return getStruct<MachO::source_version_command>(this, L.Ptr);
2292 }
2293
2294 MachO::entry_point_command
2295 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2296   return getStruct<MachO::entry_point_command>(this, L.Ptr);
2297 }
2298
2299
2300 MachO::any_relocation_info
2301 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2302   DataRefImpl Sec;
2303   Sec.d.a = Rel.d.a;
2304   uint32_t Offset;
2305   if (is64Bit()) {
2306     MachO::section_64 Sect = getSection64(Sec);
2307     Offset = Sect.reloff;
2308   } else {
2309     MachO::section Sect = getSection(Sec);
2310     Offset = Sect.reloff;
2311   }
2312
2313   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2314       getPtr(this, Offset)) + Rel.d.b;
2315   return getStruct<MachO::any_relocation_info>(
2316       this, reinterpret_cast<const char *>(P));
2317 }
2318
2319 MachO::data_in_code_entry
2320 MachOObjectFile::getDice(DataRefImpl Rel) const {
2321   const char *P = reinterpret_cast<const char *>(Rel.p);
2322   return getStruct<MachO::data_in_code_entry>(this, P);
2323 }
2324
2325 MachO::mach_header MachOObjectFile::getHeader() const {
2326   return getStruct<MachO::mach_header>(this, getPtr(this, 0));
2327 }
2328
2329 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
2330   return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
2331 }
2332
2333 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2334                                              const MachO::dysymtab_command &DLC,
2335                                              unsigned Index) const {
2336   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2337   return getStruct<uint32_t>(this, getPtr(this, Offset));
2338 }
2339
2340 MachO::data_in_code_entry
2341 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2342                                          unsigned Index) const {
2343   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2344   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2345 }
2346
2347 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2348   if (SymtabLoadCmd)
2349     return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2350
2351   // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2352   MachO::symtab_command Cmd;
2353   Cmd.cmd = MachO::LC_SYMTAB;
2354   Cmd.cmdsize = sizeof(MachO::symtab_command);
2355   Cmd.symoff = 0;
2356   Cmd.nsyms = 0;
2357   Cmd.stroff = 0;
2358   Cmd.strsize = 0;
2359   return Cmd;
2360 }
2361
2362 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2363   if (DysymtabLoadCmd)
2364     return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2365
2366   // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2367   MachO::dysymtab_command Cmd;
2368   Cmd.cmd = MachO::LC_DYSYMTAB;
2369   Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2370   Cmd.ilocalsym = 0;
2371   Cmd.nlocalsym = 0;
2372   Cmd.iextdefsym = 0;
2373   Cmd.nextdefsym = 0;
2374   Cmd.iundefsym = 0;
2375   Cmd.nundefsym = 0;
2376   Cmd.tocoff = 0;
2377   Cmd.ntoc = 0;
2378   Cmd.modtaboff = 0;
2379   Cmd.nmodtab = 0;
2380   Cmd.extrefsymoff = 0;
2381   Cmd.nextrefsyms = 0;
2382   Cmd.indirectsymoff = 0;
2383   Cmd.nindirectsyms = 0;
2384   Cmd.extreloff = 0;
2385   Cmd.nextrel = 0;
2386   Cmd.locreloff = 0;
2387   Cmd.nlocrel = 0;
2388   return Cmd;
2389 }
2390
2391 MachO::linkedit_data_command
2392 MachOObjectFile::getDataInCodeLoadCommand() const {
2393   if (DataInCodeLoadCmd)
2394     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2395
2396   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2397   MachO::linkedit_data_command Cmd;
2398   Cmd.cmd = MachO::LC_DATA_IN_CODE;
2399   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2400   Cmd.dataoff = 0;
2401   Cmd.datasize = 0;
2402   return Cmd;
2403 }
2404
2405 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2406   if (!DyldInfoLoadCmd) 
2407     return ArrayRef<uint8_t>();
2408
2409   MachO::dyld_info_command DyldInfo 
2410                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2411   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2412                                              getPtr(this, DyldInfo.rebase_off));
2413   return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2414 }
2415
2416 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2417   if (!DyldInfoLoadCmd) 
2418     return ArrayRef<uint8_t>();
2419
2420   MachO::dyld_info_command DyldInfo 
2421                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2422   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2423                                                getPtr(this, DyldInfo.bind_off));
2424   return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2425 }
2426
2427 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2428   if (!DyldInfoLoadCmd) 
2429     return ArrayRef<uint8_t>();
2430
2431   MachO::dyld_info_command DyldInfo 
2432                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2433   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2434                                           getPtr(this, DyldInfo.weak_bind_off));
2435   return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2436 }
2437
2438 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2439   if (!DyldInfoLoadCmd) 
2440     return ArrayRef<uint8_t>();
2441
2442   MachO::dyld_info_command DyldInfo 
2443                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2444   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2445                                           getPtr(this, DyldInfo.lazy_bind_off));
2446   return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2447 }
2448
2449 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2450   if (!DyldInfoLoadCmd) 
2451     return ArrayRef<uint8_t>();
2452
2453   MachO::dyld_info_command DyldInfo 
2454                    = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2455   const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2456                                              getPtr(this, DyldInfo.export_off));
2457   return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2458 }
2459
2460 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2461   if (!UuidLoadCmd)
2462     return ArrayRef<uint8_t>();
2463   // Returning a pointer is fine as uuid doesn't need endian swapping.
2464   const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2465   return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2466 }
2467
2468 StringRef MachOObjectFile::getStringTableData() const {
2469   MachO::symtab_command S = getSymtabLoadCommand();
2470   return getData().substr(S.stroff, S.strsize);
2471 }
2472
2473 bool MachOObjectFile::is64Bit() const {
2474   return getType() == getMachOType(false, true) ||
2475     getType() == getMachOType(true, true);
2476 }
2477
2478 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2479                                    SmallVectorImpl<uint64_t> &Out) const {
2480   DataExtractor extractor(ObjectFile::getData(), true, 0);
2481
2482   uint32_t offset = Index;
2483   uint64_t data = 0;
2484   while (uint64_t delta = extractor.getULEB128(&offset)) {
2485     data += delta;
2486     Out.push_back(data);
2487   }
2488 }
2489
2490 bool MachOObjectFile::isRelocatableObject() const {
2491   return getHeader().filetype == MachO::MH_OBJECT;
2492 }
2493
2494 ErrorOr<std::unique_ptr<MachOObjectFile>>
2495 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2496   StringRef Magic = Buffer.getBuffer().slice(0, 4);
2497   std::error_code EC;
2498   std::unique_ptr<MachOObjectFile> Ret;
2499   if (Magic == "\xFE\xED\xFA\xCE")
2500     Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2501   else if (Magic == "\xCE\xFA\xED\xFE")
2502     Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2503   else if (Magic == "\xFE\xED\xFA\xCF")
2504     Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2505   else if (Magic == "\xCF\xFA\xED\xFE")
2506     Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2507   else
2508     return object_error::parse_failed;
2509
2510   if (EC)
2511     return EC;
2512   return std::move(Ret);
2513 }
2514