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