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 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
350 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
351 return Entry.n_value;
353 MachO::nlist Entry = getSymbolTableEntry(Sym);
354 return Entry.n_value;
357 // getIndirectName() returns the name of the alias'ed symbol who's string table
358 // index is in the n_value field.
359 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
360 StringRef &Res) const {
361 StringRef StringTable = getStringTableData();
362 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
363 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
364 return object_error::parse_failed;
365 uint64_t NValue = getNValue(Symb);
366 if (NValue >= StringTable.size())
367 return object_error::parse_failed;
368 const char *Start = &StringTable.data()[NValue];
369 Res = StringRef(Start);
370 return std::error_code();
373 uint64_t MachOObjectFile::getSymbolValue(DataRefImpl Sym) const {
374 uint64_t NValue = getNValue(Sym);
375 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Sym);
376 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0)
377 return UnknownAddress;
381 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Sym,
382 uint64_t &Res) const {
383 Res = getSymbolValue(Sym);
384 return std::error_code();
387 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
388 uint32_t flags = getSymbolFlags(DRI);
389 if (flags & SymbolRef::SF_Common) {
390 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
391 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
396 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
398 getSymbolAddress(DRI, Value);
402 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
403 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
404 uint8_t n_type = Entry.n_type;
406 // If this is a STAB debugging symbol, we can do nothing more.
407 if (n_type & MachO::N_STAB)
408 return SymbolRef::ST_Debug;
410 switch (n_type & MachO::N_TYPE) {
412 return SymbolRef::ST_Unknown;
414 return SymbolRef::ST_Function;
416 return SymbolRef::ST_Other;
419 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
420 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
422 uint8_t MachOType = Entry.n_type;
423 uint16_t MachOFlags = Entry.n_desc;
425 uint32_t Result = SymbolRef::SF_None;
427 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
428 Result |= SymbolRef::SF_Undefined;
430 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
431 Result |= SymbolRef::SF_Indirect;
433 if (MachOType & MachO::N_STAB)
434 Result |= SymbolRef::SF_FormatSpecific;
436 if (MachOType & MachO::N_EXT) {
437 Result |= SymbolRef::SF_Global;
438 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
440 getSymbolAddress(DRI, Value);
441 if (Value && Value != UnknownAddress)
442 Result |= SymbolRef::SF_Common;
445 if (!(MachOType & MachO::N_PEXT))
446 Result |= SymbolRef::SF_Exported;
449 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
450 Result |= SymbolRef::SF_Weak;
452 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
453 Result |= SymbolRef::SF_Thumb;
455 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
456 Result |= SymbolRef::SF_Absolute;
461 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
462 section_iterator &Res) const {
463 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
464 uint8_t index = Entry.n_sect;
471 if (DRI.d.a >= Sections.size())
472 report_fatal_error("getSymbolSection: Invalid section index.");
473 Res = section_iterator(SectionRef(DRI, this));
476 return std::error_code();
479 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
480 MachO::nlist_base Entry =
481 getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
482 return Entry.n_sect - 1;
485 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
489 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
490 StringRef &Result) const {
491 ArrayRef<char> Raw = getSectionRawName(Sec);
492 Result = parseSegmentOrSectionName(Raw.data());
493 return std::error_code();
496 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
498 return getSection64(Sec).addr;
499 return getSection(Sec).addr;
502 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
504 return getSection64(Sec).size;
505 return getSection(Sec).size;
508 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
509 StringRef &Res) const {
514 MachO::section_64 Sect = getSection64(Sec);
515 Offset = Sect.offset;
518 MachO::section Sect = getSection(Sec);
519 Offset = Sect.offset;
523 Res = this->getData().substr(Offset, Size);
524 return std::error_code();
527 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
530 MachO::section_64 Sect = getSection64(Sec);
533 MachO::section Sect = getSection(Sec);
537 return uint64_t(1) << Align;
540 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
541 uint32_t Flags = getSectionFlags(this, Sec);
542 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
545 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
546 uint32_t Flags = getSectionFlags(this, Sec);
547 unsigned SectionType = Flags & MachO::SECTION_TYPE;
548 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
549 !(SectionType == MachO::S_ZEROFILL ||
550 SectionType == MachO::S_GB_ZEROFILL);
553 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
554 uint32_t Flags = getSectionFlags(this, Sec);
555 unsigned SectionType = Flags & MachO::SECTION_TYPE;
556 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
557 (SectionType == MachO::S_ZEROFILL ||
558 SectionType == MachO::S_GB_ZEROFILL);
561 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
562 return Sec.getRawDataRefImpl().d.a;
565 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
566 // FIXME: Unimplemented.
570 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
571 DataRefImpl Symb) const {
572 SymbolRef::Type ST = getSymbolType(Symb);
573 if (ST == SymbolRef::ST_Unknown)
576 uint64_t SectBegin = getSectionAddress(Sec);
577 uint64_t SectEnd = getSectionSize(Sec);
578 SectEnd += SectBegin;
581 getSymbolAddress(Symb, SymAddr);
582 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
585 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
589 return relocation_iterator(RelocationRef(Ret, this));
593 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
596 MachO::section_64 Sect = getSection64(Sec);
599 MachO::section Sect = getSection(Sec);
606 return relocation_iterator(RelocationRef(Ret, this));
609 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
613 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
614 uint64_t &Res) const {
615 uint64_t Offset = getRelocationOffset(Rel);
619 uint64_t SecAddress = getSectionAddress(Sec);
620 Res = SecAddress + Offset;
621 return std::error_code();
624 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
625 assert(getHeader().filetype == MachO::MH_OBJECT &&
626 "Only implemented for MH_OBJECT");
627 MachO::any_relocation_info RE = getRelocation(Rel);
628 return getAnyRelocationAddress(RE);
632 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
633 MachO::any_relocation_info RE = getRelocation(Rel);
634 if (isRelocationScattered(RE))
637 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
638 bool isExtern = getPlainRelocationExternal(RE);
642 MachO::symtab_command S = getSymtabLoadCommand();
643 unsigned SymbolTableEntrySize = is64Bit() ?
644 sizeof(MachO::nlist_64) :
645 sizeof(MachO::nlist);
646 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
648 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
649 return symbol_iterator(SymbolRef(Sym, this));
653 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
654 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
657 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
658 MachO::any_relocation_info RE = getRelocation(Rel);
659 return getAnyRelocationType(RE);
663 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
664 SmallVectorImpl<char> &Result) const {
666 uint64_t RType = getRelocationType(Rel);
668 unsigned Arch = this->getArch();
672 static const char *const Table[] = {
673 "GENERIC_RELOC_VANILLA",
674 "GENERIC_RELOC_PAIR",
675 "GENERIC_RELOC_SECTDIFF",
676 "GENERIC_RELOC_PB_LA_PTR",
677 "GENERIC_RELOC_LOCAL_SECTDIFF",
678 "GENERIC_RELOC_TLV" };
686 case Triple::x86_64: {
687 static const char *const Table[] = {
688 "X86_64_RELOC_UNSIGNED",
689 "X86_64_RELOC_SIGNED",
690 "X86_64_RELOC_BRANCH",
691 "X86_64_RELOC_GOT_LOAD",
693 "X86_64_RELOC_SUBTRACTOR",
694 "X86_64_RELOC_SIGNED_1",
695 "X86_64_RELOC_SIGNED_2",
696 "X86_64_RELOC_SIGNED_4",
697 "X86_64_RELOC_TLV" };
706 static const char *const Table[] = {
709 "ARM_RELOC_SECTDIFF",
710 "ARM_RELOC_LOCAL_SECTDIFF",
711 "ARM_RELOC_PB_LA_PTR",
713 "ARM_THUMB_RELOC_BR22",
714 "ARM_THUMB_32BIT_BRANCH",
716 "ARM_RELOC_HALF_SECTDIFF" };
724 case Triple::aarch64: {
725 static const char *const Table[] = {
726 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
727 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
728 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
729 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
730 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
734 if (RType >= array_lengthof(Table))
741 static const char *const Table[] = {
750 "PPC_RELOC_SECTDIFF",
751 "PPC_RELOC_PB_LA_PTR",
752 "PPC_RELOC_HI16_SECTDIFF",
753 "PPC_RELOC_LO16_SECTDIFF",
754 "PPC_RELOC_HA16_SECTDIFF",
756 "PPC_RELOC_LO14_SECTDIFF",
757 "PPC_RELOC_LOCAL_SECTDIFF" };
765 case Triple::UnknownArch:
769 Result.append(res.begin(), res.end());
770 return std::error_code();
773 bool MachOObjectFile::getRelocationHidden(DataRefImpl Rel) const {
774 unsigned Arch = getArch();
775 uint64_t Type = getRelocationType(Rel);
777 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
779 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
780 if (Type == MachO::GENERIC_RELOC_PAIR)
782 } else if (Arch == Triple::x86_64) {
783 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
784 // an X86_64_RELOC_SUBTRACTOR.
785 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
786 DataRefImpl RelPrev = Rel;
788 uint64_t PrevType = getRelocationType(RelPrev);
789 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
797 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
798 MachO::any_relocation_info RE = getRelocation(Rel);
799 return getAnyRelocationLength(RE);
803 // guessLibraryShortName() is passed a name of a dynamic library and returns a
804 // guess on what the short name is. Then name is returned as a substring of the
805 // StringRef Name passed in. The name of the dynamic library is recognized as
806 // a framework if it has one of the two following forms:
807 // Foo.framework/Versions/A/Foo
809 // Where A and Foo can be any string. And may contain a trailing suffix
810 // starting with an underbar. If the Name is recognized as a framework then
811 // isFramework is set to true else it is set to false. If the Name has a
812 // suffix then Suffix is set to the substring in Name that contains the suffix
813 // else it is set to a NULL StringRef.
815 // The Name of the dynamic library is recognized as a library name if it has
816 // one of the two following forms:
819 // The library may have a suffix trailing the name Foo of the form:
820 // libFoo_profile.A.dylib
821 // libFoo_profile.dylib
823 // The Name of the dynamic library is also recognized as a library name if it
824 // has the following form:
827 // If the Name of the dynamic library is none of the forms above then a NULL
828 // StringRef is returned.
830 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
833 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
834 size_t a, b, c, d, Idx;
837 Suffix = StringRef();
839 // Pull off the last component and make Foo point to it
841 if (a == Name.npos || a == 0)
843 Foo = Name.slice(a+1, Name.npos);
845 // Look for a suffix starting with a '_'
846 Idx = Foo.rfind('_');
847 if (Idx != Foo.npos && Foo.size() >= 2) {
848 Suffix = Foo.slice(Idx, Foo.npos);
849 Foo = Foo.slice(0, Idx);
852 // First look for the form Foo.framework/Foo
853 b = Name.rfind('/', a);
858 F = Name.slice(Idx, Idx + Foo.size());
859 DotFramework = Name.slice(Idx + Foo.size(),
860 Idx + Foo.size() + sizeof(".framework/")-1);
861 if (F == Foo && DotFramework == ".framework/") {
866 // Next look for the form Foo.framework/Versions/A/Foo
869 c = Name.rfind('/', b);
870 if (c == Name.npos || c == 0)
872 V = Name.slice(c+1, Name.npos);
873 if (!V.startswith("Versions/"))
875 d = Name.rfind('/', c);
880 F = Name.slice(Idx, Idx + Foo.size());
881 DotFramework = Name.slice(Idx + Foo.size(),
882 Idx + Foo.size() + sizeof(".framework/")-1);
883 if (F == Foo && DotFramework == ".framework/") {
889 // pull off the suffix after the "." and make a point to it
891 if (a == Name.npos || a == 0)
893 Dylib = Name.slice(a, Name.npos);
894 if (Dylib != ".dylib")
897 // First pull off the version letter for the form Foo.A.dylib if any.
899 Dot = Name.slice(a-2, a-1);
904 b = Name.rfind('/', a);
909 // ignore any suffix after an underbar like Foo_profile.A.dylib
910 Idx = Name.find('_', b);
911 if (Idx != Name.npos && Idx != b) {
912 Lib = Name.slice(b, Idx);
913 Suffix = Name.slice(Idx, a);
916 Lib = Name.slice(b, a);
917 // There are incorrect library names of the form:
918 // libATS.A_profile.dylib so check for these.
919 if (Lib.size() >= 3) {
920 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
922 Lib = Lib.slice(0, Lib.size()-2);
927 Qtx = Name.slice(a, Name.npos);
930 b = Name.rfind('/', a);
932 Lib = Name.slice(0, a);
934 Lib = Name.slice(b+1, a);
935 // There are library names of the form: QT.A.qtx so check for these.
936 if (Lib.size() >= 3) {
937 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
939 Lib = Lib.slice(0, Lib.size()-2);
944 // getLibraryShortNameByIndex() is used to get the short name of the library
945 // for an undefined symbol in a linked Mach-O binary that was linked with the
946 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
947 // It is passed the index (0 - based) of the library as translated from
948 // GET_LIBRARY_ORDINAL (1 - based).
949 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
950 StringRef &Res) const {
951 if (Index >= Libraries.size())
952 return object_error::parse_failed;
954 // If the cache of LibrariesShortNames is not built up do that first for
955 // all the Libraries.
956 if (LibrariesShortNames.size() == 0) {
957 for (unsigned i = 0; i < Libraries.size(); i++) {
958 MachO::dylib_command D =
959 getStruct<MachO::dylib_command>(this, Libraries[i]);
960 if (D.dylib.name >= D.cmdsize)
961 return object_error::parse_failed;
962 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
963 StringRef Name = StringRef(P);
964 if (D.dylib.name+Name.size() >= D.cmdsize)
965 return object_error::parse_failed;
968 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
969 if (shortName.empty())
970 LibrariesShortNames.push_back(Name);
972 LibrariesShortNames.push_back(shortName);
976 Res = LibrariesShortNames[Index];
977 return std::error_code();
980 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
981 return getSymbolByIndex(0);
984 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
987 return basic_symbol_iterator(SymbolRef(DRI, this));
989 MachO::symtab_command Symtab = getSymtabLoadCommand();
990 unsigned SymbolTableEntrySize = is64Bit() ?
991 sizeof(MachO::nlist_64) :
992 sizeof(MachO::nlist);
993 unsigned Offset = Symtab.symoff +
994 Symtab.nsyms * SymbolTableEntrySize;
995 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
996 return basic_symbol_iterator(SymbolRef(DRI, this));
999 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1002 return basic_symbol_iterator(SymbolRef(DRI, this));
1004 MachO::symtab_command Symtab = getSymtabLoadCommand();
1005 if (Index >= Symtab.nsyms)
1006 report_fatal_error("Requested symbol index is out of range.");
1007 unsigned SymbolTableEntrySize =
1008 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1009 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1010 DRI.p += Index * SymbolTableEntrySize;
1011 return basic_symbol_iterator(SymbolRef(DRI, this));
1014 section_iterator MachOObjectFile::section_begin() const {
1016 return section_iterator(SectionRef(DRI, this));
1019 section_iterator MachOObjectFile::section_end() const {
1021 DRI.d.a = Sections.size();
1022 return section_iterator(SectionRef(DRI, this));
1025 uint8_t MachOObjectFile::getBytesInAddress() const {
1026 return is64Bit() ? 8 : 4;
1029 StringRef MachOObjectFile::getFileFormatName() const {
1030 unsigned CPUType = getCPUType(this);
1033 case llvm::MachO::CPU_TYPE_I386:
1034 return "Mach-O 32-bit i386";
1035 case llvm::MachO::CPU_TYPE_ARM:
1036 return "Mach-O arm";
1037 case llvm::MachO::CPU_TYPE_POWERPC:
1038 return "Mach-O 32-bit ppc";
1040 return "Mach-O 32-bit unknown";
1045 case llvm::MachO::CPU_TYPE_X86_64:
1046 return "Mach-O 64-bit x86-64";
1047 case llvm::MachO::CPU_TYPE_ARM64:
1048 return "Mach-O arm64";
1049 case llvm::MachO::CPU_TYPE_POWERPC64:
1050 return "Mach-O 64-bit ppc64";
1052 return "Mach-O 64-bit unknown";
1056 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1058 case llvm::MachO::CPU_TYPE_I386:
1060 case llvm::MachO::CPU_TYPE_X86_64:
1061 return Triple::x86_64;
1062 case llvm::MachO::CPU_TYPE_ARM:
1064 case llvm::MachO::CPU_TYPE_ARM64:
1065 return Triple::aarch64;
1066 case llvm::MachO::CPU_TYPE_POWERPC:
1068 case llvm::MachO::CPU_TYPE_POWERPC64:
1069 return Triple::ppc64;
1071 return Triple::UnknownArch;
1075 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1076 const char **McpuDefault) {
1078 *McpuDefault = nullptr;
1081 case MachO::CPU_TYPE_I386:
1082 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1083 case MachO::CPU_SUBTYPE_I386_ALL:
1084 return Triple("i386-apple-darwin");
1088 case MachO::CPU_TYPE_X86_64:
1089 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1090 case MachO::CPU_SUBTYPE_X86_64_ALL:
1091 return Triple("x86_64-apple-darwin");
1092 case MachO::CPU_SUBTYPE_X86_64_H:
1093 return Triple("x86_64h-apple-darwin");
1097 case MachO::CPU_TYPE_ARM:
1098 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1099 case MachO::CPU_SUBTYPE_ARM_V4T:
1100 return Triple("armv4t-apple-darwin");
1101 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1102 return Triple("armv5e-apple-darwin");
1103 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1104 return Triple("xscale-apple-darwin");
1105 case MachO::CPU_SUBTYPE_ARM_V6:
1106 return Triple("armv6-apple-darwin");
1107 case MachO::CPU_SUBTYPE_ARM_V6M:
1109 *McpuDefault = "cortex-m0";
1110 return Triple("armv6m-apple-darwin");
1111 case MachO::CPU_SUBTYPE_ARM_V7:
1112 return Triple("armv7-apple-darwin");
1113 case MachO::CPU_SUBTYPE_ARM_V7EM:
1115 *McpuDefault = "cortex-m4";
1116 return Triple("armv7em-apple-darwin");
1117 case MachO::CPU_SUBTYPE_ARM_V7K:
1118 return Triple("armv7k-apple-darwin");
1119 case MachO::CPU_SUBTYPE_ARM_V7M:
1121 *McpuDefault = "cortex-m3";
1122 return Triple("armv7m-apple-darwin");
1123 case MachO::CPU_SUBTYPE_ARM_V7S:
1124 return Triple("armv7s-apple-darwin");
1128 case MachO::CPU_TYPE_ARM64:
1129 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1130 case MachO::CPU_SUBTYPE_ARM64_ALL:
1131 return Triple("arm64-apple-darwin");
1135 case MachO::CPU_TYPE_POWERPC:
1136 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1137 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1138 return Triple("ppc-apple-darwin");
1142 case MachO::CPU_TYPE_POWERPC64:
1143 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1144 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1145 return Triple("ppc64-apple-darwin");
1154 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1155 const char **McpuDefault) {
1157 *McpuDefault = nullptr;
1160 case MachO::CPU_TYPE_ARM:
1161 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1162 case MachO::CPU_SUBTYPE_ARM_V4T:
1163 return Triple("thumbv4t-apple-darwin");
1164 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1165 return Triple("thumbv5e-apple-darwin");
1166 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1167 return Triple("xscale-apple-darwin");
1168 case MachO::CPU_SUBTYPE_ARM_V6:
1169 return Triple("thumbv6-apple-darwin");
1170 case MachO::CPU_SUBTYPE_ARM_V6M:
1172 *McpuDefault = "cortex-m0";
1173 return Triple("thumbv6m-apple-darwin");
1174 case MachO::CPU_SUBTYPE_ARM_V7:
1175 return Triple("thumbv7-apple-darwin");
1176 case MachO::CPU_SUBTYPE_ARM_V7EM:
1178 *McpuDefault = "cortex-m4";
1179 return Triple("thumbv7em-apple-darwin");
1180 case MachO::CPU_SUBTYPE_ARM_V7K:
1181 return Triple("thumbv7k-apple-darwin");
1182 case MachO::CPU_SUBTYPE_ARM_V7M:
1184 *McpuDefault = "cortex-m3";
1185 return Triple("thumbv7m-apple-darwin");
1186 case MachO::CPU_SUBTYPE_ARM_V7S:
1187 return Triple("thumbv7s-apple-darwin");
1196 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1197 const char **McpuDefault,
1198 Triple *ThumbTriple) {
1199 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1200 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1205 Triple MachOObjectFile::getHostArch() {
1206 return Triple(sys::getDefaultTargetTriple());
1209 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1210 return StringSwitch<bool>(ArchFlag)
1212 .Case("x86_64", true)
1213 .Case("x86_64h", true)
1214 .Case("armv4t", true)
1216 .Case("armv5e", true)
1217 .Case("armv6", true)
1218 .Case("armv6m", true)
1219 .Case("armv7", true)
1220 .Case("armv7em", true)
1221 .Case("armv7k", true)
1222 .Case("armv7m", true)
1223 .Case("armv7s", true)
1224 .Case("arm64", true)
1226 .Case("ppc64", true)
1230 unsigned MachOObjectFile::getArch() const {
1231 return getArch(getCPUType(this));
1234 Triple MachOObjectFile::getArch(const char **McpuDefault,
1235 Triple *ThumbTriple) const {
1236 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1237 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1240 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1243 return section_rel_begin(DRI);
1246 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1249 return section_rel_end(DRI);
1252 dice_iterator MachOObjectFile::begin_dices() const {
1254 if (!DataInCodeLoadCmd)
1255 return dice_iterator(DiceRef(DRI, this));
1257 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1258 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1259 return dice_iterator(DiceRef(DRI, this));
1262 dice_iterator MachOObjectFile::end_dices() const {
1264 if (!DataInCodeLoadCmd)
1265 return dice_iterator(DiceRef(DRI, this));
1267 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1268 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1269 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1270 return dice_iterator(DiceRef(DRI, this));
1273 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1274 : Trie(T), Malformed(false), Done(false) { }
1276 void ExportEntry::moveToFirst() {
1278 pushDownUntilBottom();
1281 void ExportEntry::moveToEnd() {
1286 bool ExportEntry::operator==(const ExportEntry &Other) const {
1287 // Common case, one at end, other iterating from begin.
1288 if (Done || Other.Done)
1289 return (Done == Other.Done);
1290 // Not equal if different stack sizes.
1291 if (Stack.size() != Other.Stack.size())
1293 // Not equal if different cumulative strings.
1294 if (!CumulativeString.equals(Other.CumulativeString))
1296 // Equal if all nodes in both stacks match.
1297 for (unsigned i=0; i < Stack.size(); ++i) {
1298 if (Stack[i].Start != Other.Stack[i].Start)
1304 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1306 uint64_t Result = decodeULEB128(Ptr, &Count);
1308 if (Ptr > Trie.end()) {
1315 StringRef ExportEntry::name() const {
1316 return CumulativeString;
1319 uint64_t ExportEntry::flags() const {
1320 return Stack.back().Flags;
1323 uint64_t ExportEntry::address() const {
1324 return Stack.back().Address;
1327 uint64_t ExportEntry::other() const {
1328 return Stack.back().Other;
1331 StringRef ExportEntry::otherName() const {
1332 const char* ImportName = Stack.back().ImportName;
1334 return StringRef(ImportName);
1338 uint32_t ExportEntry::nodeOffset() const {
1339 return Stack.back().Start - Trie.begin();
1342 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1343 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1344 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1345 ParentStringLength(0), IsExportNode(false) {
1348 void ExportEntry::pushNode(uint64_t offset) {
1349 const uint8_t *Ptr = Trie.begin() + offset;
1350 NodeState State(Ptr);
1351 uint64_t ExportInfoSize = readULEB128(State.Current);
1352 State.IsExportNode = (ExportInfoSize != 0);
1353 const uint8_t* Children = State.Current + ExportInfoSize;
1354 if (State.IsExportNode) {
1355 State.Flags = readULEB128(State.Current);
1356 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1358 State.Other = readULEB128(State.Current); // dylib ordinal
1359 State.ImportName = reinterpret_cast<const char*>(State.Current);
1361 State.Address = readULEB128(State.Current);
1362 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1363 State.Other = readULEB128(State.Current);
1366 State.ChildCount = *Children;
1367 State.Current = Children + 1;
1368 State.NextChildIndex = 0;
1369 State.ParentStringLength = CumulativeString.size();
1370 Stack.push_back(State);
1373 void ExportEntry::pushDownUntilBottom() {
1374 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1375 NodeState &Top = Stack.back();
1376 CumulativeString.resize(Top.ParentStringLength);
1377 for (;*Top.Current != 0; Top.Current++) {
1378 char C = *Top.Current;
1379 CumulativeString.push_back(C);
1382 uint64_t childNodeIndex = readULEB128(Top.Current);
1383 Top.NextChildIndex += 1;
1384 pushNode(childNodeIndex);
1386 if (!Stack.back().IsExportNode) {
1392 // We have a trie data structure and need a way to walk it that is compatible
1393 // with the C++ iterator model. The solution is a non-recursive depth first
1394 // traversal where the iterator contains a stack of parent nodes along with a
1395 // string that is the accumulation of all edge strings along the parent chain
1398 // There is one "export" node for each exported symbol. But because some
1399 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1400 // node may have child nodes too.
1402 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1403 // child until hitting a node with no children (which is an export node or
1404 // else the trie is malformed). On the way down, each node is pushed on the
1405 // stack ivar. If there is no more ways down, it pops up one and tries to go
1406 // down a sibling path until a childless node is reached.
1407 void ExportEntry::moveNext() {
1408 if (Stack.empty() || !Stack.back().IsExportNode) {
1415 while (!Stack.empty()) {
1416 NodeState &Top = Stack.back();
1417 if (Top.NextChildIndex < Top.ChildCount) {
1418 pushDownUntilBottom();
1419 // Now at the next export node.
1422 if (Top.IsExportNode) {
1423 // This node has no children but is itself an export node.
1424 CumulativeString.resize(Top.ParentStringLength);
1433 iterator_range<export_iterator>
1434 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1435 ExportEntry Start(Trie);
1436 if (Trie.size() == 0)
1439 Start.moveToFirst();
1441 ExportEntry Finish(Trie);
1444 return iterator_range<export_iterator>(export_iterator(Start),
1445 export_iterator(Finish));
1448 iterator_range<export_iterator> MachOObjectFile::exports() const {
1449 return exports(getDyldInfoExportsTrie());
1453 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1454 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1455 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1456 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1458 void MachORebaseEntry::moveToFirst() {
1459 Ptr = Opcodes.begin();
1463 void MachORebaseEntry::moveToEnd() {
1464 Ptr = Opcodes.end();
1465 RemainingLoopCount = 0;
1469 void MachORebaseEntry::moveNext() {
1470 // If in the middle of some loop, move to next rebasing in loop.
1471 SegmentOffset += AdvanceAmount;
1472 if (RemainingLoopCount) {
1473 --RemainingLoopCount;
1476 if (Ptr == Opcodes.end()) {
1481 while (More && !Malformed) {
1482 // Parse next opcode and set up next loop.
1483 uint8_t Byte = *Ptr++;
1484 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1485 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1487 case MachO::REBASE_OPCODE_DONE:
1491 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1493 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1494 RebaseType = ImmValue;
1497 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1498 << "RebaseType=" << (int) RebaseType << "\n");
1500 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1501 SegmentIndex = ImmValue;
1502 SegmentOffset = readULEB128();
1505 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1506 << "SegmentIndex=" << SegmentIndex << ", "
1507 << format("SegmentOffset=0x%06X", SegmentOffset)
1510 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1511 SegmentOffset += readULEB128();
1512 DEBUG_WITH_TYPE("mach-o-rebase",
1513 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1514 << format("SegmentOffset=0x%06X",
1515 SegmentOffset) << "\n");
1517 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1518 SegmentOffset += ImmValue * PointerSize;
1519 DEBUG_WITH_TYPE("mach-o-rebase",
1520 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1521 << format("SegmentOffset=0x%06X",
1522 SegmentOffset) << "\n");
1524 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1525 AdvanceAmount = PointerSize;
1526 RemainingLoopCount = ImmValue - 1;
1529 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1530 << format("SegmentOffset=0x%06X", SegmentOffset)
1531 << ", AdvanceAmount=" << AdvanceAmount
1532 << ", RemainingLoopCount=" << RemainingLoopCount
1535 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1536 AdvanceAmount = PointerSize;
1537 RemainingLoopCount = readULEB128() - 1;
1540 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1541 << format("SegmentOffset=0x%06X", SegmentOffset)
1542 << ", AdvanceAmount=" << AdvanceAmount
1543 << ", RemainingLoopCount=" << RemainingLoopCount
1546 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1547 AdvanceAmount = readULEB128() + PointerSize;
1548 RemainingLoopCount = 0;
1551 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1552 << format("SegmentOffset=0x%06X", SegmentOffset)
1553 << ", AdvanceAmount=" << AdvanceAmount
1554 << ", RemainingLoopCount=" << RemainingLoopCount
1557 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1558 RemainingLoopCount = readULEB128() - 1;
1559 AdvanceAmount = readULEB128() + PointerSize;
1562 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1563 << format("SegmentOffset=0x%06X", SegmentOffset)
1564 << ", AdvanceAmount=" << AdvanceAmount
1565 << ", RemainingLoopCount=" << RemainingLoopCount
1574 uint64_t MachORebaseEntry::readULEB128() {
1576 uint64_t Result = decodeULEB128(Ptr, &Count);
1578 if (Ptr > Opcodes.end()) {
1579 Ptr = Opcodes.end();
1585 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1587 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1589 StringRef MachORebaseEntry::typeName() const {
1590 switch (RebaseType) {
1591 case MachO::REBASE_TYPE_POINTER:
1593 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1594 return "text abs32";
1595 case MachO::REBASE_TYPE_TEXT_PCREL32:
1596 return "text rel32";
1601 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1602 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1603 return (Ptr == Other.Ptr) &&
1604 (RemainingLoopCount == Other.RemainingLoopCount) &&
1605 (Done == Other.Done);
1608 iterator_range<rebase_iterator>
1609 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1610 MachORebaseEntry Start(Opcodes, is64);
1611 Start.moveToFirst();
1613 MachORebaseEntry Finish(Opcodes, is64);
1616 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1617 rebase_iterator(Finish));
1620 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1621 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1625 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1627 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1628 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1629 BindType(0), PointerSize(is64Bit ? 8 : 4),
1630 TableKind(BK), Malformed(false), Done(false) {}
1632 void MachOBindEntry::moveToFirst() {
1633 Ptr = Opcodes.begin();
1637 void MachOBindEntry::moveToEnd() {
1638 Ptr = Opcodes.end();
1639 RemainingLoopCount = 0;
1643 void MachOBindEntry::moveNext() {
1644 // If in the middle of some loop, move to next binding in loop.
1645 SegmentOffset += AdvanceAmount;
1646 if (RemainingLoopCount) {
1647 --RemainingLoopCount;
1650 if (Ptr == Opcodes.end()) {
1655 while (More && !Malformed) {
1656 // Parse next opcode and set up next loop.
1657 uint8_t Byte = *Ptr++;
1658 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1659 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1660 int8_t SignExtended;
1661 const uint8_t *SymStart;
1663 case MachO::BIND_OPCODE_DONE:
1664 if (TableKind == Kind::Lazy) {
1665 // Lazying bindings have a DONE opcode between entries. Need to ignore
1666 // it to advance to next entry. But need not if this is last entry.
1667 bool NotLastEntry = false;
1668 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1670 NotLastEntry = true;
1679 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1681 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1685 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1686 << "Ordinal=" << Ordinal << "\n");
1688 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1689 Ordinal = readULEB128();
1692 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1693 << "Ordinal=" << Ordinal << "\n");
1695 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1697 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1698 Ordinal = SignExtended;
1703 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1704 << "Ordinal=" << Ordinal << "\n");
1706 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1712 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1717 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1718 << "SymbolName=" << SymbolName << "\n");
1719 if (TableKind == Kind::Weak) {
1720 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1724 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1725 BindType = ImmValue;
1728 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1729 << "BindType=" << (int)BindType << "\n");
1731 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1732 Addend = readSLEB128();
1733 if (TableKind == Kind::Lazy)
1737 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1738 << "Addend=" << Addend << "\n");
1740 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1741 SegmentIndex = ImmValue;
1742 SegmentOffset = readULEB128();
1745 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1746 << "SegmentIndex=" << SegmentIndex << ", "
1747 << format("SegmentOffset=0x%06X", SegmentOffset)
1750 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1751 SegmentOffset += readULEB128();
1752 DEBUG_WITH_TYPE("mach-o-bind",
1753 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1754 << format("SegmentOffset=0x%06X",
1755 SegmentOffset) << "\n");
1757 case MachO::BIND_OPCODE_DO_BIND:
1758 AdvanceAmount = PointerSize;
1759 RemainingLoopCount = 0;
1760 DEBUG_WITH_TYPE("mach-o-bind",
1761 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1762 << format("SegmentOffset=0x%06X",
1763 SegmentOffset) << "\n");
1765 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1766 AdvanceAmount = readULEB128() + PointerSize;
1767 RemainingLoopCount = 0;
1768 if (TableKind == Kind::Lazy)
1772 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1773 << format("SegmentOffset=0x%06X", SegmentOffset)
1774 << ", AdvanceAmount=" << AdvanceAmount
1775 << ", RemainingLoopCount=" << RemainingLoopCount
1778 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1779 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1780 RemainingLoopCount = 0;
1781 if (TableKind == Kind::Lazy)
1783 DEBUG_WITH_TYPE("mach-o-bind",
1785 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1786 << format("SegmentOffset=0x%06X",
1787 SegmentOffset) << "\n");
1789 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1790 RemainingLoopCount = readULEB128() - 1;
1791 AdvanceAmount = readULEB128() + PointerSize;
1792 if (TableKind == Kind::Lazy)
1796 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1797 << format("SegmentOffset=0x%06X", SegmentOffset)
1798 << ", AdvanceAmount=" << AdvanceAmount
1799 << ", RemainingLoopCount=" << RemainingLoopCount
1808 uint64_t MachOBindEntry::readULEB128() {
1810 uint64_t Result = decodeULEB128(Ptr, &Count);
1812 if (Ptr > Opcodes.end()) {
1813 Ptr = Opcodes.end();
1819 int64_t MachOBindEntry::readSLEB128() {
1821 int64_t Result = decodeSLEB128(Ptr, &Count);
1823 if (Ptr > Opcodes.end()) {
1824 Ptr = Opcodes.end();
1831 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1833 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1835 StringRef MachOBindEntry::typeName() const {
1837 case MachO::BIND_TYPE_POINTER:
1839 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1840 return "text abs32";
1841 case MachO::BIND_TYPE_TEXT_PCREL32:
1842 return "text rel32";
1847 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1849 int64_t MachOBindEntry::addend() const { return Addend; }
1851 uint32_t MachOBindEntry::flags() const { return Flags; }
1853 int MachOBindEntry::ordinal() const { return Ordinal; }
1855 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1856 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1857 return (Ptr == Other.Ptr) &&
1858 (RemainingLoopCount == Other.RemainingLoopCount) &&
1859 (Done == Other.Done);
1862 iterator_range<bind_iterator>
1863 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1864 MachOBindEntry::Kind BKind) {
1865 MachOBindEntry Start(Opcodes, is64, BKind);
1866 Start.moveToFirst();
1868 MachOBindEntry Finish(Opcodes, is64, BKind);
1871 return iterator_range<bind_iterator>(bind_iterator(Start),
1872 bind_iterator(Finish));
1875 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1876 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1877 MachOBindEntry::Kind::Regular);
1880 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1881 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1882 MachOBindEntry::Kind::Lazy);
1885 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1886 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1887 MachOBindEntry::Kind::Weak);
1890 MachOObjectFile::load_command_iterator
1891 MachOObjectFile::begin_load_commands() const {
1892 return LoadCommands.begin();
1895 MachOObjectFile::load_command_iterator
1896 MachOObjectFile::end_load_commands() const {
1897 return LoadCommands.end();
1900 iterator_range<MachOObjectFile::load_command_iterator>
1901 MachOObjectFile::load_commands() const {
1902 return iterator_range<load_command_iterator>(begin_load_commands(),
1903 end_load_commands());
1907 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1908 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1909 return parseSegmentOrSectionName(Raw.data());
1913 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1914 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1915 const section_base *Base =
1916 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1917 return makeArrayRef(Base->sectname);
1921 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1922 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1923 const section_base *Base =
1924 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1925 return makeArrayRef(Base->segname);
1929 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1931 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1933 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1936 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1937 const MachO::any_relocation_info &RE) const {
1938 if (isLittleEndian())
1939 return RE.r_word1 & 0xffffff;
1940 return RE.r_word1 >> 8;
1943 bool MachOObjectFile::getPlainRelocationExternal(
1944 const MachO::any_relocation_info &RE) const {
1945 if (isLittleEndian())
1946 return (RE.r_word1 >> 27) & 1;
1947 return (RE.r_word1 >> 4) & 1;
1950 bool MachOObjectFile::getScatteredRelocationScattered(
1951 const MachO::any_relocation_info &RE) const {
1952 return RE.r_word0 >> 31;
1955 uint32_t MachOObjectFile::getScatteredRelocationValue(
1956 const MachO::any_relocation_info &RE) const {
1960 uint32_t MachOObjectFile::getScatteredRelocationType(
1961 const MachO::any_relocation_info &RE) const {
1962 return (RE.r_word0 >> 24) & 0xf;
1965 unsigned MachOObjectFile::getAnyRelocationAddress(
1966 const MachO::any_relocation_info &RE) const {
1967 if (isRelocationScattered(RE))
1968 return getScatteredRelocationAddress(RE);
1969 return getPlainRelocationAddress(RE);
1972 unsigned MachOObjectFile::getAnyRelocationPCRel(
1973 const MachO::any_relocation_info &RE) const {
1974 if (isRelocationScattered(RE))
1975 return getScatteredRelocationPCRel(this, RE);
1976 return getPlainRelocationPCRel(this, RE);
1979 unsigned MachOObjectFile::getAnyRelocationLength(
1980 const MachO::any_relocation_info &RE) const {
1981 if (isRelocationScattered(RE))
1982 return getScatteredRelocationLength(RE);
1983 return getPlainRelocationLength(this, RE);
1987 MachOObjectFile::getAnyRelocationType(
1988 const MachO::any_relocation_info &RE) const {
1989 if (isRelocationScattered(RE))
1990 return getScatteredRelocationType(RE);
1991 return getPlainRelocationType(this, RE);
1995 MachOObjectFile::getAnyRelocationSection(
1996 const MachO::any_relocation_info &RE) const {
1997 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1998 return *section_end();
1999 unsigned SecNum = getPlainRelocationSymbolNum(RE);
2000 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
2001 return *section_end();
2003 DRI.d.a = SecNum - 1;
2004 return SectionRef(DRI, this);
2007 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2008 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2009 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2012 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2013 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2014 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2017 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2018 unsigned Index) const {
2019 const char *Sec = getSectionPtr(this, L, Index);
2020 return getStruct<MachO::section>(this, Sec);
2023 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2024 unsigned Index) const {
2025 const char *Sec = getSectionPtr(this, L, Index);
2026 return getStruct<MachO::section_64>(this, Sec);
2030 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2031 const char *P = reinterpret_cast<const char *>(DRI.p);
2032 return getStruct<MachO::nlist>(this, P);
2036 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2037 const char *P = reinterpret_cast<const char *>(DRI.p);
2038 return getStruct<MachO::nlist_64>(this, P);
2041 MachO::linkedit_data_command
2042 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2043 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2046 MachO::segment_command
2047 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2048 return getStruct<MachO::segment_command>(this, L.Ptr);
2051 MachO::segment_command_64
2052 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2053 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2056 MachO::linker_option_command
2057 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2058 return getStruct<MachO::linker_option_command>(this, L.Ptr);
2061 MachO::version_min_command
2062 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2063 return getStruct<MachO::version_min_command>(this, L.Ptr);
2066 MachO::dylib_command
2067 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2068 return getStruct<MachO::dylib_command>(this, L.Ptr);
2071 MachO::dyld_info_command
2072 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2073 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2076 MachO::dylinker_command
2077 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2078 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2082 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2083 return getStruct<MachO::uuid_command>(this, L.Ptr);
2086 MachO::rpath_command
2087 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2088 return getStruct<MachO::rpath_command>(this, L.Ptr);
2091 MachO::source_version_command
2092 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2093 return getStruct<MachO::source_version_command>(this, L.Ptr);
2096 MachO::entry_point_command
2097 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2098 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2101 MachO::encryption_info_command
2102 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2103 return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2106 MachO::encryption_info_command_64
2107 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2108 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2111 MachO::sub_framework_command
2112 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2113 return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2116 MachO::sub_umbrella_command
2117 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2118 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2121 MachO::sub_library_command
2122 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2123 return getStruct<MachO::sub_library_command>(this, L.Ptr);
2126 MachO::sub_client_command
2127 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2128 return getStruct<MachO::sub_client_command>(this, L.Ptr);
2131 MachO::routines_command
2132 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2133 return getStruct<MachO::routines_command>(this, L.Ptr);
2136 MachO::routines_command_64
2137 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2138 return getStruct<MachO::routines_command_64>(this, L.Ptr);
2141 MachO::thread_command
2142 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2143 return getStruct<MachO::thread_command>(this, L.Ptr);
2146 MachO::any_relocation_info
2147 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2152 MachO::section_64 Sect = getSection64(Sec);
2153 Offset = Sect.reloff;
2155 MachO::section Sect = getSection(Sec);
2156 Offset = Sect.reloff;
2159 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2160 getPtr(this, Offset)) + Rel.d.b;
2161 return getStruct<MachO::any_relocation_info>(
2162 this, reinterpret_cast<const char *>(P));
2165 MachO::data_in_code_entry
2166 MachOObjectFile::getDice(DataRefImpl Rel) const {
2167 const char *P = reinterpret_cast<const char *>(Rel.p);
2168 return getStruct<MachO::data_in_code_entry>(this, P);
2171 const MachO::mach_header &MachOObjectFile::getHeader() const {
2175 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2180 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2181 const MachO::dysymtab_command &DLC,
2182 unsigned Index) const {
2183 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2184 return getStruct<uint32_t>(this, getPtr(this, Offset));
2187 MachO::data_in_code_entry
2188 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2189 unsigned Index) const {
2190 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2191 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2194 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2196 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2198 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2199 MachO::symtab_command Cmd;
2200 Cmd.cmd = MachO::LC_SYMTAB;
2201 Cmd.cmdsize = sizeof(MachO::symtab_command);
2209 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2210 if (DysymtabLoadCmd)
2211 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2213 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2214 MachO::dysymtab_command Cmd;
2215 Cmd.cmd = MachO::LC_DYSYMTAB;
2216 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2227 Cmd.extrefsymoff = 0;
2228 Cmd.nextrefsyms = 0;
2229 Cmd.indirectsymoff = 0;
2230 Cmd.nindirectsyms = 0;
2238 MachO::linkedit_data_command
2239 MachOObjectFile::getDataInCodeLoadCommand() const {
2240 if (DataInCodeLoadCmd)
2241 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2243 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2244 MachO::linkedit_data_command Cmd;
2245 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2246 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2252 MachO::linkedit_data_command
2253 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2254 if (LinkOptHintsLoadCmd)
2255 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2257 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2259 MachO::linkedit_data_command Cmd;
2260 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2261 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2267 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2268 if (!DyldInfoLoadCmd)
2269 return ArrayRef<uint8_t>();
2271 MachO::dyld_info_command DyldInfo
2272 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2273 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2274 getPtr(this, DyldInfo.rebase_off));
2275 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2278 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2279 if (!DyldInfoLoadCmd)
2280 return ArrayRef<uint8_t>();
2282 MachO::dyld_info_command DyldInfo
2283 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2284 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2285 getPtr(this, DyldInfo.bind_off));
2286 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2289 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2290 if (!DyldInfoLoadCmd)
2291 return ArrayRef<uint8_t>();
2293 MachO::dyld_info_command DyldInfo
2294 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2295 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2296 getPtr(this, DyldInfo.weak_bind_off));
2297 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2300 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2301 if (!DyldInfoLoadCmd)
2302 return ArrayRef<uint8_t>();
2304 MachO::dyld_info_command DyldInfo
2305 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2306 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2307 getPtr(this, DyldInfo.lazy_bind_off));
2308 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2311 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2312 if (!DyldInfoLoadCmd)
2313 return ArrayRef<uint8_t>();
2315 MachO::dyld_info_command DyldInfo
2316 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2317 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2318 getPtr(this, DyldInfo.export_off));
2319 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2322 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2324 return ArrayRef<uint8_t>();
2325 // Returning a pointer is fine as uuid doesn't need endian swapping.
2326 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2327 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2330 StringRef MachOObjectFile::getStringTableData() const {
2331 MachO::symtab_command S = getSymtabLoadCommand();
2332 return getData().substr(S.stroff, S.strsize);
2335 bool MachOObjectFile::is64Bit() const {
2336 return getType() == getMachOType(false, true) ||
2337 getType() == getMachOType(true, true);
2340 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2341 SmallVectorImpl<uint64_t> &Out) const {
2342 DataExtractor extractor(ObjectFile::getData(), true, 0);
2344 uint32_t offset = Index;
2346 while (uint64_t delta = extractor.getULEB128(&offset)) {
2348 Out.push_back(data);
2352 bool MachOObjectFile::isRelocatableObject() const {
2353 return getHeader().filetype == MachO::MH_OBJECT;
2356 ErrorOr<std::unique_ptr<MachOObjectFile>>
2357 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2358 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2360 std::unique_ptr<MachOObjectFile> Ret;
2361 if (Magic == "\xFE\xED\xFA\xCE")
2362 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2363 else if (Magic == "\xCE\xFA\xED\xFE")
2364 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2365 else if (Magic == "\xFE\xED\xFA\xCF")
2366 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2367 else if (Magic == "\xCF\xFA\xED\xFE")
2368 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2370 return object_error::parse_failed;
2374 return std::move(Ret);