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