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 ErrorOr<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
331 StringRef StringTable = getStringTableData();
332 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
333 const char *Start = &StringTable.data()[Entry.n_strx];
334 if (Start < getData().begin() || Start >= getData().end())
336 "Symbol name entry points before beginning or past end of file.");
337 return StringRef(Start);
340 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
341 DataRefImpl DRI = Sec.getRawDataRefImpl();
342 uint32_t Flags = getSectionFlags(this, DRI);
343 return Flags & MachO::SECTION_TYPE;
346 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
348 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
349 return Entry.n_value;
351 MachO::nlist Entry = getSymbolTableEntry(Sym);
352 return Entry.n_value;
355 // getIndirectName() returns the name of the alias'ed symbol who's string table
356 // index is in the n_value field.
357 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
358 StringRef &Res) const {
359 StringRef StringTable = getStringTableData();
360 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
361 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
362 return object_error::parse_failed;
363 uint64_t NValue = getNValue(Symb);
364 if (NValue >= StringTable.size())
365 return object_error::parse_failed;
366 const char *Start = &StringTable.data()[NValue];
367 Res = StringRef(Start);
368 return std::error_code();
371 uint64_t MachOObjectFile::getSymbolValue(DataRefImpl Sym) const {
372 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Sym);
373 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF)
374 return UnknownAddress;
375 return getNValue(Sym);
378 ErrorOr<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
379 return getSymbolValue(Sym);
382 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
383 uint32_t flags = getSymbolFlags(DRI);
384 if (flags & SymbolRef::SF_Common) {
385 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
386 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
391 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
392 return getNValue(DRI);
395 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
396 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
397 uint8_t n_type = Entry.n_type;
399 // If this is a STAB debugging symbol, we can do nothing more.
400 if (n_type & MachO::N_STAB)
401 return SymbolRef::ST_Debug;
403 switch (n_type & MachO::N_TYPE) {
405 return SymbolRef::ST_Unknown;
407 return SymbolRef::ST_Function;
409 return SymbolRef::ST_Other;
412 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
413 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
415 uint8_t MachOType = Entry.n_type;
416 uint16_t MachOFlags = Entry.n_desc;
418 uint32_t Result = SymbolRef::SF_None;
420 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
421 Result |= SymbolRef::SF_Indirect;
423 if (MachOType & MachO::N_STAB)
424 Result |= SymbolRef::SF_FormatSpecific;
426 if (MachOType & MachO::N_EXT) {
427 Result |= SymbolRef::SF_Global;
428 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
430 Result |= SymbolRef::SF_Common;
432 Result |= SymbolRef::SF_Undefined;
435 if (!(MachOType & MachO::N_PEXT))
436 Result |= SymbolRef::SF_Exported;
439 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
440 Result |= SymbolRef::SF_Weak;
442 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
443 Result |= SymbolRef::SF_Thumb;
445 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
446 Result |= SymbolRef::SF_Absolute;
451 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
452 section_iterator &Res) const {
453 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
454 uint8_t index = Entry.n_sect;
461 if (DRI.d.a >= Sections.size())
462 report_fatal_error("getSymbolSection: Invalid section index.");
463 Res = section_iterator(SectionRef(DRI, this));
466 return std::error_code();
469 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
470 MachO::nlist_base Entry =
471 getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
472 return Entry.n_sect - 1;
475 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
479 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
480 StringRef &Result) const {
481 ArrayRef<char> Raw = getSectionRawName(Sec);
482 Result = parseSegmentOrSectionName(Raw.data());
483 return std::error_code();
486 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
488 return getSection64(Sec).addr;
489 return getSection(Sec).addr;
492 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
494 return getSection64(Sec).size;
495 return getSection(Sec).size;
498 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
499 StringRef &Res) const {
504 MachO::section_64 Sect = getSection64(Sec);
505 Offset = Sect.offset;
508 MachO::section Sect = getSection(Sec);
509 Offset = Sect.offset;
513 Res = this->getData().substr(Offset, Size);
514 return std::error_code();
517 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
520 MachO::section_64 Sect = getSection64(Sec);
523 MachO::section Sect = getSection(Sec);
527 return uint64_t(1) << Align;
530 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
531 uint32_t Flags = getSectionFlags(this, Sec);
532 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
535 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
536 uint32_t Flags = getSectionFlags(this, Sec);
537 unsigned SectionType = Flags & MachO::SECTION_TYPE;
538 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
539 !(SectionType == MachO::S_ZEROFILL ||
540 SectionType == MachO::S_GB_ZEROFILL);
543 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
544 uint32_t Flags = getSectionFlags(this, Sec);
545 unsigned SectionType = Flags & MachO::SECTION_TYPE;
546 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
547 (SectionType == MachO::S_ZEROFILL ||
548 SectionType == MachO::S_GB_ZEROFILL);
551 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
552 return Sec.getRawDataRefImpl().d.a;
555 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
556 // FIXME: Unimplemented.
560 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
564 return relocation_iterator(RelocationRef(Ret, this));
568 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
571 MachO::section_64 Sect = getSection64(Sec);
574 MachO::section Sect = getSection(Sec);
581 return relocation_iterator(RelocationRef(Ret, this));
584 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
588 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
589 assert(getHeader().filetype == MachO::MH_OBJECT &&
590 "Only implemented for MH_OBJECT");
591 MachO::any_relocation_info RE = getRelocation(Rel);
592 return getAnyRelocationAddress(RE);
596 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
597 MachO::any_relocation_info RE = getRelocation(Rel);
598 if (isRelocationScattered(RE))
601 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
602 bool isExtern = getPlainRelocationExternal(RE);
606 MachO::symtab_command S = getSymtabLoadCommand();
607 unsigned SymbolTableEntrySize = is64Bit() ?
608 sizeof(MachO::nlist_64) :
609 sizeof(MachO::nlist);
610 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
612 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
613 return symbol_iterator(SymbolRef(Sym, this));
617 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
618 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
621 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
622 MachO::any_relocation_info RE = getRelocation(Rel);
623 return getAnyRelocationType(RE);
626 void MachOObjectFile::getRelocationTypeName(
627 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
629 uint64_t RType = getRelocationType(Rel);
631 unsigned Arch = this->getArch();
635 static const char *const Table[] = {
636 "GENERIC_RELOC_VANILLA",
637 "GENERIC_RELOC_PAIR",
638 "GENERIC_RELOC_SECTDIFF",
639 "GENERIC_RELOC_PB_LA_PTR",
640 "GENERIC_RELOC_LOCAL_SECTDIFF",
641 "GENERIC_RELOC_TLV" };
649 case Triple::x86_64: {
650 static const char *const Table[] = {
651 "X86_64_RELOC_UNSIGNED",
652 "X86_64_RELOC_SIGNED",
653 "X86_64_RELOC_BRANCH",
654 "X86_64_RELOC_GOT_LOAD",
656 "X86_64_RELOC_SUBTRACTOR",
657 "X86_64_RELOC_SIGNED_1",
658 "X86_64_RELOC_SIGNED_2",
659 "X86_64_RELOC_SIGNED_4",
660 "X86_64_RELOC_TLV" };
669 static const char *const Table[] = {
672 "ARM_RELOC_SECTDIFF",
673 "ARM_RELOC_LOCAL_SECTDIFF",
674 "ARM_RELOC_PB_LA_PTR",
676 "ARM_THUMB_RELOC_BR22",
677 "ARM_THUMB_32BIT_BRANCH",
679 "ARM_RELOC_HALF_SECTDIFF" };
687 case Triple::aarch64: {
688 static const char *const Table[] = {
689 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
690 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
691 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
692 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
693 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
697 if (RType >= array_lengthof(Table))
704 static const char *const Table[] = {
713 "PPC_RELOC_SECTDIFF",
714 "PPC_RELOC_PB_LA_PTR",
715 "PPC_RELOC_HI16_SECTDIFF",
716 "PPC_RELOC_LO16_SECTDIFF",
717 "PPC_RELOC_HA16_SECTDIFF",
719 "PPC_RELOC_LO14_SECTDIFF",
720 "PPC_RELOC_LOCAL_SECTDIFF" };
728 case Triple::UnknownArch:
732 Result.append(res.begin(), res.end());
735 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
736 MachO::any_relocation_info RE = getRelocation(Rel);
737 return getAnyRelocationLength(RE);
741 // guessLibraryShortName() is passed a name of a dynamic library and returns a
742 // guess on what the short name is. Then name is returned as a substring of the
743 // StringRef Name passed in. The name of the dynamic library is recognized as
744 // a framework if it has one of the two following forms:
745 // Foo.framework/Versions/A/Foo
747 // Where A and Foo can be any string. And may contain a trailing suffix
748 // starting with an underbar. If the Name is recognized as a framework then
749 // isFramework is set to true else it is set to false. If the Name has a
750 // suffix then Suffix is set to the substring in Name that contains the suffix
751 // else it is set to a NULL StringRef.
753 // The Name of the dynamic library is recognized as a library name if it has
754 // one of the two following forms:
757 // The library may have a suffix trailing the name Foo of the form:
758 // libFoo_profile.A.dylib
759 // libFoo_profile.dylib
761 // The Name of the dynamic library is also recognized as a library name if it
762 // has the following form:
765 // If the Name of the dynamic library is none of the forms above then a NULL
766 // StringRef is returned.
768 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
771 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
772 size_t a, b, c, d, Idx;
775 Suffix = StringRef();
777 // Pull off the last component and make Foo point to it
779 if (a == Name.npos || a == 0)
781 Foo = Name.slice(a+1, Name.npos);
783 // Look for a suffix starting with a '_'
784 Idx = Foo.rfind('_');
785 if (Idx != Foo.npos && Foo.size() >= 2) {
786 Suffix = Foo.slice(Idx, Foo.npos);
787 Foo = Foo.slice(0, Idx);
790 // First look for the form Foo.framework/Foo
791 b = Name.rfind('/', a);
796 F = Name.slice(Idx, Idx + Foo.size());
797 DotFramework = Name.slice(Idx + Foo.size(),
798 Idx + Foo.size() + sizeof(".framework/")-1);
799 if (F == Foo && DotFramework == ".framework/") {
804 // Next look for the form Foo.framework/Versions/A/Foo
807 c = Name.rfind('/', b);
808 if (c == Name.npos || c == 0)
810 V = Name.slice(c+1, Name.npos);
811 if (!V.startswith("Versions/"))
813 d = Name.rfind('/', c);
818 F = Name.slice(Idx, Idx + Foo.size());
819 DotFramework = Name.slice(Idx + Foo.size(),
820 Idx + Foo.size() + sizeof(".framework/")-1);
821 if (F == Foo && DotFramework == ".framework/") {
827 // pull off the suffix after the "." and make a point to it
829 if (a == Name.npos || a == 0)
831 Dylib = Name.slice(a, Name.npos);
832 if (Dylib != ".dylib")
835 // First pull off the version letter for the form Foo.A.dylib if any.
837 Dot = Name.slice(a-2, a-1);
842 b = Name.rfind('/', a);
847 // ignore any suffix after an underbar like Foo_profile.A.dylib
848 Idx = Name.find('_', b);
849 if (Idx != Name.npos && Idx != b) {
850 Lib = Name.slice(b, Idx);
851 Suffix = Name.slice(Idx, a);
854 Lib = Name.slice(b, a);
855 // There are incorrect library names of the form:
856 // libATS.A_profile.dylib so check for these.
857 if (Lib.size() >= 3) {
858 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
860 Lib = Lib.slice(0, Lib.size()-2);
865 Qtx = Name.slice(a, Name.npos);
868 b = Name.rfind('/', a);
870 Lib = Name.slice(0, a);
872 Lib = Name.slice(b+1, a);
873 // There are library names of the form: QT.A.qtx so check for these.
874 if (Lib.size() >= 3) {
875 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
877 Lib = Lib.slice(0, Lib.size()-2);
882 // getLibraryShortNameByIndex() is used to get the short name of the library
883 // for an undefined symbol in a linked Mach-O binary that was linked with the
884 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
885 // It is passed the index (0 - based) of the library as translated from
886 // GET_LIBRARY_ORDINAL (1 - based).
887 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
888 StringRef &Res) const {
889 if (Index >= Libraries.size())
890 return object_error::parse_failed;
892 // If the cache of LibrariesShortNames is not built up do that first for
893 // all the Libraries.
894 if (LibrariesShortNames.size() == 0) {
895 for (unsigned i = 0; i < Libraries.size(); i++) {
896 MachO::dylib_command D =
897 getStruct<MachO::dylib_command>(this, Libraries[i]);
898 if (D.dylib.name >= D.cmdsize)
899 return object_error::parse_failed;
900 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
901 StringRef Name = StringRef(P);
902 if (D.dylib.name+Name.size() >= D.cmdsize)
903 return object_error::parse_failed;
906 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
907 if (shortName.empty())
908 LibrariesShortNames.push_back(Name);
910 LibrariesShortNames.push_back(shortName);
914 Res = LibrariesShortNames[Index];
915 return std::error_code();
919 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
921 Sec.d.a = Rel->getRawDataRefImpl().d.a;
922 return section_iterator(SectionRef(Sec, this));
925 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
926 return getSymbolByIndex(0);
929 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
932 return basic_symbol_iterator(SymbolRef(DRI, this));
934 MachO::symtab_command Symtab = getSymtabLoadCommand();
935 unsigned SymbolTableEntrySize = is64Bit() ?
936 sizeof(MachO::nlist_64) :
937 sizeof(MachO::nlist);
938 unsigned Offset = Symtab.symoff +
939 Symtab.nsyms * SymbolTableEntrySize;
940 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
941 return basic_symbol_iterator(SymbolRef(DRI, this));
944 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
947 return basic_symbol_iterator(SymbolRef(DRI, this));
949 MachO::symtab_command Symtab = getSymtabLoadCommand();
950 if (Index >= Symtab.nsyms)
951 report_fatal_error("Requested symbol index is out of range.");
952 unsigned SymbolTableEntrySize =
953 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
954 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
955 DRI.p += Index * SymbolTableEntrySize;
956 return basic_symbol_iterator(SymbolRef(DRI, this));
959 section_iterator MachOObjectFile::section_begin() const {
961 return section_iterator(SectionRef(DRI, this));
964 section_iterator MachOObjectFile::section_end() const {
966 DRI.d.a = Sections.size();
967 return section_iterator(SectionRef(DRI, this));
970 uint8_t MachOObjectFile::getBytesInAddress() const {
971 return is64Bit() ? 8 : 4;
974 StringRef MachOObjectFile::getFileFormatName() const {
975 unsigned CPUType = getCPUType(this);
978 case llvm::MachO::CPU_TYPE_I386:
979 return "Mach-O 32-bit i386";
980 case llvm::MachO::CPU_TYPE_ARM:
982 case llvm::MachO::CPU_TYPE_POWERPC:
983 return "Mach-O 32-bit ppc";
985 return "Mach-O 32-bit unknown";
990 case llvm::MachO::CPU_TYPE_X86_64:
991 return "Mach-O 64-bit x86-64";
992 case llvm::MachO::CPU_TYPE_ARM64:
993 return "Mach-O arm64";
994 case llvm::MachO::CPU_TYPE_POWERPC64:
995 return "Mach-O 64-bit ppc64";
997 return "Mach-O 64-bit unknown";
1001 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1003 case llvm::MachO::CPU_TYPE_I386:
1005 case llvm::MachO::CPU_TYPE_X86_64:
1006 return Triple::x86_64;
1007 case llvm::MachO::CPU_TYPE_ARM:
1009 case llvm::MachO::CPU_TYPE_ARM64:
1010 return Triple::aarch64;
1011 case llvm::MachO::CPU_TYPE_POWERPC:
1013 case llvm::MachO::CPU_TYPE_POWERPC64:
1014 return Triple::ppc64;
1016 return Triple::UnknownArch;
1020 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1021 const char **McpuDefault) {
1023 *McpuDefault = nullptr;
1026 case MachO::CPU_TYPE_I386:
1027 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1028 case MachO::CPU_SUBTYPE_I386_ALL:
1029 return Triple("i386-apple-darwin");
1033 case MachO::CPU_TYPE_X86_64:
1034 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1035 case MachO::CPU_SUBTYPE_X86_64_ALL:
1036 return Triple("x86_64-apple-darwin");
1037 case MachO::CPU_SUBTYPE_X86_64_H:
1038 return Triple("x86_64h-apple-darwin");
1042 case MachO::CPU_TYPE_ARM:
1043 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1044 case MachO::CPU_SUBTYPE_ARM_V4T:
1045 return Triple("armv4t-apple-darwin");
1046 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1047 return Triple("armv5e-apple-darwin");
1048 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1049 return Triple("xscale-apple-darwin");
1050 case MachO::CPU_SUBTYPE_ARM_V6:
1051 return Triple("armv6-apple-darwin");
1052 case MachO::CPU_SUBTYPE_ARM_V6M:
1054 *McpuDefault = "cortex-m0";
1055 return Triple("armv6m-apple-darwin");
1056 case MachO::CPU_SUBTYPE_ARM_V7:
1057 return Triple("armv7-apple-darwin");
1058 case MachO::CPU_SUBTYPE_ARM_V7EM:
1060 *McpuDefault = "cortex-m4";
1061 return Triple("armv7em-apple-darwin");
1062 case MachO::CPU_SUBTYPE_ARM_V7K:
1063 return Triple("armv7k-apple-darwin");
1064 case MachO::CPU_SUBTYPE_ARM_V7M:
1066 *McpuDefault = "cortex-m3";
1067 return Triple("armv7m-apple-darwin");
1068 case MachO::CPU_SUBTYPE_ARM_V7S:
1069 return Triple("armv7s-apple-darwin");
1073 case MachO::CPU_TYPE_ARM64:
1074 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1075 case MachO::CPU_SUBTYPE_ARM64_ALL:
1076 return Triple("arm64-apple-darwin");
1080 case MachO::CPU_TYPE_POWERPC:
1081 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1082 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1083 return Triple("ppc-apple-darwin");
1087 case MachO::CPU_TYPE_POWERPC64:
1088 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1089 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1090 return Triple("ppc64-apple-darwin");
1099 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1100 const char **McpuDefault) {
1102 *McpuDefault = nullptr;
1105 case MachO::CPU_TYPE_ARM:
1106 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1107 case MachO::CPU_SUBTYPE_ARM_V4T:
1108 return Triple("thumbv4t-apple-darwin");
1109 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1110 return Triple("thumbv5e-apple-darwin");
1111 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1112 return Triple("xscale-apple-darwin");
1113 case MachO::CPU_SUBTYPE_ARM_V6:
1114 return Triple("thumbv6-apple-darwin");
1115 case MachO::CPU_SUBTYPE_ARM_V6M:
1117 *McpuDefault = "cortex-m0";
1118 return Triple("thumbv6m-apple-darwin");
1119 case MachO::CPU_SUBTYPE_ARM_V7:
1120 return Triple("thumbv7-apple-darwin");
1121 case MachO::CPU_SUBTYPE_ARM_V7EM:
1123 *McpuDefault = "cortex-m4";
1124 return Triple("thumbv7em-apple-darwin");
1125 case MachO::CPU_SUBTYPE_ARM_V7K:
1126 return Triple("thumbv7k-apple-darwin");
1127 case MachO::CPU_SUBTYPE_ARM_V7M:
1129 *McpuDefault = "cortex-m3";
1130 return Triple("thumbv7m-apple-darwin");
1131 case MachO::CPU_SUBTYPE_ARM_V7S:
1132 return Triple("thumbv7s-apple-darwin");
1141 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1142 const char **McpuDefault,
1143 Triple *ThumbTriple) {
1144 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1145 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1150 Triple MachOObjectFile::getHostArch() {
1151 return Triple(sys::getDefaultTargetTriple());
1154 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1155 return StringSwitch<bool>(ArchFlag)
1157 .Case("x86_64", true)
1158 .Case("x86_64h", true)
1159 .Case("armv4t", true)
1161 .Case("armv5e", true)
1162 .Case("armv6", true)
1163 .Case("armv6m", true)
1164 .Case("armv7", true)
1165 .Case("armv7em", true)
1166 .Case("armv7k", true)
1167 .Case("armv7m", true)
1168 .Case("armv7s", true)
1169 .Case("arm64", true)
1171 .Case("ppc64", true)
1175 unsigned MachOObjectFile::getArch() const {
1176 return getArch(getCPUType(this));
1179 Triple MachOObjectFile::getArch(const char **McpuDefault,
1180 Triple *ThumbTriple) const {
1181 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1182 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1185 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1188 return section_rel_begin(DRI);
1191 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1194 return section_rel_end(DRI);
1197 dice_iterator MachOObjectFile::begin_dices() const {
1199 if (!DataInCodeLoadCmd)
1200 return dice_iterator(DiceRef(DRI, this));
1202 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1203 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1204 return dice_iterator(DiceRef(DRI, this));
1207 dice_iterator MachOObjectFile::end_dices() const {
1209 if (!DataInCodeLoadCmd)
1210 return dice_iterator(DiceRef(DRI, this));
1212 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1213 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1214 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1215 return dice_iterator(DiceRef(DRI, this));
1218 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1219 : Trie(T), Malformed(false), Done(false) { }
1221 void ExportEntry::moveToFirst() {
1223 pushDownUntilBottom();
1226 void ExportEntry::moveToEnd() {
1231 bool ExportEntry::operator==(const ExportEntry &Other) const {
1232 // Common case, one at end, other iterating from begin.
1233 if (Done || Other.Done)
1234 return (Done == Other.Done);
1235 // Not equal if different stack sizes.
1236 if (Stack.size() != Other.Stack.size())
1238 // Not equal if different cumulative strings.
1239 if (!CumulativeString.equals(Other.CumulativeString))
1241 // Equal if all nodes in both stacks match.
1242 for (unsigned i=0; i < Stack.size(); ++i) {
1243 if (Stack[i].Start != Other.Stack[i].Start)
1249 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1251 uint64_t Result = decodeULEB128(Ptr, &Count);
1253 if (Ptr > Trie.end()) {
1260 StringRef ExportEntry::name() const {
1261 return CumulativeString;
1264 uint64_t ExportEntry::flags() const {
1265 return Stack.back().Flags;
1268 uint64_t ExportEntry::address() const {
1269 return Stack.back().Address;
1272 uint64_t ExportEntry::other() const {
1273 return Stack.back().Other;
1276 StringRef ExportEntry::otherName() const {
1277 const char* ImportName = Stack.back().ImportName;
1279 return StringRef(ImportName);
1283 uint32_t ExportEntry::nodeOffset() const {
1284 return Stack.back().Start - Trie.begin();
1287 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1288 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1289 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1290 ParentStringLength(0), IsExportNode(false) {
1293 void ExportEntry::pushNode(uint64_t offset) {
1294 const uint8_t *Ptr = Trie.begin() + offset;
1295 NodeState State(Ptr);
1296 uint64_t ExportInfoSize = readULEB128(State.Current);
1297 State.IsExportNode = (ExportInfoSize != 0);
1298 const uint8_t* Children = State.Current + ExportInfoSize;
1299 if (State.IsExportNode) {
1300 State.Flags = readULEB128(State.Current);
1301 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1303 State.Other = readULEB128(State.Current); // dylib ordinal
1304 State.ImportName = reinterpret_cast<const char*>(State.Current);
1306 State.Address = readULEB128(State.Current);
1307 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1308 State.Other = readULEB128(State.Current);
1311 State.ChildCount = *Children;
1312 State.Current = Children + 1;
1313 State.NextChildIndex = 0;
1314 State.ParentStringLength = CumulativeString.size();
1315 Stack.push_back(State);
1318 void ExportEntry::pushDownUntilBottom() {
1319 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1320 NodeState &Top = Stack.back();
1321 CumulativeString.resize(Top.ParentStringLength);
1322 for (;*Top.Current != 0; Top.Current++) {
1323 char C = *Top.Current;
1324 CumulativeString.push_back(C);
1327 uint64_t childNodeIndex = readULEB128(Top.Current);
1328 Top.NextChildIndex += 1;
1329 pushNode(childNodeIndex);
1331 if (!Stack.back().IsExportNode) {
1337 // We have a trie data structure and need a way to walk it that is compatible
1338 // with the C++ iterator model. The solution is a non-recursive depth first
1339 // traversal where the iterator contains a stack of parent nodes along with a
1340 // string that is the accumulation of all edge strings along the parent chain
1343 // There is one "export" node for each exported symbol. But because some
1344 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1345 // node may have child nodes too.
1347 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1348 // child until hitting a node with no children (which is an export node or
1349 // else the trie is malformed). On the way down, each node is pushed on the
1350 // stack ivar. If there is no more ways down, it pops up one and tries to go
1351 // down a sibling path until a childless node is reached.
1352 void ExportEntry::moveNext() {
1353 if (Stack.empty() || !Stack.back().IsExportNode) {
1360 while (!Stack.empty()) {
1361 NodeState &Top = Stack.back();
1362 if (Top.NextChildIndex < Top.ChildCount) {
1363 pushDownUntilBottom();
1364 // Now at the next export node.
1367 if (Top.IsExportNode) {
1368 // This node has no children but is itself an export node.
1369 CumulativeString.resize(Top.ParentStringLength);
1378 iterator_range<export_iterator>
1379 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1380 ExportEntry Start(Trie);
1381 if (Trie.size() == 0)
1384 Start.moveToFirst();
1386 ExportEntry Finish(Trie);
1389 return iterator_range<export_iterator>(export_iterator(Start),
1390 export_iterator(Finish));
1393 iterator_range<export_iterator> MachOObjectFile::exports() const {
1394 return exports(getDyldInfoExportsTrie());
1398 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1399 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1400 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1401 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1403 void MachORebaseEntry::moveToFirst() {
1404 Ptr = Opcodes.begin();
1408 void MachORebaseEntry::moveToEnd() {
1409 Ptr = Opcodes.end();
1410 RemainingLoopCount = 0;
1414 void MachORebaseEntry::moveNext() {
1415 // If in the middle of some loop, move to next rebasing in loop.
1416 SegmentOffset += AdvanceAmount;
1417 if (RemainingLoopCount) {
1418 --RemainingLoopCount;
1421 if (Ptr == Opcodes.end()) {
1426 while (More && !Malformed) {
1427 // Parse next opcode and set up next loop.
1428 uint8_t Byte = *Ptr++;
1429 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1430 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1432 case MachO::REBASE_OPCODE_DONE:
1436 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1438 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1439 RebaseType = ImmValue;
1442 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1443 << "RebaseType=" << (int) RebaseType << "\n");
1445 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1446 SegmentIndex = ImmValue;
1447 SegmentOffset = readULEB128();
1450 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1451 << "SegmentIndex=" << SegmentIndex << ", "
1452 << format("SegmentOffset=0x%06X", SegmentOffset)
1455 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1456 SegmentOffset += readULEB128();
1457 DEBUG_WITH_TYPE("mach-o-rebase",
1458 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1459 << format("SegmentOffset=0x%06X",
1460 SegmentOffset) << "\n");
1462 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1463 SegmentOffset += ImmValue * PointerSize;
1464 DEBUG_WITH_TYPE("mach-o-rebase",
1465 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1466 << format("SegmentOffset=0x%06X",
1467 SegmentOffset) << "\n");
1469 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1470 AdvanceAmount = PointerSize;
1471 RemainingLoopCount = ImmValue - 1;
1474 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1475 << format("SegmentOffset=0x%06X", SegmentOffset)
1476 << ", AdvanceAmount=" << AdvanceAmount
1477 << ", RemainingLoopCount=" << RemainingLoopCount
1480 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1481 AdvanceAmount = PointerSize;
1482 RemainingLoopCount = readULEB128() - 1;
1485 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1486 << format("SegmentOffset=0x%06X", SegmentOffset)
1487 << ", AdvanceAmount=" << AdvanceAmount
1488 << ", RemainingLoopCount=" << RemainingLoopCount
1491 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1492 AdvanceAmount = readULEB128() + PointerSize;
1493 RemainingLoopCount = 0;
1496 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1497 << format("SegmentOffset=0x%06X", SegmentOffset)
1498 << ", AdvanceAmount=" << AdvanceAmount
1499 << ", RemainingLoopCount=" << RemainingLoopCount
1502 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1503 RemainingLoopCount = readULEB128() - 1;
1504 AdvanceAmount = readULEB128() + PointerSize;
1507 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1508 << format("SegmentOffset=0x%06X", SegmentOffset)
1509 << ", AdvanceAmount=" << AdvanceAmount
1510 << ", RemainingLoopCount=" << RemainingLoopCount
1519 uint64_t MachORebaseEntry::readULEB128() {
1521 uint64_t Result = decodeULEB128(Ptr, &Count);
1523 if (Ptr > Opcodes.end()) {
1524 Ptr = Opcodes.end();
1530 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1532 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1534 StringRef MachORebaseEntry::typeName() const {
1535 switch (RebaseType) {
1536 case MachO::REBASE_TYPE_POINTER:
1538 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1539 return "text abs32";
1540 case MachO::REBASE_TYPE_TEXT_PCREL32:
1541 return "text rel32";
1546 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1547 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1548 return (Ptr == Other.Ptr) &&
1549 (RemainingLoopCount == Other.RemainingLoopCount) &&
1550 (Done == Other.Done);
1553 iterator_range<rebase_iterator>
1554 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1555 MachORebaseEntry Start(Opcodes, is64);
1556 Start.moveToFirst();
1558 MachORebaseEntry Finish(Opcodes, is64);
1561 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1562 rebase_iterator(Finish));
1565 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1566 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1570 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1572 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1573 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1574 BindType(0), PointerSize(is64Bit ? 8 : 4),
1575 TableKind(BK), Malformed(false), Done(false) {}
1577 void MachOBindEntry::moveToFirst() {
1578 Ptr = Opcodes.begin();
1582 void MachOBindEntry::moveToEnd() {
1583 Ptr = Opcodes.end();
1584 RemainingLoopCount = 0;
1588 void MachOBindEntry::moveNext() {
1589 // If in the middle of some loop, move to next binding in loop.
1590 SegmentOffset += AdvanceAmount;
1591 if (RemainingLoopCount) {
1592 --RemainingLoopCount;
1595 if (Ptr == Opcodes.end()) {
1600 while (More && !Malformed) {
1601 // Parse next opcode and set up next loop.
1602 uint8_t Byte = *Ptr++;
1603 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1604 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1605 int8_t SignExtended;
1606 const uint8_t *SymStart;
1608 case MachO::BIND_OPCODE_DONE:
1609 if (TableKind == Kind::Lazy) {
1610 // Lazying bindings have a DONE opcode between entries. Need to ignore
1611 // it to advance to next entry. But need not if this is last entry.
1612 bool NotLastEntry = false;
1613 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1615 NotLastEntry = true;
1624 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1626 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1630 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1631 << "Ordinal=" << Ordinal << "\n");
1633 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1634 Ordinal = readULEB128();
1637 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1638 << "Ordinal=" << Ordinal << "\n");
1640 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1642 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1643 Ordinal = SignExtended;
1648 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1649 << "Ordinal=" << Ordinal << "\n");
1651 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1657 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1662 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1663 << "SymbolName=" << SymbolName << "\n");
1664 if (TableKind == Kind::Weak) {
1665 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1669 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1670 BindType = ImmValue;
1673 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1674 << "BindType=" << (int)BindType << "\n");
1676 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1677 Addend = readSLEB128();
1678 if (TableKind == Kind::Lazy)
1682 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1683 << "Addend=" << Addend << "\n");
1685 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1686 SegmentIndex = ImmValue;
1687 SegmentOffset = readULEB128();
1690 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1691 << "SegmentIndex=" << SegmentIndex << ", "
1692 << format("SegmentOffset=0x%06X", SegmentOffset)
1695 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1696 SegmentOffset += readULEB128();
1697 DEBUG_WITH_TYPE("mach-o-bind",
1698 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1699 << format("SegmentOffset=0x%06X",
1700 SegmentOffset) << "\n");
1702 case MachO::BIND_OPCODE_DO_BIND:
1703 AdvanceAmount = PointerSize;
1704 RemainingLoopCount = 0;
1705 DEBUG_WITH_TYPE("mach-o-bind",
1706 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1707 << format("SegmentOffset=0x%06X",
1708 SegmentOffset) << "\n");
1710 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1711 AdvanceAmount = readULEB128() + PointerSize;
1712 RemainingLoopCount = 0;
1713 if (TableKind == Kind::Lazy)
1717 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1718 << format("SegmentOffset=0x%06X", SegmentOffset)
1719 << ", AdvanceAmount=" << AdvanceAmount
1720 << ", RemainingLoopCount=" << RemainingLoopCount
1723 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1724 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1725 RemainingLoopCount = 0;
1726 if (TableKind == Kind::Lazy)
1728 DEBUG_WITH_TYPE("mach-o-bind",
1730 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1731 << format("SegmentOffset=0x%06X",
1732 SegmentOffset) << "\n");
1734 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1735 RemainingLoopCount = readULEB128() - 1;
1736 AdvanceAmount = readULEB128() + PointerSize;
1737 if (TableKind == Kind::Lazy)
1741 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1742 << format("SegmentOffset=0x%06X", SegmentOffset)
1743 << ", AdvanceAmount=" << AdvanceAmount
1744 << ", RemainingLoopCount=" << RemainingLoopCount
1753 uint64_t MachOBindEntry::readULEB128() {
1755 uint64_t Result = decodeULEB128(Ptr, &Count);
1757 if (Ptr > Opcodes.end()) {
1758 Ptr = Opcodes.end();
1764 int64_t MachOBindEntry::readSLEB128() {
1766 int64_t Result = decodeSLEB128(Ptr, &Count);
1768 if (Ptr > Opcodes.end()) {
1769 Ptr = Opcodes.end();
1776 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1778 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1780 StringRef MachOBindEntry::typeName() const {
1782 case MachO::BIND_TYPE_POINTER:
1784 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1785 return "text abs32";
1786 case MachO::BIND_TYPE_TEXT_PCREL32:
1787 return "text rel32";
1792 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1794 int64_t MachOBindEntry::addend() const { return Addend; }
1796 uint32_t MachOBindEntry::flags() const { return Flags; }
1798 int MachOBindEntry::ordinal() const { return Ordinal; }
1800 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1801 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1802 return (Ptr == Other.Ptr) &&
1803 (RemainingLoopCount == Other.RemainingLoopCount) &&
1804 (Done == Other.Done);
1807 iterator_range<bind_iterator>
1808 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1809 MachOBindEntry::Kind BKind) {
1810 MachOBindEntry Start(Opcodes, is64, BKind);
1811 Start.moveToFirst();
1813 MachOBindEntry Finish(Opcodes, is64, BKind);
1816 return iterator_range<bind_iterator>(bind_iterator(Start),
1817 bind_iterator(Finish));
1820 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1821 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1822 MachOBindEntry::Kind::Regular);
1825 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1826 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1827 MachOBindEntry::Kind::Lazy);
1830 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1831 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1832 MachOBindEntry::Kind::Weak);
1835 MachOObjectFile::load_command_iterator
1836 MachOObjectFile::begin_load_commands() const {
1837 return LoadCommands.begin();
1840 MachOObjectFile::load_command_iterator
1841 MachOObjectFile::end_load_commands() const {
1842 return LoadCommands.end();
1845 iterator_range<MachOObjectFile::load_command_iterator>
1846 MachOObjectFile::load_commands() const {
1847 return iterator_range<load_command_iterator>(begin_load_commands(),
1848 end_load_commands());
1852 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1853 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1854 return parseSegmentOrSectionName(Raw.data());
1858 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1859 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1860 const section_base *Base =
1861 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1862 return makeArrayRef(Base->sectname);
1866 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1867 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1868 const section_base *Base =
1869 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1870 return makeArrayRef(Base->segname);
1874 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1876 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1878 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1881 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1882 const MachO::any_relocation_info &RE) const {
1883 if (isLittleEndian())
1884 return RE.r_word1 & 0xffffff;
1885 return RE.r_word1 >> 8;
1888 bool MachOObjectFile::getPlainRelocationExternal(
1889 const MachO::any_relocation_info &RE) const {
1890 if (isLittleEndian())
1891 return (RE.r_word1 >> 27) & 1;
1892 return (RE.r_word1 >> 4) & 1;
1895 bool MachOObjectFile::getScatteredRelocationScattered(
1896 const MachO::any_relocation_info &RE) const {
1897 return RE.r_word0 >> 31;
1900 uint32_t MachOObjectFile::getScatteredRelocationValue(
1901 const MachO::any_relocation_info &RE) const {
1905 uint32_t MachOObjectFile::getScatteredRelocationType(
1906 const MachO::any_relocation_info &RE) const {
1907 return (RE.r_word0 >> 24) & 0xf;
1910 unsigned MachOObjectFile::getAnyRelocationAddress(
1911 const MachO::any_relocation_info &RE) const {
1912 if (isRelocationScattered(RE))
1913 return getScatteredRelocationAddress(RE);
1914 return getPlainRelocationAddress(RE);
1917 unsigned MachOObjectFile::getAnyRelocationPCRel(
1918 const MachO::any_relocation_info &RE) const {
1919 if (isRelocationScattered(RE))
1920 return getScatteredRelocationPCRel(this, RE);
1921 return getPlainRelocationPCRel(this, RE);
1924 unsigned MachOObjectFile::getAnyRelocationLength(
1925 const MachO::any_relocation_info &RE) const {
1926 if (isRelocationScattered(RE))
1927 return getScatteredRelocationLength(RE);
1928 return getPlainRelocationLength(this, RE);
1932 MachOObjectFile::getAnyRelocationType(
1933 const MachO::any_relocation_info &RE) const {
1934 if (isRelocationScattered(RE))
1935 return getScatteredRelocationType(RE);
1936 return getPlainRelocationType(this, RE);
1940 MachOObjectFile::getAnyRelocationSection(
1941 const MachO::any_relocation_info &RE) const {
1942 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1943 return *section_end();
1944 unsigned SecNum = getPlainRelocationSymbolNum(RE);
1945 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
1946 return *section_end();
1948 DRI.d.a = SecNum - 1;
1949 return SectionRef(DRI, this);
1952 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1953 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1954 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1957 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1958 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1959 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1962 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1963 unsigned Index) const {
1964 const char *Sec = getSectionPtr(this, L, Index);
1965 return getStruct<MachO::section>(this, Sec);
1968 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1969 unsigned Index) const {
1970 const char *Sec = getSectionPtr(this, L, Index);
1971 return getStruct<MachO::section_64>(this, Sec);
1975 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1976 const char *P = reinterpret_cast<const char *>(DRI.p);
1977 return getStruct<MachO::nlist>(this, P);
1981 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1982 const char *P = reinterpret_cast<const char *>(DRI.p);
1983 return getStruct<MachO::nlist_64>(this, P);
1986 MachO::linkedit_data_command
1987 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1988 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1991 MachO::segment_command
1992 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1993 return getStruct<MachO::segment_command>(this, L.Ptr);
1996 MachO::segment_command_64
1997 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1998 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2001 MachO::linker_option_command
2002 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2003 return getStruct<MachO::linker_option_command>(this, L.Ptr);
2006 MachO::version_min_command
2007 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2008 return getStruct<MachO::version_min_command>(this, L.Ptr);
2011 MachO::dylib_command
2012 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2013 return getStruct<MachO::dylib_command>(this, L.Ptr);
2016 MachO::dyld_info_command
2017 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2018 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2021 MachO::dylinker_command
2022 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2023 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2027 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2028 return getStruct<MachO::uuid_command>(this, L.Ptr);
2031 MachO::rpath_command
2032 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2033 return getStruct<MachO::rpath_command>(this, L.Ptr);
2036 MachO::source_version_command
2037 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2038 return getStruct<MachO::source_version_command>(this, L.Ptr);
2041 MachO::entry_point_command
2042 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2043 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2046 MachO::encryption_info_command
2047 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2048 return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2051 MachO::encryption_info_command_64
2052 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2053 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2056 MachO::sub_framework_command
2057 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2058 return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2061 MachO::sub_umbrella_command
2062 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2063 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2066 MachO::sub_library_command
2067 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2068 return getStruct<MachO::sub_library_command>(this, L.Ptr);
2071 MachO::sub_client_command
2072 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2073 return getStruct<MachO::sub_client_command>(this, L.Ptr);
2076 MachO::routines_command
2077 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2078 return getStruct<MachO::routines_command>(this, L.Ptr);
2081 MachO::routines_command_64
2082 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2083 return getStruct<MachO::routines_command_64>(this, L.Ptr);
2086 MachO::thread_command
2087 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2088 return getStruct<MachO::thread_command>(this, L.Ptr);
2091 MachO::any_relocation_info
2092 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2097 MachO::section_64 Sect = getSection64(Sec);
2098 Offset = Sect.reloff;
2100 MachO::section Sect = getSection(Sec);
2101 Offset = Sect.reloff;
2104 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2105 getPtr(this, Offset)) + Rel.d.b;
2106 return getStruct<MachO::any_relocation_info>(
2107 this, reinterpret_cast<const char *>(P));
2110 MachO::data_in_code_entry
2111 MachOObjectFile::getDice(DataRefImpl Rel) const {
2112 const char *P = reinterpret_cast<const char *>(Rel.p);
2113 return getStruct<MachO::data_in_code_entry>(this, P);
2116 const MachO::mach_header &MachOObjectFile::getHeader() const {
2120 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2125 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2126 const MachO::dysymtab_command &DLC,
2127 unsigned Index) const {
2128 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2129 return getStruct<uint32_t>(this, getPtr(this, Offset));
2132 MachO::data_in_code_entry
2133 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2134 unsigned Index) const {
2135 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2136 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2139 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2141 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2143 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2144 MachO::symtab_command Cmd;
2145 Cmd.cmd = MachO::LC_SYMTAB;
2146 Cmd.cmdsize = sizeof(MachO::symtab_command);
2154 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2155 if (DysymtabLoadCmd)
2156 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2158 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2159 MachO::dysymtab_command Cmd;
2160 Cmd.cmd = MachO::LC_DYSYMTAB;
2161 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2172 Cmd.extrefsymoff = 0;
2173 Cmd.nextrefsyms = 0;
2174 Cmd.indirectsymoff = 0;
2175 Cmd.nindirectsyms = 0;
2183 MachO::linkedit_data_command
2184 MachOObjectFile::getDataInCodeLoadCommand() const {
2185 if (DataInCodeLoadCmd)
2186 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2188 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2189 MachO::linkedit_data_command Cmd;
2190 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2191 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2197 MachO::linkedit_data_command
2198 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2199 if (LinkOptHintsLoadCmd)
2200 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2202 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2204 MachO::linkedit_data_command Cmd;
2205 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2206 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2212 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2213 if (!DyldInfoLoadCmd)
2214 return ArrayRef<uint8_t>();
2216 MachO::dyld_info_command DyldInfo
2217 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2218 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2219 getPtr(this, DyldInfo.rebase_off));
2220 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2223 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2224 if (!DyldInfoLoadCmd)
2225 return ArrayRef<uint8_t>();
2227 MachO::dyld_info_command DyldInfo
2228 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2229 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2230 getPtr(this, DyldInfo.bind_off));
2231 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2234 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2235 if (!DyldInfoLoadCmd)
2236 return ArrayRef<uint8_t>();
2238 MachO::dyld_info_command DyldInfo
2239 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2240 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2241 getPtr(this, DyldInfo.weak_bind_off));
2242 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2245 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2246 if (!DyldInfoLoadCmd)
2247 return ArrayRef<uint8_t>();
2249 MachO::dyld_info_command DyldInfo
2250 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2251 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2252 getPtr(this, DyldInfo.lazy_bind_off));
2253 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2256 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2257 if (!DyldInfoLoadCmd)
2258 return ArrayRef<uint8_t>();
2260 MachO::dyld_info_command DyldInfo
2261 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2262 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2263 getPtr(this, DyldInfo.export_off));
2264 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2267 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2269 return ArrayRef<uint8_t>();
2270 // Returning a pointer is fine as uuid doesn't need endian swapping.
2271 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2272 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2275 StringRef MachOObjectFile::getStringTableData() const {
2276 MachO::symtab_command S = getSymtabLoadCommand();
2277 return getData().substr(S.stroff, S.strsize);
2280 bool MachOObjectFile::is64Bit() const {
2281 return getType() == getMachOType(false, true) ||
2282 getType() == getMachOType(true, true);
2285 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2286 SmallVectorImpl<uint64_t> &Out) const {
2287 DataExtractor extractor(ObjectFile::getData(), true, 0);
2289 uint32_t offset = Index;
2291 while (uint64_t delta = extractor.getULEB128(&offset)) {
2293 Out.push_back(data);
2297 bool MachOObjectFile::isRelocatableObject() const {
2298 return getHeader().filetype == MachO::MH_OBJECT;
2301 ErrorOr<std::unique_ptr<MachOObjectFile>>
2302 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2303 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2305 std::unique_ptr<MachOObjectFile> Ret;
2306 if (Magic == "\xFE\xED\xFA\xCE")
2307 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2308 else if (Magic == "\xCE\xFA\xED\xFE")
2309 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2310 else if (Magic == "\xFE\xED\xFA\xCF")
2311 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2312 else if (Magic == "\xCF\xFA\xED\xFE")
2313 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2315 return object_error::parse_failed;
2319 return std::move(Ret);