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;
223 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
224 return (RE.r_word0 >> 24) & 0xf;
227 static uint32_t getSectionFlags(const MachOObjectFile *O,
230 MachO::section_64 Sect = O->getSection64(Sec);
233 MachO::section Sect = O->getSection(Sec);
237 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
238 bool Is64bits, std::error_code &EC)
239 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
240 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
241 DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
242 UuidLoadCmd(nullptr), HasPageZeroSegment(false) {
243 uint32_t LoadCommandCount = this->getHeader().ncmds;
244 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
245 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
247 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
248 for (unsigned I = 0; ; ++I) {
249 if (Load.C.cmd == MachO::LC_SYMTAB) {
250 assert(!SymtabLoadCmd && "Multiple symbol tables");
251 SymtabLoadCmd = Load.Ptr;
252 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
253 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
254 DysymtabLoadCmd = Load.Ptr;
255 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
256 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
257 DataInCodeLoadCmd = Load.Ptr;
258 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
259 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
260 assert(!DyldInfoLoadCmd && "Multiple dyldinfo load commands");
261 DyldInfoLoadCmd = Load.Ptr;
262 } else if (Load.C.cmd == MachO::LC_UUID) {
263 assert(!UuidLoadCmd && "Multiple UUID load commands");
264 UuidLoadCmd = Load.Ptr;
265 } else if (Load.C.cmd == SegmentLoadType) {
266 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
267 for (unsigned J = 0; J < NumSections; ++J) {
268 const char *Sec = getSectionPtr(this, Load, J);
269 Sections.push_back(Sec);
271 if (isPageZeroSegment(this, Load))
272 HasPageZeroSegment = true;
273 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
274 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
275 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
276 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
277 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
278 Libraries.push_back(Load.Ptr);
281 if (I == LoadCommandCount - 1)
284 Load = getNextLoadCommandInfo(Load);
288 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
289 unsigned SymbolTableEntrySize = is64Bit() ?
290 sizeof(MachO::nlist_64) :
291 sizeof(MachO::nlist);
292 Symb.p += SymbolTableEntrySize;
295 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
296 StringRef &Res) const {
297 StringRef StringTable = getStringTableData();
298 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
299 const char *Start = &StringTable.data()[Entry.n_strx];
300 Res = StringRef(Start);
301 return object_error::success;
304 // getIndirectName() returns the name of the alias'ed symbol who's string table
305 // index is in the n_value field.
306 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
307 StringRef &Res) const {
308 StringRef StringTable = getStringTableData();
311 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
312 NValue = Entry.n_value;
313 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
314 return object_error::parse_failed;
316 MachO::nlist Entry = getSymbolTableEntry(Symb);
317 NValue = Entry.n_value;
318 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
319 return object_error::parse_failed;
321 if (NValue >= StringTable.size())
322 return object_error::parse_failed;
323 const char *Start = &StringTable.data()[NValue];
324 Res = StringRef(Start);
325 return object_error::success;
328 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
329 uint64_t &Res) const {
331 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
332 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
334 Res = UnknownAddressOrSize;
338 MachO::nlist Entry = getSymbolTableEntry(Symb);
339 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
341 Res = UnknownAddressOrSize;
345 return object_error::success;
348 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
349 uint32_t &Result) const {
350 uint32_t flags = getSymbolFlags(DRI);
351 if (flags & SymbolRef::SF_Common) {
352 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
353 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
357 return object_error::success;
360 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
361 uint64_t &Result) const {
362 uint64_t BeginOffset;
363 uint64_t EndOffset = 0;
364 uint8_t SectionIndex;
366 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
368 getSymbolAddress(DRI, Value);
369 if (Value == UnknownAddressOrSize) {
370 Result = UnknownAddressOrSize;
371 return object_error::success;
376 SectionIndex = Entry.n_sect;
378 uint32_t flags = getSymbolFlags(DRI);
379 if (flags & SymbolRef::SF_Common)
382 Result = UnknownAddressOrSize;
383 return object_error::success;
385 // Unfortunately symbols are unsorted so we need to touch all
386 // symbols from load command
387 for (const SymbolRef &Symbol : symbols()) {
388 DataRefImpl DRI = Symbol.getRawDataRefImpl();
389 Entry = getSymbolTableEntryBase(this, DRI);
390 getSymbolAddress(DRI, Value);
391 if (Value == UnknownAddressOrSize)
393 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
394 if (!EndOffset || Value < EndOffset)
399 Sec.d.a = SectionIndex-1;
400 uint64_t Size = getSectionSize(Sec);
401 EndOffset = getSectionAddress(Sec);
404 Result = EndOffset - BeginOffset;
405 return object_error::success;
408 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
409 SymbolRef::Type &Res) const {
410 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
411 uint8_t n_type = Entry.n_type;
413 Res = SymbolRef::ST_Other;
415 // If this is a STAB debugging symbol, we can do nothing more.
416 if (n_type & MachO::N_STAB) {
417 Res = SymbolRef::ST_Debug;
418 return object_error::success;
421 switch (n_type & MachO::N_TYPE) {
423 Res = SymbolRef::ST_Unknown;
426 Res = SymbolRef::ST_Function;
429 return object_error::success;
432 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
433 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
435 uint8_t MachOType = Entry.n_type;
436 uint16_t MachOFlags = Entry.n_desc;
438 uint32_t Result = SymbolRef::SF_None;
440 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
441 Result |= SymbolRef::SF_Undefined;
443 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
444 Result |= SymbolRef::SF_Indirect;
446 if (MachOType & MachO::N_STAB)
447 Result |= SymbolRef::SF_FormatSpecific;
449 if (MachOType & MachO::N_EXT) {
450 Result |= SymbolRef::SF_Global;
451 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
453 getSymbolAddress(DRI, Value);
454 if (Value && Value != UnknownAddressOrSize)
455 Result |= SymbolRef::SF_Common;
459 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
460 Result |= SymbolRef::SF_Weak;
462 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
463 Result |= SymbolRef::SF_Thumb;
465 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
466 Result |= SymbolRef::SF_Absolute;
471 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
472 section_iterator &Res) const {
473 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
474 uint8_t index = Entry.n_sect;
481 Res = section_iterator(SectionRef(DRI, this));
484 return object_error::success;
487 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
491 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
492 StringRef &Result) const {
493 ArrayRef<char> Raw = getSectionRawName(Sec);
494 Result = parseSegmentOrSectionName(Raw.data());
495 return object_error::success;
498 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
500 return getSection64(Sec).addr;
501 return getSection(Sec).addr;
504 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
506 return getSection64(Sec).size;
507 return getSection(Sec).size;
510 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
511 StringRef &Res) const {
516 MachO::section_64 Sect = getSection64(Sec);
517 Offset = Sect.offset;
520 MachO::section Sect = getSection(Sec);
521 Offset = Sect.offset;
525 Res = this->getData().substr(Offset, Size);
526 return object_error::success;
529 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
532 MachO::section_64 Sect = getSection64(Sec);
535 MachO::section Sect = getSection(Sec);
539 return uint64_t(1) << Align;
542 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
543 uint32_t Flags = getSectionFlags(this, Sec);
544 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
547 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
548 uint32_t Flags = getSectionFlags(this, Sec);
549 unsigned SectionType = Flags & MachO::SECTION_TYPE;
550 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
551 !(SectionType == MachO::S_ZEROFILL ||
552 SectionType == MachO::S_GB_ZEROFILL);
555 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
556 uint32_t Flags = getSectionFlags(this, Sec);
557 unsigned SectionType = Flags & MachO::SECTION_TYPE;
558 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
559 (SectionType == MachO::S_ZEROFILL ||
560 SectionType == MachO::S_GB_ZEROFILL);
563 bool MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sect) const {
564 // FIXME: Unimplemented.
568 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
569 // FIXME: Unimplemented.
573 bool MachOObjectFile::isSectionZeroInit(DataRefImpl Sec) const {
574 uint32_t Flags = getSectionFlags(this, Sec);
575 unsigned SectionType = Flags & MachO::SECTION_TYPE;
576 return SectionType == MachO::S_ZEROFILL ||
577 SectionType == MachO::S_GB_ZEROFILL;
580 bool MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const {
581 // Consider using the code from isSectionText to look for __const sections.
582 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
583 // to use section attributes to distinguish code from data.
585 // FIXME: Unimplemented.
589 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
590 DataRefImpl Symb) const {
592 this->getSymbolType(Symb, ST);
593 if (ST == SymbolRef::ST_Unknown)
596 uint64_t SectBegin = getSectionAddress(Sec);
597 uint64_t SectEnd = getSectionSize(Sec);
598 SectEnd += SectBegin;
601 getSymbolAddress(Symb, SymAddr);
602 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
605 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
609 return relocation_iterator(RelocationRef(Ret, this));
613 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
616 MachO::section_64 Sect = getSection64(Sec);
619 MachO::section Sect = getSection(Sec);
626 return relocation_iterator(RelocationRef(Ret, this));
629 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
633 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
634 uint64_t &Res) const {
636 getRelocationOffset(Rel, Offset);
640 uint64_t SecAddress = getSectionAddress(Sec);
641 Res = SecAddress + Offset;
642 return object_error::success;
645 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
646 uint64_t &Res) const {
647 assert(getHeader().filetype == MachO::MH_OBJECT &&
648 "Only implemented for MH_OBJECT");
649 MachO::any_relocation_info RE = getRelocation(Rel);
650 Res = getAnyRelocationAddress(RE);
651 return object_error::success;
655 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
656 MachO::any_relocation_info RE = getRelocation(Rel);
657 if (isRelocationScattered(RE))
660 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
661 bool isExtern = getPlainRelocationExternal(RE);
665 MachO::symtab_command S = getSymtabLoadCommand();
666 unsigned SymbolTableEntrySize = is64Bit() ?
667 sizeof(MachO::nlist_64) :
668 sizeof(MachO::nlist);
669 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
671 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
672 return symbol_iterator(SymbolRef(Sym, this));
675 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
676 uint64_t &Res) const {
677 MachO::any_relocation_info RE = getRelocation(Rel);
678 Res = getAnyRelocationType(RE);
679 return object_error::success;
683 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
684 SmallVectorImpl<char> &Result) const {
687 getRelocationType(Rel, RType);
689 unsigned Arch = this->getArch();
693 static const char *const Table[] = {
694 "GENERIC_RELOC_VANILLA",
695 "GENERIC_RELOC_PAIR",
696 "GENERIC_RELOC_SECTDIFF",
697 "GENERIC_RELOC_PB_LA_PTR",
698 "GENERIC_RELOC_LOCAL_SECTDIFF",
699 "GENERIC_RELOC_TLV" };
707 case Triple::x86_64: {
708 static const char *const Table[] = {
709 "X86_64_RELOC_UNSIGNED",
710 "X86_64_RELOC_SIGNED",
711 "X86_64_RELOC_BRANCH",
712 "X86_64_RELOC_GOT_LOAD",
714 "X86_64_RELOC_SUBTRACTOR",
715 "X86_64_RELOC_SIGNED_1",
716 "X86_64_RELOC_SIGNED_2",
717 "X86_64_RELOC_SIGNED_4",
718 "X86_64_RELOC_TLV" };
727 static const char *const Table[] = {
730 "ARM_RELOC_SECTDIFF",
731 "ARM_RELOC_LOCAL_SECTDIFF",
732 "ARM_RELOC_PB_LA_PTR",
734 "ARM_THUMB_RELOC_BR22",
735 "ARM_THUMB_32BIT_BRANCH",
737 "ARM_RELOC_HALF_SECTDIFF" };
745 case Triple::aarch64: {
746 static const char *const Table[] = {
747 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
748 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
749 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
750 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
751 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
755 if (RType >= array_lengthof(Table))
762 static const char *const Table[] = {
771 "PPC_RELOC_SECTDIFF",
772 "PPC_RELOC_PB_LA_PTR",
773 "PPC_RELOC_HI16_SECTDIFF",
774 "PPC_RELOC_LO16_SECTDIFF",
775 "PPC_RELOC_HA16_SECTDIFF",
777 "PPC_RELOC_LO14_SECTDIFF",
778 "PPC_RELOC_LOCAL_SECTDIFF" };
786 case Triple::UnknownArch:
790 Result.append(res.begin(), res.end());
791 return object_error::success;
795 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
796 SmallVectorImpl<char> &Result) const {
797 MachO::any_relocation_info RE = getRelocation(Rel);
799 unsigned Arch = this->getArch();
802 raw_string_ostream fmt(fmtbuf);
803 unsigned Type = this->getAnyRelocationType(RE);
804 bool IsPCRel = this->getAnyRelocationPCRel(RE);
806 // Determine any addends that should be displayed with the relocation.
807 // These require decoding the relocation type, which is triple-specific.
809 // X86_64 has entirely custom relocation types.
810 if (Arch == Triple::x86_64) {
811 bool isPCRel = getAnyRelocationPCRel(RE);
814 case MachO::X86_64_RELOC_GOT_LOAD:
815 case MachO::X86_64_RELOC_GOT: {
816 printRelocationTargetName(this, RE, fmt);
818 if (isPCRel) fmt << "PCREL";
821 case MachO::X86_64_RELOC_SUBTRACTOR: {
822 DataRefImpl RelNext = Rel;
823 moveRelocationNext(RelNext);
824 MachO::any_relocation_info RENext = getRelocation(RelNext);
826 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
827 // X86_64_RELOC_UNSIGNED.
828 // NOTE: Scattered relocations don't exist on x86_64.
829 unsigned RType = getAnyRelocationType(RENext);
830 if (RType != MachO::X86_64_RELOC_UNSIGNED)
831 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
832 "X86_64_RELOC_SUBTRACTOR.");
834 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
835 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
836 printRelocationTargetName(this, RENext, fmt);
838 printRelocationTargetName(this, RE, fmt);
841 case MachO::X86_64_RELOC_TLV:
842 printRelocationTargetName(this, RE, fmt);
844 if (isPCRel) fmt << "P";
846 case MachO::X86_64_RELOC_SIGNED_1:
847 printRelocationTargetName(this, RE, fmt);
850 case MachO::X86_64_RELOC_SIGNED_2:
851 printRelocationTargetName(this, RE, fmt);
854 case MachO::X86_64_RELOC_SIGNED_4:
855 printRelocationTargetName(this, RE, fmt);
859 printRelocationTargetName(this, RE, fmt);
862 // X86 and ARM share some relocation types in common.
863 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
864 Arch == Triple::ppc) {
865 // Generic relocation types...
867 case MachO::GENERIC_RELOC_PAIR: // prints no info
868 return object_error::success;
869 case MachO::GENERIC_RELOC_SECTDIFF: {
870 DataRefImpl RelNext = Rel;
871 moveRelocationNext(RelNext);
872 MachO::any_relocation_info RENext = getRelocation(RelNext);
874 // X86 sect diff's must be followed by a relocation of type
875 // GENERIC_RELOC_PAIR.
876 unsigned RType = getAnyRelocationType(RENext);
878 if (RType != MachO::GENERIC_RELOC_PAIR)
879 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
880 "GENERIC_RELOC_SECTDIFF.");
882 printRelocationTargetName(this, RE, fmt);
884 printRelocationTargetName(this, RENext, fmt);
889 if (Arch == Triple::x86 || Arch == Triple::ppc) {
891 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
892 DataRefImpl RelNext = Rel;
893 moveRelocationNext(RelNext);
894 MachO::any_relocation_info RENext = getRelocation(RelNext);
896 // X86 sect diff's must be followed by a relocation of type
897 // GENERIC_RELOC_PAIR.
898 unsigned RType = getAnyRelocationType(RENext);
899 if (RType != MachO::GENERIC_RELOC_PAIR)
900 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
901 "GENERIC_RELOC_LOCAL_SECTDIFF.");
903 printRelocationTargetName(this, RE, fmt);
905 printRelocationTargetName(this, RENext, fmt);
908 case MachO::GENERIC_RELOC_TLV: {
909 printRelocationTargetName(this, RE, fmt);
911 if (IsPCRel) fmt << "P";
915 printRelocationTargetName(this, RE, fmt);
917 } else { // ARM-specific relocations
919 case MachO::ARM_RELOC_HALF:
920 case MachO::ARM_RELOC_HALF_SECTDIFF: {
921 // Half relocations steal a bit from the length field to encode
922 // whether this is an upper16 or a lower16 relocation.
923 bool isUpper = getAnyRelocationLength(RE) >> 1;
929 printRelocationTargetName(this, RE, fmt);
931 DataRefImpl RelNext = Rel;
932 moveRelocationNext(RelNext);
933 MachO::any_relocation_info RENext = getRelocation(RelNext);
935 // ARM half relocs must be followed by a relocation of type
937 unsigned RType = getAnyRelocationType(RENext);
938 if (RType != MachO::ARM_RELOC_PAIR)
939 report_fatal_error("Expected ARM_RELOC_PAIR after "
942 // NOTE: The half of the target virtual address is stashed in the
943 // address field of the secondary relocation, but we can't reverse
944 // engineer the constant offset from it without decoding the movw/movt
945 // instruction to find the other half in its immediate field.
947 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
948 // symbol/section pointer of the follow-on relocation.
949 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
951 printRelocationTargetName(this, RENext, fmt);
958 printRelocationTargetName(this, RE, fmt);
963 printRelocationTargetName(this, RE, fmt);
966 Result.append(fmtbuf.begin(), fmtbuf.end());
967 return object_error::success;
970 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
971 bool &Result) const {
972 unsigned Arch = getArch();
974 getRelocationType(Rel, Type);
978 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
980 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
981 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
982 } else if (Arch == Triple::x86_64) {
983 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
984 // an X86_64_RELOC_SUBTRACTOR.
985 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
986 DataRefImpl RelPrev = Rel;
989 getRelocationType(RelPrev, PrevType);
990 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
995 return object_error::success;
999 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1000 // guess on what the short name is. Then name is returned as a substring of the
1001 // StringRef Name passed in. The name of the dynamic library is recognized as
1002 // a framework if it has one of the two following forms:
1003 // Foo.framework/Versions/A/Foo
1004 // Foo.framework/Foo
1005 // Where A and Foo can be any string. And may contain a trailing suffix
1006 // starting with an underbar. If the Name is recognized as a framework then
1007 // isFramework is set to true else it is set to false. If the Name has a
1008 // suffix then Suffix is set to the substring in Name that contains the suffix
1009 // else it is set to a NULL StringRef.
1011 // The Name of the dynamic library is recognized as a library name if it has
1012 // one of the two following forms:
1015 // The library may have a suffix trailing the name Foo of the form:
1016 // libFoo_profile.A.dylib
1017 // libFoo_profile.dylib
1019 // The Name of the dynamic library is also recognized as a library name if it
1020 // has the following form:
1023 // If the Name of the dynamic library is none of the forms above then a NULL
1024 // StringRef is returned.
1026 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1028 StringRef &Suffix) {
1029 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1030 size_t a, b, c, d, Idx;
1032 isFramework = false;
1033 Suffix = StringRef();
1035 // Pull off the last component and make Foo point to it
1036 a = Name.rfind('/');
1037 if (a == Name.npos || a == 0)
1039 Foo = Name.slice(a+1, Name.npos);
1041 // Look for a suffix starting with a '_'
1042 Idx = Foo.rfind('_');
1043 if (Idx != Foo.npos && Foo.size() >= 2) {
1044 Suffix = Foo.slice(Idx, Foo.npos);
1045 Foo = Foo.slice(0, Idx);
1048 // First look for the form Foo.framework/Foo
1049 b = Name.rfind('/', a);
1054 F = Name.slice(Idx, Idx + Foo.size());
1055 DotFramework = Name.slice(Idx + Foo.size(),
1056 Idx + Foo.size() + sizeof(".framework/")-1);
1057 if (F == Foo && DotFramework == ".framework/") {
1062 // Next look for the form Foo.framework/Versions/A/Foo
1065 c = Name.rfind('/', b);
1066 if (c == Name.npos || c == 0)
1068 V = Name.slice(c+1, Name.npos);
1069 if (!V.startswith("Versions/"))
1071 d = Name.rfind('/', c);
1076 F = Name.slice(Idx, Idx + Foo.size());
1077 DotFramework = Name.slice(Idx + Foo.size(),
1078 Idx + Foo.size() + sizeof(".framework/")-1);
1079 if (F == Foo && DotFramework == ".framework/") {
1085 // pull off the suffix after the "." and make a point to it
1086 a = Name.rfind('.');
1087 if (a == Name.npos || a == 0)
1089 Dylib = Name.slice(a, Name.npos);
1090 if (Dylib != ".dylib")
1093 // First pull off the version letter for the form Foo.A.dylib if any.
1095 Dot = Name.slice(a-2, a-1);
1100 b = Name.rfind('/', a);
1105 // ignore any suffix after an underbar like Foo_profile.A.dylib
1106 Idx = Name.find('_', b);
1107 if (Idx != Name.npos && Idx != b) {
1108 Lib = Name.slice(b, Idx);
1109 Suffix = Name.slice(Idx, a);
1112 Lib = Name.slice(b, a);
1113 // There are incorrect library names of the form:
1114 // libATS.A_profile.dylib so check for these.
1115 if (Lib.size() >= 3) {
1116 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1118 Lib = Lib.slice(0, Lib.size()-2);
1123 Qtx = Name.slice(a, Name.npos);
1126 b = Name.rfind('/', a);
1128 Lib = Name.slice(0, a);
1130 Lib = Name.slice(b+1, a);
1131 // There are library names of the form: QT.A.qtx so check for these.
1132 if (Lib.size() >= 3) {
1133 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1135 Lib = Lib.slice(0, Lib.size()-2);
1140 // getLibraryShortNameByIndex() is used to get the short name of the library
1141 // for an undefined symbol in a linked Mach-O binary that was linked with the
1142 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1143 // It is passed the index (0 - based) of the library as translated from
1144 // GET_LIBRARY_ORDINAL (1 - based).
1145 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1146 StringRef &Res) const {
1147 if (Index >= Libraries.size())
1148 return object_error::parse_failed;
1150 // If the cache of LibrariesShortNames is not built up do that first for
1151 // all the Libraries.
1152 if (LibrariesShortNames.size() == 0) {
1153 for (unsigned i = 0; i < Libraries.size(); i++) {
1154 MachO::dylib_command D =
1155 getStruct<MachO::dylib_command>(this, Libraries[i]);
1156 if (D.dylib.name >= D.cmdsize)
1157 return object_error::parse_failed;
1158 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1159 StringRef Name = StringRef(P);
1160 if (D.dylib.name+Name.size() >= D.cmdsize)
1161 return object_error::parse_failed;
1164 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1165 if (shortName.empty())
1166 LibrariesShortNames.push_back(Name);
1168 LibrariesShortNames.push_back(shortName);
1172 Res = LibrariesShortNames[Index];
1173 return object_error::success;
1176 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1177 return getSymbolByIndex(0);
1180 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1183 return basic_symbol_iterator(SymbolRef(DRI, this));
1185 MachO::symtab_command Symtab = getSymtabLoadCommand();
1186 unsigned SymbolTableEntrySize = is64Bit() ?
1187 sizeof(MachO::nlist_64) :
1188 sizeof(MachO::nlist);
1189 unsigned Offset = Symtab.symoff +
1190 Symtab.nsyms * SymbolTableEntrySize;
1191 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1192 return basic_symbol_iterator(SymbolRef(DRI, this));
1195 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1198 return basic_symbol_iterator(SymbolRef(DRI, this));
1200 MachO::symtab_command Symtab = getSymtabLoadCommand();
1201 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1202 unsigned SymbolTableEntrySize =
1203 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1204 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1205 DRI.p += Index * SymbolTableEntrySize;
1206 return basic_symbol_iterator(SymbolRef(DRI, this));
1209 section_iterator MachOObjectFile::section_begin() const {
1211 return section_iterator(SectionRef(DRI, this));
1214 section_iterator MachOObjectFile::section_end() const {
1216 DRI.d.a = Sections.size();
1217 return section_iterator(SectionRef(DRI, this));
1220 uint8_t MachOObjectFile::getBytesInAddress() const {
1221 return is64Bit() ? 8 : 4;
1224 StringRef MachOObjectFile::getFileFormatName() const {
1225 unsigned CPUType = getCPUType(this);
1228 case llvm::MachO::CPU_TYPE_I386:
1229 return "Mach-O 32-bit i386";
1230 case llvm::MachO::CPU_TYPE_ARM:
1231 return "Mach-O arm";
1232 case llvm::MachO::CPU_TYPE_POWERPC:
1233 return "Mach-O 32-bit ppc";
1235 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1236 "64-bit object file when we're not 64-bit?");
1237 return "Mach-O 32-bit unknown";
1241 // Make sure the cpu type has the correct mask.
1242 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1243 == llvm::MachO::CPU_ARCH_ABI64 &&
1244 "32-bit object file when we're 64-bit?");
1247 case llvm::MachO::CPU_TYPE_X86_64:
1248 return "Mach-O 64-bit x86-64";
1249 case llvm::MachO::CPU_TYPE_ARM64:
1250 return "Mach-O arm64";
1251 case llvm::MachO::CPU_TYPE_POWERPC64:
1252 return "Mach-O 64-bit ppc64";
1254 return "Mach-O 64-bit unknown";
1258 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1260 case llvm::MachO::CPU_TYPE_I386:
1262 case llvm::MachO::CPU_TYPE_X86_64:
1263 return Triple::x86_64;
1264 case llvm::MachO::CPU_TYPE_ARM:
1266 case llvm::MachO::CPU_TYPE_ARM64:
1267 return Triple::aarch64;
1268 case llvm::MachO::CPU_TYPE_POWERPC:
1270 case llvm::MachO::CPU_TYPE_POWERPC64:
1271 return Triple::ppc64;
1273 return Triple::UnknownArch;
1277 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1278 const char **McpuDefault) {
1280 *McpuDefault = nullptr;
1283 case MachO::CPU_TYPE_I386:
1284 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1285 case MachO::CPU_SUBTYPE_I386_ALL:
1286 return Triple("i386-apple-darwin");
1290 case MachO::CPU_TYPE_X86_64:
1291 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1292 case MachO::CPU_SUBTYPE_X86_64_ALL:
1293 return Triple("x86_64-apple-darwin");
1294 case MachO::CPU_SUBTYPE_X86_64_H:
1295 return Triple("x86_64h-apple-darwin");
1299 case MachO::CPU_TYPE_ARM:
1300 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1301 case MachO::CPU_SUBTYPE_ARM_V4T:
1302 return Triple("armv4t-apple-darwin");
1303 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1304 return Triple("armv5e-apple-darwin");
1305 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1306 return Triple("xscale-apple-darwin");
1307 case MachO::CPU_SUBTYPE_ARM_V6:
1308 return Triple("armv6-apple-darwin");
1309 case MachO::CPU_SUBTYPE_ARM_V6M:
1311 *McpuDefault = "cortex-m0";
1312 return Triple("armv6m-apple-darwin");
1313 case MachO::CPU_SUBTYPE_ARM_V7:
1314 return Triple("armv7-apple-darwin");
1315 case MachO::CPU_SUBTYPE_ARM_V7EM:
1317 *McpuDefault = "cortex-m4";
1318 return Triple("armv7em-apple-darwin");
1319 case MachO::CPU_SUBTYPE_ARM_V7K:
1320 return Triple("armv7k-apple-darwin");
1321 case MachO::CPU_SUBTYPE_ARM_V7M:
1323 *McpuDefault = "cortex-m3";
1324 return Triple("armv7m-apple-darwin");
1325 case MachO::CPU_SUBTYPE_ARM_V7S:
1326 return Triple("armv7s-apple-darwin");
1330 case MachO::CPU_TYPE_ARM64:
1331 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1332 case MachO::CPU_SUBTYPE_ARM64_ALL:
1333 return Triple("arm64-apple-darwin");
1337 case MachO::CPU_TYPE_POWERPC:
1338 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1339 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1340 return Triple("ppc-apple-darwin");
1344 case MachO::CPU_TYPE_POWERPC64:
1345 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1346 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1347 return Triple("ppc64-apple-darwin");
1356 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1357 const char **McpuDefault) {
1359 *McpuDefault = nullptr;
1362 case MachO::CPU_TYPE_ARM:
1363 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1364 case MachO::CPU_SUBTYPE_ARM_V4T:
1365 return Triple("thumbv4t-apple-darwin");
1366 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1367 return Triple("thumbv5e-apple-darwin");
1368 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1369 return Triple("xscale-apple-darwin");
1370 case MachO::CPU_SUBTYPE_ARM_V6:
1371 return Triple("thumbv6-apple-darwin");
1372 case MachO::CPU_SUBTYPE_ARM_V6M:
1374 *McpuDefault = "cortex-m0";
1375 return Triple("thumbv6m-apple-darwin");
1376 case MachO::CPU_SUBTYPE_ARM_V7:
1377 return Triple("thumbv7-apple-darwin");
1378 case MachO::CPU_SUBTYPE_ARM_V7EM:
1380 *McpuDefault = "cortex-m4";
1381 return Triple("thumbv7em-apple-darwin");
1382 case MachO::CPU_SUBTYPE_ARM_V7K:
1383 return Triple("thumbv7k-apple-darwin");
1384 case MachO::CPU_SUBTYPE_ARM_V7M:
1386 *McpuDefault = "cortex-m3";
1387 return Triple("thumbv7m-apple-darwin");
1388 case MachO::CPU_SUBTYPE_ARM_V7S:
1389 return Triple("thumbv7s-apple-darwin");
1398 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1399 const char **McpuDefault,
1400 Triple *ThumbTriple) {
1401 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1402 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1407 Triple MachOObjectFile::getHostArch() {
1408 return Triple(sys::getDefaultTargetTriple());
1411 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1412 return StringSwitch<bool>(ArchFlag)
1414 .Case("x86_64", true)
1415 .Case("x86_64h", true)
1416 .Case("armv4t", true)
1418 .Case("armv5e", true)
1419 .Case("armv6", true)
1420 .Case("armv6m", true)
1421 .Case("armv7em", true)
1422 .Case("armv7k", true)
1423 .Case("armv7m", true)
1424 .Case("armv7s", true)
1425 .Case("arm64", true)
1427 .Case("ppc64", true)
1431 unsigned MachOObjectFile::getArch() const {
1432 return getArch(getCPUType(this));
1435 Triple MachOObjectFile::getArch(const char **McpuDefault,
1436 Triple *ThumbTriple) const {
1439 MachO::mach_header_64 H_64;
1440 H_64 = getHeader64();
1441 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
1442 *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
1445 MachO::mach_header H;
1447 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
1448 *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
1454 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1457 return section_rel_begin(DRI);
1460 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1463 return section_rel_end(DRI);
1466 dice_iterator MachOObjectFile::begin_dices() const {
1468 if (!DataInCodeLoadCmd)
1469 return dice_iterator(DiceRef(DRI, this));
1471 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1472 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1473 return dice_iterator(DiceRef(DRI, this));
1476 dice_iterator MachOObjectFile::end_dices() const {
1478 if (!DataInCodeLoadCmd)
1479 return dice_iterator(DiceRef(DRI, this));
1481 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1482 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1483 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1484 return dice_iterator(DiceRef(DRI, this));
1487 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1488 : Trie(T), Malformed(false), Done(false) { }
1490 void ExportEntry::moveToFirst() {
1492 pushDownUntilBottom();
1495 void ExportEntry::moveToEnd() {
1500 bool ExportEntry::operator==(const ExportEntry &Other) const {
1501 // Common case, one at end, other iterating from begin.
1502 if (Done || Other.Done)
1503 return (Done == Other.Done);
1504 // Not equal if different stack sizes.
1505 if (Stack.size() != Other.Stack.size())
1507 // Not equal if different cumulative strings.
1508 if (!CumulativeString.str().equals(Other.CumulativeString.str()))
1510 // Equal if all nodes in both stacks match.
1511 for (unsigned i=0; i < Stack.size(); ++i) {
1512 if (Stack[i].Start != Other.Stack[i].Start)
1518 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1520 uint64_t Result = decodeULEB128(Ptr, &Count);
1522 if (Ptr > Trie.end()) {
1529 StringRef ExportEntry::name() const {
1530 return CumulativeString.str();
1533 uint64_t ExportEntry::flags() const {
1534 return Stack.back().Flags;
1537 uint64_t ExportEntry::address() const {
1538 return Stack.back().Address;
1541 uint64_t ExportEntry::other() const {
1542 return Stack.back().Other;
1545 StringRef ExportEntry::otherName() const {
1546 const char* ImportName = Stack.back().ImportName;
1548 return StringRef(ImportName);
1552 uint32_t ExportEntry::nodeOffset() const {
1553 return Stack.back().Start - Trie.begin();
1556 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1557 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1558 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1559 ParentStringLength(0), IsExportNode(false) {
1562 void ExportEntry::pushNode(uint64_t offset) {
1563 const uint8_t *Ptr = Trie.begin() + offset;
1564 NodeState State(Ptr);
1565 uint64_t ExportInfoSize = readULEB128(State.Current);
1566 State.IsExportNode = (ExportInfoSize != 0);
1567 const uint8_t* Children = State.Current + ExportInfoSize;
1568 if (State.IsExportNode) {
1569 State.Flags = readULEB128(State.Current);
1570 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1572 State.Other = readULEB128(State.Current); // dylib ordinal
1573 State.ImportName = reinterpret_cast<const char*>(State.Current);
1575 State.Address = readULEB128(State.Current);
1576 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1577 State.Other = readULEB128(State.Current);
1580 State.ChildCount = *Children;
1581 State.Current = Children + 1;
1582 State.NextChildIndex = 0;
1583 State.ParentStringLength = CumulativeString.size();
1584 Stack.push_back(State);
1587 void ExportEntry::pushDownUntilBottom() {
1588 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1589 NodeState &Top = Stack.back();
1590 CumulativeString.resize(Top.ParentStringLength);
1591 for (;*Top.Current != 0; Top.Current++) {
1592 char C = *Top.Current;
1593 CumulativeString.push_back(C);
1596 uint64_t childNodeIndex = readULEB128(Top.Current);
1597 Top.NextChildIndex += 1;
1598 pushNode(childNodeIndex);
1600 if (!Stack.back().IsExportNode) {
1606 // We have a trie data structure and need a way to walk it that is compatible
1607 // with the C++ iterator model. The solution is a non-recursive depth first
1608 // traversal where the iterator contains a stack of parent nodes along with a
1609 // string that is the accumulation of all edge strings along the parent chain
1612 // There is one "export" node for each exported symbol. But because some
1613 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1614 // node may have child nodes too.
1616 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1617 // child until hitting a node with no children (which is an export node or
1618 // else the trie is malformed). On the way down, each node is pushed on the
1619 // stack ivar. If there is no more ways down, it pops up one and tries to go
1620 // down a sibling path until a childless node is reached.
1621 void ExportEntry::moveNext() {
1622 if (Stack.empty() || !Stack.back().IsExportNode) {
1629 while (!Stack.empty()) {
1630 NodeState &Top = Stack.back();
1631 if (Top.NextChildIndex < Top.ChildCount) {
1632 pushDownUntilBottom();
1633 // Now at the next export node.
1636 if (Top.IsExportNode) {
1637 // This node has no children but is itself an export node.
1638 CumulativeString.resize(Top.ParentStringLength);
1647 iterator_range<export_iterator>
1648 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1649 ExportEntry Start(Trie);
1650 Start.moveToFirst();
1652 ExportEntry Finish(Trie);
1655 return iterator_range<export_iterator>(export_iterator(Start),
1656 export_iterator(Finish));
1659 iterator_range<export_iterator> MachOObjectFile::exports() const {
1660 return exports(getDyldInfoExportsTrie());
1664 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1665 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1666 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1667 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1669 void MachORebaseEntry::moveToFirst() {
1670 Ptr = Opcodes.begin();
1674 void MachORebaseEntry::moveToEnd() {
1675 Ptr = Opcodes.end();
1676 RemainingLoopCount = 0;
1680 void MachORebaseEntry::moveNext() {
1681 // If in the middle of some loop, move to next rebasing in loop.
1682 SegmentOffset += AdvanceAmount;
1683 if (RemainingLoopCount) {
1684 --RemainingLoopCount;
1687 if (Ptr == Opcodes.end()) {
1692 while (More && !Malformed) {
1693 // Parse next opcode and set up next loop.
1694 uint8_t Byte = *Ptr++;
1695 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1696 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1698 case MachO::REBASE_OPCODE_DONE:
1702 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1704 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1705 RebaseType = ImmValue;
1708 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1709 << "RebaseType=" << (int) RebaseType << "\n");
1711 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1712 SegmentIndex = ImmValue;
1713 SegmentOffset = readULEB128();
1716 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1717 << "SegmentIndex=" << SegmentIndex << ", "
1718 << format("SegmentOffset=0x%06X", SegmentOffset)
1721 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1722 SegmentOffset += readULEB128();
1723 DEBUG_WITH_TYPE("mach-o-rebase",
1724 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1725 << format("SegmentOffset=0x%06X",
1726 SegmentOffset) << "\n");
1728 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1729 SegmentOffset += ImmValue * PointerSize;
1730 DEBUG_WITH_TYPE("mach-o-rebase",
1731 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1732 << format("SegmentOffset=0x%06X",
1733 SegmentOffset) << "\n");
1735 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1736 AdvanceAmount = PointerSize;
1737 RemainingLoopCount = ImmValue - 1;
1740 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1741 << format("SegmentOffset=0x%06X", SegmentOffset)
1742 << ", AdvanceAmount=" << AdvanceAmount
1743 << ", RemainingLoopCount=" << RemainingLoopCount
1746 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1747 AdvanceAmount = PointerSize;
1748 RemainingLoopCount = readULEB128() - 1;
1751 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1752 << format("SegmentOffset=0x%06X", SegmentOffset)
1753 << ", AdvanceAmount=" << AdvanceAmount
1754 << ", RemainingLoopCount=" << RemainingLoopCount
1757 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1758 AdvanceAmount = readULEB128() + PointerSize;
1759 RemainingLoopCount = 0;
1762 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1763 << format("SegmentOffset=0x%06X", SegmentOffset)
1764 << ", AdvanceAmount=" << AdvanceAmount
1765 << ", RemainingLoopCount=" << RemainingLoopCount
1768 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1769 RemainingLoopCount = readULEB128() - 1;
1770 AdvanceAmount = readULEB128() + PointerSize;
1773 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1774 << format("SegmentOffset=0x%06X", SegmentOffset)
1775 << ", AdvanceAmount=" << AdvanceAmount
1776 << ", RemainingLoopCount=" << RemainingLoopCount
1785 uint64_t MachORebaseEntry::readULEB128() {
1787 uint64_t Result = decodeULEB128(Ptr, &Count);
1789 if (Ptr > Opcodes.end()) {
1790 Ptr = Opcodes.end();
1796 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1798 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1800 StringRef MachORebaseEntry::typeName() const {
1801 switch (RebaseType) {
1802 case MachO::REBASE_TYPE_POINTER:
1804 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1805 return "text abs32";
1806 case MachO::REBASE_TYPE_TEXT_PCREL32:
1807 return "text rel32";
1812 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1813 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1814 return (Ptr == Other.Ptr) &&
1815 (RemainingLoopCount == Other.RemainingLoopCount) &&
1816 (Done == Other.Done);
1819 iterator_range<rebase_iterator>
1820 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1821 MachORebaseEntry Start(Opcodes, is64);
1822 Start.moveToFirst();
1824 MachORebaseEntry Finish(Opcodes, is64);
1827 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1828 rebase_iterator(Finish));
1831 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1832 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1836 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1838 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1839 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1840 BindType(0), PointerSize(is64Bit ? 8 : 4),
1841 TableKind(BK), Malformed(false), Done(false) {}
1843 void MachOBindEntry::moveToFirst() {
1844 Ptr = Opcodes.begin();
1848 void MachOBindEntry::moveToEnd() {
1849 Ptr = Opcodes.end();
1850 RemainingLoopCount = 0;
1854 void MachOBindEntry::moveNext() {
1855 // If in the middle of some loop, move to next binding in loop.
1856 SegmentOffset += AdvanceAmount;
1857 if (RemainingLoopCount) {
1858 --RemainingLoopCount;
1861 if (Ptr == Opcodes.end()) {
1866 while (More && !Malformed) {
1867 // Parse next opcode and set up next loop.
1868 uint8_t Byte = *Ptr++;
1869 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1870 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1871 int8_t SignExtended;
1872 const uint8_t *SymStart;
1874 case MachO::BIND_OPCODE_DONE:
1875 if (TableKind == Kind::Lazy) {
1876 // Lazying bindings have a DONE opcode between entries. Need to ignore
1877 // it to advance to next entry. But need not if this is last entry.
1878 bool NotLastEntry = false;
1879 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1881 NotLastEntry = true;
1890 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1892 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1896 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1897 << "Ordinal=" << Ordinal << "\n");
1899 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1900 Ordinal = readULEB128();
1903 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1904 << "Ordinal=" << Ordinal << "\n");
1906 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1908 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1909 Ordinal = SignExtended;
1914 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1915 << "Ordinal=" << Ordinal << "\n");
1917 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1923 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1928 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1929 << "SymbolName=" << SymbolName << "\n");
1930 if (TableKind == Kind::Weak) {
1931 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1935 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1936 BindType = ImmValue;
1939 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1940 << "BindType=" << (int)BindType << "\n");
1942 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1943 Addend = readSLEB128();
1944 if (TableKind == Kind::Lazy)
1948 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1949 << "Addend=" << Addend << "\n");
1951 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1952 SegmentIndex = ImmValue;
1953 SegmentOffset = readULEB128();
1956 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1957 << "SegmentIndex=" << SegmentIndex << ", "
1958 << format("SegmentOffset=0x%06X", SegmentOffset)
1961 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1962 SegmentOffset += readULEB128();
1963 DEBUG_WITH_TYPE("mach-o-bind",
1964 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1965 << format("SegmentOffset=0x%06X",
1966 SegmentOffset) << "\n");
1968 case MachO::BIND_OPCODE_DO_BIND:
1969 AdvanceAmount = PointerSize;
1970 RemainingLoopCount = 0;
1971 DEBUG_WITH_TYPE("mach-o-bind",
1972 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1973 << format("SegmentOffset=0x%06X",
1974 SegmentOffset) << "\n");
1976 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1977 AdvanceAmount = readULEB128() + PointerSize;
1978 RemainingLoopCount = 0;
1979 if (TableKind == Kind::Lazy)
1983 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1984 << format("SegmentOffset=0x%06X", SegmentOffset)
1985 << ", AdvanceAmount=" << AdvanceAmount
1986 << ", RemainingLoopCount=" << RemainingLoopCount
1989 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1990 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1991 RemainingLoopCount = 0;
1992 if (TableKind == Kind::Lazy)
1994 DEBUG_WITH_TYPE("mach-o-bind",
1996 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1997 << format("SegmentOffset=0x%06X",
1998 SegmentOffset) << "\n");
2000 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
2001 RemainingLoopCount = readULEB128() - 1;
2002 AdvanceAmount = readULEB128() + PointerSize;
2003 if (TableKind == Kind::Lazy)
2007 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
2008 << format("SegmentOffset=0x%06X", SegmentOffset)
2009 << ", AdvanceAmount=" << AdvanceAmount
2010 << ", RemainingLoopCount=" << RemainingLoopCount
2019 uint64_t MachOBindEntry::readULEB128() {
2021 uint64_t Result = decodeULEB128(Ptr, &Count);
2023 if (Ptr > Opcodes.end()) {
2024 Ptr = Opcodes.end();
2030 int64_t MachOBindEntry::readSLEB128() {
2032 int64_t Result = decodeSLEB128(Ptr, &Count);
2034 if (Ptr > Opcodes.end()) {
2035 Ptr = Opcodes.end();
2042 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
2044 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
2046 StringRef MachOBindEntry::typeName() const {
2048 case MachO::BIND_TYPE_POINTER:
2050 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
2051 return "text abs32";
2052 case MachO::BIND_TYPE_TEXT_PCREL32:
2053 return "text rel32";
2058 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
2060 int64_t MachOBindEntry::addend() const { return Addend; }
2062 uint32_t MachOBindEntry::flags() const { return Flags; }
2064 int MachOBindEntry::ordinal() const { return Ordinal; }
2066 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
2067 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
2068 return (Ptr == Other.Ptr) &&
2069 (RemainingLoopCount == Other.RemainingLoopCount) &&
2070 (Done == Other.Done);
2073 iterator_range<bind_iterator>
2074 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
2075 MachOBindEntry::Kind BKind) {
2076 MachOBindEntry Start(Opcodes, is64, BKind);
2077 Start.moveToFirst();
2079 MachOBindEntry Finish(Opcodes, is64, BKind);
2082 return iterator_range<bind_iterator>(bind_iterator(Start),
2083 bind_iterator(Finish));
2086 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
2087 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
2088 MachOBindEntry::Kind::Regular);
2091 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
2092 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
2093 MachOBindEntry::Kind::Lazy);
2096 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
2097 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
2098 MachOBindEntry::Kind::Weak);
2102 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
2103 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
2104 return parseSegmentOrSectionName(Raw.data());
2108 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
2109 const section_base *Base =
2110 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2111 return makeArrayRef(Base->sectname);
2115 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
2116 const section_base *Base =
2117 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
2118 return makeArrayRef(Base->segname);
2122 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
2124 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
2126 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
2129 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
2130 const MachO::any_relocation_info &RE) const {
2131 if (isLittleEndian())
2132 return RE.r_word1 & 0xffffff;
2133 return RE.r_word1 >> 8;
2136 bool MachOObjectFile::getPlainRelocationExternal(
2137 const MachO::any_relocation_info &RE) const {
2138 if (isLittleEndian())
2139 return (RE.r_word1 >> 27) & 1;
2140 return (RE.r_word1 >> 4) & 1;
2143 bool MachOObjectFile::getScatteredRelocationScattered(
2144 const MachO::any_relocation_info &RE) const {
2145 return RE.r_word0 >> 31;
2148 uint32_t MachOObjectFile::getScatteredRelocationValue(
2149 const MachO::any_relocation_info &RE) const {
2153 unsigned MachOObjectFile::getAnyRelocationAddress(
2154 const MachO::any_relocation_info &RE) const {
2155 if (isRelocationScattered(RE))
2156 return getScatteredRelocationAddress(RE);
2157 return getPlainRelocationAddress(RE);
2160 unsigned MachOObjectFile::getAnyRelocationPCRel(
2161 const MachO::any_relocation_info &RE) const {
2162 if (isRelocationScattered(RE))
2163 return getScatteredRelocationPCRel(this, RE);
2164 return getPlainRelocationPCRel(this, RE);
2167 unsigned MachOObjectFile::getAnyRelocationLength(
2168 const MachO::any_relocation_info &RE) const {
2169 if (isRelocationScattered(RE))
2170 return getScatteredRelocationLength(RE);
2171 return getPlainRelocationLength(this, RE);
2175 MachOObjectFile::getAnyRelocationType(
2176 const MachO::any_relocation_info &RE) const {
2177 if (isRelocationScattered(RE))
2178 return getScatteredRelocationType(RE);
2179 return getPlainRelocationType(this, RE);
2183 MachOObjectFile::getRelocationSection(
2184 const MachO::any_relocation_info &RE) const {
2185 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2186 return *section_end();
2187 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
2190 return SectionRef(DRI, this);
2193 MachOObjectFile::LoadCommandInfo
2194 MachOObjectFile::getFirstLoadCommandInfo() const {
2195 MachOObjectFile::LoadCommandInfo Load;
2197 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
2198 sizeof(MachO::mach_header);
2199 Load.Ptr = getPtr(this, HeaderSize);
2200 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
2204 MachOObjectFile::LoadCommandInfo
2205 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
2206 MachOObjectFile::LoadCommandInfo Next;
2207 Next.Ptr = L.Ptr + L.C.cmdsize;
2208 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
2212 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2213 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2216 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2217 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2220 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2221 unsigned Index) const {
2222 const char *Sec = getSectionPtr(this, L, Index);
2223 return getStruct<MachO::section>(this, Sec);
2226 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2227 unsigned Index) const {
2228 const char *Sec = getSectionPtr(this, L, Index);
2229 return getStruct<MachO::section_64>(this, Sec);
2233 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2234 const char *P = reinterpret_cast<const char *>(DRI.p);
2235 return getStruct<MachO::nlist>(this, P);
2239 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2240 const char *P = reinterpret_cast<const char *>(DRI.p);
2241 return getStruct<MachO::nlist_64>(this, P);
2244 MachO::linkedit_data_command
2245 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2246 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2249 MachO::segment_command
2250 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2251 return getStruct<MachO::segment_command>(this, L.Ptr);
2254 MachO::segment_command_64
2255 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2256 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2259 MachO::linker_options_command
2260 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
2261 return getStruct<MachO::linker_options_command>(this, L.Ptr);
2264 MachO::version_min_command
2265 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2266 return getStruct<MachO::version_min_command>(this, L.Ptr);
2269 MachO::dylib_command
2270 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2271 return getStruct<MachO::dylib_command>(this, L.Ptr);
2274 MachO::dyld_info_command
2275 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2276 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2279 MachO::dylinker_command
2280 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2281 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2285 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2286 return getStruct<MachO::uuid_command>(this, L.Ptr);
2289 MachO::source_version_command
2290 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2291 return getStruct<MachO::source_version_command>(this, L.Ptr);
2294 MachO::entry_point_command
2295 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2296 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2300 MachO::any_relocation_info
2301 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2306 MachO::section_64 Sect = getSection64(Sec);
2307 Offset = Sect.reloff;
2309 MachO::section Sect = getSection(Sec);
2310 Offset = Sect.reloff;
2313 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2314 getPtr(this, Offset)) + Rel.d.b;
2315 return getStruct<MachO::any_relocation_info>(
2316 this, reinterpret_cast<const char *>(P));
2319 MachO::data_in_code_entry
2320 MachOObjectFile::getDice(DataRefImpl Rel) const {
2321 const char *P = reinterpret_cast<const char *>(Rel.p);
2322 return getStruct<MachO::data_in_code_entry>(this, P);
2325 MachO::mach_header MachOObjectFile::getHeader() const {
2326 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
2329 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
2330 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
2333 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2334 const MachO::dysymtab_command &DLC,
2335 unsigned Index) const {
2336 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2337 return getStruct<uint32_t>(this, getPtr(this, Offset));
2340 MachO::data_in_code_entry
2341 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2342 unsigned Index) const {
2343 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2344 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2347 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2349 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2351 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2352 MachO::symtab_command Cmd;
2353 Cmd.cmd = MachO::LC_SYMTAB;
2354 Cmd.cmdsize = sizeof(MachO::symtab_command);
2362 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2363 if (DysymtabLoadCmd)
2364 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2366 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2367 MachO::dysymtab_command Cmd;
2368 Cmd.cmd = MachO::LC_DYSYMTAB;
2369 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2380 Cmd.extrefsymoff = 0;
2381 Cmd.nextrefsyms = 0;
2382 Cmd.indirectsymoff = 0;
2383 Cmd.nindirectsyms = 0;
2391 MachO::linkedit_data_command
2392 MachOObjectFile::getDataInCodeLoadCommand() const {
2393 if (DataInCodeLoadCmd)
2394 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2396 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2397 MachO::linkedit_data_command Cmd;
2398 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2399 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2405 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2406 if (!DyldInfoLoadCmd)
2407 return ArrayRef<uint8_t>();
2409 MachO::dyld_info_command DyldInfo
2410 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2411 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2412 getPtr(this, DyldInfo.rebase_off));
2413 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2416 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2417 if (!DyldInfoLoadCmd)
2418 return ArrayRef<uint8_t>();
2420 MachO::dyld_info_command DyldInfo
2421 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2422 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2423 getPtr(this, DyldInfo.bind_off));
2424 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2427 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2428 if (!DyldInfoLoadCmd)
2429 return ArrayRef<uint8_t>();
2431 MachO::dyld_info_command DyldInfo
2432 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2433 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2434 getPtr(this, DyldInfo.weak_bind_off));
2435 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2438 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2439 if (!DyldInfoLoadCmd)
2440 return ArrayRef<uint8_t>();
2442 MachO::dyld_info_command DyldInfo
2443 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2444 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2445 getPtr(this, DyldInfo.lazy_bind_off));
2446 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2449 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2450 if (!DyldInfoLoadCmd)
2451 return ArrayRef<uint8_t>();
2453 MachO::dyld_info_command DyldInfo
2454 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2455 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2456 getPtr(this, DyldInfo.export_off));
2457 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2460 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2462 return ArrayRef<uint8_t>();
2463 // Returning a pointer is fine as uuid doesn't need endian swapping.
2464 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2465 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2468 StringRef MachOObjectFile::getStringTableData() const {
2469 MachO::symtab_command S = getSymtabLoadCommand();
2470 return getData().substr(S.stroff, S.strsize);
2473 bool MachOObjectFile::is64Bit() const {
2474 return getType() == getMachOType(false, true) ||
2475 getType() == getMachOType(true, true);
2478 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2479 SmallVectorImpl<uint64_t> &Out) const {
2480 DataExtractor extractor(ObjectFile::getData(), true, 0);
2482 uint32_t offset = Index;
2484 while (uint64_t delta = extractor.getULEB128(&offset)) {
2486 Out.push_back(data);
2490 bool MachOObjectFile::isRelocatableObject() const {
2491 return getHeader().filetype == MachO::MH_OBJECT;
2494 ErrorOr<std::unique_ptr<MachOObjectFile>>
2495 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2496 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2498 std::unique_ptr<MachOObjectFile> Ret;
2499 if (Magic == "\xFE\xED\xFA\xCE")
2500 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2501 else if (Magic == "\xCE\xFA\xED\xFE")
2502 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2503 else if (Magic == "\xFE\xED\xFA\xCF")
2504 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2505 else if (Magic == "\xCF\xFA\xED\xFE")
2506 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2508 return object_error::parse_failed;
2512 return std::move(Ret);