1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the MachOObjectFile class, which binds the MachOObject 11 // class to the generic ObjectFile wrapper. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Object/MachO.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Support/DataExtractor.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/Format.h" 22 #include "llvm/Support/Host.h" 23 #include "llvm/Support/LEB128.h" 24 #include "llvm/Support/MachO.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <cctype> 28 #include <cstring> 29 #include <limits> 30 31 using namespace llvm; 32 using namespace object; 33 34 namespace { 35 struct section_base { 36 char sectname[16]; 37 char segname[16]; 38 }; 39 } 40 41 template <typename T> 42 static T getStruct(const MachOObjectFile *O, const char *P) { 43 // Don't read before the beginning or past the end of the file 44 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end()) 45 report_fatal_error("Malformed MachO file."); 46 47 T Cmd; 48 memcpy(&Cmd, P, sizeof(T)); 49 if (O->isLittleEndian() != sys::IsLittleEndianHost) 50 MachO::swapStruct(Cmd); 51 return Cmd; 52 } 53 54 template <typename SegmentCmd> 55 static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S, 56 uint32_t Cmdsize) { 57 const unsigned SectionSize = sizeof(SegmentCmd); 58 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize || 59 S.nsects * SectionSize > Cmdsize - sizeof(S)) 60 report_fatal_error( 61 "Number of sections too large for size of load command."); 62 return S.nsects; 63 } 64 65 static uint32_t 66 getSegmentLoadCommandNumSections(const MachOObjectFile *O, 67 const MachOObjectFile::LoadCommandInfo &L) { 68 if (O->is64Bit()) 69 return getSegmentLoadCommandNumSections(O->getSegment64LoadCommand(L), 70 L.C.cmdsize); 71 72 return getSegmentLoadCommandNumSections(O->getSegmentLoadCommand(L), 73 L.C.cmdsize); 74 } 75 76 static bool isPageZeroSegment(const MachOObjectFile *O, 77 const MachOObjectFile::LoadCommandInfo &L) { 78 if (O->is64Bit()) { 79 MachO::segment_command_64 S = O->getSegment64LoadCommand(L); 80 return StringRef("__PAGEZERO").equals(S.segname); 81 } 82 MachO::segment_command S = O->getSegmentLoadCommand(L); 83 return StringRef("__PAGEZERO").equals(S.segname); 84 } 85 86 87 static const char * 88 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, 89 unsigned Sec) { 90 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr); 91 92 bool Is64 = O->is64Bit(); 93 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) : 94 sizeof(MachO::segment_command); 95 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) : 96 sizeof(MachO::section); 97 98 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; 99 return reinterpret_cast<const char*>(SectionAddr); 100 } 101 102 static const char *getPtr(const MachOObjectFile *O, size_t Offset) { 103 return O->getData().substr(Offset, 1).data(); 104 } 105 106 static MachO::nlist_base 107 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { 108 const char *P = reinterpret_cast<const char *>(DRI.p); 109 return getStruct<MachO::nlist_base>(O, P); 110 } 111 112 static StringRef parseSegmentOrSectionName(const char *P) { 113 if (P[15] == 0) 114 // Null terminated. 115 return P; 116 // Not null terminated, so this is a 16 char string. 117 return StringRef(P, 16); 118 } 119 120 // Helper to advance a section or symbol iterator multiple increments at a time. 121 template<class T> 122 static void advance(T &it, size_t Val) { 123 while (Val--) 124 ++it; 125 } 126 127 static unsigned getCPUType(const MachOObjectFile *O) { 128 return O->getHeader().cputype; 129 } 130 131 static uint32_t 132 getPlainRelocationAddress(const MachO::any_relocation_info &RE) { 133 return RE.r_word0; 134 } 135 136 static unsigned 137 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) { 138 return RE.r_word0 & 0xffffff; 139 } 140 141 static bool getPlainRelocationPCRel(const MachOObjectFile *O, 142 const MachO::any_relocation_info &RE) { 143 if (O->isLittleEndian()) 144 return (RE.r_word1 >> 24) & 1; 145 return (RE.r_word1 >> 7) & 1; 146 } 147 148 static bool 149 getScatteredRelocationPCRel(const MachOObjectFile *O, 150 const MachO::any_relocation_info &RE) { 151 return (RE.r_word0 >> 30) & 1; 152 } 153 154 static unsigned getPlainRelocationLength(const MachOObjectFile *O, 155 const MachO::any_relocation_info &RE) { 156 if (O->isLittleEndian()) 157 return (RE.r_word1 >> 25) & 3; 158 return (RE.r_word1 >> 5) & 3; 159 } 160 161 static unsigned 162 getScatteredRelocationLength(const MachO::any_relocation_info &RE) { 163 return (RE.r_word0 >> 28) & 3; 164 } 165 166 static unsigned getPlainRelocationType(const MachOObjectFile *O, 167 const MachO::any_relocation_info &RE) { 168 if (O->isLittleEndian()) 169 return RE.r_word1 >> 28; 170 return RE.r_word1 & 0xf; 171 } 172 173 static uint32_t getSectionFlags(const MachOObjectFile *O, 174 DataRefImpl Sec) { 175 if (O->is64Bit()) { 176 MachO::section_64 Sect = O->getSection64(Sec); 177 return Sect.flags; 178 } 179 MachO::section Sect = O->getSection(Sec); 180 return Sect.flags; 181 } 182 183 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, 184 bool Is64bits, std::error_code &EC) 185 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), 186 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), 187 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr), 188 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr), 189 HasPageZeroSegment(false) { 190 uint32_t LoadCommandCount = this->getHeader().ncmds; 191 if (LoadCommandCount == 0) 192 return; 193 194 MachO::LoadCommandType SegmentLoadType = is64Bit() ? 195 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT; 196 197 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo(); 198 for (unsigned I = 0; ; ++I) { 199 if (Load.C.cmd == MachO::LC_SYMTAB) { 200 // Multiple symbol tables 201 if (SymtabLoadCmd) { 202 EC = object_error::parse_failed; 203 return; 204 } 205 SymtabLoadCmd = Load.Ptr; 206 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) { 207 // Multiple dynamic symbol tables 208 if (DysymtabLoadCmd) { 209 EC = object_error::parse_failed; 210 return; 211 } 212 DysymtabLoadCmd = Load.Ptr; 213 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) { 214 // Multiple data in code tables 215 if (DataInCodeLoadCmd) { 216 EC = object_error::parse_failed; 217 return; 218 } 219 DataInCodeLoadCmd = Load.Ptr; 220 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) { 221 // Multiple linker optimization hint tables 222 if (LinkOptHintsLoadCmd) { 223 EC = object_error::parse_failed; 224 return; 225 } 226 LinkOptHintsLoadCmd = Load.Ptr; 227 } else if (Load.C.cmd == MachO::LC_DYLD_INFO || 228 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) { 229 // Multiple dyldinfo load commands 230 if (DyldInfoLoadCmd) { 231 EC = object_error::parse_failed; 232 return; 233 } 234 DyldInfoLoadCmd = Load.Ptr; 235 } else if (Load.C.cmd == MachO::LC_UUID) { 236 // Multiple UUID load commands 237 if (UuidLoadCmd) { 238 EC = object_error::parse_failed; 239 return; 240 } 241 UuidLoadCmd = Load.Ptr; 242 } else if (Load.C.cmd == SegmentLoadType) { 243 const unsigned SegmentLoadSize = this->is64Bit() 244 ? sizeof(MachO::segment_command_64) 245 : sizeof(MachO::segment_command); 246 if (Load.C.cmdsize < SegmentLoadSize) 247 report_fatal_error("Segment load command size is too small."); 248 249 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); 250 for (unsigned J = 0; J < NumSections; ++J) { 251 const char *Sec = getSectionPtr(this, Load, J); 252 Sections.push_back(Sec); 253 } 254 if (isPageZeroSegment(this, Load)) 255 HasPageZeroSegment = true; 256 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB || 257 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB || 258 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB || 259 Load.C.cmd == MachO::LC_REEXPORT_DYLIB || 260 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) { 261 Libraries.push_back(Load.Ptr); 262 } 263 264 if (I == LoadCommandCount - 1) 265 break; 266 else 267 Load = getNextLoadCommandInfo(Load); 268 } 269 } 270 271 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 272 unsigned SymbolTableEntrySize = is64Bit() ? 273 sizeof(MachO::nlist_64) : 274 sizeof(MachO::nlist); 275 Symb.p += SymbolTableEntrySize; 276 } 277 278 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, 279 StringRef &Res) const { 280 StringRef StringTable = getStringTableData(); 281 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 282 const char *Start = &StringTable.data()[Entry.n_strx]; 283 if (Start < getData().begin() || Start >= getData().end()) 284 report_fatal_error( 285 "Symbol name entry points before beginning or past end of file."); 286 Res = StringRef(Start); 287 return object_error::success; 288 } 289 290 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const { 291 DataRefImpl DRI = Sec.getRawDataRefImpl(); 292 uint32_t Flags = getSectionFlags(this, DRI); 293 return Flags & MachO::SECTION_TYPE; 294 } 295 296 // getIndirectName() returns the name of the alias'ed symbol who's string table 297 // index is in the n_value field. 298 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb, 299 StringRef &Res) const { 300 StringRef StringTable = getStringTableData(); 301 uint64_t NValue; 302 if (is64Bit()) { 303 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb); 304 NValue = Entry.n_value; 305 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 306 return object_error::parse_failed; 307 } else { 308 MachO::nlist Entry = getSymbolTableEntry(Symb); 309 NValue = Entry.n_value; 310 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 311 return object_error::parse_failed; 312 } 313 if (NValue >= StringTable.size()) 314 return object_error::parse_failed; 315 const char *Start = &StringTable.data()[NValue]; 316 Res = StringRef(Start); 317 return object_error::success; 318 } 319 320 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, 321 uint64_t &Res) const { 322 if (is64Bit()) { 323 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb); 324 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && 325 Entry.n_value == 0) 326 Res = UnknownAddressOrSize; 327 else 328 Res = Entry.n_value; 329 } else { 330 MachO::nlist Entry = getSymbolTableEntry(Symb); 331 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && 332 Entry.n_value == 0) 333 Res = UnknownAddressOrSize; 334 else 335 Res = Entry.n_value; 336 } 337 return object_error::success; 338 } 339 340 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const { 341 uint32_t flags = getSymbolFlags(DRI); 342 if (flags & SymbolRef::SF_Common) { 343 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 344 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); 345 } 346 return 0; 347 } 348 349 uint64_t MachOObjectFile::getSymbolSize(DataRefImpl DRI) const { 350 uint64_t Value; 351 getSymbolAddress(DRI, Value); 352 uint32_t flags = getSymbolFlags(DRI); 353 if (flags & SymbolRef::SF_Common) 354 return Value; 355 return UnknownAddressOrSize; 356 } 357 358 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, 359 SymbolRef::Type &Res) const { 360 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 361 uint8_t n_type = Entry.n_type; 362 363 Res = SymbolRef::ST_Other; 364 365 // If this is a STAB debugging symbol, we can do nothing more. 366 if (n_type & MachO::N_STAB) { 367 Res = SymbolRef::ST_Debug; 368 return object_error::success; 369 } 370 371 switch (n_type & MachO::N_TYPE) { 372 case MachO::N_UNDF : 373 Res = SymbolRef::ST_Unknown; 374 break; 375 case MachO::N_SECT : 376 Res = SymbolRef::ST_Function; 377 break; 378 } 379 return object_error::success; 380 } 381 382 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { 383 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 384 385 uint8_t MachOType = Entry.n_type; 386 uint16_t MachOFlags = Entry.n_desc; 387 388 uint32_t Result = SymbolRef::SF_None; 389 390 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) 391 Result |= SymbolRef::SF_Undefined; 392 393 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR) 394 Result |= SymbolRef::SF_Indirect; 395 396 if (MachOType & MachO::N_STAB) 397 Result |= SymbolRef::SF_FormatSpecific; 398 399 if (MachOType & MachO::N_EXT) { 400 Result |= SymbolRef::SF_Global; 401 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { 402 uint64_t Value; 403 getSymbolAddress(DRI, Value); 404 if (Value && Value != UnknownAddressOrSize) 405 Result |= SymbolRef::SF_Common; 406 } 407 408 if (!(MachOType & MachO::N_PEXT)) 409 Result |= SymbolRef::SF_Exported; 410 } 411 412 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 413 Result |= SymbolRef::SF_Weak; 414 415 if (MachOFlags & (MachO::N_ARM_THUMB_DEF)) 416 Result |= SymbolRef::SF_Thumb; 417 418 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) 419 Result |= SymbolRef::SF_Absolute; 420 421 return Result; 422 } 423 424 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, 425 section_iterator &Res) const { 426 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 427 uint8_t index = Entry.n_sect; 428 429 if (index == 0) { 430 Res = section_end(); 431 } else { 432 DataRefImpl DRI; 433 DRI.d.a = index - 1; 434 if (DRI.d.a >= Sections.size()) 435 report_fatal_error("getSymbolSection: Invalid section index."); 436 Res = section_iterator(SectionRef(DRI, this)); 437 } 438 439 return object_error::success; 440 } 441 442 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { 443 Sec.d.a++; 444 } 445 446 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec, 447 StringRef &Result) const { 448 ArrayRef<char> Raw = getSectionRawName(Sec); 449 Result = parseSegmentOrSectionName(Raw.data()); 450 return object_error::success; 451 } 452 453 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { 454 if (is64Bit()) 455 return getSection64(Sec).addr; 456 return getSection(Sec).addr; 457 } 458 459 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { 460 if (is64Bit()) 461 return getSection64(Sec).size; 462 return getSection(Sec).size; 463 } 464 465 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, 466 StringRef &Res) const { 467 uint32_t Offset; 468 uint64_t Size; 469 470 if (is64Bit()) { 471 MachO::section_64 Sect = getSection64(Sec); 472 Offset = Sect.offset; 473 Size = Sect.size; 474 } else { 475 MachO::section Sect = getSection(Sec); 476 Offset = Sect.offset; 477 Size = Sect.size; 478 } 479 480 Res = this->getData().substr(Offset, Size); 481 return object_error::success; 482 } 483 484 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const { 485 uint32_t Align; 486 if (is64Bit()) { 487 MachO::section_64 Sect = getSection64(Sec); 488 Align = Sect.align; 489 } else { 490 MachO::section Sect = getSection(Sec); 491 Align = Sect.align; 492 } 493 494 return uint64_t(1) << Align; 495 } 496 497 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const { 498 uint32_t Flags = getSectionFlags(this, Sec); 499 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; 500 } 501 502 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const { 503 uint32_t Flags = getSectionFlags(this, Sec); 504 unsigned SectionType = Flags & MachO::SECTION_TYPE; 505 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 506 !(SectionType == MachO::S_ZEROFILL || 507 SectionType == MachO::S_GB_ZEROFILL); 508 } 509 510 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const { 511 uint32_t Flags = getSectionFlags(this, Sec); 512 unsigned SectionType = Flags & MachO::SECTION_TYPE; 513 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 514 (SectionType == MachO::S_ZEROFILL || 515 SectionType == MachO::S_GB_ZEROFILL); 516 } 517 518 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const { 519 // FIXME: Unimplemented. 520 return false; 521 } 522 523 bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, 524 DataRefImpl Symb) const { 525 SymbolRef::Type ST; 526 this->getSymbolType(Symb, ST); 527 if (ST == SymbolRef::ST_Unknown) 528 return false; 529 530 uint64_t SectBegin = getSectionAddress(Sec); 531 uint64_t SectEnd = getSectionSize(Sec); 532 SectEnd += SectBegin; 533 534 uint64_t SymAddr; 535 getSymbolAddress(Symb, SymAddr); 536 return (SymAddr >= SectBegin) && (SymAddr < SectEnd); 537 } 538 539 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 540 DataRefImpl Ret; 541 Ret.d.a = Sec.d.a; 542 Ret.d.b = 0; 543 return relocation_iterator(RelocationRef(Ret, this)); 544 } 545 546 relocation_iterator 547 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 548 uint32_t Num; 549 if (is64Bit()) { 550 MachO::section_64 Sect = getSection64(Sec); 551 Num = Sect.nreloc; 552 } else { 553 MachO::section Sect = getSection(Sec); 554 Num = Sect.nreloc; 555 } 556 557 DataRefImpl Ret; 558 Ret.d.a = Sec.d.a; 559 Ret.d.b = Num; 560 return relocation_iterator(RelocationRef(Ret, this)); 561 } 562 563 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 564 ++Rel.d.b; 565 } 566 567 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, 568 uint64_t &Res) const { 569 uint64_t Offset; 570 getRelocationOffset(Rel, Offset); 571 572 DataRefImpl Sec; 573 Sec.d.a = Rel.d.a; 574 uint64_t SecAddress = getSectionAddress(Sec); 575 Res = SecAddress + Offset; 576 return object_error::success; 577 } 578 579 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, 580 uint64_t &Res) const { 581 assert(getHeader().filetype == MachO::MH_OBJECT && 582 "Only implemented for MH_OBJECT"); 583 MachO::any_relocation_info RE = getRelocation(Rel); 584 Res = getAnyRelocationAddress(RE); 585 return object_error::success; 586 } 587 588 symbol_iterator 589 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 590 MachO::any_relocation_info RE = getRelocation(Rel); 591 if (isRelocationScattered(RE)) 592 return symbol_end(); 593 594 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 595 bool isExtern = getPlainRelocationExternal(RE); 596 if (!isExtern) 597 return symbol_end(); 598 599 MachO::symtab_command S = getSymtabLoadCommand(); 600 unsigned SymbolTableEntrySize = is64Bit() ? 601 sizeof(MachO::nlist_64) : 602 sizeof(MachO::nlist); 603 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 604 DataRefImpl Sym; 605 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 606 return symbol_iterator(SymbolRef(Sym, this)); 607 } 608 609 section_iterator 610 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { 611 return section_iterator(getAnyRelocationSection(getRelocation(Rel))); 612 } 613 614 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, 615 uint64_t &Res) const { 616 MachO::any_relocation_info RE = getRelocation(Rel); 617 Res = getAnyRelocationType(RE); 618 return object_error::success; 619 } 620 621 std::error_code 622 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, 623 SmallVectorImpl<char> &Result) const { 624 StringRef res; 625 uint64_t RType; 626 getRelocationType(Rel, RType); 627 628 unsigned Arch = this->getArch(); 629 630 switch (Arch) { 631 case Triple::x86: { 632 static const char *const Table[] = { 633 "GENERIC_RELOC_VANILLA", 634 "GENERIC_RELOC_PAIR", 635 "GENERIC_RELOC_SECTDIFF", 636 "GENERIC_RELOC_PB_LA_PTR", 637 "GENERIC_RELOC_LOCAL_SECTDIFF", 638 "GENERIC_RELOC_TLV" }; 639 640 if (RType > 5) 641 res = "Unknown"; 642 else 643 res = Table[RType]; 644 break; 645 } 646 case Triple::x86_64: { 647 static const char *const Table[] = { 648 "X86_64_RELOC_UNSIGNED", 649 "X86_64_RELOC_SIGNED", 650 "X86_64_RELOC_BRANCH", 651 "X86_64_RELOC_GOT_LOAD", 652 "X86_64_RELOC_GOT", 653 "X86_64_RELOC_SUBTRACTOR", 654 "X86_64_RELOC_SIGNED_1", 655 "X86_64_RELOC_SIGNED_2", 656 "X86_64_RELOC_SIGNED_4", 657 "X86_64_RELOC_TLV" }; 658 659 if (RType > 9) 660 res = "Unknown"; 661 else 662 res = Table[RType]; 663 break; 664 } 665 case Triple::arm: { 666 static const char *const Table[] = { 667 "ARM_RELOC_VANILLA", 668 "ARM_RELOC_PAIR", 669 "ARM_RELOC_SECTDIFF", 670 "ARM_RELOC_LOCAL_SECTDIFF", 671 "ARM_RELOC_PB_LA_PTR", 672 "ARM_RELOC_BR24", 673 "ARM_THUMB_RELOC_BR22", 674 "ARM_THUMB_32BIT_BRANCH", 675 "ARM_RELOC_HALF", 676 "ARM_RELOC_HALF_SECTDIFF" }; 677 678 if (RType > 9) 679 res = "Unknown"; 680 else 681 res = Table[RType]; 682 break; 683 } 684 case Triple::aarch64: { 685 static const char *const Table[] = { 686 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 687 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 688 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 689 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 690 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 691 "ARM64_RELOC_ADDEND" 692 }; 693 694 if (RType >= array_lengthof(Table)) 695 res = "Unknown"; 696 else 697 res = Table[RType]; 698 break; 699 } 700 case Triple::ppc: { 701 static const char *const Table[] = { 702 "PPC_RELOC_VANILLA", 703 "PPC_RELOC_PAIR", 704 "PPC_RELOC_BR14", 705 "PPC_RELOC_BR24", 706 "PPC_RELOC_HI16", 707 "PPC_RELOC_LO16", 708 "PPC_RELOC_HA16", 709 "PPC_RELOC_LO14", 710 "PPC_RELOC_SECTDIFF", 711 "PPC_RELOC_PB_LA_PTR", 712 "PPC_RELOC_HI16_SECTDIFF", 713 "PPC_RELOC_LO16_SECTDIFF", 714 "PPC_RELOC_HA16_SECTDIFF", 715 "PPC_RELOC_JBSR", 716 "PPC_RELOC_LO14_SECTDIFF", 717 "PPC_RELOC_LOCAL_SECTDIFF" }; 718 719 if (RType > 15) 720 res = "Unknown"; 721 else 722 res = Table[RType]; 723 break; 724 } 725 case Triple::UnknownArch: 726 res = "Unknown"; 727 break; 728 } 729 Result.append(res.begin(), res.end()); 730 return object_error::success; 731 } 732 733 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, 734 bool &Result) const { 735 unsigned Arch = getArch(); 736 uint64_t Type; 737 getRelocationType(Rel, Type); 738 739 Result = false; 740 741 // On arches that use the generic relocations, GENERIC_RELOC_PAIR 742 // is always hidden. 743 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { 744 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true; 745 } else if (Arch == Triple::x86_64) { 746 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows 747 // an X86_64_RELOC_SUBTRACTOR. 748 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { 749 DataRefImpl RelPrev = Rel; 750 RelPrev.d.a--; 751 uint64_t PrevType; 752 getRelocationType(RelPrev, PrevType); 753 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) 754 Result = true; 755 } 756 } 757 758 return object_error::success; 759 } 760 761 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { 762 MachO::any_relocation_info RE = getRelocation(Rel); 763 return getAnyRelocationLength(RE); 764 } 765 766 // 767 // guessLibraryShortName() is passed a name of a dynamic library and returns a 768 // guess on what the short name is. Then name is returned as a substring of the 769 // StringRef Name passed in. The name of the dynamic library is recognized as 770 // a framework if it has one of the two following forms: 771 // Foo.framework/Versions/A/Foo 772 // Foo.framework/Foo 773 // Where A and Foo can be any string. And may contain a trailing suffix 774 // starting with an underbar. If the Name is recognized as a framework then 775 // isFramework is set to true else it is set to false. If the Name has a 776 // suffix then Suffix is set to the substring in Name that contains the suffix 777 // else it is set to a NULL StringRef. 778 // 779 // The Name of the dynamic library is recognized as a library name if it has 780 // one of the two following forms: 781 // libFoo.A.dylib 782 // libFoo.dylib 783 // The library may have a suffix trailing the name Foo of the form: 784 // libFoo_profile.A.dylib 785 // libFoo_profile.dylib 786 // 787 // The Name of the dynamic library is also recognized as a library name if it 788 // has the following form: 789 // Foo.qtx 790 // 791 // If the Name of the dynamic library is none of the forms above then a NULL 792 // StringRef is returned. 793 // 794 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 795 bool &isFramework, 796 StringRef &Suffix) { 797 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 798 size_t a, b, c, d, Idx; 799 800 isFramework = false; 801 Suffix = StringRef(); 802 803 // Pull off the last component and make Foo point to it 804 a = Name.rfind('/'); 805 if (a == Name.npos || a == 0) 806 goto guess_library; 807 Foo = Name.slice(a+1, Name.npos); 808 809 // Look for a suffix starting with a '_' 810 Idx = Foo.rfind('_'); 811 if (Idx != Foo.npos && Foo.size() >= 2) { 812 Suffix = Foo.slice(Idx, Foo.npos); 813 Foo = Foo.slice(0, Idx); 814 } 815 816 // First look for the form Foo.framework/Foo 817 b = Name.rfind('/', a); 818 if (b == Name.npos) 819 Idx = 0; 820 else 821 Idx = b+1; 822 F = Name.slice(Idx, Idx + Foo.size()); 823 DotFramework = Name.slice(Idx + Foo.size(), 824 Idx + Foo.size() + sizeof(".framework/")-1); 825 if (F == Foo && DotFramework == ".framework/") { 826 isFramework = true; 827 return Foo; 828 } 829 830 // Next look for the form Foo.framework/Versions/A/Foo 831 if (b == Name.npos) 832 goto guess_library; 833 c = Name.rfind('/', b); 834 if (c == Name.npos || c == 0) 835 goto guess_library; 836 V = Name.slice(c+1, Name.npos); 837 if (!V.startswith("Versions/")) 838 goto guess_library; 839 d = Name.rfind('/', c); 840 if (d == Name.npos) 841 Idx = 0; 842 else 843 Idx = d+1; 844 F = Name.slice(Idx, Idx + Foo.size()); 845 DotFramework = Name.slice(Idx + Foo.size(), 846 Idx + Foo.size() + sizeof(".framework/")-1); 847 if (F == Foo && DotFramework == ".framework/") { 848 isFramework = true; 849 return Foo; 850 } 851 852 guess_library: 853 // pull off the suffix after the "." and make a point to it 854 a = Name.rfind('.'); 855 if (a == Name.npos || a == 0) 856 return StringRef(); 857 Dylib = Name.slice(a, Name.npos); 858 if (Dylib != ".dylib") 859 goto guess_qtx; 860 861 // First pull off the version letter for the form Foo.A.dylib if any. 862 if (a >= 3) { 863 Dot = Name.slice(a-2, a-1); 864 if (Dot == ".") 865 a = a - 2; 866 } 867 868 b = Name.rfind('/', a); 869 if (b == Name.npos) 870 b = 0; 871 else 872 b = b+1; 873 // ignore any suffix after an underbar like Foo_profile.A.dylib 874 Idx = Name.find('_', b); 875 if (Idx != Name.npos && Idx != b) { 876 Lib = Name.slice(b, Idx); 877 Suffix = Name.slice(Idx, a); 878 } 879 else 880 Lib = Name.slice(b, a); 881 // There are incorrect library names of the form: 882 // libATS.A_profile.dylib so check for these. 883 if (Lib.size() >= 3) { 884 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 885 if (Dot == ".") 886 Lib = Lib.slice(0, Lib.size()-2); 887 } 888 return Lib; 889 890 guess_qtx: 891 Qtx = Name.slice(a, Name.npos); 892 if (Qtx != ".qtx") 893 return StringRef(); 894 b = Name.rfind('/', a); 895 if (b == Name.npos) 896 Lib = Name.slice(0, a); 897 else 898 Lib = Name.slice(b+1, a); 899 // There are library names of the form: QT.A.qtx so check for these. 900 if (Lib.size() >= 3) { 901 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 902 if (Dot == ".") 903 Lib = Lib.slice(0, Lib.size()-2); 904 } 905 return Lib; 906 } 907 908 // getLibraryShortNameByIndex() is used to get the short name of the library 909 // for an undefined symbol in a linked Mach-O binary that was linked with the 910 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 911 // It is passed the index (0 - based) of the library as translated from 912 // GET_LIBRARY_ORDINAL (1 - based). 913 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 914 StringRef &Res) const { 915 if (Index >= Libraries.size()) 916 return object_error::parse_failed; 917 918 // If the cache of LibrariesShortNames is not built up do that first for 919 // all the Libraries. 920 if (LibrariesShortNames.size() == 0) { 921 for (unsigned i = 0; i < Libraries.size(); i++) { 922 MachO::dylib_command D = 923 getStruct<MachO::dylib_command>(this, Libraries[i]); 924 if (D.dylib.name >= D.cmdsize) 925 return object_error::parse_failed; 926 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 927 StringRef Name = StringRef(P); 928 if (D.dylib.name+Name.size() >= D.cmdsize) 929 return object_error::parse_failed; 930 StringRef Suffix; 931 bool isFramework; 932 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 933 if (shortName.empty()) 934 LibrariesShortNames.push_back(Name); 935 else 936 LibrariesShortNames.push_back(shortName); 937 } 938 } 939 940 Res = LibrariesShortNames[Index]; 941 return object_error::success; 942 } 943 944 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { 945 return getSymbolByIndex(0); 946 } 947 948 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { 949 DataRefImpl DRI; 950 if (!SymtabLoadCmd) 951 return basic_symbol_iterator(SymbolRef(DRI, this)); 952 953 MachO::symtab_command Symtab = getSymtabLoadCommand(); 954 unsigned SymbolTableEntrySize = is64Bit() ? 955 sizeof(MachO::nlist_64) : 956 sizeof(MachO::nlist); 957 unsigned Offset = Symtab.symoff + 958 Symtab.nsyms * SymbolTableEntrySize; 959 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 960 return basic_symbol_iterator(SymbolRef(DRI, this)); 961 } 962 963 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 964 DataRefImpl DRI; 965 if (!SymtabLoadCmd) 966 return basic_symbol_iterator(SymbolRef(DRI, this)); 967 968 MachO::symtab_command Symtab = getSymtabLoadCommand(); 969 if (Index >= Symtab.nsyms) 970 report_fatal_error("Requested symbol index is out of range."); 971 unsigned SymbolTableEntrySize = 972 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 973 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); 974 DRI.p += Index * SymbolTableEntrySize; 975 return basic_symbol_iterator(SymbolRef(DRI, this)); 976 } 977 978 section_iterator MachOObjectFile::section_begin() const { 979 DataRefImpl DRI; 980 return section_iterator(SectionRef(DRI, this)); 981 } 982 983 section_iterator MachOObjectFile::section_end() const { 984 DataRefImpl DRI; 985 DRI.d.a = Sections.size(); 986 return section_iterator(SectionRef(DRI, this)); 987 } 988 989 uint8_t MachOObjectFile::getBytesInAddress() const { 990 return is64Bit() ? 8 : 4; 991 } 992 993 StringRef MachOObjectFile::getFileFormatName() const { 994 unsigned CPUType = getCPUType(this); 995 if (!is64Bit()) { 996 switch (CPUType) { 997 case llvm::MachO::CPU_TYPE_I386: 998 return "Mach-O 32-bit i386"; 999 case llvm::MachO::CPU_TYPE_ARM: 1000 return "Mach-O arm"; 1001 case llvm::MachO::CPU_TYPE_POWERPC: 1002 return "Mach-O 32-bit ppc"; 1003 default: 1004 return "Mach-O 32-bit unknown"; 1005 } 1006 } 1007 1008 switch (CPUType) { 1009 case llvm::MachO::CPU_TYPE_X86_64: 1010 return "Mach-O 64-bit x86-64"; 1011 case llvm::MachO::CPU_TYPE_ARM64: 1012 return "Mach-O arm64"; 1013 case llvm::MachO::CPU_TYPE_POWERPC64: 1014 return "Mach-O 64-bit ppc64"; 1015 default: 1016 return "Mach-O 64-bit unknown"; 1017 } 1018 } 1019 1020 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 1021 switch (CPUType) { 1022 case llvm::MachO::CPU_TYPE_I386: 1023 return Triple::x86; 1024 case llvm::MachO::CPU_TYPE_X86_64: 1025 return Triple::x86_64; 1026 case llvm::MachO::CPU_TYPE_ARM: 1027 return Triple::arm; 1028 case llvm::MachO::CPU_TYPE_ARM64: 1029 return Triple::aarch64; 1030 case llvm::MachO::CPU_TYPE_POWERPC: 1031 return Triple::ppc; 1032 case llvm::MachO::CPU_TYPE_POWERPC64: 1033 return Triple::ppc64; 1034 default: 1035 return Triple::UnknownArch; 1036 } 1037 } 1038 1039 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1040 const char **McpuDefault) { 1041 if (McpuDefault) 1042 *McpuDefault = nullptr; 1043 1044 switch (CPUType) { 1045 case MachO::CPU_TYPE_I386: 1046 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1047 case MachO::CPU_SUBTYPE_I386_ALL: 1048 return Triple("i386-apple-darwin"); 1049 default: 1050 return Triple(); 1051 } 1052 case MachO::CPU_TYPE_X86_64: 1053 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1054 case MachO::CPU_SUBTYPE_X86_64_ALL: 1055 return Triple("x86_64-apple-darwin"); 1056 case MachO::CPU_SUBTYPE_X86_64_H: 1057 return Triple("x86_64h-apple-darwin"); 1058 default: 1059 return Triple(); 1060 } 1061 case MachO::CPU_TYPE_ARM: 1062 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1063 case MachO::CPU_SUBTYPE_ARM_V4T: 1064 return Triple("armv4t-apple-darwin"); 1065 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1066 return Triple("armv5e-apple-darwin"); 1067 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1068 return Triple("xscale-apple-darwin"); 1069 case MachO::CPU_SUBTYPE_ARM_V6: 1070 return Triple("armv6-apple-darwin"); 1071 case MachO::CPU_SUBTYPE_ARM_V6M: 1072 if (McpuDefault) 1073 *McpuDefault = "cortex-m0"; 1074 return Triple("armv6m-apple-darwin"); 1075 case MachO::CPU_SUBTYPE_ARM_V7: 1076 return Triple("armv7-apple-darwin"); 1077 case MachO::CPU_SUBTYPE_ARM_V7EM: 1078 if (McpuDefault) 1079 *McpuDefault = "cortex-m4"; 1080 return Triple("armv7em-apple-darwin"); 1081 case MachO::CPU_SUBTYPE_ARM_V7K: 1082 return Triple("armv7k-apple-darwin"); 1083 case MachO::CPU_SUBTYPE_ARM_V7M: 1084 if (McpuDefault) 1085 *McpuDefault = "cortex-m3"; 1086 return Triple("armv7m-apple-darwin"); 1087 case MachO::CPU_SUBTYPE_ARM_V7S: 1088 return Triple("armv7s-apple-darwin"); 1089 default: 1090 return Triple(); 1091 } 1092 case MachO::CPU_TYPE_ARM64: 1093 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1094 case MachO::CPU_SUBTYPE_ARM64_ALL: 1095 return Triple("arm64-apple-darwin"); 1096 default: 1097 return Triple(); 1098 } 1099 case MachO::CPU_TYPE_POWERPC: 1100 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1101 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1102 return Triple("ppc-apple-darwin"); 1103 default: 1104 return Triple(); 1105 } 1106 case MachO::CPU_TYPE_POWERPC64: 1107 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1108 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1109 return Triple("ppc64-apple-darwin"); 1110 default: 1111 return Triple(); 1112 } 1113 default: 1114 return Triple(); 1115 } 1116 } 1117 1118 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType, 1119 const char **McpuDefault) { 1120 if (McpuDefault) 1121 *McpuDefault = nullptr; 1122 1123 switch (CPUType) { 1124 case MachO::CPU_TYPE_ARM: 1125 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1126 case MachO::CPU_SUBTYPE_ARM_V4T: 1127 return Triple("thumbv4t-apple-darwin"); 1128 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1129 return Triple("thumbv5e-apple-darwin"); 1130 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1131 return Triple("xscale-apple-darwin"); 1132 case MachO::CPU_SUBTYPE_ARM_V6: 1133 return Triple("thumbv6-apple-darwin"); 1134 case MachO::CPU_SUBTYPE_ARM_V6M: 1135 if (McpuDefault) 1136 *McpuDefault = "cortex-m0"; 1137 return Triple("thumbv6m-apple-darwin"); 1138 case MachO::CPU_SUBTYPE_ARM_V7: 1139 return Triple("thumbv7-apple-darwin"); 1140 case MachO::CPU_SUBTYPE_ARM_V7EM: 1141 if (McpuDefault) 1142 *McpuDefault = "cortex-m4"; 1143 return Triple("thumbv7em-apple-darwin"); 1144 case MachO::CPU_SUBTYPE_ARM_V7K: 1145 return Triple("thumbv7k-apple-darwin"); 1146 case MachO::CPU_SUBTYPE_ARM_V7M: 1147 if (McpuDefault) 1148 *McpuDefault = "cortex-m3"; 1149 return Triple("thumbv7m-apple-darwin"); 1150 case MachO::CPU_SUBTYPE_ARM_V7S: 1151 return Triple("thumbv7s-apple-darwin"); 1152 default: 1153 return Triple(); 1154 } 1155 default: 1156 return Triple(); 1157 } 1158 } 1159 1160 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1161 const char **McpuDefault, 1162 Triple *ThumbTriple) { 1163 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault); 1164 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType, 1165 McpuDefault); 1166 return T; 1167 } 1168 1169 Triple MachOObjectFile::getHostArch() { 1170 return Triple(sys::getDefaultTargetTriple()); 1171 } 1172 1173 bool MachOObjectFile::isValidArch(StringRef ArchFlag) { 1174 return StringSwitch<bool>(ArchFlag) 1175 .Case("i386", true) 1176 .Case("x86_64", true) 1177 .Case("x86_64h", true) 1178 .Case("armv4t", true) 1179 .Case("arm", true) 1180 .Case("armv5e", true) 1181 .Case("armv6", true) 1182 .Case("armv6m", true) 1183 .Case("armv7em", true) 1184 .Case("armv7k", true) 1185 .Case("armv7m", true) 1186 .Case("armv7s", true) 1187 .Case("arm64", true) 1188 .Case("ppc", true) 1189 .Case("ppc64", true) 1190 .Default(false); 1191 } 1192 1193 unsigned MachOObjectFile::getArch() const { 1194 return getArch(getCPUType(this)); 1195 } 1196 1197 Triple MachOObjectFile::getArch(const char **McpuDefault, 1198 Triple *ThumbTriple) const { 1199 Triple T; 1200 if (is64Bit()) { 1201 MachO::mach_header_64 H_64; 1202 H_64 = getHeader64(); 1203 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault); 1204 *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype, 1205 McpuDefault); 1206 } else { 1207 MachO::mach_header H; 1208 H = getHeader(); 1209 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault); 1210 *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype, 1211 McpuDefault); 1212 } 1213 return T; 1214 } 1215 1216 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 1217 DataRefImpl DRI; 1218 DRI.d.a = Index; 1219 return section_rel_begin(DRI); 1220 } 1221 1222 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 1223 DataRefImpl DRI; 1224 DRI.d.a = Index; 1225 return section_rel_end(DRI); 1226 } 1227 1228 dice_iterator MachOObjectFile::begin_dices() const { 1229 DataRefImpl DRI; 1230 if (!DataInCodeLoadCmd) 1231 return dice_iterator(DiceRef(DRI, this)); 1232 1233 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1234 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff)); 1235 return dice_iterator(DiceRef(DRI, this)); 1236 } 1237 1238 dice_iterator MachOObjectFile::end_dices() const { 1239 DataRefImpl DRI; 1240 if (!DataInCodeLoadCmd) 1241 return dice_iterator(DiceRef(DRI, this)); 1242 1243 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1244 unsigned Offset = DicLC.dataoff + DicLC.datasize; 1245 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1246 return dice_iterator(DiceRef(DRI, this)); 1247 } 1248 1249 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 1250 : Trie(T), Malformed(false), Done(false) { } 1251 1252 void ExportEntry::moveToFirst() { 1253 pushNode(0); 1254 pushDownUntilBottom(); 1255 } 1256 1257 void ExportEntry::moveToEnd() { 1258 Stack.clear(); 1259 Done = true; 1260 } 1261 1262 bool ExportEntry::operator==(const ExportEntry &Other) const { 1263 // Common case, one at end, other iterating from begin. 1264 if (Done || Other.Done) 1265 return (Done == Other.Done); 1266 // Not equal if different stack sizes. 1267 if (Stack.size() != Other.Stack.size()) 1268 return false; 1269 // Not equal if different cumulative strings. 1270 if (!CumulativeString.equals(Other.CumulativeString)) 1271 return false; 1272 // Equal if all nodes in both stacks match. 1273 for (unsigned i=0; i < Stack.size(); ++i) { 1274 if (Stack[i].Start != Other.Stack[i].Start) 1275 return false; 1276 } 1277 return true; 1278 } 1279 1280 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { 1281 unsigned Count; 1282 uint64_t Result = decodeULEB128(Ptr, &Count); 1283 Ptr += Count; 1284 if (Ptr > Trie.end()) { 1285 Ptr = Trie.end(); 1286 Malformed = true; 1287 } 1288 return Result; 1289 } 1290 1291 StringRef ExportEntry::name() const { 1292 return CumulativeString; 1293 } 1294 1295 uint64_t ExportEntry::flags() const { 1296 return Stack.back().Flags; 1297 } 1298 1299 uint64_t ExportEntry::address() const { 1300 return Stack.back().Address; 1301 } 1302 1303 uint64_t ExportEntry::other() const { 1304 return Stack.back().Other; 1305 } 1306 1307 StringRef ExportEntry::otherName() const { 1308 const char* ImportName = Stack.back().ImportName; 1309 if (ImportName) 1310 return StringRef(ImportName); 1311 return StringRef(); 1312 } 1313 1314 uint32_t ExportEntry::nodeOffset() const { 1315 return Stack.back().Start - Trie.begin(); 1316 } 1317 1318 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 1319 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 1320 ImportName(nullptr), ChildCount(0), NextChildIndex(0), 1321 ParentStringLength(0), IsExportNode(false) { 1322 } 1323 1324 void ExportEntry::pushNode(uint64_t offset) { 1325 const uint8_t *Ptr = Trie.begin() + offset; 1326 NodeState State(Ptr); 1327 uint64_t ExportInfoSize = readULEB128(State.Current); 1328 State.IsExportNode = (ExportInfoSize != 0); 1329 const uint8_t* Children = State.Current + ExportInfoSize; 1330 if (State.IsExportNode) { 1331 State.Flags = readULEB128(State.Current); 1332 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 1333 State.Address = 0; 1334 State.Other = readULEB128(State.Current); // dylib ordinal 1335 State.ImportName = reinterpret_cast<const char*>(State.Current); 1336 } else { 1337 State.Address = readULEB128(State.Current); 1338 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) 1339 State.Other = readULEB128(State.Current); 1340 } 1341 } 1342 State.ChildCount = *Children; 1343 State.Current = Children + 1; 1344 State.NextChildIndex = 0; 1345 State.ParentStringLength = CumulativeString.size(); 1346 Stack.push_back(State); 1347 } 1348 1349 void ExportEntry::pushDownUntilBottom() { 1350 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 1351 NodeState &Top = Stack.back(); 1352 CumulativeString.resize(Top.ParentStringLength); 1353 for (;*Top.Current != 0; Top.Current++) { 1354 char C = *Top.Current; 1355 CumulativeString.push_back(C); 1356 } 1357 Top.Current += 1; 1358 uint64_t childNodeIndex = readULEB128(Top.Current); 1359 Top.NextChildIndex += 1; 1360 pushNode(childNodeIndex); 1361 } 1362 if (!Stack.back().IsExportNode) { 1363 Malformed = true; 1364 moveToEnd(); 1365 } 1366 } 1367 1368 // We have a trie data structure and need a way to walk it that is compatible 1369 // with the C++ iterator model. The solution is a non-recursive depth first 1370 // traversal where the iterator contains a stack of parent nodes along with a 1371 // string that is the accumulation of all edge strings along the parent chain 1372 // to this point. 1373 // 1374 // There is one "export" node for each exported symbol. But because some 1375 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 1376 // node may have child nodes too. 1377 // 1378 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 1379 // child until hitting a node with no children (which is an export node or 1380 // else the trie is malformed). On the way down, each node is pushed on the 1381 // stack ivar. If there is no more ways down, it pops up one and tries to go 1382 // down a sibling path until a childless node is reached. 1383 void ExportEntry::moveNext() { 1384 if (Stack.empty() || !Stack.back().IsExportNode) { 1385 Malformed = true; 1386 moveToEnd(); 1387 return; 1388 } 1389 1390 Stack.pop_back(); 1391 while (!Stack.empty()) { 1392 NodeState &Top = Stack.back(); 1393 if (Top.NextChildIndex < Top.ChildCount) { 1394 pushDownUntilBottom(); 1395 // Now at the next export node. 1396 return; 1397 } else { 1398 if (Top.IsExportNode) { 1399 // This node has no children but is itself an export node. 1400 CumulativeString.resize(Top.ParentStringLength); 1401 return; 1402 } 1403 Stack.pop_back(); 1404 } 1405 } 1406 Done = true; 1407 } 1408 1409 iterator_range<export_iterator> 1410 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { 1411 ExportEntry Start(Trie); 1412 if (Trie.size() == 0) 1413 Start.moveToEnd(); 1414 else 1415 Start.moveToFirst(); 1416 1417 ExportEntry Finish(Trie); 1418 Finish.moveToEnd(); 1419 1420 return iterator_range<export_iterator>(export_iterator(Start), 1421 export_iterator(Finish)); 1422 } 1423 1424 iterator_range<export_iterator> MachOObjectFile::exports() const { 1425 return exports(getDyldInfoExportsTrie()); 1426 } 1427 1428 1429 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit) 1430 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1431 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0), 1432 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {} 1433 1434 void MachORebaseEntry::moveToFirst() { 1435 Ptr = Opcodes.begin(); 1436 moveNext(); 1437 } 1438 1439 void MachORebaseEntry::moveToEnd() { 1440 Ptr = Opcodes.end(); 1441 RemainingLoopCount = 0; 1442 Done = true; 1443 } 1444 1445 void MachORebaseEntry::moveNext() { 1446 // If in the middle of some loop, move to next rebasing in loop. 1447 SegmentOffset += AdvanceAmount; 1448 if (RemainingLoopCount) { 1449 --RemainingLoopCount; 1450 return; 1451 } 1452 if (Ptr == Opcodes.end()) { 1453 Done = true; 1454 return; 1455 } 1456 bool More = true; 1457 while (More && !Malformed) { 1458 // Parse next opcode and set up next loop. 1459 uint8_t Byte = *Ptr++; 1460 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 1461 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 1462 switch (Opcode) { 1463 case MachO::REBASE_OPCODE_DONE: 1464 More = false; 1465 Done = true; 1466 moveToEnd(); 1467 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n"); 1468 break; 1469 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 1470 RebaseType = ImmValue; 1471 DEBUG_WITH_TYPE( 1472 "mach-o-rebase", 1473 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 1474 << "RebaseType=" << (int) RebaseType << "\n"); 1475 break; 1476 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1477 SegmentIndex = ImmValue; 1478 SegmentOffset = readULEB128(); 1479 DEBUG_WITH_TYPE( 1480 "mach-o-rebase", 1481 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1482 << "SegmentIndex=" << SegmentIndex << ", " 1483 << format("SegmentOffset=0x%06X", SegmentOffset) 1484 << "\n"); 1485 break; 1486 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 1487 SegmentOffset += readULEB128(); 1488 DEBUG_WITH_TYPE("mach-o-rebase", 1489 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 1490 << format("SegmentOffset=0x%06X", 1491 SegmentOffset) << "\n"); 1492 break; 1493 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 1494 SegmentOffset += ImmValue * PointerSize; 1495 DEBUG_WITH_TYPE("mach-o-rebase", 1496 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 1497 << format("SegmentOffset=0x%06X", 1498 SegmentOffset) << "\n"); 1499 break; 1500 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 1501 AdvanceAmount = PointerSize; 1502 RemainingLoopCount = ImmValue - 1; 1503 DEBUG_WITH_TYPE( 1504 "mach-o-rebase", 1505 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 1506 << format("SegmentOffset=0x%06X", SegmentOffset) 1507 << ", AdvanceAmount=" << AdvanceAmount 1508 << ", RemainingLoopCount=" << RemainingLoopCount 1509 << "\n"); 1510 return; 1511 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 1512 AdvanceAmount = PointerSize; 1513 RemainingLoopCount = readULEB128() - 1; 1514 DEBUG_WITH_TYPE( 1515 "mach-o-rebase", 1516 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 1517 << format("SegmentOffset=0x%06X", SegmentOffset) 1518 << ", AdvanceAmount=" << AdvanceAmount 1519 << ", RemainingLoopCount=" << RemainingLoopCount 1520 << "\n"); 1521 return; 1522 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 1523 AdvanceAmount = readULEB128() + PointerSize; 1524 RemainingLoopCount = 0; 1525 DEBUG_WITH_TYPE( 1526 "mach-o-rebase", 1527 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 1528 << format("SegmentOffset=0x%06X", SegmentOffset) 1529 << ", AdvanceAmount=" << AdvanceAmount 1530 << ", RemainingLoopCount=" << RemainingLoopCount 1531 << "\n"); 1532 return; 1533 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 1534 RemainingLoopCount = readULEB128() - 1; 1535 AdvanceAmount = readULEB128() + PointerSize; 1536 DEBUG_WITH_TYPE( 1537 "mach-o-rebase", 1538 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 1539 << format("SegmentOffset=0x%06X", SegmentOffset) 1540 << ", AdvanceAmount=" << AdvanceAmount 1541 << ", RemainingLoopCount=" << RemainingLoopCount 1542 << "\n"); 1543 return; 1544 default: 1545 Malformed = true; 1546 } 1547 } 1548 } 1549 1550 uint64_t MachORebaseEntry::readULEB128() { 1551 unsigned Count; 1552 uint64_t Result = decodeULEB128(Ptr, &Count); 1553 Ptr += Count; 1554 if (Ptr > Opcodes.end()) { 1555 Ptr = Opcodes.end(); 1556 Malformed = true; 1557 } 1558 return Result; 1559 } 1560 1561 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 1562 1563 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 1564 1565 StringRef MachORebaseEntry::typeName() const { 1566 switch (RebaseType) { 1567 case MachO::REBASE_TYPE_POINTER: 1568 return "pointer"; 1569 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 1570 return "text abs32"; 1571 case MachO::REBASE_TYPE_TEXT_PCREL32: 1572 return "text rel32"; 1573 } 1574 return "unknown"; 1575 } 1576 1577 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 1578 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1579 return (Ptr == Other.Ptr) && 1580 (RemainingLoopCount == Other.RemainingLoopCount) && 1581 (Done == Other.Done); 1582 } 1583 1584 iterator_range<rebase_iterator> 1585 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) { 1586 MachORebaseEntry Start(Opcodes, is64); 1587 Start.moveToFirst(); 1588 1589 MachORebaseEntry Finish(Opcodes, is64); 1590 Finish.moveToEnd(); 1591 1592 return iterator_range<rebase_iterator>(rebase_iterator(Start), 1593 rebase_iterator(Finish)); 1594 } 1595 1596 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const { 1597 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit()); 1598 } 1599 1600 1601 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, 1602 Kind BK) 1603 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1604 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0), 1605 BindType(0), PointerSize(is64Bit ? 8 : 4), 1606 TableKind(BK), Malformed(false), Done(false) {} 1607 1608 void MachOBindEntry::moveToFirst() { 1609 Ptr = Opcodes.begin(); 1610 moveNext(); 1611 } 1612 1613 void MachOBindEntry::moveToEnd() { 1614 Ptr = Opcodes.end(); 1615 RemainingLoopCount = 0; 1616 Done = true; 1617 } 1618 1619 void MachOBindEntry::moveNext() { 1620 // If in the middle of some loop, move to next binding in loop. 1621 SegmentOffset += AdvanceAmount; 1622 if (RemainingLoopCount) { 1623 --RemainingLoopCount; 1624 return; 1625 } 1626 if (Ptr == Opcodes.end()) { 1627 Done = true; 1628 return; 1629 } 1630 bool More = true; 1631 while (More && !Malformed) { 1632 // Parse next opcode and set up next loop. 1633 uint8_t Byte = *Ptr++; 1634 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK; 1635 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK; 1636 int8_t SignExtended; 1637 const uint8_t *SymStart; 1638 switch (Opcode) { 1639 case MachO::BIND_OPCODE_DONE: 1640 if (TableKind == Kind::Lazy) { 1641 // Lazying bindings have a DONE opcode between entries. Need to ignore 1642 // it to advance to next entry. But need not if this is last entry. 1643 bool NotLastEntry = false; 1644 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) { 1645 if (*P) { 1646 NotLastEntry = true; 1647 } 1648 } 1649 if (NotLastEntry) 1650 break; 1651 } 1652 More = false; 1653 Done = true; 1654 moveToEnd(); 1655 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n"); 1656 break; 1657 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 1658 Ordinal = ImmValue; 1659 DEBUG_WITH_TYPE( 1660 "mach-o-bind", 1661 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 1662 << "Ordinal=" << Ordinal << "\n"); 1663 break; 1664 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 1665 Ordinal = readULEB128(); 1666 DEBUG_WITH_TYPE( 1667 "mach-o-bind", 1668 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 1669 << "Ordinal=" << Ordinal << "\n"); 1670 break; 1671 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 1672 if (ImmValue) { 1673 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue; 1674 Ordinal = SignExtended; 1675 } else 1676 Ordinal = 0; 1677 DEBUG_WITH_TYPE( 1678 "mach-o-bind", 1679 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 1680 << "Ordinal=" << Ordinal << "\n"); 1681 break; 1682 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 1683 Flags = ImmValue; 1684 SymStart = Ptr; 1685 while (*Ptr) { 1686 ++Ptr; 1687 } 1688 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart), 1689 Ptr-SymStart); 1690 ++Ptr; 1691 DEBUG_WITH_TYPE( 1692 "mach-o-bind", 1693 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 1694 << "SymbolName=" << SymbolName << "\n"); 1695 if (TableKind == Kind::Weak) { 1696 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) 1697 return; 1698 } 1699 break; 1700 case MachO::BIND_OPCODE_SET_TYPE_IMM: 1701 BindType = ImmValue; 1702 DEBUG_WITH_TYPE( 1703 "mach-o-bind", 1704 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: " 1705 << "BindType=" << (int)BindType << "\n"); 1706 break; 1707 case MachO::BIND_OPCODE_SET_ADDEND_SLEB: 1708 Addend = readSLEB128(); 1709 if (TableKind == Kind::Lazy) 1710 Malformed = true; 1711 DEBUG_WITH_TYPE( 1712 "mach-o-bind", 1713 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: " 1714 << "Addend=" << Addend << "\n"); 1715 break; 1716 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1717 SegmentIndex = ImmValue; 1718 SegmentOffset = readULEB128(); 1719 DEBUG_WITH_TYPE( 1720 "mach-o-bind", 1721 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1722 << "SegmentIndex=" << SegmentIndex << ", " 1723 << format("SegmentOffset=0x%06X", SegmentOffset) 1724 << "\n"); 1725 break; 1726 case MachO::BIND_OPCODE_ADD_ADDR_ULEB: 1727 SegmentOffset += readULEB128(); 1728 DEBUG_WITH_TYPE("mach-o-bind", 1729 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: " 1730 << format("SegmentOffset=0x%06X", 1731 SegmentOffset) << "\n"); 1732 break; 1733 case MachO::BIND_OPCODE_DO_BIND: 1734 AdvanceAmount = PointerSize; 1735 RemainingLoopCount = 0; 1736 DEBUG_WITH_TYPE("mach-o-bind", 1737 llvm::dbgs() << "BIND_OPCODE_DO_BIND: " 1738 << format("SegmentOffset=0x%06X", 1739 SegmentOffset) << "\n"); 1740 return; 1741 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 1742 AdvanceAmount = readULEB128() + PointerSize; 1743 RemainingLoopCount = 0; 1744 if (TableKind == Kind::Lazy) 1745 Malformed = true; 1746 DEBUG_WITH_TYPE( 1747 "mach-o-bind", 1748 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 1749 << format("SegmentOffset=0x%06X", SegmentOffset) 1750 << ", AdvanceAmount=" << AdvanceAmount 1751 << ", RemainingLoopCount=" << RemainingLoopCount 1752 << "\n"); 1753 return; 1754 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 1755 AdvanceAmount = ImmValue * PointerSize + PointerSize; 1756 RemainingLoopCount = 0; 1757 if (TableKind == Kind::Lazy) 1758 Malformed = true; 1759 DEBUG_WITH_TYPE("mach-o-bind", 1760 llvm::dbgs() 1761 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 1762 << format("SegmentOffset=0x%06X", 1763 SegmentOffset) << "\n"); 1764 return; 1765 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 1766 RemainingLoopCount = readULEB128() - 1; 1767 AdvanceAmount = readULEB128() + PointerSize; 1768 if (TableKind == Kind::Lazy) 1769 Malformed = true; 1770 DEBUG_WITH_TYPE( 1771 "mach-o-bind", 1772 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 1773 << format("SegmentOffset=0x%06X", SegmentOffset) 1774 << ", AdvanceAmount=" << AdvanceAmount 1775 << ", RemainingLoopCount=" << RemainingLoopCount 1776 << "\n"); 1777 return; 1778 default: 1779 Malformed = true; 1780 } 1781 } 1782 } 1783 1784 uint64_t MachOBindEntry::readULEB128() { 1785 unsigned Count; 1786 uint64_t Result = decodeULEB128(Ptr, &Count); 1787 Ptr += Count; 1788 if (Ptr > Opcodes.end()) { 1789 Ptr = Opcodes.end(); 1790 Malformed = true; 1791 } 1792 return Result; 1793 } 1794 1795 int64_t MachOBindEntry::readSLEB128() { 1796 unsigned Count; 1797 int64_t Result = decodeSLEB128(Ptr, &Count); 1798 Ptr += Count; 1799 if (Ptr > Opcodes.end()) { 1800 Ptr = Opcodes.end(); 1801 Malformed = true; 1802 } 1803 return Result; 1804 } 1805 1806 1807 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; } 1808 1809 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; } 1810 1811 StringRef MachOBindEntry::typeName() const { 1812 switch (BindType) { 1813 case MachO::BIND_TYPE_POINTER: 1814 return "pointer"; 1815 case MachO::BIND_TYPE_TEXT_ABSOLUTE32: 1816 return "text abs32"; 1817 case MachO::BIND_TYPE_TEXT_PCREL32: 1818 return "text rel32"; 1819 } 1820 return "unknown"; 1821 } 1822 1823 StringRef MachOBindEntry::symbolName() const { return SymbolName; } 1824 1825 int64_t MachOBindEntry::addend() const { return Addend; } 1826 1827 uint32_t MachOBindEntry::flags() const { return Flags; } 1828 1829 int MachOBindEntry::ordinal() const { return Ordinal; } 1830 1831 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const { 1832 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1833 return (Ptr == Other.Ptr) && 1834 (RemainingLoopCount == Other.RemainingLoopCount) && 1835 (Done == Other.Done); 1836 } 1837 1838 iterator_range<bind_iterator> 1839 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64, 1840 MachOBindEntry::Kind BKind) { 1841 MachOBindEntry Start(Opcodes, is64, BKind); 1842 Start.moveToFirst(); 1843 1844 MachOBindEntry Finish(Opcodes, is64, BKind); 1845 Finish.moveToEnd(); 1846 1847 return iterator_range<bind_iterator>(bind_iterator(Start), 1848 bind_iterator(Finish)); 1849 } 1850 1851 iterator_range<bind_iterator> MachOObjectFile::bindTable() const { 1852 return bindTable(getDyldInfoBindOpcodes(), is64Bit(), 1853 MachOBindEntry::Kind::Regular); 1854 } 1855 1856 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const { 1857 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(), 1858 MachOBindEntry::Kind::Lazy); 1859 } 1860 1861 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const { 1862 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(), 1863 MachOBindEntry::Kind::Weak); 1864 } 1865 1866 StringRef 1867 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 1868 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 1869 return parseSegmentOrSectionName(Raw.data()); 1870 } 1871 1872 ArrayRef<char> 1873 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 1874 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1875 const section_base *Base = 1876 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1877 return makeArrayRef(Base->sectname); 1878 } 1879 1880 ArrayRef<char> 1881 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 1882 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1883 const section_base *Base = 1884 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1885 return makeArrayRef(Base->segname); 1886 } 1887 1888 bool 1889 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 1890 const { 1891 if (getCPUType(this) == MachO::CPU_TYPE_X86_64) 1892 return false; 1893 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 1894 } 1895 1896 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 1897 const MachO::any_relocation_info &RE) const { 1898 if (isLittleEndian()) 1899 return RE.r_word1 & 0xffffff; 1900 return RE.r_word1 >> 8; 1901 } 1902 1903 bool MachOObjectFile::getPlainRelocationExternal( 1904 const MachO::any_relocation_info &RE) const { 1905 if (isLittleEndian()) 1906 return (RE.r_word1 >> 27) & 1; 1907 return (RE.r_word1 >> 4) & 1; 1908 } 1909 1910 bool MachOObjectFile::getScatteredRelocationScattered( 1911 const MachO::any_relocation_info &RE) const { 1912 return RE.r_word0 >> 31; 1913 } 1914 1915 uint32_t MachOObjectFile::getScatteredRelocationValue( 1916 const MachO::any_relocation_info &RE) const { 1917 return RE.r_word1; 1918 } 1919 1920 uint32_t MachOObjectFile::getScatteredRelocationType( 1921 const MachO::any_relocation_info &RE) const { 1922 return (RE.r_word0 >> 24) & 0xf; 1923 } 1924 1925 unsigned MachOObjectFile::getAnyRelocationAddress( 1926 const MachO::any_relocation_info &RE) const { 1927 if (isRelocationScattered(RE)) 1928 return getScatteredRelocationAddress(RE); 1929 return getPlainRelocationAddress(RE); 1930 } 1931 1932 unsigned MachOObjectFile::getAnyRelocationPCRel( 1933 const MachO::any_relocation_info &RE) const { 1934 if (isRelocationScattered(RE)) 1935 return getScatteredRelocationPCRel(this, RE); 1936 return getPlainRelocationPCRel(this, RE); 1937 } 1938 1939 unsigned MachOObjectFile::getAnyRelocationLength( 1940 const MachO::any_relocation_info &RE) const { 1941 if (isRelocationScattered(RE)) 1942 return getScatteredRelocationLength(RE); 1943 return getPlainRelocationLength(this, RE); 1944 } 1945 1946 unsigned 1947 MachOObjectFile::getAnyRelocationType( 1948 const MachO::any_relocation_info &RE) const { 1949 if (isRelocationScattered(RE)) 1950 return getScatteredRelocationType(RE); 1951 return getPlainRelocationType(this, RE); 1952 } 1953 1954 SectionRef 1955 MachOObjectFile::getAnyRelocationSection( 1956 const MachO::any_relocation_info &RE) const { 1957 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 1958 return *section_end(); 1959 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; 1960 DataRefImpl DRI; 1961 DRI.d.a = SecNum; 1962 return SectionRef(DRI, this); 1963 } 1964 1965 MachOObjectFile::LoadCommandInfo 1966 MachOObjectFile::getFirstLoadCommandInfo() const { 1967 MachOObjectFile::LoadCommandInfo Load; 1968 1969 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) : 1970 sizeof(MachO::mach_header); 1971 Load.Ptr = getPtr(this, HeaderSize); 1972 Load.C = getStruct<MachO::load_command>(this, Load.Ptr); 1973 if (Load.C.cmdsize < 8) 1974 report_fatal_error("Load command with size < 8 bytes."); 1975 return Load; 1976 } 1977 1978 MachOObjectFile::LoadCommandInfo 1979 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const { 1980 MachOObjectFile::LoadCommandInfo Next; 1981 Next.Ptr = L.Ptr + L.C.cmdsize; 1982 Next.C = getStruct<MachO::load_command>(this, Next.Ptr); 1983 if (Next.C.cmdsize < 8) 1984 report_fatal_error("Load command with size < 8 bytes."); 1985 return Next; 1986 } 1987 1988 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 1989 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 1990 return getStruct<MachO::section>(this, Sections[DRI.d.a]); 1991 } 1992 1993 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 1994 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 1995 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]); 1996 } 1997 1998 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 1999 unsigned Index) const { 2000 const char *Sec = getSectionPtr(this, L, Index); 2001 return getStruct<MachO::section>(this, Sec); 2002 } 2003 2004 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 2005 unsigned Index) const { 2006 const char *Sec = getSectionPtr(this, L, Index); 2007 return getStruct<MachO::section_64>(this, Sec); 2008 } 2009 2010 MachO::nlist 2011 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 2012 const char *P = reinterpret_cast<const char *>(DRI.p); 2013 return getStruct<MachO::nlist>(this, P); 2014 } 2015 2016 MachO::nlist_64 2017 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 2018 const char *P = reinterpret_cast<const char *>(DRI.p); 2019 return getStruct<MachO::nlist_64>(this, P); 2020 } 2021 2022 MachO::linkedit_data_command 2023 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 2024 return getStruct<MachO::linkedit_data_command>(this, L.Ptr); 2025 } 2026 2027 MachO::segment_command 2028 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 2029 return getStruct<MachO::segment_command>(this, L.Ptr); 2030 } 2031 2032 MachO::segment_command_64 2033 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 2034 return getStruct<MachO::segment_command_64>(this, L.Ptr); 2035 } 2036 2037 MachO::linker_option_command 2038 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const { 2039 return getStruct<MachO::linker_option_command>(this, L.Ptr); 2040 } 2041 2042 MachO::version_min_command 2043 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 2044 return getStruct<MachO::version_min_command>(this, L.Ptr); 2045 } 2046 2047 MachO::dylib_command 2048 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 2049 return getStruct<MachO::dylib_command>(this, L.Ptr); 2050 } 2051 2052 MachO::dyld_info_command 2053 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const { 2054 return getStruct<MachO::dyld_info_command>(this, L.Ptr); 2055 } 2056 2057 MachO::dylinker_command 2058 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const { 2059 return getStruct<MachO::dylinker_command>(this, L.Ptr); 2060 } 2061 2062 MachO::uuid_command 2063 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const { 2064 return getStruct<MachO::uuid_command>(this, L.Ptr); 2065 } 2066 2067 MachO::rpath_command 2068 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const { 2069 return getStruct<MachO::rpath_command>(this, L.Ptr); 2070 } 2071 2072 MachO::source_version_command 2073 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const { 2074 return getStruct<MachO::source_version_command>(this, L.Ptr); 2075 } 2076 2077 MachO::entry_point_command 2078 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const { 2079 return getStruct<MachO::entry_point_command>(this, L.Ptr); 2080 } 2081 2082 MachO::encryption_info_command 2083 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const { 2084 return getStruct<MachO::encryption_info_command>(this, L.Ptr); 2085 } 2086 2087 MachO::encryption_info_command_64 2088 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const { 2089 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr); 2090 } 2091 2092 MachO::sub_framework_command 2093 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const { 2094 return getStruct<MachO::sub_framework_command>(this, L.Ptr); 2095 } 2096 2097 MachO::sub_umbrella_command 2098 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const { 2099 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr); 2100 } 2101 2102 MachO::sub_library_command 2103 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const { 2104 return getStruct<MachO::sub_library_command>(this, L.Ptr); 2105 } 2106 2107 MachO::sub_client_command 2108 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const { 2109 return getStruct<MachO::sub_client_command>(this, L.Ptr); 2110 } 2111 2112 MachO::routines_command 2113 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const { 2114 return getStruct<MachO::routines_command>(this, L.Ptr); 2115 } 2116 2117 MachO::routines_command_64 2118 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const { 2119 return getStruct<MachO::routines_command_64>(this, L.Ptr); 2120 } 2121 2122 MachO::thread_command 2123 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { 2124 return getStruct<MachO::thread_command>(this, L.Ptr); 2125 } 2126 2127 MachO::any_relocation_info 2128 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 2129 DataRefImpl Sec; 2130 Sec.d.a = Rel.d.a; 2131 uint32_t Offset; 2132 if (is64Bit()) { 2133 MachO::section_64 Sect = getSection64(Sec); 2134 Offset = Sect.reloff; 2135 } else { 2136 MachO::section Sect = getSection(Sec); 2137 Offset = Sect.reloff; 2138 } 2139 2140 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 2141 getPtr(this, Offset)) + Rel.d.b; 2142 return getStruct<MachO::any_relocation_info>( 2143 this, reinterpret_cast<const char *>(P)); 2144 } 2145 2146 MachO::data_in_code_entry 2147 MachOObjectFile::getDice(DataRefImpl Rel) const { 2148 const char *P = reinterpret_cast<const char *>(Rel.p); 2149 return getStruct<MachO::data_in_code_entry>(this, P); 2150 } 2151 2152 MachO::mach_header MachOObjectFile::getHeader() const { 2153 return getStruct<MachO::mach_header>(this, getPtr(this, 0)); 2154 } 2155 2156 MachO::mach_header_64 MachOObjectFile::getHeader64() const { 2157 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0)); 2158 } 2159 2160 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 2161 const MachO::dysymtab_command &DLC, 2162 unsigned Index) const { 2163 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 2164 return getStruct<uint32_t>(this, getPtr(this, Offset)); 2165 } 2166 2167 MachO::data_in_code_entry 2168 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 2169 unsigned Index) const { 2170 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 2171 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset)); 2172 } 2173 2174 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 2175 if (SymtabLoadCmd) 2176 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd); 2177 2178 // If there is no SymtabLoadCmd return a load command with zero'ed fields. 2179 MachO::symtab_command Cmd; 2180 Cmd.cmd = MachO::LC_SYMTAB; 2181 Cmd.cmdsize = sizeof(MachO::symtab_command); 2182 Cmd.symoff = 0; 2183 Cmd.nsyms = 0; 2184 Cmd.stroff = 0; 2185 Cmd.strsize = 0; 2186 return Cmd; 2187 } 2188 2189 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 2190 if (DysymtabLoadCmd) 2191 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd); 2192 2193 // If there is no DysymtabLoadCmd return a load command with zero'ed fields. 2194 MachO::dysymtab_command Cmd; 2195 Cmd.cmd = MachO::LC_DYSYMTAB; 2196 Cmd.cmdsize = sizeof(MachO::dysymtab_command); 2197 Cmd.ilocalsym = 0; 2198 Cmd.nlocalsym = 0; 2199 Cmd.iextdefsym = 0; 2200 Cmd.nextdefsym = 0; 2201 Cmd.iundefsym = 0; 2202 Cmd.nundefsym = 0; 2203 Cmd.tocoff = 0; 2204 Cmd.ntoc = 0; 2205 Cmd.modtaboff = 0; 2206 Cmd.nmodtab = 0; 2207 Cmd.extrefsymoff = 0; 2208 Cmd.nextrefsyms = 0; 2209 Cmd.indirectsymoff = 0; 2210 Cmd.nindirectsyms = 0; 2211 Cmd.extreloff = 0; 2212 Cmd.nextrel = 0; 2213 Cmd.locreloff = 0; 2214 Cmd.nlocrel = 0; 2215 return Cmd; 2216 } 2217 2218 MachO::linkedit_data_command 2219 MachOObjectFile::getDataInCodeLoadCommand() const { 2220 if (DataInCodeLoadCmd) 2221 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd); 2222 2223 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 2224 MachO::linkedit_data_command Cmd; 2225 Cmd.cmd = MachO::LC_DATA_IN_CODE; 2226 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2227 Cmd.dataoff = 0; 2228 Cmd.datasize = 0; 2229 return Cmd; 2230 } 2231 2232 MachO::linkedit_data_command 2233 MachOObjectFile::getLinkOptHintsLoadCommand() const { 2234 if (LinkOptHintsLoadCmd) 2235 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd); 2236 2237 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed 2238 // fields. 2239 MachO::linkedit_data_command Cmd; 2240 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; 2241 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2242 Cmd.dataoff = 0; 2243 Cmd.datasize = 0; 2244 return Cmd; 2245 } 2246 2247 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { 2248 if (!DyldInfoLoadCmd) 2249 return ArrayRef<uint8_t>(); 2250 2251 MachO::dyld_info_command DyldInfo 2252 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2253 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2254 getPtr(this, DyldInfo.rebase_off)); 2255 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size); 2256 } 2257 2258 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 2259 if (!DyldInfoLoadCmd) 2260 return ArrayRef<uint8_t>(); 2261 2262 MachO::dyld_info_command DyldInfo 2263 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2264 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2265 getPtr(this, DyldInfo.bind_off)); 2266 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size); 2267 } 2268 2269 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 2270 if (!DyldInfoLoadCmd) 2271 return ArrayRef<uint8_t>(); 2272 2273 MachO::dyld_info_command DyldInfo 2274 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2275 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2276 getPtr(this, DyldInfo.weak_bind_off)); 2277 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size); 2278 } 2279 2280 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 2281 if (!DyldInfoLoadCmd) 2282 return ArrayRef<uint8_t>(); 2283 2284 MachO::dyld_info_command DyldInfo 2285 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2286 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2287 getPtr(this, DyldInfo.lazy_bind_off)); 2288 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size); 2289 } 2290 2291 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 2292 if (!DyldInfoLoadCmd) 2293 return ArrayRef<uint8_t>(); 2294 2295 MachO::dyld_info_command DyldInfo 2296 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2297 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2298 getPtr(this, DyldInfo.export_off)); 2299 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size); 2300 } 2301 2302 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 2303 if (!UuidLoadCmd) 2304 return ArrayRef<uint8_t>(); 2305 // Returning a pointer is fine as uuid doesn't need endian swapping. 2306 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); 2307 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16); 2308 } 2309 2310 StringRef MachOObjectFile::getStringTableData() const { 2311 MachO::symtab_command S = getSymtabLoadCommand(); 2312 return getData().substr(S.stroff, S.strsize); 2313 } 2314 2315 bool MachOObjectFile::is64Bit() const { 2316 return getType() == getMachOType(false, true) || 2317 getType() == getMachOType(true, true); 2318 } 2319 2320 void MachOObjectFile::ReadULEB128s(uint64_t Index, 2321 SmallVectorImpl<uint64_t> &Out) const { 2322 DataExtractor extractor(ObjectFile::getData(), true, 0); 2323 2324 uint32_t offset = Index; 2325 uint64_t data = 0; 2326 while (uint64_t delta = extractor.getULEB128(&offset)) { 2327 data += delta; 2328 Out.push_back(data); 2329 } 2330 } 2331 2332 bool MachOObjectFile::isRelocatableObject() const { 2333 return getHeader().filetype == MachO::MH_OBJECT; 2334 } 2335 2336 ErrorOr<std::unique_ptr<MachOObjectFile>> 2337 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) { 2338 StringRef Magic = Buffer.getBuffer().slice(0, 4); 2339 std::error_code EC; 2340 std::unique_ptr<MachOObjectFile> Ret; 2341 if (Magic == "\xFE\xED\xFA\xCE") 2342 Ret.reset(new MachOObjectFile(Buffer, false, false, EC)); 2343 else if (Magic == "\xCE\xFA\xED\xFE") 2344 Ret.reset(new MachOObjectFile(Buffer, true, false, EC)); 2345 else if (Magic == "\xFE\xED\xFA\xCF") 2346 Ret.reset(new MachOObjectFile(Buffer, false, true, EC)); 2347 else if (Magic == "\xCF\xFA\xED\xFE") 2348 Ret.reset(new MachOObjectFile(Buffer, true, true, EC)); 2349 else 2350 return object_error::parse_failed; 2351 2352 if (EC) 2353 return EC; 2354 return std::move(Ret); 2355 } 2356 2357