xref: /llvm-project/llvm/lib/Object/MachOObjectFile.cpp (revision 20122a436c31f61a0063f10759589ec0c73bac31)
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/Support/DataExtractor.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/Host.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <cctype>
23 #include <cstring>
24 #include <limits>
25 
26 using namespace llvm;
27 using namespace object;
28 
29 namespace llvm {
30 namespace object {
31 
32 struct nlist_base {
33   uint32_t n_strx;
34   uint8_t n_type;
35   uint8_t n_sect;
36   uint16_t n_desc;
37 };
38 
39 struct section_base {
40   char sectname[16];
41   char segname[16];
42 };
43 
44 template<typename T>
45 static void SwapValue(T &Value) {
46   Value = sys::SwapByteOrder(Value);
47 }
48 
49 template<typename T>
50 static void SwapStruct(T &Value);
51 
52 template<>
53 void SwapStruct(MachO::any_relocation_info &H) {
54   SwapValue(H.r_word0);
55   SwapValue(H.r_word1);
56 }
57 
58 template<>
59 void SwapStruct(MachO::load_command &L) {
60   SwapValue(L.cmd);
61   SwapValue(L.cmdsize);
62 }
63 
64 template<>
65 void SwapStruct(nlist_base &S) {
66   SwapValue(S.n_strx);
67   SwapValue(S.n_desc);
68 }
69 
70 template<>
71 void SwapStruct(MachO::section &S) {
72   SwapValue(S.addr);
73   SwapValue(S.size);
74   SwapValue(S.offset);
75   SwapValue(S.align);
76   SwapValue(S.reloff);
77   SwapValue(S.nreloc);
78   SwapValue(S.flags);
79   SwapValue(S.reserved1);
80   SwapValue(S.reserved2);
81 }
82 
83 template<>
84 void SwapStruct(MachO::section_64 &S) {
85   SwapValue(S.addr);
86   SwapValue(S.size);
87   SwapValue(S.offset);
88   SwapValue(S.align);
89   SwapValue(S.reloff);
90   SwapValue(S.nreloc);
91   SwapValue(S.flags);
92   SwapValue(S.reserved1);
93   SwapValue(S.reserved2);
94   SwapValue(S.reserved3);
95 }
96 
97 template<>
98 void SwapStruct(MachO::nlist &S) {
99   SwapValue(S.n_strx);
100   SwapValue(S.n_desc);
101   SwapValue(S.n_value);
102 }
103 
104 template<>
105 void SwapStruct(MachO::nlist_64 &S) {
106   SwapValue(S.n_strx);
107   SwapValue(S.n_desc);
108   SwapValue(S.n_value);
109 }
110 
111 template<>
112 void SwapStruct(MachO::mach_header &H) {
113   SwapValue(H.magic);
114   SwapValue(H.cputype);
115   SwapValue(H.cpusubtype);
116   SwapValue(H.filetype);
117   SwapValue(H.ncmds);
118   SwapValue(H.sizeofcmds);
119   SwapValue(H.flags);
120 }
121 
122 template<>
123 void SwapStruct(MachO::mach_header_64 &H) {
124   SwapValue(H.magic);
125   SwapValue(H.cputype);
126   SwapValue(H.cpusubtype);
127   SwapValue(H.filetype);
128   SwapValue(H.ncmds);
129   SwapValue(H.sizeofcmds);
130   SwapValue(H.flags);
131   SwapValue(H.reserved);
132 }
133 
134 template<>
135 void SwapStruct(MachO::symtab_command &C) {
136   SwapValue(C.cmd);
137   SwapValue(C.cmdsize);
138   SwapValue(C.symoff);
139   SwapValue(C.nsyms);
140   SwapValue(C.stroff);
141   SwapValue(C.strsize);
142 }
143 
144 template<>
145 void SwapStruct(MachO::dysymtab_command &C) {
146   SwapValue(C.cmd);
147   SwapValue(C.cmdsize);
148   SwapValue(C.ilocalsym);
149   SwapValue(C.nlocalsym);
150   SwapValue(C.iextdefsym);
151   SwapValue(C.nextdefsym);
152   SwapValue(C.iundefsym);
153   SwapValue(C.nundefsym);
154   SwapValue(C.tocoff);
155   SwapValue(C.ntoc);
156   SwapValue(C.modtaboff);
157   SwapValue(C.nmodtab);
158   SwapValue(C.extrefsymoff);
159   SwapValue(C.nextrefsyms);
160   SwapValue(C.indirectsymoff);
161   SwapValue(C.nindirectsyms);
162   SwapValue(C.extreloff);
163   SwapValue(C.nextrel);
164   SwapValue(C.locreloff);
165   SwapValue(C.nlocrel);
166 }
167 
168 template<>
169 void SwapStruct(MachO::linkedit_data_command &C) {
170   SwapValue(C.cmd);
171   SwapValue(C.cmdsize);
172   SwapValue(C.dataoff);
173   SwapValue(C.datasize);
174 }
175 
176 template<>
177 void SwapStruct(MachO::segment_command &C) {
178   SwapValue(C.cmd);
179   SwapValue(C.cmdsize);
180   SwapValue(C.vmaddr);
181   SwapValue(C.vmsize);
182   SwapValue(C.fileoff);
183   SwapValue(C.filesize);
184   SwapValue(C.maxprot);
185   SwapValue(C.initprot);
186   SwapValue(C.nsects);
187   SwapValue(C.flags);
188 }
189 
190 template<>
191 void SwapStruct(MachO::segment_command_64 &C) {
192   SwapValue(C.cmd);
193   SwapValue(C.cmdsize);
194   SwapValue(C.vmaddr);
195   SwapValue(C.vmsize);
196   SwapValue(C.fileoff);
197   SwapValue(C.filesize);
198   SwapValue(C.maxprot);
199   SwapValue(C.initprot);
200   SwapValue(C.nsects);
201   SwapValue(C.flags);
202 }
203 
204 template<>
205 void SwapStruct(uint32_t &C) {
206   SwapValue(C);
207 }
208 
209 template<>
210 void SwapStruct(MachO::linker_options_command &C) {
211   SwapValue(C.cmd);
212   SwapValue(C.cmdsize);
213   SwapValue(C.count);
214 }
215 
216 template<>
217 void SwapStruct(MachO::data_in_code_entry &C) {
218   SwapValue(C.offset);
219   SwapValue(C.length);
220   SwapValue(C.kind);
221 }
222 
223 template<typename T>
224 T getStruct(const MachOObjectFile *O, const char *P) {
225   T Cmd;
226   memcpy(&Cmd, P, sizeof(T));
227   if (O->isLittleEndian() != sys::IsLittleEndianHost)
228     SwapStruct(Cmd);
229   return Cmd;
230 }
231 
232 static uint32_t
233 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
234                                  const MachOObjectFile::LoadCommandInfo &L) {
235   if (O->is64Bit()) {
236     MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
237     return S.nsects;
238   }
239   MachO::segment_command S = O->getSegmentLoadCommand(L);
240   return S.nsects;
241 }
242 
243 static const char *
244 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
245               unsigned Sec) {
246   uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
247 
248   bool Is64 = O->is64Bit();
249   unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
250                                     sizeof(MachO::segment_command);
251   unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
252                                 sizeof(MachO::section);
253 
254   uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
255   return reinterpret_cast<const char*>(SectionAddr);
256 }
257 
258 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
259   return O->getData().substr(Offset, 1).data();
260 }
261 
262 static nlist_base
263 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
264   const char *P = reinterpret_cast<const char *>(DRI.p);
265   return getStruct<nlist_base>(O, P);
266 }
267 
268 static StringRef parseSegmentOrSectionName(const char *P) {
269   if (P[15] == 0)
270     // Null terminated.
271     return P;
272   // Not null terminated, so this is a 16 char string.
273   return StringRef(P, 16);
274 }
275 
276 // Helper to advance a section or symbol iterator multiple increments at a time.
277 template<class T>
278 static void advance(T &it, size_t Val) {
279   while (Val--)
280     ++it;
281 }
282 
283 static unsigned getCPUType(const MachOObjectFile *O) {
284   return O->getHeader().cputype;
285 }
286 
287 static void printRelocationTargetName(const MachOObjectFile *O,
288                                       const MachO::any_relocation_info &RE,
289                                       raw_string_ostream &fmt) {
290   bool IsScattered = O->isRelocationScattered(RE);
291 
292   // Target of a scattered relocation is an address.  In the interest of
293   // generating pretty output, scan through the symbol table looking for a
294   // symbol that aligns with that address.  If we find one, print it.
295   // Otherwise, we just print the hex address of the target.
296   if (IsScattered) {
297     uint32_t Val = O->getPlainRelocationSymbolNum(RE);
298 
299     for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols();
300          SI != SE; ++SI) {
301       error_code ec;
302       uint64_t Addr;
303       StringRef Name;
304 
305       if ((ec = SI->getAddress(Addr)))
306         report_fatal_error(ec.message());
307       if (Addr != Val) continue;
308       if ((ec = SI->getName(Name)))
309         report_fatal_error(ec.message());
310       fmt << Name;
311       return;
312     }
313 
314     // If we couldn't find a symbol that this relocation refers to, try
315     // to find a section beginning instead.
316     for (section_iterator SI = O->begin_sections(), SE = O->end_sections();
317          SI != SE; ++SI) {
318       error_code ec;
319       uint64_t Addr;
320       StringRef Name;
321 
322       if ((ec = SI->getAddress(Addr)))
323         report_fatal_error(ec.message());
324       if (Addr != Val) continue;
325       if ((ec = SI->getName(Name)))
326         report_fatal_error(ec.message());
327       fmt << Name;
328       return;
329     }
330 
331     fmt << format("0x%x", Val);
332     return;
333   }
334 
335   StringRef S;
336   bool isExtern = O->getPlainRelocationExternal(RE);
337   uint64_t Val = O->getPlainRelocationSymbolNum(RE);
338 
339   if (isExtern) {
340     symbol_iterator SI = O->begin_symbols();
341     advance(SI, Val);
342     SI->getName(S);
343   } else {
344     section_iterator SI = O->begin_sections();
345     // Adjust for the fact that sections are 1-indexed.
346     advance(SI, Val - 1);
347     SI->getName(S);
348   }
349 
350   fmt << S;
351 }
352 
353 static uint32_t
354 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
355   return RE.r_word0;
356 }
357 
358 static unsigned
359 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
360   return RE.r_word0 & 0xffffff;
361 }
362 
363 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
364                                     const MachO::any_relocation_info &RE) {
365   if (O->isLittleEndian())
366     return (RE.r_word1 >> 24) & 1;
367   return (RE.r_word1 >> 7) & 1;
368 }
369 
370 static bool
371 getScatteredRelocationPCRel(const MachOObjectFile *O,
372                             const MachO::any_relocation_info &RE) {
373   return (RE.r_word0 >> 30) & 1;
374 }
375 
376 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
377                                          const MachO::any_relocation_info &RE) {
378   if (O->isLittleEndian())
379     return (RE.r_word1 >> 25) & 3;
380   return (RE.r_word1 >> 5) & 3;
381 }
382 
383 static unsigned
384 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
385   return (RE.r_word0 >> 28) & 3;
386 }
387 
388 static unsigned getPlainRelocationType(const MachOObjectFile *O,
389                                        const MachO::any_relocation_info &RE) {
390   if (O->isLittleEndian())
391     return RE.r_word1 >> 28;
392   return RE.r_word1 & 0xf;
393 }
394 
395 static unsigned
396 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
397   return (RE.r_word0 >> 24) & 0xf;
398 }
399 
400 static uint32_t getSectionFlags(const MachOObjectFile *O,
401                                 DataRefImpl Sec) {
402   if (O->is64Bit()) {
403     MachO::section_64 Sect = O->getSection64(Sec);
404     return Sect.flags;
405   }
406   MachO::section Sect = O->getSection(Sec);
407   return Sect.flags;
408 }
409 
410 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
411                                  bool Is64bits, error_code &EC,
412                                  bool BufferOwned)
413     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
414       SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) {
415   uint32_t LoadCommandCount = this->getHeader().ncmds;
416   MachO::LoadCommandType SegmentLoadType = is64Bit() ?
417     MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
418 
419   MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
420   for (unsigned I = 0; ; ++I) {
421     if (Load.C.cmd == MachO::LC_SYMTAB) {
422       assert(!SymtabLoadCmd && "Multiple symbol tables");
423       SymtabLoadCmd = Load.Ptr;
424     } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
425       assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
426       DysymtabLoadCmd = Load.Ptr;
427     } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
428       assert(!DataInCodeLoadCmd && "Multiple data in code tables");
429       DataInCodeLoadCmd = Load.Ptr;
430     } else if (Load.C.cmd == SegmentLoadType) {
431       uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
432       for (unsigned J = 0; J < NumSections; ++J) {
433         const char *Sec = getSectionPtr(this, Load, J);
434         Sections.push_back(Sec);
435       }
436     }
437 
438     if (I == LoadCommandCount - 1)
439       break;
440     else
441       Load = getNextLoadCommandInfo(Load);
442   }
443 }
444 
445 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
446   unsigned SymbolTableEntrySize = is64Bit() ?
447     sizeof(MachO::nlist_64) :
448     sizeof(MachO::nlist);
449   Symb.p += SymbolTableEntrySize;
450 }
451 
452 error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
453                                           StringRef &Res) const {
454   StringRef StringTable = getStringTableData();
455   nlist_base Entry = getSymbolTableEntryBase(this, Symb);
456   const char *Start = &StringTable.data()[Entry.n_strx];
457   Res = StringRef(Start);
458   return object_error::success;
459 }
460 
461 error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
462                                              uint64_t &Res) const {
463   if (is64Bit()) {
464     MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
465     Res = Entry.n_value;
466   } else {
467     MachO::nlist Entry = getSymbolTableEntry(Symb);
468     Res = Entry.n_value;
469   }
470   return object_error::success;
471 }
472 
473 error_code
474 MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
475                                      uint64_t &Res) const {
476   nlist_base Entry = getSymbolTableEntryBase(this, Symb);
477   getSymbolAddress(Symb, Res);
478   if (Entry.n_sect) {
479     uint64_t Delta;
480     DataRefImpl SecRel;
481     SecRel.d.a = Entry.n_sect-1;
482     if (is64Bit()) {
483       MachO::section_64 Sec = getSection64(SecRel);
484       Delta = Sec.offset - Sec.addr;
485     } else {
486       MachO::section Sec = getSection(SecRel);
487       Delta = Sec.offset - Sec.addr;
488     }
489 
490     Res += Delta;
491   }
492 
493   return object_error::success;
494 }
495 
496 error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
497                                                uint32_t &Result) const {
498   uint32_t flags = getSymbolFlags(DRI);
499   if (flags & SymbolRef::SF_Common) {
500     nlist_base Entry = getSymbolTableEntryBase(this, DRI);
501     Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
502   } else {
503     Result = 0;
504   }
505   return object_error::success;
506 }
507 
508 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
509                                           uint64_t &Result) const {
510   uint64_t BeginOffset;
511   uint64_t EndOffset = 0;
512   uint8_t SectionIndex;
513 
514   nlist_base Entry = getSymbolTableEntryBase(this, DRI);
515   uint64_t Value;
516   getSymbolAddress(DRI, Value);
517 
518   BeginOffset = Value;
519 
520   SectionIndex = Entry.n_sect;
521   if (!SectionIndex) {
522     uint32_t flags = getSymbolFlags(DRI);
523     if (flags & SymbolRef::SF_Common)
524       Result = Value;
525     else
526       Result = UnknownAddressOrSize;
527     return object_error::success;
528   }
529   // Unfortunately symbols are unsorted so we need to touch all
530   // symbols from load command
531   for (symbol_iterator I = begin_symbols(), E = end_symbols(); I != E; ++I) {
532     DataRefImpl DRI = I->getRawDataRefImpl();
533     Entry = getSymbolTableEntryBase(this, DRI);
534     getSymbolAddress(DRI, Value);
535     if (Entry.n_sect == SectionIndex && Value > BeginOffset)
536       if (!EndOffset || Value < EndOffset)
537         EndOffset = Value;
538   }
539   if (!EndOffset) {
540     uint64_t Size;
541     DataRefImpl Sec;
542     Sec.d.a = SectionIndex-1;
543     getSectionSize(Sec, Size);
544     getSectionAddress(Sec, EndOffset);
545     EndOffset += Size;
546   }
547   Result = EndOffset - BeginOffset;
548   return object_error::success;
549 }
550 
551 error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
552                                           SymbolRef::Type &Res) const {
553   nlist_base Entry = getSymbolTableEntryBase(this, Symb);
554   uint8_t n_type = Entry.n_type;
555 
556   Res = SymbolRef::ST_Other;
557 
558   // If this is a STAB debugging symbol, we can do nothing more.
559   if (n_type & MachO::N_STAB) {
560     Res = SymbolRef::ST_Debug;
561     return object_error::success;
562   }
563 
564   switch (n_type & MachO::N_TYPE) {
565     case MachO::N_UNDF :
566       Res = SymbolRef::ST_Unknown;
567       break;
568     case MachO::N_SECT :
569       Res = SymbolRef::ST_Function;
570       break;
571   }
572   return object_error::success;
573 }
574 
575 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
576   nlist_base Entry = getSymbolTableEntryBase(this, DRI);
577 
578   uint8_t MachOType = Entry.n_type;
579   uint16_t MachOFlags = Entry.n_desc;
580 
581   // TODO: Correctly set SF_ThreadLocal
582   uint32_t Result = SymbolRef::SF_None;
583 
584   if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
585     Result |= SymbolRef::SF_Undefined;
586 
587   if (MachOType & MachO::N_STAB)
588     Result |= SymbolRef::SF_FormatSpecific;
589 
590   if (MachOType & MachO::N_EXT) {
591     Result |= SymbolRef::SF_Global;
592     if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
593       uint64_t Value;
594       getSymbolAddress(DRI, Value);
595       if (Value)
596         Result |= SymbolRef::SF_Common;
597     }
598   }
599 
600   if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
601     Result |= SymbolRef::SF_Weak;
602 
603   if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
604     Result |= SymbolRef::SF_Absolute;
605 
606   return Result;
607 }
608 
609 error_code
610 MachOObjectFile::getSymbolSection(DataRefImpl Symb,
611                                   section_iterator &Res) const {
612   nlist_base Entry = getSymbolTableEntryBase(this, Symb);
613   uint8_t index = Entry.n_sect;
614 
615   if (index == 0) {
616     Res = end_sections();
617   } else {
618     DataRefImpl DRI;
619     DRI.d.a = index - 1;
620     Res = section_iterator(SectionRef(DRI, this));
621   }
622 
623   return object_error::success;
624 }
625 
626 error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
627                                            uint64_t &Val) const {
628   report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
629 }
630 
631 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
632   Sec.d.a++;
633 }
634 
635 error_code
636 MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
637   ArrayRef<char> Raw = getSectionRawName(Sec);
638   Result = parseSegmentOrSectionName(Raw.data());
639   return object_error::success;
640 }
641 
642 error_code
643 MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
644   if (is64Bit()) {
645     MachO::section_64 Sect = getSection64(Sec);
646     Res = Sect.addr;
647   } else {
648     MachO::section Sect = getSection(Sec);
649     Res = Sect.addr;
650   }
651   return object_error::success;
652 }
653 
654 error_code
655 MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
656   if (is64Bit()) {
657     MachO::section_64 Sect = getSection64(Sec);
658     Res = Sect.size;
659   } else {
660     MachO::section Sect = getSection(Sec);
661     Res = Sect.size;
662   }
663 
664   return object_error::success;
665 }
666 
667 error_code
668 MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
669   uint32_t Offset;
670   uint64_t Size;
671 
672   if (is64Bit()) {
673     MachO::section_64 Sect = getSection64(Sec);
674     Offset = Sect.offset;
675     Size = Sect.size;
676   } else {
677     MachO::section Sect = getSection(Sec);
678     Offset = Sect.offset;
679     Size = Sect.size;
680   }
681 
682   Res = this->getData().substr(Offset, Size);
683   return object_error::success;
684 }
685 
686 error_code
687 MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
688   uint32_t Align;
689   if (is64Bit()) {
690     MachO::section_64 Sect = getSection64(Sec);
691     Align = Sect.align;
692   } else {
693     MachO::section Sect = getSection(Sec);
694     Align = Sect.align;
695   }
696 
697   Res = uint64_t(1) << Align;
698   return object_error::success;
699 }
700 
701 error_code
702 MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
703   uint32_t Flags = getSectionFlags(this, Sec);
704   Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
705   return object_error::success;
706 }
707 
708 error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const {
709   // FIXME: Unimplemented.
710   Result = false;
711   return object_error::success;
712 }
713 
714 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const {
715   // FIXME: Unimplemented.
716   Result = false;
717   return object_error::success;
718 }
719 
720 error_code
721 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
722                                                bool &Result) const {
723   // FIXME: Unimplemented.
724   Result = true;
725   return object_error::success;
726 }
727 
728 error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
729                                              bool &Result) const {
730   // FIXME: Unimplemented.
731   Result = false;
732   return object_error::success;
733 }
734 
735 error_code
736 MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
737   uint32_t Flags = getSectionFlags(this, Sec);
738   unsigned SectionType = Flags & MachO::SECTION_TYPE;
739   Res = SectionType == MachO::S_ZEROFILL ||
740     SectionType == MachO::S_GB_ZEROFILL;
741   return object_error::success;
742 }
743 
744 error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
745                                                   bool &Result) const {
746   // Consider using the code from isSectionText to look for __const sections.
747   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
748   // to use section attributes to distinguish code from data.
749 
750   // FIXME: Unimplemented.
751   Result = false;
752   return object_error::success;
753 }
754 
755 error_code
756 MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
757                                        bool &Result) const {
758   SymbolRef::Type ST;
759   this->getSymbolType(Symb, ST);
760   if (ST == SymbolRef::ST_Unknown) {
761     Result = false;
762     return object_error::success;
763   }
764 
765   uint64_t SectBegin, SectEnd;
766   getSectionAddress(Sec, SectBegin);
767   getSectionSize(Sec, SectEnd);
768   SectEnd += SectBegin;
769 
770   uint64_t SymAddr;
771   getSymbolAddress(Symb, SymAddr);
772   Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
773 
774   return object_error::success;
775 }
776 
777 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
778   uint32_t Offset;
779   if (is64Bit()) {
780     MachO::section_64 Sect = getSection64(Sec);
781     Offset = Sect.reloff;
782   } else {
783     MachO::section Sect = getSection(Sec);
784     Offset = Sect.reloff;
785   }
786 
787   DataRefImpl Ret;
788   Ret.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
789   return relocation_iterator(RelocationRef(Ret, this));
790 }
791 
792 relocation_iterator
793 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
794   uint32_t Offset;
795   uint32_t Num;
796   if (is64Bit()) {
797     MachO::section_64 Sect = getSection64(Sec);
798     Offset = Sect.reloff;
799     Num = Sect.nreloc;
800   } else {
801     MachO::section Sect = getSection(Sec);
802     Offset = Sect.reloff;
803     Num = Sect.nreloc;
804   }
805 
806   const MachO::any_relocation_info *P =
807     reinterpret_cast<const MachO::any_relocation_info *>(getPtr(this, Offset));
808 
809   DataRefImpl Ret;
810   Ret.p = reinterpret_cast<uintptr_t>(P + Num);
811   return relocation_iterator(RelocationRef(Ret, this));
812 }
813 
814 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
815   const MachO::any_relocation_info *P =
816     reinterpret_cast<const MachO::any_relocation_info *>(Rel.p);
817   Rel.p = reinterpret_cast<uintptr_t>(P + 1);
818 }
819 
820 error_code
821 MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
822   report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
823 }
824 
825 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
826                                                 uint64_t &Res) const {
827   MachO::any_relocation_info RE = getRelocation(Rel);
828   Res = getAnyRelocationAddress(RE);
829   return object_error::success;
830 }
831 
832 symbol_iterator
833 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
834   MachO::any_relocation_info RE = getRelocation(Rel);
835   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
836   bool isExtern = getPlainRelocationExternal(RE);
837   if (!isExtern)
838     return end_symbols();
839 
840   MachO::symtab_command S = getSymtabLoadCommand();
841   unsigned SymbolTableEntrySize = is64Bit() ?
842     sizeof(MachO::nlist_64) :
843     sizeof(MachO::nlist);
844   uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
845   DataRefImpl Sym;
846   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
847   return symbol_iterator(SymbolRef(Sym, this));
848 }
849 
850 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
851                                               uint64_t &Res) const {
852   MachO::any_relocation_info RE = getRelocation(Rel);
853   Res = getAnyRelocationType(RE);
854   return object_error::success;
855 }
856 
857 error_code
858 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
859                                        SmallVectorImpl<char> &Result) const {
860   StringRef res;
861   uint64_t RType;
862   getRelocationType(Rel, RType);
863 
864   unsigned Arch = this->getArch();
865 
866   switch (Arch) {
867     case Triple::x86: {
868       static const char *const Table[] =  {
869         "GENERIC_RELOC_VANILLA",
870         "GENERIC_RELOC_PAIR",
871         "GENERIC_RELOC_SECTDIFF",
872         "GENERIC_RELOC_PB_LA_PTR",
873         "GENERIC_RELOC_LOCAL_SECTDIFF",
874         "GENERIC_RELOC_TLV" };
875 
876       if (RType > 5)
877         res = "Unknown";
878       else
879         res = Table[RType];
880       break;
881     }
882     case Triple::x86_64: {
883       static const char *const Table[] =  {
884         "X86_64_RELOC_UNSIGNED",
885         "X86_64_RELOC_SIGNED",
886         "X86_64_RELOC_BRANCH",
887         "X86_64_RELOC_GOT_LOAD",
888         "X86_64_RELOC_GOT",
889         "X86_64_RELOC_SUBTRACTOR",
890         "X86_64_RELOC_SIGNED_1",
891         "X86_64_RELOC_SIGNED_2",
892         "X86_64_RELOC_SIGNED_4",
893         "X86_64_RELOC_TLV" };
894 
895       if (RType > 9)
896         res = "Unknown";
897       else
898         res = Table[RType];
899       break;
900     }
901     case Triple::arm: {
902       static const char *const Table[] =  {
903         "ARM_RELOC_VANILLA",
904         "ARM_RELOC_PAIR",
905         "ARM_RELOC_SECTDIFF",
906         "ARM_RELOC_LOCAL_SECTDIFF",
907         "ARM_RELOC_PB_LA_PTR",
908         "ARM_RELOC_BR24",
909         "ARM_THUMB_RELOC_BR22",
910         "ARM_THUMB_32BIT_BRANCH",
911         "ARM_RELOC_HALF",
912         "ARM_RELOC_HALF_SECTDIFF" };
913 
914       if (RType > 9)
915         res = "Unknown";
916       else
917         res = Table[RType];
918       break;
919     }
920     case Triple::ppc: {
921       static const char *const Table[] =  {
922         "PPC_RELOC_VANILLA",
923         "PPC_RELOC_PAIR",
924         "PPC_RELOC_BR14",
925         "PPC_RELOC_BR24",
926         "PPC_RELOC_HI16",
927         "PPC_RELOC_LO16",
928         "PPC_RELOC_HA16",
929         "PPC_RELOC_LO14",
930         "PPC_RELOC_SECTDIFF",
931         "PPC_RELOC_PB_LA_PTR",
932         "PPC_RELOC_HI16_SECTDIFF",
933         "PPC_RELOC_LO16_SECTDIFF",
934         "PPC_RELOC_HA16_SECTDIFF",
935         "PPC_RELOC_JBSR",
936         "PPC_RELOC_LO14_SECTDIFF",
937         "PPC_RELOC_LOCAL_SECTDIFF" };
938 
939       if (RType > 15)
940         res = "Unknown";
941       else
942         res = Table[RType];
943       break;
944     }
945     case Triple::UnknownArch:
946       res = "Unknown";
947       break;
948   }
949   Result.append(res.begin(), res.end());
950   return object_error::success;
951 }
952 
953 error_code
954 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
955                                           SmallVectorImpl<char> &Result) const {
956   MachO::any_relocation_info RE = getRelocation(Rel);
957 
958   unsigned Arch = this->getArch();
959 
960   std::string fmtbuf;
961   raw_string_ostream fmt(fmtbuf);
962   unsigned Type = this->getAnyRelocationType(RE);
963   bool IsPCRel = this->getAnyRelocationPCRel(RE);
964 
965   // Determine any addends that should be displayed with the relocation.
966   // These require decoding the relocation type, which is triple-specific.
967 
968   // X86_64 has entirely custom relocation types.
969   if (Arch == Triple::x86_64) {
970     bool isPCRel = getAnyRelocationPCRel(RE);
971 
972     switch (Type) {
973       case MachO::X86_64_RELOC_GOT_LOAD:
974       case MachO::X86_64_RELOC_GOT: {
975         printRelocationTargetName(this, RE, fmt);
976         fmt << "@GOT";
977         if (isPCRel) fmt << "PCREL";
978         break;
979       }
980       case MachO::X86_64_RELOC_SUBTRACTOR: {
981         DataRefImpl RelNext = Rel;
982         RelNext.d.a++;
983         MachO::any_relocation_info RENext = getRelocation(RelNext);
984 
985         // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
986         // X86_64_RELOC_UNSIGNED.
987         // NOTE: Scattered relocations don't exist on x86_64.
988         unsigned RType = getAnyRelocationType(RENext);
989         if (RType != MachO::X86_64_RELOC_UNSIGNED)
990           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
991                              "X86_64_RELOC_SUBTRACTOR.");
992 
993         // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
994         // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
995         printRelocationTargetName(this, RENext, fmt);
996         fmt << "-";
997         printRelocationTargetName(this, RE, fmt);
998         break;
999       }
1000       case MachO::X86_64_RELOC_TLV:
1001         printRelocationTargetName(this, RE, fmt);
1002         fmt << "@TLV";
1003         if (isPCRel) fmt << "P";
1004         break;
1005       case MachO::X86_64_RELOC_SIGNED_1:
1006         printRelocationTargetName(this, RE, fmt);
1007         fmt << "-1";
1008         break;
1009       case MachO::X86_64_RELOC_SIGNED_2:
1010         printRelocationTargetName(this, RE, fmt);
1011         fmt << "-2";
1012         break;
1013       case MachO::X86_64_RELOC_SIGNED_4:
1014         printRelocationTargetName(this, RE, fmt);
1015         fmt << "-4";
1016         break;
1017       default:
1018         printRelocationTargetName(this, RE, fmt);
1019         break;
1020     }
1021   // X86 and ARM share some relocation types in common.
1022   } else if (Arch == Triple::x86 || Arch == Triple::arm ||
1023              Arch == Triple::ppc) {
1024     // Generic relocation types...
1025     switch (Type) {
1026       case MachO::GENERIC_RELOC_PAIR: // prints no info
1027         return object_error::success;
1028       case MachO::GENERIC_RELOC_SECTDIFF: {
1029         DataRefImpl RelNext = Rel;
1030         RelNext.d.a++;
1031         MachO::any_relocation_info RENext = getRelocation(RelNext);
1032 
1033         // X86 sect diff's must be followed by a relocation of type
1034         // GENERIC_RELOC_PAIR.
1035         unsigned RType = getAnyRelocationType(RENext);
1036 
1037         if (RType != MachO::GENERIC_RELOC_PAIR)
1038           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1039                              "GENERIC_RELOC_SECTDIFF.");
1040 
1041         printRelocationTargetName(this, RE, fmt);
1042         fmt << "-";
1043         printRelocationTargetName(this, RENext, fmt);
1044         break;
1045       }
1046     }
1047 
1048     if (Arch == Triple::x86 || Arch == Triple::ppc) {
1049       switch (Type) {
1050         case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
1051           DataRefImpl RelNext = Rel;
1052           RelNext.d.a++;
1053           MachO::any_relocation_info RENext = getRelocation(RelNext);
1054 
1055           // X86 sect diff's must be followed by a relocation of type
1056           // GENERIC_RELOC_PAIR.
1057           unsigned RType = getAnyRelocationType(RENext);
1058           if (RType != MachO::GENERIC_RELOC_PAIR)
1059             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1060                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
1061 
1062           printRelocationTargetName(this, RE, fmt);
1063           fmt << "-";
1064           printRelocationTargetName(this, RENext, fmt);
1065           break;
1066         }
1067         case MachO::GENERIC_RELOC_TLV: {
1068           printRelocationTargetName(this, RE, fmt);
1069           fmt << "@TLV";
1070           if (IsPCRel) fmt << "P";
1071           break;
1072         }
1073         default:
1074           printRelocationTargetName(this, RE, fmt);
1075       }
1076     } else { // ARM-specific relocations
1077       switch (Type) {
1078         case MachO::ARM_RELOC_HALF:
1079         case MachO::ARM_RELOC_HALF_SECTDIFF: {
1080           // Half relocations steal a bit from the length field to encode
1081           // whether this is an upper16 or a lower16 relocation.
1082           bool isUpper = getAnyRelocationLength(RE) >> 1;
1083 
1084           if (isUpper)
1085             fmt << ":upper16:(";
1086           else
1087             fmt << ":lower16:(";
1088           printRelocationTargetName(this, RE, fmt);
1089 
1090           DataRefImpl RelNext = Rel;
1091           RelNext.d.a++;
1092           MachO::any_relocation_info RENext = getRelocation(RelNext);
1093 
1094           // ARM half relocs must be followed by a relocation of type
1095           // ARM_RELOC_PAIR.
1096           unsigned RType = getAnyRelocationType(RENext);
1097           if (RType != MachO::ARM_RELOC_PAIR)
1098             report_fatal_error("Expected ARM_RELOC_PAIR after "
1099                                "ARM_RELOC_HALF");
1100 
1101           // NOTE: The half of the target virtual address is stashed in the
1102           // address field of the secondary relocation, but we can't reverse
1103           // engineer the constant offset from it without decoding the movw/movt
1104           // instruction to find the other half in its immediate field.
1105 
1106           // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1107           // symbol/section pointer of the follow-on relocation.
1108           if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1109             fmt << "-";
1110             printRelocationTargetName(this, RENext, fmt);
1111           }
1112 
1113           fmt << ")";
1114           break;
1115         }
1116         default: {
1117           printRelocationTargetName(this, RE, fmt);
1118         }
1119       }
1120     }
1121   } else
1122     printRelocationTargetName(this, RE, fmt);
1123 
1124   fmt.flush();
1125   Result.append(fmtbuf.begin(), fmtbuf.end());
1126   return object_error::success;
1127 }
1128 
1129 error_code
1130 MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
1131   unsigned Arch = getArch();
1132   uint64_t Type;
1133   getRelocationType(Rel, Type);
1134 
1135   Result = false;
1136 
1137   // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1138   // is always hidden.
1139   if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
1140     if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
1141   } else if (Arch == Triple::x86_64) {
1142     // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1143     // an X86_64_RELOC_SUBTRACTOR.
1144     if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1145       DataRefImpl RelPrev = Rel;
1146       RelPrev.d.a--;
1147       uint64_t PrevType;
1148       getRelocationType(RelPrev, PrevType);
1149       if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1150         Result = true;
1151     }
1152   }
1153 
1154   return object_error::success;
1155 }
1156 
1157 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1158                                            LibraryRef &Res) const {
1159   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1160 }
1161 
1162 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1163                                            StringRef &Res) const {
1164   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1165 }
1166 
1167 symbol_iterator MachOObjectFile::begin_symbols() const {
1168   DataRefImpl DRI;
1169   if (!SymtabLoadCmd)
1170     return symbol_iterator(SymbolRef(DRI, this));
1171 
1172   MachO::symtab_command Symtab = getSymtabLoadCommand();
1173   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1174   return symbol_iterator(SymbolRef(DRI, this));
1175 }
1176 
1177 symbol_iterator MachOObjectFile::end_symbols() const {
1178   DataRefImpl DRI;
1179   if (!SymtabLoadCmd)
1180     return symbol_iterator(SymbolRef(DRI, this));
1181 
1182   MachO::symtab_command Symtab = getSymtabLoadCommand();
1183   unsigned SymbolTableEntrySize = is64Bit() ?
1184     sizeof(MachO::nlist_64) :
1185     sizeof(MachO::nlist);
1186   unsigned Offset = Symtab.symoff +
1187     Symtab.nsyms * SymbolTableEntrySize;
1188   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1189   return symbol_iterator(SymbolRef(DRI, this));
1190 }
1191 
1192 section_iterator MachOObjectFile::begin_sections() const {
1193   DataRefImpl DRI;
1194   return section_iterator(SectionRef(DRI, this));
1195 }
1196 
1197 section_iterator MachOObjectFile::end_sections() const {
1198   DataRefImpl DRI;
1199   DRI.d.a = Sections.size();
1200   return section_iterator(SectionRef(DRI, this));
1201 }
1202 
1203 library_iterator MachOObjectFile::begin_libraries_needed() const {
1204   // TODO: implement
1205   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1206 }
1207 
1208 library_iterator MachOObjectFile::end_libraries_needed() const {
1209   // TODO: implement
1210   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1211 }
1212 
1213 uint8_t MachOObjectFile::getBytesInAddress() const {
1214   return is64Bit() ? 8 : 4;
1215 }
1216 
1217 StringRef MachOObjectFile::getFileFormatName() const {
1218   unsigned CPUType = getCPUType(this);
1219   if (!is64Bit()) {
1220     switch (CPUType) {
1221     case llvm::MachO::CPU_TYPE_I386:
1222       return "Mach-O 32-bit i386";
1223     case llvm::MachO::CPU_TYPE_ARM:
1224       return "Mach-O arm";
1225     case llvm::MachO::CPU_TYPE_POWERPC:
1226       return "Mach-O 32-bit ppc";
1227     default:
1228       assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1229              "64-bit object file when we're not 64-bit?");
1230       return "Mach-O 32-bit unknown";
1231     }
1232   }
1233 
1234   // Make sure the cpu type has the correct mask.
1235   assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1236          == llvm::MachO::CPU_ARCH_ABI64 &&
1237          "32-bit object file when we're 64-bit?");
1238 
1239   switch (CPUType) {
1240   case llvm::MachO::CPU_TYPE_X86_64:
1241     return "Mach-O 64-bit x86-64";
1242   case llvm::MachO::CPU_TYPE_POWERPC64:
1243     return "Mach-O 64-bit ppc64";
1244   default:
1245     return "Mach-O 64-bit unknown";
1246   }
1247 }
1248 
1249 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1250   switch (CPUType) {
1251   case llvm::MachO::CPU_TYPE_I386:
1252     return Triple::x86;
1253   case llvm::MachO::CPU_TYPE_X86_64:
1254     return Triple::x86_64;
1255   case llvm::MachO::CPU_TYPE_ARM:
1256     return Triple::arm;
1257   case llvm::MachO::CPU_TYPE_POWERPC:
1258     return Triple::ppc;
1259   case llvm::MachO::CPU_TYPE_POWERPC64:
1260     return Triple::ppc64;
1261   default:
1262     return Triple::UnknownArch;
1263   }
1264 }
1265 
1266 unsigned MachOObjectFile::getArch() const {
1267   return getArch(getCPUType(this));
1268 }
1269 
1270 StringRef MachOObjectFile::getLoadName() const {
1271   // TODO: Implement
1272   report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1273 }
1274 
1275 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1276   DataRefImpl DRI;
1277   DRI.d.a = Index;
1278   return section_rel_begin(DRI);
1279 }
1280 
1281 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1282   DataRefImpl DRI;
1283   DRI.d.a = Index;
1284   return section_rel_end(DRI);
1285 }
1286 
1287 dice_iterator MachOObjectFile::begin_dices() const {
1288   DataRefImpl DRI;
1289   if (!DataInCodeLoadCmd)
1290     return dice_iterator(DiceRef(DRI, this));
1291 
1292   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1293   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1294   return dice_iterator(DiceRef(DRI, this));
1295 }
1296 
1297 dice_iterator MachOObjectFile::end_dices() const {
1298   DataRefImpl DRI;
1299   if (!DataInCodeLoadCmd)
1300     return dice_iterator(DiceRef(DRI, this));
1301 
1302   MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1303   unsigned Offset = DicLC.dataoff + DicLC.datasize;
1304   DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1305   return dice_iterator(DiceRef(DRI, this));
1306 }
1307 
1308 StringRef
1309 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1310   ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1311   return parseSegmentOrSectionName(Raw.data());
1312 }
1313 
1314 ArrayRef<char>
1315 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1316   const section_base *Base =
1317     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1318   return ArrayRef<char>(Base->sectname);
1319 }
1320 
1321 ArrayRef<char>
1322 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1323   const section_base *Base =
1324     reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1325   return ArrayRef<char>(Base->segname);
1326 }
1327 
1328 bool
1329 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1330   const {
1331   if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1332     return false;
1333   return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1334 }
1335 
1336 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1337     const MachO::any_relocation_info &RE) const {
1338   if (isLittleEndian())
1339     return RE.r_word1 & 0xffffff;
1340   return RE.r_word1 >> 8;
1341 }
1342 
1343 bool MachOObjectFile::getPlainRelocationExternal(
1344     const MachO::any_relocation_info &RE) const {
1345   if (isLittleEndian())
1346     return (RE.r_word1 >> 27) & 1;
1347   return (RE.r_word1 >> 4) & 1;
1348 }
1349 
1350 bool MachOObjectFile::getScatteredRelocationScattered(
1351     const MachO::any_relocation_info &RE) const {
1352   return RE.r_word0 >> 31;
1353 }
1354 
1355 uint32_t MachOObjectFile::getScatteredRelocationValue(
1356     const MachO::any_relocation_info &RE) const {
1357   return RE.r_word1;
1358 }
1359 
1360 unsigned MachOObjectFile::getAnyRelocationAddress(
1361     const MachO::any_relocation_info &RE) const {
1362   if (isRelocationScattered(RE))
1363     return getScatteredRelocationAddress(RE);
1364   return getPlainRelocationAddress(RE);
1365 }
1366 
1367 unsigned MachOObjectFile::getAnyRelocationPCRel(
1368     const MachO::any_relocation_info &RE) const {
1369   if (isRelocationScattered(RE))
1370     return getScatteredRelocationPCRel(this, RE);
1371   return getPlainRelocationPCRel(this, RE);
1372 }
1373 
1374 unsigned MachOObjectFile::getAnyRelocationLength(
1375     const MachO::any_relocation_info &RE) const {
1376   if (isRelocationScattered(RE))
1377     return getScatteredRelocationLength(RE);
1378   return getPlainRelocationLength(this, RE);
1379 }
1380 
1381 unsigned
1382 MachOObjectFile::getAnyRelocationType(
1383                                    const MachO::any_relocation_info &RE) const {
1384   if (isRelocationScattered(RE))
1385     return getScatteredRelocationType(RE);
1386   return getPlainRelocationType(this, RE);
1387 }
1388 
1389 SectionRef
1390 MachOObjectFile::getRelocationSection(
1391                                    const MachO::any_relocation_info &RE) const {
1392   if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1393     return *end_sections();
1394   unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1395   DataRefImpl DRI;
1396   DRI.d.a = SecNum;
1397   return SectionRef(DRI, this);
1398 }
1399 
1400 MachOObjectFile::LoadCommandInfo
1401 MachOObjectFile::getFirstLoadCommandInfo() const {
1402   MachOObjectFile::LoadCommandInfo Load;
1403 
1404   unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1405                                     sizeof(MachO::mach_header);
1406   Load.Ptr = getPtr(this, HeaderSize);
1407   Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1408   return Load;
1409 }
1410 
1411 MachOObjectFile::LoadCommandInfo
1412 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1413   MachOObjectFile::LoadCommandInfo Next;
1414   Next.Ptr = L.Ptr + L.C.cmdsize;
1415   Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1416   return Next;
1417 }
1418 
1419 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1420   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1421 }
1422 
1423 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1424   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1425 }
1426 
1427 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1428                                            unsigned Index) const {
1429   const char *Sec = getSectionPtr(this, L, Index);
1430   return getStruct<MachO::section>(this, Sec);
1431 }
1432 
1433 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1434                                                 unsigned Index) const {
1435   const char *Sec = getSectionPtr(this, L, Index);
1436   return getStruct<MachO::section_64>(this, Sec);
1437 }
1438 
1439 MachO::nlist
1440 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1441   const char *P = reinterpret_cast<const char *>(DRI.p);
1442   return getStruct<MachO::nlist>(this, P);
1443 }
1444 
1445 MachO::nlist_64
1446 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1447   const char *P = reinterpret_cast<const char *>(DRI.p);
1448   return getStruct<MachO::nlist_64>(this, P);
1449 }
1450 
1451 MachO::linkedit_data_command
1452 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1453   return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1454 }
1455 
1456 MachO::segment_command
1457 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1458   return getStruct<MachO::segment_command>(this, L.Ptr);
1459 }
1460 
1461 MachO::segment_command_64
1462 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1463   return getStruct<MachO::segment_command_64>(this, L.Ptr);
1464 }
1465 
1466 MachO::linker_options_command
1467 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1468   return getStruct<MachO::linker_options_command>(this, L.Ptr);
1469 }
1470 
1471 MachO::any_relocation_info
1472 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1473   const char *P = reinterpret_cast<const char *>(Rel.p);
1474   return getStruct<MachO::any_relocation_info>(this, P);
1475 }
1476 
1477 MachO::data_in_code_entry
1478 MachOObjectFile::getDice(DataRefImpl Rel) const {
1479   const char *P = reinterpret_cast<const char *>(Rel.p);
1480   return getStruct<MachO::data_in_code_entry>(this, P);
1481 }
1482 
1483 MachO::mach_header MachOObjectFile::getHeader() const {
1484   return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1485 }
1486 
1487 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1488   return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1489 }
1490 
1491 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1492                                              const MachO::dysymtab_command &DLC,
1493                                              unsigned Index) const {
1494   uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1495   return getStruct<uint32_t>(this, getPtr(this, Offset));
1496 }
1497 
1498 MachO::data_in_code_entry
1499 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1500                                          unsigned Index) const {
1501   uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1502   return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1503 }
1504 
1505 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1506   return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1507 }
1508 
1509 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1510   return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1511 }
1512 
1513 MachO::linkedit_data_command
1514 MachOObjectFile::getDataInCodeLoadCommand() const {
1515   if (DataInCodeLoadCmd)
1516     return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1517 
1518   // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1519   MachO::linkedit_data_command Cmd;
1520   Cmd.cmd = MachO::LC_DATA_IN_CODE;
1521   Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1522   Cmd.dataoff = 0;
1523   Cmd.datasize = 0;
1524   return Cmd;
1525 }
1526 
1527 StringRef MachOObjectFile::getStringTableData() const {
1528   MachO::symtab_command S = getSymtabLoadCommand();
1529   return getData().substr(S.stroff, S.strsize);
1530 }
1531 
1532 bool MachOObjectFile::is64Bit() const {
1533   return getType() == getMachOType(false, true) ||
1534     getType() == getMachOType(true, true);
1535 }
1536 
1537 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1538                                    SmallVectorImpl<uint64_t> &Out) const {
1539   DataExtractor extractor(ObjectFile::getData(), true, 0);
1540 
1541   uint32_t offset = Index;
1542   uint64_t data = 0;
1543   while (uint64_t delta = extractor.getULEB128(&offset)) {
1544     data += delta;
1545     Out.push_back(data);
1546   }
1547 }
1548 
1549 ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
1550                                                         bool BufferOwned) {
1551   StringRef Magic = Buffer->getBuffer().slice(0, 4);
1552   error_code EC;
1553   OwningPtr<MachOObjectFile> Ret;
1554   if (Magic == "\xFE\xED\xFA\xCE")
1555     Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
1556   else if (Magic == "\xCE\xFA\xED\xFE")
1557     Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
1558   else if (Magic == "\xFE\xED\xFA\xCF")
1559     Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
1560   else if (Magic == "\xCF\xFA\xED\xFE")
1561     Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
1562   else {
1563     delete Buffer;
1564     return object_error::parse_failed;
1565   }
1566 
1567   if (EC)
1568     return EC;
1569   return Ret.take();
1570 }
1571 
1572 } // end namespace object
1573 } // end namespace llvm
1574