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 return object_error::parse_failed; 336 return StringRef(Start); 337 } 338 339 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const { 340 DataRefImpl DRI = Sec.getRawDataRefImpl(); 341 uint32_t Flags = getSectionFlags(this, DRI); 342 return Flags & MachO::SECTION_TYPE; 343 } 344 345 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const { 346 if (is64Bit()) { 347 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym); 348 return Entry.n_value; 349 } 350 MachO::nlist Entry = getSymbolTableEntry(Sym); 351 return Entry.n_value; 352 } 353 354 // getIndirectName() returns the name of the alias'ed symbol who's string table 355 // index is in the n_value field. 356 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb, 357 StringRef &Res) const { 358 StringRef StringTable = getStringTableData(); 359 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 360 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 361 return object_error::parse_failed; 362 uint64_t NValue = getNValue(Symb); 363 if (NValue >= StringTable.size()) 364 return object_error::parse_failed; 365 const char *Start = &StringTable.data()[NValue]; 366 Res = StringRef(Start); 367 return std::error_code(); 368 } 369 370 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const { 371 return getNValue(Sym); 372 } 373 374 ErrorOr<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const { 375 return getSymbolValue(Sym); 376 } 377 378 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const { 379 uint32_t flags = getSymbolFlags(DRI); 380 if (flags & SymbolRef::SF_Common) { 381 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 382 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); 383 } 384 return 0; 385 } 386 387 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const { 388 return getNValue(DRI); 389 } 390 391 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const { 392 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 393 uint8_t n_type = Entry.n_type; 394 395 // If this is a STAB debugging symbol, we can do nothing more. 396 if (n_type & MachO::N_STAB) 397 return SymbolRef::ST_Debug; 398 399 switch (n_type & MachO::N_TYPE) { 400 case MachO::N_UNDF : 401 return SymbolRef::ST_Unknown; 402 case MachO::N_SECT : 403 section_iterator Sec = *getSymbolSection(Symb); 404 if (Sec->isData() || Sec->isBSS()) 405 return SymbolRef::ST_Data; 406 return SymbolRef::ST_Function; 407 } 408 return SymbolRef::ST_Other; 409 } 410 411 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { 412 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 413 414 uint8_t MachOType = Entry.n_type; 415 uint16_t MachOFlags = Entry.n_desc; 416 417 uint32_t Result = SymbolRef::SF_None; 418 419 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR) 420 Result |= SymbolRef::SF_Indirect; 421 422 if (MachOType & MachO::N_STAB) 423 Result |= SymbolRef::SF_FormatSpecific; 424 425 if (MachOType & MachO::N_EXT) { 426 Result |= SymbolRef::SF_Global; 427 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { 428 if (getNValue(DRI)) 429 Result |= SymbolRef::SF_Common; 430 else 431 Result |= SymbolRef::SF_Undefined; 432 } 433 434 if (!(MachOType & MachO::N_PEXT)) 435 Result |= SymbolRef::SF_Exported; 436 } 437 438 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 439 Result |= SymbolRef::SF_Weak; 440 441 if (MachOFlags & (MachO::N_ARM_THUMB_DEF)) 442 Result |= SymbolRef::SF_Thumb; 443 444 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) 445 Result |= SymbolRef::SF_Absolute; 446 447 return Result; 448 } 449 450 ErrorOr<section_iterator> 451 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const { 452 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 453 uint8_t index = Entry.n_sect; 454 455 if (index == 0) 456 return section_end(); 457 DataRefImpl DRI; 458 DRI.d.a = index - 1; 459 if (DRI.d.a >= Sections.size()) 460 return object_error::parse_failed; 461 return section_iterator(SectionRef(DRI, this)); 462 } 463 464 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const { 465 MachO::nlist_base Entry = 466 getSymbolTableEntryBase(this, Sym.getRawDataRefImpl()); 467 return Entry.n_sect - 1; 468 } 469 470 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { 471 Sec.d.a++; 472 } 473 474 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec, 475 StringRef &Result) const { 476 ArrayRef<char> Raw = getSectionRawName(Sec); 477 Result = parseSegmentOrSectionName(Raw.data()); 478 return std::error_code(); 479 } 480 481 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { 482 if (is64Bit()) 483 return getSection64(Sec).addr; 484 return getSection(Sec).addr; 485 } 486 487 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { 488 // In the case if a malformed Mach-O file where the section offset is past 489 // the end of the file or some part of the section size is past the end of 490 // the file return a size of zero or a size that covers the rest of the file 491 // but does not extend past the end of the file. 492 uint32_t SectOffset, SectType; 493 uint64_t SectSize; 494 495 if (is64Bit()) { 496 MachO::section_64 Sect = getSection64(Sec); 497 SectOffset = Sect.offset; 498 SectSize = Sect.size; 499 SectType = Sect.flags & MachO::SECTION_TYPE; 500 } else { 501 MachO::section Sect = getSection(Sec); 502 SectOffset = Sect.offset; 503 SectSize = Sect.size; 504 SectType = Sect.flags & MachO::SECTION_TYPE; 505 } 506 if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL) 507 return SectSize; 508 uint64_t FileSize = getData().size(); 509 if (SectOffset > FileSize) 510 return 0; 511 if (FileSize - SectOffset < SectSize) 512 return FileSize - SectOffset; 513 return SectSize; 514 } 515 516 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, 517 StringRef &Res) const { 518 uint32_t Offset; 519 uint64_t Size; 520 521 if (is64Bit()) { 522 MachO::section_64 Sect = getSection64(Sec); 523 Offset = Sect.offset; 524 Size = Sect.size; 525 } else { 526 MachO::section Sect = getSection(Sec); 527 Offset = Sect.offset; 528 Size = Sect.size; 529 } 530 531 Res = this->getData().substr(Offset, Size); 532 return std::error_code(); 533 } 534 535 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const { 536 uint32_t Align; 537 if (is64Bit()) { 538 MachO::section_64 Sect = getSection64(Sec); 539 Align = Sect.align; 540 } else { 541 MachO::section Sect = getSection(Sec); 542 Align = Sect.align; 543 } 544 545 return uint64_t(1) << Align; 546 } 547 548 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const { 549 uint32_t Flags = getSectionFlags(this, Sec); 550 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; 551 } 552 553 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const { 554 uint32_t Flags = getSectionFlags(this, Sec); 555 unsigned SectionType = Flags & MachO::SECTION_TYPE; 556 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 557 !(SectionType == MachO::S_ZEROFILL || 558 SectionType == MachO::S_GB_ZEROFILL); 559 } 560 561 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const { 562 uint32_t Flags = getSectionFlags(this, Sec); 563 unsigned SectionType = Flags & MachO::SECTION_TYPE; 564 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 565 (SectionType == MachO::S_ZEROFILL || 566 SectionType == MachO::S_GB_ZEROFILL); 567 } 568 569 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const { 570 return Sec.getRawDataRefImpl().d.a; 571 } 572 573 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const { 574 // FIXME: Unimplemented. 575 return false; 576 } 577 578 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 579 DataRefImpl Ret; 580 Ret.d.a = Sec.d.a; 581 Ret.d.b = 0; 582 return relocation_iterator(RelocationRef(Ret, this)); 583 } 584 585 relocation_iterator 586 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 587 uint32_t Num; 588 if (is64Bit()) { 589 MachO::section_64 Sect = getSection64(Sec); 590 Num = Sect.nreloc; 591 } else { 592 MachO::section Sect = getSection(Sec); 593 Num = Sect.nreloc; 594 } 595 596 DataRefImpl Ret; 597 Ret.d.a = Sec.d.a; 598 Ret.d.b = Num; 599 return relocation_iterator(RelocationRef(Ret, this)); 600 } 601 602 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 603 ++Rel.d.b; 604 } 605 606 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const { 607 assert(getHeader().filetype == MachO::MH_OBJECT && 608 "Only implemented for MH_OBJECT"); 609 MachO::any_relocation_info RE = getRelocation(Rel); 610 return getAnyRelocationAddress(RE); 611 } 612 613 symbol_iterator 614 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 615 MachO::any_relocation_info RE = getRelocation(Rel); 616 if (isRelocationScattered(RE)) 617 return symbol_end(); 618 619 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 620 bool isExtern = getPlainRelocationExternal(RE); 621 if (!isExtern) 622 return symbol_end(); 623 624 MachO::symtab_command S = getSymtabLoadCommand(); 625 unsigned SymbolTableEntrySize = is64Bit() ? 626 sizeof(MachO::nlist_64) : 627 sizeof(MachO::nlist); 628 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 629 DataRefImpl Sym; 630 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 631 return symbol_iterator(SymbolRef(Sym, this)); 632 } 633 634 section_iterator 635 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { 636 return section_iterator(getAnyRelocationSection(getRelocation(Rel))); 637 } 638 639 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const { 640 MachO::any_relocation_info RE = getRelocation(Rel); 641 return getAnyRelocationType(RE); 642 } 643 644 void MachOObjectFile::getRelocationTypeName( 645 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 646 StringRef res; 647 uint64_t RType = getRelocationType(Rel); 648 649 unsigned Arch = this->getArch(); 650 651 switch (Arch) { 652 case Triple::x86: { 653 static const char *const Table[] = { 654 "GENERIC_RELOC_VANILLA", 655 "GENERIC_RELOC_PAIR", 656 "GENERIC_RELOC_SECTDIFF", 657 "GENERIC_RELOC_PB_LA_PTR", 658 "GENERIC_RELOC_LOCAL_SECTDIFF", 659 "GENERIC_RELOC_TLV" }; 660 661 if (RType > 5) 662 res = "Unknown"; 663 else 664 res = Table[RType]; 665 break; 666 } 667 case Triple::x86_64: { 668 static const char *const Table[] = { 669 "X86_64_RELOC_UNSIGNED", 670 "X86_64_RELOC_SIGNED", 671 "X86_64_RELOC_BRANCH", 672 "X86_64_RELOC_GOT_LOAD", 673 "X86_64_RELOC_GOT", 674 "X86_64_RELOC_SUBTRACTOR", 675 "X86_64_RELOC_SIGNED_1", 676 "X86_64_RELOC_SIGNED_2", 677 "X86_64_RELOC_SIGNED_4", 678 "X86_64_RELOC_TLV" }; 679 680 if (RType > 9) 681 res = "Unknown"; 682 else 683 res = Table[RType]; 684 break; 685 } 686 case Triple::arm: { 687 static const char *const Table[] = { 688 "ARM_RELOC_VANILLA", 689 "ARM_RELOC_PAIR", 690 "ARM_RELOC_SECTDIFF", 691 "ARM_RELOC_LOCAL_SECTDIFF", 692 "ARM_RELOC_PB_LA_PTR", 693 "ARM_RELOC_BR24", 694 "ARM_THUMB_RELOC_BR22", 695 "ARM_THUMB_32BIT_BRANCH", 696 "ARM_RELOC_HALF", 697 "ARM_RELOC_HALF_SECTDIFF" }; 698 699 if (RType > 9) 700 res = "Unknown"; 701 else 702 res = Table[RType]; 703 break; 704 } 705 case Triple::aarch64: { 706 static const char *const Table[] = { 707 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 708 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 709 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 710 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 711 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 712 "ARM64_RELOC_ADDEND" 713 }; 714 715 if (RType >= array_lengthof(Table)) 716 res = "Unknown"; 717 else 718 res = Table[RType]; 719 break; 720 } 721 case Triple::ppc: { 722 static const char *const Table[] = { 723 "PPC_RELOC_VANILLA", 724 "PPC_RELOC_PAIR", 725 "PPC_RELOC_BR14", 726 "PPC_RELOC_BR24", 727 "PPC_RELOC_HI16", 728 "PPC_RELOC_LO16", 729 "PPC_RELOC_HA16", 730 "PPC_RELOC_LO14", 731 "PPC_RELOC_SECTDIFF", 732 "PPC_RELOC_PB_LA_PTR", 733 "PPC_RELOC_HI16_SECTDIFF", 734 "PPC_RELOC_LO16_SECTDIFF", 735 "PPC_RELOC_HA16_SECTDIFF", 736 "PPC_RELOC_JBSR", 737 "PPC_RELOC_LO14_SECTDIFF", 738 "PPC_RELOC_LOCAL_SECTDIFF" }; 739 740 if (RType > 15) 741 res = "Unknown"; 742 else 743 res = Table[RType]; 744 break; 745 } 746 case Triple::UnknownArch: 747 res = "Unknown"; 748 break; 749 } 750 Result.append(res.begin(), res.end()); 751 } 752 753 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { 754 MachO::any_relocation_info RE = getRelocation(Rel); 755 return getAnyRelocationLength(RE); 756 } 757 758 // 759 // guessLibraryShortName() is passed a name of a dynamic library and returns a 760 // guess on what the short name is. Then name is returned as a substring of the 761 // StringRef Name passed in. The name of the dynamic library is recognized as 762 // a framework if it has one of the two following forms: 763 // Foo.framework/Versions/A/Foo 764 // Foo.framework/Foo 765 // Where A and Foo can be any string. And may contain a trailing suffix 766 // starting with an underbar. If the Name is recognized as a framework then 767 // isFramework is set to true else it is set to false. If the Name has a 768 // suffix then Suffix is set to the substring in Name that contains the suffix 769 // else it is set to a NULL StringRef. 770 // 771 // The Name of the dynamic library is recognized as a library name if it has 772 // one of the two following forms: 773 // libFoo.A.dylib 774 // libFoo.dylib 775 // The library may have a suffix trailing the name Foo of the form: 776 // libFoo_profile.A.dylib 777 // libFoo_profile.dylib 778 // 779 // The Name of the dynamic library is also recognized as a library name if it 780 // has the following form: 781 // Foo.qtx 782 // 783 // If the Name of the dynamic library is none of the forms above then a NULL 784 // StringRef is returned. 785 // 786 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 787 bool &isFramework, 788 StringRef &Suffix) { 789 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 790 size_t a, b, c, d, Idx; 791 792 isFramework = false; 793 Suffix = StringRef(); 794 795 // Pull off the last component and make Foo point to it 796 a = Name.rfind('/'); 797 if (a == Name.npos || a == 0) 798 goto guess_library; 799 Foo = Name.slice(a+1, Name.npos); 800 801 // Look for a suffix starting with a '_' 802 Idx = Foo.rfind('_'); 803 if (Idx != Foo.npos && Foo.size() >= 2) { 804 Suffix = Foo.slice(Idx, Foo.npos); 805 Foo = Foo.slice(0, Idx); 806 } 807 808 // First look for the form Foo.framework/Foo 809 b = Name.rfind('/', a); 810 if (b == Name.npos) 811 Idx = 0; 812 else 813 Idx = b+1; 814 F = Name.slice(Idx, Idx + Foo.size()); 815 DotFramework = Name.slice(Idx + Foo.size(), 816 Idx + Foo.size() + sizeof(".framework/")-1); 817 if (F == Foo && DotFramework == ".framework/") { 818 isFramework = true; 819 return Foo; 820 } 821 822 // Next look for the form Foo.framework/Versions/A/Foo 823 if (b == Name.npos) 824 goto guess_library; 825 c = Name.rfind('/', b); 826 if (c == Name.npos || c == 0) 827 goto guess_library; 828 V = Name.slice(c+1, Name.npos); 829 if (!V.startswith("Versions/")) 830 goto guess_library; 831 d = Name.rfind('/', c); 832 if (d == Name.npos) 833 Idx = 0; 834 else 835 Idx = d+1; 836 F = Name.slice(Idx, Idx + Foo.size()); 837 DotFramework = Name.slice(Idx + Foo.size(), 838 Idx + Foo.size() + sizeof(".framework/")-1); 839 if (F == Foo && DotFramework == ".framework/") { 840 isFramework = true; 841 return Foo; 842 } 843 844 guess_library: 845 // pull off the suffix after the "." and make a point to it 846 a = Name.rfind('.'); 847 if (a == Name.npos || a == 0) 848 return StringRef(); 849 Dylib = Name.slice(a, Name.npos); 850 if (Dylib != ".dylib") 851 goto guess_qtx; 852 853 // First pull off the version letter for the form Foo.A.dylib if any. 854 if (a >= 3) { 855 Dot = Name.slice(a-2, a-1); 856 if (Dot == ".") 857 a = a - 2; 858 } 859 860 b = Name.rfind('/', a); 861 if (b == Name.npos) 862 b = 0; 863 else 864 b = b+1; 865 // ignore any suffix after an underbar like Foo_profile.A.dylib 866 Idx = Name.find('_', b); 867 if (Idx != Name.npos && Idx != b) { 868 Lib = Name.slice(b, Idx); 869 Suffix = Name.slice(Idx, a); 870 } 871 else 872 Lib = Name.slice(b, a); 873 // There are incorrect library names of the form: 874 // libATS.A_profile.dylib so check for these. 875 if (Lib.size() >= 3) { 876 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 877 if (Dot == ".") 878 Lib = Lib.slice(0, Lib.size()-2); 879 } 880 return Lib; 881 882 guess_qtx: 883 Qtx = Name.slice(a, Name.npos); 884 if (Qtx != ".qtx") 885 return StringRef(); 886 b = Name.rfind('/', a); 887 if (b == Name.npos) 888 Lib = Name.slice(0, a); 889 else 890 Lib = Name.slice(b+1, a); 891 // There are library names of the form: QT.A.qtx so check for these. 892 if (Lib.size() >= 3) { 893 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 894 if (Dot == ".") 895 Lib = Lib.slice(0, Lib.size()-2); 896 } 897 return Lib; 898 } 899 900 // getLibraryShortNameByIndex() is used to get the short name of the library 901 // for an undefined symbol in a linked Mach-O binary that was linked with the 902 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 903 // It is passed the index (0 - based) of the library as translated from 904 // GET_LIBRARY_ORDINAL (1 - based). 905 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 906 StringRef &Res) const { 907 if (Index >= Libraries.size()) 908 return object_error::parse_failed; 909 910 // If the cache of LibrariesShortNames is not built up do that first for 911 // all the Libraries. 912 if (LibrariesShortNames.size() == 0) { 913 for (unsigned i = 0; i < Libraries.size(); i++) { 914 MachO::dylib_command D = 915 getStruct<MachO::dylib_command>(this, Libraries[i]); 916 if (D.dylib.name >= D.cmdsize) 917 return object_error::parse_failed; 918 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 919 StringRef Name = StringRef(P); 920 if (D.dylib.name+Name.size() >= D.cmdsize) 921 return object_error::parse_failed; 922 StringRef Suffix; 923 bool isFramework; 924 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 925 if (shortName.empty()) 926 LibrariesShortNames.push_back(Name); 927 else 928 LibrariesShortNames.push_back(shortName); 929 } 930 } 931 932 Res = LibrariesShortNames[Index]; 933 return std::error_code(); 934 } 935 936 section_iterator 937 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const { 938 DataRefImpl Sec; 939 Sec.d.a = Rel->getRawDataRefImpl().d.a; 940 return section_iterator(SectionRef(Sec, this)); 941 } 942 943 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { 944 return getSymbolByIndex(0); 945 } 946 947 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { 948 DataRefImpl DRI; 949 if (!SymtabLoadCmd) 950 return basic_symbol_iterator(SymbolRef(DRI, this)); 951 952 MachO::symtab_command Symtab = getSymtabLoadCommand(); 953 unsigned SymbolTableEntrySize = is64Bit() ? 954 sizeof(MachO::nlist_64) : 955 sizeof(MachO::nlist); 956 unsigned Offset = Symtab.symoff + 957 Symtab.nsyms * SymbolTableEntrySize; 958 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 959 return basic_symbol_iterator(SymbolRef(DRI, this)); 960 } 961 962 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 963 DataRefImpl DRI; 964 if (!SymtabLoadCmd) 965 return basic_symbol_iterator(SymbolRef(DRI, this)); 966 967 MachO::symtab_command Symtab = getSymtabLoadCommand(); 968 if (Index >= Symtab.nsyms) 969 report_fatal_error("Requested symbol index is out of range."); 970 unsigned SymbolTableEntrySize = 971 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 972 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); 973 DRI.p += Index * SymbolTableEntrySize; 974 return basic_symbol_iterator(SymbolRef(DRI, this)); 975 } 976 977 section_iterator MachOObjectFile::section_begin() const { 978 DataRefImpl DRI; 979 return section_iterator(SectionRef(DRI, this)); 980 } 981 982 section_iterator MachOObjectFile::section_end() const { 983 DataRefImpl DRI; 984 DRI.d.a = Sections.size(); 985 return section_iterator(SectionRef(DRI, this)); 986 } 987 988 uint8_t MachOObjectFile::getBytesInAddress() const { 989 return is64Bit() ? 8 : 4; 990 } 991 992 StringRef MachOObjectFile::getFileFormatName() const { 993 unsigned CPUType = getCPUType(this); 994 if (!is64Bit()) { 995 switch (CPUType) { 996 case llvm::MachO::CPU_TYPE_I386: 997 return "Mach-O 32-bit i386"; 998 case llvm::MachO::CPU_TYPE_ARM: 999 return "Mach-O arm"; 1000 case llvm::MachO::CPU_TYPE_POWERPC: 1001 return "Mach-O 32-bit ppc"; 1002 default: 1003 return "Mach-O 32-bit unknown"; 1004 } 1005 } 1006 1007 switch (CPUType) { 1008 case llvm::MachO::CPU_TYPE_X86_64: 1009 return "Mach-O 64-bit x86-64"; 1010 case llvm::MachO::CPU_TYPE_ARM64: 1011 return "Mach-O arm64"; 1012 case llvm::MachO::CPU_TYPE_POWERPC64: 1013 return "Mach-O 64-bit ppc64"; 1014 default: 1015 return "Mach-O 64-bit unknown"; 1016 } 1017 } 1018 1019 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 1020 switch (CPUType) { 1021 case llvm::MachO::CPU_TYPE_I386: 1022 return Triple::x86; 1023 case llvm::MachO::CPU_TYPE_X86_64: 1024 return Triple::x86_64; 1025 case llvm::MachO::CPU_TYPE_ARM: 1026 return Triple::arm; 1027 case llvm::MachO::CPU_TYPE_ARM64: 1028 return Triple::aarch64; 1029 case llvm::MachO::CPU_TYPE_POWERPC: 1030 return Triple::ppc; 1031 case llvm::MachO::CPU_TYPE_POWERPC64: 1032 return Triple::ppc64; 1033 default: 1034 return Triple::UnknownArch; 1035 } 1036 } 1037 1038 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1039 const char **McpuDefault) { 1040 if (McpuDefault) 1041 *McpuDefault = nullptr; 1042 1043 switch (CPUType) { 1044 case MachO::CPU_TYPE_I386: 1045 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1046 case MachO::CPU_SUBTYPE_I386_ALL: 1047 return Triple("i386-apple-darwin"); 1048 default: 1049 return Triple(); 1050 } 1051 case MachO::CPU_TYPE_X86_64: 1052 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1053 case MachO::CPU_SUBTYPE_X86_64_ALL: 1054 return Triple("x86_64-apple-darwin"); 1055 case MachO::CPU_SUBTYPE_X86_64_H: 1056 return Triple("x86_64h-apple-darwin"); 1057 default: 1058 return Triple(); 1059 } 1060 case MachO::CPU_TYPE_ARM: 1061 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1062 case MachO::CPU_SUBTYPE_ARM_V4T: 1063 return Triple("armv4t-apple-darwin"); 1064 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1065 return Triple("armv5e-apple-darwin"); 1066 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1067 return Triple("xscale-apple-darwin"); 1068 case MachO::CPU_SUBTYPE_ARM_V6: 1069 return Triple("armv6-apple-darwin"); 1070 case MachO::CPU_SUBTYPE_ARM_V6M: 1071 if (McpuDefault) 1072 *McpuDefault = "cortex-m0"; 1073 return Triple("armv6m-apple-darwin"); 1074 case MachO::CPU_SUBTYPE_ARM_V7: 1075 return Triple("armv7-apple-darwin"); 1076 case MachO::CPU_SUBTYPE_ARM_V7EM: 1077 if (McpuDefault) 1078 *McpuDefault = "cortex-m4"; 1079 return Triple("armv7em-apple-darwin"); 1080 case MachO::CPU_SUBTYPE_ARM_V7K: 1081 return Triple("armv7k-apple-darwin"); 1082 case MachO::CPU_SUBTYPE_ARM_V7M: 1083 if (McpuDefault) 1084 *McpuDefault = "cortex-m3"; 1085 return Triple("armv7m-apple-darwin"); 1086 case MachO::CPU_SUBTYPE_ARM_V7S: 1087 return Triple("armv7s-apple-darwin"); 1088 default: 1089 return Triple(); 1090 } 1091 case MachO::CPU_TYPE_ARM64: 1092 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1093 case MachO::CPU_SUBTYPE_ARM64_ALL: 1094 return Triple("arm64-apple-darwin"); 1095 default: 1096 return Triple(); 1097 } 1098 case MachO::CPU_TYPE_POWERPC: 1099 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1100 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1101 return Triple("ppc-apple-darwin"); 1102 default: 1103 return Triple(); 1104 } 1105 case MachO::CPU_TYPE_POWERPC64: 1106 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1107 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1108 return Triple("ppc64-apple-darwin"); 1109 default: 1110 return Triple(); 1111 } 1112 default: 1113 return Triple(); 1114 } 1115 } 1116 1117 Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType, 1118 const char **McpuDefault) { 1119 if (McpuDefault) 1120 *McpuDefault = nullptr; 1121 1122 switch (CPUType) { 1123 case MachO::CPU_TYPE_ARM: 1124 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1125 case MachO::CPU_SUBTYPE_ARM_V4T: 1126 return Triple("thumbv4t-apple-darwin"); 1127 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1128 return Triple("thumbv5e-apple-darwin"); 1129 case MachO::CPU_SUBTYPE_ARM_XSCALE: 1130 return Triple("xscale-apple-darwin"); 1131 case MachO::CPU_SUBTYPE_ARM_V6: 1132 return Triple("thumbv6-apple-darwin"); 1133 case MachO::CPU_SUBTYPE_ARM_V6M: 1134 if (McpuDefault) 1135 *McpuDefault = "cortex-m0"; 1136 return Triple("thumbv6m-apple-darwin"); 1137 case MachO::CPU_SUBTYPE_ARM_V7: 1138 return Triple("thumbv7-apple-darwin"); 1139 case MachO::CPU_SUBTYPE_ARM_V7EM: 1140 if (McpuDefault) 1141 *McpuDefault = "cortex-m4"; 1142 return Triple("thumbv7em-apple-darwin"); 1143 case MachO::CPU_SUBTYPE_ARM_V7K: 1144 return Triple("thumbv7k-apple-darwin"); 1145 case MachO::CPU_SUBTYPE_ARM_V7M: 1146 if (McpuDefault) 1147 *McpuDefault = "cortex-m3"; 1148 return Triple("thumbv7m-apple-darwin"); 1149 case MachO::CPU_SUBTYPE_ARM_V7S: 1150 return Triple("thumbv7s-apple-darwin"); 1151 default: 1152 return Triple(); 1153 } 1154 default: 1155 return Triple(); 1156 } 1157 } 1158 1159 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, 1160 const char **McpuDefault, Triple *ThumbTriple) { 1161 Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault); 1162 *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType, 1163 McpuDefault); 1164 return T; 1165 } 1166 1167 Triple MachOObjectFile::getHostArch() { 1168 return Triple(sys::getDefaultTargetTriple()); 1169 } 1170 1171 bool MachOObjectFile::isValidArch(StringRef ArchFlag) { 1172 return StringSwitch<bool>(ArchFlag) 1173 .Case("i386", true) 1174 .Case("x86_64", true) 1175 .Case("x86_64h", true) 1176 .Case("armv4t", true) 1177 .Case("arm", true) 1178 .Case("armv5e", true) 1179 .Case("armv6", true) 1180 .Case("armv6m", true) 1181 .Case("armv7", true) 1182 .Case("armv7em", true) 1183 .Case("armv7k", true) 1184 .Case("armv7m", true) 1185 .Case("armv7s", true) 1186 .Case("arm64", true) 1187 .Case("ppc", true) 1188 .Case("ppc64", true) 1189 .Default(false); 1190 } 1191 1192 unsigned MachOObjectFile::getArch() const { 1193 return getArch(getCPUType(this)); 1194 } 1195 1196 Triple MachOObjectFile::getArch(const char **McpuDefault, 1197 Triple *ThumbTriple) const { 1198 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault); 1199 return getArch(Header.cputype, Header.cpusubtype, McpuDefault); 1200 } 1201 1202 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 1203 DataRefImpl DRI; 1204 DRI.d.a = Index; 1205 return section_rel_begin(DRI); 1206 } 1207 1208 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 1209 DataRefImpl DRI; 1210 DRI.d.a = Index; 1211 return section_rel_end(DRI); 1212 } 1213 1214 dice_iterator MachOObjectFile::begin_dices() const { 1215 DataRefImpl DRI; 1216 if (!DataInCodeLoadCmd) 1217 return dice_iterator(DiceRef(DRI, this)); 1218 1219 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1220 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff)); 1221 return dice_iterator(DiceRef(DRI, this)); 1222 } 1223 1224 dice_iterator MachOObjectFile::end_dices() const { 1225 DataRefImpl DRI; 1226 if (!DataInCodeLoadCmd) 1227 return dice_iterator(DiceRef(DRI, this)); 1228 1229 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1230 unsigned Offset = DicLC.dataoff + DicLC.datasize; 1231 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1232 return dice_iterator(DiceRef(DRI, this)); 1233 } 1234 1235 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 1236 : Trie(T), Malformed(false), Done(false) {} 1237 1238 void ExportEntry::moveToFirst() { 1239 pushNode(0); 1240 pushDownUntilBottom(); 1241 } 1242 1243 void ExportEntry::moveToEnd() { 1244 Stack.clear(); 1245 Done = true; 1246 } 1247 1248 bool ExportEntry::operator==(const ExportEntry &Other) const { 1249 // Common case, one at end, other iterating from begin. 1250 if (Done || Other.Done) 1251 return (Done == Other.Done); 1252 // Not equal if different stack sizes. 1253 if (Stack.size() != Other.Stack.size()) 1254 return false; 1255 // Not equal if different cumulative strings. 1256 if (!CumulativeString.equals(Other.CumulativeString)) 1257 return false; 1258 // Equal if all nodes in both stacks match. 1259 for (unsigned i=0; i < Stack.size(); ++i) { 1260 if (Stack[i].Start != Other.Stack[i].Start) 1261 return false; 1262 } 1263 return true; 1264 } 1265 1266 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { 1267 unsigned Count; 1268 uint64_t Result = decodeULEB128(Ptr, &Count); 1269 Ptr += Count; 1270 if (Ptr > Trie.end()) { 1271 Ptr = Trie.end(); 1272 Malformed = true; 1273 } 1274 return Result; 1275 } 1276 1277 StringRef ExportEntry::name() const { 1278 return CumulativeString; 1279 } 1280 1281 uint64_t ExportEntry::flags() const { 1282 return Stack.back().Flags; 1283 } 1284 1285 uint64_t ExportEntry::address() const { 1286 return Stack.back().Address; 1287 } 1288 1289 uint64_t ExportEntry::other() const { 1290 return Stack.back().Other; 1291 } 1292 1293 StringRef ExportEntry::otherName() const { 1294 const char* ImportName = Stack.back().ImportName; 1295 if (ImportName) 1296 return StringRef(ImportName); 1297 return StringRef(); 1298 } 1299 1300 uint32_t ExportEntry::nodeOffset() const { 1301 return Stack.back().Start - Trie.begin(); 1302 } 1303 1304 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 1305 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 1306 ImportName(nullptr), ChildCount(0), NextChildIndex(0), 1307 ParentStringLength(0), IsExportNode(false) {} 1308 1309 void ExportEntry::pushNode(uint64_t offset) { 1310 const uint8_t *Ptr = Trie.begin() + offset; 1311 NodeState State(Ptr); 1312 uint64_t ExportInfoSize = readULEB128(State.Current); 1313 State.IsExportNode = (ExportInfoSize != 0); 1314 const uint8_t* Children = State.Current + ExportInfoSize; 1315 if (State.IsExportNode) { 1316 State.Flags = readULEB128(State.Current); 1317 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 1318 State.Address = 0; 1319 State.Other = readULEB128(State.Current); // dylib ordinal 1320 State.ImportName = reinterpret_cast<const char*>(State.Current); 1321 } else { 1322 State.Address = readULEB128(State.Current); 1323 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) 1324 State.Other = readULEB128(State.Current); 1325 } 1326 } 1327 State.ChildCount = *Children; 1328 State.Current = Children + 1; 1329 State.NextChildIndex = 0; 1330 State.ParentStringLength = CumulativeString.size(); 1331 Stack.push_back(State); 1332 } 1333 1334 void ExportEntry::pushDownUntilBottom() { 1335 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 1336 NodeState &Top = Stack.back(); 1337 CumulativeString.resize(Top.ParentStringLength); 1338 for (;*Top.Current != 0; Top.Current++) { 1339 char C = *Top.Current; 1340 CumulativeString.push_back(C); 1341 } 1342 Top.Current += 1; 1343 uint64_t childNodeIndex = readULEB128(Top.Current); 1344 Top.NextChildIndex += 1; 1345 pushNode(childNodeIndex); 1346 } 1347 if (!Stack.back().IsExportNode) { 1348 Malformed = true; 1349 moveToEnd(); 1350 } 1351 } 1352 1353 // We have a trie data structure and need a way to walk it that is compatible 1354 // with the C++ iterator model. The solution is a non-recursive depth first 1355 // traversal where the iterator contains a stack of parent nodes along with a 1356 // string that is the accumulation of all edge strings along the parent chain 1357 // to this point. 1358 // 1359 // There is one "export" node for each exported symbol. But because some 1360 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 1361 // node may have child nodes too. 1362 // 1363 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 1364 // child until hitting a node with no children (which is an export node or 1365 // else the trie is malformed). On the way down, each node is pushed on the 1366 // stack ivar. If there is no more ways down, it pops up one and tries to go 1367 // down a sibling path until a childless node is reached. 1368 void ExportEntry::moveNext() { 1369 if (Stack.empty() || !Stack.back().IsExportNode) { 1370 Malformed = true; 1371 moveToEnd(); 1372 return; 1373 } 1374 1375 Stack.pop_back(); 1376 while (!Stack.empty()) { 1377 NodeState &Top = Stack.back(); 1378 if (Top.NextChildIndex < Top.ChildCount) { 1379 pushDownUntilBottom(); 1380 // Now at the next export node. 1381 return; 1382 } else { 1383 if (Top.IsExportNode) { 1384 // This node has no children but is itself an export node. 1385 CumulativeString.resize(Top.ParentStringLength); 1386 return; 1387 } 1388 Stack.pop_back(); 1389 } 1390 } 1391 Done = true; 1392 } 1393 1394 iterator_range<export_iterator> 1395 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { 1396 ExportEntry Start(Trie); 1397 if (Trie.size() == 0) 1398 Start.moveToEnd(); 1399 else 1400 Start.moveToFirst(); 1401 1402 ExportEntry Finish(Trie); 1403 Finish.moveToEnd(); 1404 1405 return make_range(export_iterator(Start), export_iterator(Finish)); 1406 } 1407 1408 iterator_range<export_iterator> MachOObjectFile::exports() const { 1409 return exports(getDyldInfoExportsTrie()); 1410 } 1411 1412 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit) 1413 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1414 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0), 1415 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {} 1416 1417 void MachORebaseEntry::moveToFirst() { 1418 Ptr = Opcodes.begin(); 1419 moveNext(); 1420 } 1421 1422 void MachORebaseEntry::moveToEnd() { 1423 Ptr = Opcodes.end(); 1424 RemainingLoopCount = 0; 1425 Done = true; 1426 } 1427 1428 void MachORebaseEntry::moveNext() { 1429 // If in the middle of some loop, move to next rebasing in loop. 1430 SegmentOffset += AdvanceAmount; 1431 if (RemainingLoopCount) { 1432 --RemainingLoopCount; 1433 return; 1434 } 1435 if (Ptr == Opcodes.end()) { 1436 Done = true; 1437 return; 1438 } 1439 bool More = true; 1440 while (More && !Malformed) { 1441 // Parse next opcode and set up next loop. 1442 uint8_t Byte = *Ptr++; 1443 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 1444 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 1445 switch (Opcode) { 1446 case MachO::REBASE_OPCODE_DONE: 1447 More = false; 1448 Done = true; 1449 moveToEnd(); 1450 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n"); 1451 break; 1452 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 1453 RebaseType = ImmValue; 1454 DEBUG_WITH_TYPE( 1455 "mach-o-rebase", 1456 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 1457 << "RebaseType=" << (int) RebaseType << "\n"); 1458 break; 1459 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1460 SegmentIndex = ImmValue; 1461 SegmentOffset = readULEB128(); 1462 DEBUG_WITH_TYPE( 1463 "mach-o-rebase", 1464 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1465 << "SegmentIndex=" << SegmentIndex << ", " 1466 << format("SegmentOffset=0x%06X", SegmentOffset) 1467 << "\n"); 1468 break; 1469 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 1470 SegmentOffset += readULEB128(); 1471 DEBUG_WITH_TYPE("mach-o-rebase", 1472 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 1473 << format("SegmentOffset=0x%06X", 1474 SegmentOffset) << "\n"); 1475 break; 1476 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 1477 SegmentOffset += ImmValue * PointerSize; 1478 DEBUG_WITH_TYPE("mach-o-rebase", 1479 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 1480 << format("SegmentOffset=0x%06X", 1481 SegmentOffset) << "\n"); 1482 break; 1483 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 1484 AdvanceAmount = PointerSize; 1485 RemainingLoopCount = ImmValue - 1; 1486 DEBUG_WITH_TYPE( 1487 "mach-o-rebase", 1488 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 1489 << format("SegmentOffset=0x%06X", SegmentOffset) 1490 << ", AdvanceAmount=" << AdvanceAmount 1491 << ", RemainingLoopCount=" << RemainingLoopCount 1492 << "\n"); 1493 return; 1494 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 1495 AdvanceAmount = PointerSize; 1496 RemainingLoopCount = readULEB128() - 1; 1497 DEBUG_WITH_TYPE( 1498 "mach-o-rebase", 1499 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 1500 << format("SegmentOffset=0x%06X", SegmentOffset) 1501 << ", AdvanceAmount=" << AdvanceAmount 1502 << ", RemainingLoopCount=" << RemainingLoopCount 1503 << "\n"); 1504 return; 1505 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 1506 AdvanceAmount = readULEB128() + PointerSize; 1507 RemainingLoopCount = 0; 1508 DEBUG_WITH_TYPE( 1509 "mach-o-rebase", 1510 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 1511 << format("SegmentOffset=0x%06X", SegmentOffset) 1512 << ", AdvanceAmount=" << AdvanceAmount 1513 << ", RemainingLoopCount=" << RemainingLoopCount 1514 << "\n"); 1515 return; 1516 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 1517 RemainingLoopCount = readULEB128() - 1; 1518 AdvanceAmount = readULEB128() + PointerSize; 1519 DEBUG_WITH_TYPE( 1520 "mach-o-rebase", 1521 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 1522 << format("SegmentOffset=0x%06X", SegmentOffset) 1523 << ", AdvanceAmount=" << AdvanceAmount 1524 << ", RemainingLoopCount=" << RemainingLoopCount 1525 << "\n"); 1526 return; 1527 default: 1528 Malformed = true; 1529 } 1530 } 1531 } 1532 1533 uint64_t MachORebaseEntry::readULEB128() { 1534 unsigned Count; 1535 uint64_t Result = decodeULEB128(Ptr, &Count); 1536 Ptr += Count; 1537 if (Ptr > Opcodes.end()) { 1538 Ptr = Opcodes.end(); 1539 Malformed = true; 1540 } 1541 return Result; 1542 } 1543 1544 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 1545 1546 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 1547 1548 StringRef MachORebaseEntry::typeName() const { 1549 switch (RebaseType) { 1550 case MachO::REBASE_TYPE_POINTER: 1551 return "pointer"; 1552 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 1553 return "text abs32"; 1554 case MachO::REBASE_TYPE_TEXT_PCREL32: 1555 return "text rel32"; 1556 } 1557 return "unknown"; 1558 } 1559 1560 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 1561 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1562 return (Ptr == Other.Ptr) && 1563 (RemainingLoopCount == Other.RemainingLoopCount) && 1564 (Done == Other.Done); 1565 } 1566 1567 iterator_range<rebase_iterator> 1568 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) { 1569 MachORebaseEntry Start(Opcodes, is64); 1570 Start.moveToFirst(); 1571 1572 MachORebaseEntry Finish(Opcodes, is64); 1573 Finish.moveToEnd(); 1574 1575 return make_range(rebase_iterator(Start), 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 make_range(bind_iterator(Start), bind_iterator(Finish)); 1827 } 1828 1829 iterator_range<bind_iterator> MachOObjectFile::bindTable() const { 1830 return bindTable(getDyldInfoBindOpcodes(), is64Bit(), 1831 MachOBindEntry::Kind::Regular); 1832 } 1833 1834 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const { 1835 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(), 1836 MachOBindEntry::Kind::Lazy); 1837 } 1838 1839 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const { 1840 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(), 1841 MachOBindEntry::Kind::Weak); 1842 } 1843 1844 MachOObjectFile::load_command_iterator 1845 MachOObjectFile::begin_load_commands() const { 1846 return LoadCommands.begin(); 1847 } 1848 1849 MachOObjectFile::load_command_iterator 1850 MachOObjectFile::end_load_commands() const { 1851 return LoadCommands.end(); 1852 } 1853 1854 iterator_range<MachOObjectFile::load_command_iterator> 1855 MachOObjectFile::load_commands() const { 1856 return make_range(begin_load_commands(), end_load_commands()); 1857 } 1858 1859 StringRef 1860 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 1861 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 1862 return parseSegmentOrSectionName(Raw.data()); 1863 } 1864 1865 ArrayRef<char> 1866 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 1867 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1868 const section_base *Base = 1869 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1870 return makeArrayRef(Base->sectname); 1871 } 1872 1873 ArrayRef<char> 1874 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 1875 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1876 const section_base *Base = 1877 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1878 return makeArrayRef(Base->segname); 1879 } 1880 1881 bool 1882 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 1883 const { 1884 if (getCPUType(this) == MachO::CPU_TYPE_X86_64) 1885 return false; 1886 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 1887 } 1888 1889 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 1890 const MachO::any_relocation_info &RE) const { 1891 if (isLittleEndian()) 1892 return RE.r_word1 & 0xffffff; 1893 return RE.r_word1 >> 8; 1894 } 1895 1896 bool MachOObjectFile::getPlainRelocationExternal( 1897 const MachO::any_relocation_info &RE) const { 1898 if (isLittleEndian()) 1899 return (RE.r_word1 >> 27) & 1; 1900 return (RE.r_word1 >> 4) & 1; 1901 } 1902 1903 bool MachOObjectFile::getScatteredRelocationScattered( 1904 const MachO::any_relocation_info &RE) const { 1905 return RE.r_word0 >> 31; 1906 } 1907 1908 uint32_t MachOObjectFile::getScatteredRelocationValue( 1909 const MachO::any_relocation_info &RE) const { 1910 return RE.r_word1; 1911 } 1912 1913 uint32_t MachOObjectFile::getScatteredRelocationType( 1914 const MachO::any_relocation_info &RE) const { 1915 return (RE.r_word0 >> 24) & 0xf; 1916 } 1917 1918 unsigned MachOObjectFile::getAnyRelocationAddress( 1919 const MachO::any_relocation_info &RE) const { 1920 if (isRelocationScattered(RE)) 1921 return getScatteredRelocationAddress(RE); 1922 return getPlainRelocationAddress(RE); 1923 } 1924 1925 unsigned MachOObjectFile::getAnyRelocationPCRel( 1926 const MachO::any_relocation_info &RE) const { 1927 if (isRelocationScattered(RE)) 1928 return getScatteredRelocationPCRel(this, RE); 1929 return getPlainRelocationPCRel(this, RE); 1930 } 1931 1932 unsigned MachOObjectFile::getAnyRelocationLength( 1933 const MachO::any_relocation_info &RE) const { 1934 if (isRelocationScattered(RE)) 1935 return getScatteredRelocationLength(RE); 1936 return getPlainRelocationLength(this, RE); 1937 } 1938 1939 unsigned 1940 MachOObjectFile::getAnyRelocationType( 1941 const MachO::any_relocation_info &RE) const { 1942 if (isRelocationScattered(RE)) 1943 return getScatteredRelocationType(RE); 1944 return getPlainRelocationType(this, RE); 1945 } 1946 1947 SectionRef 1948 MachOObjectFile::getAnyRelocationSection( 1949 const MachO::any_relocation_info &RE) const { 1950 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 1951 return *section_end(); 1952 unsigned SecNum = getPlainRelocationSymbolNum(RE); 1953 if (SecNum == MachO::R_ABS || SecNum > Sections.size()) 1954 return *section_end(); 1955 DataRefImpl DRI; 1956 DRI.d.a = SecNum - 1; 1957 return SectionRef(DRI, this); 1958 } 1959 1960 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 1961 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 1962 return getStruct<MachO::section>(this, Sections[DRI.d.a]); 1963 } 1964 1965 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 1966 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 1967 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]); 1968 } 1969 1970 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 1971 unsigned Index) const { 1972 const char *Sec = getSectionPtr(this, L, Index); 1973 return getStruct<MachO::section>(this, Sec); 1974 } 1975 1976 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 1977 unsigned Index) const { 1978 const char *Sec = getSectionPtr(this, L, Index); 1979 return getStruct<MachO::section_64>(this, Sec); 1980 } 1981 1982 MachO::nlist 1983 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 1984 const char *P = reinterpret_cast<const char *>(DRI.p); 1985 return getStruct<MachO::nlist>(this, P); 1986 } 1987 1988 MachO::nlist_64 1989 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 1990 const char *P = reinterpret_cast<const char *>(DRI.p); 1991 return getStruct<MachO::nlist_64>(this, P); 1992 } 1993 1994 MachO::linkedit_data_command 1995 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 1996 return getStruct<MachO::linkedit_data_command>(this, L.Ptr); 1997 } 1998 1999 MachO::segment_command 2000 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 2001 return getStruct<MachO::segment_command>(this, L.Ptr); 2002 } 2003 2004 MachO::segment_command_64 2005 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 2006 return getStruct<MachO::segment_command_64>(this, L.Ptr); 2007 } 2008 2009 MachO::linker_option_command 2010 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const { 2011 return getStruct<MachO::linker_option_command>(this, L.Ptr); 2012 } 2013 2014 MachO::version_min_command 2015 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 2016 return getStruct<MachO::version_min_command>(this, L.Ptr); 2017 } 2018 2019 MachO::dylib_command 2020 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 2021 return getStruct<MachO::dylib_command>(this, L.Ptr); 2022 } 2023 2024 MachO::dyld_info_command 2025 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const { 2026 return getStruct<MachO::dyld_info_command>(this, L.Ptr); 2027 } 2028 2029 MachO::dylinker_command 2030 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const { 2031 return getStruct<MachO::dylinker_command>(this, L.Ptr); 2032 } 2033 2034 MachO::uuid_command 2035 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const { 2036 return getStruct<MachO::uuid_command>(this, L.Ptr); 2037 } 2038 2039 MachO::rpath_command 2040 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const { 2041 return getStruct<MachO::rpath_command>(this, L.Ptr); 2042 } 2043 2044 MachO::source_version_command 2045 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const { 2046 return getStruct<MachO::source_version_command>(this, L.Ptr); 2047 } 2048 2049 MachO::entry_point_command 2050 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const { 2051 return getStruct<MachO::entry_point_command>(this, L.Ptr); 2052 } 2053 2054 MachO::encryption_info_command 2055 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const { 2056 return getStruct<MachO::encryption_info_command>(this, L.Ptr); 2057 } 2058 2059 MachO::encryption_info_command_64 2060 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const { 2061 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr); 2062 } 2063 2064 MachO::sub_framework_command 2065 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const { 2066 return getStruct<MachO::sub_framework_command>(this, L.Ptr); 2067 } 2068 2069 MachO::sub_umbrella_command 2070 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const { 2071 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr); 2072 } 2073 2074 MachO::sub_library_command 2075 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const { 2076 return getStruct<MachO::sub_library_command>(this, L.Ptr); 2077 } 2078 2079 MachO::sub_client_command 2080 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const { 2081 return getStruct<MachO::sub_client_command>(this, L.Ptr); 2082 } 2083 2084 MachO::routines_command 2085 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const { 2086 return getStruct<MachO::routines_command>(this, L.Ptr); 2087 } 2088 2089 MachO::routines_command_64 2090 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const { 2091 return getStruct<MachO::routines_command_64>(this, L.Ptr); 2092 } 2093 2094 MachO::thread_command 2095 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { 2096 return getStruct<MachO::thread_command>(this, L.Ptr); 2097 } 2098 2099 MachO::any_relocation_info 2100 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 2101 DataRefImpl Sec; 2102 Sec.d.a = Rel.d.a; 2103 uint32_t Offset; 2104 if (is64Bit()) { 2105 MachO::section_64 Sect = getSection64(Sec); 2106 Offset = Sect.reloff; 2107 } else { 2108 MachO::section Sect = getSection(Sec); 2109 Offset = Sect.reloff; 2110 } 2111 2112 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 2113 getPtr(this, Offset)) + Rel.d.b; 2114 return getStruct<MachO::any_relocation_info>( 2115 this, reinterpret_cast<const char *>(P)); 2116 } 2117 2118 MachO::data_in_code_entry 2119 MachOObjectFile::getDice(DataRefImpl Rel) const { 2120 const char *P = reinterpret_cast<const char *>(Rel.p); 2121 return getStruct<MachO::data_in_code_entry>(this, P); 2122 } 2123 2124 const MachO::mach_header &MachOObjectFile::getHeader() const { 2125 return Header; 2126 } 2127 2128 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const { 2129 assert(is64Bit()); 2130 return Header64; 2131 } 2132 2133 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 2134 const MachO::dysymtab_command &DLC, 2135 unsigned Index) const { 2136 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 2137 return getStruct<uint32_t>(this, getPtr(this, Offset)); 2138 } 2139 2140 MachO::data_in_code_entry 2141 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 2142 unsigned Index) const { 2143 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 2144 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset)); 2145 } 2146 2147 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 2148 if (SymtabLoadCmd) 2149 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd); 2150 2151 // If there is no SymtabLoadCmd return a load command with zero'ed fields. 2152 MachO::symtab_command Cmd; 2153 Cmd.cmd = MachO::LC_SYMTAB; 2154 Cmd.cmdsize = sizeof(MachO::symtab_command); 2155 Cmd.symoff = 0; 2156 Cmd.nsyms = 0; 2157 Cmd.stroff = 0; 2158 Cmd.strsize = 0; 2159 return Cmd; 2160 } 2161 2162 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 2163 if (DysymtabLoadCmd) 2164 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd); 2165 2166 // If there is no DysymtabLoadCmd return a load command with zero'ed fields. 2167 MachO::dysymtab_command Cmd; 2168 Cmd.cmd = MachO::LC_DYSYMTAB; 2169 Cmd.cmdsize = sizeof(MachO::dysymtab_command); 2170 Cmd.ilocalsym = 0; 2171 Cmd.nlocalsym = 0; 2172 Cmd.iextdefsym = 0; 2173 Cmd.nextdefsym = 0; 2174 Cmd.iundefsym = 0; 2175 Cmd.nundefsym = 0; 2176 Cmd.tocoff = 0; 2177 Cmd.ntoc = 0; 2178 Cmd.modtaboff = 0; 2179 Cmd.nmodtab = 0; 2180 Cmd.extrefsymoff = 0; 2181 Cmd.nextrefsyms = 0; 2182 Cmd.indirectsymoff = 0; 2183 Cmd.nindirectsyms = 0; 2184 Cmd.extreloff = 0; 2185 Cmd.nextrel = 0; 2186 Cmd.locreloff = 0; 2187 Cmd.nlocrel = 0; 2188 return Cmd; 2189 } 2190 2191 MachO::linkedit_data_command 2192 MachOObjectFile::getDataInCodeLoadCommand() const { 2193 if (DataInCodeLoadCmd) 2194 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd); 2195 2196 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 2197 MachO::linkedit_data_command Cmd; 2198 Cmd.cmd = MachO::LC_DATA_IN_CODE; 2199 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2200 Cmd.dataoff = 0; 2201 Cmd.datasize = 0; 2202 return Cmd; 2203 } 2204 2205 MachO::linkedit_data_command 2206 MachOObjectFile::getLinkOptHintsLoadCommand() const { 2207 if (LinkOptHintsLoadCmd) 2208 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd); 2209 2210 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed 2211 // fields. 2212 MachO::linkedit_data_command Cmd; 2213 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; 2214 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2215 Cmd.dataoff = 0; 2216 Cmd.datasize = 0; 2217 return Cmd; 2218 } 2219 2220 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { 2221 if (!DyldInfoLoadCmd) 2222 return None; 2223 2224 MachO::dyld_info_command DyldInfo = 2225 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2226 const uint8_t *Ptr = 2227 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off)); 2228 return makeArrayRef(Ptr, DyldInfo.rebase_size); 2229 } 2230 2231 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 2232 if (!DyldInfoLoadCmd) 2233 return None; 2234 2235 MachO::dyld_info_command DyldInfo = 2236 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2237 const uint8_t *Ptr = 2238 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off)); 2239 return makeArrayRef(Ptr, DyldInfo.bind_size); 2240 } 2241 2242 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 2243 if (!DyldInfoLoadCmd) 2244 return None; 2245 2246 MachO::dyld_info_command DyldInfo = 2247 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2248 const uint8_t *Ptr = 2249 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off)); 2250 return makeArrayRef(Ptr, DyldInfo.weak_bind_size); 2251 } 2252 2253 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 2254 if (!DyldInfoLoadCmd) 2255 return None; 2256 2257 MachO::dyld_info_command DyldInfo = 2258 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2259 const uint8_t *Ptr = 2260 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off)); 2261 return makeArrayRef(Ptr, DyldInfo.lazy_bind_size); 2262 } 2263 2264 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 2265 if (!DyldInfoLoadCmd) 2266 return None; 2267 2268 MachO::dyld_info_command DyldInfo = 2269 getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2270 const uint8_t *Ptr = 2271 reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off)); 2272 return makeArrayRef(Ptr, DyldInfo.export_size); 2273 } 2274 2275 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 2276 if (!UuidLoadCmd) 2277 return None; 2278 // Returning a pointer is fine as uuid doesn't need endian swapping. 2279 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); 2280 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16); 2281 } 2282 2283 StringRef MachOObjectFile::getStringTableData() const { 2284 MachO::symtab_command S = getSymtabLoadCommand(); 2285 return getData().substr(S.stroff, S.strsize); 2286 } 2287 2288 bool MachOObjectFile::is64Bit() const { 2289 return getType() == getMachOType(false, true) || 2290 getType() == getMachOType(true, true); 2291 } 2292 2293 void MachOObjectFile::ReadULEB128s(uint64_t Index, 2294 SmallVectorImpl<uint64_t> &Out) const { 2295 DataExtractor extractor(ObjectFile::getData(), true, 0); 2296 2297 uint32_t offset = Index; 2298 uint64_t data = 0; 2299 while (uint64_t delta = extractor.getULEB128(&offset)) { 2300 data += delta; 2301 Out.push_back(data); 2302 } 2303 } 2304 2305 bool MachOObjectFile::isRelocatableObject() const { 2306 return getHeader().filetype == MachO::MH_OBJECT; 2307 } 2308 2309 ErrorOr<std::unique_ptr<MachOObjectFile>> 2310 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) { 2311 StringRef Magic = Buffer.getBuffer().slice(0, 4); 2312 std::error_code EC; 2313 std::unique_ptr<MachOObjectFile> Ret; 2314 if (Magic == "\xFE\xED\xFA\xCE") 2315 Ret.reset(new MachOObjectFile(Buffer, false, false, EC)); 2316 else if (Magic == "\xCE\xFA\xED\xFE") 2317 Ret.reset(new MachOObjectFile(Buffer, true, false, EC)); 2318 else if (Magic == "\xFE\xED\xFA\xCF") 2319 Ret.reset(new MachOObjectFile(Buffer, false, true, EC)); 2320 else if (Magic == "\xCF\xFA\xED\xFE") 2321 Ret.reset(new MachOObjectFile(Buffer, true, true, EC)); 2322 else 2323 return object_error::parse_failed; 2324 2325 if (EC) 2326 return EC; 2327 return std::move(Ret); 2328 } 2329