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