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