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;
40 T getStruct(const MachOObjectFile *O, const char *P) {
42 memcpy(&Cmd, P, sizeof(T));
43 if (O->isLittleEndian() != sys::IsLittleEndianHost)
44 MachO::swapStruct(Cmd);
49 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
50 const MachOObjectFile::LoadCommandInfo &L) {
52 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
55 MachO::segment_command S = O->getSegmentLoadCommand(L);
60 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
62 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
64 bool Is64 = O->is64Bit();
65 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
66 sizeof(MachO::segment_command);
67 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
68 sizeof(MachO::section);
70 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
71 return reinterpret_cast<const char*>(SectionAddr);
74 static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
75 return O->getData().substr(Offset, 1).data();
78 static MachO::nlist_base
79 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
80 const char *P = reinterpret_cast<const char *>(DRI.p);
81 return getStruct<MachO::nlist_base>(O, P);
84 static StringRef parseSegmentOrSectionName(const char *P) {
88 // Not null terminated, so this is a 16 char string.
89 return StringRef(P, 16);
92 // Helper to advance a section or symbol iterator multiple increments at a time.
94 static void advance(T &it, size_t Val) {
99 static unsigned getCPUType(const MachOObjectFile *O) {
100 return O->getHeader().cputype;
103 static void printRelocationTargetName(const MachOObjectFile *O,
104 const MachO::any_relocation_info &RE,
105 raw_string_ostream &fmt) {
106 bool IsScattered = O->isRelocationScattered(RE);
108 // Target of a scattered relocation is an address. In the interest of
109 // generating pretty output, scan through the symbol table looking for a
110 // symbol that aligns with that address. If we find one, print it.
111 // Otherwise, we just print the hex address of the target.
113 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
115 for (const SymbolRef &Symbol : O->symbols()) {
120 if ((ec = Symbol.getAddress(Addr)))
121 report_fatal_error(ec.message());
124 if ((ec = Symbol.getName(Name)))
125 report_fatal_error(ec.message());
130 // If we couldn't find a symbol that this relocation refers to, try
131 // to find a section beginning instead.
132 for (const SectionRef &Section : O->sections()) {
137 if ((ec = Section.getAddress(Addr)))
138 report_fatal_error(ec.message());
141 if ((ec = Section.getName(Name)))
142 report_fatal_error(ec.message());
147 fmt << format("0x%x", Val);
152 bool isExtern = O->getPlainRelocationExternal(RE);
153 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
156 symbol_iterator SI = O->symbol_begin();
160 section_iterator SI = O->section_begin();
161 // Adjust for the fact that sections are 1-indexed.
162 advance(SI, Val - 1);
170 getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
175 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
176 return RE.r_word0 & 0xffffff;
179 static bool getPlainRelocationPCRel(const MachOObjectFile *O,
180 const MachO::any_relocation_info &RE) {
181 if (O->isLittleEndian())
182 return (RE.r_word1 >> 24) & 1;
183 return (RE.r_word1 >> 7) & 1;
187 getScatteredRelocationPCRel(const MachOObjectFile *O,
188 const MachO::any_relocation_info &RE) {
189 return (RE.r_word0 >> 30) & 1;
192 static unsigned getPlainRelocationLength(const MachOObjectFile *O,
193 const MachO::any_relocation_info &RE) {
194 if (O->isLittleEndian())
195 return (RE.r_word1 >> 25) & 3;
196 return (RE.r_word1 >> 5) & 3;
200 getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
201 return (RE.r_word0 >> 28) & 3;
204 static unsigned getPlainRelocationType(const MachOObjectFile *O,
205 const MachO::any_relocation_info &RE) {
206 if (O->isLittleEndian())
207 return RE.r_word1 >> 28;
208 return RE.r_word1 & 0xf;
212 getScatteredRelocationType(const MachO::any_relocation_info &RE) {
213 return (RE.r_word0 >> 24) & 0xf;
216 static uint32_t getSectionFlags(const MachOObjectFile *O,
219 MachO::section_64 Sect = O->getSection64(Sec);
222 MachO::section Sect = O->getSection(Sec);
226 MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object,
227 bool IsLittleEndian, bool Is64bits,
229 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)),
230 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
231 DataInCodeLoadCmd(nullptr) {
232 uint32_t LoadCommandCount = this->getHeader().ncmds;
233 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
234 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
236 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
237 for (unsigned I = 0; ; ++I) {
238 if (Load.C.cmd == MachO::LC_SYMTAB) {
239 assert(!SymtabLoadCmd && "Multiple symbol tables");
240 SymtabLoadCmd = Load.Ptr;
241 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
242 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
243 DysymtabLoadCmd = Load.Ptr;
244 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
245 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
246 DataInCodeLoadCmd = Load.Ptr;
247 } else if (Load.C.cmd == SegmentLoadType) {
248 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
249 for (unsigned J = 0; J < NumSections; ++J) {
250 const char *Sec = getSectionPtr(this, Load, J);
251 Sections.push_back(Sec);
253 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
254 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
255 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
256 Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
257 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
258 Libraries.push_back(Load.Ptr);
261 if (I == LoadCommandCount - 1)
264 Load = getNextLoadCommandInfo(Load);
268 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
269 unsigned SymbolTableEntrySize = is64Bit() ?
270 sizeof(MachO::nlist_64) :
271 sizeof(MachO::nlist);
272 Symb.p += SymbolTableEntrySize;
275 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
276 StringRef &Res) const {
277 StringRef StringTable = getStringTableData();
278 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
279 const char *Start = &StringTable.data()[Entry.n_strx];
280 Res = StringRef(Start);
281 return object_error::success;
284 // getIndirectName() returns the name of the alias'ed symbol who's string table
285 // index is in the n_value field.
286 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
287 StringRef &Res) const {
288 StringRef StringTable = getStringTableData();
291 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
292 NValue = Entry.n_value;
293 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
294 return object_error::parse_failed;
296 MachO::nlist Entry = getSymbolTableEntry(Symb);
297 NValue = Entry.n_value;
298 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
299 return object_error::parse_failed;
301 if (NValue >= StringTable.size())
302 return object_error::parse_failed;
303 const char *Start = &StringTable.data()[NValue];
304 Res = StringRef(Start);
305 return object_error::success;
308 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
309 uint64_t &Res) const {
311 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
312 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
314 Res = UnknownAddressOrSize;
318 MachO::nlist Entry = getSymbolTableEntry(Symb);
319 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
321 Res = UnknownAddressOrSize;
325 return object_error::success;
328 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
329 uint32_t &Result) const {
330 uint32_t flags = getSymbolFlags(DRI);
331 if (flags & SymbolRef::SF_Common) {
332 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
333 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
337 return object_error::success;
340 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
341 uint64_t &Result) const {
342 uint64_t BeginOffset;
343 uint64_t EndOffset = 0;
344 uint8_t SectionIndex;
346 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
348 getSymbolAddress(DRI, Value);
349 if (Value == UnknownAddressOrSize) {
350 Result = UnknownAddressOrSize;
351 return object_error::success;
356 SectionIndex = Entry.n_sect;
358 uint32_t flags = getSymbolFlags(DRI);
359 if (flags & SymbolRef::SF_Common)
362 Result = UnknownAddressOrSize;
363 return object_error::success;
365 // Unfortunately symbols are unsorted so we need to touch all
366 // symbols from load command
367 for (const SymbolRef &Symbol : symbols()) {
368 DataRefImpl DRI = Symbol.getRawDataRefImpl();
369 Entry = getSymbolTableEntryBase(this, DRI);
370 getSymbolAddress(DRI, Value);
371 if (Value == UnknownAddressOrSize)
373 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
374 if (!EndOffset || Value < EndOffset)
380 Sec.d.a = SectionIndex-1;
381 getSectionSize(Sec, Size);
382 getSectionAddress(Sec, EndOffset);
385 Result = EndOffset - BeginOffset;
386 return object_error::success;
389 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
390 SymbolRef::Type &Res) const {
391 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
392 uint8_t n_type = Entry.n_type;
394 Res = SymbolRef::ST_Other;
396 // If this is a STAB debugging symbol, we can do nothing more.
397 if (n_type & MachO::N_STAB) {
398 Res = SymbolRef::ST_Debug;
399 return object_error::success;
402 switch (n_type & MachO::N_TYPE) {
404 Res = SymbolRef::ST_Unknown;
407 Res = SymbolRef::ST_Function;
410 return object_error::success;
413 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
414 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
416 uint8_t MachOType = Entry.n_type;
417 uint16_t MachOFlags = Entry.n_desc;
419 uint32_t Result = SymbolRef::SF_None;
421 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
422 Result |= SymbolRef::SF_Undefined;
424 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
425 Result |= SymbolRef::SF_Indirect;
427 if (MachOType & MachO::N_STAB)
428 Result |= SymbolRef::SF_FormatSpecific;
430 if (MachOType & MachO::N_EXT) {
431 Result |= SymbolRef::SF_Global;
432 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
434 getSymbolAddress(DRI, Value);
435 if (Value && Value != UnknownAddressOrSize)
436 Result |= SymbolRef::SF_Common;
440 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
441 Result |= SymbolRef::SF_Weak;
443 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
444 Result |= SymbolRef::SF_Absolute;
449 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
450 section_iterator &Res) const {
451 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
452 uint8_t index = Entry.n_sect;
459 Res = section_iterator(SectionRef(DRI, this));
462 return object_error::success;
465 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
469 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
470 StringRef &Result) const {
471 ArrayRef<char> Raw = getSectionRawName(Sec);
472 Result = parseSegmentOrSectionName(Raw.data());
473 return object_error::success;
476 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
477 uint64_t &Res) const {
479 MachO::section_64 Sect = getSection64(Sec);
482 MachO::section Sect = getSection(Sec);
485 return object_error::success;
488 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
489 uint64_t &Res) const {
491 MachO::section_64 Sect = getSection64(Sec);
494 MachO::section Sect = getSection(Sec);
498 return object_error::success;
501 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
502 StringRef &Res) const {
507 MachO::section_64 Sect = getSection64(Sec);
508 Offset = Sect.offset;
511 MachO::section Sect = getSection(Sec);
512 Offset = Sect.offset;
516 Res = this->getData().substr(Offset, Size);
517 return object_error::success;
520 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
521 uint64_t &Res) const {
524 MachO::section_64 Sect = getSection64(Sec);
527 MachO::section Sect = getSection(Sec);
531 Res = uint64_t(1) << Align;
532 return object_error::success;
535 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
537 uint32_t Flags = getSectionFlags(this, Sec);
538 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
539 return object_error::success;
542 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
543 bool &Result) const {
544 uint32_t Flags = getSectionFlags(this, Sec);
545 unsigned SectionType = Flags & MachO::SECTION_TYPE;
546 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
547 !(SectionType == MachO::S_ZEROFILL ||
548 SectionType == MachO::S_GB_ZEROFILL);
549 return object_error::success;
552 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
553 bool &Result) const {
554 uint32_t Flags = getSectionFlags(this, Sec);
555 unsigned SectionType = Flags & MachO::SECTION_TYPE;
556 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
557 (SectionType == MachO::S_ZEROFILL ||
558 SectionType == MachO::S_GB_ZEROFILL);
559 return object_error::success;
563 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
564 bool &Result) const {
565 // FIXME: Unimplemented.
567 return object_error::success;
570 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
571 bool &Result) const {
572 // FIXME: Unimplemented.
574 return object_error::success;
577 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
579 uint32_t Flags = getSectionFlags(this, Sec);
580 unsigned SectionType = Flags & MachO::SECTION_TYPE;
581 Res = SectionType == MachO::S_ZEROFILL ||
582 SectionType == MachO::S_GB_ZEROFILL;
583 return object_error::success;
586 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
587 bool &Result) const {
588 // Consider using the code from isSectionText to look for __const sections.
589 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
590 // to use section attributes to distinguish code from data.
592 // FIXME: Unimplemented.
594 return object_error::success;
597 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
599 bool &Result) const {
601 this->getSymbolType(Symb, ST);
602 if (ST == SymbolRef::ST_Unknown) {
604 return object_error::success;
607 uint64_t SectBegin, SectEnd;
608 getSectionAddress(Sec, SectBegin);
609 getSectionSize(Sec, SectEnd);
610 SectEnd += SectBegin;
613 getSymbolAddress(Symb, SymAddr);
614 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
616 return object_error::success;
619 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
623 return relocation_iterator(RelocationRef(Ret, this));
627 MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
630 MachO::section_64 Sect = getSection64(Sec);
633 MachO::section Sect = getSection(Sec);
640 return relocation_iterator(RelocationRef(Ret, this));
643 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
647 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
648 uint64_t &Res) const {
650 getRelocationOffset(Rel, Offset);
655 getSectionAddress(Sec, SecAddress);
656 Res = SecAddress + Offset;
657 return object_error::success;
660 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
661 uint64_t &Res) const {
662 assert(getHeader().filetype == MachO::MH_OBJECT &&
663 "Only implemented for MH_OBJECT");
664 MachO::any_relocation_info RE = getRelocation(Rel);
665 Res = getAnyRelocationAddress(RE);
666 return object_error::success;
670 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
671 MachO::any_relocation_info RE = getRelocation(Rel);
672 if (isRelocationScattered(RE))
675 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
676 bool isExtern = getPlainRelocationExternal(RE);
680 MachO::symtab_command S = getSymtabLoadCommand();
681 unsigned SymbolTableEntrySize = is64Bit() ?
682 sizeof(MachO::nlist_64) :
683 sizeof(MachO::nlist);
684 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
686 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
687 return symbol_iterator(SymbolRef(Sym, this));
690 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
691 uint64_t &Res) const {
692 MachO::any_relocation_info RE = getRelocation(Rel);
693 Res = getAnyRelocationType(RE);
694 return object_error::success;
698 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
699 SmallVectorImpl<char> &Result) const {
702 getRelocationType(Rel, RType);
704 unsigned Arch = this->getArch();
708 static const char *const Table[] = {
709 "GENERIC_RELOC_VANILLA",
710 "GENERIC_RELOC_PAIR",
711 "GENERIC_RELOC_SECTDIFF",
712 "GENERIC_RELOC_PB_LA_PTR",
713 "GENERIC_RELOC_LOCAL_SECTDIFF",
714 "GENERIC_RELOC_TLV" };
722 case Triple::x86_64: {
723 static const char *const Table[] = {
724 "X86_64_RELOC_UNSIGNED",
725 "X86_64_RELOC_SIGNED",
726 "X86_64_RELOC_BRANCH",
727 "X86_64_RELOC_GOT_LOAD",
729 "X86_64_RELOC_SUBTRACTOR",
730 "X86_64_RELOC_SIGNED_1",
731 "X86_64_RELOC_SIGNED_2",
732 "X86_64_RELOC_SIGNED_4",
733 "X86_64_RELOC_TLV" };
742 static const char *const Table[] = {
745 "ARM_RELOC_SECTDIFF",
746 "ARM_RELOC_LOCAL_SECTDIFF",
747 "ARM_RELOC_PB_LA_PTR",
749 "ARM_THUMB_RELOC_BR22",
750 "ARM_THUMB_32BIT_BRANCH",
752 "ARM_RELOC_HALF_SECTDIFF" };
761 case Triple::aarch64: {
762 static const char *const Table[] = {
763 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
764 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
765 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
766 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
767 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
771 if (RType >= array_lengthof(Table))
778 static const char *const Table[] = {
787 "PPC_RELOC_SECTDIFF",
788 "PPC_RELOC_PB_LA_PTR",
789 "PPC_RELOC_HI16_SECTDIFF",
790 "PPC_RELOC_LO16_SECTDIFF",
791 "PPC_RELOC_HA16_SECTDIFF",
793 "PPC_RELOC_LO14_SECTDIFF",
794 "PPC_RELOC_LOCAL_SECTDIFF" };
802 case Triple::UnknownArch:
806 Result.append(res.begin(), res.end());
807 return object_error::success;
811 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
812 SmallVectorImpl<char> &Result) const {
813 MachO::any_relocation_info RE = getRelocation(Rel);
815 unsigned Arch = this->getArch();
818 raw_string_ostream fmt(fmtbuf);
819 unsigned Type = this->getAnyRelocationType(RE);
820 bool IsPCRel = this->getAnyRelocationPCRel(RE);
822 // Determine any addends that should be displayed with the relocation.
823 // These require decoding the relocation type, which is triple-specific.
825 // X86_64 has entirely custom relocation types.
826 if (Arch == Triple::x86_64) {
827 bool isPCRel = getAnyRelocationPCRel(RE);
830 case MachO::X86_64_RELOC_GOT_LOAD:
831 case MachO::X86_64_RELOC_GOT: {
832 printRelocationTargetName(this, RE, fmt);
834 if (isPCRel) fmt << "PCREL";
837 case MachO::X86_64_RELOC_SUBTRACTOR: {
838 DataRefImpl RelNext = Rel;
839 moveRelocationNext(RelNext);
840 MachO::any_relocation_info RENext = getRelocation(RelNext);
842 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
843 // X86_64_RELOC_UNSIGNED.
844 // NOTE: Scattered relocations don't exist on x86_64.
845 unsigned RType = getAnyRelocationType(RENext);
846 if (RType != MachO::X86_64_RELOC_UNSIGNED)
847 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
848 "X86_64_RELOC_SUBTRACTOR.");
850 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
851 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
852 printRelocationTargetName(this, RENext, fmt);
854 printRelocationTargetName(this, RE, fmt);
857 case MachO::X86_64_RELOC_TLV:
858 printRelocationTargetName(this, RE, fmt);
860 if (isPCRel) fmt << "P";
862 case MachO::X86_64_RELOC_SIGNED_1:
863 printRelocationTargetName(this, RE, fmt);
866 case MachO::X86_64_RELOC_SIGNED_2:
867 printRelocationTargetName(this, RE, fmt);
870 case MachO::X86_64_RELOC_SIGNED_4:
871 printRelocationTargetName(this, RE, fmt);
875 printRelocationTargetName(this, RE, fmt);
878 // X86 and ARM share some relocation types in common.
879 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
880 Arch == Triple::ppc) {
881 // Generic relocation types...
883 case MachO::GENERIC_RELOC_PAIR: // prints no info
884 return object_error::success;
885 case MachO::GENERIC_RELOC_SECTDIFF: {
886 DataRefImpl RelNext = Rel;
887 moveRelocationNext(RelNext);
888 MachO::any_relocation_info RENext = getRelocation(RelNext);
890 // X86 sect diff's must be followed by a relocation of type
891 // GENERIC_RELOC_PAIR.
892 unsigned RType = getAnyRelocationType(RENext);
894 if (RType != MachO::GENERIC_RELOC_PAIR)
895 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
896 "GENERIC_RELOC_SECTDIFF.");
898 printRelocationTargetName(this, RE, fmt);
900 printRelocationTargetName(this, RENext, fmt);
905 if (Arch == Triple::x86 || Arch == Triple::ppc) {
907 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
908 DataRefImpl RelNext = Rel;
909 moveRelocationNext(RelNext);
910 MachO::any_relocation_info RENext = getRelocation(RelNext);
912 // X86 sect diff's must be followed by a relocation of type
913 // GENERIC_RELOC_PAIR.
914 unsigned RType = getAnyRelocationType(RENext);
915 if (RType != MachO::GENERIC_RELOC_PAIR)
916 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
917 "GENERIC_RELOC_LOCAL_SECTDIFF.");
919 printRelocationTargetName(this, RE, fmt);
921 printRelocationTargetName(this, RENext, fmt);
924 case MachO::GENERIC_RELOC_TLV: {
925 printRelocationTargetName(this, RE, fmt);
927 if (IsPCRel) fmt << "P";
931 printRelocationTargetName(this, RE, fmt);
933 } else { // ARM-specific relocations
935 case MachO::ARM_RELOC_HALF:
936 case MachO::ARM_RELOC_HALF_SECTDIFF: {
937 // Half relocations steal a bit from the length field to encode
938 // whether this is an upper16 or a lower16 relocation.
939 bool isUpper = getAnyRelocationLength(RE) >> 1;
945 printRelocationTargetName(this, RE, fmt);
947 DataRefImpl RelNext = Rel;
948 moveRelocationNext(RelNext);
949 MachO::any_relocation_info RENext = getRelocation(RelNext);
951 // ARM half relocs must be followed by a relocation of type
953 unsigned RType = getAnyRelocationType(RENext);
954 if (RType != MachO::ARM_RELOC_PAIR)
955 report_fatal_error("Expected ARM_RELOC_PAIR after "
958 // NOTE: The half of the target virtual address is stashed in the
959 // address field of the secondary relocation, but we can't reverse
960 // engineer the constant offset from it without decoding the movw/movt
961 // instruction to find the other half in its immediate field.
963 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
964 // symbol/section pointer of the follow-on relocation.
965 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
967 printRelocationTargetName(this, RENext, fmt);
974 printRelocationTargetName(this, RE, fmt);
979 printRelocationTargetName(this, RE, fmt);
982 Result.append(fmtbuf.begin(), fmtbuf.end());
983 return object_error::success;
986 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
987 bool &Result) const {
988 unsigned Arch = getArch();
990 getRelocationType(Rel, Type);
994 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
996 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
997 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
998 } else if (Arch == Triple::x86_64) {
999 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1000 // an X86_64_RELOC_SUBTRACTOR.
1001 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
1002 DataRefImpl RelPrev = Rel;
1005 getRelocationType(RelPrev, PrevType);
1006 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
1011 return object_error::success;
1014 std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1015 LibraryRef &Res) const {
1016 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1019 std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1020 StringRef &Res) const {
1021 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1025 // guessLibraryShortName() is passed a name of a dynamic library and returns a
1026 // guess on what the short name is. Then name is returned as a substring of the
1027 // StringRef Name passed in. The name of the dynamic library is recognized as
1028 // a framework if it has one of the two following forms:
1029 // Foo.framework/Versions/A/Foo
1030 // Foo.framework/Foo
1031 // Where A and Foo can be any string. And may contain a trailing suffix
1032 // starting with an underbar. If the Name is recognized as a framework then
1033 // isFramework is set to true else it is set to false. If the Name has a
1034 // suffix then Suffix is set to the substring in Name that contains the suffix
1035 // else it is set to a NULL StringRef.
1037 // The Name of the dynamic library is recognized as a library name if it has
1038 // one of the two following forms:
1041 // The library may have a suffix trailing the name Foo of the form:
1042 // libFoo_profile.A.dylib
1043 // libFoo_profile.dylib
1045 // The Name of the dynamic library is also recognized as a library name if it
1046 // has the following form:
1049 // If the Name of the dynamic library is none of the forms above then a NULL
1050 // StringRef is returned.
1052 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
1054 StringRef &Suffix) {
1055 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
1056 size_t a, b, c, d, Idx;
1058 isFramework = false;
1059 Suffix = StringRef();
1061 // Pull off the last component and make Foo point to it
1062 a = Name.rfind('/');
1063 if (a == Name.npos || a == 0)
1065 Foo = Name.slice(a+1, Name.npos);
1067 // Look for a suffix starting with a '_'
1068 Idx = Foo.rfind('_');
1069 if (Idx != Foo.npos && Foo.size() >= 2) {
1070 Suffix = Foo.slice(Idx, Foo.npos);
1071 Foo = Foo.slice(0, Idx);
1074 // First look for the form Foo.framework/Foo
1075 b = Name.rfind('/', a);
1080 F = Name.slice(Idx, Idx + Foo.size());
1081 DotFramework = Name.slice(Idx + Foo.size(),
1082 Idx + Foo.size() + sizeof(".framework/")-1);
1083 if (F == Foo && DotFramework == ".framework/") {
1088 // Next look for the form Foo.framework/Versions/A/Foo
1091 c = Name.rfind('/', b);
1092 if (c == Name.npos || c == 0)
1094 V = Name.slice(c+1, Name.npos);
1095 if (!V.startswith("Versions/"))
1097 d = Name.rfind('/', c);
1102 F = Name.slice(Idx, Idx + Foo.size());
1103 DotFramework = Name.slice(Idx + Foo.size(),
1104 Idx + Foo.size() + sizeof(".framework/")-1);
1105 if (F == Foo && DotFramework == ".framework/") {
1111 // pull off the suffix after the "." and make a point to it
1112 a = Name.rfind('.');
1113 if (a == Name.npos || a == 0)
1115 Dylib = Name.slice(a, Name.npos);
1116 if (Dylib != ".dylib")
1119 // First pull off the version letter for the form Foo.A.dylib if any.
1121 Dot = Name.slice(a-2, a-1);
1126 b = Name.rfind('/', a);
1131 // ignore any suffix after an underbar like Foo_profile.A.dylib
1132 Idx = Name.find('_', b);
1133 if (Idx != Name.npos && Idx != b) {
1134 Lib = Name.slice(b, Idx);
1135 Suffix = Name.slice(Idx, a);
1138 Lib = Name.slice(b, a);
1139 // There are incorrect library names of the form:
1140 // libATS.A_profile.dylib so check for these.
1141 if (Lib.size() >= 3) {
1142 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1144 Lib = Lib.slice(0, Lib.size()-2);
1149 Qtx = Name.slice(a, Name.npos);
1152 b = Name.rfind('/', a);
1154 Lib = Name.slice(0, a);
1156 Lib = Name.slice(b+1, a);
1157 // There are library names of the form: QT.A.qtx so check for these.
1158 if (Lib.size() >= 3) {
1159 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1161 Lib = Lib.slice(0, Lib.size()-2);
1166 // getLibraryShortNameByIndex() is used to get the short name of the library
1167 // for an undefined symbol in a linked Mach-O binary that was linked with the
1168 // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1169 // It is passed the index (0 - based) of the library as translated from
1170 // GET_LIBRARY_ORDINAL (1 - based).
1171 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1173 if (Index >= Libraries.size())
1174 return object_error::parse_failed;
1176 MachO::dylib_command D =
1177 getStruct<MachO::dylib_command>(this, Libraries[Index]);
1178 if (D.dylib.name >= D.cmdsize)
1179 return object_error::parse_failed;
1181 // If the cache of LibrariesShortNames is not built up do that first for
1182 // all the Libraries.
1183 if (LibrariesShortNames.size() == 0) {
1184 for (unsigned i = 0; i < Libraries.size(); i++) {
1185 MachO::dylib_command D =
1186 getStruct<MachO::dylib_command>(this, Libraries[i]);
1187 if (D.dylib.name >= D.cmdsize) {
1188 LibrariesShortNames.push_back(StringRef());
1191 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1192 StringRef Name = StringRef(P);
1195 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1196 if (shortName == StringRef())
1197 LibrariesShortNames.push_back(Name);
1199 LibrariesShortNames.push_back(shortName);
1203 Res = LibrariesShortNames[Index];
1204 return object_error::success;
1207 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1208 return getSymbolByIndex(0);
1211 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1214 return basic_symbol_iterator(SymbolRef(DRI, this));
1216 MachO::symtab_command Symtab = getSymtabLoadCommand();
1217 unsigned SymbolTableEntrySize = is64Bit() ?
1218 sizeof(MachO::nlist_64) :
1219 sizeof(MachO::nlist);
1220 unsigned Offset = Symtab.symoff +
1221 Symtab.nsyms * SymbolTableEntrySize;
1222 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1223 return basic_symbol_iterator(SymbolRef(DRI, this));
1226 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1229 return basic_symbol_iterator(SymbolRef(DRI, this));
1231 MachO::symtab_command Symtab = getSymtabLoadCommand();
1232 assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
1233 unsigned SymbolTableEntrySize =
1234 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1235 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1236 DRI.p += Index * SymbolTableEntrySize;
1237 return basic_symbol_iterator(SymbolRef(DRI, this));
1240 section_iterator MachOObjectFile::section_begin() const {
1242 return section_iterator(SectionRef(DRI, this));
1245 section_iterator MachOObjectFile::section_end() const {
1247 DRI.d.a = Sections.size();
1248 return section_iterator(SectionRef(DRI, this));
1251 library_iterator MachOObjectFile::needed_library_begin() const {
1253 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1256 library_iterator MachOObjectFile::needed_library_end() const {
1258 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1261 uint8_t MachOObjectFile::getBytesInAddress() const {
1262 return is64Bit() ? 8 : 4;
1265 StringRef MachOObjectFile::getFileFormatName() const {
1266 unsigned CPUType = getCPUType(this);
1269 case llvm::MachO::CPU_TYPE_I386:
1270 return "Mach-O 32-bit i386";
1271 case llvm::MachO::CPU_TYPE_ARM:
1272 return "Mach-O arm";
1273 case llvm::MachO::CPU_TYPE_POWERPC:
1274 return "Mach-O 32-bit ppc";
1276 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
1277 "64-bit object file when we're not 64-bit?");
1278 return "Mach-O 32-bit unknown";
1282 // Make sure the cpu type has the correct mask.
1283 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1284 == llvm::MachO::CPU_ARCH_ABI64 &&
1285 "32-bit object file when we're 64-bit?");
1288 case llvm::MachO::CPU_TYPE_X86_64:
1289 return "Mach-O 64-bit x86-64";
1290 case llvm::MachO::CPU_TYPE_ARM64:
1291 return "Mach-O arm64";
1292 case llvm::MachO::CPU_TYPE_POWERPC64:
1293 return "Mach-O 64-bit ppc64";
1295 return "Mach-O 64-bit unknown";
1299 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1301 case llvm::MachO::CPU_TYPE_I386:
1303 case llvm::MachO::CPU_TYPE_X86_64:
1304 return Triple::x86_64;
1305 case llvm::MachO::CPU_TYPE_ARM:
1307 case llvm::MachO::CPU_TYPE_ARM64:
1308 return Triple::arm64;
1309 case llvm::MachO::CPU_TYPE_POWERPC:
1311 case llvm::MachO::CPU_TYPE_POWERPC64:
1312 return Triple::ppc64;
1314 return Triple::UnknownArch;
1318 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
1320 case MachO::CPU_TYPE_I386:
1321 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1322 case MachO::CPU_SUBTYPE_I386_ALL:
1323 return Triple("i386-apple-darwin");
1327 case MachO::CPU_TYPE_X86_64:
1328 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1329 case MachO::CPU_SUBTYPE_X86_64_ALL:
1330 return Triple("x86_64-apple-darwin");
1331 case MachO::CPU_SUBTYPE_X86_64_H:
1332 return Triple("x86_64h-apple-darwin");
1336 case MachO::CPU_TYPE_ARM:
1337 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1338 case MachO::CPU_SUBTYPE_ARM_V4T:
1339 return Triple("armv4t-apple-darwin");
1340 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1341 return Triple("armv5e-apple-darwin");
1342 case MachO::CPU_SUBTYPE_ARM_V6:
1343 return Triple("armv6-apple-darwin");
1344 case MachO::CPU_SUBTYPE_ARM_V6M:
1345 return Triple("armv6m-apple-darwin");
1346 case MachO::CPU_SUBTYPE_ARM_V7EM:
1347 return Triple("armv7em-apple-darwin");
1348 case MachO::CPU_SUBTYPE_ARM_V7K:
1349 return Triple("armv7k-apple-darwin");
1350 case MachO::CPU_SUBTYPE_ARM_V7M:
1351 return Triple("armv7m-apple-darwin");
1352 case MachO::CPU_SUBTYPE_ARM_V7S:
1353 return Triple("armv7s-apple-darwin");
1357 case MachO::CPU_TYPE_ARM64:
1358 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1359 case MachO::CPU_SUBTYPE_ARM64_ALL:
1360 return Triple("arm64-apple-darwin");
1364 case MachO::CPU_TYPE_POWERPC:
1365 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1366 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1367 return Triple("ppc-apple-darwin");
1371 case MachO::CPU_TYPE_POWERPC64:
1372 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1373 case MachO::CPU_SUBTYPE_POWERPC_ALL:
1374 return Triple("ppc64-apple-darwin");
1383 Triple MachOObjectFile::getHostArch() {
1384 return Triple(sys::getDefaultTargetTriple());
1387 Triple MachOObjectFile::getArch(StringRef ArchFlag) {
1388 if (ArchFlag == "i386")
1389 return Triple("i386-apple-darwin");
1390 else if (ArchFlag == "x86_64")
1391 return Triple("x86_64-apple-darwin");
1392 else if (ArchFlag == "x86_64h")
1393 return Triple("x86_64h-apple-darwin");
1394 else if (ArchFlag == "armv4t" || ArchFlag == "arm")
1395 return Triple("armv4t-apple-darwin");
1396 else if (ArchFlag == "armv5e")
1397 return Triple("armv5e-apple-darwin");
1398 else if (ArchFlag == "armv6")
1399 return Triple("armv6-apple-darwin");
1400 else if (ArchFlag == "armv6m")
1401 return Triple("armv6m-apple-darwin");
1402 else if (ArchFlag == "armv7em")
1403 return Triple("armv7em-apple-darwin");
1404 else if (ArchFlag == "armv7k")
1405 return Triple("armv7k-apple-darwin");
1406 else if (ArchFlag == "armv7k")
1407 return Triple("armv7m-apple-darwin");
1408 else if (ArchFlag == "armv7s")
1409 return Triple("armv7s-apple-darwin");
1410 else if (ArchFlag == "arm64")
1411 return Triple("arm64-apple-darwin");
1412 else if (ArchFlag == "ppc")
1413 return Triple("ppc-apple-darwin");
1414 else if (ArchFlag == "ppc64")
1415 return Triple("ppc64-apple-darwin");
1420 unsigned MachOObjectFile::getArch() const {
1421 return getArch(getCPUType(this));
1424 StringRef MachOObjectFile::getLoadName() const {
1426 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
1429 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1432 return section_rel_begin(DRI);
1435 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1438 return section_rel_end(DRI);
1441 dice_iterator MachOObjectFile::begin_dices() const {
1443 if (!DataInCodeLoadCmd)
1444 return dice_iterator(DiceRef(DRI, this));
1446 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1447 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1448 return dice_iterator(DiceRef(DRI, this));
1451 dice_iterator MachOObjectFile::end_dices() const {
1453 if (!DataInCodeLoadCmd)
1454 return dice_iterator(DiceRef(DRI, this));
1456 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1457 unsigned Offset = DicLC.dataoff + DicLC.datasize;
1458 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1459 return dice_iterator(DiceRef(DRI, this));
1463 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1464 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1465 return parseSegmentOrSectionName(Raw.data());
1469 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1470 const section_base *Base =
1471 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1472 return ArrayRef<char>(Base->sectname);
1476 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1477 const section_base *Base =
1478 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1479 return ArrayRef<char>(Base->segname);
1483 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1485 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1487 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1490 unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1491 const MachO::any_relocation_info &RE) const {
1492 if (isLittleEndian())
1493 return RE.r_word1 & 0xffffff;
1494 return RE.r_word1 >> 8;
1497 bool MachOObjectFile::getPlainRelocationExternal(
1498 const MachO::any_relocation_info &RE) const {
1499 if (isLittleEndian())
1500 return (RE.r_word1 >> 27) & 1;
1501 return (RE.r_word1 >> 4) & 1;
1504 bool MachOObjectFile::getScatteredRelocationScattered(
1505 const MachO::any_relocation_info &RE) const {
1506 return RE.r_word0 >> 31;
1509 uint32_t MachOObjectFile::getScatteredRelocationValue(
1510 const MachO::any_relocation_info &RE) const {
1514 unsigned MachOObjectFile::getAnyRelocationAddress(
1515 const MachO::any_relocation_info &RE) const {
1516 if (isRelocationScattered(RE))
1517 return getScatteredRelocationAddress(RE);
1518 return getPlainRelocationAddress(RE);
1521 unsigned MachOObjectFile::getAnyRelocationPCRel(
1522 const MachO::any_relocation_info &RE) const {
1523 if (isRelocationScattered(RE))
1524 return getScatteredRelocationPCRel(this, RE);
1525 return getPlainRelocationPCRel(this, RE);
1528 unsigned MachOObjectFile::getAnyRelocationLength(
1529 const MachO::any_relocation_info &RE) const {
1530 if (isRelocationScattered(RE))
1531 return getScatteredRelocationLength(RE);
1532 return getPlainRelocationLength(this, RE);
1536 MachOObjectFile::getAnyRelocationType(
1537 const MachO::any_relocation_info &RE) const {
1538 if (isRelocationScattered(RE))
1539 return getScatteredRelocationType(RE);
1540 return getPlainRelocationType(this, RE);
1544 MachOObjectFile::getRelocationSection(
1545 const MachO::any_relocation_info &RE) const {
1546 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
1547 return *section_end();
1548 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1551 return SectionRef(DRI, this);
1554 MachOObjectFile::LoadCommandInfo
1555 MachOObjectFile::getFirstLoadCommandInfo() const {
1556 MachOObjectFile::LoadCommandInfo Load;
1558 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1559 sizeof(MachO::mach_header);
1560 Load.Ptr = getPtr(this, HeaderSize);
1561 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
1565 MachOObjectFile::LoadCommandInfo
1566 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1567 MachOObjectFile::LoadCommandInfo Next;
1568 Next.Ptr = L.Ptr + L.C.cmdsize;
1569 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
1573 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1574 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
1577 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1578 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
1581 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
1582 unsigned Index) const {
1583 const char *Sec = getSectionPtr(this, L, Index);
1584 return getStruct<MachO::section>(this, Sec);
1587 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1588 unsigned Index) const {
1589 const char *Sec = getSectionPtr(this, L, Index);
1590 return getStruct<MachO::section_64>(this, Sec);
1594 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
1595 const char *P = reinterpret_cast<const char *>(DRI.p);
1596 return getStruct<MachO::nlist>(this, P);
1600 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
1601 const char *P = reinterpret_cast<const char *>(DRI.p);
1602 return getStruct<MachO::nlist_64>(this, P);
1605 MachO::linkedit_data_command
1606 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1607 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
1610 MachO::segment_command
1611 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
1612 return getStruct<MachO::segment_command>(this, L.Ptr);
1615 MachO::segment_command_64
1616 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
1617 return getStruct<MachO::segment_command_64>(this, L.Ptr);
1620 MachO::linker_options_command
1621 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
1622 return getStruct<MachO::linker_options_command>(this, L.Ptr);
1625 MachO::version_min_command
1626 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
1627 return getStruct<MachO::version_min_command>(this, L.Ptr);
1630 MachO::dylib_command
1631 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
1632 return getStruct<MachO::dylib_command>(this, L.Ptr);
1636 MachO::any_relocation_info
1637 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
1642 MachO::section_64 Sect = getSection64(Sec);
1643 Offset = Sect.reloff;
1645 MachO::section Sect = getSection(Sec);
1646 Offset = Sect.reloff;
1649 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
1650 getPtr(this, Offset)) + Rel.d.b;
1651 return getStruct<MachO::any_relocation_info>(
1652 this, reinterpret_cast<const char *>(P));
1655 MachO::data_in_code_entry
1656 MachOObjectFile::getDice(DataRefImpl Rel) const {
1657 const char *P = reinterpret_cast<const char *>(Rel.p);
1658 return getStruct<MachO::data_in_code_entry>(this, P);
1661 MachO::mach_header MachOObjectFile::getHeader() const {
1662 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
1665 MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1666 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
1669 uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1670 const MachO::dysymtab_command &DLC,
1671 unsigned Index) const {
1672 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1673 return getStruct<uint32_t>(this, getPtr(this, Offset));
1676 MachO::data_in_code_entry
1677 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1678 unsigned Index) const {
1679 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1680 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
1683 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1684 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
1687 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1688 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
1691 MachO::linkedit_data_command
1692 MachOObjectFile::getDataInCodeLoadCommand() const {
1693 if (DataInCodeLoadCmd)
1694 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
1696 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
1697 MachO::linkedit_data_command Cmd;
1698 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1699 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1705 StringRef MachOObjectFile::getStringTableData() const {
1706 MachO::symtab_command S = getSymtabLoadCommand();
1707 return getData().substr(S.stroff, S.strsize);
1710 bool MachOObjectFile::is64Bit() const {
1711 return getType() == getMachOType(false, true) ||
1712 getType() == getMachOType(true, true);
1715 void MachOObjectFile::ReadULEB128s(uint64_t Index,
1716 SmallVectorImpl<uint64_t> &Out) const {
1717 DataExtractor extractor(ObjectFile::getData(), true, 0);
1719 uint32_t offset = Index;
1721 while (uint64_t delta = extractor.getULEB128(&offset)) {
1723 Out.push_back(data);
1727 ErrorOr<ObjectFile *>
1728 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
1729 StringRef Magic = Buffer->getBuffer().slice(0, 4);
1731 std::unique_ptr<MachOObjectFile> Ret;
1732 if (Magic == "\xFE\xED\xFA\xCE")
1733 Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
1734 else if (Magic == "\xCE\xFA\xED\xFE")
1735 Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
1736 else if (Magic == "\xFE\xED\xFA\xCF")
1737 Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
1738 else if (Magic == "\xCF\xFA\xED\xFE")
1739 Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
1741 return object_error::parse_failed;
1745 return Ret.release();
1748 } // end namespace object
1749 } // end namespace llvm