[Reassociation] Add support for reassociation with unsafe algebra.
[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 //
1013 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1014 // guess on what the short name is.  Then name is returned as a substring of the
1015 // StringRef Name passed in.  The name of the dynamic library is recognized as
1016 // a framework if it has one of the two following forms:
1017 //      Foo.framework/Versions/A/Foo
1018 //      Foo.framework/Foo
1019 // Where A and Foo can be any string.  And may contain a trailing suffix
1020 // starting with an underbar.  If the Name is recognized as a framework then
1021 // isFramework is set to true else it is set to false.  If the Name has a
1022 // suffix then Suffix is set to the substring in Name that contains the suffix
1023 // else it is set to a NULL StringRef.
1024 //
1025 // The Name of the dynamic library is recognized as a library name if it has
1026 // one of the two following forms:
1027 //      libFoo.A.dylib
1028 //      libFoo.dylib
1029 // The library may have a suffix trailing the name Foo of the form:
1030 //      libFoo_profile.A.dylib
1031 //      libFoo_profile.dylib
1032 //
1033 // The Name of the dynamic library is also recognized as a library name if it
1034 // has the following form:
1035 //      Foo.qtx
1036 //
1037 // If the Name of the dynamic library is none of the forms above then a NULL
1038 // StringRef is returned.
1039 //
1040 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1041                                                  bool &isFramework,
1042                                                  StringRef &Suffix) {
1043   StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1044   size_t a, b, c, d, Idx;
1045
1046   isFramework = false;
1047   Suffix = StringRef();
1048
1049   // Pull off the last component and make Foo point to it
1050   a = Name.rfind('/');
1051   if (a == Name.npos || a == 0)
1052     goto guess_library;
1053   Foo = Name.slice(a+1, Name.npos);
1054
1055   // Look for a suffix starting with a '_'
1056   Idx = Foo.rfind('_');
1057   if (Idx != Foo.npos && Foo.size() >= 2) {
1058     Suffix = Foo.slice(Idx, Foo.npos);
1059     Foo = Foo.slice(0, Idx);
1060   }
1061
1062   // First look for the form Foo.framework/Foo
1063   b = Name.rfind('/', a);
1064   if (b == Name.npos)
1065     Idx = 0;
1066   else
1067     Idx = b+1;
1068   F = Name.slice(Idx, Idx + Foo.size());
1069   DotFramework = Name.slice(Idx + Foo.size(),
1070                             Idx + Foo.size() + sizeof(".framework/")-1);
1071   if (F == Foo && DotFramework == ".framework/") {
1072     isFramework = true;
1073     return Foo;
1074   }
1075
1076   // Next look for the form Foo.framework/Versions/A/Foo
1077   if (b == Name.npos)
1078     goto guess_library;
1079   c =  Name.rfind('/', b);
1080   if (c == Name.npos || c == 0)
1081     goto guess_library;
1082   V = Name.slice(c+1, Name.npos);
1083   if (!V.startswith("Versions/"))
1084     goto guess_library;
1085   d =  Name.rfind('/', c);
1086   if (d == Name.npos)
1087     Idx = 0;
1088   else
1089     Idx = d+1;
1090   F = Name.slice(Idx, Idx + Foo.size());
1091   DotFramework = Name.slice(Idx + Foo.size(),
1092                             Idx + Foo.size() + sizeof(".framework/")-1);
1093   if (F == Foo && DotFramework == ".framework/") {
1094     isFramework = true;
1095     return Foo;
1096   }
1097
1098 guess_library:
1099   // pull off the suffix after the "." and make a point to it
1100   a = Name.rfind('.');
1101   if (a == Name.npos || a == 0)
1102     return StringRef();
1103   Dylib = Name.slice(a, Name.npos);
1104   if (Dylib != ".dylib")
1105     goto guess_qtx;
1106
1107   // First pull off the version letter for the form Foo.A.dylib if any.
1108   if (a >= 3) {
1109     Dot = Name.slice(a-2, a-1);
1110     if (Dot == ".")
1111       a = a - 2;
1112   }
1113
1114   b = Name.rfind('/', a);
1115   if (b == Name.npos)
1116     b = 0;
1117   else
1118     b = b+1;
1119   // ignore any suffix after an underbar like Foo_profile.A.dylib
1120   Idx = Name.find('_', b);
1121   if (Idx != Name.npos && Idx != b) {
1122     Lib = Name.slice(b, Idx);
1123     Suffix = Name.slice(Idx, a);
1124   }
1125   else
1126     Lib = Name.slice(b, a);
1127   // There are incorrect library names of the form:
1128   // libATS.A_profile.dylib so check for these.
1129   if (Lib.size() >= 3) {
1130     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1131     if (Dot == ".")
1132       Lib = Lib.slice(0, Lib.size()-2);
1133   }
1134   return Lib;
1135
1136 guess_qtx:
1137   Qtx = Name.slice(a, Name.npos);
1138   if (Qtx != ".qtx")
1139     return StringRef();
1140   b = Name.rfind('/', a);
1141   if (b == Name.npos)
1142     Lib = Name.slice(0, a);
1143   else
1144     Lib = Name.slice(b+1, a);
1145   // There are library names of the form: QT.A.qtx so check for these.
1146   if (Lib.size() >= 3) {
1147     Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1148     if (Dot == ".")
1149       Lib = Lib.slice(0, Lib.size()-2);
1150   }
1151   return Lib;
1152 }
1153
1154 // getLibraryShortNameByIndex() is used to get the short name of the library
1155 // for an undefined symbol in a linked Mach-O binary that was linked with the
1156 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1157 // It is passed the index (0 - based) of the library as translated from
1158 // GET_LIBRARY_ORDINAL (1 - based).
1159 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1160                                                             StringRef &Res) {
1161   if (Index >= Libraries.size())
1162     return object_error::parse_failed;
1163
1164   MachO::dylib_command D =
1165     getStruct<MachO::dylib_command>(this, Libraries[Index]);
1166   if (D.dylib.name >= D.cmdsize)
1167     return object_error::parse_failed;
1168
1169   // If the cache of LibrariesShortNames is not built up do that first for
1170   // all the Libraries.
1171   if (LibrariesShortNames.size() == 0) {
1172     for (unsigned i = 0; i < Libraries.size(); i++) {
1173       MachO::dylib_command D =
1174         getStruct<MachO::dylib_command>(this, Libraries[i]);
1175       if (D.dylib.name >= D.cmdsize) {
1176         LibrariesShortNames.push_back(StringRef());
1177         continue;
1178       }
1179       const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1180       StringRef Name = StringRef(P);
1181       StringRef Suffix;
1182       bool isFramework;
1183       StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1184       if (shortName == StringRef())
1185         LibrariesShortNames.push_back(Name);
1186       else
1187         LibrariesShortNames.push_back(shortName);
1188     }
1189   }
1190
1191   Res = LibrariesShortNames[Index];
1192   return object_error::success;
1193 }
1194
1195 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1196   return getSymbolByIndex(0);
1197 }
1198
1199 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1200   DataRefImpl DRI;
1201   if (!SymtabLoadCmd)
1202     return basic_symbol_iterator(SymbolRef(DRI, this));
1203
1204   MachO::symtab_command Symtab = getSymtabLoadCommand();
1205   unsigned SymbolTableEntrySize = is64Bit() ?
1206     sizeof(MachO::nlist_64) :
1207     sizeof(MachO::nlist);
1208   unsigned Offset = Symtab.symoff +
1209     Symtab.nsyms * SymbolTableEntrySize;
1210   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1211   return basic_symbol_iterator(SymbolRef(DRI, this));
1212 }
1213
1214 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1215   DataRefImpl DRI;
1216   if (!SymtabLoadCmd)
1217     return basic_symbol_iterator(SymbolRef(DRI, this));
1218
1219   MachO::symtab_command Symtab = getSymtabLoadCommand();
1220   assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1221   unsigned SymbolTableEntrySize =
1222     is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1223   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1224   DRI.p += Index * SymbolTableEntrySize;
1225   return basic_symbol_iterator(SymbolRef(DRI, this));
1226 }
1227
1228 section_iterator MachOObjectFile::section_begin() const {
1229   DataRefImpl DRI;
1230   return section_iterator(SectionRef(DRI, this));
1231 }
1232
1233 section_iterator MachOObjectFile::section_end() const {
1234   DataRefImpl DRI;
1235   DRI.d.a = Sections.size();
1236   return section_iterator(SectionRef(DRI, this));
1237 }
1238
1239 uint8_t MachOObjectFile::getBytesInAddress() const {
1240   return is64Bit() ? 8 : 4;
1241 }
1242
1243 StringRef MachOObjectFile::getFileFormatName() const {
1244   unsigned CPUType = getCPUType(this);
1245   if (!is64Bit()) {
1246     switch (CPUType) {
1247     case llvm::MachO::CPU_TYPE_I386:
1248       return "Mach-O 32-bit i386";
1249     case llvm::MachO::CPU_TYPE_ARM:
1250       return "Mach-O arm";
1251     case llvm::MachO::CPU_TYPE_POWERPC:
1252       return "Mach-O 32-bit ppc";
1253     default:
1254       assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1255              "64-bit object file when we're not 64-bit?");
1256       return "Mach-O 32-bit unknown";
1257     }
1258   }
1259
1260   // Make sure the cpu type has the correct mask.
1261   assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1262          == llvm::MachO::CPU_ARCH_ABI64 &&
1263          "32-bit object file when we're 64-bit?");
1264
1265   switch (CPUType) {
1266   case llvm::MachO::CPU_TYPE_X86_64:
1267     return "Mach-O 64-bit x86-64";
1268   case llvm::MachO::CPU_TYPE_ARM64:
1269     return "Mach-O arm64";
1270   case llvm::MachO::CPU_TYPE_POWERPC64:
1271     return "Mach-O 64-bit ppc64";
1272   default:
1273     return "Mach-O 64-bit unknown";
1274   }
1275 }
1276
1277 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1278   switch (CPUType) {
1279   case llvm::MachO::CPU_TYPE_I386:
1280     return Triple::x86;
1281   case llvm::MachO::CPU_TYPE_X86_64:
1282     return Triple::x86_64;
1283   case llvm::MachO::CPU_TYPE_ARM:
1284     return Triple::arm;
1285   case llvm::MachO::CPU_TYPE_ARM64:
1286     return Triple::aarch64;
1287   case llvm::MachO::CPU_TYPE_POWERPC:
1288     return Triple::ppc;
1289   case llvm::MachO::CPU_TYPE_POWERPC64:
1290     return Triple::ppc64;
1291   default:
1292     return Triple::UnknownArch;
1293   }
1294 }
1295
1296 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
1297   switch (CPUType) {
1298   case MachO::CPU_TYPE_I386:
1299     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1300     case MachO::CPU_SUBTYPE_I386_ALL:
1301       return Triple("i386-apple-darwin");
1302     default:
1303       return Triple();
1304     }
1305   case MachO::CPU_TYPE_X86_64:
1306     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1307     case MachO::CPU_SUBTYPE_X86_64_ALL:
1308       return Triple("x86_64-apple-darwin");
1309     case MachO::CPU_SUBTYPE_X86_64_H:
1310       return Triple("x86_64h-apple-darwin");
1311     default:
1312       return Triple();
1313     }
1314   case MachO::CPU_TYPE_ARM:
1315     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1316     case MachO::CPU_SUBTYPE_ARM_V4T:
1317       return Triple("armv4t-apple-darwin");
1318     case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1319       return Triple("armv5e-apple-darwin");
1320     case MachO::CPU_SUBTYPE_ARM_XSCALE:
1321       return Triple("xscale-apple-darwin");
1322     case MachO::CPU_SUBTYPE_ARM_V6:
1323       return Triple("armv6-apple-darwin");
1324     case MachO::CPU_SUBTYPE_ARM_V6M:
1325       return Triple("armv6m-apple-darwin");
1326     case MachO::CPU_SUBTYPE_ARM_V7:
1327       return Triple("armv7-apple-darwin");
1328     case MachO::CPU_SUBTYPE_ARM_V7EM:
1329       return Triple("armv7em-apple-darwin");
1330     case MachO::CPU_SUBTYPE_ARM_V7K:
1331       return Triple("armv7k-apple-darwin");
1332     case MachO::CPU_SUBTYPE_ARM_V7M:
1333       return Triple("armv7m-apple-darwin");
1334     case MachO::CPU_SUBTYPE_ARM_V7S:
1335       return Triple("armv7s-apple-darwin");
1336     default:
1337       return Triple();
1338     }
1339   case MachO::CPU_TYPE_ARM64:
1340     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1341     case MachO::CPU_SUBTYPE_ARM64_ALL:
1342       return Triple("arm64-apple-darwin");
1343     default:
1344       return Triple();
1345     }
1346   case MachO::CPU_TYPE_POWERPC:
1347     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1348     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1349       return Triple("ppc-apple-darwin");
1350     default:
1351       return Triple();
1352     }
1353   case MachO::CPU_TYPE_POWERPC64:
1354     switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1355     case MachO::CPU_SUBTYPE_POWERPC_ALL:
1356       return Triple("ppc64-apple-darwin");
1357     default:
1358       return Triple();
1359     }
1360   default:
1361     return Triple();
1362   }
1363 }
1364
1365 Triple MachOObjectFile::getHostArch() {
1366   return Triple(sys::getDefaultTargetTriple());
1367 }
1368
1369 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1370   return StringSwitch<bool>(ArchFlag)
1371       .Case("i386", true)
1372       .Case("x86_64", true)
1373       .Case("x86_64h", true)
1374       .Case("armv4t", true)
1375       .Case("arm", true)
1376       .Case("armv5e", true)
1377       .Case("armv6", true)
1378       .Case("armv6m", true)
1379       .Case("armv7em", true)
1380       .Case("armv7k", true)
1381       .Case("armv7m", true)
1382       .Case("armv7s", true)
1383       .Case("arm64", true)
1384       .Case("ppc", true)
1385       .Case("ppc64", true)
1386       .Default(false);
1387 }
1388
1389 unsigned MachOObjectFile::getArch() const {
1390   return getArch(getCPUType(this));
1391 }
1392
1393 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1394   DataRefImpl DRI;
1395   DRI.d.a = Index;
1396   return section_rel_begin(DRI);
1397 }
1398
1399 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1400   DataRefImpl DRI;
1401   DRI.d.a = Index;
1402   return section_rel_end(DRI);
1403 }
1404
1405 dice_iterator MachOObjectFile::begin_dices() const {
1406   DataRefImpl DRI;
1407   if (!DataInCodeLoadCmd)
1408     return dice_iterator(DiceRef(DRI, this));
1409
1410   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1411   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1412   return dice_iterator(DiceRef(DRI, this));
1413 }
1414
1415 dice_iterator MachOObjectFile::end_dices() const {
1416   DataRefImpl DRI;
1417   if (!DataInCodeLoadCmd)
1418     return dice_iterator(DiceRef(DRI, this));
1419
1420   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1421   unsigned Offset = DicLC.dataoff + DicLC.datasize;
1422   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1423   return dice_iterator(DiceRef(DRI, this));
1424 }
1425
1426 StringRef
1427 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1428   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1429   return parseSegmentOrSectionName(Raw.data());
1430 }
1431
1432 ArrayRef<char>
1433 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1434   const section_base *Base =
1435     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1436   return ArrayRef<char>(Base->sectname);
1437 }
1438
1439 ArrayRef<char>
1440 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1441   const section_base *Base =
1442     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1443   return ArrayRef<char>(Base->segname);
1444 }
1445
1446 bool
1447 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1448   const {
1449   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1450     return false;
1451   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1452 }
1453
1454 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1455     const MachO::any_relocation_info &RE) const {
1456   if (isLittleEndian())
1457     return RE.r_word1 & 0xffffff;
1458   return RE.r_word1 >> 8;
1459 }
1460
1461 bool MachOObjectFile::getPlainRelocationExternal(
1462     const MachO::any_relocation_info &RE) const {
1463   if (isLittleEndian())
1464     return (RE.r_word1 >> 27) & 1;
1465   return (RE.r_word1 >> 4) & 1;
1466 }
1467
1468 bool MachOObjectFile::getScatteredRelocationScattered(
1469     const MachO::any_relocation_info &RE) const {
1470   return RE.r_word0 >> 31;
1471 }
1472
1473 uint32_t MachOObjectFile::getScatteredRelocationValue(
1474     const MachO::any_relocation_info &RE) const {
1475   return RE.r_word1;
1476 }
1477
1478 unsigned MachOObjectFile::getAnyRelocationAddress(
1479     const MachO::any_relocation_info &RE) const {
1480   if (isRelocationScattered(RE))
1481     return getScatteredRelocationAddress(RE);
1482   return getPlainRelocationAddress(RE);
1483 }
1484
1485 unsigned MachOObjectFile::getAnyRelocationPCRel(
1486     const MachO::any_relocation_info &RE) const {
1487   if (isRelocationScattered(RE))
1488     return getScatteredRelocationPCRel(this, RE);
1489   return getPlainRelocationPCRel(this, RE);
1490 }
1491
1492 unsigned MachOObjectFile::getAnyRelocationLength(
1493     const MachO::any_relocation_info &RE) const {
1494   if (isRelocationScattered(RE))
1495     return getScatteredRelocationLength(RE);
1496   return getPlainRelocationLength(this, RE);
1497 }
1498
1499 unsigned
1500 MachOObjectFile::getAnyRelocationType(
1501                                    const MachO::any_relocation_info &RE) const {
1502   if (isRelocationScattered(RE))
1503     return getScatteredRelocationType(RE);
1504   return getPlainRelocationType(this, RE);
1505 }
1506
1507 SectionRef
1508 MachOObjectFile::getRelocationSection(
1509                                    const MachO::any_relocation_info &RE) const {
1510   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1511     return *section_end();
1512   unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1513   DataRefImpl DRI;
1514   DRI.d.a = SecNum;
1515   return SectionRef(DRI, this);
1516 }
1517
1518 MachOObjectFile::LoadCommandInfo
1519 MachOObjectFile::getFirstLoadCommandInfo() const {
1520   MachOObjectFile::LoadCommandInfo Load;
1521
1522   unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1523                                     sizeof(MachO::mach_header);
1524   Load.Ptr = getPtr(this, HeaderSize);
1525   Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1526   return Load;
1527 }
1528
1529 MachOObjectFile::LoadCommandInfo
1530 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1531   MachOObjectFile::LoadCommandInfo Next;
1532   Next.Ptr = L.Ptr + L.C.cmdsize;
1533   Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1534   return Next;
1535 }
1536
1537 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1538   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1539 }
1540
1541 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1542   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1543 }
1544
1545 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1546                                            unsigned Index) const {
1547   const char *Sec = getSectionPtr(this, L, Index);
1548   return getStruct<MachO::section>(this, Sec);
1549 }
1550
1551 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1552                                                 unsigned Index) const {
1553   const char *Sec = getSectionPtr(this, L, Index);
1554   return getStruct<MachO::section_64>(this, Sec);
1555 }
1556
1557 MachO::nlist
1558 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1559   const char *P = reinterpret_cast<const char *>(DRI.p);
1560   return getStruct<MachO::nlist>(this, P);
1561 }
1562
1563 MachO::nlist_64
1564 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1565   const char *P = reinterpret_cast<const char *>(DRI.p);
1566   return getStruct<MachO::nlist_64>(this, P);
1567 }
1568
1569 MachO::linkedit_data_command
1570 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1571   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1572 }
1573
1574 MachO::segment_command
1575 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1576   return getStruct<MachO::segment_command>(this, L.Ptr);
1577 }
1578
1579 MachO::segment_command_64
1580 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1581   return getStruct<MachO::segment_command_64>(this, L.Ptr);
1582 }
1583
1584 MachO::linker_options_command
1585 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1586   return getStruct<MachO::linker_options_command>(this, L.Ptr);
1587 }
1588
1589 MachO::version_min_command
1590 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1591   return getStruct<MachO::version_min_command>(this, L.Ptr);
1592 }
1593
1594 MachO::dylib_command
1595 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1596   return getStruct<MachO::dylib_command>(this, L.Ptr);
1597 }
1598
1599
1600 MachO::any_relocation_info
1601 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1602   DataRefImpl Sec;
1603   Sec.d.a = Rel.d.a;
1604   uint32_t Offset;
1605   if (is64Bit()) {
1606     MachO::section_64 Sect = getSection64(Sec);
1607     Offset = Sect.reloff;
1608   } else {
1609     MachO::section Sect = getSection(Sec);
1610     Offset = Sect.reloff;
1611   }
1612
1613   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1614       getPtr(this, Offset)) + Rel.d.b;
1615   return getStruct<MachO::any_relocation_info>(
1616       this, reinterpret_cast<const char *>(P));
1617 }
1618
1619 MachO::data_in_code_entry
1620 MachOObjectFile::getDice(DataRefImpl Rel) const {
1621   const char *P = reinterpret_cast<const char *>(Rel.p);
1622   return getStruct<MachO::data_in_code_entry>(this, P);
1623 }
1624
1625 MachO::mach_header MachOObjectFile::getHeader() const {
1626   return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1627 }
1628
1629 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1630   return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1631 }
1632
1633 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1634                                              const MachO::dysymtab_command &DLC,
1635                                              unsigned Index) const {
1636   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1637   return getStruct<uint32_t>(this, getPtr(this, Offset));
1638 }
1639
1640 MachO::data_in_code_entry
1641 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1642                                          unsigned Index) const {
1643   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1644   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1645 }
1646
1647 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1648   return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1649 }
1650
1651 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1652   return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1653 }
1654
1655 MachO::linkedit_data_command
1656 MachOObjectFile::getDataInCodeLoadCommand() const {
1657   if (DataInCodeLoadCmd)
1658     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1659
1660   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1661   MachO::linkedit_data_command Cmd;
1662   Cmd.cmd = MachO::LC_DATA_IN_CODE;
1663   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1664   Cmd.dataoff = 0;
1665   Cmd.datasize = 0;
1666   return Cmd;
1667 }
1668
1669 StringRef MachOObjectFile::getStringTableData() const {
1670   MachO::symtab_command S = getSymtabLoadCommand();
1671   return getData().substr(S.stroff, S.strsize);
1672 }
1673
1674 bool MachOObjectFile::is64Bit() const {
1675   return getType() == getMachOType(false, true) ||
1676     getType() == getMachOType(true, true);
1677 }
1678
1679 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1680                                    SmallVectorImpl<uint64_t> &Out) const {
1681   DataExtractor extractor(ObjectFile::getData(), true, 0);
1682
1683   uint32_t offset = Index;
1684   uint64_t data = 0;
1685   while (uint64_t delta = extractor.getULEB128(&offset)) {
1686     data += delta;
1687     Out.push_back(data);
1688   }
1689 }
1690
1691 ErrorOr<std::unique_ptr<MachOObjectFile>>
1692 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1693   StringRef Magic = Buffer->getBuffer().slice(0, 4);
1694   std::error_code EC;
1695   std::unique_ptr<MachOObjectFile> Ret;
1696   if (Magic == "\xFE\xED\xFA\xCE")
1697     Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1698   else if (Magic == "\xCE\xFA\xED\xFE")
1699     Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1700   else if (Magic == "\xFE\xED\xFA\xCF")
1701     Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1702   else if (Magic == "\xCF\xFA\xED\xFE")
1703     Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1704   else
1705     return object_error::parse_failed;
1706
1707   if (EC)
1708     return EC;
1709   return std::move(Ret);
1710 }
1711