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/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/raw_ostream.h"
32 using namespace object;
42 static T getStruct(const MachOObjectFile *O, const char *P) {
44 memcpy(&Cmd, P, sizeof(T));
45 if (O->isLittleEndian() != sys::IsLittleEndianHost)
46 MachO::swapStruct(Cmd);
51 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
52 const MachOObjectFile::LoadCommandInfo &L) {
54 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
57 MachO::segment_command S = O->getSegmentLoadCommand(L);
61 static bool isPageZeroSegment(const MachOObjectFile *O,
62 const MachOObjectFile::LoadCommandInfo &L) {
64 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
65 return StringRef("__PAGEZERO").equals(S.segname);
67 MachO::segment_command S = O->getSegmentLoadCommand(L);
68 return StringRef("__PAGEZERO").equals(S.segname);
73 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
75 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
77 bool Is64 = O->is64Bit();
78 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
79 sizeof(MachO::segment_command);
80 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
81 sizeof(MachO::section);
83 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
84 return reinterpret_cast<const char*>(SectionAddr);
87 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
88 return O->getData().substr(Offset, 1).data();
91 static MachO::nlist_base
92 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
93 const char *P = reinterpret_cast<const char *>(DRI.p);
94 return getStruct<MachO::nlist_base>(O, P);
97 static StringRef parseSegmentOrSectionName(const char *P) {
101 // Not null terminated, so this is a 16 char string.
102 return StringRef(P, 16);
105 // Helper to advance a section or symbol iterator multiple increments at a time.
107 static void advance(T &it, size_t Val) {
112 static unsigned getCPUType(const MachOObjectFile *O) {
113 return O->getHeader().cputype;
116 static void printRelocationTargetName(const MachOObjectFile *O,
117 const MachO::any_relocation_info &RE,
118 raw_string_ostream &fmt) {
119 bool IsScattered = O->isRelocationScattered(RE);
121 // Target of a scattered relocation is an address. In the interest of
122 // generating pretty output, scan through the symbol table looking for a
123 // symbol that aligns with that address. If we find one, print it.
124 // Otherwise, we just print the hex address of the target.
126 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
128 for (const SymbolRef &Symbol : O->symbols()) {
133 if ((ec = Symbol.getAddress(Addr)))
134 report_fatal_error(ec.message());
137 if ((ec = Symbol.getName(Name)))
138 report_fatal_error(ec.message());
143 // If we couldn't find a symbol that this relocation refers to, try
144 // to find a section beginning instead.
145 for (const SectionRef &Section : O->sections()) {
149 uint64_t Addr = Section.getAddress();
152 if ((ec = Section.getName(Name)))
153 report_fatal_error(ec.message());
158 fmt << format("0x%x", Val);
163 bool isExtern = O->getPlainRelocationExternal(RE);
164 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
167 symbol_iterator SI = O->symbol_begin();
171 section_iterator SI = O->section_begin();
172 // Adjust for the fact that sections are 1-indexed.
173 advance(SI, Val - 1);
181 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
186 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
187 return RE.r_word0 & 0xffffff;
190 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
191 const MachO::any_relocation_info &RE) {
192 if (O->isLittleEndian())
193 return (RE.r_word1 >> 24) & 1;
194 return (RE.r_word1 >> 7) & 1;
198 getScatteredRelocationPCRel(const MachOObjectFile *O,
199 const MachO::any_relocation_info &RE) {
200 return (RE.r_word0 >> 30) & 1;
203 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
204 const MachO::any_relocation_info &RE) {
205 if (O->isLittleEndian())
206 return (RE.r_word1 >> 25) & 3;
207 return (RE.r_word1 >> 5) & 3;
211 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
212 return (RE.r_word0 >> 28) & 3;
215 static unsigned getPlainRelocationType(const MachOObjectFile *O,
216 const MachO::any_relocation_info &RE) {
217 if (O->isLittleEndian())
218 return RE.r_word1 >> 28;
219 return RE.r_word1 & 0xf;
222 static uint32_t getSectionFlags(const MachOObjectFile *O,
225 MachO::section_64 Sect = O->getSection64(Sec);
228 MachO::section Sect = O->getSection(Sec);
232 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
233 bool Is64bits, std::error_code &EC)
234 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
235 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
236 DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
237 UuidLoadCmd(nullptr), HasPageZeroSegment(false) {
238 uint32_t LoadCommandCount = this->getHeader().ncmds;
239 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
240 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
242 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
243 for (unsigned I = 0; ; ++I) {
244 if (Load.C.cmd == MachO::LC_SYMTAB) {
245 // Multiple symbol tables
247 EC = object_error::parse_failed;
250 SymtabLoadCmd = Load.Ptr;
251 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
252 // Multiple dynamic symbol tables
253 if (DysymtabLoadCmd) {
254 EC = object_error::parse_failed;
257 DysymtabLoadCmd = Load.Ptr;
258 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
259 // Multiple data in code tables
260 if (DataInCodeLoadCmd) {
261 EC = object_error::parse_failed;
264 DataInCodeLoadCmd = Load.Ptr;
265 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
266 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
267 // Multiple dyldinfo load commands
268 if (DyldInfoLoadCmd) {
269 EC = object_error::parse_failed;
272 DyldInfoLoadCmd = Load.Ptr;
273 } else if (Load.C.cmd == MachO::LC_UUID) {
274 // Multiple UUID load commands
276 EC = object_error::parse_failed;
279 UuidLoadCmd = Load.Ptr;
280 } else if (Load.C.cmd == SegmentLoadType) {
281 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
282 for (unsigned J = 0; J < NumSections; ++J) {
283 const char *Sec = getSectionPtr(this, Load, J);
284 Sections.push_back(Sec);
286 if (isPageZeroSegment(this, Load))
287 HasPageZeroSegment = true;
288 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
289 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
290 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
291 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
292 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
293 Libraries.push_back(Load.Ptr);
296 if (I == LoadCommandCount - 1)
299 Load = getNextLoadCommandInfo(Load);
303 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
304 unsigned SymbolTableEntrySize = is64Bit() ?
305 sizeof(MachO::nlist_64) :
306 sizeof(MachO::nlist);
307 Symb.p += SymbolTableEntrySize;
310 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
311 StringRef &Res) const {
312 StringRef StringTable = getStringTableData();
313 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
314 const char *Start = &StringTable.data()[Entry.n_strx];
315 Res = StringRef(Start);
316 return object_error::success;
319 // getIndirectName() returns the name of the alias'ed symbol who's string table
320 // index is in the n_value field.
321 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
322 StringRef &Res) const {
323 StringRef StringTable = getStringTableData();
326 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
327 NValue = Entry.n_value;
328 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
329 return object_error::parse_failed;
331 MachO::nlist Entry = getSymbolTableEntry(Symb);
332 NValue = Entry.n_value;
333 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
334 return object_error::parse_failed;
336 if (NValue >= StringTable.size())
337 return object_error::parse_failed;
338 const char *Start = &StringTable.data()[NValue];
339 Res = StringRef(Start);
340 return object_error::success;
343 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
344 uint64_t &Res) const {
346 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
347 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
349 Res = UnknownAddressOrSize;
353 MachO::nlist Entry = getSymbolTableEntry(Symb);
354 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
356 Res = UnknownAddressOrSize;
360 return object_error::success;
363 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
364 uint32_t &Result) const {
365 uint32_t flags = getSymbolFlags(DRI);
366 if (flags & SymbolRef::SF_Common) {
367 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
368 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
372 return object_error::success;
375 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
376 uint64_t &Result) const {
377 uint64_t BeginOffset;
378 uint64_t EndOffset = 0;
379 uint8_t SectionIndex;
381 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
383 getSymbolAddress(DRI, Value);
384 if (Value == UnknownAddressOrSize) {
385 Result = UnknownAddressOrSize;
386 return object_error::success;
391 SectionIndex = Entry.n_sect;
393 uint32_t flags = getSymbolFlags(DRI);
394 if (flags & SymbolRef::SF_Common)
397 Result = UnknownAddressOrSize;
398 return object_error::success;
400 // Unfortunately symbols are unsorted so we need to touch all
401 // symbols from load command
402 for (const SymbolRef &Symbol : symbols()) {
403 DataRefImpl DRI = Symbol.getRawDataRefImpl();
404 Entry = getSymbolTableEntryBase(this, DRI);
405 getSymbolAddress(DRI, Value);
406 if (Value == UnknownAddressOrSize)
408 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
409 if (!EndOffset || Value < EndOffset)
414 Sec.d.a = SectionIndex-1;
415 uint64_t Size = getSectionSize(Sec);
416 EndOffset = getSectionAddress(Sec);
419 Result = EndOffset - BeginOffset;
420 return object_error::success;
423 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
424 SymbolRef::Type &Res) const {
425 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
426 uint8_t n_type = Entry.n_type;
428 Res = SymbolRef::ST_Other;
430 // If this is a STAB debugging symbol, we can do nothing more.
431 if (n_type & MachO::N_STAB) {
432 Res = SymbolRef::ST_Debug;
433 return object_error::success;
436 switch (n_type & MachO::N_TYPE) {
438 Res = SymbolRef::ST_Unknown;
441 Res = SymbolRef::ST_Function;
444 return object_error::success;
447 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
448 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
450 uint8_t MachOType = Entry.n_type;
451 uint16_t MachOFlags = Entry.n_desc;
453 uint32_t Result = SymbolRef::SF_None;
455 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
456 Result |= SymbolRef::SF_Undefined;
458 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
459 Result |= SymbolRef::SF_Indirect;
461 if (MachOType & MachO::N_STAB)
462 Result |= SymbolRef::SF_FormatSpecific;
464 if (MachOType & MachO::N_EXT) {
465 Result |= SymbolRef::SF_Global;
466 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
468 getSymbolAddress(DRI, Value);
469 if (Value && Value != UnknownAddressOrSize)
470 Result |= SymbolRef::SF_Common;
474 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
475 Result |= SymbolRef::SF_Weak;
477 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
478 Result |= SymbolRef::SF_Thumb;
480 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
481 Result |= SymbolRef::SF_Absolute;
486 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
487 section_iterator &Res) const {
488 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
489 uint8_t index = Entry.n_sect;
496 Res = section_iterator(SectionRef(DRI, this));
499 return object_error::success;
502 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
506 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
507 StringRef &Result) const {
508 ArrayRef<char> Raw = getSectionRawName(Sec);
509 Result = parseSegmentOrSectionName(Raw.data());
510 return object_error::success;
513 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
515 return getSection64(Sec).addr;
516 return getSection(Sec).addr;
519 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
521 return getSection64(Sec).size;
522 return getSection(Sec).size;
525 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
526 StringRef &Res) const {
531 MachO::section_64 Sect = getSection64(Sec);
532 Offset = Sect.offset;
535 MachO::section Sect = getSection(Sec);
536 Offset = Sect.offset;
540 Res = this->getData().substr(Offset, Size);
541 return object_error::success;
544 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
547 MachO::section_64 Sect = getSection64(Sec);
550 MachO::section Sect = getSection(Sec);
554 return uint64_t(1) << Align;
557 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
558 uint32_t Flags = getSectionFlags(this, Sec);
559 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
562 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
563 uint32_t Flags = getSectionFlags(this, Sec);
564 unsigned SectionType = Flags & MachO::SECTION_TYPE;
565 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
566 !(SectionType == MachO::S_ZEROFILL ||
567 SectionType == MachO::S_GB_ZEROFILL);
570 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
571 uint32_t Flags = getSectionFlags(this, Sec);
572 unsigned SectionType = Flags & MachO::SECTION_TYPE;
573 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
574 (SectionType == MachO::S_ZEROFILL ||
575 SectionType == MachO::S_GB_ZEROFILL);
578 bool MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sect) const {
579 // FIXME: Unimplemented.
583 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
584 // FIXME: Unimplemented.
588 bool MachOObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
589 uint32_t Flags = getSectionFlags(this, Sec);
590 unsigned SectionType = Flags & MachO::SECTION_TYPE;
591 return SectionType == MachO::S_ZEROFILL ||
592 SectionType == MachO::S_GB_ZEROFILL;
595 bool MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const {
596 // Consider using the code from isSectionText to look for __const sections.
597 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
598 // to use section attributes to distinguish code from data.
600 // FIXME: Unimplemented.
604 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
605 DataRefImpl Symb) const {
607 this->getSymbolType(Symb, ST);
608 if (ST == SymbolRef::ST_Unknown)
611 uint64_t SectBegin = getSectionAddress(Sec);
612 uint64_t SectEnd = getSectionSize(Sec);
613 SectEnd += SectBegin;
616 getSymbolAddress(Symb, SymAddr);
617 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
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);
655 uint64_t SecAddress = getSectionAddress(Sec);
656 Res = SecAddress + Offset;
657 return object_error::success;
660 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
661 uint64_t &Res) const {
662 assert(getHeader().filetype == MachO::MH_OBJECT &&
663 "Only implemented for MH_OBJECT");
664 MachO::any_relocation_info RE = getRelocation(Rel);
665 Res = getAnyRelocationAddress(RE);
666 return object_error::success;
670 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
671 MachO::any_relocation_info RE = getRelocation(Rel);
672 if (isRelocationScattered(RE))
675 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
676 bool isExtern = getPlainRelocationExternal(RE);
680 MachO::symtab_command S = getSymtabLoadCommand();
681 unsigned SymbolTableEntrySize = is64Bit() ?
682 sizeof(MachO::nlist_64) :
683 sizeof(MachO::nlist);
684 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
686 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
687 return symbol_iterator(SymbolRef(Sym, this));
690 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
691 uint64_t &Res) const {
692 MachO::any_relocation_info RE = getRelocation(Rel);
693 Res = getAnyRelocationType(RE);
694 return object_error::success;
698 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
699 SmallVectorImpl<char> &Result) const {
702 getRelocationType(Rel, RType);
704 unsigned Arch = this->getArch();
708 static const char *const Table[] = {
709 "GENERIC_RELOC_VANILLA",
710 "GENERIC_RELOC_PAIR",
711 "GENERIC_RELOC_SECTDIFF",
712 "GENERIC_RELOC_PB_LA_PTR",
713 "GENERIC_RELOC_LOCAL_SECTDIFF",
714 "GENERIC_RELOC_TLV" };
722 case Triple::x86_64: {
723 static const char *const Table[] = {
724 "X86_64_RELOC_UNSIGNED",
725 "X86_64_RELOC_SIGNED",
726 "X86_64_RELOC_BRANCH",
727 "X86_64_RELOC_GOT_LOAD",
729 "X86_64_RELOC_SUBTRACTOR",
730 "X86_64_RELOC_SIGNED_1",
731 "X86_64_RELOC_SIGNED_2",
732 "X86_64_RELOC_SIGNED_4",
733 "X86_64_RELOC_TLV" };
742 static const char *const Table[] = {
745 "ARM_RELOC_SECTDIFF",
746 "ARM_RELOC_LOCAL_SECTDIFF",
747 "ARM_RELOC_PB_LA_PTR",
749 "ARM_THUMB_RELOC_BR22",
750 "ARM_THUMB_32BIT_BRANCH",
752 "ARM_RELOC_HALF_SECTDIFF" };
760 case Triple::aarch64: {
761 static const char *const Table[] = {
762 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
763 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
764 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
765 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
766 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
770 if (RType >= array_lengthof(Table))
777 static const char *const Table[] = {
786 "PPC_RELOC_SECTDIFF",
787 "PPC_RELOC_PB_LA_PTR",
788 "PPC_RELOC_HI16_SECTDIFF",
789 "PPC_RELOC_LO16_SECTDIFF",
790 "PPC_RELOC_HA16_SECTDIFF",
792 "PPC_RELOC_LO14_SECTDIFF",
793 "PPC_RELOC_LOCAL_SECTDIFF" };
801 case Triple::UnknownArch:
805 Result.append(res.begin(), res.end());
806 return object_error::success;
810 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
811 SmallVectorImpl<char> &Result) const {
812 MachO::any_relocation_info RE = getRelocation(Rel);
814 unsigned Arch = this->getArch();
817 raw_string_ostream fmt(fmtbuf);
818 unsigned Type = this->getAnyRelocationType(RE);
819 bool IsPCRel = this->getAnyRelocationPCRel(RE);
821 // Determine any addends that should be displayed with the relocation.
822 // These require decoding the relocation type, which is triple-specific.
824 // X86_64 has entirely custom relocation types.
825 if (Arch == Triple::x86_64) {
826 bool isPCRel = getAnyRelocationPCRel(RE);
829 case MachO::X86_64_RELOC_GOT_LOAD:
830 case MachO::X86_64_RELOC_GOT: {
831 printRelocationTargetName(this, RE, fmt);
833 if (isPCRel) fmt << "PCREL";
836 case MachO::X86_64_RELOC_SUBTRACTOR: {
837 DataRefImpl RelNext = Rel;
838 moveRelocationNext(RelNext);
839 MachO::any_relocation_info RENext = getRelocation(RelNext);
841 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
842 // X86_64_RELOC_UNSIGNED.
843 // NOTE: Scattered relocations don't exist on x86_64.
844 unsigned RType = getAnyRelocationType(RENext);
845 if (RType != MachO::X86_64_RELOC_UNSIGNED)
846 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
847 "X86_64_RELOC_SUBTRACTOR.");
849 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
850 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
851 printRelocationTargetName(this, RENext, fmt);
853 printRelocationTargetName(this, RE, fmt);
856 case MachO::X86_64_RELOC_TLV:
857 printRelocationTargetName(this, RE, fmt);
859 if (isPCRel) fmt << "P";
861 case MachO::X86_64_RELOC_SIGNED_1:
862 printRelocationTargetName(this, RE, fmt);
865 case MachO::X86_64_RELOC_SIGNED_2:
866 printRelocationTargetName(this, RE, fmt);
869 case MachO::X86_64_RELOC_SIGNED_4:
870 printRelocationTargetName(this, RE, fmt);
874 printRelocationTargetName(this, RE, fmt);
877 // X86 and ARM share some relocation types in common.
878 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
879 Arch == Triple::ppc) {
880 // Generic relocation types...
882 case MachO::GENERIC_RELOC_PAIR: // prints no info
883 return object_error::success;
884 case MachO::GENERIC_RELOC_SECTDIFF: {
885 DataRefImpl RelNext = Rel;
886 moveRelocationNext(RelNext);
887 MachO::any_relocation_info RENext = getRelocation(RelNext);
889 // X86 sect diff's must be followed by a relocation of type
890 // GENERIC_RELOC_PAIR.
891 unsigned RType = getAnyRelocationType(RENext);
893 if (RType != MachO::GENERIC_RELOC_PAIR)
894 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
895 "GENERIC_RELOC_SECTDIFF.");
897 printRelocationTargetName(this, RE, fmt);
899 printRelocationTargetName(this, RENext, fmt);
904 if (Arch == Triple::x86 || Arch == Triple::ppc) {
906 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
907 DataRefImpl RelNext = Rel;
908 moveRelocationNext(RelNext);
909 MachO::any_relocation_info RENext = getRelocation(RelNext);
911 // X86 sect diff's must be followed by a relocation of type
912 // GENERIC_RELOC_PAIR.
913 unsigned RType = getAnyRelocationType(RENext);
914 if (RType != MachO::GENERIC_RELOC_PAIR)
915 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
916 "GENERIC_RELOC_LOCAL_SECTDIFF.");
918 printRelocationTargetName(this, RE, fmt);
920 printRelocationTargetName(this, RENext, fmt);
923 case MachO::GENERIC_RELOC_TLV: {
924 printRelocationTargetName(this, RE, fmt);
926 if (IsPCRel) fmt << "P";
930 printRelocationTargetName(this, RE, fmt);
932 } else { // ARM-specific relocations
934 case MachO::ARM_RELOC_HALF:
935 case MachO::ARM_RELOC_HALF_SECTDIFF: {
936 // Half relocations steal a bit from the length field to encode
937 // whether this is an upper16 or a lower16 relocation.
938 bool isUpper = getAnyRelocationLength(RE) >> 1;
944 printRelocationTargetName(this, RE, fmt);
946 DataRefImpl RelNext = Rel;
947 moveRelocationNext(RelNext);
948 MachO::any_relocation_info RENext = getRelocation(RelNext);
950 // ARM half relocs must be followed by a relocation of type
952 unsigned RType = getAnyRelocationType(RENext);
953 if (RType != MachO::ARM_RELOC_PAIR)
954 report_fatal_error("Expected ARM_RELOC_PAIR after "
957 // NOTE: The half of the target virtual address is stashed in the
958 // address field of the secondary relocation, but we can't reverse
959 // engineer the constant offset from it without decoding the movw/movt
960 // instruction to find the other half in its immediate field.
962 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
963 // symbol/section pointer of the follow-on relocation.
964 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
966 printRelocationTargetName(this, RENext, fmt);
973 printRelocationTargetName(this, RE, fmt);
978 printRelocationTargetName(this, RE, fmt);
981 Result.append(fmtbuf.begin(), fmtbuf.end());
982 return object_error::success;
985 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
986 bool &Result) const {
987 unsigned Arch = getArch();
989 getRelocationType(Rel, Type);
993 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
995 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
996 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
997 } else if (Arch == Triple::x86_64) {
998 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
999 // an X86_64_RELOC_SUBTRACTOR.
1000 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1001 DataRefImpl RelPrev = Rel;
1004 getRelocationType(RelPrev, PrevType);
1005 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1010 return object_error::success;
1014 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1015 // guess on what the short name is. Then name is returned as a substring of the
1016 // StringRef Name passed in. The name of the dynamic library is recognized as
1017 // a framework if it has one of the two following forms:
1018 // Foo.framework/Versions/A/Foo
1019 // Foo.framework/Foo
1020 // Where A and Foo can be any string. And may contain a trailing suffix
1021 // starting with an underbar. If the Name is recognized as a framework then
1022 // isFramework is set to true else it is set to false. If the Name has a
1023 // suffix then Suffix is set to the substring in Name that contains the suffix
1024 // else it is set to a NULL StringRef.
1026 // The Name of the dynamic library is recognized as a library name if it has
1027 // one of the two following forms:
1030 // The library may have a suffix trailing the name Foo of the form:
1031 // libFoo_profile.A.dylib
1032 // libFoo_profile.dylib
1034 // The Name of the dynamic library is also recognized as a library name if it
1035 // has the following form:
1038 // If the Name of the dynamic library is none of the forms above then a NULL
1039 // StringRef is returned.
1041 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1043 StringRef &Suffix) {
1044 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1045 size_t a, b, c, d, Idx;
1047 isFramework = false;
1048 Suffix = StringRef();
1050 // Pull off the last component and make Foo point to it
1051 a = Name.rfind('/');
1052 if (a == Name.npos || a == 0)
1054 Foo = Name.slice(a+1, Name.npos);
1056 // Look for a suffix starting with a '_'
1057 Idx = Foo.rfind('_');
1058 if (Idx != Foo.npos && Foo.size() >= 2) {
1059 Suffix = Foo.slice(Idx, Foo.npos);
1060 Foo = Foo.slice(0, Idx);
1063 // First look for the form Foo.framework/Foo
1064 b = Name.rfind('/', a);
1069 F = Name.slice(Idx, Idx + Foo.size());
1070 DotFramework = Name.slice(Idx + Foo.size(),
1071 Idx + Foo.size() + sizeof(".framework/")-1);
1072 if (F == Foo && DotFramework == ".framework/") {
1077 // Next look for the form Foo.framework/Versions/A/Foo
1080 c = Name.rfind('/', b);
1081 if (c == Name.npos || c == 0)
1083 V = Name.slice(c+1, Name.npos);
1084 if (!V.startswith("Versions/"))
1086 d = Name.rfind('/', c);
1091 F = Name.slice(Idx, Idx + Foo.size());
1092 DotFramework = Name.slice(Idx + Foo.size(),
1093 Idx + Foo.size() + sizeof(".framework/")-1);
1094 if (F == Foo && DotFramework == ".framework/") {
1100 // pull off the suffix after the "." and make a point to it
1101 a = Name.rfind('.');
1102 if (a == Name.npos || a == 0)
1104 Dylib = Name.slice(a, Name.npos);
1105 if (Dylib != ".dylib")
1108 // First pull off the version letter for the form Foo.A.dylib if any.
1110 Dot = Name.slice(a-2, a-1);
1115 b = Name.rfind('/', a);
1120 // ignore any suffix after an underbar like Foo_profile.A.dylib
1121 Idx = Name.find('_', b);
1122 if (Idx != Name.npos && Idx != b) {
1123 Lib = Name.slice(b, Idx);
1124 Suffix = Name.slice(Idx, a);
1127 Lib = Name.slice(b, a);
1128 // There are incorrect library names of the form:
1129 // libATS.A_profile.dylib so check for these.
1130 if (Lib.size() >= 3) {
1131 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1133 Lib = Lib.slice(0, Lib.size()-2);
1138 Qtx = Name.slice(a, Name.npos);
1141 b = Name.rfind('/', a);
1143 Lib = Name.slice(0, a);
1145 Lib = Name.slice(b+1, a);
1146 // There are library names of the form: QT.A.qtx so check for these.
1147 if (Lib.size() >= 3) {
1148 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1150 Lib = Lib.slice(0, Lib.size()-2);
1155 // getLibraryShortNameByIndex() is used to get the short name of the library
1156 // for an undefined symbol in a linked Mach-O binary that was linked with the
1157 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1158 // It is passed the index (0 - based) of the library as translated from
1159 // GET_LIBRARY_ORDINAL (1 - based).
1160 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1161 StringRef &Res) const {
1162 if (Index >= Libraries.size())
1163 return object_error::parse_failed;
1165 // If the cache of LibrariesShortNames is not built up do that first for
1166 // all the Libraries.
1167 if (LibrariesShortNames.size() == 0) {
1168 for (unsigned i = 0; i < Libraries.size(); i++) {
1169 MachO::dylib_command D =
1170 getStruct<MachO::dylib_command>(this, Libraries[i]);
1171 if (D.dylib.name >= D.cmdsize)
1172 return object_error::parse_failed;
1173 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1174 StringRef Name = StringRef(P);
1175 if (D.dylib.name+Name.size() >= D.cmdsize)
1176 return object_error::parse_failed;
1179 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1180 if (shortName.empty())
1181 LibrariesShortNames.push_back(Name);
1183 LibrariesShortNames.push_back(shortName);
1187 Res = LibrariesShortNames[Index];
1188 return object_error::success;
1191 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1192 return getSymbolByIndex(0);
1195 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1198 return basic_symbol_iterator(SymbolRef(DRI, this));
1200 MachO::symtab_command Symtab = getSymtabLoadCommand();
1201 unsigned SymbolTableEntrySize = is64Bit() ?
1202 sizeof(MachO::nlist_64) :
1203 sizeof(MachO::nlist);
1204 unsigned Offset = Symtab.symoff +
1205 Symtab.nsyms * SymbolTableEntrySize;
1206 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1207 return basic_symbol_iterator(SymbolRef(DRI, this));
1210 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1213 return basic_symbol_iterator(SymbolRef(DRI, this));
1215 MachO::symtab_command Symtab = getSymtabLoadCommand();
1216 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1217 unsigned SymbolTableEntrySize =
1218 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1219 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1220 DRI.p += Index * SymbolTableEntrySize;
1221 return basic_symbol_iterator(SymbolRef(DRI, this));
1224 section_iterator MachOObjectFile::section_begin() const {
1226 return section_iterator(SectionRef(DRI, this));
1229 section_iterator MachOObjectFile::section_end() const {
1231 DRI.d.a = Sections.size();
1232 return section_iterator(SectionRef(DRI, this));
1235 uint8_t MachOObjectFile::getBytesInAddress() const {
1236 return is64Bit() ? 8 : 4;
1239 StringRef MachOObjectFile::getFileFormatName() const {
1240 unsigned CPUType = getCPUType(this);
1243 case llvm::MachO::CPU_TYPE_I386:
1244 return "Mach-O 32-bit i386";
1245 case llvm::MachO::CPU_TYPE_ARM:
1246 return "Mach-O arm";
1247 case llvm::MachO::CPU_TYPE_POWERPC:
1248 return "Mach-O 32-bit ppc";
1250 return "Mach-O 32-bit unknown";
1255 case llvm::MachO::CPU_TYPE_X86_64:
1256 return "Mach-O 64-bit x86-64";
1257 case llvm::MachO::CPU_TYPE_ARM64:
1258 return "Mach-O arm64";
1259 case llvm::MachO::CPU_TYPE_POWERPC64:
1260 return "Mach-O 64-bit ppc64";
1262 return "Mach-O 64-bit unknown";
1266 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1268 case llvm::MachO::CPU_TYPE_I386:
1270 case llvm::MachO::CPU_TYPE_X86_64:
1271 return Triple::x86_64;
1272 case llvm::MachO::CPU_TYPE_ARM:
1274 case llvm::MachO::CPU_TYPE_ARM64:
1275 return Triple::aarch64;
1276 case llvm::MachO::CPU_TYPE_POWERPC:
1278 case llvm::MachO::CPU_TYPE_POWERPC64:
1279 return Triple::ppc64;
1281 return Triple::UnknownArch;
1285 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1286 const char **McpuDefault) {
1288 *McpuDefault = nullptr;
1291 case MachO::CPU_TYPE_I386:
1292 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1293 case MachO::CPU_SUBTYPE_I386_ALL:
1294 return Triple("i386-apple-darwin");
1298 case MachO::CPU_TYPE_X86_64:
1299 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1300 case MachO::CPU_SUBTYPE_X86_64_ALL:
1301 return Triple("x86_64-apple-darwin");
1302 case MachO::CPU_SUBTYPE_X86_64_H:
1303 return Triple("x86_64h-apple-darwin");
1307 case MachO::CPU_TYPE_ARM:
1308 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1309 case MachO::CPU_SUBTYPE_ARM_V4T:
1310 return Triple("armv4t-apple-darwin");
1311 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1312 return Triple("armv5e-apple-darwin");
1313 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1314 return Triple("xscale-apple-darwin");
1315 case MachO::CPU_SUBTYPE_ARM_V6:
1316 return Triple("armv6-apple-darwin");
1317 case MachO::CPU_SUBTYPE_ARM_V6M:
1319 *McpuDefault = "cortex-m0";
1320 return Triple("armv6m-apple-darwin");
1321 case MachO::CPU_SUBTYPE_ARM_V7:
1322 return Triple("armv7-apple-darwin");
1323 case MachO::CPU_SUBTYPE_ARM_V7EM:
1325 *McpuDefault = "cortex-m4";
1326 return Triple("armv7em-apple-darwin");
1327 case MachO::CPU_SUBTYPE_ARM_V7K:
1328 return Triple("armv7k-apple-darwin");
1329 case MachO::CPU_SUBTYPE_ARM_V7M:
1331 *McpuDefault = "cortex-m3";
1332 return Triple("armv7m-apple-darwin");
1333 case MachO::CPU_SUBTYPE_ARM_V7S:
1334 return Triple("armv7s-apple-darwin");
1338 case MachO::CPU_TYPE_ARM64:
1339 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1340 case MachO::CPU_SUBTYPE_ARM64_ALL:
1341 return Triple("arm64-apple-darwin");
1345 case MachO::CPU_TYPE_POWERPC:
1346 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1347 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1348 return Triple("ppc-apple-darwin");
1352 case MachO::CPU_TYPE_POWERPC64:
1353 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1354 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1355 return Triple("ppc64-apple-darwin");
1364 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1365 const char **McpuDefault) {
1367 *McpuDefault = nullptr;
1370 case MachO::CPU_TYPE_ARM:
1371 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1372 case MachO::CPU_SUBTYPE_ARM_V4T:
1373 return Triple("thumbv4t-apple-darwin");
1374 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1375 return Triple("thumbv5e-apple-darwin");
1376 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1377 return Triple("xscale-apple-darwin");
1378 case MachO::CPU_SUBTYPE_ARM_V6:
1379 return Triple("thumbv6-apple-darwin");
1380 case MachO::CPU_SUBTYPE_ARM_V6M:
1382 *McpuDefault = "cortex-m0";
1383 return Triple("thumbv6m-apple-darwin");
1384 case MachO::CPU_SUBTYPE_ARM_V7:
1385 return Triple("thumbv7-apple-darwin");
1386 case MachO::CPU_SUBTYPE_ARM_V7EM:
1388 *McpuDefault = "cortex-m4";
1389 return Triple("thumbv7em-apple-darwin");
1390 case MachO::CPU_SUBTYPE_ARM_V7K:
1391 return Triple("thumbv7k-apple-darwin");
1392 case MachO::CPU_SUBTYPE_ARM_V7M:
1394 *McpuDefault = "cortex-m3";
1395 return Triple("thumbv7m-apple-darwin");
1396 case MachO::CPU_SUBTYPE_ARM_V7S:
1397 return Triple("thumbv7s-apple-darwin");
1406 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1407 const char **McpuDefault,
1408 Triple *ThumbTriple) {
1409 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1410 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1415 Triple MachOObjectFile::getHostArch() {
1416 return Triple(sys::getDefaultTargetTriple());
1419 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1420 return StringSwitch<bool>(ArchFlag)
1422 .Case("x86_64", true)
1423 .Case("x86_64h", true)
1424 .Case("armv4t", true)
1426 .Case("armv5e", true)
1427 .Case("armv6", true)
1428 .Case("armv6m", true)
1429 .Case("armv7em", true)
1430 .Case("armv7k", true)
1431 .Case("armv7m", true)
1432 .Case("armv7s", true)
1433 .Case("arm64", true)
1435 .Case("ppc64", true)
1439 unsigned MachOObjectFile::getArch() const {
1440 return getArch(getCPUType(this));
1443 Triple MachOObjectFile::getArch(const char **McpuDefault,
1444 Triple *ThumbTriple) const {
1447 MachO::mach_header_64 H_64;
1448 H_64 = getHeader64();
1449 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
1450 *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
1453 MachO::mach_header H;
1455 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
1456 *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
1462 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1465 return section_rel_begin(DRI);
1468 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1471 return section_rel_end(DRI);
1474 dice_iterator MachOObjectFile::begin_dices() const {
1476 if (!DataInCodeLoadCmd)
1477 return dice_iterator(DiceRef(DRI, this));
1479 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1480 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1481 return dice_iterator(DiceRef(DRI, this));
1484 dice_iterator MachOObjectFile::end_dices() const {
1486 if (!DataInCodeLoadCmd)
1487 return dice_iterator(DiceRef(DRI, this));
1489 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1490 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1491 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1492 return dice_iterator(DiceRef(DRI, this));
1495 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1496 : Trie(T), Malformed(false), Done(false) { }
1498 void ExportEntry::moveToFirst() {
1500 pushDownUntilBottom();
1503 void ExportEntry::moveToEnd() {
1508 bool ExportEntry::operator==(const ExportEntry &Other) const {
1509 // Common case, one at end, other iterating from begin.
1510 if (Done || Other.Done)
1511 return (Done == Other.Done);
1512 // Not equal if different stack sizes.
1513 if (Stack.size() != Other.Stack.size())
1515 // Not equal if different cumulative strings.
1516 if (!CumulativeString.str().equals(Other.CumulativeString.str()))
1518 // Equal if all nodes in both stacks match.
1519 for (unsigned i=0; i < Stack.size(); ++i) {
1520 if (Stack[i].Start != Other.Stack[i].Start)
1526 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1528 uint64_t Result = decodeULEB128(Ptr, &Count);
1530 if (Ptr > Trie.end()) {
1537 StringRef ExportEntry::name() const {
1538 return CumulativeString.str();
1541 uint64_t ExportEntry::flags() const {
1542 return Stack.back().Flags;
1545 uint64_t ExportEntry::address() const {
1546 return Stack.back().Address;
1549 uint64_t ExportEntry::other() const {
1550 return Stack.back().Other;
1553 StringRef ExportEntry::otherName() const {
1554 const char* ImportName = Stack.back().ImportName;
1556 return StringRef(ImportName);
1560 uint32_t ExportEntry::nodeOffset() const {
1561 return Stack.back().Start - Trie.begin();
1564 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1565 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1566 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1567 ParentStringLength(0), IsExportNode(false) {
1570 void ExportEntry::pushNode(uint64_t offset) {
1571 const uint8_t *Ptr = Trie.begin() + offset;
1572 NodeState State(Ptr);
1573 uint64_t ExportInfoSize = readULEB128(State.Current);
1574 State.IsExportNode = (ExportInfoSize != 0);
1575 const uint8_t* Children = State.Current + ExportInfoSize;
1576 if (State.IsExportNode) {
1577 State.Flags = readULEB128(State.Current);
1578 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1580 State.Other = readULEB128(State.Current); // dylib ordinal
1581 State.ImportName = reinterpret_cast<const char*>(State.Current);
1583 State.Address = readULEB128(State.Current);
1584 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1585 State.Other = readULEB128(State.Current);
1588 State.ChildCount = *Children;
1589 State.Current = Children + 1;
1590 State.NextChildIndex = 0;
1591 State.ParentStringLength = CumulativeString.size();
1592 Stack.push_back(State);
1595 void ExportEntry::pushDownUntilBottom() {
1596 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1597 NodeState &Top = Stack.back();
1598 CumulativeString.resize(Top.ParentStringLength);
1599 for (;*Top.Current != 0; Top.Current++) {
1600 char C = *Top.Current;
1601 CumulativeString.push_back(C);
1604 uint64_t childNodeIndex = readULEB128(Top.Current);
1605 Top.NextChildIndex += 1;
1606 pushNode(childNodeIndex);
1608 if (!Stack.back().IsExportNode) {
1614 // We have a trie data structure and need a way to walk it that is compatible
1615 // with the C++ iterator model. The solution is a non-recursive depth first
1616 // traversal where the iterator contains a stack of parent nodes along with a
1617 // string that is the accumulation of all edge strings along the parent chain
1620 // There is one "export" node for each exported symbol. But because some
1621 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1622 // node may have child nodes too.
1624 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1625 // child until hitting a node with no children (which is an export node or
1626 // else the trie is malformed). On the way down, each node is pushed on the
1627 // stack ivar. If there is no more ways down, it pops up one and tries to go
1628 // down a sibling path until a childless node is reached.
1629 void ExportEntry::moveNext() {
1630 if (Stack.empty() || !Stack.back().IsExportNode) {
1637 while (!Stack.empty()) {
1638 NodeState &Top = Stack.back();
1639 if (Top.NextChildIndex < Top.ChildCount) {
1640 pushDownUntilBottom();
1641 // Now at the next export node.
1644 if (Top.IsExportNode) {
1645 // This node has no children but is itself an export node.
1646 CumulativeString.resize(Top.ParentStringLength);
1655 iterator_range<export_iterator>
1656 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1657 ExportEntry Start(Trie);
1658 Start.moveToFirst();
1660 ExportEntry Finish(Trie);
1663 return iterator_range<export_iterator>(export_iterator(Start),
1664 export_iterator(Finish));
1667 iterator_range<export_iterator> MachOObjectFile::exports() const {
1668 return exports(getDyldInfoExportsTrie());
1672 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1673 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1674 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1675 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1677 void MachORebaseEntry::moveToFirst() {
1678 Ptr = Opcodes.begin();
1682 void MachORebaseEntry::moveToEnd() {
1683 Ptr = Opcodes.end();
1684 RemainingLoopCount = 0;
1688 void MachORebaseEntry::moveNext() {
1689 // If in the middle of some loop, move to next rebasing in loop.
1690 SegmentOffset += AdvanceAmount;
1691 if (RemainingLoopCount) {
1692 --RemainingLoopCount;
1695 if (Ptr == Opcodes.end()) {
1700 while (More && !Malformed) {
1701 // Parse next opcode and set up next loop.
1702 uint8_t Byte = *Ptr++;
1703 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1704 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1706 case MachO::REBASE_OPCODE_DONE:
1710 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1712 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1713 RebaseType = ImmValue;
1716 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1717 << "RebaseType=" << (int) RebaseType << "\n");
1719 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1720 SegmentIndex = ImmValue;
1721 SegmentOffset = readULEB128();
1724 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1725 << "SegmentIndex=" << SegmentIndex << ", "
1726 << format("SegmentOffset=0x%06X", SegmentOffset)
1729 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1730 SegmentOffset += readULEB128();
1731 DEBUG_WITH_TYPE("mach-o-rebase",
1732 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1733 << format("SegmentOffset=0x%06X",
1734 SegmentOffset) << "\n");
1736 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1737 SegmentOffset += ImmValue * PointerSize;
1738 DEBUG_WITH_TYPE("mach-o-rebase",
1739 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1740 << format("SegmentOffset=0x%06X",
1741 SegmentOffset) << "\n");
1743 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1744 AdvanceAmount = PointerSize;
1745 RemainingLoopCount = ImmValue - 1;
1748 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1749 << format("SegmentOffset=0x%06X", SegmentOffset)
1750 << ", AdvanceAmount=" << AdvanceAmount
1751 << ", RemainingLoopCount=" << RemainingLoopCount
1754 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1755 AdvanceAmount = PointerSize;
1756 RemainingLoopCount = readULEB128() - 1;
1759 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1760 << format("SegmentOffset=0x%06X", SegmentOffset)
1761 << ", AdvanceAmount=" << AdvanceAmount
1762 << ", RemainingLoopCount=" << RemainingLoopCount
1765 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1766 AdvanceAmount = readULEB128() + PointerSize;
1767 RemainingLoopCount = 0;
1770 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1771 << format("SegmentOffset=0x%06X", SegmentOffset)
1772 << ", AdvanceAmount=" << AdvanceAmount
1773 << ", RemainingLoopCount=" << RemainingLoopCount
1776 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1777 RemainingLoopCount = readULEB128() - 1;
1778 AdvanceAmount = readULEB128() + PointerSize;
1781 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1782 << format("SegmentOffset=0x%06X", SegmentOffset)
1783 << ", AdvanceAmount=" << AdvanceAmount
1784 << ", RemainingLoopCount=" << RemainingLoopCount
1793 uint64_t MachORebaseEntry::readULEB128() {
1795 uint64_t Result = decodeULEB128(Ptr, &Count);
1797 if (Ptr > Opcodes.end()) {
1798 Ptr = Opcodes.end();
1804 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1806 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1808 StringRef MachORebaseEntry::typeName() const {
1809 switch (RebaseType) {
1810 case MachO::REBASE_TYPE_POINTER:
1812 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1813 return "text abs32";
1814 case MachO::REBASE_TYPE_TEXT_PCREL32:
1815 return "text rel32";
1820 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1821 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1822 return (Ptr == Other.Ptr) &&
1823 (RemainingLoopCount == Other.RemainingLoopCount) &&
1824 (Done == Other.Done);
1827 iterator_range<rebase_iterator>
1828 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1829 MachORebaseEntry Start(Opcodes, is64);
1830 Start.moveToFirst();
1832 MachORebaseEntry Finish(Opcodes, is64);
1835 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1836 rebase_iterator(Finish));
1839 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1840 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1844 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1846 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1847 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1848 BindType(0), PointerSize(is64Bit ? 8 : 4),
1849 TableKind(BK), Malformed(false), Done(false) {}
1851 void MachOBindEntry::moveToFirst() {
1852 Ptr = Opcodes.begin();
1856 void MachOBindEntry::moveToEnd() {
1857 Ptr = Opcodes.end();
1858 RemainingLoopCount = 0;
1862 void MachOBindEntry::moveNext() {
1863 // If in the middle of some loop, move to next binding in loop.
1864 SegmentOffset += AdvanceAmount;
1865 if (RemainingLoopCount) {
1866 --RemainingLoopCount;
1869 if (Ptr == Opcodes.end()) {
1874 while (More && !Malformed) {
1875 // Parse next opcode and set up next loop.
1876 uint8_t Byte = *Ptr++;
1877 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1878 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1879 int8_t SignExtended;
1880 const uint8_t *SymStart;
1882 case MachO::BIND_OPCODE_DONE:
1883 if (TableKind == Kind::Lazy) {
1884 // Lazying bindings have a DONE opcode between entries. Need to ignore
1885 // it to advance to next entry. But need not if this is last entry.
1886 bool NotLastEntry = false;
1887 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1889 NotLastEntry = true;
1898 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1900 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1904 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1905 << "Ordinal=" << Ordinal << "\n");
1907 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1908 Ordinal = readULEB128();
1911 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1912 << "Ordinal=" << Ordinal << "\n");
1914 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1916 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1917 Ordinal = SignExtended;
1922 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1923 << "Ordinal=" << Ordinal << "\n");
1925 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1931 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1936 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1937 << "SymbolName=" << SymbolName << "\n");
1938 if (TableKind == Kind::Weak) {
1939 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1943 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1944 BindType = ImmValue;
1947 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1948 << "BindType=" << (int)BindType << "\n");
1950 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1951 Addend = readSLEB128();
1952 if (TableKind == Kind::Lazy)
1956 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1957 << "Addend=" << Addend << "\n");
1959 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1960 SegmentIndex = ImmValue;
1961 SegmentOffset = readULEB128();
1964 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1965 << "SegmentIndex=" << SegmentIndex << ", "
1966 << format("SegmentOffset=0x%06X", SegmentOffset)
1969 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1970 SegmentOffset += readULEB128();
1971 DEBUG_WITH_TYPE("mach-o-bind",
1972 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1973 << format("SegmentOffset=0x%06X",
1974 SegmentOffset) << "\n");
1976 case MachO::BIND_OPCODE_DO_BIND:
1977 AdvanceAmount = PointerSize;
1978 RemainingLoopCount = 0;
1979 DEBUG_WITH_TYPE("mach-o-bind",
1980 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1981 << format("SegmentOffset=0x%06X",
1982 SegmentOffset) << "\n");
1984 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1985 AdvanceAmount = readULEB128() + PointerSize;
1986 RemainingLoopCount = 0;
1987 if (TableKind == Kind::Lazy)
1991 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1992 << format("SegmentOffset=0x%06X", SegmentOffset)
1993 << ", AdvanceAmount=" << AdvanceAmount
1994 << ", RemainingLoopCount=" << RemainingLoopCount
1997 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1998 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1999 RemainingLoopCount = 0;
2000 if (TableKind == Kind::Lazy)
2002 DEBUG_WITH_TYPE("mach-o-bind",
2004 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
2005 << format("SegmentOffset=0x%06X",
2006 SegmentOffset) << "\n");
2008 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
2009 RemainingLoopCount = readULEB128() - 1;
2010 AdvanceAmount = readULEB128() + PointerSize;
2011 if (TableKind == Kind::Lazy)
2015 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
2016 << format("SegmentOffset=0x%06X", SegmentOffset)
2017 << ", AdvanceAmount=" << AdvanceAmount
2018 << ", RemainingLoopCount=" << RemainingLoopCount
2027 uint64_t MachOBindEntry::readULEB128() {
2029 uint64_t Result = decodeULEB128(Ptr, &Count);
2031 if (Ptr > Opcodes.end()) {
2032 Ptr = Opcodes.end();
2038 int64_t MachOBindEntry::readSLEB128() {
2040 int64_t Result = decodeSLEB128(Ptr, &Count);
2042 if (Ptr > Opcodes.end()) {
2043 Ptr = Opcodes.end();
2050 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
2052 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
2054 StringRef MachOBindEntry::typeName() const {
2056 case MachO::BIND_TYPE_POINTER:
2058 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
2059 return "text abs32";
2060 case MachO::BIND_TYPE_TEXT_PCREL32:
2061 return "text rel32";
2066 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
2068 int64_t MachOBindEntry::addend() const { return Addend; }
2070 uint32_t MachOBindEntry::flags() const { return Flags; }
2072 int MachOBindEntry::ordinal() const { return Ordinal; }
2074 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
2075 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2076 return (Ptr == Other.Ptr) &&
2077 (RemainingLoopCount == Other.RemainingLoopCount) &&
2078 (Done == Other.Done);
2081 iterator_range<bind_iterator>
2082 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
2083 MachOBindEntry::Kind BKind) {
2084 MachOBindEntry Start(Opcodes, is64, BKind);
2085 Start.moveToFirst();
2087 MachOBindEntry Finish(Opcodes, is64, BKind);
2090 return iterator_range<bind_iterator>(bind_iterator(Start),
2091 bind_iterator(Finish));
2094 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
2095 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
2096 MachOBindEntry::Kind::Regular);
2099 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
2100 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
2101 MachOBindEntry::Kind::Lazy);
2104 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
2105 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
2106 MachOBindEntry::Kind::Weak);
2110 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
2111 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
2112 return parseSegmentOrSectionName(Raw.data());
2116 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
2117 const section_base *Base =
2118 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2119 return makeArrayRef(Base->sectname);
2123 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
2124 const section_base *Base =
2125 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2126 return makeArrayRef(Base->segname);
2130 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
2132 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
2134 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
2137 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
2138 const MachO::any_relocation_info &RE) const {
2139 if (isLittleEndian())
2140 return RE.r_word1 & 0xffffff;
2141 return RE.r_word1 >> 8;
2144 bool MachOObjectFile::getPlainRelocationExternal(
2145 const MachO::any_relocation_info &RE) const {
2146 if (isLittleEndian())
2147 return (RE.r_word1 >> 27) & 1;
2148 return (RE.r_word1 >> 4) & 1;
2151 bool MachOObjectFile::getScatteredRelocationScattered(
2152 const MachO::any_relocation_info &RE) const {
2153 return RE.r_word0 >> 31;
2156 uint32_t MachOObjectFile::getScatteredRelocationValue(
2157 const MachO::any_relocation_info &RE) const {
2161 uint32_t MachOObjectFile::getScatteredRelocationType(
2162 const MachO::any_relocation_info &RE) const {
2163 return (RE.r_word0 >> 24) & 0xf;
2166 unsigned MachOObjectFile::getAnyRelocationAddress(
2167 const MachO::any_relocation_info &RE) const {
2168 if (isRelocationScattered(RE))
2169 return getScatteredRelocationAddress(RE);
2170 return getPlainRelocationAddress(RE);
2173 unsigned MachOObjectFile::getAnyRelocationPCRel(
2174 const MachO::any_relocation_info &RE) const {
2175 if (isRelocationScattered(RE))
2176 return getScatteredRelocationPCRel(this, RE);
2177 return getPlainRelocationPCRel(this, RE);
2180 unsigned MachOObjectFile::getAnyRelocationLength(
2181 const MachO::any_relocation_info &RE) const {
2182 if (isRelocationScattered(RE))
2183 return getScatteredRelocationLength(RE);
2184 return getPlainRelocationLength(this, RE);
2188 MachOObjectFile::getAnyRelocationType(
2189 const MachO::any_relocation_info &RE) const {
2190 if (isRelocationScattered(RE))
2191 return getScatteredRelocationType(RE);
2192 return getPlainRelocationType(this, RE);
2196 MachOObjectFile::getRelocationSection(
2197 const MachO::any_relocation_info &RE) const {
2198 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2199 return *section_end();
2200 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
2203 return SectionRef(DRI, this);
2206 MachOObjectFile::LoadCommandInfo
2207 MachOObjectFile::getFirstLoadCommandInfo() const {
2208 MachOObjectFile::LoadCommandInfo Load;
2210 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
2211 sizeof(MachO::mach_header);
2212 Load.Ptr = getPtr(this, HeaderSize);
2213 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
2217 MachOObjectFile::LoadCommandInfo
2218 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
2219 MachOObjectFile::LoadCommandInfo Next;
2220 Next.Ptr = L.Ptr + L.C.cmdsize;
2221 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
2225 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2226 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2229 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2230 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2233 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2234 unsigned Index) const {
2235 const char *Sec = getSectionPtr(this, L, Index);
2236 return getStruct<MachO::section>(this, Sec);
2239 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2240 unsigned Index) const {
2241 const char *Sec = getSectionPtr(this, L, Index);
2242 return getStruct<MachO::section_64>(this, Sec);
2246 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2247 const char *P = reinterpret_cast<const char *>(DRI.p);
2248 return getStruct<MachO::nlist>(this, P);
2252 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2253 const char *P = reinterpret_cast<const char *>(DRI.p);
2254 return getStruct<MachO::nlist_64>(this, P);
2257 MachO::linkedit_data_command
2258 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2259 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2262 MachO::segment_command
2263 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2264 return getStruct<MachO::segment_command>(this, L.Ptr);
2267 MachO::segment_command_64
2268 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2269 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2272 MachO::linker_options_command
2273 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
2274 return getStruct<MachO::linker_options_command>(this, L.Ptr);
2277 MachO::version_min_command
2278 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2279 return getStruct<MachO::version_min_command>(this, L.Ptr);
2282 MachO::dylib_command
2283 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2284 return getStruct<MachO::dylib_command>(this, L.Ptr);
2287 MachO::dyld_info_command
2288 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2289 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2292 MachO::dylinker_command
2293 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2294 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2298 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2299 return getStruct<MachO::uuid_command>(this, L.Ptr);
2302 MachO::source_version_command
2303 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2304 return getStruct<MachO::source_version_command>(this, L.Ptr);
2307 MachO::entry_point_command
2308 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2309 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2313 MachO::any_relocation_info
2314 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2319 MachO::section_64 Sect = getSection64(Sec);
2320 Offset = Sect.reloff;
2322 MachO::section Sect = getSection(Sec);
2323 Offset = Sect.reloff;
2326 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2327 getPtr(this, Offset)) + Rel.d.b;
2328 return getStruct<MachO::any_relocation_info>(
2329 this, reinterpret_cast<const char *>(P));
2332 MachO::data_in_code_entry
2333 MachOObjectFile::getDice(DataRefImpl Rel) const {
2334 const char *P = reinterpret_cast<const char *>(Rel.p);
2335 return getStruct<MachO::data_in_code_entry>(this, P);
2338 MachO::mach_header MachOObjectFile::getHeader() const {
2339 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
2342 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
2343 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
2346 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2347 const MachO::dysymtab_command &DLC,
2348 unsigned Index) const {
2349 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2350 return getStruct<uint32_t>(this, getPtr(this, Offset));
2353 MachO::data_in_code_entry
2354 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2355 unsigned Index) const {
2356 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2357 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2360 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2362 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2364 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2365 MachO::symtab_command Cmd;
2366 Cmd.cmd = MachO::LC_SYMTAB;
2367 Cmd.cmdsize = sizeof(MachO::symtab_command);
2375 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2376 if (DysymtabLoadCmd)
2377 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2379 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2380 MachO::dysymtab_command Cmd;
2381 Cmd.cmd = MachO::LC_DYSYMTAB;
2382 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2393 Cmd.extrefsymoff = 0;
2394 Cmd.nextrefsyms = 0;
2395 Cmd.indirectsymoff = 0;
2396 Cmd.nindirectsyms = 0;
2404 MachO::linkedit_data_command
2405 MachOObjectFile::getDataInCodeLoadCommand() const {
2406 if (DataInCodeLoadCmd)
2407 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2409 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2410 MachO::linkedit_data_command Cmd;
2411 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2412 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2418 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2419 if (!DyldInfoLoadCmd)
2420 return ArrayRef<uint8_t>();
2422 MachO::dyld_info_command DyldInfo
2423 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2424 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2425 getPtr(this, DyldInfo.rebase_off));
2426 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2429 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2430 if (!DyldInfoLoadCmd)
2431 return ArrayRef<uint8_t>();
2433 MachO::dyld_info_command DyldInfo
2434 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2435 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2436 getPtr(this, DyldInfo.bind_off));
2437 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2440 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2441 if (!DyldInfoLoadCmd)
2442 return ArrayRef<uint8_t>();
2444 MachO::dyld_info_command DyldInfo
2445 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2446 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2447 getPtr(this, DyldInfo.weak_bind_off));
2448 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2451 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2452 if (!DyldInfoLoadCmd)
2453 return ArrayRef<uint8_t>();
2455 MachO::dyld_info_command DyldInfo
2456 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2457 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2458 getPtr(this, DyldInfo.lazy_bind_off));
2459 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2462 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2463 if (!DyldInfoLoadCmd)
2464 return ArrayRef<uint8_t>();
2466 MachO::dyld_info_command DyldInfo
2467 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2468 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2469 getPtr(this, DyldInfo.export_off));
2470 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2473 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2475 return ArrayRef<uint8_t>();
2476 // Returning a pointer is fine as uuid doesn't need endian swapping.
2477 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2478 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2481 StringRef MachOObjectFile::getStringTableData() const {
2482 MachO::symtab_command S = getSymtabLoadCommand();
2483 return getData().substr(S.stroff, S.strsize);
2486 bool MachOObjectFile::is64Bit() const {
2487 return getType() == getMachOType(false, true) ||
2488 getType() == getMachOType(true, true);
2491 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2492 SmallVectorImpl<uint64_t> &Out) const {
2493 DataExtractor extractor(ObjectFile::getData(), true, 0);
2495 uint32_t offset = Index;
2497 while (uint64_t delta = extractor.getULEB128(&offset)) {
2499 Out.push_back(data);
2503 bool MachOObjectFile::isRelocatableObject() const {
2504 return getHeader().filetype == MachO::MH_OBJECT;
2507 ErrorOr<std::unique_ptr<MachOObjectFile>>
2508 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2509 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2511 std::unique_ptr<MachOObjectFile> Ret;
2512 if (Magic == "\xFE\xED\xFA\xCE")
2513 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2514 else if (Magic == "\xCE\xFA\xED\xFE")
2515 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2516 else if (Magic == "\xFE\xED\xFA\xCF")
2517 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2518 else if (Magic == "\xCF\xFA\xED\xFE")
2519 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2521 return object_error::parse_failed;
2525 return std::move(Ret);