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