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/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/Host.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/raw_ostream.h"
29 using namespace object;
39 static T getStruct(const MachOObjectFile *O, const char *P) {
41 memcpy(&Cmd, P, sizeof(T));
42 if (O->isLittleEndian() != sys::IsLittleEndianHost)
43 MachO::swapStruct(Cmd);
48 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
49 const MachOObjectFile::LoadCommandInfo &L) {
51 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
54 MachO::segment_command S = O->getSegmentLoadCommand(L);
59 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
61 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
63 bool Is64 = O->is64Bit();
64 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
65 sizeof(MachO::segment_command);
66 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
67 sizeof(MachO::section);
69 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
70 return reinterpret_cast<const char*>(SectionAddr);
73 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
74 return O->getData().substr(Offset, 1).data();
77 static MachO::nlist_base
78 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
79 const char *P = reinterpret_cast<const char *>(DRI.p);
80 return getStruct<MachO::nlist_base>(O, P);
83 static StringRef parseSegmentOrSectionName(const char *P) {
87 // Not null terminated, so this is a 16 char string.
88 return StringRef(P, 16);
91 // Helper to advance a section or symbol iterator multiple increments at a time.
93 static void advance(T &it, size_t Val) {
98 static unsigned getCPUType(const MachOObjectFile *O) {
99 return O->getHeader().cputype;
102 static void printRelocationTargetName(const MachOObjectFile *O,
103 const MachO::any_relocation_info &RE,
104 raw_string_ostream &fmt) {
105 bool IsScattered = O->isRelocationScattered(RE);
107 // Target of a scattered relocation is an address. In the interest of
108 // generating pretty output, scan through the symbol table looking for a
109 // symbol that aligns with that address. If we find one, print it.
110 // Otherwise, we just print the hex address of the target.
112 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
114 for (const SymbolRef &Symbol : O->symbols()) {
119 if ((ec = Symbol.getAddress(Addr)))
120 report_fatal_error(ec.message());
123 if ((ec = Symbol.getName(Name)))
124 report_fatal_error(ec.message());
129 // If we couldn't find a symbol that this relocation refers to, try
130 // to find a section beginning instead.
131 for (const SectionRef &Section : O->sections()) {
136 if ((ec = Section.getAddress(Addr)))
137 report_fatal_error(ec.message());
140 if ((ec = Section.getName(Name)))
141 report_fatal_error(ec.message());
146 fmt << format("0x%x", Val);
151 bool isExtern = O->getPlainRelocationExternal(RE);
152 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
155 symbol_iterator SI = O->symbol_begin();
159 section_iterator SI = O->section_begin();
160 // Adjust for the fact that sections are 1-indexed.
161 advance(SI, Val - 1);
169 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
174 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
175 return RE.r_word0 & 0xffffff;
178 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
179 const MachO::any_relocation_info &RE) {
180 if (O->isLittleEndian())
181 return (RE.r_word1 >> 24) & 1;
182 return (RE.r_word1 >> 7) & 1;
186 getScatteredRelocationPCRel(const MachOObjectFile *O,
187 const MachO::any_relocation_info &RE) {
188 return (RE.r_word0 >> 30) & 1;
191 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
192 const MachO::any_relocation_info &RE) {
193 if (O->isLittleEndian())
194 return (RE.r_word1 >> 25) & 3;
195 return (RE.r_word1 >> 5) & 3;
199 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
200 return (RE.r_word0 >> 28) & 3;
203 static unsigned getPlainRelocationType(const MachOObjectFile *O,
204 const MachO::any_relocation_info &RE) {
205 if (O->isLittleEndian())
206 return RE.r_word1 >> 28;
207 return RE.r_word1 & 0xf;
211 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
212 return (RE.r_word0 >> 24) & 0xf;
215 static uint32_t getSectionFlags(const MachOObjectFile *O,
218 MachO::section_64 Sect = O->getSection64(Sec);
221 MachO::section Sect = O->getSection(Sec);
225 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
226 bool Is64bits, std::error_code &EC)
227 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
228 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
229 DataInCodeLoadCmd(nullptr) {
230 uint32_t LoadCommandCount = this->getHeader().ncmds;
231 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
232 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
234 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
235 for (unsigned I = 0; ; ++I) {
236 if (Load.C.cmd == MachO::LC_SYMTAB) {
237 assert(!SymtabLoadCmd && "Multiple symbol tables");
238 SymtabLoadCmd = Load.Ptr;
239 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
240 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
241 DysymtabLoadCmd = Load.Ptr;
242 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
243 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
244 DataInCodeLoadCmd = Load.Ptr;
245 } else if (Load.C.cmd == SegmentLoadType) {
246 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
247 for (unsigned J = 0; J < NumSections; ++J) {
248 const char *Sec = getSectionPtr(this, Load, J);
249 Sections.push_back(Sec);
251 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
252 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
253 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
254 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
255 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
256 Libraries.push_back(Load.Ptr);
259 if (I == LoadCommandCount - 1)
262 Load = getNextLoadCommandInfo(Load);
266 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
267 unsigned SymbolTableEntrySize = is64Bit() ?
268 sizeof(MachO::nlist_64) :
269 sizeof(MachO::nlist);
270 Symb.p += SymbolTableEntrySize;
273 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
274 StringRef &Res) const {
275 StringRef StringTable = getStringTableData();
276 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
277 const char *Start = &StringTable.data()[Entry.n_strx];
278 Res = StringRef(Start);
279 return object_error::success;
282 // getIndirectName() returns the name of the alias'ed symbol who's string table
283 // index is in the n_value field.
284 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
285 StringRef &Res) const {
286 StringRef StringTable = getStringTableData();
289 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
290 NValue = Entry.n_value;
291 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
292 return object_error::parse_failed;
294 MachO::nlist Entry = getSymbolTableEntry(Symb);
295 NValue = Entry.n_value;
296 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
297 return object_error::parse_failed;
299 if (NValue >= StringTable.size())
300 return object_error::parse_failed;
301 const char *Start = &StringTable.data()[NValue];
302 Res = StringRef(Start);
303 return object_error::success;
306 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
307 uint64_t &Res) const {
309 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
310 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
312 Res = UnknownAddressOrSize;
316 MachO::nlist Entry = getSymbolTableEntry(Symb);
317 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
319 Res = UnknownAddressOrSize;
323 return object_error::success;
326 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
327 uint32_t &Result) const {
328 uint32_t flags = getSymbolFlags(DRI);
329 if (flags & SymbolRef::SF_Common) {
330 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
331 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
335 return object_error::success;
338 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
339 uint64_t &Result) const {
340 uint64_t BeginOffset;
341 uint64_t EndOffset = 0;
342 uint8_t SectionIndex;
344 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
346 getSymbolAddress(DRI, Value);
347 if (Value == UnknownAddressOrSize) {
348 Result = UnknownAddressOrSize;
349 return object_error::success;
354 SectionIndex = Entry.n_sect;
356 uint32_t flags = getSymbolFlags(DRI);
357 if (flags & SymbolRef::SF_Common)
360 Result = UnknownAddressOrSize;
361 return object_error::success;
363 // Unfortunately symbols are unsorted so we need to touch all
364 // symbols from load command
365 for (const SymbolRef &Symbol : symbols()) {
366 DataRefImpl DRI = Symbol.getRawDataRefImpl();
367 Entry = getSymbolTableEntryBase(this, DRI);
368 getSymbolAddress(DRI, Value);
369 if (Value == UnknownAddressOrSize)
371 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
372 if (!EndOffset || Value < EndOffset)
378 Sec.d.a = SectionIndex-1;
379 getSectionSize(Sec, Size);
380 getSectionAddress(Sec, EndOffset);
383 Result = EndOffset - BeginOffset;
384 return object_error::success;
387 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
388 SymbolRef::Type &Res) const {
389 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
390 uint8_t n_type = Entry.n_type;
392 Res = SymbolRef::ST_Other;
394 // If this is a STAB debugging symbol, we can do nothing more.
395 if (n_type & MachO::N_STAB) {
396 Res = SymbolRef::ST_Debug;
397 return object_error::success;
400 switch (n_type & MachO::N_TYPE) {
402 Res = SymbolRef::ST_Unknown;
405 Res = SymbolRef::ST_Function;
408 return object_error::success;
411 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
412 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
414 uint8_t MachOType = Entry.n_type;
415 uint16_t MachOFlags = Entry.n_desc;
417 uint32_t Result = SymbolRef::SF_None;
419 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
420 Result |= SymbolRef::SF_Undefined;
422 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
423 Result |= SymbolRef::SF_Indirect;
425 if (MachOType & MachO::N_STAB)
426 Result |= SymbolRef::SF_FormatSpecific;
428 if (MachOType & MachO::N_EXT) {
429 Result |= SymbolRef::SF_Global;
430 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
432 getSymbolAddress(DRI, Value);
433 if (Value && Value != UnknownAddressOrSize)
434 Result |= SymbolRef::SF_Common;
438 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
439 Result |= SymbolRef::SF_Weak;
441 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
442 Result |= SymbolRef::SF_Thumb;
444 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
445 Result |= SymbolRef::SF_Absolute;
450 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
451 section_iterator &Res) const {
452 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
453 uint8_t index = Entry.n_sect;
460 Res = section_iterator(SectionRef(DRI, this));
463 return object_error::success;
466 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
470 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
471 StringRef &Result) const {
472 ArrayRef<char> Raw = getSectionRawName(Sec);
473 Result = parseSegmentOrSectionName(Raw.data());
474 return object_error::success;
477 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
478 uint64_t &Res) const {
480 MachO::section_64 Sect = getSection64(Sec);
483 MachO::section Sect = getSection(Sec);
486 return object_error::success;
489 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
490 uint64_t &Res) const {
492 MachO::section_64 Sect = getSection64(Sec);
495 MachO::section Sect = getSection(Sec);
499 return object_error::success;
502 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
503 StringRef &Res) const {
508 MachO::section_64 Sect = getSection64(Sec);
509 Offset = Sect.offset;
512 MachO::section Sect = getSection(Sec);
513 Offset = Sect.offset;
517 Res = this->getData().substr(Offset, Size);
518 return object_error::success;
521 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
522 uint64_t &Res) const {
525 MachO::section_64 Sect = getSection64(Sec);
528 MachO::section Sect = getSection(Sec);
532 Res = uint64_t(1) << Align;
533 return object_error::success;
536 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
538 uint32_t Flags = getSectionFlags(this, Sec);
539 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
540 return object_error::success;
543 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
544 bool &Result) const {
545 uint32_t Flags = getSectionFlags(this, Sec);
546 unsigned SectionType = Flags & MachO::SECTION_TYPE;
547 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
548 !(SectionType == MachO::S_ZEROFILL ||
549 SectionType == MachO::S_GB_ZEROFILL);
550 return object_error::success;
553 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
554 bool &Result) const {
555 uint32_t Flags = getSectionFlags(this, Sec);
556 unsigned SectionType = Flags & MachO::SECTION_TYPE;
557 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
558 (SectionType == MachO::S_ZEROFILL ||
559 SectionType == MachO::S_GB_ZEROFILL);
560 return object_error::success;
564 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
565 bool &Result) const {
566 // FIXME: Unimplemented.
568 return object_error::success;
571 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
572 bool &Result) const {
573 // FIXME: Unimplemented.
575 return object_error::success;
578 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
580 uint32_t Flags = getSectionFlags(this, Sec);
581 unsigned SectionType = Flags & MachO::SECTION_TYPE;
582 Res = SectionType == MachO::S_ZEROFILL ||
583 SectionType == MachO::S_GB_ZEROFILL;
584 return object_error::success;
587 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
588 bool &Result) const {
589 // Consider using the code from isSectionText to look for __const sections.
590 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
591 // to use section attributes to distinguish code from data.
593 // FIXME: Unimplemented.
595 return object_error::success;
598 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
600 bool &Result) const {
602 this->getSymbolType(Symb, ST);
603 if (ST == SymbolRef::ST_Unknown) {
605 return object_error::success;
608 uint64_t SectBegin, SectEnd;
609 getSectionAddress(Sec, SectBegin);
610 getSectionSize(Sec, SectEnd);
611 SectEnd += SectBegin;
614 getSymbolAddress(Symb, SymAddr);
615 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
617 return object_error::success;
620 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
624 return relocation_iterator(RelocationRef(Ret, this));
628 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
631 MachO::section_64 Sect = getSection64(Sec);
634 MachO::section Sect = getSection(Sec);
641 return relocation_iterator(RelocationRef(Ret, this));
644 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
648 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
649 uint64_t &Res) const {
651 getRelocationOffset(Rel, Offset);
656 getSectionAddress(Sec, SecAddress);
657 Res = SecAddress + Offset;
658 return object_error::success;
661 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
662 uint64_t &Res) const {
663 assert(getHeader().filetype == MachO::MH_OBJECT &&
664 "Only implemented for MH_OBJECT");
665 MachO::any_relocation_info RE = getRelocation(Rel);
666 Res = getAnyRelocationAddress(RE);
667 return object_error::success;
671 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
672 MachO::any_relocation_info RE = getRelocation(Rel);
673 if (isRelocationScattered(RE))
676 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
677 bool isExtern = getPlainRelocationExternal(RE);
681 MachO::symtab_command S = getSymtabLoadCommand();
682 unsigned SymbolTableEntrySize = is64Bit() ?
683 sizeof(MachO::nlist_64) :
684 sizeof(MachO::nlist);
685 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
687 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
688 return symbol_iterator(SymbolRef(Sym, this));
691 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
692 uint64_t &Res) const {
693 MachO::any_relocation_info RE = getRelocation(Rel);
694 Res = getAnyRelocationType(RE);
695 return object_error::success;
699 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
700 SmallVectorImpl<char> &Result) const {
703 getRelocationType(Rel, RType);
705 unsigned Arch = this->getArch();
709 static const char *const Table[] = {
710 "GENERIC_RELOC_VANILLA",
711 "GENERIC_RELOC_PAIR",
712 "GENERIC_RELOC_SECTDIFF",
713 "GENERIC_RELOC_PB_LA_PTR",
714 "GENERIC_RELOC_LOCAL_SECTDIFF",
715 "GENERIC_RELOC_TLV" };
723 case Triple::x86_64: {
724 static const char *const Table[] = {
725 "X86_64_RELOC_UNSIGNED",
726 "X86_64_RELOC_SIGNED",
727 "X86_64_RELOC_BRANCH",
728 "X86_64_RELOC_GOT_LOAD",
730 "X86_64_RELOC_SUBTRACTOR",
731 "X86_64_RELOC_SIGNED_1",
732 "X86_64_RELOC_SIGNED_2",
733 "X86_64_RELOC_SIGNED_4",
734 "X86_64_RELOC_TLV" };
743 static const char *const Table[] = {
746 "ARM_RELOC_SECTDIFF",
747 "ARM_RELOC_LOCAL_SECTDIFF",
748 "ARM_RELOC_PB_LA_PTR",
750 "ARM_THUMB_RELOC_BR22",
751 "ARM_THUMB_32BIT_BRANCH",
753 "ARM_RELOC_HALF_SECTDIFF" };
761 case Triple::aarch64: {
762 static const char *const Table[] = {
763 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
764 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
765 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
766 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
767 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
771 if (RType >= array_lengthof(Table))
778 static const char *const Table[] = {
787 "PPC_RELOC_SECTDIFF",
788 "PPC_RELOC_PB_LA_PTR",
789 "PPC_RELOC_HI16_SECTDIFF",
790 "PPC_RELOC_LO16_SECTDIFF",
791 "PPC_RELOC_HA16_SECTDIFF",
793 "PPC_RELOC_LO14_SECTDIFF",
794 "PPC_RELOC_LOCAL_SECTDIFF" };
802 case Triple::UnknownArch:
806 Result.append(res.begin(), res.end());
807 return object_error::success;
811 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
812 SmallVectorImpl<char> &Result) const {
813 MachO::any_relocation_info RE = getRelocation(Rel);
815 unsigned Arch = this->getArch();
818 raw_string_ostream fmt(fmtbuf);
819 unsigned Type = this->getAnyRelocationType(RE);
820 bool IsPCRel = this->getAnyRelocationPCRel(RE);
822 // Determine any addends that should be displayed with the relocation.
823 // These require decoding the relocation type, which is triple-specific.
825 // X86_64 has entirely custom relocation types.
826 if (Arch == Triple::x86_64) {
827 bool isPCRel = getAnyRelocationPCRel(RE);
830 case MachO::X86_64_RELOC_GOT_LOAD:
831 case MachO::X86_64_RELOC_GOT: {
832 printRelocationTargetName(this, RE, fmt);
834 if (isPCRel) fmt << "PCREL";
837 case MachO::X86_64_RELOC_SUBTRACTOR: {
838 DataRefImpl RelNext = Rel;
839 moveRelocationNext(RelNext);
840 MachO::any_relocation_info RENext = getRelocation(RelNext);
842 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
843 // X86_64_RELOC_UNSIGNED.
844 // NOTE: Scattered relocations don't exist on x86_64.
845 unsigned RType = getAnyRelocationType(RENext);
846 if (RType != MachO::X86_64_RELOC_UNSIGNED)
847 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
848 "X86_64_RELOC_SUBTRACTOR.");
850 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
851 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
852 printRelocationTargetName(this, RENext, fmt);
854 printRelocationTargetName(this, RE, fmt);
857 case MachO::X86_64_RELOC_TLV:
858 printRelocationTargetName(this, RE, fmt);
860 if (isPCRel) fmt << "P";
862 case MachO::X86_64_RELOC_SIGNED_1:
863 printRelocationTargetName(this, RE, fmt);
866 case MachO::X86_64_RELOC_SIGNED_2:
867 printRelocationTargetName(this, RE, fmt);
870 case MachO::X86_64_RELOC_SIGNED_4:
871 printRelocationTargetName(this, RE, fmt);
875 printRelocationTargetName(this, RE, fmt);
878 // X86 and ARM share some relocation types in common.
879 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
880 Arch == Triple::ppc) {
881 // Generic relocation types...
883 case MachO::GENERIC_RELOC_PAIR: // prints no info
884 return object_error::success;
885 case MachO::GENERIC_RELOC_SECTDIFF: {
886 DataRefImpl RelNext = Rel;
887 moveRelocationNext(RelNext);
888 MachO::any_relocation_info RENext = getRelocation(RelNext);
890 // X86 sect diff's must be followed by a relocation of type
891 // GENERIC_RELOC_PAIR.
892 unsigned RType = getAnyRelocationType(RENext);
894 if (RType != MachO::GENERIC_RELOC_PAIR)
895 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
896 "GENERIC_RELOC_SECTDIFF.");
898 printRelocationTargetName(this, RE, fmt);
900 printRelocationTargetName(this, RENext, fmt);
905 if (Arch == Triple::x86 || Arch == Triple::ppc) {
907 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
908 DataRefImpl RelNext = Rel;
909 moveRelocationNext(RelNext);
910 MachO::any_relocation_info RENext = getRelocation(RelNext);
912 // X86 sect diff's must be followed by a relocation of type
913 // GENERIC_RELOC_PAIR.
914 unsigned RType = getAnyRelocationType(RENext);
915 if (RType != MachO::GENERIC_RELOC_PAIR)
916 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
917 "GENERIC_RELOC_LOCAL_SECTDIFF.");
919 printRelocationTargetName(this, RE, fmt);
921 printRelocationTargetName(this, RENext, fmt);
924 case MachO::GENERIC_RELOC_TLV: {
925 printRelocationTargetName(this, RE, fmt);
927 if (IsPCRel) fmt << "P";
931 printRelocationTargetName(this, RE, fmt);
933 } else { // ARM-specific relocations
935 case MachO::ARM_RELOC_HALF:
936 case MachO::ARM_RELOC_HALF_SECTDIFF: {
937 // Half relocations steal a bit from the length field to encode
938 // whether this is an upper16 or a lower16 relocation.
939 bool isUpper = getAnyRelocationLength(RE) >> 1;
945 printRelocationTargetName(this, RE, fmt);
947 DataRefImpl RelNext = Rel;
948 moveRelocationNext(RelNext);
949 MachO::any_relocation_info RENext = getRelocation(RelNext);
951 // ARM half relocs must be followed by a relocation of type
953 unsigned RType = getAnyRelocationType(RENext);
954 if (RType != MachO::ARM_RELOC_PAIR)
955 report_fatal_error("Expected ARM_RELOC_PAIR after "
958 // NOTE: The half of the target virtual address is stashed in the
959 // address field of the secondary relocation, but we can't reverse
960 // engineer the constant offset from it without decoding the movw/movt
961 // instruction to find the other half in its immediate field.
963 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
964 // symbol/section pointer of the follow-on relocation.
965 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
967 printRelocationTargetName(this, RENext, fmt);
974 printRelocationTargetName(this, RE, fmt);
979 printRelocationTargetName(this, RE, fmt);
982 Result.append(fmtbuf.begin(), fmtbuf.end());
983 return object_error::success;
986 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
987 bool &Result) const {
988 unsigned Arch = getArch();
990 getRelocationType(Rel, Type);
994 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
996 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
997 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
998 } else if (Arch == Triple::x86_64) {
999 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1000 // an X86_64_RELOC_SUBTRACTOR.
1001 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1002 DataRefImpl RelPrev = Rel;
1005 getRelocationType(RelPrev, PrevType);
1006 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1011 return object_error::success;
1015 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1016 // guess on what the short name is. Then name is returned as a substring of the
1017 // StringRef Name passed in. The name of the dynamic library is recognized as
1018 // a framework if it has one of the two following forms:
1019 // Foo.framework/Versions/A/Foo
1020 // Foo.framework/Foo
1021 // Where A and Foo can be any string. And may contain a trailing suffix
1022 // starting with an underbar. If the Name is recognized as a framework then
1023 // isFramework is set to true else it is set to false. If the Name has a
1024 // suffix then Suffix is set to the substring in Name that contains the suffix
1025 // else it is set to a NULL StringRef.
1027 // The Name of the dynamic library is recognized as a library name if it has
1028 // one of the two following forms:
1031 // The library may have a suffix trailing the name Foo of the form:
1032 // libFoo_profile.A.dylib
1033 // libFoo_profile.dylib
1035 // The Name of the dynamic library is also recognized as a library name if it
1036 // has the following form:
1039 // If the Name of the dynamic library is none of the forms above then a NULL
1040 // StringRef is returned.
1042 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1044 StringRef &Suffix) {
1045 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1046 size_t a, b, c, d, Idx;
1048 isFramework = false;
1049 Suffix = StringRef();
1051 // Pull off the last component and make Foo point to it
1052 a = Name.rfind('/');
1053 if (a == Name.npos || a == 0)
1055 Foo = Name.slice(a+1, Name.npos);
1057 // Look for a suffix starting with a '_'
1058 Idx = Foo.rfind('_');
1059 if (Idx != Foo.npos && Foo.size() >= 2) {
1060 Suffix = Foo.slice(Idx, Foo.npos);
1061 Foo = Foo.slice(0, Idx);
1064 // First look for the form Foo.framework/Foo
1065 b = Name.rfind('/', a);
1070 F = Name.slice(Idx, Idx + Foo.size());
1071 DotFramework = Name.slice(Idx + Foo.size(),
1072 Idx + Foo.size() + sizeof(".framework/")-1);
1073 if (F == Foo && DotFramework == ".framework/") {
1078 // Next look for the form Foo.framework/Versions/A/Foo
1081 c = Name.rfind('/', b);
1082 if (c == Name.npos || c == 0)
1084 V = Name.slice(c+1, Name.npos);
1085 if (!V.startswith("Versions/"))
1087 d = Name.rfind('/', c);
1092 F = Name.slice(Idx, Idx + Foo.size());
1093 DotFramework = Name.slice(Idx + Foo.size(),
1094 Idx + Foo.size() + sizeof(".framework/")-1);
1095 if (F == Foo && DotFramework == ".framework/") {
1101 // pull off the suffix after the "." and make a point to it
1102 a = Name.rfind('.');
1103 if (a == Name.npos || a == 0)
1105 Dylib = Name.slice(a, Name.npos);
1106 if (Dylib != ".dylib")
1109 // First pull off the version letter for the form Foo.A.dylib if any.
1111 Dot = Name.slice(a-2, a-1);
1116 b = Name.rfind('/', a);
1121 // ignore any suffix after an underbar like Foo_profile.A.dylib
1122 Idx = Name.find('_', b);
1123 if (Idx != Name.npos && Idx != b) {
1124 Lib = Name.slice(b, Idx);
1125 Suffix = Name.slice(Idx, a);
1128 Lib = Name.slice(b, a);
1129 // There are incorrect library names of the form:
1130 // libATS.A_profile.dylib so check for these.
1131 if (Lib.size() >= 3) {
1132 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1134 Lib = Lib.slice(0, Lib.size()-2);
1139 Qtx = Name.slice(a, Name.npos);
1142 b = Name.rfind('/', a);
1144 Lib = Name.slice(0, a);
1146 Lib = Name.slice(b+1, a);
1147 // There are library names of the form: QT.A.qtx so check for these.
1148 if (Lib.size() >= 3) {
1149 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1151 Lib = Lib.slice(0, Lib.size()-2);
1156 // getLibraryShortNameByIndex() is used to get the short name of the library
1157 // for an undefined symbol in a linked Mach-O binary that was linked with the
1158 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1159 // It is passed the index (0 - based) of the library as translated from
1160 // GET_LIBRARY_ORDINAL (1 - based).
1161 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1163 if (Index >= Libraries.size())
1164 return object_error::parse_failed;
1166 MachO::dylib_command D =
1167 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1168 if (D.dylib.name >= D.cmdsize)
1169 return object_error::parse_failed;
1171 // If the cache of LibrariesShortNames is not built up do that first for
1172 // all the Libraries.
1173 if (LibrariesShortNames.size() == 0) {
1174 for (unsigned i = 0; i < Libraries.size(); i++) {
1175 MachO::dylib_command D =
1176 getStruct<MachO::dylib_command>(this, Libraries[i]);
1177 if (D.dylib.name >= D.cmdsize) {
1178 LibrariesShortNames.push_back(StringRef());
1181 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1182 StringRef Name = StringRef(P);
1185 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1186 if (shortName == StringRef())
1187 LibrariesShortNames.push_back(Name);
1189 LibrariesShortNames.push_back(shortName);
1193 Res = LibrariesShortNames[Index];
1194 return object_error::success;
1197 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1198 return getSymbolByIndex(0);
1201 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1204 return basic_symbol_iterator(SymbolRef(DRI, this));
1206 MachO::symtab_command Symtab = getSymtabLoadCommand();
1207 unsigned SymbolTableEntrySize = is64Bit() ?
1208 sizeof(MachO::nlist_64) :
1209 sizeof(MachO::nlist);
1210 unsigned Offset = Symtab.symoff +
1211 Symtab.nsyms * SymbolTableEntrySize;
1212 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1213 return basic_symbol_iterator(SymbolRef(DRI, this));
1216 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1219 return basic_symbol_iterator(SymbolRef(DRI, this));
1221 MachO::symtab_command Symtab = getSymtabLoadCommand();
1222 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1223 unsigned SymbolTableEntrySize =
1224 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1225 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1226 DRI.p += Index * SymbolTableEntrySize;
1227 return basic_symbol_iterator(SymbolRef(DRI, this));
1230 section_iterator MachOObjectFile::section_begin() const {
1232 return section_iterator(SectionRef(DRI, this));
1235 section_iterator MachOObjectFile::section_end() const {
1237 DRI.d.a = Sections.size();
1238 return section_iterator(SectionRef(DRI, this));
1241 uint8_t MachOObjectFile::getBytesInAddress() const {
1242 return is64Bit() ? 8 : 4;
1245 StringRef MachOObjectFile::getFileFormatName() const {
1246 unsigned CPUType = getCPUType(this);
1249 case llvm::MachO::CPU_TYPE_I386:
1250 return "Mach-O 32-bit i386";
1251 case llvm::MachO::CPU_TYPE_ARM:
1252 return "Mach-O arm";
1253 case llvm::MachO::CPU_TYPE_POWERPC:
1254 return "Mach-O 32-bit ppc";
1256 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1257 "64-bit object file when we're not 64-bit?");
1258 return "Mach-O 32-bit unknown";
1262 // Make sure the cpu type has the correct mask.
1263 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1264 == llvm::MachO::CPU_ARCH_ABI64 &&
1265 "32-bit object file when we're 64-bit?");
1268 case llvm::MachO::CPU_TYPE_X86_64:
1269 return "Mach-O 64-bit x86-64";
1270 case llvm::MachO::CPU_TYPE_ARM64:
1271 return "Mach-O arm64";
1272 case llvm::MachO::CPU_TYPE_POWERPC64:
1273 return "Mach-O 64-bit ppc64";
1275 return "Mach-O 64-bit unknown";
1279 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1281 case llvm::MachO::CPU_TYPE_I386:
1283 case llvm::MachO::CPU_TYPE_X86_64:
1284 return Triple::x86_64;
1285 case llvm::MachO::CPU_TYPE_ARM:
1287 case llvm::MachO::CPU_TYPE_ARM64:
1288 return Triple::aarch64;
1289 case llvm::MachO::CPU_TYPE_POWERPC:
1291 case llvm::MachO::CPU_TYPE_POWERPC64:
1292 return Triple::ppc64;
1294 return Triple::UnknownArch;
1298 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1299 const char **McpuDefault) {
1301 *McpuDefault = nullptr;
1304 case MachO::CPU_TYPE_I386:
1305 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1306 case MachO::CPU_SUBTYPE_I386_ALL:
1307 return Triple("i386-apple-darwin");
1311 case MachO::CPU_TYPE_X86_64:
1312 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1313 case MachO::CPU_SUBTYPE_X86_64_ALL:
1314 return Triple("x86_64-apple-darwin");
1315 case MachO::CPU_SUBTYPE_X86_64_H:
1316 return Triple("x86_64h-apple-darwin");
1320 case MachO::CPU_TYPE_ARM:
1321 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1322 case MachO::CPU_SUBTYPE_ARM_V4T:
1323 return Triple("armv4t-apple-darwin");
1324 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1325 return Triple("armv5e-apple-darwin");
1326 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1327 return Triple("xscale-apple-darwin");
1328 case MachO::CPU_SUBTYPE_ARM_V6:
1329 return Triple("armv6-apple-darwin");
1330 case MachO::CPU_SUBTYPE_ARM_V6M:
1332 *McpuDefault = "cortex-m0";
1333 return Triple("armv6m-apple-darwin");
1334 case MachO::CPU_SUBTYPE_ARM_V7:
1335 return Triple("armv7-apple-darwin");
1336 case MachO::CPU_SUBTYPE_ARM_V7EM:
1338 *McpuDefault = "cortex-m4";
1339 return Triple("armv7em-apple-darwin");
1340 case MachO::CPU_SUBTYPE_ARM_V7K:
1341 return Triple("armv7k-apple-darwin");
1342 case MachO::CPU_SUBTYPE_ARM_V7M:
1344 *McpuDefault = "cortex-m3";
1345 return Triple("armv7m-apple-darwin");
1346 case MachO::CPU_SUBTYPE_ARM_V7S:
1347 return Triple("armv7s-apple-darwin");
1351 case MachO::CPU_TYPE_ARM64:
1352 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1353 case MachO::CPU_SUBTYPE_ARM64_ALL:
1354 return Triple("arm64-apple-darwin");
1358 case MachO::CPU_TYPE_POWERPC:
1359 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1360 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1361 return Triple("ppc-apple-darwin");
1365 case MachO::CPU_TYPE_POWERPC64:
1366 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1367 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1368 return Triple("ppc64-apple-darwin");
1377 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1378 const char **McpuDefault) {
1380 *McpuDefault = nullptr;
1383 case MachO::CPU_TYPE_ARM:
1384 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1385 case MachO::CPU_SUBTYPE_ARM_V4T:
1386 return Triple("thumbv4t-apple-darwin");
1387 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1388 return Triple("thumbv5e-apple-darwin");
1389 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1390 return Triple("xscale-apple-darwin");
1391 case MachO::CPU_SUBTYPE_ARM_V6:
1392 return Triple("thumbv6-apple-darwin");
1393 case MachO::CPU_SUBTYPE_ARM_V6M:
1395 *McpuDefault = "cortex-m0";
1396 return Triple("thumbv6m-apple-darwin");
1397 case MachO::CPU_SUBTYPE_ARM_V7:
1398 return Triple("thumbv7-apple-darwin");
1399 case MachO::CPU_SUBTYPE_ARM_V7EM:
1401 *McpuDefault = "cortex-m4";
1402 return Triple("thumbv7em-apple-darwin");
1403 case MachO::CPU_SUBTYPE_ARM_V7K:
1404 return Triple("thumbv7k-apple-darwin");
1405 case MachO::CPU_SUBTYPE_ARM_V7M:
1407 *McpuDefault = "cortex-m3";
1408 return Triple("thumbv7m-apple-darwin");
1409 case MachO::CPU_SUBTYPE_ARM_V7S:
1410 return Triple("thumbv7s-apple-darwin");
1419 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1420 const char **McpuDefault,
1421 Triple *ThumbTriple) {
1422 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1423 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1428 Triple MachOObjectFile::getHostArch() {
1429 return Triple(sys::getDefaultTargetTriple());
1432 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1433 return StringSwitch<bool>(ArchFlag)
1435 .Case("x86_64", true)
1436 .Case("x86_64h", true)
1437 .Case("armv4t", true)
1439 .Case("armv5e", true)
1440 .Case("armv6", true)
1441 .Case("armv6m", true)
1442 .Case("armv7em", true)
1443 .Case("armv7k", true)
1444 .Case("armv7m", true)
1445 .Case("armv7s", true)
1446 .Case("arm64", true)
1448 .Case("ppc64", true)
1452 unsigned MachOObjectFile::getArch() const {
1453 return getArch(getCPUType(this));
1456 Triple MachOObjectFile::getArch(const char **McpuDefault,
1457 Triple *ThumbTriple) const {
1460 MachO::mach_header_64 H_64;
1461 H_64 = getHeader64();
1462 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
1463 *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
1466 MachO::mach_header H;
1468 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
1469 *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
1475 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1478 return section_rel_begin(DRI);
1481 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1484 return section_rel_end(DRI);
1487 dice_iterator MachOObjectFile::begin_dices() const {
1489 if (!DataInCodeLoadCmd)
1490 return dice_iterator(DiceRef(DRI, this));
1492 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1493 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1494 return dice_iterator(DiceRef(DRI, this));
1497 dice_iterator MachOObjectFile::end_dices() const {
1499 if (!DataInCodeLoadCmd)
1500 return dice_iterator(DiceRef(DRI, this));
1502 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1503 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1504 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1505 return dice_iterator(DiceRef(DRI, this));
1509 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1510 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1511 return parseSegmentOrSectionName(Raw.data());
1515 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1516 const section_base *Base =
1517 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1518 return makeArrayRef(Base->sectname);
1522 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1523 const section_base *Base =
1524 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1525 return makeArrayRef(Base->segname);
1529 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1531 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1533 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1536 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1537 const MachO::any_relocation_info &RE) const {
1538 if (isLittleEndian())
1539 return RE.r_word1 & 0xffffff;
1540 return RE.r_word1 >> 8;
1543 bool MachOObjectFile::getPlainRelocationExternal(
1544 const MachO::any_relocation_info &RE) const {
1545 if (isLittleEndian())
1546 return (RE.r_word1 >> 27) & 1;
1547 return (RE.r_word1 >> 4) & 1;
1550 bool MachOObjectFile::getScatteredRelocationScattered(
1551 const MachO::any_relocation_info &RE) const {
1552 return RE.r_word0 >> 31;
1555 uint32_t MachOObjectFile::getScatteredRelocationValue(
1556 const MachO::any_relocation_info &RE) const {
1560 unsigned MachOObjectFile::getAnyRelocationAddress(
1561 const MachO::any_relocation_info &RE) const {
1562 if (isRelocationScattered(RE))
1563 return getScatteredRelocationAddress(RE);
1564 return getPlainRelocationAddress(RE);
1567 unsigned MachOObjectFile::getAnyRelocationPCRel(
1568 const MachO::any_relocation_info &RE) const {
1569 if (isRelocationScattered(RE))
1570 return getScatteredRelocationPCRel(this, RE);
1571 return getPlainRelocationPCRel(this, RE);
1574 unsigned MachOObjectFile::getAnyRelocationLength(
1575 const MachO::any_relocation_info &RE) const {
1576 if (isRelocationScattered(RE))
1577 return getScatteredRelocationLength(RE);
1578 return getPlainRelocationLength(this, RE);
1582 MachOObjectFile::getAnyRelocationType(
1583 const MachO::any_relocation_info &RE) const {
1584 if (isRelocationScattered(RE))
1585 return getScatteredRelocationType(RE);
1586 return getPlainRelocationType(this, RE);
1590 MachOObjectFile::getRelocationSection(
1591 const MachO::any_relocation_info &RE) const {
1592 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1593 return *section_end();
1594 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1597 return SectionRef(DRI, this);
1600 MachOObjectFile::LoadCommandInfo
1601 MachOObjectFile::getFirstLoadCommandInfo() const {
1602 MachOObjectFile::LoadCommandInfo Load;
1604 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1605 sizeof(MachO::mach_header);
1606 Load.Ptr = getPtr(this, HeaderSize);
1607 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1611 MachOObjectFile::LoadCommandInfo
1612 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1613 MachOObjectFile::LoadCommandInfo Next;
1614 Next.Ptr = L.Ptr + L.C.cmdsize;
1615 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1619 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1620 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1623 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1624 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1627 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1628 unsigned Index) const {
1629 const char *Sec = getSectionPtr(this, L, Index);
1630 return getStruct<MachO::section>(this, Sec);
1633 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1634 unsigned Index) const {
1635 const char *Sec = getSectionPtr(this, L, Index);
1636 return getStruct<MachO::section_64>(this, Sec);
1640 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1641 const char *P = reinterpret_cast<const char *>(DRI.p);
1642 return getStruct<MachO::nlist>(this, P);
1646 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1647 const char *P = reinterpret_cast<const char *>(DRI.p);
1648 return getStruct<MachO::nlist_64>(this, P);
1651 MachO::linkedit_data_command
1652 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1653 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1656 MachO::segment_command
1657 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1658 return getStruct<MachO::segment_command>(this, L.Ptr);
1661 MachO::segment_command_64
1662 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1663 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1666 MachO::linker_options_command
1667 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1668 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1671 MachO::version_min_command
1672 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1673 return getStruct<MachO::version_min_command>(this, L.Ptr);
1676 MachO::dylib_command
1677 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1678 return getStruct<MachO::dylib_command>(this, L.Ptr);
1682 MachO::any_relocation_info
1683 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1688 MachO::section_64 Sect = getSection64(Sec);
1689 Offset = Sect.reloff;
1691 MachO::section Sect = getSection(Sec);
1692 Offset = Sect.reloff;
1695 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1696 getPtr(this, Offset)) + Rel.d.b;
1697 return getStruct<MachO::any_relocation_info>(
1698 this, reinterpret_cast<const char *>(P));
1701 MachO::data_in_code_entry
1702 MachOObjectFile::getDice(DataRefImpl Rel) const {
1703 const char *P = reinterpret_cast<const char *>(Rel.p);
1704 return getStruct<MachO::data_in_code_entry>(this, P);
1707 MachO::mach_header MachOObjectFile::getHeader() const {
1708 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1711 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1712 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1715 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1716 const MachO::dysymtab_command &DLC,
1717 unsigned Index) const {
1718 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1719 return getStruct<uint32_t>(this, getPtr(this, Offset));
1722 MachO::data_in_code_entry
1723 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1724 unsigned Index) const {
1725 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1726 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1729 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1730 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1733 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1734 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1737 MachO::linkedit_data_command
1738 MachOObjectFile::getDataInCodeLoadCommand() const {
1739 if (DataInCodeLoadCmd)
1740 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1742 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1743 MachO::linkedit_data_command Cmd;
1744 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1745 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1751 StringRef MachOObjectFile::getStringTableData() const {
1752 MachO::symtab_command S = getSymtabLoadCommand();
1753 return getData().substr(S.stroff, S.strsize);
1756 bool MachOObjectFile::is64Bit() const {
1757 return getType() == getMachOType(false, true) ||
1758 getType() == getMachOType(true, true);
1761 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1762 SmallVectorImpl<uint64_t> &Out) const {
1763 DataExtractor extractor(ObjectFile::getData(), true, 0);
1765 uint32_t offset = Index;
1767 while (uint64_t delta = extractor.getULEB128(&offset)) {
1769 Out.push_back(data);
1773 bool MachOObjectFile::isRelocatableObject() const {
1774 return getHeader().filetype == MachO::MH_OBJECT;
1777 ErrorOr<std::unique_ptr<MachOObjectFile>>
1778 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
1779 StringRef Magic = Buffer.getBuffer().slice(0, 4);
1781 std::unique_ptr<MachOObjectFile> Ret;
1782 if (Magic == "\xFE\xED\xFA\xCE")
1783 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
1784 else if (Magic == "\xCE\xFA\xED\xFE")
1785 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
1786 else if (Magic == "\xFE\xED\xFA\xCF")
1787 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
1788 else if (Magic == "\xCF\xFA\xED\xFE")
1789 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
1791 return object_error::parse_failed;
1795 return std::move(Ret);