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