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