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