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