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