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