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" };
759 case Triple::aarch64: {
760 static const char *const Table[] = {
761 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
762 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
763 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
764 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
765 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
769 if (RType >= array_lengthof(Table))
776 static const char *const Table[] = {
785 "PPC_RELOC_SECTDIFF",
786 "PPC_RELOC_PB_LA_PTR",
787 "PPC_RELOC_HI16_SECTDIFF",
788 "PPC_RELOC_LO16_SECTDIFF",
789 "PPC_RELOC_HA16_SECTDIFF",
791 "PPC_RELOC_LO14_SECTDIFF",
792 "PPC_RELOC_LOCAL_SECTDIFF" };
800 case Triple::UnknownArch:
804 Result.append(res.begin(), res.end());
805 return object_error::success;
809 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
810 SmallVectorImpl<char> &Result) const {
811 MachO::any_relocation_info RE = getRelocation(Rel);
813 unsigned Arch = this->getArch();
816 raw_string_ostream fmt(fmtbuf);
817 unsigned Type = this->getAnyRelocationType(RE);
818 bool IsPCRel = this->getAnyRelocationPCRel(RE);
820 // Determine any addends that should be displayed with the relocation.
821 // These require decoding the relocation type, which is triple-specific.
823 // X86_64 has entirely custom relocation types.
824 if (Arch == Triple::x86_64) {
825 bool isPCRel = getAnyRelocationPCRel(RE);
828 case MachO::X86_64_RELOC_GOT_LOAD:
829 case MachO::X86_64_RELOC_GOT: {
830 printRelocationTargetName(this, RE, fmt);
832 if (isPCRel) fmt << "PCREL";
835 case MachO::X86_64_RELOC_SUBTRACTOR: {
836 DataRefImpl RelNext = Rel;
837 moveRelocationNext(RelNext);
838 MachO::any_relocation_info RENext = getRelocation(RelNext);
840 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
841 // X86_64_RELOC_UNSIGNED.
842 // NOTE: Scattered relocations don't exist on x86_64.
843 unsigned RType = getAnyRelocationType(RENext);
844 if (RType != MachO::X86_64_RELOC_UNSIGNED)
845 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
846 "X86_64_RELOC_SUBTRACTOR.");
848 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
849 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
850 printRelocationTargetName(this, RENext, fmt);
852 printRelocationTargetName(this, RE, fmt);
855 case MachO::X86_64_RELOC_TLV:
856 printRelocationTargetName(this, RE, fmt);
858 if (isPCRel) fmt << "P";
860 case MachO::X86_64_RELOC_SIGNED_1:
861 printRelocationTargetName(this, RE, fmt);
864 case MachO::X86_64_RELOC_SIGNED_2:
865 printRelocationTargetName(this, RE, fmt);
868 case MachO::X86_64_RELOC_SIGNED_4:
869 printRelocationTargetName(this, RE, fmt);
873 printRelocationTargetName(this, RE, fmt);
876 // X86 and ARM share some relocation types in common.
877 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
878 Arch == Triple::ppc) {
879 // Generic relocation types...
881 case MachO::GENERIC_RELOC_PAIR: // prints no info
882 return object_error::success;
883 case MachO::GENERIC_RELOC_SECTDIFF: {
884 DataRefImpl RelNext = Rel;
885 moveRelocationNext(RelNext);
886 MachO::any_relocation_info RENext = getRelocation(RelNext);
888 // X86 sect diff's must be followed by a relocation of type
889 // GENERIC_RELOC_PAIR.
890 unsigned RType = getAnyRelocationType(RENext);
892 if (RType != MachO::GENERIC_RELOC_PAIR)
893 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
894 "GENERIC_RELOC_SECTDIFF.");
896 printRelocationTargetName(this, RE, fmt);
898 printRelocationTargetName(this, RENext, fmt);
903 if (Arch == Triple::x86 || Arch == Triple::ppc) {
905 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
906 DataRefImpl RelNext = Rel;
907 moveRelocationNext(RelNext);
908 MachO::any_relocation_info RENext = getRelocation(RelNext);
910 // X86 sect diff's must be followed by a relocation of type
911 // GENERIC_RELOC_PAIR.
912 unsigned RType = getAnyRelocationType(RENext);
913 if (RType != MachO::GENERIC_RELOC_PAIR)
914 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
915 "GENERIC_RELOC_LOCAL_SECTDIFF.");
917 printRelocationTargetName(this, RE, fmt);
919 printRelocationTargetName(this, RENext, fmt);
922 case MachO::GENERIC_RELOC_TLV: {
923 printRelocationTargetName(this, RE, fmt);
925 if (IsPCRel) fmt << "P";
929 printRelocationTargetName(this, RE, fmt);
931 } else { // ARM-specific relocations
933 case MachO::ARM_RELOC_HALF:
934 case MachO::ARM_RELOC_HALF_SECTDIFF: {
935 // Half relocations steal a bit from the length field to encode
936 // whether this is an upper16 or a lower16 relocation.
937 bool isUpper = getAnyRelocationLength(RE) >> 1;
943 printRelocationTargetName(this, RE, fmt);
945 DataRefImpl RelNext = Rel;
946 moveRelocationNext(RelNext);
947 MachO::any_relocation_info RENext = getRelocation(RelNext);
949 // ARM half relocs must be followed by a relocation of type
951 unsigned RType = getAnyRelocationType(RENext);
952 if (RType != MachO::ARM_RELOC_PAIR)
953 report_fatal_error("Expected ARM_RELOC_PAIR after "
956 // NOTE: The half of the target virtual address is stashed in the
957 // address field of the secondary relocation, but we can't reverse
958 // engineer the constant offset from it without decoding the movw/movt
959 // instruction to find the other half in its immediate field.
961 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
962 // symbol/section pointer of the follow-on relocation.
963 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
965 printRelocationTargetName(this, RENext, fmt);
972 printRelocationTargetName(this, RE, fmt);
977 printRelocationTargetName(this, RE, fmt);
980 Result.append(fmtbuf.begin(), fmtbuf.end());
981 return object_error::success;
984 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
985 bool &Result) const {
986 unsigned Arch = getArch();
988 getRelocationType(Rel, Type);
992 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
994 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
995 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
996 } else if (Arch == Triple::x86_64) {
997 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
998 // an X86_64_RELOC_SUBTRACTOR.
999 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1000 DataRefImpl RelPrev = Rel;
1003 getRelocationType(RelPrev, PrevType);
1004 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1009 return object_error::success;
1012 std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1013 LibraryRef &Res) const {
1014 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1017 std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1018 StringRef &Res) const {
1019 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1023 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1024 // guess on what the short name is. Then name is returned as a substring of the
1025 // StringRef Name passed in. The name of the dynamic library is recognized as
1026 // a framework if it has one of the two following forms:
1027 // Foo.framework/Versions/A/Foo
1028 // Foo.framework/Foo
1029 // Where A and Foo can be any string. And may contain a trailing suffix
1030 // starting with an underbar. If the Name is recognized as a framework then
1031 // isFramework is set to true else it is set to false. If the Name has a
1032 // suffix then Suffix is set to the substring in Name that contains the suffix
1033 // else it is set to a NULL StringRef.
1035 // The Name of the dynamic library is recognized as a library name if it has
1036 // one of the two following forms:
1039 // The library may have a suffix trailing the name Foo of the form:
1040 // libFoo_profile.A.dylib
1041 // libFoo_profile.dylib
1043 // The Name of the dynamic library is also recognized as a library name if it
1044 // has the following form:
1047 // If the Name of the dynamic library is none of the forms above then a NULL
1048 // StringRef is returned.
1050 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1052 StringRef &Suffix) {
1053 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1054 size_t a, b, c, d, Idx;
1056 isFramework = false;
1057 Suffix = StringRef();
1059 // Pull off the last component and make Foo point to it
1060 a = Name.rfind('/');
1061 if (a == Name.npos || a == 0)
1063 Foo = Name.slice(a+1, Name.npos);
1065 // Look for a suffix starting with a '_'
1066 Idx = Foo.rfind('_');
1067 if (Idx != Foo.npos && Foo.size() >= 2) {
1068 Suffix = Foo.slice(Idx, Foo.npos);
1069 Foo = Foo.slice(0, Idx);
1072 // First look for the form Foo.framework/Foo
1073 b = Name.rfind('/', a);
1078 F = Name.slice(Idx, Idx + Foo.size());
1079 DotFramework = Name.slice(Idx + Foo.size(),
1080 Idx + Foo.size() + sizeof(".framework/")-1);
1081 if (F == Foo && DotFramework == ".framework/") {
1086 // Next look for the form Foo.framework/Versions/A/Foo
1089 c = Name.rfind('/', b);
1090 if (c == Name.npos || c == 0)
1092 V = Name.slice(c+1, Name.npos);
1093 if (!V.startswith("Versions/"))
1095 d = Name.rfind('/', c);
1100 F = Name.slice(Idx, Idx + Foo.size());
1101 DotFramework = Name.slice(Idx + Foo.size(),
1102 Idx + Foo.size() + sizeof(".framework/")-1);
1103 if (F == Foo && DotFramework == ".framework/") {
1109 // pull off the suffix after the "." and make a point to it
1110 a = Name.rfind('.');
1111 if (a == Name.npos || a == 0)
1113 Dylib = Name.slice(a, Name.npos);
1114 if (Dylib != ".dylib")
1117 // First pull off the version letter for the form Foo.A.dylib if any.
1119 Dot = Name.slice(a-2, a-1);
1124 b = Name.rfind('/', a);
1129 // ignore any suffix after an underbar like Foo_profile.A.dylib
1130 Idx = Name.find('_', b);
1131 if (Idx != Name.npos && Idx != b) {
1132 Lib = Name.slice(b, Idx);
1133 Suffix = Name.slice(Idx, a);
1136 Lib = Name.slice(b, a);
1137 // There are incorrect library names of the form:
1138 // libATS.A_profile.dylib so check for these.
1139 if (Lib.size() >= 3) {
1140 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1142 Lib = Lib.slice(0, Lib.size()-2);
1147 Qtx = Name.slice(a, Name.npos);
1150 b = Name.rfind('/', a);
1152 Lib = Name.slice(0, a);
1154 Lib = Name.slice(b+1, a);
1155 // There are library names of the form: QT.A.qtx so check for these.
1156 if (Lib.size() >= 3) {
1157 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1159 Lib = Lib.slice(0, Lib.size()-2);
1164 // getLibraryShortNameByIndex() is used to get the short name of the library
1165 // for an undefined symbol in a linked Mach-O binary that was linked with the
1166 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1167 // It is passed the index (0 - based) of the library as translated from
1168 // GET_LIBRARY_ORDINAL (1 - based).
1169 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1171 if (Index >= Libraries.size())
1172 return object_error::parse_failed;
1174 MachO::dylib_command D =
1175 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1176 if (D.dylib.name >= D.cmdsize)
1177 return object_error::parse_failed;
1179 // If the cache of LibrariesShortNames is not built up do that first for
1180 // all the Libraries.
1181 if (LibrariesShortNames.size() == 0) {
1182 for (unsigned i = 0; i < Libraries.size(); i++) {
1183 MachO::dylib_command D =
1184 getStruct<MachO::dylib_command>(this, Libraries[i]);
1185 if (D.dylib.name >= D.cmdsize) {
1186 LibrariesShortNames.push_back(StringRef());
1189 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1190 StringRef Name = StringRef(P);
1193 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1194 if (shortName == StringRef())
1195 LibrariesShortNames.push_back(Name);
1197 LibrariesShortNames.push_back(shortName);
1201 Res = LibrariesShortNames[Index];
1202 return object_error::success;
1205 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1206 return getSymbolByIndex(0);
1209 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1212 return basic_symbol_iterator(SymbolRef(DRI, this));
1214 MachO::symtab_command Symtab = getSymtabLoadCommand();
1215 unsigned SymbolTableEntrySize = is64Bit() ?
1216 sizeof(MachO::nlist_64) :
1217 sizeof(MachO::nlist);
1218 unsigned Offset = Symtab.symoff +
1219 Symtab.nsyms * SymbolTableEntrySize;
1220 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1221 return basic_symbol_iterator(SymbolRef(DRI, this));
1224 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1227 return basic_symbol_iterator(SymbolRef(DRI, this));
1229 MachO::symtab_command Symtab = getSymtabLoadCommand();
1230 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1231 unsigned SymbolTableEntrySize =
1232 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1233 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1234 DRI.p += Index * SymbolTableEntrySize;
1235 return basic_symbol_iterator(SymbolRef(DRI, this));
1238 section_iterator MachOObjectFile::section_begin() const {
1240 return section_iterator(SectionRef(DRI, this));
1243 section_iterator MachOObjectFile::section_end() const {
1245 DRI.d.a = Sections.size();
1246 return section_iterator(SectionRef(DRI, this));
1249 library_iterator MachOObjectFile::needed_library_begin() const {
1251 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1254 library_iterator MachOObjectFile::needed_library_end() const {
1256 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1259 uint8_t MachOObjectFile::getBytesInAddress() const {
1260 return is64Bit() ? 8 : 4;
1263 StringRef MachOObjectFile::getFileFormatName() const {
1264 unsigned CPUType = getCPUType(this);
1267 case llvm::MachO::CPU_TYPE_I386:
1268 return "Mach-O 32-bit i386";
1269 case llvm::MachO::CPU_TYPE_ARM:
1270 return "Mach-O arm";
1271 case llvm::MachO::CPU_TYPE_POWERPC:
1272 return "Mach-O 32-bit ppc";
1274 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1275 "64-bit object file when we're not 64-bit?");
1276 return "Mach-O 32-bit unknown";
1280 // Make sure the cpu type has the correct mask.
1281 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1282 == llvm::MachO::CPU_ARCH_ABI64 &&
1283 "32-bit object file when we're 64-bit?");
1286 case llvm::MachO::CPU_TYPE_X86_64:
1287 return "Mach-O 64-bit x86-64";
1288 case llvm::MachO::CPU_TYPE_ARM64:
1289 return "Mach-O arm64";
1290 case llvm::MachO::CPU_TYPE_POWERPC64:
1291 return "Mach-O 64-bit ppc64";
1293 return "Mach-O 64-bit unknown";
1297 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1299 case llvm::MachO::CPU_TYPE_I386:
1301 case llvm::MachO::CPU_TYPE_X86_64:
1302 return Triple::x86_64;
1303 case llvm::MachO::CPU_TYPE_ARM:
1305 case llvm::MachO::CPU_TYPE_ARM64:
1306 return Triple::arm64;
1307 case llvm::MachO::CPU_TYPE_POWERPC:
1309 case llvm::MachO::CPU_TYPE_POWERPC64:
1310 return Triple::ppc64;
1312 return Triple::UnknownArch;
1316 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
1318 case MachO::CPU_TYPE_I386:
1319 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1320 case MachO::CPU_SUBTYPE_I386_ALL:
1321 return Triple("i386-apple-darwin");
1325 case MachO::CPU_TYPE_X86_64:
1326 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1327 case MachO::CPU_SUBTYPE_X86_64_ALL:
1328 return Triple("x86_64-apple-darwin");
1329 case MachO::CPU_SUBTYPE_X86_64_H:
1330 return Triple("x86_64h-apple-darwin");
1334 case MachO::CPU_TYPE_ARM:
1335 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1336 case MachO::CPU_SUBTYPE_ARM_V4T:
1337 return Triple("armv4t-apple-darwin");
1338 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1339 return Triple("armv5e-apple-darwin");
1340 case MachO::CPU_SUBTYPE_ARM_V6:
1341 return Triple("armv6-apple-darwin");
1342 case MachO::CPU_SUBTYPE_ARM_V6M:
1343 return Triple("armv6m-apple-darwin");
1344 case MachO::CPU_SUBTYPE_ARM_V7EM:
1345 return Triple("armv7em-apple-darwin");
1346 case MachO::CPU_SUBTYPE_ARM_V7K:
1347 return Triple("armv7k-apple-darwin");
1348 case MachO::CPU_SUBTYPE_ARM_V7M:
1349 return Triple("armv7m-apple-darwin");
1350 case MachO::CPU_SUBTYPE_ARM_V7S:
1351 return Triple("armv7s-apple-darwin");
1355 case MachO::CPU_TYPE_ARM64:
1356 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1357 case MachO::CPU_SUBTYPE_ARM64_ALL:
1358 return Triple("arm64-apple-darwin");
1362 case MachO::CPU_TYPE_POWERPC:
1363 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1364 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1365 return Triple("ppc-apple-darwin");
1369 case MachO::CPU_TYPE_POWERPC64:
1370 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1371 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1372 return Triple("ppc64-apple-darwin");
1381 Triple MachOObjectFile::getHostArch() {
1382 return Triple(sys::getDefaultTargetTriple());
1385 Triple MachOObjectFile::getArch(StringRef ArchFlag) {
1386 if (ArchFlag == "i386")
1387 return Triple("i386-apple-darwin");
1388 else if (ArchFlag == "x86_64")
1389 return Triple("x86_64-apple-darwin");
1390 else if (ArchFlag == "x86_64h")
1391 return Triple("x86_64h-apple-darwin");
1392 else if (ArchFlag == "armv4t" || ArchFlag == "arm")
1393 return Triple("armv4t-apple-darwin");
1394 else if (ArchFlag == "armv5e")
1395 return Triple("armv5e-apple-darwin");
1396 else if (ArchFlag == "armv6")
1397 return Triple("armv6-apple-darwin");
1398 else if (ArchFlag == "armv6m")
1399 return Triple("armv6m-apple-darwin");
1400 else if (ArchFlag == "armv7em")
1401 return Triple("armv7em-apple-darwin");
1402 else if (ArchFlag == "armv7k")
1403 return Triple("armv7k-apple-darwin");
1404 else if (ArchFlag == "armv7k")
1405 return Triple("armv7m-apple-darwin");
1406 else if (ArchFlag == "armv7s")
1407 return Triple("armv7s-apple-darwin");
1408 else if (ArchFlag == "arm64")
1409 return Triple("arm64-apple-darwin");
1410 else if (ArchFlag == "ppc")
1411 return Triple("ppc-apple-darwin");
1412 else if (ArchFlag == "ppc64")
1413 return Triple("ppc64-apple-darwin");
1418 unsigned MachOObjectFile::getArch() const {
1419 return getArch(getCPUType(this));
1422 StringRef MachOObjectFile::getLoadName() const {
1424 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1427 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1430 return section_rel_begin(DRI);
1433 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1436 return section_rel_end(DRI);
1439 dice_iterator MachOObjectFile::begin_dices() const {
1441 if (!DataInCodeLoadCmd)
1442 return dice_iterator(DiceRef(DRI, this));
1444 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1445 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1446 return dice_iterator(DiceRef(DRI, this));
1449 dice_iterator MachOObjectFile::end_dices() const {
1451 if (!DataInCodeLoadCmd)
1452 return dice_iterator(DiceRef(DRI, this));
1454 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1455 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1456 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1457 return dice_iterator(DiceRef(DRI, this));
1461 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1462 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1463 return parseSegmentOrSectionName(Raw.data());
1467 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1468 const section_base *Base =
1469 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1470 return ArrayRef<char>(Base->sectname);
1474 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1475 const section_base *Base =
1476 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1477 return ArrayRef<char>(Base->segname);
1481 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1483 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1485 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1488 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1489 const MachO::any_relocation_info &RE) const {
1490 if (isLittleEndian())
1491 return RE.r_word1 & 0xffffff;
1492 return RE.r_word1 >> 8;
1495 bool MachOObjectFile::getPlainRelocationExternal(
1496 const MachO::any_relocation_info &RE) const {
1497 if (isLittleEndian())
1498 return (RE.r_word1 >> 27) & 1;
1499 return (RE.r_word1 >> 4) & 1;
1502 bool MachOObjectFile::getScatteredRelocationScattered(
1503 const MachO::any_relocation_info &RE) const {
1504 return RE.r_word0 >> 31;
1507 uint32_t MachOObjectFile::getScatteredRelocationValue(
1508 const MachO::any_relocation_info &RE) const {
1512 unsigned MachOObjectFile::getAnyRelocationAddress(
1513 const MachO::any_relocation_info &RE) const {
1514 if (isRelocationScattered(RE))
1515 return getScatteredRelocationAddress(RE);
1516 return getPlainRelocationAddress(RE);
1519 unsigned MachOObjectFile::getAnyRelocationPCRel(
1520 const MachO::any_relocation_info &RE) const {
1521 if (isRelocationScattered(RE))
1522 return getScatteredRelocationPCRel(this, RE);
1523 return getPlainRelocationPCRel(this, RE);
1526 unsigned MachOObjectFile::getAnyRelocationLength(
1527 const MachO::any_relocation_info &RE) const {
1528 if (isRelocationScattered(RE))
1529 return getScatteredRelocationLength(RE);
1530 return getPlainRelocationLength(this, RE);
1534 MachOObjectFile::getAnyRelocationType(
1535 const MachO::any_relocation_info &RE) const {
1536 if (isRelocationScattered(RE))
1537 return getScatteredRelocationType(RE);
1538 return getPlainRelocationType(this, RE);
1542 MachOObjectFile::getRelocationSection(
1543 const MachO::any_relocation_info &RE) const {
1544 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1545 return *section_end();
1546 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1549 return SectionRef(DRI, this);
1552 MachOObjectFile::LoadCommandInfo
1553 MachOObjectFile::getFirstLoadCommandInfo() const {
1554 MachOObjectFile::LoadCommandInfo Load;
1556 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1557 sizeof(MachO::mach_header);
1558 Load.Ptr = getPtr(this, HeaderSize);
1559 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1563 MachOObjectFile::LoadCommandInfo
1564 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1565 MachOObjectFile::LoadCommandInfo Next;
1566 Next.Ptr = L.Ptr + L.C.cmdsize;
1567 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1571 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1572 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1575 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1576 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1579 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1580 unsigned Index) const {
1581 const char *Sec = getSectionPtr(this, L, Index);
1582 return getStruct<MachO::section>(this, Sec);
1585 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1586 unsigned Index) const {
1587 const char *Sec = getSectionPtr(this, L, Index);
1588 return getStruct<MachO::section_64>(this, Sec);
1592 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1593 const char *P = reinterpret_cast<const char *>(DRI.p);
1594 return getStruct<MachO::nlist>(this, P);
1598 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1599 const char *P = reinterpret_cast<const char *>(DRI.p);
1600 return getStruct<MachO::nlist_64>(this, P);
1603 MachO::linkedit_data_command
1604 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1605 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1608 MachO::segment_command
1609 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1610 return getStruct<MachO::segment_command>(this, L.Ptr);
1613 MachO::segment_command_64
1614 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1615 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1618 MachO::linker_options_command
1619 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1620 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1623 MachO::version_min_command
1624 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1625 return getStruct<MachO::version_min_command>(this, L.Ptr);
1628 MachO::dylib_command
1629 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1630 return getStruct<MachO::dylib_command>(this, L.Ptr);
1634 MachO::any_relocation_info
1635 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1640 MachO::section_64 Sect = getSection64(Sec);
1641 Offset = Sect.reloff;
1643 MachO::section Sect = getSection(Sec);
1644 Offset = Sect.reloff;
1647 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1648 getPtr(this, Offset)) + Rel.d.b;
1649 return getStruct<MachO::any_relocation_info>(
1650 this, reinterpret_cast<const char *>(P));
1653 MachO::data_in_code_entry
1654 MachOObjectFile::getDice(DataRefImpl Rel) const {
1655 const char *P = reinterpret_cast<const char *>(Rel.p);
1656 return getStruct<MachO::data_in_code_entry>(this, P);
1659 MachO::mach_header MachOObjectFile::getHeader() const {
1660 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1663 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1664 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1667 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1668 const MachO::dysymtab_command &DLC,
1669 unsigned Index) const {
1670 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1671 return getStruct<uint32_t>(this, getPtr(this, Offset));
1674 MachO::data_in_code_entry
1675 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1676 unsigned Index) const {
1677 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1678 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1681 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1682 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1685 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1686 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1689 MachO::linkedit_data_command
1690 MachOObjectFile::getDataInCodeLoadCommand() const {
1691 if (DataInCodeLoadCmd)
1692 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1694 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1695 MachO::linkedit_data_command Cmd;
1696 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1697 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1703 StringRef MachOObjectFile::getStringTableData() const {
1704 MachO::symtab_command S = getSymtabLoadCommand();
1705 return getData().substr(S.stroff, S.strsize);
1708 bool MachOObjectFile::is64Bit() const {
1709 return getType() == getMachOType(false, true) ||
1710 getType() == getMachOType(true, true);
1713 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1714 SmallVectorImpl<uint64_t> &Out) const {
1715 DataExtractor extractor(ObjectFile::getData(), true, 0);
1717 uint32_t offset = Index;
1719 while (uint64_t delta = extractor.getULEB128(&offset)) {
1721 Out.push_back(data);
1725 ErrorOr<ObjectFile *>
1726 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1727 StringRef Magic = Buffer->getBuffer().slice(0, 4);
1729 std::unique_ptr<MachOObjectFile> Ret;
1730 if (Magic == "\xFE\xED\xFA\xCE")
1731 Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1732 else if (Magic == "\xCE\xFA\xED\xFE")
1733 Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1734 else if (Magic == "\xFE\xED\xFA\xCF")
1735 Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1736 else if (Magic == "\xCF\xFA\xED\xFE")
1737 Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1739 return object_error::parse_failed;
1743 return Ret.release();