1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Object/MachO.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/Host.h"
22 #include "llvm/Support/LEB128.h"
23 #include "llvm/Support/MachO.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/raw_ostream.h"
31 using namespace object;
41 static T getStruct(const MachOObjectFile *O, const char *P) {
43 memcpy(&Cmd, P, sizeof(T));
44 if (O->isLittleEndian() != sys::IsLittleEndianHost)
45 MachO::swapStruct(Cmd);
50 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
51 const MachOObjectFile::LoadCommandInfo &L) {
53 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
56 MachO::segment_command S = O->getSegmentLoadCommand(L);
61 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
63 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
65 bool Is64 = O->is64Bit();
66 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
67 sizeof(MachO::segment_command);
68 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
69 sizeof(MachO::section);
71 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
72 return reinterpret_cast<const char*>(SectionAddr);
75 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
76 return O->getData().substr(Offset, 1).data();
79 static MachO::nlist_base
80 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
81 const char *P = reinterpret_cast<const char *>(DRI.p);
82 return getStruct<MachO::nlist_base>(O, P);
85 static StringRef parseSegmentOrSectionName(const char *P) {
89 // Not null terminated, so this is a 16 char string.
90 return StringRef(P, 16);
93 // Helper to advance a section or symbol iterator multiple increments at a time.
95 static void advance(T &it, size_t Val) {
100 static unsigned getCPUType(const MachOObjectFile *O) {
101 return O->getHeader().cputype;
104 static void printRelocationTargetName(const MachOObjectFile *O,
105 const MachO::any_relocation_info &RE,
106 raw_string_ostream &fmt) {
107 bool IsScattered = O->isRelocationScattered(RE);
109 // Target of a scattered relocation is an address. In the interest of
110 // generating pretty output, scan through the symbol table looking for a
111 // symbol that aligns with that address. If we find one, print it.
112 // Otherwise, we just print the hex address of the target.
114 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
116 for (const SymbolRef &Symbol : O->symbols()) {
121 if ((ec = Symbol.getAddress(Addr)))
122 report_fatal_error(ec.message());
125 if ((ec = Symbol.getName(Name)))
126 report_fatal_error(ec.message());
131 // If we couldn't find a symbol that this relocation refers to, try
132 // to find a section beginning instead.
133 for (const SectionRef &Section : O->sections()) {
138 if ((ec = Section.getAddress(Addr)))
139 report_fatal_error(ec.message());
142 if ((ec = Section.getName(Name)))
143 report_fatal_error(ec.message());
148 fmt << format("0x%x", Val);
153 bool isExtern = O->getPlainRelocationExternal(RE);
154 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
157 symbol_iterator SI = O->symbol_begin();
161 section_iterator SI = O->section_begin();
162 // Adjust for the fact that sections are 1-indexed.
163 advance(SI, Val - 1);
171 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
176 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
177 return RE.r_word0 & 0xffffff;
180 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
181 const MachO::any_relocation_info &RE) {
182 if (O->isLittleEndian())
183 return (RE.r_word1 >> 24) & 1;
184 return (RE.r_word1 >> 7) & 1;
188 getScatteredRelocationPCRel(const MachOObjectFile *O,
189 const MachO::any_relocation_info &RE) {
190 return (RE.r_word0 >> 30) & 1;
193 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
194 const MachO::any_relocation_info &RE) {
195 if (O->isLittleEndian())
196 return (RE.r_word1 >> 25) & 3;
197 return (RE.r_word1 >> 5) & 3;
201 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
202 return (RE.r_word0 >> 28) & 3;
205 static unsigned getPlainRelocationType(const MachOObjectFile *O,
206 const MachO::any_relocation_info &RE) {
207 if (O->isLittleEndian())
208 return RE.r_word1 >> 28;
209 return RE.r_word1 & 0xf;
213 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
214 return (RE.r_word0 >> 24) & 0xf;
217 static uint32_t getSectionFlags(const MachOObjectFile *O,
220 MachO::section_64 Sect = O->getSection64(Sec);
223 MachO::section Sect = O->getSection(Sec);
227 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
228 bool Is64bits, std::error_code &EC)
229 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
230 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
231 DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr) {
232 uint32_t LoadCommandCount = this->getHeader().ncmds;
233 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
234 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
236 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
237 for (unsigned I = 0; ; ++I) {
238 if (Load.C.cmd == MachO::LC_SYMTAB) {
239 assert(!SymtabLoadCmd && "Multiple symbol tables");
240 SymtabLoadCmd = Load.Ptr;
241 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
242 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
243 DysymtabLoadCmd = Load.Ptr;
244 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
245 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
246 DataInCodeLoadCmd = Load.Ptr;
247 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
248 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
249 assert(!DyldInfoLoadCmd && "Multiple dyldinfo load commands");
250 DyldInfoLoadCmd = Load.Ptr;
251 } else if (Load.C.cmd == SegmentLoadType) {
252 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
253 for (unsigned J = 0; J < NumSections; ++J) {
254 const char *Sec = getSectionPtr(this, Load, J);
255 Sections.push_back(Sec);
257 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
258 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
259 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
260 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
261 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
262 Libraries.push_back(Load.Ptr);
265 if (I == LoadCommandCount - 1)
268 Load = getNextLoadCommandInfo(Load);
272 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
273 unsigned SymbolTableEntrySize = is64Bit() ?
274 sizeof(MachO::nlist_64) :
275 sizeof(MachO::nlist);
276 Symb.p += SymbolTableEntrySize;
279 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
280 StringRef &Res) const {
281 StringRef StringTable = getStringTableData();
282 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
283 const char *Start = &StringTable.data()[Entry.n_strx];
284 Res = StringRef(Start);
285 return object_error::success;
288 // getIndirectName() returns the name of the alias'ed symbol who's string table
289 // index is in the n_value field.
290 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
291 StringRef &Res) const {
292 StringRef StringTable = getStringTableData();
295 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
296 NValue = Entry.n_value;
297 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
298 return object_error::parse_failed;
300 MachO::nlist Entry = getSymbolTableEntry(Symb);
301 NValue = Entry.n_value;
302 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
303 return object_error::parse_failed;
305 if (NValue >= StringTable.size())
306 return object_error::parse_failed;
307 const char *Start = &StringTable.data()[NValue];
308 Res = StringRef(Start);
309 return object_error::success;
312 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
313 uint64_t &Res) const {
315 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
316 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
318 Res = UnknownAddressOrSize;
322 MachO::nlist Entry = getSymbolTableEntry(Symb);
323 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
325 Res = UnknownAddressOrSize;
329 return object_error::success;
332 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
333 uint32_t &Result) const {
334 uint32_t flags = getSymbolFlags(DRI);
335 if (flags & SymbolRef::SF_Common) {
336 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
337 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
341 return object_error::success;
344 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
345 uint64_t &Result) const {
346 uint64_t BeginOffset;
347 uint64_t EndOffset = 0;
348 uint8_t SectionIndex;
350 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
352 getSymbolAddress(DRI, Value);
353 if (Value == UnknownAddressOrSize) {
354 Result = UnknownAddressOrSize;
355 return object_error::success;
360 SectionIndex = Entry.n_sect;
362 uint32_t flags = getSymbolFlags(DRI);
363 if (flags & SymbolRef::SF_Common)
366 Result = UnknownAddressOrSize;
367 return object_error::success;
369 // Unfortunately symbols are unsorted so we need to touch all
370 // symbols from load command
371 for (const SymbolRef &Symbol : symbols()) {
372 DataRefImpl DRI = Symbol.getRawDataRefImpl();
373 Entry = getSymbolTableEntryBase(this, DRI);
374 getSymbolAddress(DRI, Value);
375 if (Value == UnknownAddressOrSize)
377 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
378 if (!EndOffset || Value < EndOffset)
384 Sec.d.a = SectionIndex-1;
385 getSectionSize(Sec, Size);
386 getSectionAddress(Sec, EndOffset);
389 Result = EndOffset - BeginOffset;
390 return object_error::success;
393 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
394 SymbolRef::Type &Res) const {
395 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
396 uint8_t n_type = Entry.n_type;
398 Res = SymbolRef::ST_Other;
400 // If this is a STAB debugging symbol, we can do nothing more.
401 if (n_type & MachO::N_STAB) {
402 Res = SymbolRef::ST_Debug;
403 return object_error::success;
406 switch (n_type & MachO::N_TYPE) {
408 Res = SymbolRef::ST_Unknown;
411 Res = SymbolRef::ST_Function;
414 return object_error::success;
417 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
418 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
420 uint8_t MachOType = Entry.n_type;
421 uint16_t MachOFlags = Entry.n_desc;
423 uint32_t Result = SymbolRef::SF_None;
425 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
426 Result |= SymbolRef::SF_Undefined;
428 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
429 Result |= SymbolRef::SF_Indirect;
431 if (MachOType & MachO::N_STAB)
432 Result |= SymbolRef::SF_FormatSpecific;
434 if (MachOType & MachO::N_EXT) {
435 Result |= SymbolRef::SF_Global;
436 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
438 getSymbolAddress(DRI, Value);
439 if (Value && Value != UnknownAddressOrSize)
440 Result |= SymbolRef::SF_Common;
444 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
445 Result |= SymbolRef::SF_Weak;
447 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
448 Result |= SymbolRef::SF_Thumb;
450 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
451 Result |= SymbolRef::SF_Absolute;
456 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
457 section_iterator &Res) const {
458 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
459 uint8_t index = Entry.n_sect;
466 Res = section_iterator(SectionRef(DRI, this));
469 return object_error::success;
472 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
476 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
477 StringRef &Result) const {
478 ArrayRef<char> Raw = getSectionRawName(Sec);
479 Result = parseSegmentOrSectionName(Raw.data());
480 return object_error::success;
483 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
484 uint64_t &Res) const {
486 MachO::section_64 Sect = getSection64(Sec);
489 MachO::section Sect = getSection(Sec);
492 return object_error::success;
495 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
496 uint64_t &Res) const {
498 MachO::section_64 Sect = getSection64(Sec);
501 MachO::section Sect = getSection(Sec);
505 return object_error::success;
508 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
509 StringRef &Res) const {
514 MachO::section_64 Sect = getSection64(Sec);
515 Offset = Sect.offset;
518 MachO::section Sect = getSection(Sec);
519 Offset = Sect.offset;
523 Res = this->getData().substr(Offset, Size);
524 return object_error::success;
527 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
528 uint64_t &Res) const {
531 MachO::section_64 Sect = getSection64(Sec);
534 MachO::section Sect = getSection(Sec);
538 Res = uint64_t(1) << Align;
539 return object_error::success;
542 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
544 uint32_t Flags = getSectionFlags(this, Sec);
545 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
546 return object_error::success;
549 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
550 bool &Result) const {
551 uint32_t Flags = getSectionFlags(this, Sec);
552 unsigned SectionType = Flags & MachO::SECTION_TYPE;
553 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
554 !(SectionType == MachO::S_ZEROFILL ||
555 SectionType == MachO::S_GB_ZEROFILL);
556 return object_error::success;
559 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
560 bool &Result) const {
561 uint32_t Flags = getSectionFlags(this, Sec);
562 unsigned SectionType = Flags & MachO::SECTION_TYPE;
563 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
564 (SectionType == MachO::S_ZEROFILL ||
565 SectionType == MachO::S_GB_ZEROFILL);
566 return object_error::success;
570 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
571 bool &Result) const {
572 // FIXME: Unimplemented.
574 return object_error::success;
577 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
578 bool &Result) const {
579 // FIXME: Unimplemented.
581 return object_error::success;
584 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
586 uint32_t Flags = getSectionFlags(this, Sec);
587 unsigned SectionType = Flags & MachO::SECTION_TYPE;
588 Res = SectionType == MachO::S_ZEROFILL ||
589 SectionType == MachO::S_GB_ZEROFILL;
590 return object_error::success;
593 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
594 bool &Result) const {
595 // Consider using the code from isSectionText to look for __const sections.
596 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
597 // to use section attributes to distinguish code from data.
599 // FIXME: Unimplemented.
601 return object_error::success;
604 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
606 bool &Result) const {
608 this->getSymbolType(Symb, ST);
609 if (ST == SymbolRef::ST_Unknown) {
611 return object_error::success;
614 uint64_t SectBegin, SectEnd;
615 getSectionAddress(Sec, SectBegin);
616 getSectionSize(Sec, SectEnd);
617 SectEnd += SectBegin;
620 getSymbolAddress(Symb, SymAddr);
621 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
623 return object_error::success;
626 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
630 return relocation_iterator(RelocationRef(Ret, this));
634 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
637 MachO::section_64 Sect = getSection64(Sec);
640 MachO::section Sect = getSection(Sec);
647 return relocation_iterator(RelocationRef(Ret, this));
650 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
654 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
655 uint64_t &Res) const {
657 getRelocationOffset(Rel, Offset);
662 getSectionAddress(Sec, SecAddress);
663 Res = SecAddress + Offset;
664 return object_error::success;
667 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
668 uint64_t &Res) const {
669 assert(getHeader().filetype == MachO::MH_OBJECT &&
670 "Only implemented for MH_OBJECT");
671 MachO::any_relocation_info RE = getRelocation(Rel);
672 Res = getAnyRelocationAddress(RE);
673 return object_error::success;
677 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
678 MachO::any_relocation_info RE = getRelocation(Rel);
679 if (isRelocationScattered(RE))
682 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
683 bool isExtern = getPlainRelocationExternal(RE);
687 MachO::symtab_command S = getSymtabLoadCommand();
688 unsigned SymbolTableEntrySize = is64Bit() ?
689 sizeof(MachO::nlist_64) :
690 sizeof(MachO::nlist);
691 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
693 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
694 return symbol_iterator(SymbolRef(Sym, this));
697 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
698 uint64_t &Res) const {
699 MachO::any_relocation_info RE = getRelocation(Rel);
700 Res = getAnyRelocationType(RE);
701 return object_error::success;
705 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
706 SmallVectorImpl<char> &Result) const {
709 getRelocationType(Rel, RType);
711 unsigned Arch = this->getArch();
715 static const char *const Table[] = {
716 "GENERIC_RELOC_VANILLA",
717 "GENERIC_RELOC_PAIR",
718 "GENERIC_RELOC_SECTDIFF",
719 "GENERIC_RELOC_PB_LA_PTR",
720 "GENERIC_RELOC_LOCAL_SECTDIFF",
721 "GENERIC_RELOC_TLV" };
729 case Triple::x86_64: {
730 static const char *const Table[] = {
731 "X86_64_RELOC_UNSIGNED",
732 "X86_64_RELOC_SIGNED",
733 "X86_64_RELOC_BRANCH",
734 "X86_64_RELOC_GOT_LOAD",
736 "X86_64_RELOC_SUBTRACTOR",
737 "X86_64_RELOC_SIGNED_1",
738 "X86_64_RELOC_SIGNED_2",
739 "X86_64_RELOC_SIGNED_4",
740 "X86_64_RELOC_TLV" };
749 static const char *const Table[] = {
752 "ARM_RELOC_SECTDIFF",
753 "ARM_RELOC_LOCAL_SECTDIFF",
754 "ARM_RELOC_PB_LA_PTR",
756 "ARM_THUMB_RELOC_BR22",
757 "ARM_THUMB_32BIT_BRANCH",
759 "ARM_RELOC_HALF_SECTDIFF" };
767 case Triple::aarch64: {
768 static const char *const Table[] = {
769 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
770 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
771 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
772 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
773 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
777 if (RType >= array_lengthof(Table))
784 static const char *const Table[] = {
793 "PPC_RELOC_SECTDIFF",
794 "PPC_RELOC_PB_LA_PTR",
795 "PPC_RELOC_HI16_SECTDIFF",
796 "PPC_RELOC_LO16_SECTDIFF",
797 "PPC_RELOC_HA16_SECTDIFF",
799 "PPC_RELOC_LO14_SECTDIFF",
800 "PPC_RELOC_LOCAL_SECTDIFF" };
808 case Triple::UnknownArch:
812 Result.append(res.begin(), res.end());
813 return object_error::success;
817 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
818 SmallVectorImpl<char> &Result) const {
819 MachO::any_relocation_info RE = getRelocation(Rel);
821 unsigned Arch = this->getArch();
824 raw_string_ostream fmt(fmtbuf);
825 unsigned Type = this->getAnyRelocationType(RE);
826 bool IsPCRel = this->getAnyRelocationPCRel(RE);
828 // Determine any addends that should be displayed with the relocation.
829 // These require decoding the relocation type, which is triple-specific.
831 // X86_64 has entirely custom relocation types.
832 if (Arch == Triple::x86_64) {
833 bool isPCRel = getAnyRelocationPCRel(RE);
836 case MachO::X86_64_RELOC_GOT_LOAD:
837 case MachO::X86_64_RELOC_GOT: {
838 printRelocationTargetName(this, RE, fmt);
840 if (isPCRel) fmt << "PCREL";
843 case MachO::X86_64_RELOC_SUBTRACTOR: {
844 DataRefImpl RelNext = Rel;
845 moveRelocationNext(RelNext);
846 MachO::any_relocation_info RENext = getRelocation(RelNext);
848 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
849 // X86_64_RELOC_UNSIGNED.
850 // NOTE: Scattered relocations don't exist on x86_64.
851 unsigned RType = getAnyRelocationType(RENext);
852 if (RType != MachO::X86_64_RELOC_UNSIGNED)
853 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
854 "X86_64_RELOC_SUBTRACTOR.");
856 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
857 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
858 printRelocationTargetName(this, RENext, fmt);
860 printRelocationTargetName(this, RE, fmt);
863 case MachO::X86_64_RELOC_TLV:
864 printRelocationTargetName(this, RE, fmt);
866 if (isPCRel) fmt << "P";
868 case MachO::X86_64_RELOC_SIGNED_1:
869 printRelocationTargetName(this, RE, fmt);
872 case MachO::X86_64_RELOC_SIGNED_2:
873 printRelocationTargetName(this, RE, fmt);
876 case MachO::X86_64_RELOC_SIGNED_4:
877 printRelocationTargetName(this, RE, fmt);
881 printRelocationTargetName(this, RE, fmt);
884 // X86 and ARM share some relocation types in common.
885 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
886 Arch == Triple::ppc) {
887 // Generic relocation types...
889 case MachO::GENERIC_RELOC_PAIR: // prints no info
890 return object_error::success;
891 case MachO::GENERIC_RELOC_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);
900 if (RType != MachO::GENERIC_RELOC_PAIR)
901 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
902 "GENERIC_RELOC_SECTDIFF.");
904 printRelocationTargetName(this, RE, fmt);
906 printRelocationTargetName(this, RENext, fmt);
911 if (Arch == Triple::x86 || Arch == Triple::ppc) {
913 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
914 DataRefImpl RelNext = Rel;
915 moveRelocationNext(RelNext);
916 MachO::any_relocation_info RENext = getRelocation(RelNext);
918 // X86 sect diff's must be followed by a relocation of type
919 // GENERIC_RELOC_PAIR.
920 unsigned RType = getAnyRelocationType(RENext);
921 if (RType != MachO::GENERIC_RELOC_PAIR)
922 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
923 "GENERIC_RELOC_LOCAL_SECTDIFF.");
925 printRelocationTargetName(this, RE, fmt);
927 printRelocationTargetName(this, RENext, fmt);
930 case MachO::GENERIC_RELOC_TLV: {
931 printRelocationTargetName(this, RE, fmt);
933 if (IsPCRel) fmt << "P";
937 printRelocationTargetName(this, RE, fmt);
939 } else { // ARM-specific relocations
941 case MachO::ARM_RELOC_HALF:
942 case MachO::ARM_RELOC_HALF_SECTDIFF: {
943 // Half relocations steal a bit from the length field to encode
944 // whether this is an upper16 or a lower16 relocation.
945 bool isUpper = getAnyRelocationLength(RE) >> 1;
951 printRelocationTargetName(this, RE, fmt);
953 DataRefImpl RelNext = Rel;
954 moveRelocationNext(RelNext);
955 MachO::any_relocation_info RENext = getRelocation(RelNext);
957 // ARM half relocs must be followed by a relocation of type
959 unsigned RType = getAnyRelocationType(RENext);
960 if (RType != MachO::ARM_RELOC_PAIR)
961 report_fatal_error("Expected ARM_RELOC_PAIR after "
964 // NOTE: The half of the target virtual address is stashed in the
965 // address field of the secondary relocation, but we can't reverse
966 // engineer the constant offset from it without decoding the movw/movt
967 // instruction to find the other half in its immediate field.
969 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
970 // symbol/section pointer of the follow-on relocation.
971 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
973 printRelocationTargetName(this, RENext, fmt);
980 printRelocationTargetName(this, RE, fmt);
985 printRelocationTargetName(this, RE, fmt);
988 Result.append(fmtbuf.begin(), fmtbuf.end());
989 return object_error::success;
992 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
993 bool &Result) const {
994 unsigned Arch = getArch();
996 getRelocationType(Rel, Type);
1000 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1001 // is always hidden.
1002 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
1003 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
1004 } else if (Arch == Triple::x86_64) {
1005 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1006 // an X86_64_RELOC_SUBTRACTOR.
1007 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1008 DataRefImpl RelPrev = Rel;
1011 getRelocationType(RelPrev, PrevType);
1012 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1017 return object_error::success;
1021 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1022 // guess on what the short name is. Then name is returned as a substring of the
1023 // StringRef Name passed in. The name of the dynamic library is recognized as
1024 // a framework if it has one of the two following forms:
1025 // Foo.framework/Versions/A/Foo
1026 // Foo.framework/Foo
1027 // Where A and Foo can be any string. And may contain a trailing suffix
1028 // starting with an underbar. If the Name is recognized as a framework then
1029 // isFramework is set to true else it is set to false. If the Name has a
1030 // suffix then Suffix is set to the substring in Name that contains the suffix
1031 // else it is set to a NULL StringRef.
1033 // The Name of the dynamic library is recognized as a library name if it has
1034 // one of the two following forms:
1037 // The library may have a suffix trailing the name Foo of the form:
1038 // libFoo_profile.A.dylib
1039 // libFoo_profile.dylib
1041 // The Name of the dynamic library is also recognized as a library name if it
1042 // has the following form:
1045 // If the Name of the dynamic library is none of the forms above then a NULL
1046 // StringRef is returned.
1048 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1050 StringRef &Suffix) {
1051 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1052 size_t a, b, c, d, Idx;
1054 isFramework = false;
1055 Suffix = StringRef();
1057 // Pull off the last component and make Foo point to it
1058 a = Name.rfind('/');
1059 if (a == Name.npos || a == 0)
1061 Foo = Name.slice(a+1, Name.npos);
1063 // Look for a suffix starting with a '_'
1064 Idx = Foo.rfind('_');
1065 if (Idx != Foo.npos && Foo.size() >= 2) {
1066 Suffix = Foo.slice(Idx, Foo.npos);
1067 Foo = Foo.slice(0, Idx);
1070 // First look for the form Foo.framework/Foo
1071 b = Name.rfind('/', a);
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/") {
1084 // Next look for the form Foo.framework/Versions/A/Foo
1087 c = Name.rfind('/', b);
1088 if (c == Name.npos || c == 0)
1090 V = Name.slice(c+1, Name.npos);
1091 if (!V.startswith("Versions/"))
1093 d = Name.rfind('/', c);
1098 F = Name.slice(Idx, Idx + Foo.size());
1099 DotFramework = Name.slice(Idx + Foo.size(),
1100 Idx + Foo.size() + sizeof(".framework/")-1);
1101 if (F == Foo && DotFramework == ".framework/") {
1107 // pull off the suffix after the "." and make a point to it
1108 a = Name.rfind('.');
1109 if (a == Name.npos || a == 0)
1111 Dylib = Name.slice(a, Name.npos);
1112 if (Dylib != ".dylib")
1115 // First pull off the version letter for the form Foo.A.dylib if any.
1117 Dot = Name.slice(a-2, a-1);
1122 b = Name.rfind('/', a);
1127 // ignore any suffix after an underbar like Foo_profile.A.dylib
1128 Idx = Name.find('_', b);
1129 if (Idx != Name.npos && Idx != b) {
1130 Lib = Name.slice(b, Idx);
1131 Suffix = Name.slice(Idx, a);
1134 Lib = Name.slice(b, a);
1135 // There are incorrect library names of the form:
1136 // libATS.A_profile.dylib so check for these.
1137 if (Lib.size() >= 3) {
1138 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1140 Lib = Lib.slice(0, Lib.size()-2);
1145 Qtx = Name.slice(a, Name.npos);
1148 b = Name.rfind('/', a);
1150 Lib = Name.slice(0, a);
1152 Lib = Name.slice(b+1, a);
1153 // There are library names of the form: QT.A.qtx so check for these.
1154 if (Lib.size() >= 3) {
1155 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1157 Lib = Lib.slice(0, Lib.size()-2);
1162 // getLibraryShortNameByIndex() is used to get the short name of the library
1163 // for an undefined symbol in a linked Mach-O binary that was linked with the
1164 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1165 // It is passed the index (0 - based) of the library as translated from
1166 // GET_LIBRARY_ORDINAL (1 - based).
1167 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1168 StringRef &Res) const {
1169 if (Index >= Libraries.size())
1170 return object_error::parse_failed;
1172 MachO::dylib_command D =
1173 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1174 if (D.dylib.name >= D.cmdsize)
1175 return object_error::parse_failed;
1177 // If the cache of LibrariesShortNames is not built up do that first for
1178 // all the Libraries.
1179 if (LibrariesShortNames.size() == 0) {
1180 for (unsigned i = 0; i < Libraries.size(); i++) {
1181 MachO::dylib_command D =
1182 getStruct<MachO::dylib_command>(this, Libraries[i]);
1183 if (D.dylib.name >= D.cmdsize) {
1184 LibrariesShortNames.push_back(StringRef());
1187 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1188 StringRef Name = StringRef(P);
1191 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1192 if (shortName == StringRef())
1193 LibrariesShortNames.push_back(Name);
1195 LibrariesShortNames.push_back(shortName);
1199 Res = LibrariesShortNames[Index];
1200 return object_error::success;
1203 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1204 return getSymbolByIndex(0);
1207 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1210 return basic_symbol_iterator(SymbolRef(DRI, this));
1212 MachO::symtab_command Symtab = getSymtabLoadCommand();
1213 unsigned SymbolTableEntrySize = is64Bit() ?
1214 sizeof(MachO::nlist_64) :
1215 sizeof(MachO::nlist);
1216 unsigned Offset = Symtab.symoff +
1217 Symtab.nsyms * SymbolTableEntrySize;
1218 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1219 return basic_symbol_iterator(SymbolRef(DRI, this));
1222 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1225 return basic_symbol_iterator(SymbolRef(DRI, this));
1227 MachO::symtab_command Symtab = getSymtabLoadCommand();
1228 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1229 unsigned SymbolTableEntrySize =
1230 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1231 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1232 DRI.p += Index * SymbolTableEntrySize;
1233 return basic_symbol_iterator(SymbolRef(DRI, this));
1236 section_iterator MachOObjectFile::section_begin() const {
1238 return section_iterator(SectionRef(DRI, this));
1241 section_iterator MachOObjectFile::section_end() const {
1243 DRI.d.a = Sections.size();
1244 return section_iterator(SectionRef(DRI, this));
1247 uint8_t MachOObjectFile::getBytesInAddress() const {
1248 return is64Bit() ? 8 : 4;
1251 StringRef MachOObjectFile::getFileFormatName() const {
1252 unsigned CPUType = getCPUType(this);
1255 case llvm::MachO::CPU_TYPE_I386:
1256 return "Mach-O 32-bit i386";
1257 case llvm::MachO::CPU_TYPE_ARM:
1258 return "Mach-O arm";
1259 case llvm::MachO::CPU_TYPE_POWERPC:
1260 return "Mach-O 32-bit ppc";
1262 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1263 "64-bit object file when we're not 64-bit?");
1264 return "Mach-O 32-bit unknown";
1268 // Make sure the cpu type has the correct mask.
1269 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1270 == llvm::MachO::CPU_ARCH_ABI64 &&
1271 "32-bit object file when we're 64-bit?");
1274 case llvm::MachO::CPU_TYPE_X86_64:
1275 return "Mach-O 64-bit x86-64";
1276 case llvm::MachO::CPU_TYPE_ARM64:
1277 return "Mach-O arm64";
1278 case llvm::MachO::CPU_TYPE_POWERPC64:
1279 return "Mach-O 64-bit ppc64";
1281 return "Mach-O 64-bit unknown";
1285 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1287 case llvm::MachO::CPU_TYPE_I386:
1289 case llvm::MachO::CPU_TYPE_X86_64:
1290 return Triple::x86_64;
1291 case llvm::MachO::CPU_TYPE_ARM:
1293 case llvm::MachO::CPU_TYPE_ARM64:
1294 return Triple::aarch64;
1295 case llvm::MachO::CPU_TYPE_POWERPC:
1297 case llvm::MachO::CPU_TYPE_POWERPC64:
1298 return Triple::ppc64;
1300 return Triple::UnknownArch;
1304 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1305 const char **McpuDefault) {
1307 *McpuDefault = nullptr;
1310 case MachO::CPU_TYPE_I386:
1311 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1312 case MachO::CPU_SUBTYPE_I386_ALL:
1313 return Triple("i386-apple-darwin");
1317 case MachO::CPU_TYPE_X86_64:
1318 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1319 case MachO::CPU_SUBTYPE_X86_64_ALL:
1320 return Triple("x86_64-apple-darwin");
1321 case MachO::CPU_SUBTYPE_X86_64_H:
1322 return Triple("x86_64h-apple-darwin");
1326 case MachO::CPU_TYPE_ARM:
1327 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1328 case MachO::CPU_SUBTYPE_ARM_V4T:
1329 return Triple("armv4t-apple-darwin");
1330 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1331 return Triple("armv5e-apple-darwin");
1332 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1333 return Triple("xscale-apple-darwin");
1334 case MachO::CPU_SUBTYPE_ARM_V6:
1335 return Triple("armv6-apple-darwin");
1336 case MachO::CPU_SUBTYPE_ARM_V6M:
1338 *McpuDefault = "cortex-m0";
1339 return Triple("armv6m-apple-darwin");
1340 case MachO::CPU_SUBTYPE_ARM_V7:
1341 return Triple("armv7-apple-darwin");
1342 case MachO::CPU_SUBTYPE_ARM_V7EM:
1344 *McpuDefault = "cortex-m4";
1345 return Triple("armv7em-apple-darwin");
1346 case MachO::CPU_SUBTYPE_ARM_V7K:
1347 return Triple("armv7k-apple-darwin");
1348 case MachO::CPU_SUBTYPE_ARM_V7M:
1350 *McpuDefault = "cortex-m3";
1351 return Triple("armv7m-apple-darwin");
1352 case MachO::CPU_SUBTYPE_ARM_V7S:
1353 return Triple("armv7s-apple-darwin");
1357 case MachO::CPU_TYPE_ARM64:
1358 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1359 case MachO::CPU_SUBTYPE_ARM64_ALL:
1360 return Triple("arm64-apple-darwin");
1364 case MachO::CPU_TYPE_POWERPC:
1365 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1366 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1367 return Triple("ppc-apple-darwin");
1371 case MachO::CPU_TYPE_POWERPC64:
1372 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1373 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1374 return Triple("ppc64-apple-darwin");
1383 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1384 const char **McpuDefault) {
1386 *McpuDefault = nullptr;
1389 case MachO::CPU_TYPE_ARM:
1390 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1391 case MachO::CPU_SUBTYPE_ARM_V4T:
1392 return Triple("thumbv4t-apple-darwin");
1393 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1394 return Triple("thumbv5e-apple-darwin");
1395 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1396 return Triple("xscale-apple-darwin");
1397 case MachO::CPU_SUBTYPE_ARM_V6:
1398 return Triple("thumbv6-apple-darwin");
1399 case MachO::CPU_SUBTYPE_ARM_V6M:
1401 *McpuDefault = "cortex-m0";
1402 return Triple("thumbv6m-apple-darwin");
1403 case MachO::CPU_SUBTYPE_ARM_V7:
1404 return Triple("thumbv7-apple-darwin");
1405 case MachO::CPU_SUBTYPE_ARM_V7EM:
1407 *McpuDefault = "cortex-m4";
1408 return Triple("thumbv7em-apple-darwin");
1409 case MachO::CPU_SUBTYPE_ARM_V7K:
1410 return Triple("thumbv7k-apple-darwin");
1411 case MachO::CPU_SUBTYPE_ARM_V7M:
1413 *McpuDefault = "cortex-m3";
1414 return Triple("thumbv7m-apple-darwin");
1415 case MachO::CPU_SUBTYPE_ARM_V7S:
1416 return Triple("thumbv7s-apple-darwin");
1425 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1426 const char **McpuDefault,
1427 Triple *ThumbTriple) {
1428 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1429 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1434 Triple MachOObjectFile::getHostArch() {
1435 return Triple(sys::getDefaultTargetTriple());
1438 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1439 return StringSwitch<bool>(ArchFlag)
1441 .Case("x86_64", true)
1442 .Case("x86_64h", true)
1443 .Case("armv4t", true)
1445 .Case("armv5e", true)
1446 .Case("armv6", true)
1447 .Case("armv6m", true)
1448 .Case("armv7em", true)
1449 .Case("armv7k", true)
1450 .Case("armv7m", true)
1451 .Case("armv7s", true)
1452 .Case("arm64", true)
1454 .Case("ppc64", true)
1458 unsigned MachOObjectFile::getArch() const {
1459 return getArch(getCPUType(this));
1462 Triple MachOObjectFile::getArch(const char **McpuDefault,
1463 Triple *ThumbTriple) const {
1466 MachO::mach_header_64 H_64;
1467 H_64 = getHeader64();
1468 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault);
1469 *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype,
1472 MachO::mach_header H;
1474 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault);
1475 *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype,
1481 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1484 return section_rel_begin(DRI);
1487 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1490 return section_rel_end(DRI);
1493 dice_iterator MachOObjectFile::begin_dices() const {
1495 if (!DataInCodeLoadCmd)
1496 return dice_iterator(DiceRef(DRI, this));
1498 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1499 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1500 return dice_iterator(DiceRef(DRI, this));
1503 dice_iterator MachOObjectFile::end_dices() const {
1505 if (!DataInCodeLoadCmd)
1506 return dice_iterator(DiceRef(DRI, this));
1508 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1509 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1510 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1511 return dice_iterator(DiceRef(DRI, this));
1514 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1515 : Trie(T), Malformed(false), Done(false) { }
1517 void ExportEntry::moveToFirst() {
1519 pushDownUntilBottom();
1522 void ExportEntry::moveToEnd() {
1527 bool ExportEntry::operator==(const ExportEntry &Other) const {
1528 // Common case, one at end, other iterating from begin.
1529 if (Done || Other.Done)
1530 return (Done == Other.Done);
1531 // Not equal if different stack sizes.
1532 if (Stack.size() != Other.Stack.size())
1534 // Not equal if different cumulative strings.
1535 if (!CumulativeString.str().equals(Other.CumulativeString.str()))
1537 // Equal if all nodes in both stacks match.
1538 for (unsigned i=0; i < Stack.size(); ++i) {
1539 if (Stack[i].Start != Other.Stack[i].Start)
1545 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1547 uint64_t Result = decodeULEB128(Ptr, &Count);
1549 if (Ptr > Trie.end()) {
1556 StringRef ExportEntry::name() const {
1557 return CumulativeString.str();
1560 uint64_t ExportEntry::flags() const {
1561 return Stack.back().Flags;
1564 uint64_t ExportEntry::address() const {
1565 return Stack.back().Address;
1568 uint64_t ExportEntry::other() const {
1569 return Stack.back().Other;
1572 StringRef ExportEntry::otherName() const {
1573 const char* ImportName = Stack.back().ImportName;
1575 return StringRef(ImportName);
1579 uint32_t ExportEntry::nodeOffset() const {
1580 return Stack.back().Start - Trie.begin();
1583 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1584 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1585 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1586 ParentStringLength(0), IsExportNode(false) {
1589 void ExportEntry::pushNode(uint64_t offset) {
1590 const uint8_t *Ptr = Trie.begin() + offset;
1591 NodeState State(Ptr);
1592 uint64_t ExportInfoSize = readULEB128(State.Current);
1593 State.IsExportNode = (ExportInfoSize != 0);
1594 const uint8_t* Children = State.Current + ExportInfoSize;
1595 if (State.IsExportNode) {
1596 State.Flags = readULEB128(State.Current);
1597 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1599 State.Other = readULEB128(State.Current); // dylib ordinal
1600 State.ImportName = reinterpret_cast<const char*>(State.Current);
1602 State.Address = readULEB128(State.Current);
1603 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1604 State.Other = readULEB128(State.Current);
1607 State.ChildCount = *Children;
1608 State.Current = Children + 1;
1609 State.NextChildIndex = 0;
1610 State.ParentStringLength = CumulativeString.size();
1611 Stack.push_back(State);
1614 void ExportEntry::pushDownUntilBottom() {
1615 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1616 NodeState &Top = Stack.back();
1617 CumulativeString.resize(Top.ParentStringLength);
1618 for (;*Top.Current != 0; Top.Current++) {
1619 char C = *Top.Current;
1620 CumulativeString.push_back(C);
1623 uint64_t childNodeIndex = readULEB128(Top.Current);
1624 Top.NextChildIndex += 1;
1625 pushNode(childNodeIndex);
1627 if (!Stack.back().IsExportNode) {
1633 // We have a trie data structure and need a way to walk it that is compatible
1634 // with the C++ iterator model. The solution is a non-recursive depth first
1635 // traversal where the iterator contains a stack of parent nodes along with a
1636 // string that is the accumulation of all edge strings along the parent chain
1639 // There is one “export” node for each exported symbol. But because some
1640 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1641 // node may have child nodes too.
1643 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1644 // child until hitting a node with no children (which is an export node or
1645 // else the trie is malformed). On the way down, each node is pushed on the
1646 // stack ivar. If there is no more ways down, it pops up one and tries to go
1647 // down a sibling path until a childless node is reached.
1648 void ExportEntry::moveNext() {
1649 if (Stack.empty() || !Stack.back().IsExportNode) {
1656 while (!Stack.empty()) {
1657 NodeState &Top = Stack.back();
1658 if (Top.NextChildIndex < Top.ChildCount) {
1659 pushDownUntilBottom();
1660 // Now at the next export node.
1663 if (Top.IsExportNode) {
1664 // This node has no children but is itself an export node.
1665 CumulativeString.resize(Top.ParentStringLength);
1674 iterator_range<export_iterator>
1675 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1676 ExportEntry Start(Trie);
1677 Start.moveToFirst();
1679 ExportEntry Finish(Trie);
1682 return iterator_range<export_iterator>(export_iterator(Start),
1683 export_iterator(Finish));
1686 iterator_range<export_iterator> MachOObjectFile::exports() const {
1687 return exports(getDyldInfoExportsTrie());
1692 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1693 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1694 return parseSegmentOrSectionName(Raw.data());
1698 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1699 const section_base *Base =
1700 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1701 return makeArrayRef(Base->sectname);
1705 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1706 const section_base *Base =
1707 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1708 return makeArrayRef(Base->segname);
1712 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1714 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1716 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1719 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1720 const MachO::any_relocation_info &RE) const {
1721 if (isLittleEndian())
1722 return RE.r_word1 & 0xffffff;
1723 return RE.r_word1 >> 8;
1726 bool MachOObjectFile::getPlainRelocationExternal(
1727 const MachO::any_relocation_info &RE) const {
1728 if (isLittleEndian())
1729 return (RE.r_word1 >> 27) & 1;
1730 return (RE.r_word1 >> 4) & 1;
1733 bool MachOObjectFile::getScatteredRelocationScattered(
1734 const MachO::any_relocation_info &RE) const {
1735 return RE.r_word0 >> 31;
1738 uint32_t MachOObjectFile::getScatteredRelocationValue(
1739 const MachO::any_relocation_info &RE) const {
1743 unsigned MachOObjectFile::getAnyRelocationAddress(
1744 const MachO::any_relocation_info &RE) const {
1745 if (isRelocationScattered(RE))
1746 return getScatteredRelocationAddress(RE);
1747 return getPlainRelocationAddress(RE);
1750 unsigned MachOObjectFile::getAnyRelocationPCRel(
1751 const MachO::any_relocation_info &RE) const {
1752 if (isRelocationScattered(RE))
1753 return getScatteredRelocationPCRel(this, RE);
1754 return getPlainRelocationPCRel(this, RE);
1757 unsigned MachOObjectFile::getAnyRelocationLength(
1758 const MachO::any_relocation_info &RE) const {
1759 if (isRelocationScattered(RE))
1760 return getScatteredRelocationLength(RE);
1761 return getPlainRelocationLength(this, RE);
1765 MachOObjectFile::getAnyRelocationType(
1766 const MachO::any_relocation_info &RE) const {
1767 if (isRelocationScattered(RE))
1768 return getScatteredRelocationType(RE);
1769 return getPlainRelocationType(this, RE);
1773 MachOObjectFile::getRelocationSection(
1774 const MachO::any_relocation_info &RE) const {
1775 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1776 return *section_end();
1777 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1780 return SectionRef(DRI, this);
1783 MachOObjectFile::LoadCommandInfo
1784 MachOObjectFile::getFirstLoadCommandInfo() const {
1785 MachOObjectFile::LoadCommandInfo Load;
1787 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1788 sizeof(MachO::mach_header);
1789 Load.Ptr = getPtr(this, HeaderSize);
1790 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1794 MachOObjectFile::LoadCommandInfo
1795 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1796 MachOObjectFile::LoadCommandInfo Next;
1797 Next.Ptr = L.Ptr + L.C.cmdsize;
1798 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1802 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1803 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1806 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1807 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1810 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1811 unsigned Index) const {
1812 const char *Sec = getSectionPtr(this, L, Index);
1813 return getStruct<MachO::section>(this, Sec);
1816 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1817 unsigned Index) const {
1818 const char *Sec = getSectionPtr(this, L, Index);
1819 return getStruct<MachO::section_64>(this, Sec);
1823 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1824 const char *P = reinterpret_cast<const char *>(DRI.p);
1825 return getStruct<MachO::nlist>(this, P);
1829 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1830 const char *P = reinterpret_cast<const char *>(DRI.p);
1831 return getStruct<MachO::nlist_64>(this, P);
1834 MachO::linkedit_data_command
1835 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1836 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1839 MachO::segment_command
1840 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1841 return getStruct<MachO::segment_command>(this, L.Ptr);
1844 MachO::segment_command_64
1845 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1846 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1849 MachO::linker_options_command
1850 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1851 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1854 MachO::version_min_command
1855 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1856 return getStruct<MachO::version_min_command>(this, L.Ptr);
1859 MachO::dylib_command
1860 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1861 return getStruct<MachO::dylib_command>(this, L.Ptr);
1864 MachO::dyld_info_command
1865 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
1866 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
1869 MachO::dylinker_command
1870 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
1871 return getStruct<MachO::dylinker_command>(this, L.Ptr);
1875 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
1876 return getStruct<MachO::uuid_command>(this, L.Ptr);
1879 MachO::source_version_command
1880 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
1881 return getStruct<MachO::source_version_command>(this, L.Ptr);
1884 MachO::entry_point_command
1885 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
1886 return getStruct<MachO::entry_point_command>(this, L.Ptr);
1890 MachO::any_relocation_info
1891 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1896 MachO::section_64 Sect = getSection64(Sec);
1897 Offset = Sect.reloff;
1899 MachO::section Sect = getSection(Sec);
1900 Offset = Sect.reloff;
1903 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1904 getPtr(this, Offset)) + Rel.d.b;
1905 return getStruct<MachO::any_relocation_info>(
1906 this, reinterpret_cast<const char *>(P));
1909 MachO::data_in_code_entry
1910 MachOObjectFile::getDice(DataRefImpl Rel) const {
1911 const char *P = reinterpret_cast<const char *>(Rel.p);
1912 return getStruct<MachO::data_in_code_entry>(this, P);
1915 MachO::mach_header MachOObjectFile::getHeader() const {
1916 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1919 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1920 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1923 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1924 const MachO::dysymtab_command &DLC,
1925 unsigned Index) const {
1926 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1927 return getStruct<uint32_t>(this, getPtr(this, Offset));
1930 MachO::data_in_code_entry
1931 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1932 unsigned Index) const {
1933 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1934 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1937 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1938 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1941 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1942 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1945 MachO::linkedit_data_command
1946 MachOObjectFile::getDataInCodeLoadCommand() const {
1947 if (DataInCodeLoadCmd)
1948 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1950 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1951 MachO::linkedit_data_command Cmd;
1952 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1953 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1959 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
1960 if (!DyldInfoLoadCmd)
1961 return ArrayRef<uint8_t>();
1963 MachO::dyld_info_command DyldInfo
1964 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
1965 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
1966 getPtr(this, DyldInfo.rebase_off));
1967 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
1970 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
1971 if (!DyldInfoLoadCmd)
1972 return ArrayRef<uint8_t>();
1974 MachO::dyld_info_command DyldInfo
1975 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
1976 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
1977 getPtr(this, DyldInfo.bind_off));
1978 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
1981 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
1982 if (!DyldInfoLoadCmd)
1983 return ArrayRef<uint8_t>();
1985 MachO::dyld_info_command DyldInfo
1986 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
1987 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
1988 getPtr(this, DyldInfo.weak_bind_off));
1989 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
1992 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
1993 if (!DyldInfoLoadCmd)
1994 return ArrayRef<uint8_t>();
1996 MachO::dyld_info_command DyldInfo
1997 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
1998 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
1999 getPtr(this, DyldInfo.lazy_bind_off));
2000 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2003 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2004 if (!DyldInfoLoadCmd)
2005 return ArrayRef<uint8_t>();
2007 MachO::dyld_info_command DyldInfo
2008 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2009 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2010 getPtr(this, DyldInfo.export_off));
2011 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2015 StringRef MachOObjectFile::getStringTableData() const {
2016 MachO::symtab_command S = getSymtabLoadCommand();
2017 return getData().substr(S.stroff, S.strsize);
2020 bool MachOObjectFile::is64Bit() const {
2021 return getType() == getMachOType(false, true) ||
2022 getType() == getMachOType(true, true);
2025 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2026 SmallVectorImpl<uint64_t> &Out) const {
2027 DataExtractor extractor(ObjectFile::getData(), true, 0);
2029 uint32_t offset = Index;
2031 while (uint64_t delta = extractor.getULEB128(&offset)) {
2033 Out.push_back(data);
2037 bool MachOObjectFile::isRelocatableObject() const {
2038 return getHeader().filetype == MachO::MH_OBJECT;
2041 ErrorOr<std::unique_ptr<MachOObjectFile>>
2042 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2043 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2045 std::unique_ptr<MachOObjectFile> Ret;
2046 if (Magic == "\xFE\xED\xFA\xCE")
2047 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2048 else if (Magic == "\xCE\xFA\xED\xFE")
2049 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2050 else if (Magic == "\xFE\xED\xFA\xCF")
2051 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2052 else if (Magic == "\xCF\xFA\xED\xFE")
2053 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2055 return object_error::parse_failed;
2059 return std::move(Ret);