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