1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Object/MachO.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/Host.h"
23 #include "llvm/Support/LEB128.h"
24 #include "llvm/Support/MachO.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/raw_ostream.h"
32 using namespace object;
41 // FIXME: Replace all uses of this function with getStructOrErr.
43 static T getStruct(const MachOObjectFile *O, const char *P) {
44 // Don't read before the beginning or past the end of the file
45 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
46 report_fatal_error("Malformed MachO file.");
49 memcpy(&Cmd, P, sizeof(T));
50 if (O->isLittleEndian() != sys::IsLittleEndianHost)
51 MachO::swapStruct(Cmd);
56 static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
57 // Don't read before the beginning or past the end of the file
58 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
59 return object_error::parse_failed;
62 memcpy(&Cmd, P, sizeof(T));
63 if (O->isLittleEndian() != sys::IsLittleEndianHost)
64 MachO::swapStruct(Cmd);
69 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
71 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
73 bool Is64 = O->is64Bit();
74 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
75 sizeof(MachO::segment_command);
76 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
77 sizeof(MachO::section);
79 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
80 return reinterpret_cast<const char*>(SectionAddr);
83 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
84 return O->getData().substr(Offset, 1).data();
87 static MachO::nlist_base
88 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
89 const char *P = reinterpret_cast<const char *>(DRI.p);
90 return getStruct<MachO::nlist_base>(O, P);
93 static StringRef parseSegmentOrSectionName(const char *P) {
97 // Not null terminated, so this is a 16 char string.
98 return StringRef(P, 16);
101 // Helper to advance a section or symbol iterator multiple increments at a time.
103 static void advance(T &it, size_t Val) {
108 static unsigned getCPUType(const MachOObjectFile *O) {
109 return O->getHeader().cputype;
113 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
118 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
119 return RE.r_word0 & 0xffffff;
122 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
123 const MachO::any_relocation_info &RE) {
124 if (O->isLittleEndian())
125 return (RE.r_word1 >> 24) & 1;
126 return (RE.r_word1 >> 7) & 1;
130 getScatteredRelocationPCRel(const MachOObjectFile *O,
131 const MachO::any_relocation_info &RE) {
132 return (RE.r_word0 >> 30) & 1;
135 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
136 const MachO::any_relocation_info &RE) {
137 if (O->isLittleEndian())
138 return (RE.r_word1 >> 25) & 3;
139 return (RE.r_word1 >> 5) & 3;
143 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
144 return (RE.r_word0 >> 28) & 3;
147 static unsigned getPlainRelocationType(const MachOObjectFile *O,
148 const MachO::any_relocation_info &RE) {
149 if (O->isLittleEndian())
150 return RE.r_word1 >> 28;
151 return RE.r_word1 & 0xf;
154 static uint32_t getSectionFlags(const MachOObjectFile *O,
157 MachO::section_64 Sect = O->getSection64(Sec);
160 MachO::section Sect = O->getSection(Sec);
164 static ErrorOr<MachOObjectFile::LoadCommandInfo>
165 getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) {
166 auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr);
168 return CmdOrErr.getError();
169 if (CmdOrErr->cmdsize < 8)
170 return object_error::macho_small_load_command;
171 MachOObjectFile::LoadCommandInfo Load;
173 Load.C = CmdOrErr.get();
177 static ErrorOr<MachOObjectFile::LoadCommandInfo>
178 getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
179 unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
180 : sizeof(MachO::mach_header);
181 return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize));
184 static ErrorOr<MachOObjectFile::LoadCommandInfo>
185 getNextLoadCommandInfo(const MachOObjectFile *Obj,
186 const MachOObjectFile::LoadCommandInfo &L) {
187 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
190 template <typename T>
191 static void parseHeader(const MachOObjectFile *Obj, T &Header,
192 std::error_code &EC) {
193 auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
195 Header = HeaderOrErr.get();
197 EC = HeaderOrErr.getError();
200 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
201 // sections to \param Sections, and optionally sets
202 // \param IsPageZeroSegment to true.
203 template <typename SegmentCmd>
204 static std::error_code parseSegmentLoadCommand(
205 const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
206 SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment) {
207 const unsigned SegmentLoadSize = sizeof(SegmentCmd);
208 if (Load.C.cmdsize < SegmentLoadSize)
209 return object_error::macho_load_segment_too_small;
210 auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr);
212 return SegOrErr.getError();
213 SegmentCmd S = SegOrErr.get();
214 const unsigned SectionSize =
215 Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section);
216 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
217 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
218 return object_error::macho_load_segment_too_many_sections;
219 for (unsigned J = 0; J < S.nsects; ++J) {
220 const char *Sec = getSectionPtr(Obj, Load, J);
221 Sections.push_back(Sec);
223 IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
224 return std::error_code();
227 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
228 bool Is64bits, std::error_code &EC)
229 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
230 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
231 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
232 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
233 HasPageZeroSegment(false) {
235 parseHeader(this, Header64, EC);
237 parseHeader(this, Header, EC);
241 uint32_t LoadCommandCount = getHeader().ncmds;
242 if (LoadCommandCount == 0)
245 auto LoadOrErr = getFirstLoadCommandInfo(this);
247 EC = LoadOrErr.getError();
250 LoadCommandInfo Load = LoadOrErr.get();
251 for (unsigned I = 0; I < LoadCommandCount; ++I) {
252 LoadCommands.push_back(Load);
253 if (Load.C.cmd == MachO::LC_SYMTAB) {
254 // Multiple symbol tables
256 EC = object_error::parse_failed;
259 SymtabLoadCmd = Load.Ptr;
260 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
261 // Multiple dynamic symbol tables
262 if (DysymtabLoadCmd) {
263 EC = object_error::parse_failed;
266 DysymtabLoadCmd = Load.Ptr;
267 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
268 // Multiple data in code tables
269 if (DataInCodeLoadCmd) {
270 EC = object_error::parse_failed;
273 DataInCodeLoadCmd = Load.Ptr;
274 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
275 // Multiple linker optimization hint tables
276 if (LinkOptHintsLoadCmd) {
277 EC = object_error::parse_failed;
280 LinkOptHintsLoadCmd = Load.Ptr;
281 } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
282 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
283 // Multiple dyldinfo load commands
284 if (DyldInfoLoadCmd) {
285 EC = object_error::parse_failed;
288 DyldInfoLoadCmd = Load.Ptr;
289 } else if (Load.C.cmd == MachO::LC_UUID) {
290 // Multiple UUID load commands
292 EC = object_error::parse_failed;
295 UuidLoadCmd = Load.Ptr;
296 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
297 if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>(
298 this, Load, Sections, HasPageZeroSegment)))
300 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
301 if ((EC = parseSegmentLoadCommand<MachO::segment_command>(
302 this, Load, Sections, HasPageZeroSegment)))
304 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
305 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
306 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
307 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
308 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
309 Libraries.push_back(Load.Ptr);
311 if (I < LoadCommandCount - 1) {
312 auto LoadOrErr = getNextLoadCommandInfo(this, Load);
314 EC = LoadOrErr.getError();
317 Load = LoadOrErr.get();
320 assert(LoadCommands.size() == LoadCommandCount);
323 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
324 unsigned SymbolTableEntrySize = is64Bit() ?
325 sizeof(MachO::nlist_64) :
326 sizeof(MachO::nlist);
327 Symb.p += SymbolTableEntrySize;
330 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
331 StringRef &Res) const {
332 StringRef StringTable = getStringTableData();
333 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
334 const char *Start = &StringTable.data()[Entry.n_strx];
335 if (Start < getData().begin() || Start >= getData().end())
337 "Symbol name entry points before beginning or past end of file.");
338 Res = StringRef(Start);
339 return std::error_code();
342 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
343 DataRefImpl DRI = Sec.getRawDataRefImpl();
344 uint32_t Flags = getSectionFlags(this, DRI);
345 return Flags & MachO::SECTION_TYPE;
348 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
350 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
351 return Entry.n_value;
353 MachO::nlist Entry = getSymbolTableEntry(Sym);
354 return Entry.n_value;
357 // getIndirectName() returns the name of the alias'ed symbol who's string table
358 // index is in the n_value field.
359 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
360 StringRef &Res) const {
361 StringRef StringTable = getStringTableData();
362 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
363 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
364 return object_error::parse_failed;
365 uint64_t NValue = getNValue(Symb);
366 if (NValue >= StringTable.size())
367 return object_error::parse_failed;
368 const char *Start = &StringTable.data()[NValue];
369 Res = StringRef(Start);
370 return std::error_code();
373 uint64_t MachOObjectFile::getSymbolValue(DataRefImpl Sym) const {
374 uint64_t NValue = getNValue(Sym);
375 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Sym);
376 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0)
377 return UnknownAddress;
381 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Sym,
382 uint64_t &Res) const {
383 Res = getSymbolValue(Sym);
384 return std::error_code();
387 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
388 uint32_t flags = getSymbolFlags(DRI);
389 if (flags & SymbolRef::SF_Common) {
390 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
391 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
396 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
398 getSymbolAddress(DRI, Value);
402 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
403 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
404 uint8_t n_type = Entry.n_type;
406 // If this is a STAB debugging symbol, we can do nothing more.
407 if (n_type & MachO::N_STAB)
408 return SymbolRef::ST_Debug;
410 switch (n_type & MachO::N_TYPE) {
412 return SymbolRef::ST_Unknown;
414 return SymbolRef::ST_Function;
416 return SymbolRef::ST_Other;
419 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
420 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
422 uint8_t MachOType = Entry.n_type;
423 uint16_t MachOFlags = Entry.n_desc;
425 uint32_t Result = SymbolRef::SF_None;
427 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
428 Result |= SymbolRef::SF_Undefined;
430 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
431 Result |= SymbolRef::SF_Indirect;
433 if (MachOType & MachO::N_STAB)
434 Result |= SymbolRef::SF_FormatSpecific;
436 if (MachOType & MachO::N_EXT) {
437 Result |= SymbolRef::SF_Global;
438 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
440 getSymbolAddress(DRI, Value);
441 if (Value && Value != UnknownAddress)
442 Result |= SymbolRef::SF_Common;
445 if (!(MachOType & MachO::N_PEXT))
446 Result |= SymbolRef::SF_Exported;
449 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
450 Result |= SymbolRef::SF_Weak;
452 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
453 Result |= SymbolRef::SF_Thumb;
455 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
456 Result |= SymbolRef::SF_Absolute;
461 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
462 section_iterator &Res) const {
463 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
464 uint8_t index = Entry.n_sect;
471 if (DRI.d.a >= Sections.size())
472 report_fatal_error("getSymbolSection: Invalid section index.");
473 Res = section_iterator(SectionRef(DRI, this));
476 return std::error_code();
479 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
480 MachO::nlist_base Entry =
481 getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
482 return Entry.n_sect - 1;
485 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
489 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
490 StringRef &Result) const {
491 ArrayRef<char> Raw = getSectionRawName(Sec);
492 Result = parseSegmentOrSectionName(Raw.data());
493 return std::error_code();
496 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
498 return getSection64(Sec).addr;
499 return getSection(Sec).addr;
502 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
504 return getSection64(Sec).size;
505 return getSection(Sec).size;
508 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
509 StringRef &Res) const {
514 MachO::section_64 Sect = getSection64(Sec);
515 Offset = Sect.offset;
518 MachO::section Sect = getSection(Sec);
519 Offset = Sect.offset;
523 Res = this->getData().substr(Offset, Size);
524 return std::error_code();
527 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
530 MachO::section_64 Sect = getSection64(Sec);
533 MachO::section Sect = getSection(Sec);
537 return uint64_t(1) << Align;
540 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
541 uint32_t Flags = getSectionFlags(this, Sec);
542 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
545 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
546 uint32_t Flags = getSectionFlags(this, Sec);
547 unsigned SectionType = Flags & MachO::SECTION_TYPE;
548 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
549 !(SectionType == MachO::S_ZEROFILL ||
550 SectionType == MachO::S_GB_ZEROFILL);
553 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
554 uint32_t Flags = getSectionFlags(this, Sec);
555 unsigned SectionType = Flags & MachO::SECTION_TYPE;
556 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
557 (SectionType == MachO::S_ZEROFILL ||
558 SectionType == MachO::S_GB_ZEROFILL);
561 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
562 return Sec.getRawDataRefImpl().d.a;
565 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
566 // FIXME: Unimplemented.
570 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
571 DataRefImpl Symb) const {
572 SymbolRef::Type ST = getSymbolType(Symb);
573 if (ST == SymbolRef::ST_Unknown)
576 uint64_t SectBegin = getSectionAddress(Sec);
577 uint64_t SectEnd = getSectionSize(Sec);
578 SectEnd += SectBegin;
581 getSymbolAddress(Symb, SymAddr);
582 return (SymAddr >= SectBegin) && (SymAddr < SectEnd);
585 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
589 return relocation_iterator(RelocationRef(Ret, this));
593 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
596 MachO::section_64 Sect = getSection64(Sec);
599 MachO::section Sect = getSection(Sec);
606 return relocation_iterator(RelocationRef(Ret, this));
609 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
613 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
614 uint64_t &Res) const {
615 uint64_t Offset = getRelocationOffset(Rel);
619 uint64_t SecAddress = getSectionAddress(Sec);
620 Res = SecAddress + Offset;
621 return std::error_code();
624 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
625 assert(getHeader().filetype == MachO::MH_OBJECT &&
626 "Only implemented for MH_OBJECT");
627 MachO::any_relocation_info RE = getRelocation(Rel);
628 return getAnyRelocationAddress(RE);
632 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
633 MachO::any_relocation_info RE = getRelocation(Rel);
634 if (isRelocationScattered(RE))
637 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
638 bool isExtern = getPlainRelocationExternal(RE);
642 MachO::symtab_command S = getSymtabLoadCommand();
643 unsigned SymbolTableEntrySize = is64Bit() ?
644 sizeof(MachO::nlist_64) :
645 sizeof(MachO::nlist);
646 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
648 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
649 return symbol_iterator(SymbolRef(Sym, this));
653 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
654 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
657 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
658 MachO::any_relocation_info RE = getRelocation(Rel);
659 return getAnyRelocationType(RE);
663 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
664 SmallVectorImpl<char> &Result) const {
666 uint64_t RType = getRelocationType(Rel);
668 unsigned Arch = this->getArch();
672 static const char *const Table[] = {
673 "GENERIC_RELOC_VANILLA",
674 "GENERIC_RELOC_PAIR",
675 "GENERIC_RELOC_SECTDIFF",
676 "GENERIC_RELOC_PB_LA_PTR",
677 "GENERIC_RELOC_LOCAL_SECTDIFF",
678 "GENERIC_RELOC_TLV" };
686 case Triple::x86_64: {
687 static const char *const Table[] = {
688 "X86_64_RELOC_UNSIGNED",
689 "X86_64_RELOC_SIGNED",
690 "X86_64_RELOC_BRANCH",
691 "X86_64_RELOC_GOT_LOAD",
693 "X86_64_RELOC_SUBTRACTOR",
694 "X86_64_RELOC_SIGNED_1",
695 "X86_64_RELOC_SIGNED_2",
696 "X86_64_RELOC_SIGNED_4",
697 "X86_64_RELOC_TLV" };
706 static const char *const Table[] = {
709 "ARM_RELOC_SECTDIFF",
710 "ARM_RELOC_LOCAL_SECTDIFF",
711 "ARM_RELOC_PB_LA_PTR",
713 "ARM_THUMB_RELOC_BR22",
714 "ARM_THUMB_32BIT_BRANCH",
716 "ARM_RELOC_HALF_SECTDIFF" };
724 case Triple::aarch64: {
725 static const char *const Table[] = {
726 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
727 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
728 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
729 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
730 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
734 if (RType >= array_lengthof(Table))
741 static const char *const Table[] = {
750 "PPC_RELOC_SECTDIFF",
751 "PPC_RELOC_PB_LA_PTR",
752 "PPC_RELOC_HI16_SECTDIFF",
753 "PPC_RELOC_LO16_SECTDIFF",
754 "PPC_RELOC_HA16_SECTDIFF",
756 "PPC_RELOC_LO14_SECTDIFF",
757 "PPC_RELOC_LOCAL_SECTDIFF" };
765 case Triple::UnknownArch:
769 Result.append(res.begin(), res.end());
770 return std::error_code();
773 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
774 MachO::any_relocation_info RE = getRelocation(Rel);
775 return getAnyRelocationLength(RE);
779 // guessLibraryShortName() is passed a name of a dynamic library and returns a
780 // guess on what the short name is. Then name is returned as a substring of the
781 // StringRef Name passed in. The name of the dynamic library is recognized as
782 // a framework if it has one of the two following forms:
783 // Foo.framework/Versions/A/Foo
785 // Where A and Foo can be any string. And may contain a trailing suffix
786 // starting with an underbar. If the Name is recognized as a framework then
787 // isFramework is set to true else it is set to false. If the Name has a
788 // suffix then Suffix is set to the substring in Name that contains the suffix
789 // else it is set to a NULL StringRef.
791 // The Name of the dynamic library is recognized as a library name if it has
792 // one of the two following forms:
795 // The library may have a suffix trailing the name Foo of the form:
796 // libFoo_profile.A.dylib
797 // libFoo_profile.dylib
799 // The Name of the dynamic library is also recognized as a library name if it
800 // has the following form:
803 // If the Name of the dynamic library is none of the forms above then a NULL
804 // StringRef is returned.
806 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
809 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
810 size_t a, b, c, d, Idx;
813 Suffix = StringRef();
815 // Pull off the last component and make Foo point to it
817 if (a == Name.npos || a == 0)
819 Foo = Name.slice(a+1, Name.npos);
821 // Look for a suffix starting with a '_'
822 Idx = Foo.rfind('_');
823 if (Idx != Foo.npos && Foo.size() >= 2) {
824 Suffix = Foo.slice(Idx, Foo.npos);
825 Foo = Foo.slice(0, Idx);
828 // First look for the form Foo.framework/Foo
829 b = Name.rfind('/', a);
834 F = Name.slice(Idx, Idx + Foo.size());
835 DotFramework = Name.slice(Idx + Foo.size(),
836 Idx + Foo.size() + sizeof(".framework/")-1);
837 if (F == Foo && DotFramework == ".framework/") {
842 // Next look for the form Foo.framework/Versions/A/Foo
845 c = Name.rfind('/', b);
846 if (c == Name.npos || c == 0)
848 V = Name.slice(c+1, Name.npos);
849 if (!V.startswith("Versions/"))
851 d = Name.rfind('/', c);
856 F = Name.slice(Idx, Idx + Foo.size());
857 DotFramework = Name.slice(Idx + Foo.size(),
858 Idx + Foo.size() + sizeof(".framework/")-1);
859 if (F == Foo && DotFramework == ".framework/") {
865 // pull off the suffix after the "." and make a point to it
867 if (a == Name.npos || a == 0)
869 Dylib = Name.slice(a, Name.npos);
870 if (Dylib != ".dylib")
873 // First pull off the version letter for the form Foo.A.dylib if any.
875 Dot = Name.slice(a-2, a-1);
880 b = Name.rfind('/', a);
885 // ignore any suffix after an underbar like Foo_profile.A.dylib
886 Idx = Name.find('_', b);
887 if (Idx != Name.npos && Idx != b) {
888 Lib = Name.slice(b, Idx);
889 Suffix = Name.slice(Idx, a);
892 Lib = Name.slice(b, a);
893 // There are incorrect library names of the form:
894 // libATS.A_profile.dylib so check for these.
895 if (Lib.size() >= 3) {
896 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
898 Lib = Lib.slice(0, Lib.size()-2);
903 Qtx = Name.slice(a, Name.npos);
906 b = Name.rfind('/', a);
908 Lib = Name.slice(0, a);
910 Lib = Name.slice(b+1, a);
911 // There are library names of the form: QT.A.qtx so check for these.
912 if (Lib.size() >= 3) {
913 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
915 Lib = Lib.slice(0, Lib.size()-2);
920 // getLibraryShortNameByIndex() is used to get the short name of the library
921 // for an undefined symbol in a linked Mach-O binary that was linked with the
922 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
923 // It is passed the index (0 - based) of the library as translated from
924 // GET_LIBRARY_ORDINAL (1 - based).
925 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
926 StringRef &Res) const {
927 if (Index >= Libraries.size())
928 return object_error::parse_failed;
930 // If the cache of LibrariesShortNames is not built up do that first for
931 // all the Libraries.
932 if (LibrariesShortNames.size() == 0) {
933 for (unsigned i = 0; i < Libraries.size(); i++) {
934 MachO::dylib_command D =
935 getStruct<MachO::dylib_command>(this, Libraries[i]);
936 if (D.dylib.name >= D.cmdsize)
937 return object_error::parse_failed;
938 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
939 StringRef Name = StringRef(P);
940 if (D.dylib.name+Name.size() >= D.cmdsize)
941 return object_error::parse_failed;
944 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
945 if (shortName.empty())
946 LibrariesShortNames.push_back(Name);
948 LibrariesShortNames.push_back(shortName);
952 Res = LibrariesShortNames[Index];
953 return std::error_code();
956 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
957 return getSymbolByIndex(0);
960 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
963 return basic_symbol_iterator(SymbolRef(DRI, this));
965 MachO::symtab_command Symtab = getSymtabLoadCommand();
966 unsigned SymbolTableEntrySize = is64Bit() ?
967 sizeof(MachO::nlist_64) :
968 sizeof(MachO::nlist);
969 unsigned Offset = Symtab.symoff +
970 Symtab.nsyms * SymbolTableEntrySize;
971 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
972 return basic_symbol_iterator(SymbolRef(DRI, this));
975 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
978 return basic_symbol_iterator(SymbolRef(DRI, this));
980 MachO::symtab_command Symtab = getSymtabLoadCommand();
981 if (Index >= Symtab.nsyms)
982 report_fatal_error("Requested symbol index is out of range.");
983 unsigned SymbolTableEntrySize =
984 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
985 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
986 DRI.p += Index * SymbolTableEntrySize;
987 return basic_symbol_iterator(SymbolRef(DRI, this));
990 section_iterator MachOObjectFile::section_begin() const {
992 return section_iterator(SectionRef(DRI, this));
995 section_iterator MachOObjectFile::section_end() const {
997 DRI.d.a = Sections.size();
998 return section_iterator(SectionRef(DRI, this));
1001 uint8_t MachOObjectFile::getBytesInAddress() const {
1002 return is64Bit() ? 8 : 4;
1005 StringRef MachOObjectFile::getFileFormatName() const {
1006 unsigned CPUType = getCPUType(this);
1009 case llvm::MachO::CPU_TYPE_I386:
1010 return "Mach-O 32-bit i386";
1011 case llvm::MachO::CPU_TYPE_ARM:
1012 return "Mach-O arm";
1013 case llvm::MachO::CPU_TYPE_POWERPC:
1014 return "Mach-O 32-bit ppc";
1016 return "Mach-O 32-bit unknown";
1021 case llvm::MachO::CPU_TYPE_X86_64:
1022 return "Mach-O 64-bit x86-64";
1023 case llvm::MachO::CPU_TYPE_ARM64:
1024 return "Mach-O arm64";
1025 case llvm::MachO::CPU_TYPE_POWERPC64:
1026 return "Mach-O 64-bit ppc64";
1028 return "Mach-O 64-bit unknown";
1032 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1034 case llvm::MachO::CPU_TYPE_I386:
1036 case llvm::MachO::CPU_TYPE_X86_64:
1037 return Triple::x86_64;
1038 case llvm::MachO::CPU_TYPE_ARM:
1040 case llvm::MachO::CPU_TYPE_ARM64:
1041 return Triple::aarch64;
1042 case llvm::MachO::CPU_TYPE_POWERPC:
1044 case llvm::MachO::CPU_TYPE_POWERPC64:
1045 return Triple::ppc64;
1047 return Triple::UnknownArch;
1051 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1052 const char **McpuDefault) {
1054 *McpuDefault = nullptr;
1057 case MachO::CPU_TYPE_I386:
1058 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1059 case MachO::CPU_SUBTYPE_I386_ALL:
1060 return Triple("i386-apple-darwin");
1064 case MachO::CPU_TYPE_X86_64:
1065 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1066 case MachO::CPU_SUBTYPE_X86_64_ALL:
1067 return Triple("x86_64-apple-darwin");
1068 case MachO::CPU_SUBTYPE_X86_64_H:
1069 return Triple("x86_64h-apple-darwin");
1073 case MachO::CPU_TYPE_ARM:
1074 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1075 case MachO::CPU_SUBTYPE_ARM_V4T:
1076 return Triple("armv4t-apple-darwin");
1077 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1078 return Triple("armv5e-apple-darwin");
1079 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1080 return Triple("xscale-apple-darwin");
1081 case MachO::CPU_SUBTYPE_ARM_V6:
1082 return Triple("armv6-apple-darwin");
1083 case MachO::CPU_SUBTYPE_ARM_V6M:
1085 *McpuDefault = "cortex-m0";
1086 return Triple("armv6m-apple-darwin");
1087 case MachO::CPU_SUBTYPE_ARM_V7:
1088 return Triple("armv7-apple-darwin");
1089 case MachO::CPU_SUBTYPE_ARM_V7EM:
1091 *McpuDefault = "cortex-m4";
1092 return Triple("armv7em-apple-darwin");
1093 case MachO::CPU_SUBTYPE_ARM_V7K:
1094 return Triple("armv7k-apple-darwin");
1095 case MachO::CPU_SUBTYPE_ARM_V7M:
1097 *McpuDefault = "cortex-m3";
1098 return Triple("armv7m-apple-darwin");
1099 case MachO::CPU_SUBTYPE_ARM_V7S:
1100 return Triple("armv7s-apple-darwin");
1104 case MachO::CPU_TYPE_ARM64:
1105 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1106 case MachO::CPU_SUBTYPE_ARM64_ALL:
1107 return Triple("arm64-apple-darwin");
1111 case MachO::CPU_TYPE_POWERPC:
1112 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1113 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1114 return Triple("ppc-apple-darwin");
1118 case MachO::CPU_TYPE_POWERPC64:
1119 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1120 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1121 return Triple("ppc64-apple-darwin");
1130 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
1131 const char **McpuDefault) {
1133 *McpuDefault = nullptr;
1136 case MachO::CPU_TYPE_ARM:
1137 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1138 case MachO::CPU_SUBTYPE_ARM_V4T:
1139 return Triple("thumbv4t-apple-darwin");
1140 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1141 return Triple("thumbv5e-apple-darwin");
1142 case MachO::CPU_SUBTYPE_ARM_XSCALE:
1143 return Triple("xscale-apple-darwin");
1144 case MachO::CPU_SUBTYPE_ARM_V6:
1145 return Triple("thumbv6-apple-darwin");
1146 case MachO::CPU_SUBTYPE_ARM_V6M:
1148 *McpuDefault = "cortex-m0";
1149 return Triple("thumbv6m-apple-darwin");
1150 case MachO::CPU_SUBTYPE_ARM_V7:
1151 return Triple("thumbv7-apple-darwin");
1152 case MachO::CPU_SUBTYPE_ARM_V7EM:
1154 *McpuDefault = "cortex-m4";
1155 return Triple("thumbv7em-apple-darwin");
1156 case MachO::CPU_SUBTYPE_ARM_V7K:
1157 return Triple("thumbv7k-apple-darwin");
1158 case MachO::CPU_SUBTYPE_ARM_V7M:
1160 *McpuDefault = "cortex-m3";
1161 return Triple("thumbv7m-apple-darwin");
1162 case MachO::CPU_SUBTYPE_ARM_V7S:
1163 return Triple("thumbv7s-apple-darwin");
1172 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
1173 const char **McpuDefault,
1174 Triple *ThumbTriple) {
1175 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
1176 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
1181 Triple MachOObjectFile::getHostArch() {
1182 return Triple(sys::getDefaultTargetTriple());
1185 bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1186 return StringSwitch<bool>(ArchFlag)
1188 .Case("x86_64", true)
1189 .Case("x86_64h", true)
1190 .Case("armv4t", true)
1192 .Case("armv5e", true)
1193 .Case("armv6", true)
1194 .Case("armv6m", true)
1195 .Case("armv7", true)
1196 .Case("armv7em", true)
1197 .Case("armv7k", true)
1198 .Case("armv7m", true)
1199 .Case("armv7s", true)
1200 .Case("arm64", true)
1202 .Case("ppc64", true)
1206 unsigned MachOObjectFile::getArch() const {
1207 return getArch(getCPUType(this));
1210 Triple MachOObjectFile::getArch(const char **McpuDefault,
1211 Triple *ThumbTriple) const {
1212 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
1213 return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
1216 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1219 return section_rel_begin(DRI);
1222 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1225 return section_rel_end(DRI);
1228 dice_iterator MachOObjectFile::begin_dices() const {
1230 if (!DataInCodeLoadCmd)
1231 return dice_iterator(DiceRef(DRI, this));
1233 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1234 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1235 return dice_iterator(DiceRef(DRI, this));
1238 dice_iterator MachOObjectFile::end_dices() const {
1240 if (!DataInCodeLoadCmd)
1241 return dice_iterator(DiceRef(DRI, this));
1243 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1244 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1245 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1246 return dice_iterator(DiceRef(DRI, this));
1249 ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1250 : Trie(T), Malformed(false), Done(false) { }
1252 void ExportEntry::moveToFirst() {
1254 pushDownUntilBottom();
1257 void ExportEntry::moveToEnd() {
1262 bool ExportEntry::operator==(const ExportEntry &Other) const {
1263 // Common case, one at end, other iterating from begin.
1264 if (Done || Other.Done)
1265 return (Done == Other.Done);
1266 // Not equal if different stack sizes.
1267 if (Stack.size() != Other.Stack.size())
1269 // Not equal if different cumulative strings.
1270 if (!CumulativeString.equals(Other.CumulativeString))
1272 // Equal if all nodes in both stacks match.
1273 for (unsigned i=0; i < Stack.size(); ++i) {
1274 if (Stack[i].Start != Other.Stack[i].Start)
1280 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1282 uint64_t Result = decodeULEB128(Ptr, &Count);
1284 if (Ptr > Trie.end()) {
1291 StringRef ExportEntry::name() const {
1292 return CumulativeString;
1295 uint64_t ExportEntry::flags() const {
1296 return Stack.back().Flags;
1299 uint64_t ExportEntry::address() const {
1300 return Stack.back().Address;
1303 uint64_t ExportEntry::other() const {
1304 return Stack.back().Other;
1307 StringRef ExportEntry::otherName() const {
1308 const char* ImportName = Stack.back().ImportName;
1310 return StringRef(ImportName);
1314 uint32_t ExportEntry::nodeOffset() const {
1315 return Stack.back().Start - Trie.begin();
1318 ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1319 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1320 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1321 ParentStringLength(0), IsExportNode(false) {
1324 void ExportEntry::pushNode(uint64_t offset) {
1325 const uint8_t *Ptr = Trie.begin() + offset;
1326 NodeState State(Ptr);
1327 uint64_t ExportInfoSize = readULEB128(State.Current);
1328 State.IsExportNode = (ExportInfoSize != 0);
1329 const uint8_t* Children = State.Current + ExportInfoSize;
1330 if (State.IsExportNode) {
1331 State.Flags = readULEB128(State.Current);
1332 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1334 State.Other = readULEB128(State.Current); // dylib ordinal
1335 State.ImportName = reinterpret_cast<const char*>(State.Current);
1337 State.Address = readULEB128(State.Current);
1338 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1339 State.Other = readULEB128(State.Current);
1342 State.ChildCount = *Children;
1343 State.Current = Children + 1;
1344 State.NextChildIndex = 0;
1345 State.ParentStringLength = CumulativeString.size();
1346 Stack.push_back(State);
1349 void ExportEntry::pushDownUntilBottom() {
1350 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1351 NodeState &Top = Stack.back();
1352 CumulativeString.resize(Top.ParentStringLength);
1353 for (;*Top.Current != 0; Top.Current++) {
1354 char C = *Top.Current;
1355 CumulativeString.push_back(C);
1358 uint64_t childNodeIndex = readULEB128(Top.Current);
1359 Top.NextChildIndex += 1;
1360 pushNode(childNodeIndex);
1362 if (!Stack.back().IsExportNode) {
1368 // We have a trie data structure and need a way to walk it that is compatible
1369 // with the C++ iterator model. The solution is a non-recursive depth first
1370 // traversal where the iterator contains a stack of parent nodes along with a
1371 // string that is the accumulation of all edge strings along the parent chain
1374 // There is one "export" node for each exported symbol. But because some
1375 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1376 // node may have child nodes too.
1378 // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1379 // child until hitting a node with no children (which is an export node or
1380 // else the trie is malformed). On the way down, each node is pushed on the
1381 // stack ivar. If there is no more ways down, it pops up one and tries to go
1382 // down a sibling path until a childless node is reached.
1383 void ExportEntry::moveNext() {
1384 if (Stack.empty() || !Stack.back().IsExportNode) {
1391 while (!Stack.empty()) {
1392 NodeState &Top = Stack.back();
1393 if (Top.NextChildIndex < Top.ChildCount) {
1394 pushDownUntilBottom();
1395 // Now at the next export node.
1398 if (Top.IsExportNode) {
1399 // This node has no children but is itself an export node.
1400 CumulativeString.resize(Top.ParentStringLength);
1409 iterator_range<export_iterator>
1410 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1411 ExportEntry Start(Trie);
1412 if (Trie.size() == 0)
1415 Start.moveToFirst();
1417 ExportEntry Finish(Trie);
1420 return iterator_range<export_iterator>(export_iterator(Start),
1421 export_iterator(Finish));
1424 iterator_range<export_iterator> MachOObjectFile::exports() const {
1425 return exports(getDyldInfoExportsTrie());
1429 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1430 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1431 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1432 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1434 void MachORebaseEntry::moveToFirst() {
1435 Ptr = Opcodes.begin();
1439 void MachORebaseEntry::moveToEnd() {
1440 Ptr = Opcodes.end();
1441 RemainingLoopCount = 0;
1445 void MachORebaseEntry::moveNext() {
1446 // If in the middle of some loop, move to next rebasing in loop.
1447 SegmentOffset += AdvanceAmount;
1448 if (RemainingLoopCount) {
1449 --RemainingLoopCount;
1452 if (Ptr == Opcodes.end()) {
1457 while (More && !Malformed) {
1458 // Parse next opcode and set up next loop.
1459 uint8_t Byte = *Ptr++;
1460 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1461 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1463 case MachO::REBASE_OPCODE_DONE:
1467 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1469 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1470 RebaseType = ImmValue;
1473 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1474 << "RebaseType=" << (int) RebaseType << "\n");
1476 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1477 SegmentIndex = ImmValue;
1478 SegmentOffset = readULEB128();
1481 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1482 << "SegmentIndex=" << SegmentIndex << ", "
1483 << format("SegmentOffset=0x%06X", SegmentOffset)
1486 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1487 SegmentOffset += readULEB128();
1488 DEBUG_WITH_TYPE("mach-o-rebase",
1489 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1490 << format("SegmentOffset=0x%06X",
1491 SegmentOffset) << "\n");
1493 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1494 SegmentOffset += ImmValue * PointerSize;
1495 DEBUG_WITH_TYPE("mach-o-rebase",
1496 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1497 << format("SegmentOffset=0x%06X",
1498 SegmentOffset) << "\n");
1500 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1501 AdvanceAmount = PointerSize;
1502 RemainingLoopCount = ImmValue - 1;
1505 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1506 << format("SegmentOffset=0x%06X", SegmentOffset)
1507 << ", AdvanceAmount=" << AdvanceAmount
1508 << ", RemainingLoopCount=" << RemainingLoopCount
1511 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1512 AdvanceAmount = PointerSize;
1513 RemainingLoopCount = readULEB128() - 1;
1516 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1517 << format("SegmentOffset=0x%06X", SegmentOffset)
1518 << ", AdvanceAmount=" << AdvanceAmount
1519 << ", RemainingLoopCount=" << RemainingLoopCount
1522 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1523 AdvanceAmount = readULEB128() + PointerSize;
1524 RemainingLoopCount = 0;
1527 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1528 << format("SegmentOffset=0x%06X", SegmentOffset)
1529 << ", AdvanceAmount=" << AdvanceAmount
1530 << ", RemainingLoopCount=" << RemainingLoopCount
1533 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1534 RemainingLoopCount = readULEB128() - 1;
1535 AdvanceAmount = readULEB128() + PointerSize;
1538 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1539 << format("SegmentOffset=0x%06X", SegmentOffset)
1540 << ", AdvanceAmount=" << AdvanceAmount
1541 << ", RemainingLoopCount=" << RemainingLoopCount
1550 uint64_t MachORebaseEntry::readULEB128() {
1552 uint64_t Result = decodeULEB128(Ptr, &Count);
1554 if (Ptr > Opcodes.end()) {
1555 Ptr = Opcodes.end();
1561 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1563 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1565 StringRef MachORebaseEntry::typeName() const {
1566 switch (RebaseType) {
1567 case MachO::REBASE_TYPE_POINTER:
1569 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1570 return "text abs32";
1571 case MachO::REBASE_TYPE_TEXT_PCREL32:
1572 return "text rel32";
1577 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1578 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1579 return (Ptr == Other.Ptr) &&
1580 (RemainingLoopCount == Other.RemainingLoopCount) &&
1581 (Done == Other.Done);
1584 iterator_range<rebase_iterator>
1585 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1586 MachORebaseEntry Start(Opcodes, is64);
1587 Start.moveToFirst();
1589 MachORebaseEntry Finish(Opcodes, is64);
1592 return iterator_range<rebase_iterator>(rebase_iterator(Start),
1593 rebase_iterator(Finish));
1596 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1597 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1601 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
1603 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1604 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1605 BindType(0), PointerSize(is64Bit ? 8 : 4),
1606 TableKind(BK), Malformed(false), Done(false) {}
1608 void MachOBindEntry::moveToFirst() {
1609 Ptr = Opcodes.begin();
1613 void MachOBindEntry::moveToEnd() {
1614 Ptr = Opcodes.end();
1615 RemainingLoopCount = 0;
1619 void MachOBindEntry::moveNext() {
1620 // If in the middle of some loop, move to next binding in loop.
1621 SegmentOffset += AdvanceAmount;
1622 if (RemainingLoopCount) {
1623 --RemainingLoopCount;
1626 if (Ptr == Opcodes.end()) {
1631 while (More && !Malformed) {
1632 // Parse next opcode and set up next loop.
1633 uint8_t Byte = *Ptr++;
1634 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1635 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1636 int8_t SignExtended;
1637 const uint8_t *SymStart;
1639 case MachO::BIND_OPCODE_DONE:
1640 if (TableKind == Kind::Lazy) {
1641 // Lazying bindings have a DONE opcode between entries. Need to ignore
1642 // it to advance to next entry. But need not if this is last entry.
1643 bool NotLastEntry = false;
1644 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1646 NotLastEntry = true;
1655 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1657 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1661 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1662 << "Ordinal=" << Ordinal << "\n");
1664 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1665 Ordinal = readULEB128();
1668 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1669 << "Ordinal=" << Ordinal << "\n");
1671 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1673 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1674 Ordinal = SignExtended;
1679 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1680 << "Ordinal=" << Ordinal << "\n");
1682 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1688 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1693 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1694 << "SymbolName=" << SymbolName << "\n");
1695 if (TableKind == Kind::Weak) {
1696 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1700 case MachO::BIND_OPCODE_SET_TYPE_IMM:
1701 BindType = ImmValue;
1704 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1705 << "BindType=" << (int)BindType << "\n");
1707 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1708 Addend = readSLEB128();
1709 if (TableKind == Kind::Lazy)
1713 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1714 << "Addend=" << Addend << "\n");
1716 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1717 SegmentIndex = ImmValue;
1718 SegmentOffset = readULEB128();
1721 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1722 << "SegmentIndex=" << SegmentIndex << ", "
1723 << format("SegmentOffset=0x%06X", SegmentOffset)
1726 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1727 SegmentOffset += readULEB128();
1728 DEBUG_WITH_TYPE("mach-o-bind",
1729 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1730 << format("SegmentOffset=0x%06X",
1731 SegmentOffset) << "\n");
1733 case MachO::BIND_OPCODE_DO_BIND:
1734 AdvanceAmount = PointerSize;
1735 RemainingLoopCount = 0;
1736 DEBUG_WITH_TYPE("mach-o-bind",
1737 llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1738 << format("SegmentOffset=0x%06X",
1739 SegmentOffset) << "\n");
1741 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1742 AdvanceAmount = readULEB128() + PointerSize;
1743 RemainingLoopCount = 0;
1744 if (TableKind == Kind::Lazy)
1748 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1749 << format("SegmentOffset=0x%06X", SegmentOffset)
1750 << ", AdvanceAmount=" << AdvanceAmount
1751 << ", RemainingLoopCount=" << RemainingLoopCount
1754 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1755 AdvanceAmount = ImmValue * PointerSize + PointerSize;
1756 RemainingLoopCount = 0;
1757 if (TableKind == Kind::Lazy)
1759 DEBUG_WITH_TYPE("mach-o-bind",
1761 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1762 << format("SegmentOffset=0x%06X",
1763 SegmentOffset) << "\n");
1765 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1766 RemainingLoopCount = readULEB128() - 1;
1767 AdvanceAmount = readULEB128() + PointerSize;
1768 if (TableKind == Kind::Lazy)
1772 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1773 << format("SegmentOffset=0x%06X", SegmentOffset)
1774 << ", AdvanceAmount=" << AdvanceAmount
1775 << ", RemainingLoopCount=" << RemainingLoopCount
1784 uint64_t MachOBindEntry::readULEB128() {
1786 uint64_t Result = decodeULEB128(Ptr, &Count);
1788 if (Ptr > Opcodes.end()) {
1789 Ptr = Opcodes.end();
1795 int64_t MachOBindEntry::readSLEB128() {
1797 int64_t Result = decodeSLEB128(Ptr, &Count);
1799 if (Ptr > Opcodes.end()) {
1800 Ptr = Opcodes.end();
1807 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1809 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1811 StringRef MachOBindEntry::typeName() const {
1813 case MachO::BIND_TYPE_POINTER:
1815 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1816 return "text abs32";
1817 case MachO::BIND_TYPE_TEXT_PCREL32:
1818 return "text rel32";
1823 StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1825 int64_t MachOBindEntry::addend() const { return Addend; }
1827 uint32_t MachOBindEntry::flags() const { return Flags; }
1829 int MachOBindEntry::ordinal() const { return Ordinal; }
1831 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1832 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1833 return (Ptr == Other.Ptr) &&
1834 (RemainingLoopCount == Other.RemainingLoopCount) &&
1835 (Done == Other.Done);
1838 iterator_range<bind_iterator>
1839 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1840 MachOBindEntry::Kind BKind) {
1841 MachOBindEntry Start(Opcodes, is64, BKind);
1842 Start.moveToFirst();
1844 MachOBindEntry Finish(Opcodes, is64, BKind);
1847 return iterator_range<bind_iterator>(bind_iterator(Start),
1848 bind_iterator(Finish));
1851 iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1852 return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1853 MachOBindEntry::Kind::Regular);
1856 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1857 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1858 MachOBindEntry::Kind::Lazy);
1861 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1862 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1863 MachOBindEntry::Kind::Weak);
1866 MachOObjectFile::load_command_iterator
1867 MachOObjectFile::begin_load_commands() const {
1868 return LoadCommands.begin();
1871 MachOObjectFile::load_command_iterator
1872 MachOObjectFile::end_load_commands() const {
1873 return LoadCommands.end();
1876 iterator_range<MachOObjectFile::load_command_iterator>
1877 MachOObjectFile::load_commands() const {
1878 return iterator_range<load_command_iterator>(begin_load_commands(),
1879 end_load_commands());
1883 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1884 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1885 return parseSegmentOrSectionName(Raw.data());
1889 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1890 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1891 const section_base *Base =
1892 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1893 return makeArrayRef(Base->sectname);
1897 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1898 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1899 const section_base *Base =
1900 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1901 return makeArrayRef(Base->segname);
1905 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1907 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1909 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1912 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1913 const MachO::any_relocation_info &RE) const {
1914 if (isLittleEndian())
1915 return RE.r_word1 & 0xffffff;
1916 return RE.r_word1 >> 8;
1919 bool MachOObjectFile::getPlainRelocationExternal(
1920 const MachO::any_relocation_info &RE) const {
1921 if (isLittleEndian())
1922 return (RE.r_word1 >> 27) & 1;
1923 return (RE.r_word1 >> 4) & 1;
1926 bool MachOObjectFile::getScatteredRelocationScattered(
1927 const MachO::any_relocation_info &RE) const {
1928 return RE.r_word0 >> 31;
1931 uint32_t MachOObjectFile::getScatteredRelocationValue(
1932 const MachO::any_relocation_info &RE) const {
1936 uint32_t MachOObjectFile::getScatteredRelocationType(
1937 const MachO::any_relocation_info &RE) const {
1938 return (RE.r_word0 >> 24) & 0xf;
1941 unsigned MachOObjectFile::getAnyRelocationAddress(
1942 const MachO::any_relocation_info &RE) const {
1943 if (isRelocationScattered(RE))
1944 return getScatteredRelocationAddress(RE);
1945 return getPlainRelocationAddress(RE);
1948 unsigned MachOObjectFile::getAnyRelocationPCRel(
1949 const MachO::any_relocation_info &RE) const {
1950 if (isRelocationScattered(RE))
1951 return getScatteredRelocationPCRel(this, RE);
1952 return getPlainRelocationPCRel(this, RE);
1955 unsigned MachOObjectFile::getAnyRelocationLength(
1956 const MachO::any_relocation_info &RE) const {
1957 if (isRelocationScattered(RE))
1958 return getScatteredRelocationLength(RE);
1959 return getPlainRelocationLength(this, RE);
1963 MachOObjectFile::getAnyRelocationType(
1964 const MachO::any_relocation_info &RE) const {
1965 if (isRelocationScattered(RE))
1966 return getScatteredRelocationType(RE);
1967 return getPlainRelocationType(this, RE);
1971 MachOObjectFile::getAnyRelocationSection(
1972 const MachO::any_relocation_info &RE) const {
1973 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1974 return *section_end();
1975 unsigned SecNum = getPlainRelocationSymbolNum(RE);
1976 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
1977 return *section_end();
1979 DRI.d.a = SecNum - 1;
1980 return SectionRef(DRI, this);
1983 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1984 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1985 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1988 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1989 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
1990 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1993 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1994 unsigned Index) const {
1995 const char *Sec = getSectionPtr(this, L, Index);
1996 return getStruct<MachO::section>(this, Sec);
1999 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2000 unsigned Index) const {
2001 const char *Sec = getSectionPtr(this, L, Index);
2002 return getStruct<MachO::section_64>(this, Sec);
2006 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2007 const char *P = reinterpret_cast<const char *>(DRI.p);
2008 return getStruct<MachO::nlist>(this, P);
2012 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2013 const char *P = reinterpret_cast<const char *>(DRI.p);
2014 return getStruct<MachO::nlist_64>(this, P);
2017 MachO::linkedit_data_command
2018 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2019 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2022 MachO::segment_command
2023 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2024 return getStruct<MachO::segment_command>(this, L.Ptr);
2027 MachO::segment_command_64
2028 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2029 return getStruct<MachO::segment_command_64>(this, L.Ptr);
2032 MachO::linker_option_command
2033 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2034 return getStruct<MachO::linker_option_command>(this, L.Ptr);
2037 MachO::version_min_command
2038 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2039 return getStruct<MachO::version_min_command>(this, L.Ptr);
2042 MachO::dylib_command
2043 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2044 return getStruct<MachO::dylib_command>(this, L.Ptr);
2047 MachO::dyld_info_command
2048 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2049 return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2052 MachO::dylinker_command
2053 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2054 return getStruct<MachO::dylinker_command>(this, L.Ptr);
2058 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2059 return getStruct<MachO::uuid_command>(this, L.Ptr);
2062 MachO::rpath_command
2063 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2064 return getStruct<MachO::rpath_command>(this, L.Ptr);
2067 MachO::source_version_command
2068 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2069 return getStruct<MachO::source_version_command>(this, L.Ptr);
2072 MachO::entry_point_command
2073 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2074 return getStruct<MachO::entry_point_command>(this, L.Ptr);
2077 MachO::encryption_info_command
2078 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2079 return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2082 MachO::encryption_info_command_64
2083 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2084 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2087 MachO::sub_framework_command
2088 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2089 return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2092 MachO::sub_umbrella_command
2093 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2094 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2097 MachO::sub_library_command
2098 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2099 return getStruct<MachO::sub_library_command>(this, L.Ptr);
2102 MachO::sub_client_command
2103 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2104 return getStruct<MachO::sub_client_command>(this, L.Ptr);
2107 MachO::routines_command
2108 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2109 return getStruct<MachO::routines_command>(this, L.Ptr);
2112 MachO::routines_command_64
2113 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2114 return getStruct<MachO::routines_command_64>(this, L.Ptr);
2117 MachO::thread_command
2118 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2119 return getStruct<MachO::thread_command>(this, L.Ptr);
2122 MachO::any_relocation_info
2123 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2128 MachO::section_64 Sect = getSection64(Sec);
2129 Offset = Sect.reloff;
2131 MachO::section Sect = getSection(Sec);
2132 Offset = Sect.reloff;
2135 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2136 getPtr(this, Offset)) + Rel.d.b;
2137 return getStruct<MachO::any_relocation_info>(
2138 this, reinterpret_cast<const char *>(P));
2141 MachO::data_in_code_entry
2142 MachOObjectFile::getDice(DataRefImpl Rel) const {
2143 const char *P = reinterpret_cast<const char *>(Rel.p);
2144 return getStruct<MachO::data_in_code_entry>(this, P);
2147 const MachO::mach_header &MachOObjectFile::getHeader() const {
2151 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2156 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2157 const MachO::dysymtab_command &DLC,
2158 unsigned Index) const {
2159 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2160 return getStruct<uint32_t>(this, getPtr(this, Offset));
2163 MachO::data_in_code_entry
2164 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2165 unsigned Index) const {
2166 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2167 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2170 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2172 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2174 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2175 MachO::symtab_command Cmd;
2176 Cmd.cmd = MachO::LC_SYMTAB;
2177 Cmd.cmdsize = sizeof(MachO::symtab_command);
2185 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2186 if (DysymtabLoadCmd)
2187 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2189 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2190 MachO::dysymtab_command Cmd;
2191 Cmd.cmd = MachO::LC_DYSYMTAB;
2192 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2203 Cmd.extrefsymoff = 0;
2204 Cmd.nextrefsyms = 0;
2205 Cmd.indirectsymoff = 0;
2206 Cmd.nindirectsyms = 0;
2214 MachO::linkedit_data_command
2215 MachOObjectFile::getDataInCodeLoadCommand() const {
2216 if (DataInCodeLoadCmd)
2217 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2219 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2220 MachO::linkedit_data_command Cmd;
2221 Cmd.cmd = MachO::LC_DATA_IN_CODE;
2222 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2228 MachO::linkedit_data_command
2229 MachOObjectFile::getLinkOptHintsLoadCommand() const {
2230 if (LinkOptHintsLoadCmd)
2231 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2233 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2235 MachO::linkedit_data_command Cmd;
2236 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2237 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2243 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2244 if (!DyldInfoLoadCmd)
2245 return ArrayRef<uint8_t>();
2247 MachO::dyld_info_command DyldInfo
2248 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2249 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2250 getPtr(this, DyldInfo.rebase_off));
2251 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size);
2254 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2255 if (!DyldInfoLoadCmd)
2256 return ArrayRef<uint8_t>();
2258 MachO::dyld_info_command DyldInfo
2259 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2260 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2261 getPtr(this, DyldInfo.bind_off));
2262 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size);
2265 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2266 if (!DyldInfoLoadCmd)
2267 return ArrayRef<uint8_t>();
2269 MachO::dyld_info_command DyldInfo
2270 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2271 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2272 getPtr(this, DyldInfo.weak_bind_off));
2273 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size);
2276 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2277 if (!DyldInfoLoadCmd)
2278 return ArrayRef<uint8_t>();
2280 MachO::dyld_info_command DyldInfo
2281 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2282 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2283 getPtr(this, DyldInfo.lazy_bind_off));
2284 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size);
2287 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2288 if (!DyldInfoLoadCmd)
2289 return ArrayRef<uint8_t>();
2291 MachO::dyld_info_command DyldInfo
2292 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2293 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>(
2294 getPtr(this, DyldInfo.export_off));
2295 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size);
2298 ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2300 return ArrayRef<uint8_t>();
2301 // Returning a pointer is fine as uuid doesn't need endian swapping.
2302 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2303 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16);
2306 StringRef MachOObjectFile::getStringTableData() const {
2307 MachO::symtab_command S = getSymtabLoadCommand();
2308 return getData().substr(S.stroff, S.strsize);
2311 bool MachOObjectFile::is64Bit() const {
2312 return getType() == getMachOType(false, true) ||
2313 getType() == getMachOType(true, true);
2316 void MachOObjectFile::ReadULEB128s(uint64_t Index,
2317 SmallVectorImpl<uint64_t> &Out) const {
2318 DataExtractor extractor(ObjectFile::getData(), true, 0);
2320 uint32_t offset = Index;
2322 while (uint64_t delta = extractor.getULEB128(&offset)) {
2324 Out.push_back(data);
2328 bool MachOObjectFile::isRelocatableObject() const {
2329 return getHeader().filetype == MachO::MH_OBJECT;
2332 ErrorOr<std::unique_ptr<MachOObjectFile>>
2333 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2334 StringRef Magic = Buffer.getBuffer().slice(0, 4);
2336 std::unique_ptr<MachOObjectFile> Ret;
2337 if (Magic == "\xFE\xED\xFA\xCE")
2338 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
2339 else if (Magic == "\xCE\xFA\xED\xFE")
2340 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
2341 else if (Magic == "\xFE\xED\xFA\xCF")
2342 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
2343 else if (Magic == "\xCF\xFA\xED\xFE")
2344 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
2346 return object_error::parse_failed;
2350 return std::move(Ret);