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