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