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/Triple.h"
18 #include "llvm/Support/DataExtractor.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/Host.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/raw_ostream.h"
28 using namespace object;
38 static T getStruct(const MachOObjectFile *O, const char *P) {
40 memcpy(&Cmd, P, sizeof(T));
41 if (O->isLittleEndian() != sys::IsLittleEndianHost)
42 MachO::swapStruct(Cmd);
47 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
48 const MachOObjectFile::LoadCommandInfo &L) {
50 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
53 MachO::segment_command S = O->getSegmentLoadCommand(L);
58 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
60 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
62 bool Is64 = O->is64Bit();
63 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
64 sizeof(MachO::segment_command);
65 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
66 sizeof(MachO::section);
68 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
69 return reinterpret_cast<const char*>(SectionAddr);
72 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
73 return O->getData().substr(Offset, 1).data();
76 static MachO::nlist_base
77 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
78 const char *P = reinterpret_cast<const char *>(DRI.p);
79 return getStruct<MachO::nlist_base>(O, P);
82 static StringRef parseSegmentOrSectionName(const char *P) {
86 // Not null terminated, so this is a 16 char string.
87 return StringRef(P, 16);
90 // Helper to advance a section or symbol iterator multiple increments at a time.
92 static void advance(T &it, size_t Val) {
97 static unsigned getCPUType(const MachOObjectFile *O) {
98 return O->getHeader().cputype;
101 static void printRelocationTargetName(const MachOObjectFile *O,
102 const MachO::any_relocation_info &RE,
103 raw_string_ostream &fmt) {
104 bool IsScattered = O->isRelocationScattered(RE);
106 // Target of a scattered relocation is an address. In the interest of
107 // generating pretty output, scan through the symbol table looking for a
108 // symbol that aligns with that address. If we find one, print it.
109 // Otherwise, we just print the hex address of the target.
111 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
113 for (const SymbolRef &Symbol : O->symbols()) {
118 if ((ec = Symbol.getAddress(Addr)))
119 report_fatal_error(ec.message());
122 if ((ec = Symbol.getName(Name)))
123 report_fatal_error(ec.message());
128 // If we couldn't find a symbol that this relocation refers to, try
129 // to find a section beginning instead.
130 for (const SectionRef &Section : O->sections()) {
135 if ((ec = Section.getAddress(Addr)))
136 report_fatal_error(ec.message());
139 if ((ec = Section.getName(Name)))
140 report_fatal_error(ec.message());
145 fmt << format("0x%x", Val);
150 bool isExtern = O->getPlainRelocationExternal(RE);
151 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
154 symbol_iterator SI = O->symbol_begin();
158 section_iterator SI = O->section_begin();
159 // Adjust for the fact that sections are 1-indexed.
160 advance(SI, Val - 1);
168 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
173 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
174 return RE.r_word0 & 0xffffff;
177 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
178 const MachO::any_relocation_info &RE) {
179 if (O->isLittleEndian())
180 return (RE.r_word1 >> 24) & 1;
181 return (RE.r_word1 >> 7) & 1;
185 getScatteredRelocationPCRel(const MachOObjectFile *O,
186 const MachO::any_relocation_info &RE) {
187 return (RE.r_word0 >> 30) & 1;
190 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
191 const MachO::any_relocation_info &RE) {
192 if (O->isLittleEndian())
193 return (RE.r_word1 >> 25) & 3;
194 return (RE.r_word1 >> 5) & 3;
198 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
199 return (RE.r_word0 >> 28) & 3;
202 static unsigned getPlainRelocationType(const MachOObjectFile *O,
203 const MachO::any_relocation_info &RE) {
204 if (O->isLittleEndian())
205 return RE.r_word1 >> 28;
206 return RE.r_word1 & 0xf;
210 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
211 return (RE.r_word0 >> 24) & 0xf;
214 static uint32_t getSectionFlags(const MachOObjectFile *O,
217 MachO::section_64 Sect = O->getSection64(Sec);
220 MachO::section Sect = O->getSection(Sec);
224 MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object,
225 bool IsLittleEndian, bool Is64bits,
227 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)),
228 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
229 DataInCodeLoadCmd(nullptr) {
230 uint32_t LoadCommandCount = this->getHeader().ncmds;
231 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
232 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
234 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
235 for (unsigned I = 0; ; ++I) {
236 if (Load.C.cmd == MachO::LC_SYMTAB) {
237 assert(!SymtabLoadCmd && "Multiple symbol tables");
238 SymtabLoadCmd = Load.Ptr;
239 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
240 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
241 DysymtabLoadCmd = Load.Ptr;
242 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
243 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
244 DataInCodeLoadCmd = Load.Ptr;
245 } else if (Load.C.cmd == SegmentLoadType) {
246 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
247 for (unsigned J = 0; J < NumSections; ++J) {
248 const char *Sec = getSectionPtr(this, Load, J);
249 Sections.push_back(Sec);
251 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
252 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
253 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
254 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
255 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
256 Libraries.push_back(Load.Ptr);
259 if (I == LoadCommandCount - 1)
262 Load = getNextLoadCommandInfo(Load);
266 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
267 unsigned SymbolTableEntrySize = is64Bit() ?
268 sizeof(MachO::nlist_64) :
269 sizeof(MachO::nlist);
270 Symb.p += SymbolTableEntrySize;
273 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
274 StringRef &Res) const {
275 StringRef StringTable = getStringTableData();
276 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
277 const char *Start = &StringTable.data()[Entry.n_strx];
278 Res = StringRef(Start);
279 return object_error::success;
282 // getIndirectName() returns the name of the alias'ed symbol who's string table
283 // index is in the n_value field.
284 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
285 StringRef &Res) const {
286 StringRef StringTable = getStringTableData();
289 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
290 NValue = Entry.n_value;
291 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
292 return object_error::parse_failed;
294 MachO::nlist Entry = getSymbolTableEntry(Symb);
295 NValue = Entry.n_value;
296 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
297 return object_error::parse_failed;
299 if (NValue >= StringTable.size())
300 return object_error::parse_failed;
301 const char *Start = &StringTable.data()[NValue];
302 Res = StringRef(Start);
303 return object_error::success;
306 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
307 uint64_t &Res) const {
309 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
310 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
312 Res = UnknownAddressOrSize;
316 MachO::nlist Entry = getSymbolTableEntry(Symb);
317 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
319 Res = UnknownAddressOrSize;
323 return object_error::success;
326 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
327 uint32_t &Result) const {
328 uint32_t flags = getSymbolFlags(DRI);
329 if (flags & SymbolRef::SF_Common) {
330 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
331 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
335 return object_error::success;
338 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
339 uint64_t &Result) const {
340 uint64_t BeginOffset;
341 uint64_t EndOffset = 0;
342 uint8_t SectionIndex;
344 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
346 getSymbolAddress(DRI, Value);
347 if (Value == UnknownAddressOrSize) {
348 Result = UnknownAddressOrSize;
349 return object_error::success;
354 SectionIndex = Entry.n_sect;
356 uint32_t flags = getSymbolFlags(DRI);
357 if (flags & SymbolRef::SF_Common)
360 Result = UnknownAddressOrSize;
361 return object_error::success;
363 // Unfortunately symbols are unsorted so we need to touch all
364 // symbols from load command
365 for (const SymbolRef &Symbol : symbols()) {
366 DataRefImpl DRI = Symbol.getRawDataRefImpl();
367 Entry = getSymbolTableEntryBase(this, DRI);
368 getSymbolAddress(DRI, Value);
369 if (Value == UnknownAddressOrSize)
371 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
372 if (!EndOffset || Value < EndOffset)
378 Sec.d.a = SectionIndex-1;
379 getSectionSize(Sec, Size);
380 getSectionAddress(Sec, EndOffset);
383 Result = EndOffset - BeginOffset;
384 return object_error::success;
387 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
388 SymbolRef::Type &Res) const {
389 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
390 uint8_t n_type = Entry.n_type;
392 Res = SymbolRef::ST_Other;
394 // If this is a STAB debugging symbol, we can do nothing more.
395 if (n_type & MachO::N_STAB) {
396 Res = SymbolRef::ST_Debug;
397 return object_error::success;
400 switch (n_type & MachO::N_TYPE) {
402 Res = SymbolRef::ST_Unknown;
405 Res = SymbolRef::ST_Function;
408 return object_error::success;
411 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
412 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
414 uint8_t MachOType = Entry.n_type;
415 uint16_t MachOFlags = Entry.n_desc;
417 uint32_t Result = SymbolRef::SF_None;
419 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
420 Result |= SymbolRef::SF_Undefined;
422 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
423 Result |= SymbolRef::SF_Indirect;
425 if (MachOType & MachO::N_STAB)
426 Result |= SymbolRef::SF_FormatSpecific;
428 if (MachOType & MachO::N_EXT) {
429 Result |= SymbolRef::SF_Global;
430 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
432 getSymbolAddress(DRI, Value);
433 if (Value && Value != UnknownAddressOrSize)
434 Result |= SymbolRef::SF_Common;
438 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
439 Result |= SymbolRef::SF_Weak;
441 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
442 Result |= SymbolRef::SF_Absolute;
447 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
448 section_iterator &Res) const {
449 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
450 uint8_t index = Entry.n_sect;
457 Res = section_iterator(SectionRef(DRI, this));
460 return object_error::success;
463 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
467 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
468 StringRef &Result) const {
469 ArrayRef<char> Raw = getSectionRawName(Sec);
470 Result = parseSegmentOrSectionName(Raw.data());
471 return object_error::success;
474 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
475 uint64_t &Res) const {
477 MachO::section_64 Sect = getSection64(Sec);
480 MachO::section Sect = getSection(Sec);
483 return object_error::success;
486 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
487 uint64_t &Res) const {
489 MachO::section_64 Sect = getSection64(Sec);
492 MachO::section Sect = getSection(Sec);
496 return object_error::success;
499 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
500 StringRef &Res) const {
505 MachO::section_64 Sect = getSection64(Sec);
506 Offset = Sect.offset;
509 MachO::section Sect = getSection(Sec);
510 Offset = Sect.offset;
514 Res = this->getData().substr(Offset, Size);
515 return object_error::success;
518 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
519 uint64_t &Res) const {
522 MachO::section_64 Sect = getSection64(Sec);
525 MachO::section Sect = getSection(Sec);
529 Res = uint64_t(1) << Align;
530 return object_error::success;
533 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
535 uint32_t Flags = getSectionFlags(this, Sec);
536 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
537 return object_error::success;
540 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
541 bool &Result) const {
542 uint32_t Flags = getSectionFlags(this, Sec);
543 unsigned SectionType = Flags & MachO::SECTION_TYPE;
544 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
545 !(SectionType == MachO::S_ZEROFILL ||
546 SectionType == MachO::S_GB_ZEROFILL);
547 return object_error::success;
550 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
551 bool &Result) const {
552 uint32_t Flags = getSectionFlags(this, Sec);
553 unsigned SectionType = Flags & MachO::SECTION_TYPE;
554 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
555 (SectionType == MachO::S_ZEROFILL ||
556 SectionType == MachO::S_GB_ZEROFILL);
557 return object_error::success;
561 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
562 bool &Result) const {
563 // FIXME: Unimplemented.
565 return object_error::success;
568 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
569 bool &Result) const {
570 // FIXME: Unimplemented.
572 return object_error::success;
575 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
577 uint32_t Flags = getSectionFlags(this, Sec);
578 unsigned SectionType = Flags & MachO::SECTION_TYPE;
579 Res = SectionType == MachO::S_ZEROFILL ||
580 SectionType == MachO::S_GB_ZEROFILL;
581 return object_error::success;
584 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
585 bool &Result) const {
586 // Consider using the code from isSectionText to look for __const sections.
587 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
588 // to use section attributes to distinguish code from data.
590 // FIXME: Unimplemented.
592 return object_error::success;
595 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
597 bool &Result) const {
599 this->getSymbolType(Symb, ST);
600 if (ST == SymbolRef::ST_Unknown) {
602 return object_error::success;
605 uint64_t SectBegin, SectEnd;
606 getSectionAddress(Sec, SectBegin);
607 getSectionSize(Sec, SectEnd);
608 SectEnd += SectBegin;
611 getSymbolAddress(Symb, SymAddr);
612 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
614 return object_error::success;
617 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
621 return relocation_iterator(RelocationRef(Ret, this));
625 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
628 MachO::section_64 Sect = getSection64(Sec);
631 MachO::section Sect = getSection(Sec);
638 return relocation_iterator(RelocationRef(Ret, this));
641 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
645 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
646 uint64_t &Res) const {
648 getRelocationOffset(Rel, Offset);
653 getSectionAddress(Sec, SecAddress);
654 Res = SecAddress + Offset;
655 return object_error::success;
658 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
659 uint64_t &Res) const {
660 assert(getHeader().filetype == MachO::MH_OBJECT &&
661 "Only implemented for MH_OBJECT");
662 MachO::any_relocation_info RE = getRelocation(Rel);
663 Res = getAnyRelocationAddress(RE);
664 return object_error::success;
668 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
669 MachO::any_relocation_info RE = getRelocation(Rel);
670 if (isRelocationScattered(RE))
673 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
674 bool isExtern = getPlainRelocationExternal(RE);
678 MachO::symtab_command S = getSymtabLoadCommand();
679 unsigned SymbolTableEntrySize = is64Bit() ?
680 sizeof(MachO::nlist_64) :
681 sizeof(MachO::nlist);
682 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
684 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
685 return symbol_iterator(SymbolRef(Sym, this));
688 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
689 uint64_t &Res) const {
690 MachO::any_relocation_info RE = getRelocation(Rel);
691 Res = getAnyRelocationType(RE);
692 return object_error::success;
696 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
697 SmallVectorImpl<char> &Result) const {
700 getRelocationType(Rel, RType);
702 unsigned Arch = this->getArch();
706 static const char *const Table[] = {
707 "GENERIC_RELOC_VANILLA",
708 "GENERIC_RELOC_PAIR",
709 "GENERIC_RELOC_SECTDIFF",
710 "GENERIC_RELOC_PB_LA_PTR",
711 "GENERIC_RELOC_LOCAL_SECTDIFF",
712 "GENERIC_RELOC_TLV" };
720 case Triple::x86_64: {
721 static const char *const Table[] = {
722 "X86_64_RELOC_UNSIGNED",
723 "X86_64_RELOC_SIGNED",
724 "X86_64_RELOC_BRANCH",
725 "X86_64_RELOC_GOT_LOAD",
727 "X86_64_RELOC_SUBTRACTOR",
728 "X86_64_RELOC_SIGNED_1",
729 "X86_64_RELOC_SIGNED_2",
730 "X86_64_RELOC_SIGNED_4",
731 "X86_64_RELOC_TLV" };
740 static const char *const Table[] = {
743 "ARM_RELOC_SECTDIFF",
744 "ARM_RELOC_LOCAL_SECTDIFF",
745 "ARM_RELOC_PB_LA_PTR",
747 "ARM_THUMB_RELOC_BR22",
748 "ARM_THUMB_32BIT_BRANCH",
750 "ARM_RELOC_HALF_SECTDIFF" };
758 case Triple::aarch64: {
759 static const char *const Table[] = {
760 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
761 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
762 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
763 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
764 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
768 if (RType >= array_lengthof(Table))
775 static const char *const Table[] = {
784 "PPC_RELOC_SECTDIFF",
785 "PPC_RELOC_PB_LA_PTR",
786 "PPC_RELOC_HI16_SECTDIFF",
787 "PPC_RELOC_LO16_SECTDIFF",
788 "PPC_RELOC_HA16_SECTDIFF",
790 "PPC_RELOC_LO14_SECTDIFF",
791 "PPC_RELOC_LOCAL_SECTDIFF" };
799 case Triple::UnknownArch:
803 Result.append(res.begin(), res.end());
804 return object_error::success;
808 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
809 SmallVectorImpl<char> &Result) const {
810 MachO::any_relocation_info RE = getRelocation(Rel);
812 unsigned Arch = this->getArch();
815 raw_string_ostream fmt(fmtbuf);
816 unsigned Type = this->getAnyRelocationType(RE);
817 bool IsPCRel = this->getAnyRelocationPCRel(RE);
819 // Determine any addends that should be displayed with the relocation.
820 // These require decoding the relocation type, which is triple-specific.
822 // X86_64 has entirely custom relocation types.
823 if (Arch == Triple::x86_64) {
824 bool isPCRel = getAnyRelocationPCRel(RE);
827 case MachO::X86_64_RELOC_GOT_LOAD:
828 case MachO::X86_64_RELOC_GOT: {
829 printRelocationTargetName(this, RE, fmt);
831 if (isPCRel) fmt << "PCREL";
834 case MachO::X86_64_RELOC_SUBTRACTOR: {
835 DataRefImpl RelNext = Rel;
836 moveRelocationNext(RelNext);
837 MachO::any_relocation_info RENext = getRelocation(RelNext);
839 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
840 // X86_64_RELOC_UNSIGNED.
841 // NOTE: Scattered relocations don't exist on x86_64.
842 unsigned RType = getAnyRelocationType(RENext);
843 if (RType != MachO::X86_64_RELOC_UNSIGNED)
844 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
845 "X86_64_RELOC_SUBTRACTOR.");
847 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
848 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
849 printRelocationTargetName(this, RENext, fmt);
851 printRelocationTargetName(this, RE, fmt);
854 case MachO::X86_64_RELOC_TLV:
855 printRelocationTargetName(this, RE, fmt);
857 if (isPCRel) fmt << "P";
859 case MachO::X86_64_RELOC_SIGNED_1:
860 printRelocationTargetName(this, RE, fmt);
863 case MachO::X86_64_RELOC_SIGNED_2:
864 printRelocationTargetName(this, RE, fmt);
867 case MachO::X86_64_RELOC_SIGNED_4:
868 printRelocationTargetName(this, RE, fmt);
872 printRelocationTargetName(this, RE, fmt);
875 // X86 and ARM share some relocation types in common.
876 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
877 Arch == Triple::ppc) {
878 // Generic relocation types...
880 case MachO::GENERIC_RELOC_PAIR: // prints no info
881 return object_error::success;
882 case MachO::GENERIC_RELOC_SECTDIFF: {
883 DataRefImpl RelNext = Rel;
884 moveRelocationNext(RelNext);
885 MachO::any_relocation_info RENext = getRelocation(RelNext);
887 // X86 sect diff's must be followed by a relocation of type
888 // GENERIC_RELOC_PAIR.
889 unsigned RType = getAnyRelocationType(RENext);
891 if (RType != MachO::GENERIC_RELOC_PAIR)
892 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
893 "GENERIC_RELOC_SECTDIFF.");
895 printRelocationTargetName(this, RE, fmt);
897 printRelocationTargetName(this, RENext, fmt);
902 if (Arch == Triple::x86 || Arch == Triple::ppc) {
904 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
905 DataRefImpl RelNext = Rel;
906 moveRelocationNext(RelNext);
907 MachO::any_relocation_info RENext = getRelocation(RelNext);
909 // X86 sect diff's must be followed by a relocation of type
910 // GENERIC_RELOC_PAIR.
911 unsigned RType = getAnyRelocationType(RENext);
912 if (RType != MachO::GENERIC_RELOC_PAIR)
913 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
914 "GENERIC_RELOC_LOCAL_SECTDIFF.");
916 printRelocationTargetName(this, RE, fmt);
918 printRelocationTargetName(this, RENext, fmt);
921 case MachO::GENERIC_RELOC_TLV: {
922 printRelocationTargetName(this, RE, fmt);
924 if (IsPCRel) fmt << "P";
928 printRelocationTargetName(this, RE, fmt);
930 } else { // ARM-specific relocations
932 case MachO::ARM_RELOC_HALF:
933 case MachO::ARM_RELOC_HALF_SECTDIFF: {
934 // Half relocations steal a bit from the length field to encode
935 // whether this is an upper16 or a lower16 relocation.
936 bool isUpper = getAnyRelocationLength(RE) >> 1;
942 printRelocationTargetName(this, RE, fmt);
944 DataRefImpl RelNext = Rel;
945 moveRelocationNext(RelNext);
946 MachO::any_relocation_info RENext = getRelocation(RelNext);
948 // ARM half relocs must be followed by a relocation of type
950 unsigned RType = getAnyRelocationType(RENext);
951 if (RType != MachO::ARM_RELOC_PAIR)
952 report_fatal_error("Expected ARM_RELOC_PAIR after "
955 // NOTE: The half of the target virtual address is stashed in the
956 // address field of the secondary relocation, but we can't reverse
957 // engineer the constant offset from it without decoding the movw/movt
958 // instruction to find the other half in its immediate field.
960 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
961 // symbol/section pointer of the follow-on relocation.
962 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
964 printRelocationTargetName(this, RENext, fmt);
971 printRelocationTargetName(this, RE, fmt);
976 printRelocationTargetName(this, RE, fmt);
979 Result.append(fmtbuf.begin(), fmtbuf.end());
980 return object_error::success;
983 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
984 bool &Result) const {
985 unsigned Arch = getArch();
987 getRelocationType(Rel, Type);
991 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
993 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
994 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
995 } else if (Arch == Triple::x86_64) {
996 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
997 // an X86_64_RELOC_SUBTRACTOR.
998 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
999 DataRefImpl RelPrev = Rel;
1002 getRelocationType(RelPrev, PrevType);
1003 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1008 return object_error::success;
1011 std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1012 LibraryRef &Res) const {
1013 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1016 std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1017 StringRef &Res) const {
1018 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1022 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1023 // guess on what the short name is. Then name is returned as a substring of the
1024 // StringRef Name passed in. The name of the dynamic library is recognized as
1025 // a framework if it has one of the two following forms:
1026 // Foo.framework/Versions/A/Foo
1027 // Foo.framework/Foo
1028 // Where A and Foo can be any string. And may contain a trailing suffix
1029 // starting with an underbar. If the Name is recognized as a framework then
1030 // isFramework is set to true else it is set to false. If the Name has a
1031 // suffix then Suffix is set to the substring in Name that contains the suffix
1032 // else it is set to a NULL StringRef.
1034 // The Name of the dynamic library is recognized as a library name if it has
1035 // one of the two following forms:
1038 // The library may have a suffix trailing the name Foo of the form:
1039 // libFoo_profile.A.dylib
1040 // libFoo_profile.dylib
1042 // The Name of the dynamic library is also recognized as a library name if it
1043 // has the following form:
1046 // If the Name of the dynamic library is none of the forms above then a NULL
1047 // StringRef is returned.
1049 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1051 StringRef &Suffix) {
1052 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1053 size_t a, b, c, d, Idx;
1055 isFramework = false;
1056 Suffix = StringRef();
1058 // Pull off the last component and make Foo point to it
1059 a = Name.rfind('/');
1060 if (a == Name.npos || a == 0)
1062 Foo = Name.slice(a+1, Name.npos);
1064 // Look for a suffix starting with a '_'
1065 Idx = Foo.rfind('_');
1066 if (Idx != Foo.npos && Foo.size() >= 2) {
1067 Suffix = Foo.slice(Idx, Foo.npos);
1068 Foo = Foo.slice(0, Idx);
1071 // First look for the form Foo.framework/Foo
1072 b = Name.rfind('/', a);
1077 F = Name.slice(Idx, Idx + Foo.size());
1078 DotFramework = Name.slice(Idx + Foo.size(),
1079 Idx + Foo.size() + sizeof(".framework/")-1);
1080 if (F == Foo && DotFramework == ".framework/") {
1085 // Next look for the form Foo.framework/Versions/A/Foo
1088 c = Name.rfind('/', b);
1089 if (c == Name.npos || c == 0)
1091 V = Name.slice(c+1, Name.npos);
1092 if (!V.startswith("Versions/"))
1094 d = Name.rfind('/', c);
1099 F = Name.slice(Idx, Idx + Foo.size());
1100 DotFramework = Name.slice(Idx + Foo.size(),
1101 Idx + Foo.size() + sizeof(".framework/")-1);
1102 if (F == Foo && DotFramework == ".framework/") {
1108 // pull off the suffix after the "." and make a point to it
1109 a = Name.rfind('.');
1110 if (a == Name.npos || a == 0)
1112 Dylib = Name.slice(a, Name.npos);
1113 if (Dylib != ".dylib")
1116 // First pull off the version letter for the form Foo.A.dylib if any.
1118 Dot = Name.slice(a-2, a-1);
1123 b = Name.rfind('/', a);
1128 // ignore any suffix after an underbar like Foo_profile.A.dylib
1129 Idx = Name.find('_', b);
1130 if (Idx != Name.npos && Idx != b) {
1131 Lib = Name.slice(b, Idx);
1132 Suffix = Name.slice(Idx, a);
1135 Lib = Name.slice(b, a);
1136 // There are incorrect library names of the form:
1137 // libATS.A_profile.dylib so check for these.
1138 if (Lib.size() >= 3) {
1139 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1141 Lib = Lib.slice(0, Lib.size()-2);
1146 Qtx = Name.slice(a, Name.npos);
1149 b = Name.rfind('/', a);
1151 Lib = Name.slice(0, a);
1153 Lib = Name.slice(b+1, a);
1154 // There are library names of the form: QT.A.qtx so check for these.
1155 if (Lib.size() >= 3) {
1156 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1158 Lib = Lib.slice(0, Lib.size()-2);
1163 // getLibraryShortNameByIndex() is used to get the short name of the library
1164 // for an undefined symbol in a linked Mach-O binary that was linked with the
1165 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1166 // It is passed the index (0 - based) of the library as translated from
1167 // GET_LIBRARY_ORDINAL (1 - based).
1168 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1170 if (Index >= Libraries.size())
1171 return object_error::parse_failed;
1173 MachO::dylib_command D =
1174 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1175 if (D.dylib.name >= D.cmdsize)
1176 return object_error::parse_failed;
1178 // If the cache of LibrariesShortNames is not built up do that first for
1179 // all the Libraries.
1180 if (LibrariesShortNames.size() == 0) {
1181 for (unsigned i = 0; i < Libraries.size(); i++) {
1182 MachO::dylib_command D =
1183 getStruct<MachO::dylib_command>(this, Libraries[i]);
1184 if (D.dylib.name >= D.cmdsize) {
1185 LibrariesShortNames.push_back(StringRef());
1188 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1189 StringRef Name = StringRef(P);
1192 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1193 if (shortName == StringRef())
1194 LibrariesShortNames.push_back(Name);
1196 LibrariesShortNames.push_back(shortName);
1200 Res = LibrariesShortNames[Index];
1201 return object_error::success;
1204 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1205 return getSymbolByIndex(0);
1208 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1211 return basic_symbol_iterator(SymbolRef(DRI, this));
1213 MachO::symtab_command Symtab = getSymtabLoadCommand();
1214 unsigned SymbolTableEntrySize = is64Bit() ?
1215 sizeof(MachO::nlist_64) :
1216 sizeof(MachO::nlist);
1217 unsigned Offset = Symtab.symoff +
1218 Symtab.nsyms * SymbolTableEntrySize;
1219 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1220 return basic_symbol_iterator(SymbolRef(DRI, this));
1223 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1226 return basic_symbol_iterator(SymbolRef(DRI, this));
1228 MachO::symtab_command Symtab = getSymtabLoadCommand();
1229 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1230 unsigned SymbolTableEntrySize =
1231 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1232 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1233 DRI.p += Index * SymbolTableEntrySize;
1234 return basic_symbol_iterator(SymbolRef(DRI, this));
1237 section_iterator MachOObjectFile::section_begin() const {
1239 return section_iterator(SectionRef(DRI, this));
1242 section_iterator MachOObjectFile::section_end() const {
1244 DRI.d.a = Sections.size();
1245 return section_iterator(SectionRef(DRI, this));
1248 library_iterator MachOObjectFile::needed_library_begin() const {
1250 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1253 library_iterator MachOObjectFile::needed_library_end() const {
1255 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1258 uint8_t MachOObjectFile::getBytesInAddress() const {
1259 return is64Bit() ? 8 : 4;
1262 StringRef MachOObjectFile::getFileFormatName() const {
1263 unsigned CPUType = getCPUType(this);
1266 case llvm::MachO::CPU_TYPE_I386:
1267 return "Mach-O 32-bit i386";
1268 case llvm::MachO::CPU_TYPE_ARM:
1269 return "Mach-O arm";
1270 case llvm::MachO::CPU_TYPE_POWERPC:
1271 return "Mach-O 32-bit ppc";
1273 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1274 "64-bit object file when we're not 64-bit?");
1275 return "Mach-O 32-bit unknown";
1279 // Make sure the cpu type has the correct mask.
1280 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1281 == llvm::MachO::CPU_ARCH_ABI64 &&
1282 "32-bit object file when we're 64-bit?");
1285 case llvm::MachO::CPU_TYPE_X86_64:
1286 return "Mach-O 64-bit x86-64";
1287 case llvm::MachO::CPU_TYPE_ARM64:
1288 return "Mach-O arm64";
1289 case llvm::MachO::CPU_TYPE_POWERPC64:
1290 return "Mach-O 64-bit ppc64";
1292 return "Mach-O 64-bit unknown";
1296 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1298 case llvm::MachO::CPU_TYPE_I386:
1300 case llvm::MachO::CPU_TYPE_X86_64:
1301 return Triple::x86_64;
1302 case llvm::MachO::CPU_TYPE_ARM:
1304 case llvm::MachO::CPU_TYPE_ARM64:
1305 return Triple::aarch64;
1306 case llvm::MachO::CPU_TYPE_POWERPC:
1308 case llvm::MachO::CPU_TYPE_POWERPC64:
1309 return Triple::ppc64;
1311 return Triple::UnknownArch;
1315 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
1317 case MachO::CPU_TYPE_I386:
1318 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1319 case MachO::CPU_SUBTYPE_I386_ALL:
1320 return Triple("i386-apple-darwin");
1324 case MachO::CPU_TYPE_X86_64:
1325 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1326 case MachO::CPU_SUBTYPE_X86_64_ALL:
1327 return Triple("x86_64-apple-darwin");
1328 case MachO::CPU_SUBTYPE_X86_64_H:
1329 return Triple("x86_64h-apple-darwin");
1333 case MachO::CPU_TYPE_ARM:
1334 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1335 case MachO::CPU_SUBTYPE_ARM_V4T:
1336 return Triple("armv4t-apple-darwin");
1337 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1338 return Triple("armv5e-apple-darwin");
1339 case MachO::CPU_SUBTYPE_ARM_V6:
1340 return Triple("armv6-apple-darwin");
1341 case MachO::CPU_SUBTYPE_ARM_V6M:
1342 return Triple("armv6m-apple-darwin");
1343 case MachO::CPU_SUBTYPE_ARM_V7EM:
1344 return Triple("armv7em-apple-darwin");
1345 case MachO::CPU_SUBTYPE_ARM_V7K:
1346 return Triple("armv7k-apple-darwin");
1347 case MachO::CPU_SUBTYPE_ARM_V7M:
1348 return Triple("armv7m-apple-darwin");
1349 case MachO::CPU_SUBTYPE_ARM_V7S:
1350 return Triple("armv7s-apple-darwin");
1354 case MachO::CPU_TYPE_ARM64:
1355 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1356 case MachO::CPU_SUBTYPE_ARM64_ALL:
1357 return Triple("arm64-apple-darwin");
1361 case MachO::CPU_TYPE_POWERPC:
1362 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1363 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1364 return Triple("ppc-apple-darwin");
1368 case MachO::CPU_TYPE_POWERPC64:
1369 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1370 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1371 return Triple("ppc64-apple-darwin");
1380 Triple MachOObjectFile::getHostArch() {
1381 return Triple(sys::getDefaultTargetTriple());
1384 Triple MachOObjectFile::getArch(StringRef ArchFlag) {
1385 if (ArchFlag == "i386")
1386 return Triple("i386-apple-darwin");
1387 else if (ArchFlag == "x86_64")
1388 return Triple("x86_64-apple-darwin");
1389 else if (ArchFlag == "x86_64h")
1390 return Triple("x86_64h-apple-darwin");
1391 else if (ArchFlag == "armv4t" || ArchFlag == "arm")
1392 return Triple("armv4t-apple-darwin");
1393 else if (ArchFlag == "armv5e")
1394 return Triple("armv5e-apple-darwin");
1395 else if (ArchFlag == "armv6")
1396 return Triple("armv6-apple-darwin");
1397 else if (ArchFlag == "armv6m")
1398 return Triple("armv6m-apple-darwin");
1399 else if (ArchFlag == "armv7em")
1400 return Triple("armv7em-apple-darwin");
1401 else if (ArchFlag == "armv7k")
1402 return Triple("armv7k-apple-darwin");
1403 else if (ArchFlag == "armv7k")
1404 return Triple("armv7m-apple-darwin");
1405 else if (ArchFlag == "armv7s")
1406 return Triple("armv7s-apple-darwin");
1407 else if (ArchFlag == "arm64")
1408 return Triple("arm64-apple-darwin");
1409 else if (ArchFlag == "ppc")
1410 return Triple("ppc-apple-darwin");
1411 else if (ArchFlag == "ppc64")
1412 return Triple("ppc64-apple-darwin");
1417 unsigned MachOObjectFile::getArch() const {
1418 return getArch(getCPUType(this));
1421 StringRef MachOObjectFile::getLoadName() const {
1423 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1426 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1429 return section_rel_begin(DRI);
1432 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1435 return section_rel_end(DRI);
1438 dice_iterator MachOObjectFile::begin_dices() const {
1440 if (!DataInCodeLoadCmd)
1441 return dice_iterator(DiceRef(DRI, this));
1443 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1444 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1445 return dice_iterator(DiceRef(DRI, this));
1448 dice_iterator MachOObjectFile::end_dices() const {
1450 if (!DataInCodeLoadCmd)
1451 return dice_iterator(DiceRef(DRI, this));
1453 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1454 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1455 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1456 return dice_iterator(DiceRef(DRI, this));
1460 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1461 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1462 return parseSegmentOrSectionName(Raw.data());
1466 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1467 const section_base *Base =
1468 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1469 return ArrayRef<char>(Base->sectname);
1473 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1474 const section_base *Base =
1475 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1476 return ArrayRef<char>(Base->segname);
1480 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1482 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1484 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1487 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1488 const MachO::any_relocation_info &RE) const {
1489 if (isLittleEndian())
1490 return RE.r_word1 & 0xffffff;
1491 return RE.r_word1 >> 8;
1494 bool MachOObjectFile::getPlainRelocationExternal(
1495 const MachO::any_relocation_info &RE) const {
1496 if (isLittleEndian())
1497 return (RE.r_word1 >> 27) & 1;
1498 return (RE.r_word1 >> 4) & 1;
1501 bool MachOObjectFile::getScatteredRelocationScattered(
1502 const MachO::any_relocation_info &RE) const {
1503 return RE.r_word0 >> 31;
1506 uint32_t MachOObjectFile::getScatteredRelocationValue(
1507 const MachO::any_relocation_info &RE) const {
1511 unsigned MachOObjectFile::getAnyRelocationAddress(
1512 const MachO::any_relocation_info &RE) const {
1513 if (isRelocationScattered(RE))
1514 return getScatteredRelocationAddress(RE);
1515 return getPlainRelocationAddress(RE);
1518 unsigned MachOObjectFile::getAnyRelocationPCRel(
1519 const MachO::any_relocation_info &RE) const {
1520 if (isRelocationScattered(RE))
1521 return getScatteredRelocationPCRel(this, RE);
1522 return getPlainRelocationPCRel(this, RE);
1525 unsigned MachOObjectFile::getAnyRelocationLength(
1526 const MachO::any_relocation_info &RE) const {
1527 if (isRelocationScattered(RE))
1528 return getScatteredRelocationLength(RE);
1529 return getPlainRelocationLength(this, RE);
1533 MachOObjectFile::getAnyRelocationType(
1534 const MachO::any_relocation_info &RE) const {
1535 if (isRelocationScattered(RE))
1536 return getScatteredRelocationType(RE);
1537 return getPlainRelocationType(this, RE);
1541 MachOObjectFile::getRelocationSection(
1542 const MachO::any_relocation_info &RE) const {
1543 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1544 return *section_end();
1545 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1548 return SectionRef(DRI, this);
1551 MachOObjectFile::LoadCommandInfo
1552 MachOObjectFile::getFirstLoadCommandInfo() const {
1553 MachOObjectFile::LoadCommandInfo Load;
1555 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1556 sizeof(MachO::mach_header);
1557 Load.Ptr = getPtr(this, HeaderSize);
1558 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1562 MachOObjectFile::LoadCommandInfo
1563 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1564 MachOObjectFile::LoadCommandInfo Next;
1565 Next.Ptr = L.Ptr + L.C.cmdsize;
1566 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1570 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1571 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1574 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1575 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1578 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1579 unsigned Index) const {
1580 const char *Sec = getSectionPtr(this, L, Index);
1581 return getStruct<MachO::section>(this, Sec);
1584 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1585 unsigned Index) const {
1586 const char *Sec = getSectionPtr(this, L, Index);
1587 return getStruct<MachO::section_64>(this, Sec);
1591 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1592 const char *P = reinterpret_cast<const char *>(DRI.p);
1593 return getStruct<MachO::nlist>(this, P);
1597 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1598 const char *P = reinterpret_cast<const char *>(DRI.p);
1599 return getStruct<MachO::nlist_64>(this, P);
1602 MachO::linkedit_data_command
1603 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1604 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1607 MachO::segment_command
1608 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1609 return getStruct<MachO::segment_command>(this, L.Ptr);
1612 MachO::segment_command_64
1613 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1614 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1617 MachO::linker_options_command
1618 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1619 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1622 MachO::version_min_command
1623 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1624 return getStruct<MachO::version_min_command>(this, L.Ptr);
1627 MachO::dylib_command
1628 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1629 return getStruct<MachO::dylib_command>(this, L.Ptr);
1633 MachO::any_relocation_info
1634 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1639 MachO::section_64 Sect = getSection64(Sec);
1640 Offset = Sect.reloff;
1642 MachO::section Sect = getSection(Sec);
1643 Offset = Sect.reloff;
1646 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1647 getPtr(this, Offset)) + Rel.d.b;
1648 return getStruct<MachO::any_relocation_info>(
1649 this, reinterpret_cast<const char *>(P));
1652 MachO::data_in_code_entry
1653 MachOObjectFile::getDice(DataRefImpl Rel) const {
1654 const char *P = reinterpret_cast<const char *>(Rel.p);
1655 return getStruct<MachO::data_in_code_entry>(this, P);
1658 MachO::mach_header MachOObjectFile::getHeader() const {
1659 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1662 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1663 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1666 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1667 const MachO::dysymtab_command &DLC,
1668 unsigned Index) const {
1669 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1670 return getStruct<uint32_t>(this, getPtr(this, Offset));
1673 MachO::data_in_code_entry
1674 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1675 unsigned Index) const {
1676 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1677 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1680 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1681 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1684 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1685 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1688 MachO::linkedit_data_command
1689 MachOObjectFile::getDataInCodeLoadCommand() const {
1690 if (DataInCodeLoadCmd)
1691 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1693 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1694 MachO::linkedit_data_command Cmd;
1695 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1696 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1702 StringRef MachOObjectFile::getStringTableData() const {
1703 MachO::symtab_command S = getSymtabLoadCommand();
1704 return getData().substr(S.stroff, S.strsize);
1707 bool MachOObjectFile::is64Bit() const {
1708 return getType() == getMachOType(false, true) ||
1709 getType() == getMachOType(true, true);
1712 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1713 SmallVectorImpl<uint64_t> &Out) const {
1714 DataExtractor extractor(ObjectFile::getData(), true, 0);
1716 uint32_t offset = Index;
1718 while (uint64_t delta = extractor.getULEB128(&offset)) {
1720 Out.push_back(data);
1724 ErrorOr<ObjectFile *>
1725 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1726 StringRef Magic = Buffer->getBuffer().slice(0, 4);
1728 std::unique_ptr<MachOObjectFile> Ret;
1729 if (Magic == "\xFE\xED\xFA\xCE")
1730 Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1731 else if (Magic == "\xCE\xFA\xED\xFE")
1732 Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1733 else if (Magic == "\xFE\xED\xFA\xCF")
1734 Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1735 else if (Magic == "\xCF\xFA\xED\xFE")
1736 Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1738 return object_error::parse_failed;
1742 return Ret.release();