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