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