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