Define versions of Section that are explicitly marked as little endian.
[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       const MachOFormat::Section64 *Section =
142         getSection64(Sections[Entry->SectionIndex-1]);
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       const MachOFormat::Section *Section =
151         getSection(Sections[Entry->SectionIndex-1]);
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(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     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 static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
448   LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
449   if (LCI.Command.Type == macho::LCT_Segment64)
450     return true;
451   assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type.");
452   return false;
453 }
454
455 const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const {
456   assert(!is64BitLoadCommand(MachOObj.get(), DRI));
457   LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
458   unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) +
459     DRI.d.b * sizeof(MachOFormat::Section);
460   StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section));
461   return reinterpret_cast<const MachOFormat::Section*>(Data.data());
462 }
463
464 std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
465   SectionList::const_iterator loc =
466     std::find(Sections.begin(), Sections.end(), Sec);
467   assert(loc != Sections.end() && "Sec is not a valid section!");
468   return std::distance(Sections.begin(), loc);
469 }
470
471 const MachOFormat::Section64 *
472 MachOObjectFile::getSection64(DataRefImpl DRI) const {
473   assert(is64BitLoadCommand(MachOObj.get(), DRI));
474   LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
475   unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) +
476     DRI.d.b * sizeof(MachOFormat::Section64);
477   StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section64));
478   return reinterpret_cast<const MachOFormat::Section64*>(Data.data());
479 }
480
481 static StringRef parseSegmentOrSectionName(const char *P) {
482   if (P[15] == 0)
483     // Null terminated.
484     return P;
485   // Not null terminated, so this is a 16 char string.
486   return StringRef(P, 16);
487 }
488
489 ArrayRef<char> MachOObjectFile::getSectionRawName(DataRefImpl DRI) const {
490   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
491     const MachOFormat::Section64 *sec = getSection64(DRI);
492     return ArrayRef<char>(sec->Name);
493   } else {
494     const MachOFormat::Section *sec = getSection(DRI);
495     return ArrayRef<char>(sec->Name);
496   }
497 }
498
499 error_code MachOObjectFile::getSectionName(DataRefImpl DRI,
500                                            StringRef &Result) const {
501   ArrayRef<char> Raw = getSectionRawName(DRI);
502   Result = parseSegmentOrSectionName(Raw.data());
503   return object_error::success;
504 }
505
506 ArrayRef<char>
507 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
508   if (is64BitLoadCommand(MachOObj.get(), Sec)) {
509     const MachOFormat::Section64 *sec = getSection64(Sec);
510     return ArrayRef<char>(sec->SegmentName, 16);
511   } else {
512     const MachOFormat::Section *sec = getSection(Sec);
513     return ArrayRef<char>(sec->SegmentName);
514   }
515 }
516
517 StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const {
518   ArrayRef<char> Raw = getSectionRawFinalSegmentName(DRI);
519   return parseSegmentOrSectionName(Raw.data());
520 }
521
522 error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
523                                               uint64_t &Result) const {
524   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
525     const MachOFormat::Section64 *Sect = getSection64(DRI);
526     Result = Sect->Address;
527   } else {
528     const MachOFormat::Section *Sect = getSection(DRI);
529     Result = Sect->Address;
530   }
531   return object_error::success;
532 }
533
534 error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
535                                            uint64_t &Result) const {
536   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
537     const MachOFormat::Section64 *Sect = getSection64(DRI);
538     Result = Sect->Size;
539   } else {
540     const MachOFormat::Section *Sect = getSection(DRI);
541     Result = Sect->Size;
542   }
543   return object_error::success;
544 }
545
546 error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
547                                                StringRef &Result) const {
548   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
549     const MachOFormat::Section64 *Sect = getSection64(DRI);
550     Result = MachOObj->getData(Sect->Offset, Sect->Size);
551   } else {
552     const MachOFormat::Section *Sect = getSection(DRI);
553     Result = MachOObj->getData(Sect->Offset, Sect->Size);
554   }
555   return object_error::success;
556 }
557
558 error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
559                                                 uint64_t &Result) const {
560   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
561     const MachOFormat::Section64 *Sect = getSection64(DRI);
562     Result = uint64_t(1) << Sect->Align;
563   } else {
564     const MachOFormat::Section *Sect = getSection(DRI);
565     Result = uint64_t(1) << Sect->Align;
566   }
567   return object_error::success;
568 }
569
570 error_code MachOObjectFile::isSectionText(DataRefImpl DRI,
571                                           bool &Result) const {
572   if (is64BitLoadCommand(MachOObj.get(), DRI)) {
573     const MachOFormat::Section64 *Sect = getSection64(DRI);
574     Result = Sect->Flags & macho::SF_PureInstructions;
575   } else {
576     const MachOFormat::Section *Sect = getSection(DRI);
577     Result = Sect->Flags & macho::SF_PureInstructions;
578   }
579   return object_error::success;
580 }
581
582 error_code MachOObjectFile::isSectionData(DataRefImpl DRI,
583                                           bool &Result) const {
584   // FIXME: Unimplemented.
585   Result = false;
586   return object_error::success;
587 }
588
589 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
590                                          bool &Result) const {
591   // FIXME: Unimplemented.
592   Result = false;
593   return object_error::success;
594 }
595
596 error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
597                                                           bool &Result) const {
598   // FIXME: Unimplemented.
599   Result = true;
600   return object_error::success;
601 }
602
603 error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
604                                              bool &Result) const {
605   // FIXME: Unimplemented.
606   Result = false;
607   return object_error::success;
608 }
609
610 error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI,
611                                               bool &Result) const {
612   if (MachOObj->is64Bit()) {
613     const MachOFormat::Section64 *Sect = getSection64(DRI);
614     unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
615     Result = (SectionType == MachO::SectionTypeZeroFill ||
616               SectionType == MachO::SectionTypeZeroFillLarge);
617   } else {
618     const MachOFormat::Section *Sect = getSection(DRI);
619     unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
620     Result = (SectionType == MachO::SectionTypeZeroFill ||
621               SectionType == MachO::SectionTypeZeroFillLarge);
622   }
623
624   return object_error::success;
625 }
626
627 error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
628                                                   bool &Result) const {
629   // Consider using the code from isSectionText to look for __const sections.
630   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
631   // to use section attributes to distinguish code from data.
632
633   // FIXME: Unimplemented.
634   Result = false;
635   return object_error::success;
636 }
637
638 error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
639                                                   DataRefImpl Symb,
640                                                   bool &Result) const {
641   SymbolRef::Type ST;
642   getSymbolType(Symb, ST);
643   if (ST == SymbolRef::ST_Unknown) {
644     Result = false;
645     return object_error::success;
646   }
647
648   uint64_t SectBegin, SectEnd;
649   getSectionAddress(Sec, SectBegin);
650   getSectionSize(Sec, SectEnd);
651   SectEnd += SectBegin;
652
653   if (MachOObj->is64Bit()) {
654     InMemoryStruct<macho::Symbol64TableEntry> Entry;
655     getSymbol64TableEntry(Symb, Entry);
656     uint64_t SymAddr= Entry->Value;
657     Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
658   } else {
659     InMemoryStruct<macho::SymbolTableEntry> Entry;
660     getSymbolTableEntry(Symb, Entry);
661     uint64_t SymAddr= Entry->Value;
662     Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
663   }
664
665   return object_error::success;
666 }
667
668 relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
669   DataRefImpl ret;
670   ret.d.b = getSectionIndex(Sec);
671   return relocation_iterator(RelocationRef(ret, this));
672 }
673 relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
674   uint32_t last_reloc;
675   if (is64BitLoadCommand(MachOObj.get(), Sec)) {
676     const MachOFormat::Section64 *Sect = getSection64(Sec);
677     last_reloc = Sect->NumRelocationTableEntries;
678   } else {
679     const MachOFormat::Section *Sect = getSection(Sec);
680     last_reloc = Sect->NumRelocationTableEntries;
681   }
682   DataRefImpl ret;
683   ret.d.a = last_reloc;
684   ret.d.b = getSectionIndex(Sec);
685   return relocation_iterator(RelocationRef(ret, this));
686 }
687
688 section_iterator MachOObjectFile::begin_sections() const {
689   DataRefImpl DRI;
690   moveToNextSection(DRI);
691   return section_iterator(SectionRef(DRI, this));
692 }
693
694 section_iterator MachOObjectFile::end_sections() const {
695   DataRefImpl DRI;
696   DRI.d.a = MachOObj->getHeader().NumLoadCommands;
697   return section_iterator(SectionRef(DRI, this));
698 }
699
700 /*===-- Relocations -------------------------------------------------------===*/
701
702 void MachOObjectFile::
703 getRelocation(DataRefImpl Rel,
704               InMemoryStruct<macho::RelocationEntry> &Res) const {
705   uint32_t relOffset;
706   if (MachOObj->is64Bit()) {
707     const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]);
708     relOffset = Sect->RelocationTableOffset;
709   } else {
710     const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
711     relOffset = Sect->RelocationTableOffset;
712   }
713   MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res);
714 }
715 error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
716                                               RelocationRef &Res) const {
717   ++Rel.d.a;
718   Res = RelocationRef(Rel, this);
719   return object_error::success;
720 }
721 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
722                                                  uint64_t &Res) const {
723   const uint8_t* sectAddress = 0;
724   if (MachOObj->is64Bit()) {
725     const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]);
726     sectAddress += Sect->Address;
727   } else {
728     const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
729     sectAddress += Sect->Address;
730   }
731   InMemoryStruct<macho::RelocationEntry> RE;
732   getRelocation(Rel, RE);
733
734   unsigned Arch = getArch();
735   bool isScattered = (Arch != Triple::x86_64) &&
736                      (RE->Word0 & macho::RF_Scattered);
737   uint64_t RelAddr = 0;
738   if (isScattered)
739     RelAddr = RE->Word0 & 0xFFFFFF;
740   else
741     RelAddr = RE->Word0;
742
743   Res = reinterpret_cast<uintptr_t>(sectAddress + RelAddr);
744   return object_error::success;
745 }
746 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
747                                                 uint64_t &Res) const {
748   InMemoryStruct<macho::RelocationEntry> RE;
749   getRelocation(Rel, RE);
750
751   unsigned Arch = getArch();
752   bool isScattered = (Arch != Triple::x86_64) &&
753                      (RE->Word0 & macho::RF_Scattered);
754   if (isScattered)
755     Res = RE->Word0 & 0xFFFFFF;
756   else
757     Res = RE->Word0;
758   return object_error::success;
759 }
760 error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
761                                                 SymbolRef &Res) const {
762   InMemoryStruct<macho::RelocationEntry> RE;
763   getRelocation(Rel, RE);
764   uint32_t SymbolIdx = RE->Word1 & 0xffffff;
765   bool isExtern = (RE->Word1 >> 27) & 1;
766
767   DataRefImpl Sym;
768   moveToNextSymbol(Sym);
769   if (isExtern) {
770     for (unsigned i = 0; i < SymbolIdx; i++) {
771       Sym.d.b++;
772       moveToNextSymbol(Sym);
773       assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands &&
774              "Relocation symbol index out of range!");
775     }
776   }
777   Res = SymbolRef(Sym, this);
778   return object_error::success;
779 }
780 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
781                                               uint64_t &Res) const {
782   InMemoryStruct<macho::RelocationEntry> RE;
783   getRelocation(Rel, RE);
784   Res = RE->Word0;
785   Res <<= 32;
786   Res |= RE->Word1;
787   return object_error::success;
788 }
789 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
790                                           SmallVectorImpl<char> &Result) const {
791   // TODO: Support scattered relocations.
792   StringRef res;
793   InMemoryStruct<macho::RelocationEntry> RE;
794   getRelocation(Rel, RE);
795
796   unsigned Arch = getArch();
797   bool isScattered = (Arch != Triple::x86_64) &&
798                      (RE->Word0 & macho::RF_Scattered);
799
800   unsigned r_type;
801   if (isScattered)
802     r_type = (RE->Word0 >> 24) & 0xF;
803   else
804     r_type = (RE->Word1 >> 28) & 0xF;
805
806   switch (Arch) {
807     case Triple::x86: {
808       static const char *const Table[] =  {
809         "GENERIC_RELOC_VANILLA",
810         "GENERIC_RELOC_PAIR",
811         "GENERIC_RELOC_SECTDIFF",
812         "GENERIC_RELOC_PB_LA_PTR",
813         "GENERIC_RELOC_LOCAL_SECTDIFF",
814         "GENERIC_RELOC_TLV" };
815
816       if (r_type > 6)
817         res = "Unknown";
818       else
819         res = Table[r_type];
820       break;
821     }
822     case Triple::x86_64: {
823       static const char *const Table[] =  {
824         "X86_64_RELOC_UNSIGNED",
825         "X86_64_RELOC_SIGNED",
826         "X86_64_RELOC_BRANCH",
827         "X86_64_RELOC_GOT_LOAD",
828         "X86_64_RELOC_GOT",
829         "X86_64_RELOC_SUBTRACTOR",
830         "X86_64_RELOC_SIGNED_1",
831         "X86_64_RELOC_SIGNED_2",
832         "X86_64_RELOC_SIGNED_4",
833         "X86_64_RELOC_TLV" };
834
835       if (r_type > 9)
836         res = "Unknown";
837       else
838         res = Table[r_type];
839       break;
840     }
841     case Triple::arm: {
842       static const char *const Table[] =  {
843         "ARM_RELOC_VANILLA",
844         "ARM_RELOC_PAIR",
845         "ARM_RELOC_SECTDIFF",
846         "ARM_RELOC_LOCAL_SECTDIFF",
847         "ARM_RELOC_PB_LA_PTR",
848         "ARM_RELOC_BR24",
849         "ARM_THUMB_RELOC_BR22",
850         "ARM_THUMB_32BIT_BRANCH",
851         "ARM_RELOC_HALF",
852         "ARM_RELOC_HALF_SECTDIFF" };
853
854       if (r_type > 9)
855         res = "Unknown";
856       else
857         res = Table[r_type];
858       break;
859     }
860     case Triple::ppc: {
861       static const char *const Table[] =  {
862         "PPC_RELOC_VANILLA",
863         "PPC_RELOC_PAIR",
864         "PPC_RELOC_BR14",
865         "PPC_RELOC_BR24",
866         "PPC_RELOC_HI16",
867         "PPC_RELOC_LO16",
868         "PPC_RELOC_HA16",
869         "PPC_RELOC_LO14",
870         "PPC_RELOC_SECTDIFF",
871         "PPC_RELOC_PB_LA_PTR",
872         "PPC_RELOC_HI16_SECTDIFF",
873         "PPC_RELOC_LO16_SECTDIFF",
874         "PPC_RELOC_HA16_SECTDIFF",
875         "PPC_RELOC_JBSR",
876         "PPC_RELOC_LO14_SECTDIFF",
877         "PPC_RELOC_LOCAL_SECTDIFF" };
878
879       res = Table[r_type];
880       break;
881     }
882     case Triple::UnknownArch:
883       res = "Unknown";
884       break;
885   }
886   Result.append(res.begin(), res.end());
887   return object_error::success;
888 }
889 error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
890                                                         int64_t &Res) const {
891   InMemoryStruct<macho::RelocationEntry> RE;
892   getRelocation(Rel, RE);
893   bool isExtern = (RE->Word1 >> 27) & 1;
894   Res = 0;
895   if (!isExtern) {
896     const uint8_t* sectAddress = base();
897     if (MachOObj->is64Bit()) {
898       const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]);
899       sectAddress += Sect->Offset;
900     } else {
901       const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
902       sectAddress += Sect->Offset;
903     }
904     Res = reinterpret_cast<uintptr_t>(sectAddress);
905   }
906   return object_error::success;
907 }
908
909 // Helper to advance a section or symbol iterator multiple increments at a time.
910 template<class T>
911 error_code advance(T &it, size_t Val) {
912   error_code ec;
913   while (Val--) {
914     it.increment(ec);
915   }
916   return ec;
917 }
918
919 template<class T>
920 void advanceTo(T &it, size_t Val) {
921   if (error_code ec = advance(it, Val))
922     report_fatal_error(ec.message());
923 }
924
925 void MachOObjectFile::printRelocationTargetName(
926                                      InMemoryStruct<macho::RelocationEntry>& RE,
927                                      raw_string_ostream &fmt) const {
928   unsigned Arch = getArch();
929   bool isScattered = (Arch != Triple::x86_64) &&
930                      (RE->Word0 & macho::RF_Scattered);
931
932   // Target of a scattered relocation is an address.  In the interest of
933   // generating pretty output, scan through the symbol table looking for a
934   // symbol that aligns with that address.  If we find one, print it.
935   // Otherwise, we just print the hex address of the target.
936   if (isScattered) {
937     uint32_t Val = RE->Word1;
938
939     error_code ec;
940     for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
941         SI.increment(ec)) {
942       if (ec) report_fatal_error(ec.message());
943
944       uint64_t Addr;
945       StringRef Name;
946
947       if ((ec = SI->getAddress(Addr)))
948         report_fatal_error(ec.message());
949       if (Addr != Val) continue;
950       if ((ec = SI->getName(Name)))
951         report_fatal_error(ec.message());
952       fmt << Name;
953       return;
954     }
955
956     // If we couldn't find a symbol that this relocation refers to, try
957     // to find a section beginning instead.
958     for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
959          SI.increment(ec)) {
960       if (ec) report_fatal_error(ec.message());
961
962       uint64_t Addr;
963       StringRef Name;
964
965       if ((ec = SI->getAddress(Addr)))
966         report_fatal_error(ec.message());
967       if (Addr != Val) continue;
968       if ((ec = SI->getName(Name)))
969         report_fatal_error(ec.message());
970       fmt << Name;
971       return;
972     }
973
974     fmt << format("0x%x", Val);
975     return;
976   }
977
978   StringRef S;
979   bool isExtern = (RE->Word1 >> 27) & 1;
980   uint32_t Val = RE->Word1 & 0xFFFFFF;
981
982   if (isExtern) {
983     symbol_iterator SI = begin_symbols();
984     advanceTo(SI, Val);
985     SI->getName(S);
986   } else {
987     section_iterator SI = begin_sections();
988     advanceTo(SI, Val);
989     SI->getName(S);
990   }
991
992   fmt << S;
993 }
994
995 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
996                                           SmallVectorImpl<char> &Result) const {
997   InMemoryStruct<macho::RelocationEntry> RE;
998   getRelocation(Rel, RE);
999
1000   unsigned Arch = getArch();
1001   bool isScattered = (Arch != Triple::x86_64) &&
1002                      (RE->Word0 & macho::RF_Scattered);
1003
1004   std::string fmtbuf;
1005   raw_string_ostream fmt(fmtbuf);
1006
1007   unsigned Type;
1008   if (isScattered)
1009     Type = (RE->Word0 >> 24) & 0xF;
1010   else
1011     Type = (RE->Word1 >> 28) & 0xF;
1012
1013   bool isPCRel;
1014   if (isScattered)
1015     isPCRel = ((RE->Word0 >> 30) & 1);
1016   else
1017     isPCRel = ((RE->Word1 >> 24) & 1);
1018
1019   // Determine any addends that should be displayed with the relocation.
1020   // These require decoding the relocation type, which is triple-specific.
1021
1022   // X86_64 has entirely custom relocation types.
1023   if (Arch == Triple::x86_64) {
1024     bool isPCRel = ((RE->Word1 >> 24) & 1);
1025
1026     switch (Type) {
1027       case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD
1028       case macho::RIT_X86_64_GOT: {     // X86_64_RELOC_GOT
1029         printRelocationTargetName(RE, fmt);
1030         fmt << "@GOT";
1031         if (isPCRel) fmt << "PCREL";
1032         break;
1033       }
1034       case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
1035         InMemoryStruct<macho::RelocationEntry> RENext;
1036         DataRefImpl RelNext = Rel;
1037         RelNext.d.a++;
1038         getRelocation(RelNext, RENext);
1039
1040         // X86_64_SUBTRACTOR must be followed by a relocation of type
1041         // X86_64_RELOC_UNSIGNED.
1042         // NOTE: Scattered relocations don't exist on x86_64.
1043         unsigned RType = (RENext->Word1 >> 28) & 0xF;
1044         if (RType != 0)
1045           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1046                              "X86_64_RELOC_SUBTRACTOR.");
1047
1048         // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
1049         // X86_64_SUBTRACTOR contains to the subtrahend.
1050         printRelocationTargetName(RENext, fmt);
1051         fmt << "-";
1052         printRelocationTargetName(RE, fmt);
1053         break;
1054       }
1055       case macho::RIT_X86_64_TLV:
1056         printRelocationTargetName(RE, fmt);
1057         fmt << "@TLV";
1058         if (isPCRel) fmt << "P";
1059         break;
1060       case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
1061         printRelocationTargetName(RE, fmt);
1062         fmt << "-1";
1063         break;
1064       case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
1065         printRelocationTargetName(RE, fmt);
1066         fmt << "-2";
1067         break;
1068       case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
1069         printRelocationTargetName(RE, fmt);
1070         fmt << "-4";
1071         break;
1072       default:
1073         printRelocationTargetName(RE, fmt);
1074         break;
1075     }
1076   // X86 and ARM share some relocation types in common.
1077   } else if (Arch == Triple::x86 || Arch == Triple::arm) {
1078     // Generic relocation types...
1079     switch (Type) {
1080       case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
1081         return object_error::success;
1082       case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
1083         InMemoryStruct<macho::RelocationEntry> RENext;
1084         DataRefImpl RelNext = Rel;
1085         RelNext.d.a++;
1086         getRelocation(RelNext, RENext);
1087
1088         // X86 sect diff's must be followed by a relocation of type
1089         // GENERIC_RELOC_PAIR.
1090         bool isNextScattered = (Arch != Triple::x86_64) &&
1091                                (RENext->Word0 & macho::RF_Scattered);
1092         unsigned RType;
1093         if (isNextScattered)
1094           RType = (RENext->Word0 >> 24) & 0xF;
1095         else
1096           RType = (RENext->Word1 >> 28) & 0xF;
1097         if (RType != 1)
1098           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1099                              "GENERIC_RELOC_SECTDIFF.");
1100
1101         printRelocationTargetName(RE, fmt);
1102         fmt << "-";
1103         printRelocationTargetName(RENext, fmt);
1104         break;
1105       }
1106     }
1107
1108     if (Arch == Triple::x86) {
1109       // All X86 relocations that need special printing were already
1110       // handled in the generic code.
1111       switch (Type) {
1112         case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
1113           InMemoryStruct<macho::RelocationEntry> RENext;
1114           DataRefImpl RelNext = Rel;
1115           RelNext.d.a++;
1116           getRelocation(RelNext, RENext);
1117
1118           // X86 sect diff's must be followed by a relocation of type
1119           // GENERIC_RELOC_PAIR.
1120           bool isNextScattered = (Arch != Triple::x86_64) &&
1121                                (RENext->Word0 & macho::RF_Scattered);
1122           unsigned RType;
1123           if (isNextScattered)
1124             RType = (RENext->Word0 >> 24) & 0xF;
1125           else
1126             RType = (RENext->Word1 >> 28) & 0xF;
1127           if (RType != 1)
1128             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1129                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
1130
1131           printRelocationTargetName(RE, fmt);
1132           fmt << "-";
1133           printRelocationTargetName(RENext, fmt);
1134           break;
1135         }
1136         case macho::RIT_Generic_TLV: {
1137           printRelocationTargetName(RE, fmt);
1138           fmt << "@TLV";
1139           if (isPCRel) fmt << "P";
1140           break;
1141         }
1142         default:
1143           printRelocationTargetName(RE, fmt);
1144       }
1145     } else { // ARM-specific relocations
1146       switch (Type) {
1147         case macho::RIT_ARM_Half:             // ARM_RELOC_HALF
1148         case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
1149           // Half relocations steal a bit from the length field to encode
1150           // whether this is an upper16 or a lower16 relocation.
1151           bool isUpper;
1152           if (isScattered)
1153             isUpper = (RE->Word0 >> 28) & 1;
1154           else
1155             isUpper = (RE->Word1 >> 25) & 1;
1156
1157           if (isUpper)
1158             fmt << ":upper16:(";
1159           else
1160             fmt << ":lower16:(";
1161           printRelocationTargetName(RE, fmt);
1162
1163           InMemoryStruct<macho::RelocationEntry> RENext;
1164           DataRefImpl RelNext = Rel;
1165           RelNext.d.a++;
1166           getRelocation(RelNext, RENext);
1167
1168           // ARM half relocs must be followed by a relocation of type
1169           // ARM_RELOC_PAIR.
1170           bool isNextScattered = (Arch != Triple::x86_64) &&
1171                                  (RENext->Word0 & macho::RF_Scattered);
1172           unsigned RType;
1173           if (isNextScattered)
1174             RType = (RENext->Word0 >> 24) & 0xF;
1175           else
1176             RType = (RENext->Word1 >> 28) & 0xF;
1177
1178           if (RType != 1)
1179             report_fatal_error("Expected ARM_RELOC_PAIR after "
1180                                "GENERIC_RELOC_HALF");
1181
1182           // NOTE: The half of the target virtual address is stashed in the
1183           // address field of the secondary relocation, but we can't reverse
1184           // engineer the constant offset from it without decoding the movw/movt
1185           // instruction to find the other half in its immediate field.
1186
1187           // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1188           // symbol/section pointer of the follow-on relocation.
1189           if (Type == macho::RIT_ARM_HalfDifference) {
1190             fmt << "-";
1191             printRelocationTargetName(RENext, fmt);
1192           }
1193
1194           fmt << ")";
1195           break;
1196         }
1197         default: {
1198           printRelocationTargetName(RE, fmt);
1199         }
1200       }
1201     }
1202   } else
1203     printRelocationTargetName(RE, fmt);
1204
1205   fmt.flush();
1206   Result.append(fmtbuf.begin(), fmtbuf.end());
1207   return object_error::success;
1208 }
1209
1210 error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
1211                                                 bool &Result) const {
1212   InMemoryStruct<macho::RelocationEntry> RE;
1213   getRelocation(Rel, RE);
1214
1215   unsigned Arch = getArch();
1216   bool isScattered = (Arch != Triple::x86_64) &&
1217                      (RE->Word0 & macho::RF_Scattered);
1218   unsigned Type;
1219   if (isScattered)
1220     Type = (RE->Word0 >> 24) & 0xF;
1221   else
1222     Type = (RE->Word1 >> 28) & 0xF;
1223
1224   Result = false;
1225
1226   // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1227   // is always hidden.
1228   if (Arch == Triple::x86 || Arch == Triple::arm) {
1229     if (Type == macho::RIT_Pair) Result = true;
1230   } else if (Arch == Triple::x86_64) {
1231     // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1232     // an X864_64_RELOC_SUBTRACTOR.
1233     if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
1234       DataRefImpl RelPrev = Rel;
1235       RelPrev.d.a--;
1236       InMemoryStruct<macho::RelocationEntry> REPrev;
1237       getRelocation(RelPrev, REPrev);
1238
1239       unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
1240
1241       if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
1242     }
1243   }
1244
1245   return object_error::success;
1246 }
1247
1248 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1249                                            LibraryRef &Res) const {
1250   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1251 }
1252
1253 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1254                                            StringRef &Res) const {
1255   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1256 }
1257
1258
1259 /*===-- Miscellaneous -----------------------------------------------------===*/
1260
1261 uint8_t MachOObjectFile::getBytesInAddress() const {
1262   return MachOObj->is64Bit() ? 8 : 4;
1263 }
1264
1265 StringRef MachOObjectFile::getFileFormatName() const {
1266   if (!MachOObj->is64Bit()) {
1267     switch (MachOObj->getHeader().CPUType) {
1268     case llvm::MachO::CPUTypeI386:
1269       return "Mach-O 32-bit i386";
1270     case llvm::MachO::CPUTypeARM:
1271       return "Mach-O arm";
1272     case llvm::MachO::CPUTypePowerPC:
1273       return "Mach-O 32-bit ppc";
1274     default:
1275       assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 &&
1276              "64-bit object file when we're not 64-bit?");
1277       return "Mach-O 32-bit unknown";
1278     }
1279   }
1280
1281   // Make sure the cpu type has the correct mask.
1282   assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64)
1283          == llvm::MachO::CPUArchABI64 &&
1284          "32-bit object file when we're 64-bit?");
1285
1286   switch (MachOObj->getHeader().CPUType) {
1287   case llvm::MachO::CPUTypeX86_64:
1288     return "Mach-O 64-bit x86-64";
1289   case llvm::MachO::CPUTypePowerPC64:
1290     return "Mach-O 64-bit ppc64";
1291   default:
1292     return "Mach-O 64-bit unknown";
1293   }
1294 }
1295
1296 unsigned MachOObjectFile::getArch() const {
1297   switch (MachOObj->getHeader().CPUType) {
1298   case llvm::MachO::CPUTypeI386:
1299     return Triple::x86;
1300   case llvm::MachO::CPUTypeX86_64:
1301     return Triple::x86_64;
1302   case llvm::MachO::CPUTypeARM:
1303     return Triple::arm;
1304   case llvm::MachO::CPUTypePowerPC:
1305     return Triple::ppc;
1306   case llvm::MachO::CPUTypePowerPC64:
1307     return Triple::ppc64;
1308   default:
1309     return Triple::UnknownArch;
1310   }
1311 }
1312
1313 } // end namespace object
1314 } // end namespace llvm