xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision 676223170f929b95d3860a2751ac670f7a7e9236)
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 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1414   DataRefImpl DRI;
1415   DRI.d.a = Index;
1416   return section_rel_begin(DRI);
1417 }
1418 
1419 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1420   DataRefImpl DRI;
1421   DRI.d.a = Index;
1422   return section_rel_end(DRI);
1423 }
1424 
1425 dice_iterator MachOObjectFile::begin_dices() const {
1426   DataRefImpl DRI;
1427   if (!DataInCodeLoadCmd)
1428     return dice_iterator(DiceRef(DRI, this));
1429 
1430   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1431   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1432   return dice_iterator(DiceRef(DRI, this));
1433 }
1434 
1435 dice_iterator MachOObjectFile::end_dices() const {
1436   DataRefImpl DRI;
1437   if (!DataInCodeLoadCmd)
1438     return dice_iterator(DiceRef(DRI, this));
1439 
1440   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1441   unsigned Offset = DicLC.dataoff + DicLC.datasize;
1442   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1443   return dice_iterator(DiceRef(DRI, this));
1444 }
1445 
1446 StringRef
1447 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1448   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1449   return parseSegmentOrSectionName(Raw.data());
1450 }
1451 
1452 ArrayRef<char>
1453 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1454   const section_base *Base =
1455     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1456   return ArrayRef<char>(Base->sectname);
1457 }
1458 
1459 ArrayRef<char>
1460 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1461   const section_base *Base =
1462     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1463   return ArrayRef<char>(Base->segname);
1464 }
1465 
1466 bool
1467 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1468   const {
1469   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1470     return false;
1471   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1472 }
1473 
1474 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1475     const MachO::any_relocation_info &RE) const {
1476   if (isLittleEndian())
1477     return RE.r_word1 & 0xffffff;
1478   return RE.r_word1 >> 8;
1479 }
1480 
1481 bool MachOObjectFile::getPlainRelocationExternal(
1482     const MachO::any_relocation_info &RE) const {
1483   if (isLittleEndian())
1484     return (RE.r_word1 >> 27) & 1;
1485   return (RE.r_word1 >> 4) & 1;
1486 }
1487 
1488 bool MachOObjectFile::getScatteredRelocationScattered(
1489     const MachO::any_relocation_info &RE) const {
1490   return RE.r_word0 >> 31;
1491 }
1492 
1493 uint32_t MachOObjectFile::getScatteredRelocationValue(
1494     const MachO::any_relocation_info &RE) const {
1495   return RE.r_word1;
1496 }
1497 
1498 unsigned MachOObjectFile::getAnyRelocationAddress(
1499     const MachO::any_relocation_info &RE) const {
1500   if (isRelocationScattered(RE))
1501     return getScatteredRelocationAddress(RE);
1502   return getPlainRelocationAddress(RE);
1503 }
1504 
1505 unsigned MachOObjectFile::getAnyRelocationPCRel(
1506     const MachO::any_relocation_info &RE) const {
1507   if (isRelocationScattered(RE))
1508     return getScatteredRelocationPCRel(this, RE);
1509   return getPlainRelocationPCRel(this, RE);
1510 }
1511 
1512 unsigned MachOObjectFile::getAnyRelocationLength(
1513     const MachO::any_relocation_info &RE) const {
1514   if (isRelocationScattered(RE))
1515     return getScatteredRelocationLength(RE);
1516   return getPlainRelocationLength(this, RE);
1517 }
1518 
1519 unsigned
1520 MachOObjectFile::getAnyRelocationType(
1521                                    const MachO::any_relocation_info &RE) const {
1522   if (isRelocationScattered(RE))
1523     return getScatteredRelocationType(RE);
1524   return getPlainRelocationType(this, RE);
1525 }
1526 
1527 SectionRef
1528 MachOObjectFile::getRelocationSection(
1529                                    const MachO::any_relocation_info &RE) const {
1530   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1531     return *section_end();
1532   unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1533   DataRefImpl DRI;
1534   DRI.d.a = SecNum;
1535   return SectionRef(DRI, this);
1536 }
1537 
1538 MachOObjectFile::LoadCommandInfo
1539 MachOObjectFile::getFirstLoadCommandInfo() const {
1540   MachOObjectFile::LoadCommandInfo Load;
1541 
1542   unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1543                                     sizeof(MachO::mach_header);
1544   Load.Ptr = getPtr(this, HeaderSize);
1545   Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1546   return Load;
1547 }
1548 
1549 MachOObjectFile::LoadCommandInfo
1550 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1551   MachOObjectFile::LoadCommandInfo Next;
1552   Next.Ptr = L.Ptr + L.C.cmdsize;
1553   Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1554   return Next;
1555 }
1556 
1557 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1558   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1559 }
1560 
1561 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1562   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1563 }
1564 
1565 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1566                                            unsigned Index) const {
1567   const char *Sec = getSectionPtr(this, L, Index);
1568   return getStruct<MachO::section>(this, Sec);
1569 }
1570 
1571 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1572                                                 unsigned Index) const {
1573   const char *Sec = getSectionPtr(this, L, Index);
1574   return getStruct<MachO::section_64>(this, Sec);
1575 }
1576 
1577 MachO::nlist
1578 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1579   const char *P = reinterpret_cast<const char *>(DRI.p);
1580   return getStruct<MachO::nlist>(this, P);
1581 }
1582 
1583 MachO::nlist_64
1584 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1585   const char *P = reinterpret_cast<const char *>(DRI.p);
1586   return getStruct<MachO::nlist_64>(this, P);
1587 }
1588 
1589 MachO::linkedit_data_command
1590 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1591   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1592 }
1593 
1594 MachO::segment_command
1595 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1596   return getStruct<MachO::segment_command>(this, L.Ptr);
1597 }
1598 
1599 MachO::segment_command_64
1600 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1601   return getStruct<MachO::segment_command_64>(this, L.Ptr);
1602 }
1603 
1604 MachO::linker_options_command
1605 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1606   return getStruct<MachO::linker_options_command>(this, L.Ptr);
1607 }
1608 
1609 MachO::version_min_command
1610 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1611   return getStruct<MachO::version_min_command>(this, L.Ptr);
1612 }
1613 
1614 MachO::dylib_command
1615 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1616   return getStruct<MachO::dylib_command>(this, L.Ptr);
1617 }
1618 
1619 
1620 MachO::any_relocation_info
1621 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1622   DataRefImpl Sec;
1623   Sec.d.a = Rel.d.a;
1624   uint32_t Offset;
1625   if (is64Bit()) {
1626     MachO::section_64 Sect = getSection64(Sec);
1627     Offset = Sect.reloff;
1628   } else {
1629     MachO::section Sect = getSection(Sec);
1630     Offset = Sect.reloff;
1631   }
1632 
1633   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1634       getPtr(this, Offset)) + Rel.d.b;
1635   return getStruct<MachO::any_relocation_info>(
1636       this, reinterpret_cast<const char *>(P));
1637 }
1638 
1639 MachO::data_in_code_entry
1640 MachOObjectFile::getDice(DataRefImpl Rel) const {
1641   const char *P = reinterpret_cast<const char *>(Rel.p);
1642   return getStruct<MachO::data_in_code_entry>(this, P);
1643 }
1644 
1645 MachO::mach_header MachOObjectFile::getHeader() const {
1646   return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1647 }
1648 
1649 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1650   return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1651 }
1652 
1653 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1654                                              const MachO::dysymtab_command &DLC,
1655                                              unsigned Index) const {
1656   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1657   return getStruct<uint32_t>(this, getPtr(this, Offset));
1658 }
1659 
1660 MachO::data_in_code_entry
1661 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1662                                          unsigned Index) const {
1663   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1664   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1665 }
1666 
1667 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1668   return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1669 }
1670 
1671 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1672   return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1673 }
1674 
1675 MachO::linkedit_data_command
1676 MachOObjectFile::getDataInCodeLoadCommand() const {
1677   if (DataInCodeLoadCmd)
1678     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1679 
1680   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1681   MachO::linkedit_data_command Cmd;
1682   Cmd.cmd = MachO::LC_DATA_IN_CODE;
1683   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1684   Cmd.dataoff = 0;
1685   Cmd.datasize = 0;
1686   return Cmd;
1687 }
1688 
1689 StringRef MachOObjectFile::getStringTableData() const {
1690   MachO::symtab_command S = getSymtabLoadCommand();
1691   return getData().substr(S.stroff, S.strsize);
1692 }
1693 
1694 bool MachOObjectFile::is64Bit() const {
1695   return getType() == getMachOType(false, true) ||
1696     getType() == getMachOType(true, true);
1697 }
1698 
1699 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1700                                    SmallVectorImpl<uint64_t> &Out) const {
1701   DataExtractor extractor(ObjectFile::getData(), true, 0);
1702 
1703   uint32_t offset = Index;
1704   uint64_t data = 0;
1705   while (uint64_t delta = extractor.getULEB128(&offset)) {
1706     data += delta;
1707     Out.push_back(data);
1708   }
1709 }
1710 
1711 ErrorOr<std::unique_ptr<MachOObjectFile>>
1712 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1713   StringRef Magic = Buffer->getBuffer().slice(0, 4);
1714   std::error_code EC;
1715   std::unique_ptr<MachOObjectFile> Ret;
1716   if (Magic == "\xFE\xED\xFA\xCE")
1717     Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1718   else if (Magic == "\xCE\xFA\xED\xFE")
1719     Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1720   else if (Magic == "\xFE\xED\xFA\xCF")
1721     Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1722   else if (Magic == "\xCF\xFA\xED\xFE")
1723     Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1724   else
1725     return object_error::parse_failed;
1726 
1727   if (EC)
1728     return EC;
1729   return std::move(Ret);
1730 }
1731 
1732