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 std::error_code();
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 std::error_code();
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 std::error_code();
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 = UnknownAddress;
382 MachO::nlist Entry = getSymbolTableEntry(Symb);
383 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
385 Res = UnknownAddress;
389 return std::error_code();
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::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
403 getSymbolAddress(DRI, Value);
407 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
408 SymbolRef::Type &Res) const {
409 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
410 uint8_t n_type = Entry.n_type;
412 Res = SymbolRef::ST_Other;
414 // If this is a STAB debugging symbol, we can do nothing more.
415 if (n_type & MachO::N_STAB) {
416 Res = SymbolRef::ST_Debug;
417 return std::error_code();
420 switch (n_type & MachO::N_TYPE) {
422 Res = SymbolRef::ST_Unknown;
425 Res = SymbolRef::ST_Function;
428 return std::error_code();
431 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
432 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
434 uint8_t MachOType = Entry.n_type;
435 uint16_t MachOFlags = Entry.n_desc;
437 uint32_t Result = SymbolRef::SF_None;
439 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
440 Result |= SymbolRef::SF_Undefined;
442 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
443 Result |= SymbolRef::SF_Indirect;
445 if (MachOType & MachO::N_STAB)
446 Result |= SymbolRef::SF_FormatSpecific;
448 if (MachOType & MachO::N_EXT) {
449 Result |= SymbolRef::SF_Global;
450 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
452 getSymbolAddress(DRI, Value);
453 if (Value && Value != UnknownAddress)
454 Result |= SymbolRef::SF_Common;
457 if (!(MachOType & MachO::N_PEXT))
458 Result |= SymbolRef::SF_Exported;
461 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
462 Result |= SymbolRef::SF_Weak;
464 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
465 Result |= SymbolRef::SF_Thumb;
467 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
468 Result |= SymbolRef::SF_Absolute;
473 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
474 section_iterator &Res) const {
475 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
476 uint8_t index = Entry.n_sect;
483 if (DRI.d.a >= Sections.size())
484 report_fatal_error("getSymbolSection: Invalid section index.");
485 Res = section_iterator(SectionRef(DRI, this));
488 return std::error_code();
491 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
495 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
496 StringRef &Result) const {
497 ArrayRef<char> Raw = getSectionRawName(Sec);
498 Result = parseSegmentOrSectionName(Raw.data());
499 return std::error_code();
502 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
504 return getSection64(Sec).addr;
505 return getSection(Sec).addr;
508 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
510 return getSection64(Sec).size;
511 return getSection(Sec).size;
514 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
515 StringRef &Res) const {
520 MachO::section_64 Sect = getSection64(Sec);
521 Offset = Sect.offset;
524 MachO::section Sect = getSection(Sec);
525 Offset = Sect.offset;
529 Res = this->getData().substr(Offset, Size);
530 return std::error_code();
533 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
536 MachO::section_64 Sect = getSection64(Sec);
539 MachO::section Sect = getSection(Sec);
543 return uint64_t(1) << Align;
546 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
547 uint32_t Flags = getSectionFlags(this, Sec);
548 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
551 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
552 uint32_t Flags = getSectionFlags(this, Sec);
553 unsigned SectionType = Flags & MachO::SECTION_TYPE;
554 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
555 !(SectionType == MachO::S_ZEROFILL ||
556 SectionType == MachO::S_GB_ZEROFILL);
559 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
560 uint32_t Flags = getSectionFlags(this, Sec);
561 unsigned SectionType = Flags & MachO::SECTION_TYPE;
562 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
563 (SectionType == MachO::S_ZEROFILL ||
564 SectionType == MachO::S_GB_ZEROFILL);
567 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
568 // FIXME: Unimplemented.
572 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
573 DataRefImpl Symb) const {
575 this->getSymbolType(Symb, ST);
576 if (ST == SymbolRef::ST_Unknown)
579 uint64_t SectBegin = getSectionAddress(Sec);
580 uint64_t SectEnd = getSectionSize(Sec);
581 SectEnd += SectBegin;
584 getSymbolAddress(Symb, SymAddr);
585 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
588 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
592 return relocation_iterator(RelocationRef(Ret, this));
596 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
599 MachO::section_64 Sect = getSection64(Sec);
602 MachO::section Sect = getSection(Sec);
609 return relocation_iterator(RelocationRef(Ret, this));
612 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
616 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
617 uint64_t &Res) const {
619 getRelocationOffset(Rel, Offset);
623 uint64_t SecAddress = getSectionAddress(Sec);
624 Res = SecAddress + Offset;
625 return std::error_code();
628 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
629 uint64_t &Res) const {
630 assert(getHeader().filetype == MachO::MH_OBJECT &&
631 "Only implemented for MH_OBJECT");
632 MachO::any_relocation_info RE = getRelocation(Rel);
633 Res = getAnyRelocationAddress(RE);
634 return std::error_code();
638 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
639 MachO::any_relocation_info RE = getRelocation(Rel);
640 if (isRelocationScattered(RE))
643 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
644 bool isExtern = getPlainRelocationExternal(RE);
648 MachO::symtab_command S = getSymtabLoadCommand();
649 unsigned SymbolTableEntrySize = is64Bit() ?
650 sizeof(MachO::nlist_64) :
651 sizeof(MachO::nlist);
652 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
654 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
655 return symbol_iterator(SymbolRef(Sym, this));
659 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
660 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
663 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
664 uint64_t &Res) const {
665 MachO::any_relocation_info RE = getRelocation(Rel);
666 Res = getAnyRelocationType(RE);
667 return std::error_code();
671 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
672 SmallVectorImpl<char> &Result) const {
675 getRelocationType(Rel, RType);
677 unsigned Arch = this->getArch();
681 static const char *const Table[] = {
682 "GENERIC_RELOC_VANILLA",
683 "GENERIC_RELOC_PAIR",
684 "GENERIC_RELOC_SECTDIFF",
685 "GENERIC_RELOC_PB_LA_PTR",
686 "GENERIC_RELOC_LOCAL_SECTDIFF",
687 "GENERIC_RELOC_TLV" };
695 case Triple::x86_64: {
696 static const char *const Table[] = {
697 "X86_64_RELOC_UNSIGNED",
698 "X86_64_RELOC_SIGNED",
699 "X86_64_RELOC_BRANCH",
700 "X86_64_RELOC_GOT_LOAD",
702 "X86_64_RELOC_SUBTRACTOR",
703 "X86_64_RELOC_SIGNED_1",
704 "X86_64_RELOC_SIGNED_2",
705 "X86_64_RELOC_SIGNED_4",
706 "X86_64_RELOC_TLV" };
715 static const char *const Table[] = {
718 "ARM_RELOC_SECTDIFF",
719 "ARM_RELOC_LOCAL_SECTDIFF",
720 "ARM_RELOC_PB_LA_PTR",
722 "ARM_THUMB_RELOC_BR22",
723 "ARM_THUMB_32BIT_BRANCH",
725 "ARM_RELOC_HALF_SECTDIFF" };
733 case Triple::aarch64: {
734 static const char *const Table[] = {
735 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
736 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
737 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
738 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
739 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
743 if (RType >= array_lengthof(Table))
750 static const char *const Table[] = {
759 "PPC_RELOC_SECTDIFF",
760 "PPC_RELOC_PB_LA_PTR",
761 "PPC_RELOC_HI16_SECTDIFF",
762 "PPC_RELOC_LO16_SECTDIFF",
763 "PPC_RELOC_HA16_SECTDIFF",
765 "PPC_RELOC_LO14_SECTDIFF",
766 "PPC_RELOC_LOCAL_SECTDIFF" };
774 case Triple::UnknownArch:
778 Result.append(res.begin(), res.end());
779 return std::error_code();
782 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
783 bool &Result) const {
784 unsigned Arch = getArch();
786 getRelocationType(Rel, Type);
790 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
792 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
793 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
794 } else if (Arch == Triple::x86_64) {
795 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
796 // an X86_64_RELOC_SUBTRACTOR.
797 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
798 DataRefImpl RelPrev = Rel;
801 getRelocationType(RelPrev, PrevType);
802 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
807 return std::error_code();
810 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
811 MachO::any_relocation_info RE = getRelocation(Rel);
812 return getAnyRelocationLength(RE);
816 // guessLibraryShortName() is passed a name of a dynamic library and returns a
817 // guess on what the short name is. Then name is returned as a substring of the
818 // StringRef Name passed in. The name of the dynamic library is recognized as
819 // a framework if it has one of the two following forms:
820 // Foo.framework/Versions/A/Foo
822 // Where A and Foo can be any string. And may contain a trailing suffix
823 // starting with an underbar. If the Name is recognized as a framework then
824 // isFramework is set to true else it is set to false. If the Name has a
825 // suffix then Suffix is set to the substring in Name that contains the suffix
826 // else it is set to a NULL StringRef.
828 // The Name of the dynamic library is recognized as a library name if it has
829 // one of the two following forms:
832 // The library may have a suffix trailing the name Foo of the form:
833 // libFoo_profile.A.dylib
834 // libFoo_profile.dylib
836 // The Name of the dynamic library is also recognized as a library name if it
837 // has the following form:
840 // If the Name of the dynamic library is none of the forms above then a NULL
841 // StringRef is returned.
843 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
846 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
847 size_t a, b, c, d, Idx;
850 Suffix = StringRef();
852 // Pull off the last component and make Foo point to it
854 if (a == Name.npos || a == 0)
856 Foo = Name.slice(a+1, Name.npos);
858 // Look for a suffix starting with a '_'
859 Idx = Foo.rfind('_');
860 if (Idx != Foo.npos && Foo.size() >= 2) {
861 Suffix = Foo.slice(Idx, Foo.npos);
862 Foo = Foo.slice(0, Idx);
865 // First look for the form Foo.framework/Foo
866 b = Name.rfind('/', a);
871 F = Name.slice(Idx, Idx + Foo.size());
872 DotFramework = Name.slice(Idx + Foo.size(),
873 Idx + Foo.size() + sizeof(".framework/")-1);
874 if (F == Foo && DotFramework == ".framework/") {
879 // Next look for the form Foo.framework/Versions/A/Foo
882 c = Name.rfind('/', b);
883 if (c == Name.npos || c == 0)
885 V = Name.slice(c+1, Name.npos);
886 if (!V.startswith("Versions/"))
888 d = Name.rfind('/', c);
893 F = Name.slice(Idx, Idx + Foo.size());
894 DotFramework = Name.slice(Idx + Foo.size(),
895 Idx + Foo.size() + sizeof(".framework/")-1);
896 if (F == Foo && DotFramework == ".framework/") {
902 // pull off the suffix after the "." and make a point to it
904 if (a == Name.npos || a == 0)
906 Dylib = Name.slice(a, Name.npos);
907 if (Dylib != ".dylib")
910 // First pull off the version letter for the form Foo.A.dylib if any.
912 Dot = Name.slice(a-2, a-1);
917 b = Name.rfind('/', a);
922 // ignore any suffix after an underbar like Foo_profile.A.dylib
923 Idx = Name.find('_', b);
924 if (Idx != Name.npos && Idx != b) {
925 Lib = Name.slice(b, Idx);
926 Suffix = Name.slice(Idx, a);
929 Lib = Name.slice(b, a);
930 // There are incorrect library names of the form:
931 // libATS.A_profile.dylib so check for these.
932 if (Lib.size() >= 3) {
933 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
935 Lib = Lib.slice(0, Lib.size()-2);
940 Qtx = Name.slice(a, Name.npos);
943 b = Name.rfind('/', a);
945 Lib = Name.slice(0, a);
947 Lib = Name.slice(b+1, a);
948 // There are library names of the form: QT.A.qtx so check for these.
949 if (Lib.size() >= 3) {
950 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
952 Lib = Lib.slice(0, Lib.size()-2);
957 // getLibraryShortNameByIndex() is used to get the short name of the library
958 // for an undefined symbol in a linked Mach-O binary that was linked with the
959 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
960 // It is passed the index (0 - based) of the library as translated from
961 // GET_LIBRARY_ORDINAL (1 - based).
962 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
963 StringRef &Res) const {
964 if (Index >= Libraries.size())
965 return object_error::parse_failed;
967 // If the cache of LibrariesShortNames is not built up do that first for
968 // all the Libraries.
969 if (LibrariesShortNames.size() == 0) {
970 for (unsigned i = 0; i < Libraries.size(); i++) {
971 MachO::dylib_command D =
972 getStruct<MachO::dylib_command>(this, Libraries[i]);
973 if (D.dylib.name >= D.cmdsize)
974 return object_error::parse_failed;
975 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
976 StringRef Name = StringRef(P);
977 if (D.dylib.name+Name.size() >= D.cmdsize)
978 return object_error::parse_failed;
981 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
982 if (shortName.empty())
983 LibrariesShortNames.push_back(Name);
985 LibrariesShortNames.push_back(shortName);
989 Res = LibrariesShortNames[Index];
990 return std::error_code();
993 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
994 return getSymbolByIndex(0);
997 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1000 return basic_symbol_iterator(SymbolRef(DRI, this));
1002 MachO::symtab_command Symtab = getSymtabLoadCommand();
1003 unsigned SymbolTableEntrySize = is64Bit() ?
1004 sizeof(MachO::nlist_64) :
1005 sizeof(MachO::nlist);
1006 unsigned Offset = Symtab.symoff +
1007 Symtab.nsyms * SymbolTableEntrySize;
1008 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1009 return basic_symbol_iterator(SymbolRef(DRI, this));
1012 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1015 return basic_symbol_iterator(SymbolRef(DRI, this));
1017 MachO::symtab_command Symtab = getSymtabLoadCommand();
1018 if (Index >= Symtab.nsyms)
1019 report_fatal_error("Requested symbol index is out of range.");
1020 unsigned SymbolTableEntrySize =
1021 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1022 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1023 DRI.p += Index * SymbolTableEntrySize;
1024 return basic_symbol_iterator(SymbolRef(DRI, this));
1027 section_iterator MachOObjectFile::section_begin() const {
1029 return section_iterator(SectionRef(DRI, this));
1032 section_iterator MachOObjectFile::section_end() const {
1034 DRI.d.a = Sections.size();
1035 return section_iterator(SectionRef(DRI, this));
1038 uint8_t MachOObjectFile::getBytesInAddress() const {
1039 return is64Bit() ? 8 : 4;
1042 StringRef MachOObjectFile::getFileFormatName() const {
1043 unsigned CPUType = getCPUType(this);
1046 case llvm::MachO::CPU_TYPE_I386:
1047 return "Mach-O 32-bit i386";
1048 case llvm::MachO::CPU_TYPE_ARM:
1049 return "Mach-O arm";
1050 case llvm::MachO::CPU_TYPE_POWERPC:
1051 return "Mach-O 32-bit ppc";
1053 return "Mach-O 32-bit unknown";
1058 case llvm::MachO::CPU_TYPE_X86_64:
1059 return "Mach-O 64-bit x86-64";
1060 case llvm::MachO::CPU_TYPE_ARM64:
1061 return "Mach-O arm64";
1062 case llvm::MachO::CPU_TYPE_POWERPC64:
1063 return "Mach-O 64-bit ppc64";
1065 return "Mach-O 64-bit unknown";
1069 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1071 case llvm::MachO::CPU_TYPE_I386:
1073 case llvm::MachO::CPU_TYPE_X86_64:
1074 return Triple::x86_64;
1075 case llvm::MachO::CPU_TYPE_ARM:
1077 case llvm::MachO::CPU_TYPE_ARM64:
1078 return Triple::aarch64;
1079 case llvm::MachO::CPU_TYPE_POWERPC:
1081 case llvm::MachO::CPU_TYPE_POWERPC64:
1082 return Triple::ppc64;
1084 return Triple::UnknownArch;
1088 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1089 const char **McpuDefault) {
1091 *McpuDefault = nullptr;
1094 case MachO::CPU_TYPE_I386:
1095 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1096 case MachO::CPU_SUBTYPE_I386_ALL:
1097 return Triple("i386-apple-darwin");
1101 case MachO::CPU_TYPE_X86_64:
1102 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1103 case MachO::CPU_SUBTYPE_X86_64_ALL:
1104 return Triple("x86_64-apple-darwin");
1105 case MachO::CPU_SUBTYPE_X86_64_H:
1106 return Triple("x86_64h-apple-darwin");
1110 case MachO::CPU_TYPE_ARM:
1111 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1112 case MachO::CPU_SUBTYPE_ARM_V4T:
1113 return Triple("armv4t-apple-darwin");
1114 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1115 return Triple("armv5e-apple-darwin");
1116 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1117 return Triple("xscale-apple-darwin");
1118 case MachO::CPU_SUBTYPE_ARM_V6:
1119 return Triple("armv6-apple-darwin");
1120 case MachO::CPU_SUBTYPE_ARM_V6M:
1122 *McpuDefault = "cortex-m0";
1123 return Triple("armv6m-apple-darwin");
1124 case MachO::CPU_SUBTYPE_ARM_V7:
1125 return Triple("armv7-apple-darwin");
1126 case MachO::CPU_SUBTYPE_ARM_V7EM:
1128 *McpuDefault = "cortex-m4";
1129 return Triple("armv7em-apple-darwin");
1130 case MachO::CPU_SUBTYPE_ARM_V7K:
1131 return Triple("armv7k-apple-darwin");
1132 case MachO::CPU_SUBTYPE_ARM_V7M:
1134 *McpuDefault = "cortex-m3";
1135 return Triple("armv7m-apple-darwin");
1136 case MachO::CPU_SUBTYPE_ARM_V7S:
1137 return Triple("armv7s-apple-darwin");
1141 case MachO::CPU_TYPE_ARM64:
1142 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1143 case MachO::CPU_SUBTYPE_ARM64_ALL:
1144 return Triple("arm64-apple-darwin");
1148 case MachO::CPU_TYPE_POWERPC:
1149 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1150 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1151 return Triple("ppc-apple-darwin");
1155 case MachO::CPU_TYPE_POWERPC64:
1156 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1157 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1158 return Triple("ppc64-apple-darwin");
1167 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1168 const char **McpuDefault) {
1170 *McpuDefault = nullptr;
1173 case MachO::CPU_TYPE_ARM:
1174 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1175 case MachO::CPU_SUBTYPE_ARM_V4T:
1176 return Triple("thumbv4t-apple-darwin");
1177 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1178 return Triple("thumbv5e-apple-darwin");
1179 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1180 return Triple("xscale-apple-darwin");
1181 case MachO::CPU_SUBTYPE_ARM_V6:
1182 return Triple("thumbv6-apple-darwin");
1183 case MachO::CPU_SUBTYPE_ARM_V6M:
1185 *McpuDefault = "cortex-m0";
1186 return Triple("thumbv6m-apple-darwin");
1187 case MachO::CPU_SUBTYPE_ARM_V7:
1188 return Triple("thumbv7-apple-darwin");
1189 case MachO::CPU_SUBTYPE_ARM_V7EM:
1191 *McpuDefault = "cortex-m4";
1192 return Triple("thumbv7em-apple-darwin");
1193 case MachO::CPU_SUBTYPE_ARM_V7K:
1194 return Triple("thumbv7k-apple-darwin");
1195 case MachO::CPU_SUBTYPE_ARM_V7M:
1197 *McpuDefault = "cortex-m3";
1198 return Triple("thumbv7m-apple-darwin");
1199 case MachO::CPU_SUBTYPE_ARM_V7S:
1200 return Triple("thumbv7s-apple-darwin");
1209 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1210 const char **McpuDefault,
1211 Triple *ThumbTriple) {
1212 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1213 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1218 Triple MachOObjectFile::getHostArch() {
1219 return Triple(sys::getDefaultTargetTriple());
1222 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1223 return StringSwitch<bool>(ArchFlag)
1225 .Case("x86_64", true)
1226 .Case("x86_64h", true)
1227 .Case("armv4t", true)
1229 .Case("armv5e", true)
1230 .Case("armv6", true)
1231 .Case("armv6m", true)
1232 .Case("armv7", true)
1233 .Case("armv7em", true)
1234 .Case("armv7k", true)
1235 .Case("armv7m", true)
1236 .Case("armv7s", true)
1237 .Case("arm64", true)
1239 .Case("ppc64", true)
1243 unsigned MachOObjectFile::getArch() const {
1244 return getArch(getCPUType(this));
1247 Triple MachOObjectFile::getArch(const char **McpuDefault,
1248 Triple *ThumbTriple) const {
1249 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1250 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1253 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1256 return section_rel_begin(DRI);
1259 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1262 return section_rel_end(DRI);
1265 dice_iterator MachOObjectFile::begin_dices() const {
1267 if (!DataInCodeLoadCmd)
1268 return dice_iterator(DiceRef(DRI, this));
1270 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1271 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1272 return dice_iterator(DiceRef(DRI, this));
1275 dice_iterator MachOObjectFile::end_dices() const {
1277 if (!DataInCodeLoadCmd)
1278 return dice_iterator(DiceRef(DRI, this));
1280 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1281 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1282 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1283 return dice_iterator(DiceRef(DRI, this));
1286 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1287 : Trie(T), Malformed(false), Done(false) { }
1289 void ExportEntry::moveToFirst() {
1291 pushDownUntilBottom();
1294 void ExportEntry::moveToEnd() {
1299 bool ExportEntry::operator==(const ExportEntry &Other) const {
1300 // Common case, one at end, other iterating from begin.
1301 if (Done || Other.Done)
1302 return (Done == Other.Done);
1303 // Not equal if different stack sizes.
1304 if (Stack.size() != Other.Stack.size())
1306 // Not equal if different cumulative strings.
1307 if (!CumulativeString.equals(Other.CumulativeString))
1309 // Equal if all nodes in both stacks match.
1310 for (unsigned i=0; i < Stack.size(); ++i) {
1311 if (Stack[i].Start != Other.Stack[i].Start)
1317 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1319 uint64_t Result = decodeULEB128(Ptr, &Count);
1321 if (Ptr > Trie.end()) {
1328 StringRef ExportEntry::name() const {
1329 return CumulativeString;
1332 uint64_t ExportEntry::flags() const {
1333 return Stack.back().Flags;
1336 uint64_t ExportEntry::address() const {
1337 return Stack.back().Address;
1340 uint64_t ExportEntry::other() const {
1341 return Stack.back().Other;
1344 StringRef ExportEntry::otherName() const {
1345 const char* ImportName = Stack.back().ImportName;
1347 return StringRef(ImportName);
1351 uint32_t ExportEntry::nodeOffset() const {
1352 return Stack.back().Start - Trie.begin();
1355 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1356 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1357 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1358 ParentStringLength(0), IsExportNode(false) {
1361 void ExportEntry::pushNode(uint64_t offset) {
1362 const uint8_t *Ptr = Trie.begin() + offset;
1363 NodeState State(Ptr);
1364 uint64_t ExportInfoSize = readULEB128(State.Current);
1365 State.IsExportNode = (ExportInfoSize != 0);
1366 const uint8_t* Children = State.Current + ExportInfoSize;
1367 if (State.IsExportNode) {
1368 State.Flags = readULEB128(State.Current);
1369 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1371 State.Other = readULEB128(State.Current); // dylib ordinal
1372 State.ImportName = reinterpret_cast<const char*>(State.Current);
1374 State.Address = readULEB128(State.Current);
1375 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1376 State.Other = readULEB128(State.Current);
1379 State.ChildCount = *Children;
1380 State.Current = Children + 1;
1381 State.NextChildIndex = 0;
1382 State.ParentStringLength = CumulativeString.size();
1383 Stack.push_back(State);
1386 void ExportEntry::pushDownUntilBottom() {
1387 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1388 NodeState &Top = Stack.back();
1389 CumulativeString.resize(Top.ParentStringLength);
1390 for (;*Top.Current != 0; Top.Current++) {
1391 char C = *Top.Current;
1392 CumulativeString.push_back(C);
1395 uint64_t childNodeIndex = readULEB128(Top.Current);
1396 Top.NextChildIndex += 1;
1397 pushNode(childNodeIndex);
1399 if (!Stack.back().IsExportNode) {
1405 // We have a trie data structure and need a way to walk it that is compatible
1406 // with the C++ iterator model. The solution is a non-recursive depth first
1407 // traversal where the iterator contains a stack of parent nodes along with a
1408 // string that is the accumulation of all edge strings along the parent chain
1411 // There is one "export" node for each exported symbol. But because some
1412 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1413 // node may have child nodes too.
1415 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1416 // child until hitting a node with no children (which is an export node or
1417 // else the trie is malformed). On the way down, each node is pushed on the
1418 // stack ivar. If there is no more ways down, it pops up one and tries to go
1419 // down a sibling path until a childless node is reached.
1420 void ExportEntry::moveNext() {
1421 if (Stack.empty() || !Stack.back().IsExportNode) {
1428 while (!Stack.empty()) {
1429 NodeState &Top = Stack.back();
1430 if (Top.NextChildIndex < Top.ChildCount) {
1431 pushDownUntilBottom();
1432 // Now at the next export node.
1435 if (Top.IsExportNode) {
1436 // This node has no children but is itself an export node.
1437 CumulativeString.resize(Top.ParentStringLength);
1446 iterator_range<export_iterator>
1447 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1448 ExportEntry Start(Trie);
1449 if (Trie.size() == 0)
1452 Start.moveToFirst();
1454 ExportEntry Finish(Trie);
1457 return iterator_range<export_iterator>(export_iterator(Start),
1458 export_iterator(Finish));
1461 iterator_range<export_iterator> MachOObjectFile::exports() const {
1462 return exports(getDyldInfoExportsTrie());
1466 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1467 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1468 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1469 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1471 void MachORebaseEntry::moveToFirst() {
1472 Ptr = Opcodes.begin();
1476 void MachORebaseEntry::moveToEnd() {
1477 Ptr = Opcodes.end();
1478 RemainingLoopCount = 0;
1482 void MachORebaseEntry::moveNext() {
1483 // If in the middle of some loop, move to next rebasing in loop.
1484 SegmentOffset += AdvanceAmount;
1485 if (RemainingLoopCount) {
1486 --RemainingLoopCount;
1489 if (Ptr == Opcodes.end()) {
1494 while (More && !Malformed) {
1495 // Parse next opcode and set up next loop.
1496 uint8_t Byte = *Ptr++;
1497 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1498 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1500 case MachO::REBASE_OPCODE_DONE:
1504 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1506 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1507 RebaseType = ImmValue;
1510 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1511 << "RebaseType=" << (int) RebaseType << "\n");
1513 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1514 SegmentIndex = ImmValue;
1515 SegmentOffset = readULEB128();
1518 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1519 << "SegmentIndex=" << SegmentIndex << ", "
1520 << format("SegmentOffset=0x%06X", SegmentOffset)
1523 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1524 SegmentOffset += readULEB128();
1525 DEBUG_WITH_TYPE("mach-o-rebase",
1526 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1527 << format("SegmentOffset=0x%06X",
1528 SegmentOffset) << "\n");
1530 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1531 SegmentOffset += ImmValue * PointerSize;
1532 DEBUG_WITH_TYPE("mach-o-rebase",
1533 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1534 << format("SegmentOffset=0x%06X",
1535 SegmentOffset) << "\n");
1537 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1538 AdvanceAmount = PointerSize;
1539 RemainingLoopCount = ImmValue - 1;
1542 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1543 << format("SegmentOffset=0x%06X", SegmentOffset)
1544 << ", AdvanceAmount=" << AdvanceAmount
1545 << ", RemainingLoopCount=" << RemainingLoopCount
1548 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1549 AdvanceAmount = PointerSize;
1550 RemainingLoopCount = readULEB128() - 1;
1553 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1554 << format("SegmentOffset=0x%06X", SegmentOffset)
1555 << ", AdvanceAmount=" << AdvanceAmount
1556 << ", RemainingLoopCount=" << RemainingLoopCount
1559 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1560 AdvanceAmount = readULEB128() + PointerSize;
1561 RemainingLoopCount = 0;
1564 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1565 << format("SegmentOffset=0x%06X", SegmentOffset)
1566 << ", AdvanceAmount=" << AdvanceAmount
1567 << ", RemainingLoopCount=" << RemainingLoopCount
1570 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1571 RemainingLoopCount = readULEB128() - 1;
1572 AdvanceAmount = readULEB128() + PointerSize;
1575 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1576 << format("SegmentOffset=0x%06X", SegmentOffset)
1577 << ", AdvanceAmount=" << AdvanceAmount
1578 << ", RemainingLoopCount=" << RemainingLoopCount
1587 uint64_t MachORebaseEntry::readULEB128() {
1589 uint64_t Result = decodeULEB128(Ptr, &Count);
1591 if (Ptr > Opcodes.end()) {
1592 Ptr = Opcodes.end();
1598 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1600 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1602 StringRef MachORebaseEntry::typeName() const {
1603 switch (RebaseType) {
1604 case MachO::REBASE_TYPE_POINTER:
1606 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1607 return "text abs32";
1608 case MachO::REBASE_TYPE_TEXT_PCREL32:
1609 return "text rel32";
1614 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1615 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1616 return (Ptr == Other.Ptr) &&
1617 (RemainingLoopCount == Other.RemainingLoopCount) &&
1618 (Done == Other.Done);
1621 iterator_range<rebase_iterator>
1622 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1623 MachORebaseEntry Start(Opcodes, is64);
1624 Start.moveToFirst();
1626 MachORebaseEntry Finish(Opcodes, is64);
1629 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1630 rebase_iterator(Finish));
1633 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1634 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1638 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1640 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1641 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1642 BindType(0), PointerSize(is64Bit ? 8 : 4),
1643 TableKind(BK), Malformed(false), Done(false) {}
1645 void MachOBindEntry::moveToFirst() {
1646 Ptr = Opcodes.begin();
1650 void MachOBindEntry::moveToEnd() {
1651 Ptr = Opcodes.end();
1652 RemainingLoopCount = 0;
1656 void MachOBindEntry::moveNext() {
1657 // If in the middle of some loop, move to next binding in loop.
1658 SegmentOffset += AdvanceAmount;
1659 if (RemainingLoopCount) {
1660 --RemainingLoopCount;
1663 if (Ptr == Opcodes.end()) {
1668 while (More && !Malformed) {
1669 // Parse next opcode and set up next loop.
1670 uint8_t Byte = *Ptr++;
1671 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1672 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1673 int8_t SignExtended;
1674 const uint8_t *SymStart;
1676 case MachO::BIND_OPCODE_DONE:
1677 if (TableKind == Kind::Lazy) {
1678 // Lazying bindings have a DONE opcode between entries. Need to ignore
1679 // it to advance to next entry. But need not if this is last entry.
1680 bool NotLastEntry = false;
1681 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1683 NotLastEntry = true;
1692 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1694 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1698 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1699 << "Ordinal=" << Ordinal << "\n");
1701 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1702 Ordinal = readULEB128();
1705 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1706 << "Ordinal=" << Ordinal << "\n");
1708 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1710 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1711 Ordinal = SignExtended;
1716 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1717 << "Ordinal=" << Ordinal << "\n");
1719 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1725 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1730 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1731 << "SymbolName=" << SymbolName << "\n");
1732 if (TableKind == Kind::Weak) {
1733 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1737 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1738 BindType = ImmValue;
1741 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1742 << "BindType=" << (int)BindType << "\n");
1744 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1745 Addend = readSLEB128();
1746 if (TableKind == Kind::Lazy)
1750 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1751 << "Addend=" << Addend << "\n");
1753 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1754 SegmentIndex = ImmValue;
1755 SegmentOffset = readULEB128();
1758 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1759 << "SegmentIndex=" << SegmentIndex << ", "
1760 << format("SegmentOffset=0x%06X", SegmentOffset)
1763 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1764 SegmentOffset += readULEB128();
1765 DEBUG_WITH_TYPE("mach-o-bind",
1766 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1767 << format("SegmentOffset=0x%06X",
1768 SegmentOffset) << "\n");
1770 case MachO::BIND_OPCODE_DO_BIND:
1771 AdvanceAmount = PointerSize;
1772 RemainingLoopCount = 0;
1773 DEBUG_WITH_TYPE("mach-o-bind",
1774 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1775 << format("SegmentOffset=0x%06X",
1776 SegmentOffset) << "\n");
1778 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1779 AdvanceAmount = readULEB128() + PointerSize;
1780 RemainingLoopCount = 0;
1781 if (TableKind == Kind::Lazy)
1785 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1786 << format("SegmentOffset=0x%06X", SegmentOffset)
1787 << ", AdvanceAmount=" << AdvanceAmount
1788 << ", RemainingLoopCount=" << RemainingLoopCount
1791 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1792 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1793 RemainingLoopCount = 0;
1794 if (TableKind == Kind::Lazy)
1796 DEBUG_WITH_TYPE("mach-o-bind",
1798 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1799 << format("SegmentOffset=0x%06X",
1800 SegmentOffset) << "\n");
1802 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1803 RemainingLoopCount = readULEB128() - 1;
1804 AdvanceAmount = readULEB128() + PointerSize;
1805 if (TableKind == Kind::Lazy)
1809 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1810 << format("SegmentOffset=0x%06X", SegmentOffset)
1811 << ", AdvanceAmount=" << AdvanceAmount
1812 << ", RemainingLoopCount=" << RemainingLoopCount
1821 uint64_t MachOBindEntry::readULEB128() {
1823 uint64_t Result = decodeULEB128(Ptr, &Count);
1825 if (Ptr > Opcodes.end()) {
1826 Ptr = Opcodes.end();
1832 int64_t MachOBindEntry::readSLEB128() {
1834 int64_t Result = decodeSLEB128(Ptr, &Count);
1836 if (Ptr > Opcodes.end()) {
1837 Ptr = Opcodes.end();
1844 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1846 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1848 StringRef MachOBindEntry::typeName() const {
1850 case MachO::BIND_TYPE_POINTER:
1852 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1853 return "text abs32";
1854 case MachO::BIND_TYPE_TEXT_PCREL32:
1855 return "text rel32";
1860 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1862 int64_t MachOBindEntry::addend() const { return Addend; }
1864 uint32_t MachOBindEntry::flags() const { return Flags; }
1866 int MachOBindEntry::ordinal() const { return Ordinal; }
1868 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1869 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1870 return (Ptr == Other.Ptr) &&
1871 (RemainingLoopCount == Other.RemainingLoopCount) &&
1872 (Done == Other.Done);
1875 iterator_range<bind_iterator>
1876 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1877 MachOBindEntry::Kind BKind) {
1878 MachOBindEntry Start(Opcodes, is64, BKind);
1879 Start.moveToFirst();
1881 MachOBindEntry Finish(Opcodes, is64, BKind);
1884 return iterator_range<bind_iterator>(bind_iterator(Start),
1885 bind_iterator(Finish));
1888 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1889 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1890 MachOBindEntry::Kind::Regular);
1893 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1894 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1895 MachOBindEntry::Kind::Lazy);
1898 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1899 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1900 MachOBindEntry::Kind::Weak);
1903 MachOObjectFile::load_command_iterator
1904 MachOObjectFile::begin_load_commands() const {
1905 return LoadCommands.begin();
1908 MachOObjectFile::load_command_iterator
1909 MachOObjectFile::end_load_commands() const {
1910 return LoadCommands.end();
1913 iterator_range<MachOObjectFile::load_command_iterator>
1914 MachOObjectFile::load_commands() const {
1915 return iterator_range<load_command_iterator>(begin_load_commands(),
1916 end_load_commands());
1920 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1921 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1922 return parseSegmentOrSectionName(Raw.data());
1926 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1927 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1928 const section_base *Base =
1929 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1930 return makeArrayRef(Base->sectname);
1934 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1935 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1936 const section_base *Base =
1937 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1938 return makeArrayRef(Base->segname);
1942 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1944 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1946 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1949 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1950 const MachO::any_relocation_info &RE) const {
1951 if (isLittleEndian())
1952 return RE.r_word1 & 0xffffff;
1953 return RE.r_word1 >> 8;
1956 bool MachOObjectFile::getPlainRelocationExternal(
1957 const MachO::any_relocation_info &RE) const {
1958 if (isLittleEndian())
1959 return (RE.r_word1 >> 27) & 1;
1960 return (RE.r_word1 >> 4) & 1;
1963 bool MachOObjectFile::getScatteredRelocationScattered(
1964 const MachO::any_relocation_info &RE) const {
1965 return RE.r_word0 >> 31;
1968 uint32_t MachOObjectFile::getScatteredRelocationValue(
1969 const MachO::any_relocation_info &RE) const {
1973 uint32_t MachOObjectFile::getScatteredRelocationType(
1974 const MachO::any_relocation_info &RE) const {
1975 return (RE.r_word0 >> 24) & 0xf;
1978 unsigned MachOObjectFile::getAnyRelocationAddress(
1979 const MachO::any_relocation_info &RE) const {
1980 if (isRelocationScattered(RE))
1981 return getScatteredRelocationAddress(RE);
1982 return getPlainRelocationAddress(RE);
1985 unsigned MachOObjectFile::getAnyRelocationPCRel(
1986 const MachO::any_relocation_info &RE) const {
1987 if (isRelocationScattered(RE))
1988 return getScatteredRelocationPCRel(this, RE);
1989 return getPlainRelocationPCRel(this, RE);
1992 unsigned MachOObjectFile::getAnyRelocationLength(
1993 const MachO::any_relocation_info &RE) const {
1994 if (isRelocationScattered(RE))
1995 return getScatteredRelocationLength(RE);
1996 return getPlainRelocationLength(this, RE);
2000 MachOObjectFile::getAnyRelocationType(
2001 const MachO::any_relocation_info &RE) const {
2002 if (isRelocationScattered(RE))
2003 return getScatteredRelocationType(RE);
2004 return getPlainRelocationType(this, RE);
2008 MachOObjectFile::getAnyRelocationSection(
2009 const MachO::any_relocation_info &RE) const {
2010 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2011 return *section_end();
2012 unsigned SecNum = getPlainRelocationSymbolNum(RE);
2013 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
2014 return *section_end();
2016 DRI.d.a = SecNum - 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);