LLVM API Documentation

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