1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Object/MachO.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/raw_ostream.h"
32 using namespace object;
42 static T getStruct(const MachOObjectFile *O, const char *P) {
43 // Don't read before the beginning or past the end of the file
44 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
45 report_fatal_error("Malformed MachO file.");
48 memcpy(&Cmd, P, sizeof(T));
49 if (O->isLittleEndian() != sys::IsLittleEndianHost)
50 MachO::swapStruct(Cmd);
54 template <typename SegmentCmd>
55 static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
57 const unsigned SectionSize = sizeof(SegmentCmd);
58 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
59 S.nsects * SectionSize > Cmdsize - sizeof(S))
61 "Number of sections too large for size of load command.");
66 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
67 const MachOObjectFile::LoadCommandInfo &L) {
69 return getSegmentLoadCommandNumSections(O->getSegment64LoadCommand(L),
72 return getSegmentLoadCommandNumSections(O->getSegmentLoadCommand(L),
76 static bool isPageZeroSegment(const MachOObjectFile *O,
77 const MachOObjectFile::LoadCommandInfo &L) {
79 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
80 return StringRef("__PAGEZERO").equals(S.segname);
82 MachO::segment_command S = O->getSegmentLoadCommand(L);
83 return StringRef("__PAGEZERO").equals(S.segname);
88 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
90 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
92 bool Is64 = O->is64Bit();
93 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
94 sizeof(MachO::segment_command);
95 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
96 sizeof(MachO::section);
98 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
99 return reinterpret_cast<const char*>(SectionAddr);
102 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
103 return O->getData().substr(Offset, 1).data();
106 static MachO::nlist_base
107 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
108 const char *P = reinterpret_cast<const char *>(DRI.p);
109 return getStruct<MachO::nlist_base>(O, P);
112 static StringRef parseSegmentOrSectionName(const char *P) {
116 // Not null terminated, so this is a 16 char string.
117 return StringRef(P, 16);
120 // Helper to advance a section or symbol iterator multiple increments at a time.
122 static void advance(T &it, size_t Val) {
127 static unsigned getCPUType(const MachOObjectFile *O) {
128 return O->getHeader().cputype;
132 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
137 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
138 return RE.r_word0 & 0xffffff;
141 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
142 const MachO::any_relocation_info &RE) {
143 if (O->isLittleEndian())
144 return (RE.r_word1 >> 24) & 1;
145 return (RE.r_word1 >> 7) & 1;
149 getScatteredRelocationPCRel(const MachOObjectFile *O,
150 const MachO::any_relocation_info &RE) {
151 return (RE.r_word0 >> 30) & 1;
154 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
155 const MachO::any_relocation_info &RE) {
156 if (O->isLittleEndian())
157 return (RE.r_word1 >> 25) & 3;
158 return (RE.r_word1 >> 5) & 3;
162 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
163 return (RE.r_word0 >> 28) & 3;
166 static unsigned getPlainRelocationType(const MachOObjectFile *O,
167 const MachO::any_relocation_info &RE) {
168 if (O->isLittleEndian())
169 return RE.r_word1 >> 28;
170 return RE.r_word1 & 0xf;
173 static uint32_t getSectionFlags(const MachOObjectFile *O,
176 MachO::section_64 Sect = O->getSection64(Sec);
179 MachO::section Sect = O->getSection(Sec);
183 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
184 bool Is64bits, std::error_code &EC)
185 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
186 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
187 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
188 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
189 HasPageZeroSegment(false) {
192 Header64 = getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
194 // First fields of MachO::mach_header_64 are the same as
195 // in MachO::mach_header.
196 *reinterpret_cast<MachO::mach_header *>(&this->Header64) =
197 getStruct<MachO::mach_header>(this, getPtr(this, 0));
199 uint32_t LoadCommandCount = getHeader().ncmds;
200 if (LoadCommandCount == 0)
203 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
204 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
206 LoadCommandInfo Load = getFirstLoadCommandInfo();
207 for (unsigned I = 0; I < LoadCommandCount; ++I) {
208 LoadCommands.push_back(Load);
209 if (Load.C.cmd == MachO::LC_SYMTAB) {
210 // Multiple symbol tables
212 EC = object_error::parse_failed;
215 SymtabLoadCmd = Load.Ptr;
216 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
217 // Multiple dynamic symbol tables
218 if (DysymtabLoadCmd) {
219 EC = object_error::parse_failed;
222 DysymtabLoadCmd = Load.Ptr;
223 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
224 // Multiple data in code tables
225 if (DataInCodeLoadCmd) {
226 EC = object_error::parse_failed;
229 DataInCodeLoadCmd = Load.Ptr;
230 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
231 // Multiple linker optimization hint tables
232 if (LinkOptHintsLoadCmd) {
233 EC = object_error::parse_failed;
236 LinkOptHintsLoadCmd = Load.Ptr;
237 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
238 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
239 // Multiple dyldinfo load commands
240 if (DyldInfoLoadCmd) {
241 EC = object_error::parse_failed;
244 DyldInfoLoadCmd = Load.Ptr;
245 } else if (Load.C.cmd == MachO::LC_UUID) {
246 // Multiple UUID load commands
248 EC = object_error::parse_failed;
251 UuidLoadCmd = Load.Ptr;
252 } else if (Load.C.cmd == SegmentLoadType) {
253 const unsigned SegmentLoadSize = this->is64Bit()
254 ? sizeof(MachO::segment_command_64)
255 : sizeof(MachO::segment_command);
256 if (Load.C.cmdsize < SegmentLoadSize)
257 report_fatal_error("Segment load command size is too small.");
259 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
260 for (unsigned J = 0; J < NumSections; ++J) {
261 const char *Sec = getSectionPtr(this, Load, J);
262 Sections.push_back(Sec);
264 if (isPageZeroSegment(this, Load))
265 HasPageZeroSegment = true;
266 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
267 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
268 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
269 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
270 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
271 Libraries.push_back(Load.Ptr);
273 if (I < LoadCommandCount - 1)
274 Load = getNextLoadCommandInfo(Load);
276 assert(LoadCommands.size() == LoadCommandCount);
279 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
280 unsigned SymbolTableEntrySize = is64Bit() ?
281 sizeof(MachO::nlist_64) :
282 sizeof(MachO::nlist);
283 Symb.p += SymbolTableEntrySize;
286 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
287 StringRef &Res) const {
288 StringRef StringTable = getStringTableData();
289 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
290 const char *Start = &StringTable.data()[Entry.n_strx];
291 if (Start < getData().begin() || Start >= getData().end())
293 "Symbol name entry points before beginning or past end of file.");
294 Res = StringRef(Start);
295 return object_error::success;
298 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
299 DataRefImpl DRI = Sec.getRawDataRefImpl();
300 uint32_t Flags = getSectionFlags(this, DRI);
301 return Flags & MachO::SECTION_TYPE;
304 // getIndirectName() returns the name of the alias'ed symbol who's string table
305 // index is in the n_value field.
306 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
307 StringRef &Res) const {
308 StringRef StringTable = getStringTableData();
311 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
312 NValue = Entry.n_value;
313 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
314 return object_error::parse_failed;
316 MachO::nlist Entry = getSymbolTableEntry(Symb);
317 NValue = Entry.n_value;
318 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
319 return object_error::parse_failed;
321 if (NValue >= StringTable.size())
322 return object_error::parse_failed;
323 const char *Start = &StringTable.data()[NValue];
324 Res = StringRef(Start);
325 return object_error::success;
328 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
329 uint64_t &Res) const {
331 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
332 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
334 Res = UnknownAddressOrSize;
338 MachO::nlist Entry = getSymbolTableEntry(Symb);
339 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
341 Res = UnknownAddressOrSize;
345 return object_error::success;
348 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
349 uint32_t flags = getSymbolFlags(DRI);
350 if (flags & SymbolRef::SF_Common) {
351 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
352 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
357 uint64_t MachOObjectFile::getSymbolSize(DataRefImpl DRI) const {
359 getSymbolAddress(DRI, Value);
360 uint32_t flags = getSymbolFlags(DRI);
361 if (flags & SymbolRef::SF_Common)
363 return UnknownAddressOrSize;
366 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
367 SymbolRef::Type &Res) const {
368 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
369 uint8_t n_type = Entry.n_type;
371 Res = SymbolRef::ST_Other;
373 // If this is a STAB debugging symbol, we can do nothing more.
374 if (n_type & MachO::N_STAB) {
375 Res = SymbolRef::ST_Debug;
376 return object_error::success;
379 switch (n_type & MachO::N_TYPE) {
381 Res = SymbolRef::ST_Unknown;
384 Res = SymbolRef::ST_Function;
387 return object_error::success;
390 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
391 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
393 uint8_t MachOType = Entry.n_type;
394 uint16_t MachOFlags = Entry.n_desc;
396 uint32_t Result = SymbolRef::SF_None;
398 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
399 Result |= SymbolRef::SF_Undefined;
401 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
402 Result |= SymbolRef::SF_Indirect;
404 if (MachOType & MachO::N_STAB)
405 Result |= SymbolRef::SF_FormatSpecific;
407 if (MachOType & MachO::N_EXT) {
408 Result |= SymbolRef::SF_Global;
409 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
411 getSymbolAddress(DRI, Value);
412 if (Value && Value != UnknownAddressOrSize)
413 Result |= SymbolRef::SF_Common;
416 if (!(MachOType & MachO::N_PEXT))
417 Result |= SymbolRef::SF_Exported;
420 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
421 Result |= SymbolRef::SF_Weak;
423 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
424 Result |= SymbolRef::SF_Thumb;
426 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
427 Result |= SymbolRef::SF_Absolute;
432 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
433 section_iterator &Res) const {
434 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
435 uint8_t index = Entry.n_sect;
442 if (DRI.d.a >= Sections.size())
443 report_fatal_error("getSymbolSection: Invalid section index.");
444 Res = section_iterator(SectionRef(DRI, this));
447 return object_error::success;
450 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
454 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
455 StringRef &Result) const {
456 ArrayRef<char> Raw = getSectionRawName(Sec);
457 Result = parseSegmentOrSectionName(Raw.data());
458 return object_error::success;
461 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
463 return getSection64(Sec).addr;
464 return getSection(Sec).addr;
467 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
469 return getSection64(Sec).size;
470 return getSection(Sec).size;
473 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
474 StringRef &Res) const {
479 MachO::section_64 Sect = getSection64(Sec);
480 Offset = Sect.offset;
483 MachO::section Sect = getSection(Sec);
484 Offset = Sect.offset;
488 Res = this->getData().substr(Offset, Size);
489 return object_error::success;
492 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
495 MachO::section_64 Sect = getSection64(Sec);
498 MachO::section Sect = getSection(Sec);
502 return uint64_t(1) << Align;
505 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
506 uint32_t Flags = getSectionFlags(this, Sec);
507 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
510 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
511 uint32_t Flags = getSectionFlags(this, Sec);
512 unsigned SectionType = Flags & MachO::SECTION_TYPE;
513 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
514 !(SectionType == MachO::S_ZEROFILL ||
515 SectionType == MachO::S_GB_ZEROFILL);
518 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
519 uint32_t Flags = getSectionFlags(this, Sec);
520 unsigned SectionType = Flags & MachO::SECTION_TYPE;
521 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
522 (SectionType == MachO::S_ZEROFILL ||
523 SectionType == MachO::S_GB_ZEROFILL);
526 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
527 // FIXME: Unimplemented.
531 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
532 DataRefImpl Symb) const {
534 this->getSymbolType(Symb, ST);
535 if (ST == SymbolRef::ST_Unknown)
538 uint64_t SectBegin = getSectionAddress(Sec);
539 uint64_t SectEnd = getSectionSize(Sec);
540 SectEnd += SectBegin;
543 getSymbolAddress(Symb, SymAddr);
544 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
547 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
551 return relocation_iterator(RelocationRef(Ret, this));
555 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
558 MachO::section_64 Sect = getSection64(Sec);
561 MachO::section Sect = getSection(Sec);
568 return relocation_iterator(RelocationRef(Ret, this));
571 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
575 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
576 uint64_t &Res) const {
578 getRelocationOffset(Rel, Offset);
582 uint64_t SecAddress = getSectionAddress(Sec);
583 Res = SecAddress + Offset;
584 return object_error::success;
587 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
588 uint64_t &Res) const {
589 assert(getHeader().filetype == MachO::MH_OBJECT &&
590 "Only implemented for MH_OBJECT");
591 MachO::any_relocation_info RE = getRelocation(Rel);
592 Res = getAnyRelocationAddress(RE);
593 return object_error::success;
597 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
598 MachO::any_relocation_info RE = getRelocation(Rel);
599 if (isRelocationScattered(RE))
602 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
603 bool isExtern = getPlainRelocationExternal(RE);
607 MachO::symtab_command S = getSymtabLoadCommand();
608 unsigned SymbolTableEntrySize = is64Bit() ?
609 sizeof(MachO::nlist_64) :
610 sizeof(MachO::nlist);
611 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
613 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
614 return symbol_iterator(SymbolRef(Sym, this));
618 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
619 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
622 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
623 uint64_t &Res) const {
624 MachO::any_relocation_info RE = getRelocation(Rel);
625 Res = getAnyRelocationType(RE);
626 return object_error::success;
630 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
631 SmallVectorImpl<char> &Result) const {
634 getRelocationType(Rel, RType);
636 unsigned Arch = this->getArch();
640 static const char *const Table[] = {
641 "GENERIC_RELOC_VANILLA",
642 "GENERIC_RELOC_PAIR",
643 "GENERIC_RELOC_SECTDIFF",
644 "GENERIC_RELOC_PB_LA_PTR",
645 "GENERIC_RELOC_LOCAL_SECTDIFF",
646 "GENERIC_RELOC_TLV" };
654 case Triple::x86_64: {
655 static const char *const Table[] = {
656 "X86_64_RELOC_UNSIGNED",
657 "X86_64_RELOC_SIGNED",
658 "X86_64_RELOC_BRANCH",
659 "X86_64_RELOC_GOT_LOAD",
661 "X86_64_RELOC_SUBTRACTOR",
662 "X86_64_RELOC_SIGNED_1",
663 "X86_64_RELOC_SIGNED_2",
664 "X86_64_RELOC_SIGNED_4",
665 "X86_64_RELOC_TLV" };
674 static const char *const Table[] = {
677 "ARM_RELOC_SECTDIFF",
678 "ARM_RELOC_LOCAL_SECTDIFF",
679 "ARM_RELOC_PB_LA_PTR",
681 "ARM_THUMB_RELOC_BR22",
682 "ARM_THUMB_32BIT_BRANCH",
684 "ARM_RELOC_HALF_SECTDIFF" };
692 case Triple::aarch64: {
693 static const char *const Table[] = {
694 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
695 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
696 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
697 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
698 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
702 if (RType >= array_lengthof(Table))
709 static const char *const Table[] = {
718 "PPC_RELOC_SECTDIFF",
719 "PPC_RELOC_PB_LA_PTR",
720 "PPC_RELOC_HI16_SECTDIFF",
721 "PPC_RELOC_LO16_SECTDIFF",
722 "PPC_RELOC_HA16_SECTDIFF",
724 "PPC_RELOC_LO14_SECTDIFF",
725 "PPC_RELOC_LOCAL_SECTDIFF" };
733 case Triple::UnknownArch:
737 Result.append(res.begin(), res.end());
738 return object_error::success;
741 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
742 bool &Result) const {
743 unsigned Arch = getArch();
745 getRelocationType(Rel, Type);
749 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
751 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
752 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
753 } else if (Arch == Triple::x86_64) {
754 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
755 // an X86_64_RELOC_SUBTRACTOR.
756 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
757 DataRefImpl RelPrev = Rel;
760 getRelocationType(RelPrev, PrevType);
761 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
766 return object_error::success;
769 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
770 MachO::any_relocation_info RE = getRelocation(Rel);
771 return getAnyRelocationLength(RE);
775 // guessLibraryShortName() is passed a name of a dynamic library and returns a
776 // guess on what the short name is. Then name is returned as a substring of the
777 // StringRef Name passed in. The name of the dynamic library is recognized as
778 // a framework if it has one of the two following forms:
779 // Foo.framework/Versions/A/Foo
781 // Where A and Foo can be any string. And may contain a trailing suffix
782 // starting with an underbar. If the Name is recognized as a framework then
783 // isFramework is set to true else it is set to false. If the Name has a
784 // suffix then Suffix is set to the substring in Name that contains the suffix
785 // else it is set to a NULL StringRef.
787 // The Name of the dynamic library is recognized as a library name if it has
788 // one of the two following forms:
791 // The library may have a suffix trailing the name Foo of the form:
792 // libFoo_profile.A.dylib
793 // libFoo_profile.dylib
795 // The Name of the dynamic library is also recognized as a library name if it
796 // has the following form:
799 // If the Name of the dynamic library is none of the forms above then a NULL
800 // StringRef is returned.
802 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
805 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
806 size_t a, b, c, d, Idx;
809 Suffix = StringRef();
811 // Pull off the last component and make Foo point to it
813 if (a == Name.npos || a == 0)
815 Foo = Name.slice(a+1, Name.npos);
817 // Look for a suffix starting with a '_'
818 Idx = Foo.rfind('_');
819 if (Idx != Foo.npos && Foo.size() >= 2) {
820 Suffix = Foo.slice(Idx, Foo.npos);
821 Foo = Foo.slice(0, Idx);
824 // First look for the form Foo.framework/Foo
825 b = Name.rfind('/', a);
830 F = Name.slice(Idx, Idx + Foo.size());
831 DotFramework = Name.slice(Idx + Foo.size(),
832 Idx + Foo.size() + sizeof(".framework/")-1);
833 if (F == Foo && DotFramework == ".framework/") {
838 // Next look for the form Foo.framework/Versions/A/Foo
841 c = Name.rfind('/', b);
842 if (c == Name.npos || c == 0)
844 V = Name.slice(c+1, Name.npos);
845 if (!V.startswith("Versions/"))
847 d = Name.rfind('/', c);
852 F = Name.slice(Idx, Idx + Foo.size());
853 DotFramework = Name.slice(Idx + Foo.size(),
854 Idx + Foo.size() + sizeof(".framework/")-1);
855 if (F == Foo && DotFramework == ".framework/") {
861 // pull off the suffix after the "." and make a point to it
863 if (a == Name.npos || a == 0)
865 Dylib = Name.slice(a, Name.npos);
866 if (Dylib != ".dylib")
869 // First pull off the version letter for the form Foo.A.dylib if any.
871 Dot = Name.slice(a-2, a-1);
876 b = Name.rfind('/', a);
881 // ignore any suffix after an underbar like Foo_profile.A.dylib
882 Idx = Name.find('_', b);
883 if (Idx != Name.npos && Idx != b) {
884 Lib = Name.slice(b, Idx);
885 Suffix = Name.slice(Idx, a);
888 Lib = Name.slice(b, a);
889 // There are incorrect library names of the form:
890 // libATS.A_profile.dylib so check for these.
891 if (Lib.size() >= 3) {
892 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
894 Lib = Lib.slice(0, Lib.size()-2);
899 Qtx = Name.slice(a, Name.npos);
902 b = Name.rfind('/', a);
904 Lib = Name.slice(0, a);
906 Lib = Name.slice(b+1, a);
907 // There are library names of the form: QT.A.qtx so check for these.
908 if (Lib.size() >= 3) {
909 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
911 Lib = Lib.slice(0, Lib.size()-2);
916 // getLibraryShortNameByIndex() is used to get the short name of the library
917 // for an undefined symbol in a linked Mach-O binary that was linked with the
918 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
919 // It is passed the index (0 - based) of the library as translated from
920 // GET_LIBRARY_ORDINAL (1 - based).
921 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
922 StringRef &Res) const {
923 if (Index >= Libraries.size())
924 return object_error::parse_failed;
926 // If the cache of LibrariesShortNames is not built up do that first for
927 // all the Libraries.
928 if (LibrariesShortNames.size() == 0) {
929 for (unsigned i = 0; i < Libraries.size(); i++) {
930 MachO::dylib_command D =
931 getStruct<MachO::dylib_command>(this, Libraries[i]);
932 if (D.dylib.name >= D.cmdsize)
933 return object_error::parse_failed;
934 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
935 StringRef Name = StringRef(P);
936 if (D.dylib.name+Name.size() >= D.cmdsize)
937 return object_error::parse_failed;
940 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
941 if (shortName.empty())
942 LibrariesShortNames.push_back(Name);
944 LibrariesShortNames.push_back(shortName);
948 Res = LibrariesShortNames[Index];
949 return object_error::success;
952 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
953 return getSymbolByIndex(0);
956 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
959 return basic_symbol_iterator(SymbolRef(DRI, this));
961 MachO::symtab_command Symtab = getSymtabLoadCommand();
962 unsigned SymbolTableEntrySize = is64Bit() ?
963 sizeof(MachO::nlist_64) :
964 sizeof(MachO::nlist);
965 unsigned Offset = Symtab.symoff +
966 Symtab.nsyms * SymbolTableEntrySize;
967 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
968 return basic_symbol_iterator(SymbolRef(DRI, this));
971 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
974 return basic_symbol_iterator(SymbolRef(DRI, this));
976 MachO::symtab_command Symtab = getSymtabLoadCommand();
977 if (Index >= Symtab.nsyms)
978 report_fatal_error("Requested symbol index is out of range.");
979 unsigned SymbolTableEntrySize =
980 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
981 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
982 DRI.p += Index * SymbolTableEntrySize;
983 return basic_symbol_iterator(SymbolRef(DRI, this));
986 section_iterator MachOObjectFile::section_begin() const {
988 return section_iterator(SectionRef(DRI, this));
991 section_iterator MachOObjectFile::section_end() const {
993 DRI.d.a = Sections.size();
994 return section_iterator(SectionRef(DRI, this));
997 uint8_t MachOObjectFile::getBytesInAddress() const {
998 return is64Bit() ? 8 : 4;
1001 StringRef MachOObjectFile::getFileFormatName() const {
1002 unsigned CPUType = getCPUType(this);
1005 case llvm::MachO::CPU_TYPE_I386:
1006 return "Mach-O 32-bit i386";
1007 case llvm::MachO::CPU_TYPE_ARM:
1008 return "Mach-O arm";
1009 case llvm::MachO::CPU_TYPE_POWERPC:
1010 return "Mach-O 32-bit ppc";
1012 return "Mach-O 32-bit unknown";
1017 case llvm::MachO::CPU_TYPE_X86_64:
1018 return "Mach-O 64-bit x86-64";
1019 case llvm::MachO::CPU_TYPE_ARM64:
1020 return "Mach-O arm64";
1021 case llvm::MachO::CPU_TYPE_POWERPC64:
1022 return "Mach-O 64-bit ppc64";
1024 return "Mach-O 64-bit unknown";
1028 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1030 case llvm::MachO::CPU_TYPE_I386:
1032 case llvm::MachO::CPU_TYPE_X86_64:
1033 return Triple::x86_64;
1034 case llvm::MachO::CPU_TYPE_ARM:
1036 case llvm::MachO::CPU_TYPE_ARM64:
1037 return Triple::aarch64;
1038 case llvm::MachO::CPU_TYPE_POWERPC:
1040 case llvm::MachO::CPU_TYPE_POWERPC64:
1041 return Triple::ppc64;
1043 return Triple::UnknownArch;
1047 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1048 const char **McpuDefault) {
1050 *McpuDefault = nullptr;
1053 case MachO::CPU_TYPE_I386:
1054 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1055 case MachO::CPU_SUBTYPE_I386_ALL:
1056 return Triple("i386-apple-darwin");
1060 case MachO::CPU_TYPE_X86_64:
1061 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1062 case MachO::CPU_SUBTYPE_X86_64_ALL:
1063 return Triple("x86_64-apple-darwin");
1064 case MachO::CPU_SUBTYPE_X86_64_H:
1065 return Triple("x86_64h-apple-darwin");
1069 case MachO::CPU_TYPE_ARM:
1070 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1071 case MachO::CPU_SUBTYPE_ARM_V4T:
1072 return Triple("armv4t-apple-darwin");
1073 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1074 return Triple("armv5e-apple-darwin");
1075 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1076 return Triple("xscale-apple-darwin");
1077 case MachO::CPU_SUBTYPE_ARM_V6:
1078 return Triple("armv6-apple-darwin");
1079 case MachO::CPU_SUBTYPE_ARM_V6M:
1081 *McpuDefault = "cortex-m0";
1082 return Triple("armv6m-apple-darwin");
1083 case MachO::CPU_SUBTYPE_ARM_V7:
1084 return Triple("armv7-apple-darwin");
1085 case MachO::CPU_SUBTYPE_ARM_V7EM:
1087 *McpuDefault = "cortex-m4";
1088 return Triple("armv7em-apple-darwin");
1089 case MachO::CPU_SUBTYPE_ARM_V7K:
1090 return Triple("armv7k-apple-darwin");
1091 case MachO::CPU_SUBTYPE_ARM_V7M:
1093 *McpuDefault = "cortex-m3";
1094 return Triple("armv7m-apple-darwin");
1095 case MachO::CPU_SUBTYPE_ARM_V7S:
1096 return Triple("armv7s-apple-darwin");
1100 case MachO::CPU_TYPE_ARM64:
1101 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1102 case MachO::CPU_SUBTYPE_ARM64_ALL:
1103 return Triple("arm64-apple-darwin");
1107 case MachO::CPU_TYPE_POWERPC:
1108 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1109 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1110 return Triple("ppc-apple-darwin");
1114 case MachO::CPU_TYPE_POWERPC64:
1115 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1116 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1117 return Triple("ppc64-apple-darwin");
1126 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1127 const char **McpuDefault) {
1129 *McpuDefault = nullptr;
1132 case MachO::CPU_TYPE_ARM:
1133 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1134 case MachO::CPU_SUBTYPE_ARM_V4T:
1135 return Triple("thumbv4t-apple-darwin");
1136 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1137 return Triple("thumbv5e-apple-darwin");
1138 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1139 return Triple("xscale-apple-darwin");
1140 case MachO::CPU_SUBTYPE_ARM_V6:
1141 return Triple("thumbv6-apple-darwin");
1142 case MachO::CPU_SUBTYPE_ARM_V6M:
1144 *McpuDefault = "cortex-m0";
1145 return Triple("thumbv6m-apple-darwin");
1146 case MachO::CPU_SUBTYPE_ARM_V7:
1147 return Triple("thumbv7-apple-darwin");
1148 case MachO::CPU_SUBTYPE_ARM_V7EM:
1150 *McpuDefault = "cortex-m4";
1151 return Triple("thumbv7em-apple-darwin");
1152 case MachO::CPU_SUBTYPE_ARM_V7K:
1153 return Triple("thumbv7k-apple-darwin");
1154 case MachO::CPU_SUBTYPE_ARM_V7M:
1156 *McpuDefault = "cortex-m3";
1157 return Triple("thumbv7m-apple-darwin");
1158 case MachO::CPU_SUBTYPE_ARM_V7S:
1159 return Triple("thumbv7s-apple-darwin");
1168 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1169 const char **McpuDefault,
1170 Triple *ThumbTriple) {
1171 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1172 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1177 Triple MachOObjectFile::getHostArch() {
1178 return Triple(sys::getDefaultTargetTriple());
1181 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1182 return StringSwitch<bool>(ArchFlag)
1184 .Case("x86_64", true)
1185 .Case("x86_64h", true)
1186 .Case("armv4t", true)
1188 .Case("armv5e", true)
1189 .Case("armv6", true)
1190 .Case("armv6m", true)
1191 .Case("armv7em", true)
1192 .Case("armv7k", true)
1193 .Case("armv7m", true)
1194 .Case("armv7s", true)
1195 .Case("arm64", true)
1197 .Case("ppc64", true)
1201 unsigned MachOObjectFile::getArch() const {
1202 return getArch(getCPUType(this));
1205 Triple MachOObjectFile::getArch(const char **McpuDefault,
1206 Triple *ThumbTriple) const {
1207 const auto &Header = getHeader();
1208 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1209 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1212 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1215 return section_rel_begin(DRI);
1218 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1221 return section_rel_end(DRI);
1224 dice_iterator MachOObjectFile::begin_dices() const {
1226 if (!DataInCodeLoadCmd)
1227 return dice_iterator(DiceRef(DRI, this));
1229 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1230 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1231 return dice_iterator(DiceRef(DRI, this));
1234 dice_iterator MachOObjectFile::end_dices() const {
1236 if (!DataInCodeLoadCmd)
1237 return dice_iterator(DiceRef(DRI, this));
1239 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1240 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1241 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1242 return dice_iterator(DiceRef(DRI, this));
1245 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1246 : Trie(T), Malformed(false), Done(false) { }
1248 void ExportEntry::moveToFirst() {
1250 pushDownUntilBottom();
1253 void ExportEntry::moveToEnd() {
1258 bool ExportEntry::operator==(const ExportEntry &Other) const {
1259 // Common case, one at end, other iterating from begin.
1260 if (Done || Other.Done)
1261 return (Done == Other.Done);
1262 // Not equal if different stack sizes.
1263 if (Stack.size() != Other.Stack.size())
1265 // Not equal if different cumulative strings.
1266 if (!CumulativeString.equals(Other.CumulativeString))
1268 // Equal if all nodes in both stacks match.
1269 for (unsigned i=0; i < Stack.size(); ++i) {
1270 if (Stack[i].Start != Other.Stack[i].Start)
1276 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1278 uint64_t Result = decodeULEB128(Ptr, &Count);
1280 if (Ptr > Trie.end()) {
1287 StringRef ExportEntry::name() const {
1288 return CumulativeString;
1291 uint64_t ExportEntry::flags() const {
1292 return Stack.back().Flags;
1295 uint64_t ExportEntry::address() const {
1296 return Stack.back().Address;
1299 uint64_t ExportEntry::other() const {
1300 return Stack.back().Other;
1303 StringRef ExportEntry::otherName() const {
1304 const char* ImportName = Stack.back().ImportName;
1306 return StringRef(ImportName);
1310 uint32_t ExportEntry::nodeOffset() const {
1311 return Stack.back().Start - Trie.begin();
1314 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1315 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1316 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1317 ParentStringLength(0), IsExportNode(false) {
1320 void ExportEntry::pushNode(uint64_t offset) {
1321 const uint8_t *Ptr = Trie.begin() + offset;
1322 NodeState State(Ptr);
1323 uint64_t ExportInfoSize = readULEB128(State.Current);
1324 State.IsExportNode = (ExportInfoSize != 0);
1325 const uint8_t* Children = State.Current + ExportInfoSize;
1326 if (State.IsExportNode) {
1327 State.Flags = readULEB128(State.Current);
1328 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1330 State.Other = readULEB128(State.Current); // dylib ordinal
1331 State.ImportName = reinterpret_cast<const char*>(State.Current);
1333 State.Address = readULEB128(State.Current);
1334 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1335 State.Other = readULEB128(State.Current);
1338 State.ChildCount = *Children;
1339 State.Current = Children + 1;
1340 State.NextChildIndex = 0;
1341 State.ParentStringLength = CumulativeString.size();
1342 Stack.push_back(State);
1345 void ExportEntry::pushDownUntilBottom() {
1346 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1347 NodeState &Top = Stack.back();
1348 CumulativeString.resize(Top.ParentStringLength);
1349 for (;*Top.Current != 0; Top.Current++) {
1350 char C = *Top.Current;
1351 CumulativeString.push_back(C);
1354 uint64_t childNodeIndex = readULEB128(Top.Current);
1355 Top.NextChildIndex += 1;
1356 pushNode(childNodeIndex);
1358 if (!Stack.back().IsExportNode) {
1364 // We have a trie data structure and need a way to walk it that is compatible
1365 // with the C++ iterator model. The solution is a non-recursive depth first
1366 // traversal where the iterator contains a stack of parent nodes along with a
1367 // string that is the accumulation of all edge strings along the parent chain
1370 // There is one "export" node for each exported symbol. But because some
1371 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1372 // node may have child nodes too.
1374 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1375 // child until hitting a node with no children (which is an export node or
1376 // else the trie is malformed). On the way down, each node is pushed on the
1377 // stack ivar. If there is no more ways down, it pops up one and tries to go
1378 // down a sibling path until a childless node is reached.
1379 void ExportEntry::moveNext() {
1380 if (Stack.empty() || !Stack.back().IsExportNode) {
1387 while (!Stack.empty()) {
1388 NodeState &Top = Stack.back();
1389 if (Top.NextChildIndex < Top.ChildCount) {
1390 pushDownUntilBottom();
1391 // Now at the next export node.
1394 if (Top.IsExportNode) {
1395 // This node has no children but is itself an export node.
1396 CumulativeString.resize(Top.ParentStringLength);
1405 iterator_range<export_iterator>
1406 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1407 ExportEntry Start(Trie);
1408 if (Trie.size() == 0)
1411 Start.moveToFirst();
1413 ExportEntry Finish(Trie);
1416 return iterator_range<export_iterator>(export_iterator(Start),
1417 export_iterator(Finish));
1420 iterator_range<export_iterator> MachOObjectFile::exports() const {
1421 return exports(getDyldInfoExportsTrie());
1425 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1426 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1427 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1428 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1430 void MachORebaseEntry::moveToFirst() {
1431 Ptr = Opcodes.begin();
1435 void MachORebaseEntry::moveToEnd() {
1436 Ptr = Opcodes.end();
1437 RemainingLoopCount = 0;
1441 void MachORebaseEntry::moveNext() {
1442 // If in the middle of some loop, move to next rebasing in loop.
1443 SegmentOffset += AdvanceAmount;
1444 if (RemainingLoopCount) {
1445 --RemainingLoopCount;
1448 if (Ptr == Opcodes.end()) {
1453 while (More && !Malformed) {
1454 // Parse next opcode and set up next loop.
1455 uint8_t Byte = *Ptr++;
1456 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1457 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1459 case MachO::REBASE_OPCODE_DONE:
1463 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1465 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1466 RebaseType = ImmValue;
1469 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1470 << "RebaseType=" << (int) RebaseType << "\n");
1472 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1473 SegmentIndex = ImmValue;
1474 SegmentOffset = readULEB128();
1477 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1478 << "SegmentIndex=" << SegmentIndex << ", "
1479 << format("SegmentOffset=0x%06X", SegmentOffset)
1482 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1483 SegmentOffset += readULEB128();
1484 DEBUG_WITH_TYPE("mach-o-rebase",
1485 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1486 << format("SegmentOffset=0x%06X",
1487 SegmentOffset) << "\n");
1489 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1490 SegmentOffset += ImmValue * PointerSize;
1491 DEBUG_WITH_TYPE("mach-o-rebase",
1492 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1493 << format("SegmentOffset=0x%06X",
1494 SegmentOffset) << "\n");
1496 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1497 AdvanceAmount = PointerSize;
1498 RemainingLoopCount = ImmValue - 1;
1501 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1502 << format("SegmentOffset=0x%06X", SegmentOffset)
1503 << ", AdvanceAmount=" << AdvanceAmount
1504 << ", RemainingLoopCount=" << RemainingLoopCount
1507 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1508 AdvanceAmount = PointerSize;
1509 RemainingLoopCount = readULEB128() - 1;
1512 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1513 << format("SegmentOffset=0x%06X", SegmentOffset)
1514 << ", AdvanceAmount=" << AdvanceAmount
1515 << ", RemainingLoopCount=" << RemainingLoopCount
1518 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1519 AdvanceAmount = readULEB128() + PointerSize;
1520 RemainingLoopCount = 0;
1523 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1524 << format("SegmentOffset=0x%06X", SegmentOffset)
1525 << ", AdvanceAmount=" << AdvanceAmount
1526 << ", RemainingLoopCount=" << RemainingLoopCount
1529 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1530 RemainingLoopCount = readULEB128() - 1;
1531 AdvanceAmount = readULEB128() + PointerSize;
1534 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1535 << format("SegmentOffset=0x%06X", SegmentOffset)
1536 << ", AdvanceAmount=" << AdvanceAmount
1537 << ", RemainingLoopCount=" << RemainingLoopCount
1546 uint64_t MachORebaseEntry::readULEB128() {
1548 uint64_t Result = decodeULEB128(Ptr, &Count);
1550 if (Ptr > Opcodes.end()) {
1551 Ptr = Opcodes.end();
1557 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1559 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1561 StringRef MachORebaseEntry::typeName() const {
1562 switch (RebaseType) {
1563 case MachO::REBASE_TYPE_POINTER:
1565 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1566 return "text abs32";
1567 case MachO::REBASE_TYPE_TEXT_PCREL32:
1568 return "text rel32";
1573 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1574 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1575 return (Ptr == Other.Ptr) &&
1576 (RemainingLoopCount == Other.RemainingLoopCount) &&
1577 (Done == Other.Done);
1580 iterator_range<rebase_iterator>
1581 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1582 MachORebaseEntry Start(Opcodes, is64);
1583 Start.moveToFirst();
1585 MachORebaseEntry Finish(Opcodes, is64);
1588 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1589 rebase_iterator(Finish));
1592 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1593 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1597 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1599 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1600 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1601 BindType(0), PointerSize(is64Bit ? 8 : 4),
1602 TableKind(BK), Malformed(false), Done(false) {}
1604 void MachOBindEntry::moveToFirst() {
1605 Ptr = Opcodes.begin();
1609 void MachOBindEntry::moveToEnd() {
1610 Ptr = Opcodes.end();
1611 RemainingLoopCount = 0;
1615 void MachOBindEntry::moveNext() {
1616 // If in the middle of some loop, move to next binding in loop.
1617 SegmentOffset += AdvanceAmount;
1618 if (RemainingLoopCount) {
1619 --RemainingLoopCount;
1622 if (Ptr == Opcodes.end()) {
1627 while (More && !Malformed) {
1628 // Parse next opcode and set up next loop.
1629 uint8_t Byte = *Ptr++;
1630 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1631 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1632 int8_t SignExtended;
1633 const uint8_t *SymStart;
1635 case MachO::BIND_OPCODE_DONE:
1636 if (TableKind == Kind::Lazy) {
1637 // Lazying bindings have a DONE opcode between entries. Need to ignore
1638 // it to advance to next entry. But need not if this is last entry.
1639 bool NotLastEntry = false;
1640 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1642 NotLastEntry = true;
1651 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1653 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1657 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1658 << "Ordinal=" << Ordinal << "\n");
1660 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1661 Ordinal = readULEB128();
1664 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1665 << "Ordinal=" << Ordinal << "\n");
1667 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1669 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1670 Ordinal = SignExtended;
1675 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1676 << "Ordinal=" << Ordinal << "\n");
1678 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1684 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1689 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1690 << "SymbolName=" << SymbolName << "\n");
1691 if (TableKind == Kind::Weak) {
1692 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1696 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1697 BindType = ImmValue;
1700 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1701 << "BindType=" << (int)BindType << "\n");
1703 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1704 Addend = readSLEB128();
1705 if (TableKind == Kind::Lazy)
1709 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1710 << "Addend=" << Addend << "\n");
1712 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1713 SegmentIndex = ImmValue;
1714 SegmentOffset = readULEB128();
1717 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1718 << "SegmentIndex=" << SegmentIndex << ", "
1719 << format("SegmentOffset=0x%06X", SegmentOffset)
1722 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1723 SegmentOffset += readULEB128();
1724 DEBUG_WITH_TYPE("mach-o-bind",
1725 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1726 << format("SegmentOffset=0x%06X",
1727 SegmentOffset) << "\n");
1729 case MachO::BIND_OPCODE_DO_BIND:
1730 AdvanceAmount = PointerSize;
1731 RemainingLoopCount = 0;
1732 DEBUG_WITH_TYPE("mach-o-bind",
1733 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1734 << format("SegmentOffset=0x%06X",
1735 SegmentOffset) << "\n");
1737 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1738 AdvanceAmount = readULEB128() + PointerSize;
1739 RemainingLoopCount = 0;
1740 if (TableKind == Kind::Lazy)
1744 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1745 << format("SegmentOffset=0x%06X", SegmentOffset)
1746 << ", AdvanceAmount=" << AdvanceAmount
1747 << ", RemainingLoopCount=" << RemainingLoopCount
1750 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1751 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1752 RemainingLoopCount = 0;
1753 if (TableKind == Kind::Lazy)
1755 DEBUG_WITH_TYPE("mach-o-bind",
1757 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1758 << format("SegmentOffset=0x%06X",
1759 SegmentOffset) << "\n");
1761 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1762 RemainingLoopCount = readULEB128() - 1;
1763 AdvanceAmount = readULEB128() + PointerSize;
1764 if (TableKind == Kind::Lazy)
1768 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1769 << format("SegmentOffset=0x%06X", SegmentOffset)
1770 << ", AdvanceAmount=" << AdvanceAmount
1771 << ", RemainingLoopCount=" << RemainingLoopCount
1780 uint64_t MachOBindEntry::readULEB128() {
1782 uint64_t Result = decodeULEB128(Ptr, &Count);
1784 if (Ptr > Opcodes.end()) {
1785 Ptr = Opcodes.end();
1791 int64_t MachOBindEntry::readSLEB128() {
1793 int64_t Result = decodeSLEB128(Ptr, &Count);
1795 if (Ptr > Opcodes.end()) {
1796 Ptr = Opcodes.end();
1803 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1805 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1807 StringRef MachOBindEntry::typeName() const {
1809 case MachO::BIND_TYPE_POINTER:
1811 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1812 return "text abs32";
1813 case MachO::BIND_TYPE_TEXT_PCREL32:
1814 return "text rel32";
1819 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1821 int64_t MachOBindEntry::addend() const { return Addend; }
1823 uint32_t MachOBindEntry::flags() const { return Flags; }
1825 int MachOBindEntry::ordinal() const { return Ordinal; }
1827 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1828 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1829 return (Ptr == Other.Ptr) &&
1830 (RemainingLoopCount == Other.RemainingLoopCount) &&
1831 (Done == Other.Done);
1834 iterator_range<bind_iterator>
1835 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1836 MachOBindEntry::Kind BKind) {
1837 MachOBindEntry Start(Opcodes, is64, BKind);
1838 Start.moveToFirst();
1840 MachOBindEntry Finish(Opcodes, is64, BKind);
1843 return iterator_range<bind_iterator>(bind_iterator(Start),
1844 bind_iterator(Finish));
1847 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1848 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1849 MachOBindEntry::Kind::Regular);
1852 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1853 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1854 MachOBindEntry::Kind::Lazy);
1857 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1858 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1859 MachOBindEntry::Kind::Weak);
1862 MachOObjectFile::load_command_iterator
1863 MachOObjectFile::begin_load_commands() const {
1864 return LoadCommands.begin();
1867 MachOObjectFile::load_command_iterator
1868 MachOObjectFile::end_load_commands() const {
1869 return LoadCommands.end();
1872 iterator_range<MachOObjectFile::load_command_iterator>
1873 MachOObjectFile::load_commands() const {
1874 return iterator_range<load_command_iterator>(begin_load_commands(),
1875 end_load_commands());
1879 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1880 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1881 return parseSegmentOrSectionName(Raw.data());
1885 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1886 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1887 const section_base *Base =
1888 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1889 return makeArrayRef(Base->sectname);
1893 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1894 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1895 const section_base *Base =
1896 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1897 return makeArrayRef(Base->segname);
1901 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1903 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1905 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1908 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1909 const MachO::any_relocation_info &RE) const {
1910 if (isLittleEndian())
1911 return RE.r_word1 & 0xffffff;
1912 return RE.r_word1 >> 8;
1915 bool MachOObjectFile::getPlainRelocationExternal(
1916 const MachO::any_relocation_info &RE) const {
1917 if (isLittleEndian())
1918 return (RE.r_word1 >> 27) & 1;
1919 return (RE.r_word1 >> 4) & 1;
1922 bool MachOObjectFile::getScatteredRelocationScattered(
1923 const MachO::any_relocation_info &RE) const {
1924 return RE.r_word0 >> 31;
1927 uint32_t MachOObjectFile::getScatteredRelocationValue(
1928 const MachO::any_relocation_info &RE) const {
1932 uint32_t MachOObjectFile::getScatteredRelocationType(
1933 const MachO::any_relocation_info &RE) const {
1934 return (RE.r_word0 >> 24) & 0xf;
1937 unsigned MachOObjectFile::getAnyRelocationAddress(
1938 const MachO::any_relocation_info &RE) const {
1939 if (isRelocationScattered(RE))
1940 return getScatteredRelocationAddress(RE);
1941 return getPlainRelocationAddress(RE);
1944 unsigned MachOObjectFile::getAnyRelocationPCRel(
1945 const MachO::any_relocation_info &RE) const {
1946 if (isRelocationScattered(RE))
1947 return getScatteredRelocationPCRel(this, RE);
1948 return getPlainRelocationPCRel(this, RE);
1951 unsigned MachOObjectFile::getAnyRelocationLength(
1952 const MachO::any_relocation_info &RE) const {
1953 if (isRelocationScattered(RE))
1954 return getScatteredRelocationLength(RE);
1955 return getPlainRelocationLength(this, RE);
1959 MachOObjectFile::getAnyRelocationType(
1960 const MachO::any_relocation_info &RE) const {
1961 if (isRelocationScattered(RE))
1962 return getScatteredRelocationType(RE);
1963 return getPlainRelocationType(this, RE);
1967 MachOObjectFile::getAnyRelocationSection(
1968 const MachO::any_relocation_info &RE) const {
1969 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1970 return *section_end();
1971 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1974 return SectionRef(DRI, this);
1977 MachOObjectFile::LoadCommandInfo
1978 MachOObjectFile::getFirstLoadCommandInfo() const {
1979 MachOObjectFile::LoadCommandInfo Load;
1981 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1982 sizeof(MachO::mach_header);
1983 Load.Ptr = getPtr(this, HeaderSize);
1984 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1985 if (Load.C.cmdsize < 8)
1986 report_fatal_error("Load command with size < 8 bytes.");
1990 MachOObjectFile::LoadCommandInfo
1991 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1992 MachOObjectFile::LoadCommandInfo Next;
1993 Next.Ptr = L.Ptr + L.C.cmdsize;
1994 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1995 if (Next.C.cmdsize < 8)
1996 report_fatal_error("Load command with size < 8 bytes.");
2000 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2001 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2002 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2005 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2006 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2007 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2010 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2011 unsigned Index) const {
2012 const char *Sec = getSectionPtr(this, L, Index);
2013 return getStruct<MachO::section>(this, Sec);
2016 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2017 unsigned Index) const {
2018 const char *Sec = getSectionPtr(this, L, Index);
2019 return getStruct<MachO::section_64>(this, Sec);
2023 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2024 const char *P = reinterpret_cast<const char *>(DRI.p);
2025 return getStruct<MachO::nlist>(this, P);
2029 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2030 const char *P = reinterpret_cast<const char *>(DRI.p);
2031 return getStruct<MachO::nlist_64>(this, P);
2034 MachO::linkedit_data_command
2035 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2036 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2039 MachO::segment_command
2040 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2041 return getStruct<MachO::segment_command>(this, L.Ptr);
2044 MachO::segment_command_64
2045 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2046 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2049 MachO::linker_option_command
2050 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2051 return getStruct<MachO::linker_option_command>(this, L.Ptr);
2054 MachO::version_min_command
2055 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2056 return getStruct<MachO::version_min_command>(this, L.Ptr);
2059 MachO::dylib_command
2060 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2061 return getStruct<MachO::dylib_command>(this, L.Ptr);
2064 MachO::dyld_info_command
2065 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2066 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2069 MachO::dylinker_command
2070 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2071 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2075 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2076 return getStruct<MachO::uuid_command>(this, L.Ptr);
2079 MachO::rpath_command
2080 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2081 return getStruct<MachO::rpath_command>(this, L.Ptr);
2084 MachO::source_version_command
2085 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2086 return getStruct<MachO::source_version_command>(this, L.Ptr);
2089 MachO::entry_point_command
2090 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2091 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2094 MachO::encryption_info_command
2095 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2096 return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2099 MachO::encryption_info_command_64
2100 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2101 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2104 MachO::sub_framework_command
2105 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2106 return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2109 MachO::sub_umbrella_command
2110 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2111 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2114 MachO::sub_library_command
2115 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2116 return getStruct<MachO::sub_library_command>(this, L.Ptr);
2119 MachO::sub_client_command
2120 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2121 return getStruct<MachO::sub_client_command>(this, L.Ptr);
2124 MachO::routines_command
2125 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2126 return getStruct<MachO::routines_command>(this, L.Ptr);
2129 MachO::routines_command_64
2130 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2131 return getStruct<MachO::routines_command_64>(this, L.Ptr);
2134 MachO::thread_command
2135 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2136 return getStruct<MachO::thread_command>(this, L.Ptr);
2139 MachO::any_relocation_info
2140 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2145 MachO::section_64 Sect = getSection64(Sec);
2146 Offset = Sect.reloff;
2148 MachO::section Sect = getSection(Sec);
2149 Offset = Sect.reloff;
2152 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2153 getPtr(this, Offset)) + Rel.d.b;
2154 return getStruct<MachO::any_relocation_info>(
2155 this, reinterpret_cast<const char *>(P));
2158 MachO::data_in_code_entry
2159 MachOObjectFile::getDice(DataRefImpl Rel) const {
2160 const char *P = reinterpret_cast<const char *>(Rel.p);
2161 return getStruct<MachO::data_in_code_entry>(this, P);
2164 const MachO::mach_header &MachOObjectFile::getHeader() const {
2165 // First fields of MachO::mach_header_64 are the same as
2166 // in MachO::mach_header.
2167 return *reinterpret_cast<const MachO::mach_header *>(&this->Header64);
2170 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2175 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2176 const MachO::dysymtab_command &DLC,
2177 unsigned Index) const {
2178 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2179 return getStruct<uint32_t>(this, getPtr(this, Offset));
2182 MachO::data_in_code_entry
2183 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2184 unsigned Index) const {
2185 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2186 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2189 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2191 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2193 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2194 MachO::symtab_command Cmd;
2195 Cmd.cmd = MachO::LC_SYMTAB;
2196 Cmd.cmdsize = sizeof(MachO::symtab_command);
2204 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2205 if (DysymtabLoadCmd)
2206 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2208 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2209 MachO::dysymtab_command Cmd;
2210 Cmd.cmd = MachO::LC_DYSYMTAB;
2211 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2222 Cmd.extrefsymoff = 0;
2223 Cmd.nextrefsyms = 0;
2224 Cmd.indirectsymoff = 0;
2225 Cmd.nindirectsyms = 0;
2233 MachO::linkedit_data_command
2234 MachOObjectFile::getDataInCodeLoadCommand() const {
2235 if (DataInCodeLoadCmd)
2236 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2238 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2239 MachO::linkedit_data_command Cmd;
2240 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2241 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2247 MachO::linkedit_data_command
2248 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2249 if (LinkOptHintsLoadCmd)
2250 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2252 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2254 MachO::linkedit_data_command Cmd;
2255 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2256 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2262 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2263 if (!DyldInfoLoadCmd)
2264 return ArrayRef<uint8_t>();
2266 MachO::dyld_info_command DyldInfo
2267 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2268 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2269 getPtr(this, DyldInfo.rebase_off));
2270 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2273 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2274 if (!DyldInfoLoadCmd)
2275 return ArrayRef<uint8_t>();
2277 MachO::dyld_info_command DyldInfo
2278 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2279 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2280 getPtr(this, DyldInfo.bind_off));
2281 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2284 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2285 if (!DyldInfoLoadCmd)
2286 return ArrayRef<uint8_t>();
2288 MachO::dyld_info_command DyldInfo
2289 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2290 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2291 getPtr(this, DyldInfo.weak_bind_off));
2292 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2295 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2296 if (!DyldInfoLoadCmd)
2297 return ArrayRef<uint8_t>();
2299 MachO::dyld_info_command DyldInfo
2300 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2301 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2302 getPtr(this, DyldInfo.lazy_bind_off));
2303 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2306 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2307 if (!DyldInfoLoadCmd)
2308 return ArrayRef<uint8_t>();
2310 MachO::dyld_info_command DyldInfo
2311 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2312 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2313 getPtr(this, DyldInfo.export_off));
2314 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2317 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2319 return ArrayRef<uint8_t>();
2320 // Returning a pointer is fine as uuid doesn't need endian swapping.
2321 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2322 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2325 StringRef MachOObjectFile::getStringTableData() const {
2326 MachO::symtab_command S = getSymtabLoadCommand();
2327 return getData().substr(S.stroff, S.strsize);
2330 bool MachOObjectFile::is64Bit() const {
2331 return getType() == getMachOType(false, true) ||
2332 getType() == getMachOType(true, true);
2335 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2336 SmallVectorImpl<uint64_t> &Out) const {
2337 DataExtractor extractor(ObjectFile::getData(), true, 0);
2339 uint32_t offset = Index;
2341 while (uint64_t delta = extractor.getULEB128(&offset)) {
2343 Out.push_back(data);
2347 bool MachOObjectFile::isRelocatableObject() const {
2348 return getHeader().filetype == MachO::MH_OBJECT;
2351 ErrorOr<std::unique_ptr<MachOObjectFile>>
2352 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2353 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2355 std::unique_ptr<MachOObjectFile> Ret;
2356 if (Magic == "\xFE\xED\xFA\xCE")
2357 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2358 else if (Magic == "\xCE\xFA\xED\xFE")
2359 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2360 else if (Magic == "\xFE\xED\xFA\xCF")
2361 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2362 else if (Magic == "\xCF\xFA\xED\xFE")
2363 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2365 return object_error::parse_failed;
2369 return std::move(Ret);