1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
13 //===----------------------------------------------------------------------===//
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"
28 using namespace object;
46 static void SwapValue(T &Value) {
47 Value = sys::SwapByteOrder(Value);
51 static void SwapStruct(T &Value);
54 void SwapStruct(MachO::any_relocation_info &H) {
60 void SwapStruct(MachO::load_command &L) {
66 void SwapStruct(nlist_base &S) {
72 void SwapStruct(MachO::section &S) {
80 SwapValue(S.reserved1);
81 SwapValue(S.reserved2);
85 void SwapStruct(MachO::section_64 &S) {
93 SwapValue(S.reserved1);
94 SwapValue(S.reserved2);
95 SwapValue(S.reserved3);
99 void SwapStruct(MachO::nlist &S) {
102 SwapValue(S.n_value);
106 void SwapStruct(MachO::nlist_64 &S) {
109 SwapValue(S.n_value);
113 void SwapStruct(MachO::mach_header &H) {
115 SwapValue(H.cputype);
116 SwapValue(H.cpusubtype);
117 SwapValue(H.filetype);
119 SwapValue(H.sizeofcmds);
124 void SwapStruct(MachO::mach_header_64 &H) {
126 SwapValue(H.cputype);
127 SwapValue(H.cpusubtype);
128 SwapValue(H.filetype);
130 SwapValue(H.sizeofcmds);
132 SwapValue(H.reserved);
136 void SwapStruct(MachO::symtab_command &C) {
138 SwapValue(C.cmdsize);
142 SwapValue(C.strsize);
146 void SwapStruct(MachO::dysymtab_command &C) {
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);
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);
170 void SwapStruct(MachO::linkedit_data_command &C) {
172 SwapValue(C.cmdsize);
173 SwapValue(C.dataoff);
174 SwapValue(C.datasize);
178 void SwapStruct(MachO::segment_command &C) {
180 SwapValue(C.cmdsize);
183 SwapValue(C.fileoff);
184 SwapValue(C.filesize);
185 SwapValue(C.maxprot);
186 SwapValue(C.initprot);
192 void SwapStruct(MachO::segment_command_64 &C) {
194 SwapValue(C.cmdsize);
197 SwapValue(C.fileoff);
198 SwapValue(C.filesize);
199 SwapValue(C.maxprot);
200 SwapValue(C.initprot);
206 void SwapStruct(uint32_t &C) {
211 void SwapStruct(MachO::linker_options_command &C) {
213 SwapValue(C.cmdsize);
218 void SwapStruct(MachO::version_min_command&C) {
220 SwapValue(C.cmdsize);
221 SwapValue(C.version);
222 SwapValue(C.reserved);
226 void SwapStruct(MachO::dylib_command&C) {
228 SwapValue(C.cmdsize);
229 SwapValue(C.dylib.name);
230 SwapValue(C.dylib.timestamp);
231 SwapValue(C.dylib.current_version);
232 SwapValue(C.dylib.compatibility_version);
236 void SwapStruct(MachO::data_in_code_entry &C) {
243 T getStruct(const MachOObjectFile *O, const char *P) {
245 memcpy(&Cmd, P, sizeof(T));
246 if (O->isLittleEndian() != sys::IsLittleEndianHost)
252 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
253 const MachOObjectFile::LoadCommandInfo &L) {
255 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
258 MachO::segment_command S = O->getSegmentLoadCommand(L);
263 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
265 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
267 bool Is64 = O->is64Bit();
268 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
269 sizeof(MachO::segment_command);
270 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
271 sizeof(MachO::section);
273 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
274 return reinterpret_cast<const char*>(SectionAddr);
277 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
278 return O->getData().substr(Offset, 1).data();
282 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
283 const char *P = reinterpret_cast<const char *>(DRI.p);
284 return getStruct<nlist_base>(O, P);
287 static StringRef parseSegmentOrSectionName(const char *P) {
291 // Not null terminated, so this is a 16 char string.
292 return StringRef(P, 16);
295 // Helper to advance a section or symbol iterator multiple increments at a time.
297 static void advance(T &it, size_t Val) {
302 static unsigned getCPUType(const MachOObjectFile *O) {
303 return O->getHeader().cputype;
306 static void printRelocationTargetName(const MachOObjectFile *O,
307 const MachO::any_relocation_info &RE,
308 raw_string_ostream &fmt) {
309 bool IsScattered = O->isRelocationScattered(RE);
311 // Target of a scattered relocation is an address. In the interest of
312 // generating pretty output, scan through the symbol table looking for a
313 // symbol that aligns with that address. If we find one, print it.
314 // Otherwise, we just print the hex address of the target.
316 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
318 for (const SymbolRef &Symbol : O->symbols()) {
323 if ((ec = Symbol.getAddress(Addr)))
324 report_fatal_error(ec.message());
327 if ((ec = Symbol.getName(Name)))
328 report_fatal_error(ec.message());
333 // If we couldn't find a symbol that this relocation refers to, try
334 // to find a section beginning instead.
335 for (const SectionRef &Section : O->sections()) {
340 if ((ec = Section.getAddress(Addr)))
341 report_fatal_error(ec.message());
344 if ((ec = Section.getName(Name)))
345 report_fatal_error(ec.message());
350 fmt << format("0x%x", Val);
355 bool isExtern = O->getPlainRelocationExternal(RE);
356 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
359 symbol_iterator SI = O->symbol_begin();
363 section_iterator SI = O->section_begin();
364 // Adjust for the fact that sections are 1-indexed.
365 advance(SI, Val - 1);
373 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
378 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
379 return RE.r_word0 & 0xffffff;
382 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
383 const MachO::any_relocation_info &RE) {
384 if (O->isLittleEndian())
385 return (RE.r_word1 >> 24) & 1;
386 return (RE.r_word1 >> 7) & 1;
390 getScatteredRelocationPCRel(const MachOObjectFile *O,
391 const MachO::any_relocation_info &RE) {
392 return (RE.r_word0 >> 30) & 1;
395 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
396 const MachO::any_relocation_info &RE) {
397 if (O->isLittleEndian())
398 return (RE.r_word1 >> 25) & 3;
399 return (RE.r_word1 >> 5) & 3;
403 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
404 return (RE.r_word0 >> 28) & 3;
407 static unsigned getPlainRelocationType(const MachOObjectFile *O,
408 const MachO::any_relocation_info &RE) {
409 if (O->isLittleEndian())
410 return RE.r_word1 >> 28;
411 return RE.r_word1 & 0xf;
415 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
416 return (RE.r_word0 >> 24) & 0xf;
419 static uint32_t getSectionFlags(const MachOObjectFile *O,
422 MachO::section_64 Sect = O->getSection64(Sec);
425 MachO::section Sect = O->getSection(Sec);
429 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
430 bool Is64bits, error_code &EC,
432 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
433 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
434 DataInCodeLoadCmd(nullptr) {
435 uint32_t LoadCommandCount = this->getHeader().ncmds;
436 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
437 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
439 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
440 for (unsigned I = 0; ; ++I) {
441 if (Load.C.cmd == MachO::LC_SYMTAB) {
442 assert(!SymtabLoadCmd && "Multiple symbol tables");
443 SymtabLoadCmd = Load.Ptr;
444 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
445 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
446 DysymtabLoadCmd = Load.Ptr;
447 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
448 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
449 DataInCodeLoadCmd = Load.Ptr;
450 } else if (Load.C.cmd == SegmentLoadType) {
451 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
452 for (unsigned J = 0; J < NumSections; ++J) {
453 const char *Sec = getSectionPtr(this, Load, J);
454 Sections.push_back(Sec);
456 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
457 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
458 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
459 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
460 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
461 Libraries.push_back(Load.Ptr);
464 if (I == LoadCommandCount - 1)
467 Load = getNextLoadCommandInfo(Load);
471 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
472 unsigned SymbolTableEntrySize = is64Bit() ?
473 sizeof(MachO::nlist_64) :
474 sizeof(MachO::nlist);
475 Symb.p += SymbolTableEntrySize;
478 error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
479 StringRef &Res) const {
480 StringRef StringTable = getStringTableData();
481 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
482 const char *Start = &StringTable.data()[Entry.n_strx];
483 Res = StringRef(Start);
484 return object_error::success;
487 // getIndirectName() returns the name of the alias'ed symbol who's string table
488 // index is in the n_value field.
489 error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
490 StringRef &Res) const {
491 StringRef StringTable = getStringTableData();
494 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
495 NValue = Entry.n_value;
496 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
497 return object_error::parse_failed;
499 MachO::nlist Entry = getSymbolTableEntry(Symb);
500 NValue = Entry.n_value;
501 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
502 return object_error::parse_failed;
504 if (NValue >= StringTable.size())
505 return object_error::parse_failed;
506 const char *Start = &StringTable.data()[NValue];
507 Res = StringRef(Start);
508 return object_error::success;
511 error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
512 uint64_t &Res) const {
514 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
515 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
517 Res = UnknownAddressOrSize;
521 MachO::nlist Entry = getSymbolTableEntry(Symb);
522 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
524 Res = UnknownAddressOrSize;
528 return object_error::success;
531 error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
532 uint32_t &Result) const {
533 uint32_t flags = getSymbolFlags(DRI);
534 if (flags & SymbolRef::SF_Common) {
535 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
536 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
540 return object_error::success;
543 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
544 uint64_t &Result) const {
545 uint64_t BeginOffset;
546 uint64_t EndOffset = 0;
547 uint8_t SectionIndex;
549 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
551 getSymbolAddress(DRI, Value);
552 if (Value == UnknownAddressOrSize) {
553 Result = UnknownAddressOrSize;
554 return object_error::success;
559 SectionIndex = Entry.n_sect;
561 uint32_t flags = getSymbolFlags(DRI);
562 if (flags & SymbolRef::SF_Common)
565 Result = UnknownAddressOrSize;
566 return object_error::success;
568 // Unfortunately symbols are unsorted so we need to touch all
569 // symbols from load command
570 for (const SymbolRef &Symbol : symbols()) {
571 DataRefImpl DRI = Symbol.getRawDataRefImpl();
572 Entry = getSymbolTableEntryBase(this, DRI);
573 getSymbolAddress(DRI, Value);
574 if (Value == UnknownAddressOrSize)
576 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
577 if (!EndOffset || Value < EndOffset)
583 Sec.d.a = SectionIndex-1;
584 getSectionSize(Sec, Size);
585 getSectionAddress(Sec, EndOffset);
588 Result = EndOffset - BeginOffset;
589 return object_error::success;
592 error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
593 SymbolRef::Type &Res) const {
594 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
595 uint8_t n_type = Entry.n_type;
597 Res = SymbolRef::ST_Other;
599 // If this is a STAB debugging symbol, we can do nothing more.
600 if (n_type & MachO::N_STAB) {
601 Res = SymbolRef::ST_Debug;
602 return object_error::success;
605 switch (n_type & MachO::N_TYPE) {
607 Res = SymbolRef::ST_Unknown;
610 Res = SymbolRef::ST_Function;
613 return object_error::success;
616 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
617 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
619 uint8_t MachOType = Entry.n_type;
620 uint16_t MachOFlags = Entry.n_desc;
622 uint32_t Result = SymbolRef::SF_None;
624 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
625 Result |= SymbolRef::SF_Undefined;
627 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
628 Result |= SymbolRef::SF_Indirect;
630 if (MachOType & MachO::N_STAB)
631 Result |= SymbolRef::SF_FormatSpecific;
633 if (MachOType & MachO::N_EXT) {
634 Result |= SymbolRef::SF_Global;
635 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
637 getSymbolAddress(DRI, Value);
638 if (Value && Value != UnknownAddressOrSize)
639 Result |= SymbolRef::SF_Common;
643 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
644 Result |= SymbolRef::SF_Weak;
646 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
647 Result |= SymbolRef::SF_Absolute;
653 MachOObjectFile::getSymbolSection(DataRefImpl Symb,
654 section_iterator &Res) const {
655 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
656 uint8_t index = Entry.n_sect;
663 Res = section_iterator(SectionRef(DRI, this));
666 return object_error::success;
669 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
674 MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
675 ArrayRef<char> Raw = getSectionRawName(Sec);
676 Result = parseSegmentOrSectionName(Raw.data());
677 return object_error::success;
681 MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
683 MachO::section_64 Sect = getSection64(Sec);
686 MachO::section Sect = getSection(Sec);
689 return object_error::success;
693 MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
695 MachO::section_64 Sect = getSection64(Sec);
698 MachO::section Sect = getSection(Sec);
702 return object_error::success;
706 MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
711 MachO::section_64 Sect = getSection64(Sec);
712 Offset = Sect.offset;
715 MachO::section Sect = getSection(Sec);
716 Offset = Sect.offset;
720 Res = this->getData().substr(Offset, Size);
721 return object_error::success;
725 MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
728 MachO::section_64 Sect = getSection64(Sec);
731 MachO::section Sect = getSection(Sec);
735 Res = uint64_t(1) << Align;
736 return object_error::success;
740 MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
741 uint32_t Flags = getSectionFlags(this, Sec);
742 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
743 return object_error::success;
746 error_code MachOObjectFile::isSectionData(DataRefImpl Sec, bool &Result) const {
747 uint32_t Flags = getSectionFlags(this, Sec);
748 unsigned SectionType = Flags & MachO::SECTION_TYPE;
749 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
750 !(SectionType == MachO::S_ZEROFILL ||
751 SectionType == MachO::S_GB_ZEROFILL);
752 return object_error::success;
755 error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, bool &Result) const {
756 uint32_t Flags = getSectionFlags(this, Sec);
757 unsigned SectionType = Flags & MachO::SECTION_TYPE;
758 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
759 (SectionType == MachO::S_ZEROFILL ||
760 SectionType == MachO::S_GB_ZEROFILL);
761 return object_error::success;
765 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
766 bool &Result) const {
767 // FIXME: Unimplemented.
769 return object_error::success;
772 error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
773 bool &Result) const {
774 // FIXME: Unimplemented.
776 return object_error::success;
780 MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
781 uint32_t Flags = getSectionFlags(this, Sec);
782 unsigned SectionType = Flags & MachO::SECTION_TYPE;
783 Res = SectionType == MachO::S_ZEROFILL ||
784 SectionType == MachO::S_GB_ZEROFILL;
785 return object_error::success;
788 error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
789 bool &Result) const {
790 // Consider using the code from isSectionText to look for __const sections.
791 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
792 // to use section attributes to distinguish code from data.
794 // FIXME: Unimplemented.
796 return object_error::success;
800 MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
801 bool &Result) const {
803 this->getSymbolType(Symb, ST);
804 if (ST == SymbolRef::ST_Unknown) {
806 return object_error::success;
809 uint64_t SectBegin, SectEnd;
810 getSectionAddress(Sec, SectBegin);
811 getSectionSize(Sec, SectEnd);
812 SectEnd += SectBegin;
815 getSymbolAddress(Symb, SymAddr);
816 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
818 return object_error::success;
821 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
825 return relocation_iterator(RelocationRef(Ret, this));
829 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
832 MachO::section_64 Sect = getSection64(Sec);
835 MachO::section Sect = getSection(Sec);
842 return relocation_iterator(RelocationRef(Ret, this));
845 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
850 MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
852 getRelocationOffset(Rel, Offset);
857 getSectionAddress(Sec, SecAddress);
858 Res = SecAddress + Offset;
859 return object_error::success;
862 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
863 uint64_t &Res) const {
864 assert(getHeader().filetype == MachO::MH_OBJECT &&
865 "Only implemented for MH_OBJECT");
866 MachO::any_relocation_info RE = getRelocation(Rel);
867 Res = getAnyRelocationAddress(RE);
868 return object_error::success;
872 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
873 MachO::any_relocation_info RE = getRelocation(Rel);
874 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
875 bool isExtern = getPlainRelocationExternal(RE);
879 MachO::symtab_command S = getSymtabLoadCommand();
880 unsigned SymbolTableEntrySize = is64Bit() ?
881 sizeof(MachO::nlist_64) :
882 sizeof(MachO::nlist);
883 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
885 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
886 return symbol_iterator(SymbolRef(Sym, this));
889 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
890 uint64_t &Res) const {
891 MachO::any_relocation_info RE = getRelocation(Rel);
892 Res = getAnyRelocationType(RE);
893 return object_error::success;
897 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
898 SmallVectorImpl<char> &Result) const {
901 getRelocationType(Rel, RType);
903 unsigned Arch = this->getArch();
907 static const char *const Table[] = {
908 "GENERIC_RELOC_VANILLA",
909 "GENERIC_RELOC_PAIR",
910 "GENERIC_RELOC_SECTDIFF",
911 "GENERIC_RELOC_PB_LA_PTR",
912 "GENERIC_RELOC_LOCAL_SECTDIFF",
913 "GENERIC_RELOC_TLV" };
921 case Triple::x86_64: {
922 static const char *const Table[] = {
923 "X86_64_RELOC_UNSIGNED",
924 "X86_64_RELOC_SIGNED",
925 "X86_64_RELOC_BRANCH",
926 "X86_64_RELOC_GOT_LOAD",
928 "X86_64_RELOC_SUBTRACTOR",
929 "X86_64_RELOC_SIGNED_1",
930 "X86_64_RELOC_SIGNED_2",
931 "X86_64_RELOC_SIGNED_4",
932 "X86_64_RELOC_TLV" };
941 static const char *const Table[] = {
944 "ARM_RELOC_SECTDIFF",
945 "ARM_RELOC_LOCAL_SECTDIFF",
946 "ARM_RELOC_PB_LA_PTR",
948 "ARM_THUMB_RELOC_BR22",
949 "ARM_THUMB_32BIT_BRANCH",
951 "ARM_RELOC_HALF_SECTDIFF" };
960 case Triple::aarch64: {
961 static const char *const Table[] = {
962 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
963 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
964 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
965 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
966 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
970 if (RType >= array_lengthof(Table))
977 static const char *const Table[] = {
986 "PPC_RELOC_SECTDIFF",
987 "PPC_RELOC_PB_LA_PTR",
988 "PPC_RELOC_HI16_SECTDIFF",
989 "PPC_RELOC_LO16_SECTDIFF",
990 "PPC_RELOC_HA16_SECTDIFF",
992 "PPC_RELOC_LO14_SECTDIFF",
993 "PPC_RELOC_LOCAL_SECTDIFF" };
1001 case Triple::UnknownArch:
1005 Result.append(res.begin(), res.end());
1006 return object_error::success;
1010 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
1011 SmallVectorImpl<char> &Result) const {
1012 MachO::any_relocation_info RE = getRelocation(Rel);
1014 unsigned Arch = this->getArch();
1017 raw_string_ostream fmt(fmtbuf);
1018 unsigned Type = this->getAnyRelocationType(RE);
1019 bool IsPCRel = this->getAnyRelocationPCRel(RE);
1021 // Determine any addends that should be displayed with the relocation.
1022 // These require decoding the relocation type, which is triple-specific.
1024 // X86_64 has entirely custom relocation types.
1025 if (Arch == Triple::x86_64) {
1026 bool isPCRel = getAnyRelocationPCRel(RE);
1029 case MachO::X86_64_RELOC_GOT_LOAD:
1030 case MachO::X86_64_RELOC_GOT: {
1031 printRelocationTargetName(this, RE, fmt);
1033 if (isPCRel) fmt << "PCREL";
1036 case MachO::X86_64_RELOC_SUBTRACTOR: {
1037 DataRefImpl RelNext = Rel;
1038 moveRelocationNext(RelNext);
1039 MachO::any_relocation_info RENext = getRelocation(RelNext);
1041 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
1042 // X86_64_RELOC_UNSIGNED.
1043 // NOTE: Scattered relocations don't exist on x86_64.
1044 unsigned RType = getAnyRelocationType(RENext);
1045 if (RType != MachO::X86_64_RELOC_UNSIGNED)
1046 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1047 "X86_64_RELOC_SUBTRACTOR.");
1049 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
1050 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
1051 printRelocationTargetName(this, RENext, fmt);
1053 printRelocationTargetName(this, RE, fmt);
1056 case MachO::X86_64_RELOC_TLV:
1057 printRelocationTargetName(this, RE, fmt);
1059 if (isPCRel) fmt << "P";
1061 case MachO::X86_64_RELOC_SIGNED_1:
1062 printRelocationTargetName(this, RE, fmt);
1065 case MachO::X86_64_RELOC_SIGNED_2:
1066 printRelocationTargetName(this, RE, fmt);
1069 case MachO::X86_64_RELOC_SIGNED_4:
1070 printRelocationTargetName(this, RE, fmt);
1074 printRelocationTargetName(this, RE, fmt);
1077 // X86 and ARM share some relocation types in common.
1078 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
1079 Arch == Triple::ppc) {
1080 // Generic relocation types...
1082 case MachO::GENERIC_RELOC_PAIR: // prints no info
1083 return object_error::success;
1084 case MachO::GENERIC_RELOC_SECTDIFF: {
1085 DataRefImpl RelNext = Rel;
1086 moveRelocationNext(RelNext);
1087 MachO::any_relocation_info RENext = getRelocation(RelNext);
1089 // X86 sect diff's must be followed by a relocation of type
1090 // GENERIC_RELOC_PAIR.
1091 unsigned RType = getAnyRelocationType(RENext);
1093 if (RType != MachO::GENERIC_RELOC_PAIR)
1094 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1095 "GENERIC_RELOC_SECTDIFF.");
1097 printRelocationTargetName(this, RE, fmt);
1099 printRelocationTargetName(this, RENext, fmt);
1104 if (Arch == Triple::x86 || Arch == Triple::ppc) {
1106 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
1107 DataRefImpl RelNext = Rel;
1108 moveRelocationNext(RelNext);
1109 MachO::any_relocation_info RENext = getRelocation(RelNext);
1111 // X86 sect diff's must be followed by a relocation of type
1112 // GENERIC_RELOC_PAIR.
1113 unsigned RType = getAnyRelocationType(RENext);
1114 if (RType != MachO::GENERIC_RELOC_PAIR)
1115 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1116 "GENERIC_RELOC_LOCAL_SECTDIFF.");
1118 printRelocationTargetName(this, RE, fmt);
1120 printRelocationTargetName(this, RENext, fmt);
1123 case MachO::GENERIC_RELOC_TLV: {
1124 printRelocationTargetName(this, RE, fmt);
1126 if (IsPCRel) fmt << "P";
1130 printRelocationTargetName(this, RE, fmt);
1132 } else { // ARM-specific relocations
1134 case MachO::ARM_RELOC_HALF:
1135 case MachO::ARM_RELOC_HALF_SECTDIFF: {
1136 // Half relocations steal a bit from the length field to encode
1137 // whether this is an upper16 or a lower16 relocation.
1138 bool isUpper = getAnyRelocationLength(RE) >> 1;
1141 fmt << ":upper16:(";
1143 fmt << ":lower16:(";
1144 printRelocationTargetName(this, RE, fmt);
1146 DataRefImpl RelNext = Rel;
1147 moveRelocationNext(RelNext);
1148 MachO::any_relocation_info RENext = getRelocation(RelNext);
1150 // ARM half relocs must be followed by a relocation of type
1152 unsigned RType = getAnyRelocationType(RENext);
1153 if (RType != MachO::ARM_RELOC_PAIR)
1154 report_fatal_error("Expected ARM_RELOC_PAIR after "
1157 // NOTE: The half of the target virtual address is stashed in the
1158 // address field of the secondary relocation, but we can't reverse
1159 // engineer the constant offset from it without decoding the movw/movt
1160 // instruction to find the other half in its immediate field.
1162 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1163 // symbol/section pointer of the follow-on relocation.
1164 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
1166 printRelocationTargetName(this, RENext, fmt);
1173 printRelocationTargetName(this, RE, fmt);
1178 printRelocationTargetName(this, RE, fmt);
1181 Result.append(fmtbuf.begin(), fmtbuf.end());
1182 return object_error::success;
1186 MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
1187 unsigned Arch = getArch();
1189 getRelocationType(Rel, Type);
1193 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1194 // is always hidden.
1195 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
1196 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
1197 } else if (Arch == Triple::x86_64) {
1198 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1199 // an X86_64_RELOC_SUBTRACTOR.
1200 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1201 DataRefImpl RelPrev = Rel;
1204 getRelocationType(RelPrev, PrevType);
1205 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1210 return object_error::success;
1213 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1214 LibraryRef &Res) const {
1215 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1218 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1219 StringRef &Res) const {
1220 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1224 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1225 // guess on what the short name is. Then name is returned as a substring of the
1226 // StringRef Name passed in. The name of the dynamic library is recognized as
1227 // a framework if it has one of the two following forms:
1228 // Foo.framework/Versions/A/Foo
1229 // Foo.framework/Foo
1230 // Where A and Foo can be any string. And may contain a trailing suffix
1231 // starting with an underbar. If the Name is recognized as a framework then
1232 // isFramework is set to true else it is set to false. If the Name has a
1233 // suffix then Suffix is set to the substring in Name that contains the suffix
1234 // else it is set to a NULL StringRef.
1236 // The Name of the dynamic library is recognized as a library name if it has
1237 // one of the two following forms:
1240 // The library may have a suffix trailing the name Foo of the form:
1241 // libFoo_profile.A.dylib
1242 // libFoo_profile.dylib
1244 // The Name of the dynamic library is also recognized as a library name if it
1245 // has the following form:
1248 // If the Name of the dynamic library is none of the forms above then a NULL
1249 // StringRef is returned.
1251 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1253 StringRef &Suffix) {
1254 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1255 size_t a, b, c, d, Idx;
1257 isFramework = false;
1258 Suffix = StringRef();
1260 // Pull off the last component and make Foo point to it
1261 a = Name.rfind('/');
1262 if (a == Name.npos || a == 0)
1264 Foo = Name.slice(a+1, Name.npos);
1266 // Look for a suffix starting with a '_'
1267 Idx = Foo.rfind('_');
1268 if (Idx != Foo.npos && Foo.size() >= 2) {
1269 Suffix = Foo.slice(Idx, Foo.npos);
1270 Foo = Foo.slice(0, Idx);
1273 // First look for the form Foo.framework/Foo
1274 b = Name.rfind('/', a);
1279 F = Name.slice(Idx, Idx + Foo.size());
1280 DotFramework = Name.slice(Idx + Foo.size(),
1281 Idx + Foo.size() + sizeof(".framework/")-1);
1282 if (F == Foo && DotFramework == ".framework/") {
1287 // Next look for the form Foo.framework/Versions/A/Foo
1290 c = Name.rfind('/', b);
1291 if (c == Name.npos || c == 0)
1293 V = Name.slice(c+1, Name.npos);
1294 if (!V.startswith("Versions/"))
1296 d = Name.rfind('/', c);
1301 F = Name.slice(Idx, Idx + Foo.size());
1302 DotFramework = Name.slice(Idx + Foo.size(),
1303 Idx + Foo.size() + sizeof(".framework/")-1);
1304 if (F == Foo && DotFramework == ".framework/") {
1310 // pull off the suffix after the "." and make a point to it
1311 a = Name.rfind('.');
1312 if (a == Name.npos || a == 0)
1314 Dylib = Name.slice(a, Name.npos);
1315 if (Dylib != ".dylib")
1318 // First pull off the version letter for the form Foo.A.dylib if any.
1320 Dot = Name.slice(a-2, a-1);
1325 b = Name.rfind('/', a);
1330 // ignore any suffix after an underbar like Foo_profile.A.dylib
1331 Idx = Name.find('_', b);
1332 if (Idx != Name.npos && Idx != b) {
1333 Lib = Name.slice(b, Idx);
1334 Suffix = Name.slice(Idx, a);
1337 Lib = Name.slice(b, a);
1338 // There are incorrect library names of the form:
1339 // libATS.A_profile.dylib so check for these.
1340 if (Lib.size() >= 3) {
1341 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1343 Lib = Lib.slice(0, Lib.size()-2);
1348 Qtx = Name.slice(a, Name.npos);
1351 b = Name.rfind('/', a);
1353 Lib = Name.slice(0, a);
1355 Lib = Name.slice(b+1, a);
1356 // There are library names of the form: QT.A.qtx so check for these.
1357 if (Lib.size() >= 3) {
1358 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1360 Lib = Lib.slice(0, Lib.size()-2);
1365 // getLibraryShortNameByIndex() is used to get the short name of the library
1366 // for an undefined symbol in a linked Mach-O binary that was linked with the
1367 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1368 // It is passed the index (0 - based) of the library as translated from
1369 // GET_LIBRARY_ORDINAL (1 - based).
1370 error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1372 if (Index >= Libraries.size())
1373 return object_error::parse_failed;
1375 MachO::dylib_command D =
1376 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1377 if (D.dylib.name >= D.cmdsize)
1378 return object_error::parse_failed;
1380 // If the cache of LibrariesShortNames is not built up do that first for
1381 // all the Libraries.
1382 if (LibrariesShortNames.size() == 0) {
1383 for (unsigned i = 0; i < Libraries.size(); i++) {
1384 MachO::dylib_command D =
1385 getStruct<MachO::dylib_command>(this, Libraries[i]);
1386 if (D.dylib.name >= D.cmdsize) {
1387 LibrariesShortNames.push_back(StringRef());
1390 char *P = (char *)(Libraries[i]) + D.dylib.name;
1391 StringRef Name = StringRef(P);
1394 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1395 if (shortName == StringRef())
1396 LibrariesShortNames.push_back(Name);
1398 LibrariesShortNames.push_back(shortName);
1402 Res = LibrariesShortNames[Index];
1403 return object_error::success;
1406 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1407 return getSymbolByIndex(0);
1410 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1413 return basic_symbol_iterator(SymbolRef(DRI, this));
1415 MachO::symtab_command Symtab = getSymtabLoadCommand();
1416 unsigned SymbolTableEntrySize = is64Bit() ?
1417 sizeof(MachO::nlist_64) :
1418 sizeof(MachO::nlist);
1419 unsigned Offset = Symtab.symoff +
1420 Symtab.nsyms * SymbolTableEntrySize;
1421 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1422 return basic_symbol_iterator(SymbolRef(DRI, this));
1425 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1428 return basic_symbol_iterator(SymbolRef(DRI, this));
1430 MachO::symtab_command Symtab = getSymtabLoadCommand();
1431 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1432 unsigned SymbolTableEntrySize =
1433 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1434 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1435 DRI.p += Index * SymbolTableEntrySize;
1436 return basic_symbol_iterator(SymbolRef(DRI, this));
1439 section_iterator MachOObjectFile::section_begin() const {
1441 return section_iterator(SectionRef(DRI, this));
1444 section_iterator MachOObjectFile::section_end() const {
1446 DRI.d.a = Sections.size();
1447 return section_iterator(SectionRef(DRI, this));
1450 library_iterator MachOObjectFile::needed_library_begin() const {
1452 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1455 library_iterator MachOObjectFile::needed_library_end() const {
1457 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1460 uint8_t MachOObjectFile::getBytesInAddress() const {
1461 return is64Bit() ? 8 : 4;
1464 StringRef MachOObjectFile::getFileFormatName() const {
1465 unsigned CPUType = getCPUType(this);
1468 case llvm::MachO::CPU_TYPE_I386:
1469 return "Mach-O 32-bit i386";
1470 case llvm::MachO::CPU_TYPE_ARM:
1471 return "Mach-O arm";
1472 case llvm::MachO::CPU_TYPE_POWERPC:
1473 return "Mach-O 32-bit ppc";
1475 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1476 "64-bit object file when we're not 64-bit?");
1477 return "Mach-O 32-bit unknown";
1481 // Make sure the cpu type has the correct mask.
1482 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1483 == llvm::MachO::CPU_ARCH_ABI64 &&
1484 "32-bit object file when we're 64-bit?");
1487 case llvm::MachO::CPU_TYPE_X86_64:
1488 return "Mach-O 64-bit x86-64";
1489 case llvm::MachO::CPU_TYPE_ARM64:
1490 return "Mach-O arm64";
1491 case llvm::MachO::CPU_TYPE_POWERPC64:
1492 return "Mach-O 64-bit ppc64";
1494 return "Mach-O 64-bit unknown";
1498 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1500 case llvm::MachO::CPU_TYPE_I386:
1502 case llvm::MachO::CPU_TYPE_X86_64:
1503 return Triple::x86_64;
1504 case llvm::MachO::CPU_TYPE_ARM:
1506 case llvm::MachO::CPU_TYPE_ARM64:
1507 return Triple::arm64;
1508 case llvm::MachO::CPU_TYPE_POWERPC:
1510 case llvm::MachO::CPU_TYPE_POWERPC64:
1511 return Triple::ppc64;
1513 return Triple::UnknownArch;
1517 unsigned MachOObjectFile::getArch() const {
1518 return getArch(getCPUType(this));
1521 StringRef MachOObjectFile::getLoadName() const {
1523 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1526 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1529 return section_rel_begin(DRI);
1532 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1535 return section_rel_end(DRI);
1538 dice_iterator MachOObjectFile::begin_dices() const {
1540 if (!DataInCodeLoadCmd)
1541 return dice_iterator(DiceRef(DRI, this));
1543 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1544 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1545 return dice_iterator(DiceRef(DRI, this));
1548 dice_iterator MachOObjectFile::end_dices() const {
1550 if (!DataInCodeLoadCmd)
1551 return dice_iterator(DiceRef(DRI, this));
1553 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1554 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1555 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1556 return dice_iterator(DiceRef(DRI, this));
1560 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1561 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1562 return parseSegmentOrSectionName(Raw.data());
1566 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1567 const section_base *Base =
1568 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1569 return ArrayRef<char>(Base->sectname);
1573 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1574 const section_base *Base =
1575 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1576 return ArrayRef<char>(Base->segname);
1580 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1582 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1584 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1587 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1588 const MachO::any_relocation_info &RE) const {
1589 if (isLittleEndian())
1590 return RE.r_word1 & 0xffffff;
1591 return RE.r_word1 >> 8;
1594 bool MachOObjectFile::getPlainRelocationExternal(
1595 const MachO::any_relocation_info &RE) const {
1596 if (isLittleEndian())
1597 return (RE.r_word1 >> 27) & 1;
1598 return (RE.r_word1 >> 4) & 1;
1601 bool MachOObjectFile::getScatteredRelocationScattered(
1602 const MachO::any_relocation_info &RE) const {
1603 return RE.r_word0 >> 31;
1606 uint32_t MachOObjectFile::getScatteredRelocationValue(
1607 const MachO::any_relocation_info &RE) const {
1611 unsigned MachOObjectFile::getAnyRelocationAddress(
1612 const MachO::any_relocation_info &RE) const {
1613 if (isRelocationScattered(RE))
1614 return getScatteredRelocationAddress(RE);
1615 return getPlainRelocationAddress(RE);
1618 unsigned MachOObjectFile::getAnyRelocationPCRel(
1619 const MachO::any_relocation_info &RE) const {
1620 if (isRelocationScattered(RE))
1621 return getScatteredRelocationPCRel(this, RE);
1622 return getPlainRelocationPCRel(this, RE);
1625 unsigned MachOObjectFile::getAnyRelocationLength(
1626 const MachO::any_relocation_info &RE) const {
1627 if (isRelocationScattered(RE))
1628 return getScatteredRelocationLength(RE);
1629 return getPlainRelocationLength(this, RE);
1633 MachOObjectFile::getAnyRelocationType(
1634 const MachO::any_relocation_info &RE) const {
1635 if (isRelocationScattered(RE))
1636 return getScatteredRelocationType(RE);
1637 return getPlainRelocationType(this, RE);
1641 MachOObjectFile::getRelocationSection(
1642 const MachO::any_relocation_info &RE) const {
1643 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1644 return *section_end();
1645 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1648 return SectionRef(DRI, this);
1651 MachOObjectFile::LoadCommandInfo
1652 MachOObjectFile::getFirstLoadCommandInfo() const {
1653 MachOObjectFile::LoadCommandInfo Load;
1655 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1656 sizeof(MachO::mach_header);
1657 Load.Ptr = getPtr(this, HeaderSize);
1658 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1662 MachOObjectFile::LoadCommandInfo
1663 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1664 MachOObjectFile::LoadCommandInfo Next;
1665 Next.Ptr = L.Ptr + L.C.cmdsize;
1666 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1670 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1671 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1674 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1675 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1678 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1679 unsigned Index) const {
1680 const char *Sec = getSectionPtr(this, L, Index);
1681 return getStruct<MachO::section>(this, Sec);
1684 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1685 unsigned Index) const {
1686 const char *Sec = getSectionPtr(this, L, Index);
1687 return getStruct<MachO::section_64>(this, Sec);
1691 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1692 const char *P = reinterpret_cast<const char *>(DRI.p);
1693 return getStruct<MachO::nlist>(this, P);
1697 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1698 const char *P = reinterpret_cast<const char *>(DRI.p);
1699 return getStruct<MachO::nlist_64>(this, P);
1702 MachO::linkedit_data_command
1703 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1704 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1707 MachO::segment_command
1708 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1709 return getStruct<MachO::segment_command>(this, L.Ptr);
1712 MachO::segment_command_64
1713 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1714 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1717 MachO::linker_options_command
1718 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1719 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1722 MachO::version_min_command
1723 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1724 return getStruct<MachO::version_min_command>(this, L.Ptr);
1727 MachO::any_relocation_info
1728 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1733 MachO::section_64 Sect = getSection64(Sec);
1734 Offset = Sect.reloff;
1736 MachO::section Sect = getSection(Sec);
1737 Offset = Sect.reloff;
1740 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1741 getPtr(this, Offset)) + Rel.d.b;
1742 return getStruct<MachO::any_relocation_info>(
1743 this, reinterpret_cast<const char *>(P));
1746 MachO::data_in_code_entry
1747 MachOObjectFile::getDice(DataRefImpl Rel) const {
1748 const char *P = reinterpret_cast<const char *>(Rel.p);
1749 return getStruct<MachO::data_in_code_entry>(this, P);
1752 MachO::mach_header MachOObjectFile::getHeader() const {
1753 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1756 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1757 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1760 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1761 const MachO::dysymtab_command &DLC,
1762 unsigned Index) const {
1763 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1764 return getStruct<uint32_t>(this, getPtr(this, Offset));
1767 MachO::data_in_code_entry
1768 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1769 unsigned Index) const {
1770 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1771 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1774 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1775 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1778 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1779 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1782 MachO::linkedit_data_command
1783 MachOObjectFile::getDataInCodeLoadCommand() const {
1784 if (DataInCodeLoadCmd)
1785 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1787 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1788 MachO::linkedit_data_command Cmd;
1789 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1790 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1796 StringRef MachOObjectFile::getStringTableData() const {
1797 MachO::symtab_command S = getSymtabLoadCommand();
1798 return getData().substr(S.stroff, S.strsize);
1801 bool MachOObjectFile::is64Bit() const {
1802 return getType() == getMachOType(false, true) ||
1803 getType() == getMachOType(true, true);
1806 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1807 SmallVectorImpl<uint64_t> &Out) const {
1808 DataExtractor extractor(ObjectFile::getData(), true, 0);
1810 uint32_t offset = Index;
1812 while (uint64_t delta = extractor.getULEB128(&offset)) {
1814 Out.push_back(data);
1818 ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
1820 StringRef Magic = Buffer->getBuffer().slice(0, 4);
1822 std::unique_ptr<MachOObjectFile> Ret;
1823 if (Magic == "\xFE\xED\xFA\xCE")
1824 Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
1825 else if (Magic == "\xCE\xFA\xED\xFE")
1826 Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
1827 else if (Magic == "\xFE\xED\xFA\xCF")
1828 Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
1829 else if (Magic == "\xCF\xFA\xED\xFE")
1830 Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
1833 return object_error::parse_failed;
1838 return Ret.release();
1841 } // end namespace object
1842 } // end namespace llvm