xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision eb8b211e61bb4f481e47c64c02250efaa56f1b4b)
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/Triple.h"
17 #include "llvm/Object/MachOFormat.h"
18 #include "llvm/Support/DataExtractor.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include <cctype>
22 #include <cstring>
23 #include <limits>
24 
25 using namespace llvm;
26 using namespace object;
27 
28 namespace llvm {
29 namespace object {
30 
31 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool Is64bits,
32                                  error_code &ec)
33     : ObjectFile(getMachOType(true, Is64bits), Object) {
34   DataRefImpl DRI;
35   moveToNextSection(DRI);
36   uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
37   while (DRI.d.a < LoadCommandCount) {
38     Sections.push_back(DRI);
39     DRI.d.b++;
40     moveToNextSection(DRI);
41   }
42 }
43 
44 bool MachOObjectFile::is64Bit() const {
45   unsigned int Type = getType();
46   return Type == ID_MachO64L || Type == ID_MachO64B;
47 }
48 
49 const MachOFormat::LoadCommand *
50 MachOObjectFile::getLoadCommandInfo(unsigned Index) const {
51   uint64_t Offset;
52   uint64_t NewOffset = getHeaderSize();
53   const MachOFormat::LoadCommand *Load;
54   unsigned I = 0;
55   do {
56     Offset = NewOffset;
57     StringRef Data = getData(Offset, sizeof(MachOFormat::LoadCommand));
58     Load = reinterpret_cast<const MachOFormat::LoadCommand*>(Data.data());
59     NewOffset = Offset + Load->Size;
60     ++I;
61   } while (I != Index + 1);
62 
63   return Load;
64 }
65 
66 void MachOObjectFile::ReadULEB128s(uint64_t Index,
67                                    SmallVectorImpl<uint64_t> &Out) const {
68   DataExtractor extractor(ObjectFile::getData(), true, 0);
69 
70   uint32_t offset = Index;
71   uint64_t data = 0;
72   while (uint64_t delta = extractor.getULEB128(&offset)) {
73     data += delta;
74     Out.push_back(data);
75   }
76 }
77 
78 const MachOFormat::Header *MachOObjectFile::getHeader() const {
79   StringRef Data = getData(0, sizeof(MachOFormat::Header));
80   return reinterpret_cast<const MachOFormat::Header*>(Data.data());
81 }
82 
83 unsigned MachOObjectFile::getHeaderSize() const {
84   return is64Bit() ? macho::Header64Size : macho::Header32Size;
85 }
86 
87 StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const {
88   return ObjectFile::getData().substr(Offset, Size);
89 }
90 
91 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
92   StringRef Magic = Buffer->getBuffer().slice(0, 4);
93   error_code ec;
94   bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
95   ObjectFile *Ret = new MachOObjectFile(Buffer, Is64Bits, ec);
96   if (ec)
97     return NULL;
98   return Ret;
99 }
100 
101 /*===-- Symbols -----------------------------------------------------------===*/
102 
103 void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const {
104   uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
105   while (DRI.d.a < LoadCommandCount) {
106     const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
107     if (Command->Type == macho::LCT_Symtab) {
108       const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
109         reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command);
110       if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
111         return;
112     }
113 
114     DRI.d.a++;
115     DRI.d.b = 0;
116   }
117 }
118 
119 const MachOFormat::SymbolTableEntryBase *
120 MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI) const {
121   const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
122   const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
123     reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command);
124   return getSymbolTableEntryBase(DRI, SymtabLoadCmd);
125 }
126 
127 const MachOFormat::SymbolTableEntry<false> *
128 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
129   const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
130   return reinterpret_cast<const MachOFormat::SymbolTableEntry<false>*>(Base);
131 }
132 
133 const MachOFormat::SymbolTableEntryBase *
134 MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI,
135                     const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const {
136   uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset;
137   unsigned Index = DRI.d.b;
138 
139   unsigned SymbolTableEntrySize = is64Bit() ?
140     sizeof(MachOFormat::SymbolTableEntry<true>) :
141     sizeof(MachOFormat::SymbolTableEntry<false>);
142 
143   uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
144   StringRef Data = getData(Offset, SymbolTableEntrySize);
145   return
146     reinterpret_cast<const MachOFormat::SymbolTableEntryBase*>(Data.data());
147 }
148 
149 const MachOFormat::SymbolTableEntry<true>*
150 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
151   const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
152   return reinterpret_cast<const MachOFormat::SymbolTableEntry<true>*>(Base);
153 }
154 
155 error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI,
156                                           SymbolRef &Result) const {
157   DRI.d.b++;
158   moveToNextSymbol(DRI);
159   Result = SymbolRef(DRI, this);
160   return object_error::success;
161 }
162 
163 error_code MachOObjectFile::getSymbolName(DataRefImpl DRI,
164                                           StringRef &Result) const {
165   const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
166   const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
167     reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command);
168 
169   StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset,
170                                   SymtabLoadCmd->StringTableSize);
171 
172   const MachOFormat::SymbolTableEntryBase *Entry =
173     getSymbolTableEntryBase(DRI, SymtabLoadCmd);
174   uint32_t StringIndex = Entry->StringIndex;
175 
176   const char *Start = &StringTable.data()[StringIndex];
177   Result = StringRef(Start);
178 
179   return object_error::success;
180 }
181 
182 error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI,
183                                                 uint64_t &Result) const {
184   if (is64Bit()) {
185     const MachOFormat::SymbolTableEntry<true> *Entry =
186       getSymbol64TableEntry(DRI);
187     Result = Entry->Value;
188     if (Entry->SectionIndex) {
189       const MachOFormat::Section<true> *Section =
190         getSection64(Sections[Entry->SectionIndex-1]);
191       Result += Section->Offset - Section->Address;
192     }
193   } else {
194     const MachOFormat::SymbolTableEntry<false> *Entry =
195       getSymbolTableEntry(DRI);
196     Result = Entry->Value;
197     if (Entry->SectionIndex) {
198       const MachOFormat::Section<false> *Section =
199         getSection(Sections[Entry->SectionIndex-1]);
200       Result += Section->Offset - Section->Address;
201     }
202   }
203 
204   return object_error::success;
205 }
206 
207 error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI,
208                                              uint64_t &Result) const {
209   if (is64Bit()) {
210     const MachOFormat::SymbolTableEntry<true> *Entry =
211       getSymbol64TableEntry(DRI);
212     Result = Entry->Value;
213   } else {
214     const MachOFormat::SymbolTableEntry<false> *Entry =
215       getSymbolTableEntry(DRI);
216     Result = Entry->Value;
217   }
218   return object_error::success;
219 }
220 
221 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
222                                           uint64_t &Result) const {
223   uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
224   uint64_t BeginOffset;
225   uint64_t EndOffset = 0;
226   uint8_t SectionIndex;
227   if (is64Bit()) {
228     const MachOFormat::SymbolTableEntry<true> *Entry =
229       getSymbol64TableEntry(DRI);
230     BeginOffset = Entry->Value;
231     SectionIndex = Entry->SectionIndex;
232     if (!SectionIndex) {
233       uint32_t flags = SymbolRef::SF_None;
234       getSymbolFlags(DRI, flags);
235       if (flags & SymbolRef::SF_Common)
236         Result = Entry->Value;
237       else
238         Result = UnknownAddressOrSize;
239       return object_error::success;
240     }
241     // Unfortunately symbols are unsorted so we need to touch all
242     // symbols from load command
243     DRI.d.b = 0;
244     uint32_t Command = DRI.d.a;
245     while (Command == DRI.d.a) {
246       moveToNextSymbol(DRI);
247       if (DRI.d.a < LoadCommandCount) {
248         Entry = getSymbol64TableEntry(DRI);
249         if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
250           if (!EndOffset || Entry->Value < EndOffset)
251             EndOffset = Entry->Value;
252       }
253       DRI.d.b++;
254     }
255   } else {
256     const MachOFormat::SymbolTableEntry<false> *Entry =
257       getSymbolTableEntry(DRI);
258     BeginOffset = Entry->Value;
259     SectionIndex = Entry->SectionIndex;
260     if (!SectionIndex) {
261       uint32_t flags = SymbolRef::SF_None;
262       getSymbolFlags(DRI, flags);
263       if (flags & SymbolRef::SF_Common)
264         Result = Entry->Value;
265       else
266         Result = UnknownAddressOrSize;
267       return object_error::success;
268     }
269     // Unfortunately symbols are unsorted so we need to touch all
270     // symbols from load command
271     DRI.d.b = 0;
272     uint32_t Command = DRI.d.a;
273     while (Command == DRI.d.a) {
274       moveToNextSymbol(DRI);
275       if (DRI.d.a < LoadCommandCount) {
276         Entry = getSymbolTableEntry(DRI);
277         if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
278           if (!EndOffset || Entry->Value < EndOffset)
279             EndOffset = Entry->Value;
280       }
281       DRI.d.b++;
282     }
283   }
284   if (!EndOffset) {
285     uint64_t Size;
286     getSectionSize(Sections[SectionIndex-1], Size);
287     getSectionAddress(Sections[SectionIndex-1], EndOffset);
288     EndOffset += Size;
289   }
290   Result = EndOffset - BeginOffset;
291   return object_error::success;
292 }
293 
294 error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI,
295                                                 char &Result) const {
296   const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
297   uint8_t Type = Entry->Type;
298   uint16_t Flags = Entry->Flags;
299 
300   char Char;
301   switch (Type & macho::STF_TypeMask) {
302     case macho::STT_Undefined:
303       Char = 'u';
304       break;
305     case macho::STT_Absolute:
306     case macho::STT_Section:
307       Char = 's';
308       break;
309     default:
310       Char = '?';
311       break;
312   }
313 
314   if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
315     Char = toupper(static_cast<unsigned char>(Char));
316   Result = Char;
317   return object_error::success;
318 }
319 
320 error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
321                                            uint32_t &Result) const {
322   const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
323   uint8_t MachOType = Entry->Type;
324   uint16_t MachOFlags = Entry->Flags;
325 
326   // TODO: Correctly set SF_ThreadLocal
327   Result = SymbolRef::SF_None;
328 
329   if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
330     Result |= SymbolRef::SF_Undefined;
331 
332   if (MachOFlags & macho::STF_StabsEntryMask)
333     Result |= SymbolRef::SF_FormatSpecific;
334 
335   if (MachOType & MachO::NlistMaskExternal) {
336     Result |= SymbolRef::SF_Global;
337     if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
338       Result |= SymbolRef::SF_Common;
339   }
340 
341   if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
342     Result |= SymbolRef::SF_Weak;
343 
344   if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
345     Result |= SymbolRef::SF_Absolute;
346 
347   return object_error::success;
348 }
349 
350 error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
351                                              section_iterator &Res) const {
352   const MachOFormat::SymbolTableEntryBase *Entry =
353     getSymbolTableEntryBase(Symb);
354   uint8_t index = Entry->SectionIndex;
355 
356   if (index == 0)
357     Res = end_sections();
358   else
359     Res = section_iterator(SectionRef(Sections[index-1], this));
360 
361   return object_error::success;
362 }
363 
364 error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
365                                           SymbolRef::Type &Res) const {
366   const MachOFormat::SymbolTableEntryBase *Entry =
367     getSymbolTableEntryBase(Symb);
368   uint8_t n_type = Entry->Type;
369 
370   Res = SymbolRef::ST_Other;
371 
372   // If this is a STAB debugging symbol, we can do nothing more.
373   if (n_type & MachO::NlistMaskStab) {
374     Res = SymbolRef::ST_Debug;
375     return object_error::success;
376   }
377 
378   switch (n_type & MachO::NlistMaskType) {
379     case MachO::NListTypeUndefined :
380       Res = SymbolRef::ST_Unknown;
381       break;
382     case MachO::NListTypeSection :
383       Res = SymbolRef::ST_Function;
384       break;
385   }
386   return object_error::success;
387 }
388 
389 error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
390                                            uint64_t &Val) const {
391   report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
392 }
393 
394 symbol_iterator MachOObjectFile::begin_symbols() const {
395   // DRI.d.a = segment number; DRI.d.b = symbol index.
396   DataRefImpl DRI;
397   moveToNextSymbol(DRI);
398   return symbol_iterator(SymbolRef(DRI, this));
399 }
400 
401 symbol_iterator MachOObjectFile::end_symbols() const {
402   DataRefImpl DRI;
403   DRI.d.a = getHeader()->NumLoadCommands;
404   return symbol_iterator(SymbolRef(DRI, this));
405 }
406 
407 symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
408   // TODO: implement
409   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
410 }
411 
412 symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
413   // TODO: implement
414   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
415 }
416 
417 library_iterator MachOObjectFile::begin_libraries_needed() const {
418   // TODO: implement
419   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
420 }
421 
422 library_iterator MachOObjectFile::end_libraries_needed() const {
423   // TODO: implement
424   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
425 }
426 
427 StringRef MachOObjectFile::getLoadName() const {
428   // TODO: Implement
429   report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
430 }
431 
432 /*===-- Sections ----------------------------------------------------------===*/
433 
434 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
435   uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
436   while (DRI.d.a < LoadCommandCount) {
437     const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
438     if (Command->Type == macho::LCT_Segment) {
439       const MachOFormat::SegmentLoadCommand<false> *SegmentLoadCmd =
440        reinterpret_cast<const MachOFormat::SegmentLoadCommand<false>*>(Command);
441       if (DRI.d.b < SegmentLoadCmd->NumSections)
442         return;
443     } else if (Command->Type == macho::LCT_Segment64) {
444       const MachOFormat::SegmentLoadCommand<true> *SegmentLoadCmd =
445         reinterpret_cast<const MachOFormat::SegmentLoadCommand<true>*>(Command);
446       if (DRI.d.b < SegmentLoadCmd->NumSections)
447         return;
448     }
449 
450     DRI.d.a++;
451     DRI.d.b = 0;
452   }
453 }
454 
455 error_code MachOObjectFile::getSectionNext(DataRefImpl DRI,
456                                            SectionRef &Result) const {
457   DRI.d.b++;
458   moveToNextSection(DRI);
459   Result = SectionRef(DRI, this);
460   return object_error::success;
461 }
462 
463 const MachOFormat::Section<false> *
464 MachOObjectFile::getSection(DataRefImpl DRI) const {
465   assert(!is64Bit());
466   const MachOFormat::SectionBase *Addr = getSectionBase(DRI);
467   return reinterpret_cast<const MachOFormat::Section<false>*>(Addr);
468 }
469 
470 std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
471   SectionList::const_iterator loc =
472     std::find(Sections.begin(), Sections.end(), Sec);
473   assert(loc != Sections.end() && "Sec is not a valid section!");
474   return std::distance(Sections.begin(), loc);
475 }
476 
477 const MachOFormat::SectionBase*
478 MachOObjectFile::getSectionBase(DataRefImpl DRI) const {
479   const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
480   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(Command);
481 
482   bool Is64 = is64Bit();
483   unsigned SegmentLoadSize =
484     Is64 ? sizeof(MachOFormat::SegmentLoadCommand<true>) :
485            sizeof(MachOFormat::SegmentLoadCommand<false>);
486   unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section<true>) :
487                                 sizeof(MachOFormat::Section<false>);
488 
489   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
490   return reinterpret_cast<const MachOFormat::SectionBase*>(SectionAddr);
491 }
492 
493 const MachOFormat::Section<true> *
494 MachOObjectFile::getSection64(DataRefImpl DRI) const {
495   assert(is64Bit());
496   const MachOFormat::SectionBase *Addr = getSectionBase(DRI);
497   return reinterpret_cast<const MachOFormat::Section<true>*>(Addr);
498 }
499 
500 static StringRef parseSegmentOrSectionName(const char *P) {
501   if (P[15] == 0)
502     // Null terminated.
503     return P;
504   // Not null terminated, so this is a 16 char string.
505   return StringRef(P, 16);
506 }
507 
508 ArrayRef<char> MachOObjectFile::getSectionRawName(DataRefImpl DRI) const {
509   const MachOFormat::SectionBase *Base = getSectionBase(DRI);
510   return ArrayRef<char>(Base->Name);
511 }
512 
513 error_code MachOObjectFile::getSectionName(DataRefImpl DRI,
514                                            StringRef &Result) const {
515   ArrayRef<char> Raw = getSectionRawName(DRI);
516   Result = parseSegmentOrSectionName(Raw.data());
517   return object_error::success;
518 }
519 
520 ArrayRef<char>
521 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
522   const MachOFormat::SectionBase *Base = getSectionBase(Sec);
523   return ArrayRef<char>(Base->SegmentName);
524 }
525 
526 StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const {
527   ArrayRef<char> Raw = getSectionRawFinalSegmentName(DRI);
528   return parseSegmentOrSectionName(Raw.data());
529 }
530 
531 error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
532                                               uint64_t &Result) const {
533   if (is64Bit()) {
534     const MachOFormat::Section<true> *Sect = getSection64(DRI);
535     Result = Sect->Address;
536   } else {
537     const MachOFormat::Section<false> *Sect = getSection(DRI);
538     Result = Sect->Address;
539   }
540   return object_error::success;
541 }
542 
543 error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
544                                            uint64_t &Result) const {
545   if (is64Bit()) {
546     const MachOFormat::Section<true> *Sect = getSection64(DRI);
547     Result = Sect->Size;
548   } else {
549     const MachOFormat::Section<false> *Sect = getSection(DRI);
550     Result = Sect->Size;
551   }
552   return object_error::success;
553 }
554 
555 error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
556                                                StringRef &Result) const {
557   if (is64Bit()) {
558     const MachOFormat::Section<true> *Sect = getSection64(DRI);
559     Result = getData(Sect->Offset, Sect->Size);
560   } else {
561     const MachOFormat::Section<false> *Sect = getSection(DRI);
562     Result = getData(Sect->Offset, Sect->Size);
563   }
564   return object_error::success;
565 }
566 
567 error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
568                                                 uint64_t &Result) const {
569   if (is64Bit()) {
570     const MachOFormat::Section<true> *Sect = getSection64(DRI);
571     Result = uint64_t(1) << Sect->Align;
572   } else {
573     const MachOFormat::Section<false> *Sect = getSection(DRI);
574     Result = uint64_t(1) << Sect->Align;
575   }
576   return object_error::success;
577 }
578 
579 error_code MachOObjectFile::isSectionText(DataRefImpl DRI,
580                                           bool &Result) const {
581   if (is64Bit()) {
582     const MachOFormat::Section<true> *Sect = getSection64(DRI);
583     Result = Sect->Flags & macho::SF_PureInstructions;
584   } else {
585     const MachOFormat::Section<false> *Sect = getSection(DRI);
586     Result = Sect->Flags & macho::SF_PureInstructions;
587   }
588   return object_error::success;
589 }
590 
591 error_code MachOObjectFile::isSectionData(DataRefImpl DRI,
592                                           bool &Result) const {
593   // FIXME: Unimplemented.
594   Result = false;
595   return object_error::success;
596 }
597 
598 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
599                                          bool &Result) const {
600   // FIXME: Unimplemented.
601   Result = false;
602   return object_error::success;
603 }
604 
605 error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
606                                                           bool &Result) const {
607   // FIXME: Unimplemented.
608   Result = true;
609   return object_error::success;
610 }
611 
612 error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
613                                              bool &Result) const {
614   // FIXME: Unimplemented.
615   Result = false;
616   return object_error::success;
617 }
618 
619 error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI,
620                                               bool &Result) const {
621   if (is64Bit()) {
622     const MachOFormat::Section<true> *Sect = getSection64(DRI);
623     unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
624     Result = (SectionType == MachO::SectionTypeZeroFill ||
625               SectionType == MachO::SectionTypeZeroFillLarge);
626   } else {
627     const MachOFormat::Section<false> *Sect = getSection(DRI);
628     unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
629     Result = (SectionType == MachO::SectionTypeZeroFill ||
630               SectionType == MachO::SectionTypeZeroFillLarge);
631   }
632 
633   return object_error::success;
634 }
635 
636 error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
637                                                   bool &Result) const {
638   // Consider using the code from isSectionText to look for __const sections.
639   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
640   // to use section attributes to distinguish code from data.
641 
642   // FIXME: Unimplemented.
643   Result = false;
644   return object_error::success;
645 }
646 
647 error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
648                                                   DataRefImpl Symb,
649                                                   bool &Result) const {
650   SymbolRef::Type ST;
651   getSymbolType(Symb, ST);
652   if (ST == SymbolRef::ST_Unknown) {
653     Result = false;
654     return object_error::success;
655   }
656 
657   uint64_t SectBegin, SectEnd;
658   getSectionAddress(Sec, SectBegin);
659   getSectionSize(Sec, SectEnd);
660   SectEnd += SectBegin;
661 
662   if (is64Bit()) {
663     const MachOFormat::SymbolTableEntry<true> *Entry =
664       getSymbol64TableEntry(Symb);
665     uint64_t SymAddr= Entry->Value;
666     Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
667   } else {
668     const MachOFormat::SymbolTableEntry<false> *Entry =
669       getSymbolTableEntry(Symb);
670     uint64_t SymAddr= Entry->Value;
671     Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
672   }
673 
674   return object_error::success;
675 }
676 
677 relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
678   DataRefImpl ret;
679   ret.d.b = getSectionIndex(Sec);
680   return relocation_iterator(RelocationRef(ret, this));
681 }
682 
683 relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
684   uint32_t last_reloc;
685   if (is64Bit()) {
686     const MachOFormat::Section<true> *Sect = getSection64(Sec);
687     last_reloc = Sect->NumRelocationTableEntries;
688   } else {
689     const MachOFormat::Section<false> *Sect = getSection(Sec);
690     last_reloc = Sect->NumRelocationTableEntries;
691   }
692   DataRefImpl ret;
693   ret.d.a = last_reloc;
694   ret.d.b = getSectionIndex(Sec);
695   return relocation_iterator(RelocationRef(ret, this));
696 }
697 
698 section_iterator MachOObjectFile::begin_sections() const {
699   DataRefImpl DRI;
700   moveToNextSection(DRI);
701   return section_iterator(SectionRef(DRI, this));
702 }
703 
704 section_iterator MachOObjectFile::end_sections() const {
705   DataRefImpl DRI;
706   DRI.d.a = getHeader()->NumLoadCommands;
707   return section_iterator(SectionRef(DRI, this));
708 }
709 
710 /*===-- Relocations -------------------------------------------------------===*/
711 
712 const MachOFormat::RelocationEntry *
713 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
714   uint32_t relOffset;
715   if (is64Bit()) {
716     const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]);
717     relOffset = Sect->RelocationTableOffset;
718   } else {
719     const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]);
720     relOffset = Sect->RelocationTableOffset;
721   }
722   uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry);
723   StringRef Data = getData(Offset, sizeof(MachOFormat::RelocationEntry));
724   return reinterpret_cast<const MachOFormat::RelocationEntry*>(Data.data());
725 }
726 
727 error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
728                                               RelocationRef &Res) const {
729   ++Rel.d.a;
730   Res = RelocationRef(Rel, this);
731   return object_error::success;
732 }
733 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
734                                                  uint64_t &Res) const {
735   const uint8_t* sectAddress = 0;
736   if (is64Bit()) {
737     const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]);
738     sectAddress += Sect->Address;
739   } else {
740     const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]);
741     sectAddress += Sect->Address;
742   }
743   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
744 
745   unsigned Arch = getArch();
746   bool isScattered = (Arch != Triple::x86_64) &&
747                      (RE->Word0 & macho::RF_Scattered);
748   uint64_t RelAddr = 0;
749   if (isScattered)
750     RelAddr = RE->Word0 & 0xFFFFFF;
751   else
752     RelAddr = RE->Word0;
753 
754   Res = reinterpret_cast<uintptr_t>(sectAddress + RelAddr);
755   return object_error::success;
756 }
757 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
758                                                 uint64_t &Res) const {
759   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
760 
761   unsigned Arch = getArch();
762   bool isScattered = (Arch != Triple::x86_64) &&
763                      (RE->Word0 & macho::RF_Scattered);
764   if (isScattered)
765     Res = RE->Word0 & 0xFFFFFF;
766   else
767     Res = RE->Word0;
768   return object_error::success;
769 }
770 error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
771                                                 SymbolRef &Res) const {
772   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
773   uint32_t SymbolIdx = RE->Word1 & 0xffffff;
774   bool isExtern = (RE->Word1 >> 27) & 1;
775 
776   DataRefImpl Sym;
777   moveToNextSymbol(Sym);
778   if (isExtern) {
779     for (unsigned i = 0; i < SymbolIdx; i++) {
780       Sym.d.b++;
781       moveToNextSymbol(Sym);
782       assert(Sym.d.a < getHeader()->NumLoadCommands &&
783              "Relocation symbol index out of range!");
784     }
785   }
786   Res = SymbolRef(Sym, this);
787   return object_error::success;
788 }
789 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
790                                               uint64_t &Res) const {
791   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
792   Res = RE->Word0;
793   Res <<= 32;
794   Res |= RE->Word1;
795   return object_error::success;
796 }
797 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
798                                           SmallVectorImpl<char> &Result) const {
799   // TODO: Support scattered relocations.
800   StringRef res;
801   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
802 
803   unsigned Arch = getArch();
804   bool isScattered = (Arch != Triple::x86_64) &&
805                      (RE->Word0 & macho::RF_Scattered);
806 
807   unsigned r_type;
808   if (isScattered)
809     r_type = (RE->Word0 >> 24) & 0xF;
810   else
811     r_type = (RE->Word1 >> 28) & 0xF;
812 
813   switch (Arch) {
814     case Triple::x86: {
815       static const char *const Table[] =  {
816         "GENERIC_RELOC_VANILLA",
817         "GENERIC_RELOC_PAIR",
818         "GENERIC_RELOC_SECTDIFF",
819         "GENERIC_RELOC_PB_LA_PTR",
820         "GENERIC_RELOC_LOCAL_SECTDIFF",
821         "GENERIC_RELOC_TLV" };
822 
823       if (r_type > 6)
824         res = "Unknown";
825       else
826         res = Table[r_type];
827       break;
828     }
829     case Triple::x86_64: {
830       static const char *const Table[] =  {
831         "X86_64_RELOC_UNSIGNED",
832         "X86_64_RELOC_SIGNED",
833         "X86_64_RELOC_BRANCH",
834         "X86_64_RELOC_GOT_LOAD",
835         "X86_64_RELOC_GOT",
836         "X86_64_RELOC_SUBTRACTOR",
837         "X86_64_RELOC_SIGNED_1",
838         "X86_64_RELOC_SIGNED_2",
839         "X86_64_RELOC_SIGNED_4",
840         "X86_64_RELOC_TLV" };
841 
842       if (r_type > 9)
843         res = "Unknown";
844       else
845         res = Table[r_type];
846       break;
847     }
848     case Triple::arm: {
849       static const char *const Table[] =  {
850         "ARM_RELOC_VANILLA",
851         "ARM_RELOC_PAIR",
852         "ARM_RELOC_SECTDIFF",
853         "ARM_RELOC_LOCAL_SECTDIFF",
854         "ARM_RELOC_PB_LA_PTR",
855         "ARM_RELOC_BR24",
856         "ARM_THUMB_RELOC_BR22",
857         "ARM_THUMB_32BIT_BRANCH",
858         "ARM_RELOC_HALF",
859         "ARM_RELOC_HALF_SECTDIFF" };
860 
861       if (r_type > 9)
862         res = "Unknown";
863       else
864         res = Table[r_type];
865       break;
866     }
867     case Triple::ppc: {
868       static const char *const Table[] =  {
869         "PPC_RELOC_VANILLA",
870         "PPC_RELOC_PAIR",
871         "PPC_RELOC_BR14",
872         "PPC_RELOC_BR24",
873         "PPC_RELOC_HI16",
874         "PPC_RELOC_LO16",
875         "PPC_RELOC_HA16",
876         "PPC_RELOC_LO14",
877         "PPC_RELOC_SECTDIFF",
878         "PPC_RELOC_PB_LA_PTR",
879         "PPC_RELOC_HI16_SECTDIFF",
880         "PPC_RELOC_LO16_SECTDIFF",
881         "PPC_RELOC_HA16_SECTDIFF",
882         "PPC_RELOC_JBSR",
883         "PPC_RELOC_LO14_SECTDIFF",
884         "PPC_RELOC_LOCAL_SECTDIFF" };
885 
886       res = Table[r_type];
887       break;
888     }
889     case Triple::UnknownArch:
890       res = "Unknown";
891       break;
892   }
893   Result.append(res.begin(), res.end());
894   return object_error::success;
895 }
896 error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
897                                                         int64_t &Res) const {
898   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
899   bool isExtern = (RE->Word1 >> 27) & 1;
900   Res = 0;
901   if (!isExtern) {
902     const uint8_t* sectAddress = base();
903     if (is64Bit()) {
904       const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]);
905       sectAddress += Sect->Offset;
906     } else {
907       const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]);
908       sectAddress += Sect->Offset;
909     }
910     Res = reinterpret_cast<uintptr_t>(sectAddress);
911   }
912   return object_error::success;
913 }
914 
915 // Helper to advance a section or symbol iterator multiple increments at a time.
916 template<class T>
917 error_code advance(T &it, size_t Val) {
918   error_code ec;
919   while (Val--) {
920     it.increment(ec);
921   }
922   return ec;
923 }
924 
925 template<class T>
926 void advanceTo(T &it, size_t Val) {
927   if (error_code ec = advance(it, Val))
928     report_fatal_error(ec.message());
929 }
930 
931 void MachOObjectFile::printRelocationTargetName(
932                                      const MachOFormat::RelocationEntry *RE,
933                                      raw_string_ostream &fmt) const {
934   unsigned Arch = getArch();
935   bool isScattered = (Arch != Triple::x86_64) &&
936                      (RE->Word0 & macho::RF_Scattered);
937 
938   // Target of a scattered relocation is an address.  In the interest of
939   // generating pretty output, scan through the symbol table looking for a
940   // symbol that aligns with that address.  If we find one, print it.
941   // Otherwise, we just print the hex address of the target.
942   if (isScattered) {
943     uint32_t Val = RE->Word1;
944 
945     error_code ec;
946     for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
947         SI.increment(ec)) {
948       if (ec) report_fatal_error(ec.message());
949 
950       uint64_t Addr;
951       StringRef Name;
952 
953       if ((ec = SI->getAddress(Addr)))
954         report_fatal_error(ec.message());
955       if (Addr != Val) continue;
956       if ((ec = SI->getName(Name)))
957         report_fatal_error(ec.message());
958       fmt << Name;
959       return;
960     }
961 
962     // If we couldn't find a symbol that this relocation refers to, try
963     // to find a section beginning instead.
964     for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
965          SI.increment(ec)) {
966       if (ec) report_fatal_error(ec.message());
967 
968       uint64_t Addr;
969       StringRef Name;
970 
971       if ((ec = SI->getAddress(Addr)))
972         report_fatal_error(ec.message());
973       if (Addr != Val) continue;
974       if ((ec = SI->getName(Name)))
975         report_fatal_error(ec.message());
976       fmt << Name;
977       return;
978     }
979 
980     fmt << format("0x%x", Val);
981     return;
982   }
983 
984   StringRef S;
985   bool isExtern = (RE->Word1 >> 27) & 1;
986   uint32_t Val = RE->Word1 & 0xFFFFFF;
987 
988   if (isExtern) {
989     symbol_iterator SI = begin_symbols();
990     advanceTo(SI, Val);
991     SI->getName(S);
992   } else {
993     section_iterator SI = begin_sections();
994     advanceTo(SI, Val);
995     SI->getName(S);
996   }
997 
998   fmt << S;
999 }
1000 
1001 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
1002                                           SmallVectorImpl<char> &Result) const {
1003   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
1004 
1005   unsigned Arch = getArch();
1006   bool isScattered = (Arch != Triple::x86_64) &&
1007                      (RE->Word0 & macho::RF_Scattered);
1008 
1009   std::string fmtbuf;
1010   raw_string_ostream fmt(fmtbuf);
1011 
1012   unsigned Type;
1013   if (isScattered)
1014     Type = (RE->Word0 >> 24) & 0xF;
1015   else
1016     Type = (RE->Word1 >> 28) & 0xF;
1017 
1018   bool isPCRel;
1019   if (isScattered)
1020     isPCRel = ((RE->Word0 >> 30) & 1);
1021   else
1022     isPCRel = ((RE->Word1 >> 24) & 1);
1023 
1024   // Determine any addends that should be displayed with the relocation.
1025   // These require decoding the relocation type, which is triple-specific.
1026 
1027   // X86_64 has entirely custom relocation types.
1028   if (Arch == Triple::x86_64) {
1029     bool isPCRel = ((RE->Word1 >> 24) & 1);
1030 
1031     switch (Type) {
1032       case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD
1033       case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT
1034         printRelocationTargetName(RE, fmt);
1035         fmt << "@GOT";
1036         if (isPCRel) fmt << "PCREL";
1037         break;
1038       }
1039       case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
1040         DataRefImpl RelNext = Rel;
1041         RelNext.d.a++;
1042         const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1043 
1044         // X86_64_SUBTRACTOR must be followed by a relocation of type
1045         // X86_64_RELOC_UNSIGNED.
1046         // NOTE: Scattered relocations don't exist on x86_64.
1047         unsigned RType = (RENext->Word1 >> 28) & 0xF;
1048         if (RType != 0)
1049           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1050                              "X86_64_RELOC_SUBTRACTOR.");
1051 
1052         // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
1053         // X86_64_SUBTRACTOR contains to the subtrahend.
1054         printRelocationTargetName(RENext, fmt);
1055         fmt << "-";
1056         printRelocationTargetName(RE, fmt);
1057         break;
1058       }
1059       case macho::RIT_X86_64_TLV:
1060         printRelocationTargetName(RE, fmt);
1061         fmt << "@TLV";
1062         if (isPCRel) fmt << "P";
1063         break;
1064       case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
1065         printRelocationTargetName(RE, fmt);
1066         fmt << "-1";
1067         break;
1068       case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
1069         printRelocationTargetName(RE, fmt);
1070         fmt << "-2";
1071         break;
1072       case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
1073         printRelocationTargetName(RE, fmt);
1074         fmt << "-4";
1075         break;
1076       default:
1077         printRelocationTargetName(RE, fmt);
1078         break;
1079     }
1080   // X86 and ARM share some relocation types in common.
1081   } else if (Arch == Triple::x86 || Arch == Triple::arm) {
1082     // Generic relocation types...
1083     switch (Type) {
1084       case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
1085         return object_error::success;
1086       case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
1087         DataRefImpl RelNext = Rel;
1088         RelNext.d.a++;
1089         const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1090 
1091         // X86 sect diff's must be followed by a relocation of type
1092         // GENERIC_RELOC_PAIR.
1093         bool isNextScattered = (Arch != Triple::x86_64) &&
1094                                (RENext->Word0 & macho::RF_Scattered);
1095         unsigned RType;
1096         if (isNextScattered)
1097           RType = (RENext->Word0 >> 24) & 0xF;
1098         else
1099           RType = (RENext->Word1 >> 28) & 0xF;
1100         if (RType != 1)
1101           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1102                              "GENERIC_RELOC_SECTDIFF.");
1103 
1104         printRelocationTargetName(RE, fmt);
1105         fmt << "-";
1106         printRelocationTargetName(RENext, fmt);
1107         break;
1108       }
1109     }
1110 
1111     if (Arch == Triple::x86) {
1112       // All X86 relocations that need special printing were already
1113       // handled in the generic code.
1114       switch (Type) {
1115         case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
1116           DataRefImpl RelNext = Rel;
1117           RelNext.d.a++;
1118           const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1119 
1120           // X86 sect diff's must be followed by a relocation of type
1121           // GENERIC_RELOC_PAIR.
1122           bool isNextScattered = (Arch != Triple::x86_64) &&
1123                                (RENext->Word0 & macho::RF_Scattered);
1124           unsigned RType;
1125           if (isNextScattered)
1126             RType = (RENext->Word0 >> 24) & 0xF;
1127           else
1128             RType = (RENext->Word1 >> 28) & 0xF;
1129           if (RType != 1)
1130             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1131                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
1132 
1133           printRelocationTargetName(RE, fmt);
1134           fmt << "-";
1135           printRelocationTargetName(RENext, fmt);
1136           break;
1137         }
1138         case macho::RIT_Generic_TLV: {
1139           printRelocationTargetName(RE, fmt);
1140           fmt << "@TLV";
1141           if (isPCRel) fmt << "P";
1142           break;
1143         }
1144         default:
1145           printRelocationTargetName(RE, fmt);
1146       }
1147     } else { // ARM-specific relocations
1148       switch (Type) {
1149         case macho::RIT_ARM_Half:             // ARM_RELOC_HALF
1150         case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
1151           // Half relocations steal a bit from the length field to encode
1152           // whether this is an upper16 or a lower16 relocation.
1153           bool isUpper;
1154           if (isScattered)
1155             isUpper = (RE->Word0 >> 28) & 1;
1156           else
1157             isUpper = (RE->Word1 >> 25) & 1;
1158 
1159           if (isUpper)
1160             fmt << ":upper16:(";
1161           else
1162             fmt << ":lower16:(";
1163           printRelocationTargetName(RE, fmt);
1164 
1165           DataRefImpl RelNext = Rel;
1166           RelNext.d.a++;
1167           const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1168 
1169           // ARM half relocs must be followed by a relocation of type
1170           // ARM_RELOC_PAIR.
1171           bool isNextScattered = (Arch != Triple::x86_64) &&
1172                                  (RENext->Word0 & macho::RF_Scattered);
1173           unsigned RType;
1174           if (isNextScattered)
1175             RType = (RENext->Word0 >> 24) & 0xF;
1176           else
1177             RType = (RENext->Word1 >> 28) & 0xF;
1178 
1179           if (RType != 1)
1180             report_fatal_error("Expected ARM_RELOC_PAIR after "
1181                                "GENERIC_RELOC_HALF");
1182 
1183           // NOTE: The half of the target virtual address is stashed in the
1184           // address field of the secondary relocation, but we can't reverse
1185           // engineer the constant offset from it without decoding the movw/movt
1186           // instruction to find the other half in its immediate field.
1187 
1188           // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1189           // symbol/section pointer of the follow-on relocation.
1190           if (Type == macho::RIT_ARM_HalfDifference) {
1191             fmt << "-";
1192             printRelocationTargetName(RENext, fmt);
1193           }
1194 
1195           fmt << ")";
1196           break;
1197         }
1198         default: {
1199           printRelocationTargetName(RE, fmt);
1200         }
1201       }
1202     }
1203   } else
1204     printRelocationTargetName(RE, fmt);
1205 
1206   fmt.flush();
1207   Result.append(fmtbuf.begin(), fmtbuf.end());
1208   return object_error::success;
1209 }
1210 
1211 error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
1212                                                 bool &Result) const {
1213   const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
1214 
1215   unsigned Arch = getArch();
1216   bool isScattered = (Arch != Triple::x86_64) &&
1217                      (RE->Word0 & macho::RF_Scattered);
1218   unsigned Type;
1219   if (isScattered)
1220     Type = (RE->Word0 >> 24) & 0xF;
1221   else
1222     Type = (RE->Word1 >> 28) & 0xF;
1223 
1224   Result = false;
1225 
1226   // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1227   // is always hidden.
1228   if (Arch == Triple::x86 || Arch == Triple::arm) {
1229     if (Type == macho::RIT_Pair) Result = true;
1230   } else if (Arch == Triple::x86_64) {
1231     // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1232     // an X864_64_RELOC_SUBTRACTOR.
1233     if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
1234       DataRefImpl RelPrev = Rel;
1235       RelPrev.d.a--;
1236       const MachOFormat::RelocationEntry *REPrev = getRelocation(RelPrev);
1237 
1238       unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
1239 
1240       if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
1241     }
1242   }
1243 
1244   return object_error::success;
1245 }
1246 
1247 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1248                                            LibraryRef &Res) const {
1249   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1250 }
1251 
1252 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1253                                            StringRef &Res) const {
1254   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1255 }
1256 
1257 
1258 /*===-- Miscellaneous -----------------------------------------------------===*/
1259 
1260 uint8_t MachOObjectFile::getBytesInAddress() const {
1261   return is64Bit() ? 8 : 4;
1262 }
1263 
1264 StringRef MachOObjectFile::getFileFormatName() const {
1265   if (!is64Bit()) {
1266     switch (getHeader()->CPUType) {
1267     case llvm::MachO::CPUTypeI386:
1268       return "Mach-O 32-bit i386";
1269     case llvm::MachO::CPUTypeARM:
1270       return "Mach-O arm";
1271     case llvm::MachO::CPUTypePowerPC:
1272       return "Mach-O 32-bit ppc";
1273     default:
1274       assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 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((getHeader()->CPUType & llvm::MachO::CPUArchABI64)
1282 	 == llvm::MachO::CPUArchABI64 &&
1283 	 "32-bit object file when we're 64-bit?");
1284 
1285   switch (getHeader()->CPUType) {
1286   case llvm::MachO::CPUTypeX86_64:
1287     return "Mach-O 64-bit x86-64";
1288   case llvm::MachO::CPUTypePowerPC64:
1289     return "Mach-O 64-bit ppc64";
1290   default:
1291     return "Mach-O 64-bit unknown";
1292   }
1293 }
1294 
1295 unsigned MachOObjectFile::getArch() const {
1296   switch (getHeader()->CPUType) {
1297   case llvm::MachO::CPUTypeI386:
1298     return Triple::x86;
1299   case llvm::MachO::CPUTypeX86_64:
1300     return Triple::x86_64;
1301   case llvm::MachO::CPUTypeARM:
1302     return Triple::arm;
1303   case llvm::MachO::CPUTypePowerPC:
1304     return Triple::ppc;
1305   case llvm::MachO::CPUTypePowerPC64:
1306     return Triple::ppc64;
1307   default:
1308     return Triple::UnknownArch;
1309   }
1310 }
1311 
1312 } // end namespace object
1313 } // end namespace llvm
1314