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::getSymbolValueImpl(DataRefImpl Sym) const { 372 return getNValue(Sym); 373 } 374 375 ErrorOr<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const { 376 return getSymbolValue(Sym); 377 } 378 379 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const { 380 uint32_t flags = getSymbolFlags(DRI); 381 if (flags & SymbolRef::SF_Common) { 382 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 383 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); 384 } 385 return 0; 386 } 387 388 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const { 389 return getNValue(DRI); 390 } 391 392 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const { 393 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 394 uint8_t n_type = Entry.n_type; 395 396 // If this is a STAB debugging symbol, we can do nothing more. 397 if (n_type & MachO::N_STAB) 398 return SymbolRef::ST_Debug; 399 400 switch (n_type & MachO::N_TYPE) { 401 case MachO::N_UNDF : 402 return SymbolRef::ST_Unknown; 403 case MachO::N_SECT : 404 return SymbolRef::ST_Function; 405 } 406 return SymbolRef::ST_Other; 407 } 408 409 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { 410 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 411 412 uint8_t MachOType = Entry.n_type; 413 uint16_t MachOFlags = Entry.n_desc; 414 415 uint32_t Result = SymbolRef::SF_None; 416 417 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR) 418 Result |= SymbolRef::SF_Indirect; 419 420 if (MachOType & MachO::N_STAB) 421 Result |= SymbolRef::SF_FormatSpecific; 422 423 if (MachOType & MachO::N_EXT) { 424 Result |= SymbolRef::SF_Global; 425 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { 426 if (getNValue(DRI)) 427 Result |= SymbolRef::SF_Common; 428 else 429 Result |= SymbolRef::SF_Undefined; 430 } 431 432 if (!(MachOType & MachO::N_PEXT)) 433 Result |= SymbolRef::SF_Exported; 434 } 435 436 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 437 Result |= SymbolRef::SF_Weak; 438 439 if (MachOFlags & (MachO::N_ARM_THUMB_DEF)) 440 Result |= SymbolRef::SF_Thumb; 441 442 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) 443 Result |= SymbolRef::SF_Absolute; 444 445 return Result; 446 } 447 448 ErrorOr<section_iterator> 449 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const { 450 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 451 uint8_t index = Entry.n_sect; 452 453 if (index == 0) 454 return section_end(); 455 DataRefImpl DRI; 456 DRI.d.a = index - 1; 457 if (DRI.d.a >= Sections.size()) 458 report_fatal_error("getSymbolSection: Invalid section index."); 459 return section_iterator(SectionRef(DRI, this)); 460 } 461 462 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const { 463 MachO::nlist_base Entry = 464 getSymbolTableEntryBase(this, Sym.getRawDataRefImpl()); 465 return Entry.n_sect - 1; 466 } 467 468 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { 469 Sec.d.a++; 470 } 471 472 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec, 473 StringRef &Result) const { 474 ArrayRef<char> Raw = getSectionRawName(Sec); 475 Result = parseSegmentOrSectionName(Raw.data()); 476 return std::error_code(); 477 } 478 479 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { 480 if (is64Bit()) 481 return getSection64(Sec).addr; 482 return getSection(Sec).addr; 483 } 484 485 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { 486 // In the case if a malformed Mach-O file where the section offset is past 487 // the end of the file or some part of the section size is past the end of 488 // the file return a size of zero or a size that covers the rest of the file 489 // but does not extend past the end of the file. 490 uint32_t SectOffset, SectType; 491 uint64_t SectSize; 492 493 if (is64Bit()) { 494 MachO::section_64 Sect = getSection64(Sec); 495 SectOffset = Sect.offset; 496 SectSize = Sect.size; 497 SectType = Sect.flags & MachO::SECTION_TYPE; 498 } else { 499 MachO::section Sect = getSection(Sec); 500 SectOffset = Sect.offset; 501 SectSize = Sect.size; 502 SectType = Sect.flags & MachO::SECTION_TYPE; 503 } 504 if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL) 505 return SectSize; 506 uint64_t FileSize = getData().size(); 507 if (SectOffset > FileSize) 508 return 0; 509 if (FileSize - SectOffset < SectSize) 510 return FileSize - SectOffset; 511 return SectSize; 512 } 513 514 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, 515 StringRef &Res) const { 516 uint32_t Offset; 517 uint64_t Size; 518 519 if (is64Bit()) { 520 MachO::section_64 Sect = getSection64(Sec); 521 Offset = Sect.offset; 522 Size = Sect.size; 523 } else { 524 MachO::section Sect = getSection(Sec); 525 Offset = Sect.offset; 526 Size = Sect.size; 527 } 528 529 Res = this->getData().substr(Offset, Size); 530 return std::error_code(); 531 } 532 533 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const { 534 uint32_t Align; 535 if (is64Bit()) { 536 MachO::section_64 Sect = getSection64(Sec); 537 Align = Sect.align; 538 } else { 539 MachO::section Sect = getSection(Sec); 540 Align = Sect.align; 541 } 542 543 return uint64_t(1) << Align; 544 } 545 546 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const { 547 uint32_t Flags = getSectionFlags(this, Sec); 548 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; 549 } 550 551 bool MachOObjectFile::isSectionData(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 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const { 560 uint32_t Flags = getSectionFlags(this, Sec); 561 unsigned SectionType = Flags & MachO::SECTION_TYPE; 562 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 563 (SectionType == MachO::S_ZEROFILL || 564 SectionType == MachO::S_GB_ZEROFILL); 565 } 566 567 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const { 568 return Sec.getRawDataRefImpl().d.a; 569 } 570 571 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const { 572 // FIXME: Unimplemented. 573 return false; 574 } 575 576 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 577 DataRefImpl Ret; 578 Ret.d.a = Sec.d.a; 579 Ret.d.b = 0; 580 return relocation_iterator(RelocationRef(Ret, this)); 581 } 582 583 relocation_iterator 584 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 585 uint32_t Num; 586 if (is64Bit()) { 587 MachO::section_64 Sect = getSection64(Sec); 588 Num = Sect.nreloc; 589 } else { 590 MachO::section Sect = getSection(Sec); 591 Num = Sect.nreloc; 592 } 593 594 DataRefImpl Ret; 595 Ret.d.a = Sec.d.a; 596 Ret.d.b = Num; 597 return relocation_iterator(RelocationRef(Ret, this)); 598 } 599 600 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 601 ++Rel.d.b; 602 } 603 604 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const { 605 assert(getHeader().filetype == MachO::MH_OBJECT && 606 "Only implemented for MH_OBJECT"); 607 MachO::any_relocation_info RE = getRelocation(Rel); 608 return getAnyRelocationAddress(RE); 609 } 610 611 symbol_iterator 612 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 613 MachO::any_relocation_info RE = getRelocation(Rel); 614 if (isRelocationScattered(RE)) 615 return symbol_end(); 616 617 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 618 bool isExtern = getPlainRelocationExternal(RE); 619 if (!isExtern) 620 return symbol_end(); 621 622 MachO::symtab_command S = getSymtabLoadCommand(); 623 unsigned SymbolTableEntrySize = is64Bit() ? 624 sizeof(MachO::nlist_64) : 625 sizeof(MachO::nlist); 626 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 627 DataRefImpl Sym; 628 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 629 return symbol_iterator(SymbolRef(Sym, this)); 630 } 631 632 section_iterator 633 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { 634 return section_iterator(getAnyRelocationSection(getRelocation(Rel))); 635 } 636 637 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const { 638 MachO::any_relocation_info RE = getRelocation(Rel); 639 return getAnyRelocationType(RE); 640 } 641 642 void MachOObjectFile::getRelocationTypeName( 643 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 644 StringRef res; 645 uint64_t RType = getRelocationType(Rel); 646 647 unsigned Arch = this->getArch(); 648 649 switch (Arch) { 650 case Triple::x86: { 651 static const char *const Table[] = { 652 "GENERIC_RELOC_VANILLA", 653 "GENERIC_RELOC_PAIR", 654 "GENERIC_RELOC_SECTDIFF", 655 "GENERIC_RELOC_PB_LA_PTR", 656 "GENERIC_RELOC_LOCAL_SECTDIFF", 657 "GENERIC_RELOC_TLV" }; 658 659 if (RType > 5) 660 res = "Unknown"; 661 else 662 res = Table[RType]; 663 break; 664 } 665 case Triple::x86_64: { 666 static const char *const Table[] = { 667 "X86_64_RELOC_UNSIGNED", 668 "X86_64_RELOC_SIGNED", 669 "X86_64_RELOC_BRANCH", 670 "X86_64_RELOC_GOT_LOAD", 671 "X86_64_RELOC_GOT", 672 "X86_64_RELOC_SUBTRACTOR", 673 "X86_64_RELOC_SIGNED_1", 674 "X86_64_RELOC_SIGNED_2", 675 "X86_64_RELOC_SIGNED_4", 676 "X86_64_RELOC_TLV" }; 677 678 if (RType > 9) 679 res = "Unknown"; 680 else 681 res = Table[RType]; 682 break; 683 } 684 case Triple::arm: { 685 static const char *const Table[] = { 686 "ARM_RELOC_VANILLA", 687 "ARM_RELOC_PAIR", 688 "ARM_RELOC_SECTDIFF", 689 "ARM_RELOC_LOCAL_SECTDIFF", 690 "ARM_RELOC_PB_LA_PTR", 691 "ARM_RELOC_BR24", 692 "ARM_THUMB_RELOC_BR22", 693 "ARM_THUMB_32BIT_BRANCH", 694 "ARM_RELOC_HALF", 695 "ARM_RELOC_HALF_SECTDIFF" }; 696 697 if (RType > 9) 698 res = "Unknown"; 699 else 700 res = Table[RType]; 701 break; 702 } 703 case Triple::aarch64: { 704 static const char *const Table[] = { 705 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 706 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 707 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 708 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 709 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 710 "ARM64_RELOC_ADDEND" 711 }; 712 713 if (RType >= array_lengthof(Table)) 714 res = "Unknown"; 715 else 716 res = Table[RType]; 717 break; 718 } 719 case Triple::ppc: { 720 static const char *const Table[] = { 721 "PPC_RELOC_VANILLA", 722 "PPC_RELOC_PAIR", 723 "PPC_RELOC_BR14", 724 "PPC_RELOC_BR24", 725 "PPC_RELOC_HI16", 726 "PPC_RELOC_LO16", 727 "PPC_RELOC_HA16", 728 "PPC_RELOC_LO14", 729 "PPC_RELOC_SECTDIFF", 730 "PPC_RELOC_PB_LA_PTR", 731 "PPC_RELOC_HI16_SECTDIFF", 732 "PPC_RELOC_LO16_SECTDIFF", 733 "PPC_RELOC_HA16_SECTDIFF", 734 "PPC_RELOC_JBSR", 735 "PPC_RELOC_LO14_SECTDIFF", 736 "PPC_RELOC_LOCAL_SECTDIFF" }; 737 738 if (RType > 15) 739 res = "Unknown"; 740 else 741 res = Table[RType]; 742 break; 743 } 744 case Triple::UnknownArch: 745 res = "Unknown"; 746 break; 747 } 748 Result.append(res.begin(), res.end()); 749 } 750 751 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { 752 MachO::any_relocation_info RE = getRelocation(Rel); 753 return getAnyRelocationLength(RE); 754 } 755 756 // 757 // guessLibraryShortName() is passed a name of a dynamic library and returns a 758 // guess on what the short name is. Then name is returned as a substring of the 759 // StringRef Name passed in. The name of the dynamic library is recognized as 760 // a framework if it has one of the two following forms: 761 // Foo.framework/Versions/A/Foo 762 // Foo.framework/Foo 763 // Where A and Foo can be any string. And may contain a trailing suffix 764 // starting with an underbar. If the Name is recognized as a framework then 765 // isFramework is set to true else it is set to false. If the Name has a 766 // suffix then Suffix is set to the substring in Name that contains the suffix 767 // else it is set to a NULL StringRef. 768 // 769 // The Name of the dynamic library is recognized as a library name if it has 770 // one of the two following forms: 771 // libFoo.A.dylib 772 // libFoo.dylib 773 // The library may have a suffix trailing the name Foo of the form: 774 // libFoo_profile.A.dylib 775 // libFoo_profile.dylib 776 // 777 // The Name of the dynamic library is also recognized as a library name if it 778 // has the following form: 779 // Foo.qtx 780 // 781 // If the Name of the dynamic library is none of the forms above then a NULL 782 // StringRef is returned. 783 // 784 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 785 bool &isFramework, 786 StringRef &Suffix) { 787 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 788 size_t a, b, c, d, Idx; 789 790 isFramework = false; 791 Suffix = StringRef(); 792 793 // Pull off the last component and make Foo point to it 794 a = Name.rfind('/'); 795 if (a == Name.npos || a == 0) 796 goto guess_library; 797 Foo = Name.slice(a+1, Name.npos); 798 799 // Look for a suffix starting with a '_' 800 Idx = Foo.rfind('_'); 801 if (Idx != Foo.npos && Foo.size() >= 2) { 802 Suffix = Foo.slice(Idx, Foo.npos); 803 Foo = Foo.slice(0, Idx); 804 } 805 806 // First look for the form Foo.framework/Foo 807 b = Name.rfind('/', a); 808 if (b == Name.npos) 809 Idx = 0; 810 else 811 Idx = b+1; 812 F = Name.slice(Idx, Idx + Foo.size()); 813 DotFramework = Name.slice(Idx + Foo.size(), 814 Idx + Foo.size() + sizeof(".framework/")-1); 815 if (F == Foo && DotFramework == ".framework/") { 816 isFramework = true; 817 return Foo; 818 } 819 820 // Next look for the form Foo.framework/Versions/A/Foo 821 if (b == Name.npos) 822 goto guess_library; 823 c = Name.rfind('/', b); 824 if (c == Name.npos || c == 0) 825 goto guess_library; 826 V = Name.slice(c+1, Name.npos); 827 if (!V.startswith("Versions/")) 828 goto guess_library; 829 d = Name.rfind('/', c); 830 if (d == Name.npos) 831 Idx = 0; 832 else 833 Idx = d+1; 834 F = Name.slice(Idx, Idx + Foo.size()); 835 DotFramework = Name.slice(Idx + Foo.size(), 836 Idx + Foo.size() + sizeof(".framework/")-1); 837 if (F == Foo && DotFramework == ".framework/") { 838 isFramework = true; 839 return Foo; 840 } 841 842 guess_library: 843 // pull off the suffix after the "." and make a point to it 844 a = Name.rfind('.'); 845 if (a == Name.npos || a == 0) 846 return StringRef(); 847 Dylib = Name.slice(a, Name.npos); 848 if (Dylib != ".dylib") 849 goto guess_qtx; 850 851 // First pull off the version letter for the form Foo.A.dylib if any. 852 if (a >= 3) { 853 Dot = Name.slice(a-2, a-1); 854 if (Dot == ".") 855 a = a - 2; 856 } 857 858 b = Name.rfind('/', a); 859 if (b == Name.npos) 860 b = 0; 861 else 862 b = b+1; 863 // ignore any suffix after an underbar like Foo_profile.A.dylib 864 Idx = Name.find('_', b); 865 if (Idx != Name.npos && Idx != b) { 866 Lib = Name.slice(b, Idx); 867 Suffix = Name.slice(Idx, a); 868 } 869 else 870 Lib = Name.slice(b, a); 871 // There are incorrect library names of the form: 872 // libATS.A_profile.dylib so check for these. 873 if (Lib.size() >= 3) { 874 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 875 if (Dot == ".") 876 Lib = Lib.slice(0, Lib.size()-2); 877 } 878 return Lib; 879 880 guess_qtx: 881 Qtx = Name.slice(a, Name.npos); 882 if (Qtx != ".qtx") 883 return StringRef(); 884 b = Name.rfind('/', a); 885 if (b == Name.npos) 886 Lib = Name.slice(0, a); 887 else 888 Lib = Name.slice(b+1, a); 889 // There are library names of the form: QT.A.qtx so check for these. 890 if (Lib.size() >= 3) { 891 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 892 if (Dot == ".") 893 Lib = Lib.slice(0, Lib.size()-2); 894 } 895 return Lib; 896 } 897 898 // getLibraryShortNameByIndex() is used to get the short name of the library 899 // for an undefined symbol in a linked Mach-O binary that was linked with the 900 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 901 // It is passed the index (0 - based) of the library as translated from 902 // GET_LIBRARY_ORDINAL (1 - based). 903 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 904 StringRef &Res) const { 905 if (Index >= Libraries.size()) 906 return object_error::parse_failed; 907 908 // If the cache of LibrariesShortNames is not built up do that first for 909 // all the Libraries. 910 if (LibrariesShortNames.size() == 0) { 911 for (unsigned i = 0; i < Libraries.size(); i++) { 912 MachO::dylib_command D = 913 getStruct<MachO::dylib_command>(this, Libraries[i]); 914 if (D.dylib.name >= D.cmdsize) 915 return object_error::parse_failed; 916 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 917 StringRef Name = StringRef(P); 918 if (D.dylib.name+Name.size() >= D.cmdsize) 919 return object_error::parse_failed; 920 StringRef Suffix; 921 bool isFramework; 922 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 923 if (shortName.empty()) 924 LibrariesShortNames.push_back(Name); 925 else 926 LibrariesShortNames.push_back(shortName); 927 } 928 } 929 930 Res = LibrariesShortNames[Index]; 931 return std::error_code(); 932 } 933 934 section_iterator 935 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const { 936 DataRefImpl Sec; 937 Sec.d.a = Rel->getRawDataRefImpl().d.a; 938 return section_iterator(SectionRef(Sec, this)); 939 } 940 941 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { 942 return getSymbolByIndex(0); 943 } 944 945 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { 946 DataRefImpl DRI; 947 if (!SymtabLoadCmd) 948 return basic_symbol_iterator(SymbolRef(DRI, this)); 949 950 MachO::symtab_command Symtab = getSymtabLoadCommand(); 951 unsigned SymbolTableEntrySize = is64Bit() ? 952 sizeof(MachO::nlist_64) : 953 sizeof(MachO::nlist); 954 unsigned Offset = Symtab.symoff + 955 Symtab.nsyms * SymbolTableEntrySize; 956 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 957 return basic_symbol_iterator(SymbolRef(DRI, this)); 958 } 959 960 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 961 DataRefImpl DRI; 962 if (!SymtabLoadCmd) 963 return basic_symbol_iterator(SymbolRef(DRI, this)); 964 965 MachO::symtab_command Symtab = getSymtabLoadCommand(); 966 if (Index >= Symtab.nsyms) 967 report_fatal_error("Requested symbol index is out of range."); 968 unsigned SymbolTableEntrySize = 969 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 970 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); 971 DRI.p += Index * SymbolTableEntrySize; 972 return basic_symbol_iterator(SymbolRef(DRI, this)); 973 } 974 975 section_iterator MachOObjectFile::section_begin() const { 976 DataRefImpl DRI; 977 return section_iterator(SectionRef(DRI, this)); 978 } 979 980 section_iterator MachOObjectFile::section_end() const { 981 DataRefImpl DRI; 982 DRI.d.a = Sections.size(); 983 return section_iterator(SectionRef(DRI, this)); 984 } 985 986 uint8_t MachOObjectFile::getBytesInAddress() const { 987 return is64Bit() ? 8 : 4; 988 } 989 990 StringRef MachOObjectFile::getFileFormatName() const { 991 unsigned CPUType = getCPUType(this); 992 if (!is64Bit()) { 993 switch (CPUType) { 994 case llvm::MachO::CPU_TYPE_I386: 995 return "Mach-O 32-bit i386"; 996 case llvm::MachO::CPU_TYPE_ARM: 997 return "Mach-O arm"; 998 case llvm::MachO::CPU_TYPE_POWERPC: 999 return "Mach-O 32-bit ppc"; 1000 default: 1001 return "Mach-O 32-bit unknown"; 1002 } 1003 } 1004 1005 switch (CPUType) { 1006 case llvm::MachO::CPU_TYPE_X86_64: 1007 return "Mach-O 64-bit x86-64"; 1008 case llvm::MachO::CPU_TYPE_ARM64: 1009 return "Mach-O arm64"; 1010 case llvm::MachO::CPU_TYPE_POWERPC64: 1011 return "Mach-O 64-bit ppc64"; 1012 default: 1013 return "Mach-O 64-bit unknown"; 1014 } 1015 } 1016 1017 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 1018 switch (CPUType) { 1019 case llvm::MachO::CPU_TYPE_I386: 1020 return Triple::x86; 1021 case llvm::MachO::CPU_TYPE_X86_64: 1022 return Triple::x86_64; 1023 case llvm::MachO::CPU_TYPE_ARM: 1024 return Triple::arm; 1025 case llvm::MachO::CPU_TYPE_ARM64: 1026 return Triple::aarch64; 1027 case llvm::MachO::CPU_TYPE_POWERPC: 1028 return Triple::ppc; 1029 case llvm::MachO::CPU_TYPE_POWERPC64: 1030 return Triple::ppc64; 1031 default: 1032 return Triple::UnknownArch; 1033 } 1034 } 1035 1036 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1037 const char **McpuDefault) { 1038 if (McpuDefault) 1039 *McpuDefault = nullptr; 1040 1041 switch (CPUType) { 1042 case MachO::CPU_TYPE_I386: 1043 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1044 case MachO::CPU_SUBTYPE_I386_ALL: 1045 return Triple("i386-apple-darwin"); 1046 default: 1047 return Triple(); 1048 } 1049 case MachO::CPU_TYPE_X86_64: 1050 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1051 case MachO::CPU_SUBTYPE_X86_64_ALL: 1052 return Triple("x86_64-apple-darwin"); 1053 case MachO::CPU_SUBTYPE_X86_64_H: 1054 return Triple("x86_64h-apple-darwin"); 1055 default: 1056 return Triple(); 1057 } 1058 case MachO::CPU_TYPE_ARM: 1059 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1060 case MachO::CPU_SUBTYPE_ARM_V4T: 1061 return Triple("armv4t-apple-darwin"); 1062 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1063 return Triple("armv5e-apple-darwin"); 1064 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1065 return Triple("xscale-apple-darwin"); 1066 case MachO::CPU_SUBTYPE_ARM_V6: 1067 return Triple("armv6-apple-darwin"); 1068 case MachO::CPU_SUBTYPE_ARM_V6M: 1069 if (McpuDefault) 1070 *McpuDefault = "cortex-m0"; 1071 return Triple("armv6m-apple-darwin"); 1072 case MachO::CPU_SUBTYPE_ARM_V7: 1073 return Triple("armv7-apple-darwin"); 1074 case MachO::CPU_SUBTYPE_ARM_V7EM: 1075 if (McpuDefault) 1076 *McpuDefault = "cortex-m4"; 1077 return Triple("armv7em-apple-darwin"); 1078 case MachO::CPU_SUBTYPE_ARM_V7K: 1079 return Triple("armv7k-apple-darwin"); 1080 case MachO::CPU_SUBTYPE_ARM_V7M: 1081 if (McpuDefault) 1082 *McpuDefault = "cortex-m3"; 1083 return Triple("armv7m-apple-darwin"); 1084 case MachO::CPU_SUBTYPE_ARM_V7S: 1085 return Triple("armv7s-apple-darwin"); 1086 default: 1087 return Triple(); 1088 } 1089 case MachO::CPU_TYPE_ARM64: 1090 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1091 case MachO::CPU_SUBTYPE_ARM64_ALL: 1092 return Triple("arm64-apple-darwin"); 1093 default: 1094 return Triple(); 1095 } 1096 case MachO::CPU_TYPE_POWERPC: 1097 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1098 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1099 return Triple("ppc-apple-darwin"); 1100 default: 1101 return Triple(); 1102 } 1103 case MachO::CPU_TYPE_POWERPC64: 1104 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1105 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1106 return Triple("ppc64-apple-darwin"); 1107 default: 1108 return Triple(); 1109 } 1110 default: 1111 return Triple(); 1112 } 1113 } 1114 1115 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType, 1116 const char **McpuDefault) { 1117 if (McpuDefault) 1118 *McpuDefault = nullptr; 1119 1120 switch (CPUType) { 1121 case MachO::CPU_TYPE_ARM: 1122 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1123 case MachO::CPU_SUBTYPE_ARM_V4T: 1124 return Triple("thumbv4t-apple-darwin"); 1125 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1126 return Triple("thumbv5e-apple-darwin"); 1127 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1128 return Triple("xscale-apple-darwin"); 1129 case MachO::CPU_SUBTYPE_ARM_V6: 1130 return Triple("thumbv6-apple-darwin"); 1131 case MachO::CPU_SUBTYPE_ARM_V6M: 1132 if (McpuDefault) 1133 *McpuDefault = "cortex-m0"; 1134 return Triple("thumbv6m-apple-darwin"); 1135 case MachO::CPU_SUBTYPE_ARM_V7: 1136 return Triple("thumbv7-apple-darwin"); 1137 case MachO::CPU_SUBTYPE_ARM_V7EM: 1138 if (McpuDefault) 1139 *McpuDefault = "cortex-m4"; 1140 return Triple("thumbv7em-apple-darwin"); 1141 case MachO::CPU_SUBTYPE_ARM_V7K: 1142 return Triple("thumbv7k-apple-darwin"); 1143 case MachO::CPU_SUBTYPE_ARM_V7M: 1144 if (McpuDefault) 1145 *McpuDefault = "cortex-m3"; 1146 return Triple("thumbv7m-apple-darwin"); 1147 case MachO::CPU_SUBTYPE_ARM_V7S: 1148 return Triple("thumbv7s-apple-darwin"); 1149 default: 1150 return Triple(); 1151 } 1152 default: 1153 return Triple(); 1154 } 1155 } 1156 1157 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1158 const char **McpuDefault, Triple *ThumbTriple) { 1159 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault); 1160 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType, 1161 McpuDefault); 1162 return T; 1163 } 1164 1165 Triple MachOObjectFile::getHostArch() { 1166 return Triple(sys::getDefaultTargetTriple()); 1167 } 1168 1169 bool MachOObjectFile::isValidArch(StringRef ArchFlag) { 1170 return StringSwitch<bool>(ArchFlag) 1171 .Case("i386", true) 1172 .Case("x86_64", true) 1173 .Case("x86_64h", true) 1174 .Case("armv4t", true) 1175 .Case("arm", true) 1176 .Case("armv5e", true) 1177 .Case("armv6", true) 1178 .Case("armv6m", true) 1179 .Case("armv7", true) 1180 .Case("armv7em", true) 1181 .Case("armv7k", true) 1182 .Case("armv7m", true) 1183 .Case("armv7s", true) 1184 .Case("arm64", true) 1185 .Case("ppc", true) 1186 .Case("ppc64", true) 1187 .Default(false); 1188 } 1189 1190 unsigned MachOObjectFile::getArch() const { 1191 return getArch(getCPUType(this)); 1192 } 1193 1194 Triple MachOObjectFile::getArch(const char **McpuDefault, 1195 Triple *ThumbTriple) const { 1196 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault); 1197 return getArch(Header.cputype, Header.cpusubtype, McpuDefault); 1198 } 1199 1200 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 1201 DataRefImpl DRI; 1202 DRI.d.a = Index; 1203 return section_rel_begin(DRI); 1204 } 1205 1206 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 1207 DataRefImpl DRI; 1208 DRI.d.a = Index; 1209 return section_rel_end(DRI); 1210 } 1211 1212 dice_iterator MachOObjectFile::begin_dices() const { 1213 DataRefImpl DRI; 1214 if (!DataInCodeLoadCmd) 1215 return dice_iterator(DiceRef(DRI, this)); 1216 1217 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1218 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff)); 1219 return dice_iterator(DiceRef(DRI, this)); 1220 } 1221 1222 dice_iterator MachOObjectFile::end_dices() const { 1223 DataRefImpl DRI; 1224 if (!DataInCodeLoadCmd) 1225 return dice_iterator(DiceRef(DRI, this)); 1226 1227 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1228 unsigned Offset = DicLC.dataoff + DicLC.datasize; 1229 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1230 return dice_iterator(DiceRef(DRI, this)); 1231 } 1232 1233 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 1234 : Trie(T), Malformed(false), Done(false) {} 1235 1236 void ExportEntry::moveToFirst() { 1237 pushNode(0); 1238 pushDownUntilBottom(); 1239 } 1240 1241 void ExportEntry::moveToEnd() { 1242 Stack.clear(); 1243 Done = true; 1244 } 1245 1246 bool ExportEntry::operator==(const ExportEntry &Other) const { 1247 // Common case, one at end, other iterating from begin. 1248 if (Done || Other.Done) 1249 return (Done == Other.Done); 1250 // Not equal if different stack sizes. 1251 if (Stack.size() != Other.Stack.size()) 1252 return false; 1253 // Not equal if different cumulative strings. 1254 if (!CumulativeString.equals(Other.CumulativeString)) 1255 return false; 1256 // Equal if all nodes in both stacks match. 1257 for (unsigned i=0; i < Stack.size(); ++i) { 1258 if (Stack[i].Start != Other.Stack[i].Start) 1259 return false; 1260 } 1261 return true; 1262 } 1263 1264 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { 1265 unsigned Count; 1266 uint64_t Result = decodeULEB128(Ptr, &Count); 1267 Ptr += Count; 1268 if (Ptr > Trie.end()) { 1269 Ptr = Trie.end(); 1270 Malformed = true; 1271 } 1272 return Result; 1273 } 1274 1275 StringRef ExportEntry::name() const { 1276 return CumulativeString; 1277 } 1278 1279 uint64_t ExportEntry::flags() const { 1280 return Stack.back().Flags; 1281 } 1282 1283 uint64_t ExportEntry::address() const { 1284 return Stack.back().Address; 1285 } 1286 1287 uint64_t ExportEntry::other() const { 1288 return Stack.back().Other; 1289 } 1290 1291 StringRef ExportEntry::otherName() const { 1292 const char* ImportName = Stack.back().ImportName; 1293 if (ImportName) 1294 return StringRef(ImportName); 1295 return StringRef(); 1296 } 1297 1298 uint32_t ExportEntry::nodeOffset() const { 1299 return Stack.back().Start - Trie.begin(); 1300 } 1301 1302 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 1303 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 1304 ImportName(nullptr), ChildCount(0), NextChildIndex(0), 1305 ParentStringLength(0), IsExportNode(false) {} 1306 1307 void ExportEntry::pushNode(uint64_t offset) { 1308 const uint8_t *Ptr = Trie.begin() + offset; 1309 NodeState State(Ptr); 1310 uint64_t ExportInfoSize = readULEB128(State.Current); 1311 State.IsExportNode = (ExportInfoSize != 0); 1312 const uint8_t* Children = State.Current + ExportInfoSize; 1313 if (State.IsExportNode) { 1314 State.Flags = readULEB128(State.Current); 1315 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 1316 State.Address = 0; 1317 State.Other = readULEB128(State.Current); // dylib ordinal 1318 State.ImportName = reinterpret_cast<const char*>(State.Current); 1319 } else { 1320 State.Address = readULEB128(State.Current); 1321 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) 1322 State.Other = readULEB128(State.Current); 1323 } 1324 } 1325 State.ChildCount = *Children; 1326 State.Current = Children + 1; 1327 State.NextChildIndex = 0; 1328 State.ParentStringLength = CumulativeString.size(); 1329 Stack.push_back(State); 1330 } 1331 1332 void ExportEntry::pushDownUntilBottom() { 1333 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 1334 NodeState &Top = Stack.back(); 1335 CumulativeString.resize(Top.ParentStringLength); 1336 for (;*Top.Current != 0; Top.Current++) { 1337 char C = *Top.Current; 1338 CumulativeString.push_back(C); 1339 } 1340 Top.Current += 1; 1341 uint64_t childNodeIndex = readULEB128(Top.Current); 1342 Top.NextChildIndex += 1; 1343 pushNode(childNodeIndex); 1344 } 1345 if (!Stack.back().IsExportNode) { 1346 Malformed = true; 1347 moveToEnd(); 1348 } 1349 } 1350 1351 // We have a trie data structure and need a way to walk it that is compatible 1352 // with the C++ iterator model. The solution is a non-recursive depth first 1353 // traversal where the iterator contains a stack of parent nodes along with a 1354 // string that is the accumulation of all edge strings along the parent chain 1355 // to this point. 1356 // 1357 // There is one "export" node for each exported symbol. But because some 1358 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 1359 // node may have child nodes too. 1360 // 1361 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 1362 // child until hitting a node with no children (which is an export node or 1363 // else the trie is malformed). On the way down, each node is pushed on the 1364 // stack ivar. If there is no more ways down, it pops up one and tries to go 1365 // down a sibling path until a childless node is reached. 1366 void ExportEntry::moveNext() { 1367 if (Stack.empty() || !Stack.back().IsExportNode) { 1368 Malformed = true; 1369 moveToEnd(); 1370 return; 1371 } 1372 1373 Stack.pop_back(); 1374 while (!Stack.empty()) { 1375 NodeState &Top = Stack.back(); 1376 if (Top.NextChildIndex < Top.ChildCount) { 1377 pushDownUntilBottom(); 1378 // Now at the next export node. 1379 return; 1380 } else { 1381 if (Top.IsExportNode) { 1382 // This node has no children but is itself an export node. 1383 CumulativeString.resize(Top.ParentStringLength); 1384 return; 1385 } 1386 Stack.pop_back(); 1387 } 1388 } 1389 Done = true; 1390 } 1391 1392 iterator_range<export_iterator> 1393 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { 1394 ExportEntry Start(Trie); 1395 if (Trie.size() == 0) 1396 Start.moveToEnd(); 1397 else 1398 Start.moveToFirst(); 1399 1400 ExportEntry Finish(Trie); 1401 Finish.moveToEnd(); 1402 1403 return iterator_range<export_iterator>(export_iterator(Start), 1404 export_iterator(Finish)); 1405 } 1406 1407 iterator_range<export_iterator> MachOObjectFile::exports() const { 1408 return exports(getDyldInfoExportsTrie()); 1409 } 1410 1411 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit) 1412 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1413 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0), 1414 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {} 1415 1416 void MachORebaseEntry::moveToFirst() { 1417 Ptr = Opcodes.begin(); 1418 moveNext(); 1419 } 1420 1421 void MachORebaseEntry::moveToEnd() { 1422 Ptr = Opcodes.end(); 1423 RemainingLoopCount = 0; 1424 Done = true; 1425 } 1426 1427 void MachORebaseEntry::moveNext() { 1428 // If in the middle of some loop, move to next rebasing in loop. 1429 SegmentOffset += AdvanceAmount; 1430 if (RemainingLoopCount) { 1431 --RemainingLoopCount; 1432 return; 1433 } 1434 if (Ptr == Opcodes.end()) { 1435 Done = true; 1436 return; 1437 } 1438 bool More = true; 1439 while (More && !Malformed) { 1440 // Parse next opcode and set up next loop. 1441 uint8_t Byte = *Ptr++; 1442 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 1443 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 1444 switch (Opcode) { 1445 case MachO::REBASE_OPCODE_DONE: 1446 More = false; 1447 Done = true; 1448 moveToEnd(); 1449 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n"); 1450 break; 1451 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 1452 RebaseType = ImmValue; 1453 DEBUG_WITH_TYPE( 1454 "mach-o-rebase", 1455 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 1456 << "RebaseType=" << (int) RebaseType << "\n"); 1457 break; 1458 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1459 SegmentIndex = ImmValue; 1460 SegmentOffset = readULEB128(); 1461 DEBUG_WITH_TYPE( 1462 "mach-o-rebase", 1463 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1464 << "SegmentIndex=" << SegmentIndex << ", " 1465 << format("SegmentOffset=0x%06X", SegmentOffset) 1466 << "\n"); 1467 break; 1468 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 1469 SegmentOffset += readULEB128(); 1470 DEBUG_WITH_TYPE("mach-o-rebase", 1471 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 1472 << format("SegmentOffset=0x%06X", 1473 SegmentOffset) << "\n"); 1474 break; 1475 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 1476 SegmentOffset += ImmValue * PointerSize; 1477 DEBUG_WITH_TYPE("mach-o-rebase", 1478 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 1479 << format("SegmentOffset=0x%06X", 1480 SegmentOffset) << "\n"); 1481 break; 1482 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 1483 AdvanceAmount = PointerSize; 1484 RemainingLoopCount = ImmValue - 1; 1485 DEBUG_WITH_TYPE( 1486 "mach-o-rebase", 1487 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 1488 << format("SegmentOffset=0x%06X", SegmentOffset) 1489 << ", AdvanceAmount=" << AdvanceAmount 1490 << ", RemainingLoopCount=" << RemainingLoopCount 1491 << "\n"); 1492 return; 1493 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 1494 AdvanceAmount = PointerSize; 1495 RemainingLoopCount = readULEB128() - 1; 1496 DEBUG_WITH_TYPE( 1497 "mach-o-rebase", 1498 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 1499 << format("SegmentOffset=0x%06X", SegmentOffset) 1500 << ", AdvanceAmount=" << AdvanceAmount 1501 << ", RemainingLoopCount=" << RemainingLoopCount 1502 << "\n"); 1503 return; 1504 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 1505 AdvanceAmount = readULEB128() + PointerSize; 1506 RemainingLoopCount = 0; 1507 DEBUG_WITH_TYPE( 1508 "mach-o-rebase", 1509 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 1510 << format("SegmentOffset=0x%06X", SegmentOffset) 1511 << ", AdvanceAmount=" << AdvanceAmount 1512 << ", RemainingLoopCount=" << RemainingLoopCount 1513 << "\n"); 1514 return; 1515 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 1516 RemainingLoopCount = readULEB128() - 1; 1517 AdvanceAmount = readULEB128() + PointerSize; 1518 DEBUG_WITH_TYPE( 1519 "mach-o-rebase", 1520 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 1521 << format("SegmentOffset=0x%06X", SegmentOffset) 1522 << ", AdvanceAmount=" << AdvanceAmount 1523 << ", RemainingLoopCount=" << RemainingLoopCount 1524 << "\n"); 1525 return; 1526 default: 1527 Malformed = true; 1528 } 1529 } 1530 } 1531 1532 uint64_t MachORebaseEntry::readULEB128() { 1533 unsigned Count; 1534 uint64_t Result = decodeULEB128(Ptr, &Count); 1535 Ptr += Count; 1536 if (Ptr > Opcodes.end()) { 1537 Ptr = Opcodes.end(); 1538 Malformed = true; 1539 } 1540 return Result; 1541 } 1542 1543 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 1544 1545 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 1546 1547 StringRef MachORebaseEntry::typeName() const { 1548 switch (RebaseType) { 1549 case MachO::REBASE_TYPE_POINTER: 1550 return "pointer"; 1551 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 1552 return "text abs32"; 1553 case MachO::REBASE_TYPE_TEXT_PCREL32: 1554 return "text rel32"; 1555 } 1556 return "unknown"; 1557 } 1558 1559 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 1560 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1561 return (Ptr == Other.Ptr) && 1562 (RemainingLoopCount == Other.RemainingLoopCount) && 1563 (Done == Other.Done); 1564 } 1565 1566 iterator_range<rebase_iterator> 1567 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) { 1568 MachORebaseEntry Start(Opcodes, is64); 1569 Start.moveToFirst(); 1570 1571 MachORebaseEntry Finish(Opcodes, is64); 1572 Finish.moveToEnd(); 1573 1574 return iterator_range<rebase_iterator>(rebase_iterator(Start), 1575 rebase_iterator(Finish)); 1576 } 1577 1578 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const { 1579 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit()); 1580 } 1581 1582 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK) 1583 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1584 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0), 1585 BindType(0), PointerSize(is64Bit ? 8 : 4), 1586 TableKind(BK), Malformed(false), Done(false) {} 1587 1588 void MachOBindEntry::moveToFirst() { 1589 Ptr = Opcodes.begin(); 1590 moveNext(); 1591 } 1592 1593 void MachOBindEntry::moveToEnd() { 1594 Ptr = Opcodes.end(); 1595 RemainingLoopCount = 0; 1596 Done = true; 1597 } 1598 1599 void MachOBindEntry::moveNext() { 1600 // If in the middle of some loop, move to next binding in loop. 1601 SegmentOffset += AdvanceAmount; 1602 if (RemainingLoopCount) { 1603 --RemainingLoopCount; 1604 return; 1605 } 1606 if (Ptr == Opcodes.end()) { 1607 Done = true; 1608 return; 1609 } 1610 bool More = true; 1611 while (More && !Malformed) { 1612 // Parse next opcode and set up next loop. 1613 uint8_t Byte = *Ptr++; 1614 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK; 1615 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK; 1616 int8_t SignExtended; 1617 const uint8_t *SymStart; 1618 switch (Opcode) { 1619 case MachO::BIND_OPCODE_DONE: 1620 if (TableKind == Kind::Lazy) { 1621 // Lazying bindings have a DONE opcode between entries. Need to ignore 1622 // it to advance to next entry. But need not if this is last entry. 1623 bool NotLastEntry = false; 1624 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) { 1625 if (*P) { 1626 NotLastEntry = true; 1627 } 1628 } 1629 if (NotLastEntry) 1630 break; 1631 } 1632 More = false; 1633 Done = true; 1634 moveToEnd(); 1635 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n"); 1636 break; 1637 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 1638 Ordinal = ImmValue; 1639 DEBUG_WITH_TYPE( 1640 "mach-o-bind", 1641 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 1642 << "Ordinal=" << Ordinal << "\n"); 1643 break; 1644 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 1645 Ordinal = readULEB128(); 1646 DEBUG_WITH_TYPE( 1647 "mach-o-bind", 1648 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 1649 << "Ordinal=" << Ordinal << "\n"); 1650 break; 1651 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 1652 if (ImmValue) { 1653 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue; 1654 Ordinal = SignExtended; 1655 } else 1656 Ordinal = 0; 1657 DEBUG_WITH_TYPE( 1658 "mach-o-bind", 1659 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 1660 << "Ordinal=" << Ordinal << "\n"); 1661 break; 1662 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 1663 Flags = ImmValue; 1664 SymStart = Ptr; 1665 while (*Ptr) { 1666 ++Ptr; 1667 } 1668 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart), 1669 Ptr-SymStart); 1670 ++Ptr; 1671 DEBUG_WITH_TYPE( 1672 "mach-o-bind", 1673 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 1674 << "SymbolName=" << SymbolName << "\n"); 1675 if (TableKind == Kind::Weak) { 1676 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) 1677 return; 1678 } 1679 break; 1680 case MachO::BIND_OPCODE_SET_TYPE_IMM: 1681 BindType = ImmValue; 1682 DEBUG_WITH_TYPE( 1683 "mach-o-bind", 1684 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: " 1685 << "BindType=" << (int)BindType << "\n"); 1686 break; 1687 case MachO::BIND_OPCODE_SET_ADDEND_SLEB: 1688 Addend = readSLEB128(); 1689 if (TableKind == Kind::Lazy) 1690 Malformed = true; 1691 DEBUG_WITH_TYPE( 1692 "mach-o-bind", 1693 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: " 1694 << "Addend=" << Addend << "\n"); 1695 break; 1696 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1697 SegmentIndex = ImmValue; 1698 SegmentOffset = readULEB128(); 1699 DEBUG_WITH_TYPE( 1700 "mach-o-bind", 1701 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1702 << "SegmentIndex=" << SegmentIndex << ", " 1703 << format("SegmentOffset=0x%06X", SegmentOffset) 1704 << "\n"); 1705 break; 1706 case MachO::BIND_OPCODE_ADD_ADDR_ULEB: 1707 SegmentOffset += readULEB128(); 1708 DEBUG_WITH_TYPE("mach-o-bind", 1709 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: " 1710 << format("SegmentOffset=0x%06X", 1711 SegmentOffset) << "\n"); 1712 break; 1713 case MachO::BIND_OPCODE_DO_BIND: 1714 AdvanceAmount = PointerSize; 1715 RemainingLoopCount = 0; 1716 DEBUG_WITH_TYPE("mach-o-bind", 1717 llvm::dbgs() << "BIND_OPCODE_DO_BIND: " 1718 << format("SegmentOffset=0x%06X", 1719 SegmentOffset) << "\n"); 1720 return; 1721 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 1722 AdvanceAmount = readULEB128() + PointerSize; 1723 RemainingLoopCount = 0; 1724 if (TableKind == Kind::Lazy) 1725 Malformed = true; 1726 DEBUG_WITH_TYPE( 1727 "mach-o-bind", 1728 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 1729 << format("SegmentOffset=0x%06X", SegmentOffset) 1730 << ", AdvanceAmount=" << AdvanceAmount 1731 << ", RemainingLoopCount=" << RemainingLoopCount 1732 << "\n"); 1733 return; 1734 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 1735 AdvanceAmount = ImmValue * PointerSize + PointerSize; 1736 RemainingLoopCount = 0; 1737 if (TableKind == Kind::Lazy) 1738 Malformed = true; 1739 DEBUG_WITH_TYPE("mach-o-bind", 1740 llvm::dbgs() 1741 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 1742 << format("SegmentOffset=0x%06X", 1743 SegmentOffset) << "\n"); 1744 return; 1745 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 1746 RemainingLoopCount = readULEB128() - 1; 1747 AdvanceAmount = readULEB128() + PointerSize; 1748 if (TableKind == Kind::Lazy) 1749 Malformed = true; 1750 DEBUG_WITH_TYPE( 1751 "mach-o-bind", 1752 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 1753 << format("SegmentOffset=0x%06X", SegmentOffset) 1754 << ", AdvanceAmount=" << AdvanceAmount 1755 << ", RemainingLoopCount=" << RemainingLoopCount 1756 << "\n"); 1757 return; 1758 default: 1759 Malformed = true; 1760 } 1761 } 1762 } 1763 1764 uint64_t MachOBindEntry::readULEB128() { 1765 unsigned Count; 1766 uint64_t Result = decodeULEB128(Ptr, &Count); 1767 Ptr += Count; 1768 if (Ptr > Opcodes.end()) { 1769 Ptr = Opcodes.end(); 1770 Malformed = true; 1771 } 1772 return Result; 1773 } 1774 1775 int64_t MachOBindEntry::readSLEB128() { 1776 unsigned Count; 1777 int64_t Result = decodeSLEB128(Ptr, &Count); 1778 Ptr += Count; 1779 if (Ptr > Opcodes.end()) { 1780 Ptr = Opcodes.end(); 1781 Malformed = true; 1782 } 1783 return Result; 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 None; 2225 2226 MachO::dyld_info_command DyldInfo = 2227 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2228 const uint8_t *Ptr = 2229 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off)); 2230 return makeArrayRef(Ptr, DyldInfo.rebase_size); 2231 } 2232 2233 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 2234 if (!DyldInfoLoadCmd) 2235 return None; 2236 2237 MachO::dyld_info_command DyldInfo = 2238 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2239 const uint8_t *Ptr = 2240 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off)); 2241 return makeArrayRef(Ptr, DyldInfo.bind_size); 2242 } 2243 2244 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 2245 if (!DyldInfoLoadCmd) 2246 return None; 2247 2248 MachO::dyld_info_command DyldInfo = 2249 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2250 const uint8_t *Ptr = 2251 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off)); 2252 return makeArrayRef(Ptr, DyldInfo.weak_bind_size); 2253 } 2254 2255 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 2256 if (!DyldInfoLoadCmd) 2257 return None; 2258 2259 MachO::dyld_info_command DyldInfo = 2260 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2261 const uint8_t *Ptr = 2262 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off)); 2263 return makeArrayRef(Ptr, DyldInfo.lazy_bind_size); 2264 } 2265 2266 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 2267 if (!DyldInfoLoadCmd) 2268 return None; 2269 2270 MachO::dyld_info_command DyldInfo = 2271 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2272 const uint8_t *Ptr = 2273 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off)); 2274 return makeArrayRef(Ptr, DyldInfo.export_size); 2275 } 2276 2277 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 2278 if (!UuidLoadCmd) 2279 return None; 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 makeArrayRef(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