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