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;
41 // FIXME: Replace all uses of this function with getStructOrErr.
43 static T getStruct(const MachOObjectFile *O, const char *P) {
44 // Don't read before the beginning or past the end of the file
45 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
46 report_fatal_error("Malformed MachO file.");
49 memcpy(&Cmd, P, sizeof(T));
50 if (O->isLittleEndian() != sys::IsLittleEndianHost)
51 MachO::swapStruct(Cmd);
56 static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
57 // Don't read before the beginning or past the end of the file
58 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
59 return object_error::parse_failed;
62 memcpy(&Cmd, P, sizeof(T));
63 if (O->isLittleEndian() != sys::IsLittleEndianHost)
64 MachO::swapStruct(Cmd);
69 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
71 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
73 bool Is64 = O->is64Bit();
74 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
75 sizeof(MachO::segment_command);
76 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
77 sizeof(MachO::section);
79 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
80 return reinterpret_cast<const char*>(SectionAddr);
83 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
84 return O->getData().substr(Offset, 1).data();
87 static MachO::nlist_base
88 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
89 const char *P = reinterpret_cast<const char *>(DRI.p);
90 return getStruct<MachO::nlist_base>(O, P);
93 static StringRef parseSegmentOrSectionName(const char *P) {
97 // Not null terminated, so this is a 16 char string.
98 return StringRef(P, 16);
101 // Helper to advance a section or symbol iterator multiple increments at a time.
103 static void advance(T &it, size_t Val) {
108 static unsigned getCPUType(const MachOObjectFile *O) {
109 return O->getHeader().cputype;
113 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
118 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
119 return RE.r_word0 & 0xffffff;
122 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
123 const MachO::any_relocation_info &RE) {
124 if (O->isLittleEndian())
125 return (RE.r_word1 >> 24) & 1;
126 return (RE.r_word1 >> 7) & 1;
130 getScatteredRelocationPCRel(const MachOObjectFile *O,
131 const MachO::any_relocation_info &RE) {
132 return (RE.r_word0 >> 30) & 1;
135 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
136 const MachO::any_relocation_info &RE) {
137 if (O->isLittleEndian())
138 return (RE.r_word1 >> 25) & 3;
139 return (RE.r_word1 >> 5) & 3;
143 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
144 return (RE.r_word0 >> 28) & 3;
147 static unsigned getPlainRelocationType(const MachOObjectFile *O,
148 const MachO::any_relocation_info &RE) {
149 if (O->isLittleEndian())
150 return RE.r_word1 >> 28;
151 return RE.r_word1 & 0xf;
154 static uint32_t getSectionFlags(const MachOObjectFile *O,
157 MachO::section_64 Sect = O->getSection64(Sec);
160 MachO::section Sect = O->getSection(Sec);
164 static ErrorOr<MachOObjectFile::LoadCommandInfo>
165 getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) {
166 auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr);
168 return CmdOrErr.getError();
169 if (CmdOrErr->cmdsize < 8)
170 return object_error::macho_small_load_command;
171 MachOObjectFile::LoadCommandInfo Load;
173 Load.C = CmdOrErr.get();
177 static ErrorOr<MachOObjectFile::LoadCommandInfo>
178 getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
179 unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
180 : sizeof(MachO::mach_header);
181 return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize));
184 static ErrorOr<MachOObjectFile::LoadCommandInfo>
185 getNextLoadCommandInfo(const MachOObjectFile *Obj,
186 const MachOObjectFile::LoadCommandInfo &L) {
187 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
190 template <typename T>
191 static void parseHeader(const MachOObjectFile *Obj, T &Header,
192 std::error_code &EC) {
193 auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
195 Header = HeaderOrErr.get();
197 EC = HeaderOrErr.getError();
200 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
201 // sections to \param Sections, and optionally sets
202 // \param IsPageZeroSegment to true.
203 template <typename SegmentCmd>
204 static std::error_code parseSegmentLoadCommand(
205 const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
206 SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment) {
207 const unsigned SegmentLoadSize = sizeof(SegmentCmd);
208 if (Load.C.cmdsize < SegmentLoadSize)
209 return object_error::macho_load_segment_too_small;
210 auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr);
212 return SegOrErr.getError();
213 SegmentCmd S = SegOrErr.get();
214 const unsigned SectionSize =
215 Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section);
216 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
217 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
218 return object_error::macho_load_segment_too_many_sections;
219 for (unsigned J = 0; J < S.nsects; ++J) {
220 const char *Sec = getSectionPtr(Obj, Load, J);
221 Sections.push_back(Sec);
223 IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
224 return object_error::success;
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), LinkOptHintsLoadCmd(nullptr),
232 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
233 HasPageZeroSegment(false) {
235 parseHeader(this, Header64, EC);
237 parseHeader(this, Header, EC);
241 uint32_t LoadCommandCount = getHeader().ncmds;
242 if (LoadCommandCount == 0)
245 auto LoadOrErr = getFirstLoadCommandInfo(this);
247 EC = LoadOrErr.getError();
250 LoadCommandInfo Load = LoadOrErr.get();
251 for (unsigned I = 0; I < LoadCommandCount; ++I) {
252 LoadCommands.push_back(Load);
253 if (Load.C.cmd == MachO::LC_SYMTAB) {
254 // Multiple symbol tables
256 EC = object_error::parse_failed;
259 SymtabLoadCmd = Load.Ptr;
260 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
261 // Multiple dynamic symbol tables
262 if (DysymtabLoadCmd) {
263 EC = object_error::parse_failed;
266 DysymtabLoadCmd = Load.Ptr;
267 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
268 // Multiple data in code tables
269 if (DataInCodeLoadCmd) {
270 EC = object_error::parse_failed;
273 DataInCodeLoadCmd = Load.Ptr;
274 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
275 // Multiple linker optimization hint tables
276 if (LinkOptHintsLoadCmd) {
277 EC = object_error::parse_failed;
280 LinkOptHintsLoadCmd = Load.Ptr;
281 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
282 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
283 // Multiple dyldinfo load commands
284 if (DyldInfoLoadCmd) {
285 EC = object_error::parse_failed;
288 DyldInfoLoadCmd = Load.Ptr;
289 } else if (Load.C.cmd == MachO::LC_UUID) {
290 // Multiple UUID load commands
292 EC = object_error::parse_failed;
295 UuidLoadCmd = Load.Ptr;
296 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
297 if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>(
298 this, Load, Sections, HasPageZeroSegment)))
300 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
301 if ((EC = parseSegmentLoadCommand<MachO::segment_command>(
302 this, Load, Sections, HasPageZeroSegment)))
304 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
305 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
306 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
307 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
308 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
309 Libraries.push_back(Load.Ptr);
311 if (I < LoadCommandCount - 1) {
312 auto LoadOrErr = getNextLoadCommandInfo(this, Load);
314 EC = LoadOrErr.getError();
317 Load = LoadOrErr.get();
320 assert(LoadCommands.size() == LoadCommandCount);
323 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
324 unsigned SymbolTableEntrySize = is64Bit() ?
325 sizeof(MachO::nlist_64) :
326 sizeof(MachO::nlist);
327 Symb.p += SymbolTableEntrySize;
330 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
331 StringRef &Res) const {
332 StringRef StringTable = getStringTableData();
333 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
334 const char *Start = &StringTable.data()[Entry.n_strx];
335 if (Start < getData().begin() || Start >= getData().end())
337 "Symbol name entry points before beginning or past end of file.");
338 Res = StringRef(Start);
339 return object_error::success;
342 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
343 DataRefImpl DRI = Sec.getRawDataRefImpl();
344 uint32_t Flags = getSectionFlags(this, DRI);
345 return Flags & MachO::SECTION_TYPE;
348 // getIndirectName() returns the name of the alias'ed symbol who's string table
349 // index is in the n_value field.
350 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
351 StringRef &Res) const {
352 StringRef StringTable = getStringTableData();
355 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
356 NValue = Entry.n_value;
357 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
358 return object_error::parse_failed;
360 MachO::nlist Entry = getSymbolTableEntry(Symb);
361 NValue = Entry.n_value;
362 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
363 return object_error::parse_failed;
365 if (NValue >= StringTable.size())
366 return object_error::parse_failed;
367 const char *Start = &StringTable.data()[NValue];
368 Res = StringRef(Start);
369 return object_error::success;
372 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
373 uint64_t &Res) const {
375 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
376 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
378 Res = UnknownAddressOrSize;
382 MachO::nlist Entry = getSymbolTableEntry(Symb);
383 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
385 Res = UnknownAddressOrSize;
389 return object_error::success;
392 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
393 uint32_t flags = getSymbolFlags(DRI);
394 if (flags & SymbolRef::SF_Common) {
395 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
396 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
401 uint64_t MachOObjectFile::getSymbolSize(DataRefImpl DRI) const {
403 getSymbolAddress(DRI, Value);
404 uint32_t flags = getSymbolFlags(DRI);
405 if (flags & SymbolRef::SF_Common)
407 return UnknownAddressOrSize;
410 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
411 SymbolRef::Type &Res) const {
412 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
413 uint8_t n_type = Entry.n_type;
415 Res = SymbolRef::ST_Other;
417 // If this is a STAB debugging symbol, we can do nothing more.
418 if (n_type & MachO::N_STAB) {
419 Res = SymbolRef::ST_Debug;
420 return object_error::success;
423 switch (n_type & MachO::N_TYPE) {
425 Res = SymbolRef::ST_Unknown;
428 Res = SymbolRef::ST_Function;
431 return object_error::success;
434 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
435 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
437 uint8_t MachOType = Entry.n_type;
438 uint16_t MachOFlags = Entry.n_desc;
440 uint32_t Result = SymbolRef::SF_None;
442 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
443 Result |= SymbolRef::SF_Undefined;
445 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
446 Result |= SymbolRef::SF_Indirect;
448 if (MachOType & MachO::N_STAB)
449 Result |= SymbolRef::SF_FormatSpecific;
451 if (MachOType & MachO::N_EXT) {
452 Result |= SymbolRef::SF_Global;
453 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
455 getSymbolAddress(DRI, Value);
456 if (Value && Value != UnknownAddressOrSize)
457 Result |= SymbolRef::SF_Common;
460 if (!(MachOType & MachO::N_PEXT))
461 Result |= SymbolRef::SF_Exported;
464 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
465 Result |= SymbolRef::SF_Weak;
467 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
468 Result |= SymbolRef::SF_Thumb;
470 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
471 Result |= SymbolRef::SF_Absolute;
476 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
477 section_iterator &Res) const {
478 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
479 uint8_t index = Entry.n_sect;
486 if (DRI.d.a >= Sections.size())
487 report_fatal_error("getSymbolSection: Invalid section index.");
488 Res = section_iterator(SectionRef(DRI, this));
491 return object_error::success;
494 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
498 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
499 StringRef &Result) const {
500 ArrayRef<char> Raw = getSectionRawName(Sec);
501 Result = parseSegmentOrSectionName(Raw.data());
502 return object_error::success;
505 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
507 return getSection64(Sec).addr;
508 return getSection(Sec).addr;
511 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
513 return getSection64(Sec).size;
514 return getSection(Sec).size;
517 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
518 StringRef &Res) const {
523 MachO::section_64 Sect = getSection64(Sec);
524 Offset = Sect.offset;
527 MachO::section Sect = getSection(Sec);
528 Offset = Sect.offset;
532 Res = this->getData().substr(Offset, Size);
533 return object_error::success;
536 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
539 MachO::section_64 Sect = getSection64(Sec);
542 MachO::section Sect = getSection(Sec);
546 return uint64_t(1) << Align;
549 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
550 uint32_t Flags = getSectionFlags(this, Sec);
551 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
554 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
555 uint32_t Flags = getSectionFlags(this, Sec);
556 unsigned SectionType = Flags & MachO::SECTION_TYPE;
557 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
558 !(SectionType == MachO::S_ZEROFILL ||
559 SectionType == MachO::S_GB_ZEROFILL);
562 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
563 uint32_t Flags = getSectionFlags(this, Sec);
564 unsigned SectionType = Flags & MachO::SECTION_TYPE;
565 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
566 (SectionType == MachO::S_ZEROFILL ||
567 SectionType == MachO::S_GB_ZEROFILL);
570 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
571 // FIXME: Unimplemented.
575 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
576 DataRefImpl Symb) const {
578 this->getSymbolType(Symb, ST);
579 if (ST == SymbolRef::ST_Unknown)
582 uint64_t SectBegin = getSectionAddress(Sec);
583 uint64_t SectEnd = getSectionSize(Sec);
584 SectEnd += SectBegin;
587 getSymbolAddress(Symb, SymAddr);
588 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
591 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
595 return relocation_iterator(RelocationRef(Ret, this));
599 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
602 MachO::section_64 Sect = getSection64(Sec);
605 MachO::section Sect = getSection(Sec);
612 return relocation_iterator(RelocationRef(Ret, this));
615 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
619 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
620 uint64_t &Res) const {
622 getRelocationOffset(Rel, Offset);
626 uint64_t SecAddress = getSectionAddress(Sec);
627 Res = SecAddress + Offset;
628 return object_error::success;
631 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
632 uint64_t &Res) const {
633 assert(getHeader().filetype == MachO::MH_OBJECT &&
634 "Only implemented for MH_OBJECT");
635 MachO::any_relocation_info RE = getRelocation(Rel);
636 Res = getAnyRelocationAddress(RE);
637 return object_error::success;
641 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
642 MachO::any_relocation_info RE = getRelocation(Rel);
643 if (isRelocationScattered(RE))
646 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
647 bool isExtern = getPlainRelocationExternal(RE);
651 MachO::symtab_command S = getSymtabLoadCommand();
652 unsigned SymbolTableEntrySize = is64Bit() ?
653 sizeof(MachO::nlist_64) :
654 sizeof(MachO::nlist);
655 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
657 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
658 return symbol_iterator(SymbolRef(Sym, this));
662 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
663 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
666 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
667 uint64_t &Res) const {
668 MachO::any_relocation_info RE = getRelocation(Rel);
669 Res = getAnyRelocationType(RE);
670 return object_error::success;
674 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
675 SmallVectorImpl<char> &Result) const {
678 getRelocationType(Rel, RType);
680 unsigned Arch = this->getArch();
684 static const char *const Table[] = {
685 "GENERIC_RELOC_VANILLA",
686 "GENERIC_RELOC_PAIR",
687 "GENERIC_RELOC_SECTDIFF",
688 "GENERIC_RELOC_PB_LA_PTR",
689 "GENERIC_RELOC_LOCAL_SECTDIFF",
690 "GENERIC_RELOC_TLV" };
698 case Triple::x86_64: {
699 static const char *const Table[] = {
700 "X86_64_RELOC_UNSIGNED",
701 "X86_64_RELOC_SIGNED",
702 "X86_64_RELOC_BRANCH",
703 "X86_64_RELOC_GOT_LOAD",
705 "X86_64_RELOC_SUBTRACTOR",
706 "X86_64_RELOC_SIGNED_1",
707 "X86_64_RELOC_SIGNED_2",
708 "X86_64_RELOC_SIGNED_4",
709 "X86_64_RELOC_TLV" };
718 static const char *const Table[] = {
721 "ARM_RELOC_SECTDIFF",
722 "ARM_RELOC_LOCAL_SECTDIFF",
723 "ARM_RELOC_PB_LA_PTR",
725 "ARM_THUMB_RELOC_BR22",
726 "ARM_THUMB_32BIT_BRANCH",
728 "ARM_RELOC_HALF_SECTDIFF" };
736 case Triple::aarch64: {
737 static const char *const Table[] = {
738 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
739 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
740 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
741 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
742 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
746 if (RType >= array_lengthof(Table))
753 static const char *const Table[] = {
762 "PPC_RELOC_SECTDIFF",
763 "PPC_RELOC_PB_LA_PTR",
764 "PPC_RELOC_HI16_SECTDIFF",
765 "PPC_RELOC_LO16_SECTDIFF",
766 "PPC_RELOC_HA16_SECTDIFF",
768 "PPC_RELOC_LO14_SECTDIFF",
769 "PPC_RELOC_LOCAL_SECTDIFF" };
777 case Triple::UnknownArch:
781 Result.append(res.begin(), res.end());
782 return object_error::success;
785 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
786 bool &Result) const {
787 unsigned Arch = getArch();
789 getRelocationType(Rel, Type);
793 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
795 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
796 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
797 } else if (Arch == Triple::x86_64) {
798 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
799 // an X86_64_RELOC_SUBTRACTOR.
800 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
801 DataRefImpl RelPrev = Rel;
804 getRelocationType(RelPrev, PrevType);
805 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
810 return object_error::success;
813 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
814 MachO::any_relocation_info RE = getRelocation(Rel);
815 return getAnyRelocationLength(RE);
819 // guessLibraryShortName() is passed a name of a dynamic library and returns a
820 // guess on what the short name is. Then name is returned as a substring of the
821 // StringRef Name passed in. The name of the dynamic library is recognized as
822 // a framework if it has one of the two following forms:
823 // Foo.framework/Versions/A/Foo
825 // Where A and Foo can be any string. And may contain a trailing suffix
826 // starting with an underbar. If the Name is recognized as a framework then
827 // isFramework is set to true else it is set to false. If the Name has a
828 // suffix then Suffix is set to the substring in Name that contains the suffix
829 // else it is set to a NULL StringRef.
831 // The Name of the dynamic library is recognized as a library name if it has
832 // one of the two following forms:
835 // The library may have a suffix trailing the name Foo of the form:
836 // libFoo_profile.A.dylib
837 // libFoo_profile.dylib
839 // The Name of the dynamic library is also recognized as a library name if it
840 // has the following form:
843 // If the Name of the dynamic library is none of the forms above then a NULL
844 // StringRef is returned.
846 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
849 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
850 size_t a, b, c, d, Idx;
853 Suffix = StringRef();
855 // Pull off the last component and make Foo point to it
857 if (a == Name.npos || a == 0)
859 Foo = Name.slice(a+1, Name.npos);
861 // Look for a suffix starting with a '_'
862 Idx = Foo.rfind('_');
863 if (Idx != Foo.npos && Foo.size() >= 2) {
864 Suffix = Foo.slice(Idx, Foo.npos);
865 Foo = Foo.slice(0, Idx);
868 // First look for the form Foo.framework/Foo
869 b = Name.rfind('/', a);
874 F = Name.slice(Idx, Idx + Foo.size());
875 DotFramework = Name.slice(Idx + Foo.size(),
876 Idx + Foo.size() + sizeof(".framework/")-1);
877 if (F == Foo && DotFramework == ".framework/") {
882 // Next look for the form Foo.framework/Versions/A/Foo
885 c = Name.rfind('/', b);
886 if (c == Name.npos || c == 0)
888 V = Name.slice(c+1, Name.npos);
889 if (!V.startswith("Versions/"))
891 d = Name.rfind('/', c);
896 F = Name.slice(Idx, Idx + Foo.size());
897 DotFramework = Name.slice(Idx + Foo.size(),
898 Idx + Foo.size() + sizeof(".framework/")-1);
899 if (F == Foo && DotFramework == ".framework/") {
905 // pull off the suffix after the "." and make a point to it
907 if (a == Name.npos || a == 0)
909 Dylib = Name.slice(a, Name.npos);
910 if (Dylib != ".dylib")
913 // First pull off the version letter for the form Foo.A.dylib if any.
915 Dot = Name.slice(a-2, a-1);
920 b = Name.rfind('/', a);
925 // ignore any suffix after an underbar like Foo_profile.A.dylib
926 Idx = Name.find('_', b);
927 if (Idx != Name.npos && Idx != b) {
928 Lib = Name.slice(b, Idx);
929 Suffix = Name.slice(Idx, a);
932 Lib = Name.slice(b, a);
933 // There are incorrect library names of the form:
934 // libATS.A_profile.dylib so check for these.
935 if (Lib.size() >= 3) {
936 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
938 Lib = Lib.slice(0, Lib.size()-2);
943 Qtx = Name.slice(a, Name.npos);
946 b = Name.rfind('/', a);
948 Lib = Name.slice(0, a);
950 Lib = Name.slice(b+1, a);
951 // There are library names of the form: QT.A.qtx so check for these.
952 if (Lib.size() >= 3) {
953 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
955 Lib = Lib.slice(0, Lib.size()-2);
960 // getLibraryShortNameByIndex() is used to get the short name of the library
961 // for an undefined symbol in a linked Mach-O binary that was linked with the
962 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
963 // It is passed the index (0 - based) of the library as translated from
964 // GET_LIBRARY_ORDINAL (1 - based).
965 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
966 StringRef &Res) const {
967 if (Index >= Libraries.size())
968 return object_error::parse_failed;
970 // If the cache of LibrariesShortNames is not built up do that first for
971 // all the Libraries.
972 if (LibrariesShortNames.size() == 0) {
973 for (unsigned i = 0; i < Libraries.size(); i++) {
974 MachO::dylib_command D =
975 getStruct<MachO::dylib_command>(this, Libraries[i]);
976 if (D.dylib.name >= D.cmdsize)
977 return object_error::parse_failed;
978 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
979 StringRef Name = StringRef(P);
980 if (D.dylib.name+Name.size() >= D.cmdsize)
981 return object_error::parse_failed;
984 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
985 if (shortName.empty())
986 LibrariesShortNames.push_back(Name);
988 LibrariesShortNames.push_back(shortName);
992 Res = LibrariesShortNames[Index];
993 return object_error::success;
996 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
997 return getSymbolByIndex(0);
1000 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1003 return basic_symbol_iterator(SymbolRef(DRI, this));
1005 MachO::symtab_command Symtab = getSymtabLoadCommand();
1006 unsigned SymbolTableEntrySize = is64Bit() ?
1007 sizeof(MachO::nlist_64) :
1008 sizeof(MachO::nlist);
1009 unsigned Offset = Symtab.symoff +
1010 Symtab.nsyms * SymbolTableEntrySize;
1011 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1012 return basic_symbol_iterator(SymbolRef(DRI, this));
1015 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1018 return basic_symbol_iterator(SymbolRef(DRI, this));
1020 MachO::symtab_command Symtab = getSymtabLoadCommand();
1021 if (Index >= Symtab.nsyms)
1022 report_fatal_error("Requested symbol index is out of range.");
1023 unsigned SymbolTableEntrySize =
1024 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1025 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1026 DRI.p += Index * SymbolTableEntrySize;
1027 return basic_symbol_iterator(SymbolRef(DRI, this));
1030 section_iterator MachOObjectFile::section_begin() const {
1032 return section_iterator(SectionRef(DRI, this));
1035 section_iterator MachOObjectFile::section_end() const {
1037 DRI.d.a = Sections.size();
1038 return section_iterator(SectionRef(DRI, this));
1041 uint8_t MachOObjectFile::getBytesInAddress() const {
1042 return is64Bit() ? 8 : 4;
1045 StringRef MachOObjectFile::getFileFormatName() const {
1046 unsigned CPUType = getCPUType(this);
1049 case llvm::MachO::CPU_TYPE_I386:
1050 return "Mach-O 32-bit i386";
1051 case llvm::MachO::CPU_TYPE_ARM:
1052 return "Mach-O arm";
1053 case llvm::MachO::CPU_TYPE_POWERPC:
1054 return "Mach-O 32-bit ppc";
1056 return "Mach-O 32-bit unknown";
1061 case llvm::MachO::CPU_TYPE_X86_64:
1062 return "Mach-O 64-bit x86-64";
1063 case llvm::MachO::CPU_TYPE_ARM64:
1064 return "Mach-O arm64";
1065 case llvm::MachO::CPU_TYPE_POWERPC64:
1066 return "Mach-O 64-bit ppc64";
1068 return "Mach-O 64-bit unknown";
1072 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1074 case llvm::MachO::CPU_TYPE_I386:
1076 case llvm::MachO::CPU_TYPE_X86_64:
1077 return Triple::x86_64;
1078 case llvm::MachO::CPU_TYPE_ARM:
1080 case llvm::MachO::CPU_TYPE_ARM64:
1081 return Triple::aarch64;
1082 case llvm::MachO::CPU_TYPE_POWERPC:
1084 case llvm::MachO::CPU_TYPE_POWERPC64:
1085 return Triple::ppc64;
1087 return Triple::UnknownArch;
1091 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1092 const char **McpuDefault) {
1094 *McpuDefault = nullptr;
1097 case MachO::CPU_TYPE_I386:
1098 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1099 case MachO::CPU_SUBTYPE_I386_ALL:
1100 return Triple("i386-apple-darwin");
1104 case MachO::CPU_TYPE_X86_64:
1105 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1106 case MachO::CPU_SUBTYPE_X86_64_ALL:
1107 return Triple("x86_64-apple-darwin");
1108 case MachO::CPU_SUBTYPE_X86_64_H:
1109 return Triple("x86_64h-apple-darwin");
1113 case MachO::CPU_TYPE_ARM:
1114 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1115 case MachO::CPU_SUBTYPE_ARM_V4T:
1116 return Triple("armv4t-apple-darwin");
1117 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1118 return Triple("armv5e-apple-darwin");
1119 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1120 return Triple("xscale-apple-darwin");
1121 case MachO::CPU_SUBTYPE_ARM_V6:
1122 return Triple("armv6-apple-darwin");
1123 case MachO::CPU_SUBTYPE_ARM_V6M:
1125 *McpuDefault = "cortex-m0";
1126 return Triple("armv6m-apple-darwin");
1127 case MachO::CPU_SUBTYPE_ARM_V7:
1128 return Triple("armv7-apple-darwin");
1129 case MachO::CPU_SUBTYPE_ARM_V7EM:
1131 *McpuDefault = "cortex-m4";
1132 return Triple("armv7em-apple-darwin");
1133 case MachO::CPU_SUBTYPE_ARM_V7K:
1134 return Triple("armv7k-apple-darwin");
1135 case MachO::CPU_SUBTYPE_ARM_V7M:
1137 *McpuDefault = "cortex-m3";
1138 return Triple("armv7m-apple-darwin");
1139 case MachO::CPU_SUBTYPE_ARM_V7S:
1140 return Triple("armv7s-apple-darwin");
1144 case MachO::CPU_TYPE_ARM64:
1145 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1146 case MachO::CPU_SUBTYPE_ARM64_ALL:
1147 return Triple("arm64-apple-darwin");
1151 case MachO::CPU_TYPE_POWERPC:
1152 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1153 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1154 return Triple("ppc-apple-darwin");
1158 case MachO::CPU_TYPE_POWERPC64:
1159 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1160 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1161 return Triple("ppc64-apple-darwin");
1170 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1171 const char **McpuDefault) {
1173 *McpuDefault = nullptr;
1176 case MachO::CPU_TYPE_ARM:
1177 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1178 case MachO::CPU_SUBTYPE_ARM_V4T:
1179 return Triple("thumbv4t-apple-darwin");
1180 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1181 return Triple("thumbv5e-apple-darwin");
1182 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1183 return Triple("xscale-apple-darwin");
1184 case MachO::CPU_SUBTYPE_ARM_V6:
1185 return Triple("thumbv6-apple-darwin");
1186 case MachO::CPU_SUBTYPE_ARM_V6M:
1188 *McpuDefault = "cortex-m0";
1189 return Triple("thumbv6m-apple-darwin");
1190 case MachO::CPU_SUBTYPE_ARM_V7:
1191 return Triple("thumbv7-apple-darwin");
1192 case MachO::CPU_SUBTYPE_ARM_V7EM:
1194 *McpuDefault = "cortex-m4";
1195 return Triple("thumbv7em-apple-darwin");
1196 case MachO::CPU_SUBTYPE_ARM_V7K:
1197 return Triple("thumbv7k-apple-darwin");
1198 case MachO::CPU_SUBTYPE_ARM_V7M:
1200 *McpuDefault = "cortex-m3";
1201 return Triple("thumbv7m-apple-darwin");
1202 case MachO::CPU_SUBTYPE_ARM_V7S:
1203 return Triple("thumbv7s-apple-darwin");
1212 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1213 const char **McpuDefault,
1214 Triple *ThumbTriple) {
1215 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1216 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1221 Triple MachOObjectFile::getHostArch() {
1222 return Triple(sys::getDefaultTargetTriple());
1225 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1226 return StringSwitch<bool>(ArchFlag)
1228 .Case("x86_64", true)
1229 .Case("x86_64h", true)
1230 .Case("armv4t", true)
1232 .Case("armv5e", true)
1233 .Case("armv6", true)
1234 .Case("armv6m", true)
1235 .Case("armv7em", true)
1236 .Case("armv7k", true)
1237 .Case("armv7m", true)
1238 .Case("armv7s", true)
1239 .Case("arm64", true)
1241 .Case("ppc64", true)
1245 unsigned MachOObjectFile::getArch() const {
1246 return getArch(getCPUType(this));
1249 Triple MachOObjectFile::getArch(const char **McpuDefault,
1250 Triple *ThumbTriple) const {
1251 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1252 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1255 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1258 return section_rel_begin(DRI);
1261 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1264 return section_rel_end(DRI);
1267 dice_iterator MachOObjectFile::begin_dices() const {
1269 if (!DataInCodeLoadCmd)
1270 return dice_iterator(DiceRef(DRI, this));
1272 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1273 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1274 return dice_iterator(DiceRef(DRI, this));
1277 dice_iterator MachOObjectFile::end_dices() const {
1279 if (!DataInCodeLoadCmd)
1280 return dice_iterator(DiceRef(DRI, this));
1282 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1283 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1284 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1285 return dice_iterator(DiceRef(DRI, this));
1288 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1289 : Trie(T), Malformed(false), Done(false) { }
1291 void ExportEntry::moveToFirst() {
1293 pushDownUntilBottom();
1296 void ExportEntry::moveToEnd() {
1301 bool ExportEntry::operator==(const ExportEntry &Other) const {
1302 // Common case, one at end, other iterating from begin.
1303 if (Done || Other.Done)
1304 return (Done == Other.Done);
1305 // Not equal if different stack sizes.
1306 if (Stack.size() != Other.Stack.size())
1308 // Not equal if different cumulative strings.
1309 if (!CumulativeString.equals(Other.CumulativeString))
1311 // Equal if all nodes in both stacks match.
1312 for (unsigned i=0; i < Stack.size(); ++i) {
1313 if (Stack[i].Start != Other.Stack[i].Start)
1319 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1321 uint64_t Result = decodeULEB128(Ptr, &Count);
1323 if (Ptr > Trie.end()) {
1330 StringRef ExportEntry::name() const {
1331 return CumulativeString;
1334 uint64_t ExportEntry::flags() const {
1335 return Stack.back().Flags;
1338 uint64_t ExportEntry::address() const {
1339 return Stack.back().Address;
1342 uint64_t ExportEntry::other() const {
1343 return Stack.back().Other;
1346 StringRef ExportEntry::otherName() const {
1347 const char* ImportName = Stack.back().ImportName;
1349 return StringRef(ImportName);
1353 uint32_t ExportEntry::nodeOffset() const {
1354 return Stack.back().Start - Trie.begin();
1357 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1358 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1359 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1360 ParentStringLength(0), IsExportNode(false) {
1363 void ExportEntry::pushNode(uint64_t offset) {
1364 const uint8_t *Ptr = Trie.begin() + offset;
1365 NodeState State(Ptr);
1366 uint64_t ExportInfoSize = readULEB128(State.Current);
1367 State.IsExportNode = (ExportInfoSize != 0);
1368 const uint8_t* Children = State.Current + ExportInfoSize;
1369 if (State.IsExportNode) {
1370 State.Flags = readULEB128(State.Current);
1371 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1373 State.Other = readULEB128(State.Current); // dylib ordinal
1374 State.ImportName = reinterpret_cast<const char*>(State.Current);
1376 State.Address = readULEB128(State.Current);
1377 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1378 State.Other = readULEB128(State.Current);
1381 State.ChildCount = *Children;
1382 State.Current = Children + 1;
1383 State.NextChildIndex = 0;
1384 State.ParentStringLength = CumulativeString.size();
1385 Stack.push_back(State);
1388 void ExportEntry::pushDownUntilBottom() {
1389 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1390 NodeState &Top = Stack.back();
1391 CumulativeString.resize(Top.ParentStringLength);
1392 for (;*Top.Current != 0; Top.Current++) {
1393 char C = *Top.Current;
1394 CumulativeString.push_back(C);
1397 uint64_t childNodeIndex = readULEB128(Top.Current);
1398 Top.NextChildIndex += 1;
1399 pushNode(childNodeIndex);
1401 if (!Stack.back().IsExportNode) {
1407 // We have a trie data structure and need a way to walk it that is compatible
1408 // with the C++ iterator model. The solution is a non-recursive depth first
1409 // traversal where the iterator contains a stack of parent nodes along with a
1410 // string that is the accumulation of all edge strings along the parent chain
1413 // There is one "export" node for each exported symbol. But because some
1414 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1415 // node may have child nodes too.
1417 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1418 // child until hitting a node with no children (which is an export node or
1419 // else the trie is malformed). On the way down, each node is pushed on the
1420 // stack ivar. If there is no more ways down, it pops up one and tries to go
1421 // down a sibling path until a childless node is reached.
1422 void ExportEntry::moveNext() {
1423 if (Stack.empty() || !Stack.back().IsExportNode) {
1430 while (!Stack.empty()) {
1431 NodeState &Top = Stack.back();
1432 if (Top.NextChildIndex < Top.ChildCount) {
1433 pushDownUntilBottom();
1434 // Now at the next export node.
1437 if (Top.IsExportNode) {
1438 // This node has no children but is itself an export node.
1439 CumulativeString.resize(Top.ParentStringLength);
1448 iterator_range<export_iterator>
1449 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1450 ExportEntry Start(Trie);
1451 if (Trie.size() == 0)
1454 Start.moveToFirst();
1456 ExportEntry Finish(Trie);
1459 return iterator_range<export_iterator>(export_iterator(Start),
1460 export_iterator(Finish));
1463 iterator_range<export_iterator> MachOObjectFile::exports() const {
1464 return exports(getDyldInfoExportsTrie());
1468 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1469 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1470 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1471 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1473 void MachORebaseEntry::moveToFirst() {
1474 Ptr = Opcodes.begin();
1478 void MachORebaseEntry::moveToEnd() {
1479 Ptr = Opcodes.end();
1480 RemainingLoopCount = 0;
1484 void MachORebaseEntry::moveNext() {
1485 // If in the middle of some loop, move to next rebasing in loop.
1486 SegmentOffset += AdvanceAmount;
1487 if (RemainingLoopCount) {
1488 --RemainingLoopCount;
1491 if (Ptr == Opcodes.end()) {
1496 while (More && !Malformed) {
1497 // Parse next opcode and set up next loop.
1498 uint8_t Byte = *Ptr++;
1499 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1500 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1502 case MachO::REBASE_OPCODE_DONE:
1506 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1508 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1509 RebaseType = ImmValue;
1512 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1513 << "RebaseType=" << (int) RebaseType << "\n");
1515 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1516 SegmentIndex = ImmValue;
1517 SegmentOffset = readULEB128();
1520 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1521 << "SegmentIndex=" << SegmentIndex << ", "
1522 << format("SegmentOffset=0x%06X", SegmentOffset)
1525 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1526 SegmentOffset += readULEB128();
1527 DEBUG_WITH_TYPE("mach-o-rebase",
1528 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1529 << format("SegmentOffset=0x%06X",
1530 SegmentOffset) << "\n");
1532 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1533 SegmentOffset += ImmValue * PointerSize;
1534 DEBUG_WITH_TYPE("mach-o-rebase",
1535 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1536 << format("SegmentOffset=0x%06X",
1537 SegmentOffset) << "\n");
1539 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1540 AdvanceAmount = PointerSize;
1541 RemainingLoopCount = ImmValue - 1;
1544 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1545 << format("SegmentOffset=0x%06X", SegmentOffset)
1546 << ", AdvanceAmount=" << AdvanceAmount
1547 << ", RemainingLoopCount=" << RemainingLoopCount
1550 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1551 AdvanceAmount = PointerSize;
1552 RemainingLoopCount = readULEB128() - 1;
1555 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1556 << format("SegmentOffset=0x%06X", SegmentOffset)
1557 << ", AdvanceAmount=" << AdvanceAmount
1558 << ", RemainingLoopCount=" << RemainingLoopCount
1561 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1562 AdvanceAmount = readULEB128() + PointerSize;
1563 RemainingLoopCount = 0;
1566 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1567 << format("SegmentOffset=0x%06X", SegmentOffset)
1568 << ", AdvanceAmount=" << AdvanceAmount
1569 << ", RemainingLoopCount=" << RemainingLoopCount
1572 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1573 RemainingLoopCount = readULEB128() - 1;
1574 AdvanceAmount = readULEB128() + PointerSize;
1577 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1578 << format("SegmentOffset=0x%06X", SegmentOffset)
1579 << ", AdvanceAmount=" << AdvanceAmount
1580 << ", RemainingLoopCount=" << RemainingLoopCount
1589 uint64_t MachORebaseEntry::readULEB128() {
1591 uint64_t Result = decodeULEB128(Ptr, &Count);
1593 if (Ptr > Opcodes.end()) {
1594 Ptr = Opcodes.end();
1600 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1602 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1604 StringRef MachORebaseEntry::typeName() const {
1605 switch (RebaseType) {
1606 case MachO::REBASE_TYPE_POINTER:
1608 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1609 return "text abs32";
1610 case MachO::REBASE_TYPE_TEXT_PCREL32:
1611 return "text rel32";
1616 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1617 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1618 return (Ptr == Other.Ptr) &&
1619 (RemainingLoopCount == Other.RemainingLoopCount) &&
1620 (Done == Other.Done);
1623 iterator_range<rebase_iterator>
1624 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1625 MachORebaseEntry Start(Opcodes, is64);
1626 Start.moveToFirst();
1628 MachORebaseEntry Finish(Opcodes, is64);
1631 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1632 rebase_iterator(Finish));
1635 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1636 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1640 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1642 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1643 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1644 BindType(0), PointerSize(is64Bit ? 8 : 4),
1645 TableKind(BK), Malformed(false), Done(false) {}
1647 void MachOBindEntry::moveToFirst() {
1648 Ptr = Opcodes.begin();
1652 void MachOBindEntry::moveToEnd() {
1653 Ptr = Opcodes.end();
1654 RemainingLoopCount = 0;
1658 void MachOBindEntry::moveNext() {
1659 // If in the middle of some loop, move to next binding in loop.
1660 SegmentOffset += AdvanceAmount;
1661 if (RemainingLoopCount) {
1662 --RemainingLoopCount;
1665 if (Ptr == Opcodes.end()) {
1670 while (More && !Malformed) {
1671 // Parse next opcode and set up next loop.
1672 uint8_t Byte = *Ptr++;
1673 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1674 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1675 int8_t SignExtended;
1676 const uint8_t *SymStart;
1678 case MachO::BIND_OPCODE_DONE:
1679 if (TableKind == Kind::Lazy) {
1680 // Lazying bindings have a DONE opcode between entries. Need to ignore
1681 // it to advance to next entry. But need not if this is last entry.
1682 bool NotLastEntry = false;
1683 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1685 NotLastEntry = true;
1694 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1696 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1700 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1701 << "Ordinal=" << Ordinal << "\n");
1703 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1704 Ordinal = readULEB128();
1707 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1708 << "Ordinal=" << Ordinal << "\n");
1710 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1712 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1713 Ordinal = SignExtended;
1718 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1719 << "Ordinal=" << Ordinal << "\n");
1721 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1727 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1732 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1733 << "SymbolName=" << SymbolName << "\n");
1734 if (TableKind == Kind::Weak) {
1735 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1739 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1740 BindType = ImmValue;
1743 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1744 << "BindType=" << (int)BindType << "\n");
1746 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1747 Addend = readSLEB128();
1748 if (TableKind == Kind::Lazy)
1752 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1753 << "Addend=" << Addend << "\n");
1755 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1756 SegmentIndex = ImmValue;
1757 SegmentOffset = readULEB128();
1760 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1761 << "SegmentIndex=" << SegmentIndex << ", "
1762 << format("SegmentOffset=0x%06X", SegmentOffset)
1765 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1766 SegmentOffset += readULEB128();
1767 DEBUG_WITH_TYPE("mach-o-bind",
1768 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1769 << format("SegmentOffset=0x%06X",
1770 SegmentOffset) << "\n");
1772 case MachO::BIND_OPCODE_DO_BIND:
1773 AdvanceAmount = PointerSize;
1774 RemainingLoopCount = 0;
1775 DEBUG_WITH_TYPE("mach-o-bind",
1776 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1777 << format("SegmentOffset=0x%06X",
1778 SegmentOffset) << "\n");
1780 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1781 AdvanceAmount = readULEB128() + PointerSize;
1782 RemainingLoopCount = 0;
1783 if (TableKind == Kind::Lazy)
1787 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1788 << format("SegmentOffset=0x%06X", SegmentOffset)
1789 << ", AdvanceAmount=" << AdvanceAmount
1790 << ", RemainingLoopCount=" << RemainingLoopCount
1793 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1794 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1795 RemainingLoopCount = 0;
1796 if (TableKind == Kind::Lazy)
1798 DEBUG_WITH_TYPE("mach-o-bind",
1800 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1801 << format("SegmentOffset=0x%06X",
1802 SegmentOffset) << "\n");
1804 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1805 RemainingLoopCount = readULEB128() - 1;
1806 AdvanceAmount = readULEB128() + PointerSize;
1807 if (TableKind == Kind::Lazy)
1811 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1812 << format("SegmentOffset=0x%06X", SegmentOffset)
1813 << ", AdvanceAmount=" << AdvanceAmount
1814 << ", RemainingLoopCount=" << RemainingLoopCount
1823 uint64_t MachOBindEntry::readULEB128() {
1825 uint64_t Result = decodeULEB128(Ptr, &Count);
1827 if (Ptr > Opcodes.end()) {
1828 Ptr = Opcodes.end();
1834 int64_t MachOBindEntry::readSLEB128() {
1836 int64_t Result = decodeSLEB128(Ptr, &Count);
1838 if (Ptr > Opcodes.end()) {
1839 Ptr = Opcodes.end();
1846 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1848 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1850 StringRef MachOBindEntry::typeName() const {
1852 case MachO::BIND_TYPE_POINTER:
1854 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1855 return "text abs32";
1856 case MachO::BIND_TYPE_TEXT_PCREL32:
1857 return "text rel32";
1862 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1864 int64_t MachOBindEntry::addend() const { return Addend; }
1866 uint32_t MachOBindEntry::flags() const { return Flags; }
1868 int MachOBindEntry::ordinal() const { return Ordinal; }
1870 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1871 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1872 return (Ptr == Other.Ptr) &&
1873 (RemainingLoopCount == Other.RemainingLoopCount) &&
1874 (Done == Other.Done);
1877 iterator_range<bind_iterator>
1878 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1879 MachOBindEntry::Kind BKind) {
1880 MachOBindEntry Start(Opcodes, is64, BKind);
1881 Start.moveToFirst();
1883 MachOBindEntry Finish(Opcodes, is64, BKind);
1886 return iterator_range<bind_iterator>(bind_iterator(Start),
1887 bind_iterator(Finish));
1890 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1891 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1892 MachOBindEntry::Kind::Regular);
1895 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1896 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1897 MachOBindEntry::Kind::Lazy);
1900 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1901 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1902 MachOBindEntry::Kind::Weak);
1905 MachOObjectFile::load_command_iterator
1906 MachOObjectFile::begin_load_commands() const {
1907 return LoadCommands.begin();
1910 MachOObjectFile::load_command_iterator
1911 MachOObjectFile::end_load_commands() const {
1912 return LoadCommands.end();
1915 iterator_range<MachOObjectFile::load_command_iterator>
1916 MachOObjectFile::load_commands() const {
1917 return iterator_range<load_command_iterator>(begin_load_commands(),
1918 end_load_commands());
1922 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1923 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1924 return parseSegmentOrSectionName(Raw.data());
1928 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1929 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1930 const section_base *Base =
1931 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1932 return makeArrayRef(Base->sectname);
1936 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1937 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1938 const section_base *Base =
1939 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1940 return makeArrayRef(Base->segname);
1944 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1946 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1948 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1951 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1952 const MachO::any_relocation_info &RE) const {
1953 if (isLittleEndian())
1954 return RE.r_word1 & 0xffffff;
1955 return RE.r_word1 >> 8;
1958 bool MachOObjectFile::getPlainRelocationExternal(
1959 const MachO::any_relocation_info &RE) const {
1960 if (isLittleEndian())
1961 return (RE.r_word1 >> 27) & 1;
1962 return (RE.r_word1 >> 4) & 1;
1965 bool MachOObjectFile::getScatteredRelocationScattered(
1966 const MachO::any_relocation_info &RE) const {
1967 return RE.r_word0 >> 31;
1970 uint32_t MachOObjectFile::getScatteredRelocationValue(
1971 const MachO::any_relocation_info &RE) const {
1975 uint32_t MachOObjectFile::getScatteredRelocationType(
1976 const MachO::any_relocation_info &RE) const {
1977 return (RE.r_word0 >> 24) & 0xf;
1980 unsigned MachOObjectFile::getAnyRelocationAddress(
1981 const MachO::any_relocation_info &RE) const {
1982 if (isRelocationScattered(RE))
1983 return getScatteredRelocationAddress(RE);
1984 return getPlainRelocationAddress(RE);
1987 unsigned MachOObjectFile::getAnyRelocationPCRel(
1988 const MachO::any_relocation_info &RE) const {
1989 if (isRelocationScattered(RE))
1990 return getScatteredRelocationPCRel(this, RE);
1991 return getPlainRelocationPCRel(this, RE);
1994 unsigned MachOObjectFile::getAnyRelocationLength(
1995 const MachO::any_relocation_info &RE) const {
1996 if (isRelocationScattered(RE))
1997 return getScatteredRelocationLength(RE);
1998 return getPlainRelocationLength(this, RE);
2002 MachOObjectFile::getAnyRelocationType(
2003 const MachO::any_relocation_info &RE) const {
2004 if (isRelocationScattered(RE))
2005 return getScatteredRelocationType(RE);
2006 return getPlainRelocationType(this, RE);
2010 MachOObjectFile::getAnyRelocationSection(
2011 const MachO::any_relocation_info &RE) const {
2012 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2013 return *section_end();
2014 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
2017 return SectionRef(DRI, this);
2020 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2021 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2022 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2025 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2026 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2027 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2030 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2031 unsigned Index) const {
2032 const char *Sec = getSectionPtr(this, L, Index);
2033 return getStruct<MachO::section>(this, Sec);
2036 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2037 unsigned Index) const {
2038 const char *Sec = getSectionPtr(this, L, Index);
2039 return getStruct<MachO::section_64>(this, Sec);
2043 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2044 const char *P = reinterpret_cast<const char *>(DRI.p);
2045 return getStruct<MachO::nlist>(this, P);
2049 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2050 const char *P = reinterpret_cast<const char *>(DRI.p);
2051 return getStruct<MachO::nlist_64>(this, P);
2054 MachO::linkedit_data_command
2055 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2056 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2059 MachO::segment_command
2060 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2061 return getStruct<MachO::segment_command>(this, L.Ptr);
2064 MachO::segment_command_64
2065 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2066 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2069 MachO::linker_option_command
2070 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2071 return getStruct<MachO::linker_option_command>(this, L.Ptr);
2074 MachO::version_min_command
2075 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2076 return getStruct<MachO::version_min_command>(this, L.Ptr);
2079 MachO::dylib_command
2080 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2081 return getStruct<MachO::dylib_command>(this, L.Ptr);
2084 MachO::dyld_info_command
2085 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2086 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2089 MachO::dylinker_command
2090 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2091 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2095 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2096 return getStruct<MachO::uuid_command>(this, L.Ptr);
2099 MachO::rpath_command
2100 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2101 return getStruct<MachO::rpath_command>(this, L.Ptr);
2104 MachO::source_version_command
2105 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2106 return getStruct<MachO::source_version_command>(this, L.Ptr);
2109 MachO::entry_point_command
2110 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2111 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2114 MachO::encryption_info_command
2115 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2116 return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2119 MachO::encryption_info_command_64
2120 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2121 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2124 MachO::sub_framework_command
2125 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2126 return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2129 MachO::sub_umbrella_command
2130 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2131 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2134 MachO::sub_library_command
2135 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2136 return getStruct<MachO::sub_library_command>(this, L.Ptr);
2139 MachO::sub_client_command
2140 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2141 return getStruct<MachO::sub_client_command>(this, L.Ptr);
2144 MachO::routines_command
2145 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2146 return getStruct<MachO::routines_command>(this, L.Ptr);
2149 MachO::routines_command_64
2150 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2151 return getStruct<MachO::routines_command_64>(this, L.Ptr);
2154 MachO::thread_command
2155 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2156 return getStruct<MachO::thread_command>(this, L.Ptr);
2159 MachO::any_relocation_info
2160 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2165 MachO::section_64 Sect = getSection64(Sec);
2166 Offset = Sect.reloff;
2168 MachO::section Sect = getSection(Sec);
2169 Offset = Sect.reloff;
2172 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2173 getPtr(this, Offset)) + Rel.d.b;
2174 return getStruct<MachO::any_relocation_info>(
2175 this, reinterpret_cast<const char *>(P));
2178 MachO::data_in_code_entry
2179 MachOObjectFile::getDice(DataRefImpl Rel) const {
2180 const char *P = reinterpret_cast<const char *>(Rel.p);
2181 return getStruct<MachO::data_in_code_entry>(this, P);
2184 const MachO::mach_header &MachOObjectFile::getHeader() const {
2188 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2193 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2194 const MachO::dysymtab_command &DLC,
2195 unsigned Index) const {
2196 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2197 return getStruct<uint32_t>(this, getPtr(this, Offset));
2200 MachO::data_in_code_entry
2201 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2202 unsigned Index) const {
2203 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2204 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2207 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2209 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2211 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2212 MachO::symtab_command Cmd;
2213 Cmd.cmd = MachO::LC_SYMTAB;
2214 Cmd.cmdsize = sizeof(MachO::symtab_command);
2222 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2223 if (DysymtabLoadCmd)
2224 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2226 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2227 MachO::dysymtab_command Cmd;
2228 Cmd.cmd = MachO::LC_DYSYMTAB;
2229 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2240 Cmd.extrefsymoff = 0;
2241 Cmd.nextrefsyms = 0;
2242 Cmd.indirectsymoff = 0;
2243 Cmd.nindirectsyms = 0;
2251 MachO::linkedit_data_command
2252 MachOObjectFile::getDataInCodeLoadCommand() const {
2253 if (DataInCodeLoadCmd)
2254 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2256 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2257 MachO::linkedit_data_command Cmd;
2258 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2259 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2265 MachO::linkedit_data_command
2266 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2267 if (LinkOptHintsLoadCmd)
2268 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2270 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2272 MachO::linkedit_data_command Cmd;
2273 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2274 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2280 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2281 if (!DyldInfoLoadCmd)
2282 return ArrayRef<uint8_t>();
2284 MachO::dyld_info_command DyldInfo
2285 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2286 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2287 getPtr(this, DyldInfo.rebase_off));
2288 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2291 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2292 if (!DyldInfoLoadCmd)
2293 return ArrayRef<uint8_t>();
2295 MachO::dyld_info_command DyldInfo
2296 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2297 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2298 getPtr(this, DyldInfo.bind_off));
2299 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2302 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2303 if (!DyldInfoLoadCmd)
2304 return ArrayRef<uint8_t>();
2306 MachO::dyld_info_command DyldInfo
2307 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2308 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2309 getPtr(this, DyldInfo.weak_bind_off));
2310 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2313 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2314 if (!DyldInfoLoadCmd)
2315 return ArrayRef<uint8_t>();
2317 MachO::dyld_info_command DyldInfo
2318 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2319 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2320 getPtr(this, DyldInfo.lazy_bind_off));
2321 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2324 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2325 if (!DyldInfoLoadCmd)
2326 return ArrayRef<uint8_t>();
2328 MachO::dyld_info_command DyldInfo
2329 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2330 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2331 getPtr(this, DyldInfo.export_off));
2332 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2335 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2337 return ArrayRef<uint8_t>();
2338 // Returning a pointer is fine as uuid doesn't need endian swapping.
2339 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2340 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2343 StringRef MachOObjectFile::getStringTableData() const {
2344 MachO::symtab_command S = getSymtabLoadCommand();
2345 return getData().substr(S.stroff, S.strsize);
2348 bool MachOObjectFile::is64Bit() const {
2349 return getType() == getMachOType(false, true) ||
2350 getType() == getMachOType(true, true);
2353 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2354 SmallVectorImpl<uint64_t> &Out) const {
2355 DataExtractor extractor(ObjectFile::getData(), true, 0);
2357 uint32_t offset = Index;
2359 while (uint64_t delta = extractor.getULEB128(&offset)) {
2361 Out.push_back(data);
2365 bool MachOObjectFile::isRelocatableObject() const {
2366 return getHeader().filetype == MachO::MH_OBJECT;
2369 ErrorOr<std::unique_ptr<MachOObjectFile>>
2370 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2371 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2373 std::unique_ptr<MachOObjectFile> Ret;
2374 if (Magic == "\xFE\xED\xFA\xCE")
2375 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2376 else if (Magic == "\xCE\xFA\xED\xFE")
2377 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2378 else if (Magic == "\xFE\xED\xFA\xCF")
2379 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2380 else if (Magic == "\xCF\xFA\xED\xFE")
2381 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2383 return object_error::parse_failed;
2387 return std::move(Ret);