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