1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the MachOObjectFile class, which binds the MachOObject 11 // class to the generic ObjectFile wrapper. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Object/MachO.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Support/DataExtractor.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/Format.h" 22 #include "llvm/Support/Host.h" 23 #include "llvm/Support/LEB128.h" 24 #include "llvm/Support/MachO.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <cctype> 28 #include <cstring> 29 #include <limits> 30 31 using namespace llvm; 32 using namespace object; 33 34 namespace { 35 struct section_base { 36 char sectname[16]; 37 char segname[16]; 38 }; 39 } 40 41 // FIXME: Replace all uses of this function with getStructOrErr. 42 template <typename T> 43 static T getStruct(const MachOObjectFile *O, const char *P) { 44 // Don't read before the beginning or past the end of the file 45 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end()) 46 report_fatal_error("Malformed MachO file."); 47 48 T Cmd; 49 memcpy(&Cmd, P, sizeof(T)); 50 if (O->isLittleEndian() != sys::IsLittleEndianHost) 51 MachO::swapStruct(Cmd); 52 return Cmd; 53 } 54 55 template <typename T> 56 static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) { 57 // Don't read before the beginning or past the end of the file 58 if (P < O->getData().begin() || P + sizeof(T) > O->getData().end()) 59 return object_error::parse_failed; 60 61 T Cmd; 62 memcpy(&Cmd, P, sizeof(T)); 63 if (O->isLittleEndian() != sys::IsLittleEndianHost) 64 MachO::swapStruct(Cmd); 65 return Cmd; 66 } 67 68 static const char * 69 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, 70 unsigned Sec) { 71 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr); 72 73 bool Is64 = O->is64Bit(); 74 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) : 75 sizeof(MachO::segment_command); 76 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) : 77 sizeof(MachO::section); 78 79 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; 80 return reinterpret_cast<const char*>(SectionAddr); 81 } 82 83 static const char *getPtr(const MachOObjectFile *O, size_t Offset) { 84 return O->getData().substr(Offset, 1).data(); 85 } 86 87 static MachO::nlist_base 88 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { 89 const char *P = reinterpret_cast<const char *>(DRI.p); 90 return getStruct<MachO::nlist_base>(O, P); 91 } 92 93 static StringRef parseSegmentOrSectionName(const char *P) { 94 if (P[15] == 0) 95 // Null terminated. 96 return P; 97 // Not null terminated, so this is a 16 char string. 98 return StringRef(P, 16); 99 } 100 101 // Helper to advance a section or symbol iterator multiple increments at a time. 102 template<class T> 103 static void advance(T &it, size_t Val) { 104 while (Val--) 105 ++it; 106 } 107 108 static unsigned getCPUType(const MachOObjectFile *O) { 109 return O->getHeader().cputype; 110 } 111 112 static uint32_t 113 getPlainRelocationAddress(const MachO::any_relocation_info &RE) { 114 return RE.r_word0; 115 } 116 117 static unsigned 118 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) { 119 return RE.r_word0 & 0xffffff; 120 } 121 122 static bool getPlainRelocationPCRel(const MachOObjectFile *O, 123 const MachO::any_relocation_info &RE) { 124 if (O->isLittleEndian()) 125 return (RE.r_word1 >> 24) & 1; 126 return (RE.r_word1 >> 7) & 1; 127 } 128 129 static bool 130 getScatteredRelocationPCRel(const MachOObjectFile *O, 131 const MachO::any_relocation_info &RE) { 132 return (RE.r_word0 >> 30) & 1; 133 } 134 135 static unsigned getPlainRelocationLength(const MachOObjectFile *O, 136 const MachO::any_relocation_info &RE) { 137 if (O->isLittleEndian()) 138 return (RE.r_word1 >> 25) & 3; 139 return (RE.r_word1 >> 5) & 3; 140 } 141 142 static unsigned 143 getScatteredRelocationLength(const MachO::any_relocation_info &RE) { 144 return (RE.r_word0 >> 28) & 3; 145 } 146 147 static unsigned getPlainRelocationType(const MachOObjectFile *O, 148 const MachO::any_relocation_info &RE) { 149 if (O->isLittleEndian()) 150 return RE.r_word1 >> 28; 151 return RE.r_word1 & 0xf; 152 } 153 154 static uint32_t getSectionFlags(const MachOObjectFile *O, 155 DataRefImpl Sec) { 156 if (O->is64Bit()) { 157 MachO::section_64 Sect = O->getSection64(Sec); 158 return Sect.flags; 159 } 160 MachO::section Sect = O->getSection(Sec); 161 return Sect.flags; 162 } 163 164 static ErrorOr<MachOObjectFile::LoadCommandInfo> 165 getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) { 166 auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr); 167 if (!CmdOrErr) 168 return CmdOrErr.getError(); 169 if (CmdOrErr->cmdsize < 8) 170 return object_error::macho_small_load_command; 171 MachOObjectFile::LoadCommandInfo Load; 172 Load.Ptr = Ptr; 173 Load.C = CmdOrErr.get(); 174 return Load; 175 } 176 177 static ErrorOr<MachOObjectFile::LoadCommandInfo> 178 getFirstLoadCommandInfo(const MachOObjectFile *Obj) { 179 unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64) 180 : sizeof(MachO::mach_header); 181 return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize)); 182 } 183 184 static ErrorOr<MachOObjectFile::LoadCommandInfo> 185 getNextLoadCommandInfo(const MachOObjectFile *Obj, 186 const MachOObjectFile::LoadCommandInfo &L) { 187 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize); 188 } 189 190 template <typename T> 191 static void parseHeader(const MachOObjectFile *Obj, T &Header, 192 std::error_code &EC) { 193 auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)); 194 if (HeaderOrErr) 195 Header = HeaderOrErr.get(); 196 else 197 EC = HeaderOrErr.getError(); 198 } 199 200 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all 201 // sections to \param Sections, and optionally sets 202 // \param IsPageZeroSegment to true. 203 template <typename SegmentCmd> 204 static std::error_code parseSegmentLoadCommand( 205 const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load, 206 SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment) { 207 const unsigned SegmentLoadSize = sizeof(SegmentCmd); 208 if (Load.C.cmdsize < SegmentLoadSize) 209 return object_error::macho_load_segment_too_small; 210 auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr); 211 if (!SegOrErr) 212 return SegOrErr.getError(); 213 SegmentCmd S = SegOrErr.get(); 214 const unsigned SectionSize = 215 Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section); 216 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize || 217 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize) 218 return object_error::macho_load_segment_too_many_sections; 219 for (unsigned J = 0; J < S.nsects; ++J) { 220 const char *Sec = getSectionPtr(Obj, Load, J); 221 Sections.push_back(Sec); 222 } 223 IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname); 224 return std::error_code(); 225 } 226 227 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, 228 bool Is64bits, std::error_code &EC) 229 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), 230 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), 231 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr), 232 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr), 233 HasPageZeroSegment(false) { 234 if (is64Bit()) 235 parseHeader(this, Header64, EC); 236 else 237 parseHeader(this, Header, EC); 238 if (EC) 239 return; 240 241 uint32_t LoadCommandCount = getHeader().ncmds; 242 if (LoadCommandCount == 0) 243 return; 244 245 auto LoadOrErr = getFirstLoadCommandInfo(this); 246 if (!LoadOrErr) { 247 EC = LoadOrErr.getError(); 248 return; 249 } 250 LoadCommandInfo Load = LoadOrErr.get(); 251 for (unsigned I = 0; I < LoadCommandCount; ++I) { 252 LoadCommands.push_back(Load); 253 if (Load.C.cmd == MachO::LC_SYMTAB) { 254 // Multiple symbol tables 255 if (SymtabLoadCmd) { 256 EC = object_error::parse_failed; 257 return; 258 } 259 SymtabLoadCmd = Load.Ptr; 260 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) { 261 // Multiple dynamic symbol tables 262 if (DysymtabLoadCmd) { 263 EC = object_error::parse_failed; 264 return; 265 } 266 DysymtabLoadCmd = Load.Ptr; 267 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) { 268 // Multiple data in code tables 269 if (DataInCodeLoadCmd) { 270 EC = object_error::parse_failed; 271 return; 272 } 273 DataInCodeLoadCmd = Load.Ptr; 274 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) { 275 // Multiple linker optimization hint tables 276 if (LinkOptHintsLoadCmd) { 277 EC = object_error::parse_failed; 278 return; 279 } 280 LinkOptHintsLoadCmd = Load.Ptr; 281 } else if (Load.C.cmd == MachO::LC_DYLD_INFO || 282 Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) { 283 // Multiple dyldinfo load commands 284 if (DyldInfoLoadCmd) { 285 EC = object_error::parse_failed; 286 return; 287 } 288 DyldInfoLoadCmd = Load.Ptr; 289 } else if (Load.C.cmd == MachO::LC_UUID) { 290 // Multiple UUID load commands 291 if (UuidLoadCmd) { 292 EC = object_error::parse_failed; 293 return; 294 } 295 UuidLoadCmd = Load.Ptr; 296 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) { 297 if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>( 298 this, Load, Sections, HasPageZeroSegment))) 299 return; 300 } else if (Load.C.cmd == MachO::LC_SEGMENT) { 301 if ((EC = parseSegmentLoadCommand<MachO::segment_command>( 302 this, Load, Sections, HasPageZeroSegment))) 303 return; 304 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB || 305 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB || 306 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB || 307 Load.C.cmd == MachO::LC_REEXPORT_DYLIB || 308 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) { 309 Libraries.push_back(Load.Ptr); 310 } 311 if (I < LoadCommandCount - 1) { 312 auto LoadOrErr = getNextLoadCommandInfo(this, Load); 313 if (!LoadOrErr) { 314 EC = LoadOrErr.getError(); 315 return; 316 } 317 Load = LoadOrErr.get(); 318 } 319 } 320 assert(LoadCommands.size() == LoadCommandCount); 321 } 322 323 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 324 unsigned SymbolTableEntrySize = is64Bit() ? 325 sizeof(MachO::nlist_64) : 326 sizeof(MachO::nlist); 327 Symb.p += SymbolTableEntrySize; 328 } 329 330 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 std::error_code(); 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 *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault); 1252 return getArch(Header.cputype, Header.cpusubtype, McpuDefault); 1253 } 1254 1255 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 1256 DataRefImpl DRI; 1257 DRI.d.a = Index; 1258 return section_rel_begin(DRI); 1259 } 1260 1261 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 1262 DataRefImpl DRI; 1263 DRI.d.a = Index; 1264 return section_rel_end(DRI); 1265 } 1266 1267 dice_iterator MachOObjectFile::begin_dices() const { 1268 DataRefImpl DRI; 1269 if (!DataInCodeLoadCmd) 1270 return dice_iterator(DiceRef(DRI, this)); 1271 1272 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1273 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff)); 1274 return dice_iterator(DiceRef(DRI, this)); 1275 } 1276 1277 dice_iterator MachOObjectFile::end_dices() const { 1278 DataRefImpl DRI; 1279 if (!DataInCodeLoadCmd) 1280 return dice_iterator(DiceRef(DRI, this)); 1281 1282 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1283 unsigned Offset = DicLC.dataoff + DicLC.datasize; 1284 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1285 return dice_iterator(DiceRef(DRI, this)); 1286 } 1287 1288 ExportEntry::ExportEntry(ArrayRef<uint8_t> T) 1289 : Trie(T), Malformed(false), Done(false) { } 1290 1291 void ExportEntry::moveToFirst() { 1292 pushNode(0); 1293 pushDownUntilBottom(); 1294 } 1295 1296 void ExportEntry::moveToEnd() { 1297 Stack.clear(); 1298 Done = true; 1299 } 1300 1301 bool ExportEntry::operator==(const ExportEntry &Other) const { 1302 // Common case, one at end, other iterating from begin. 1303 if (Done || Other.Done) 1304 return (Done == Other.Done); 1305 // Not equal if different stack sizes. 1306 if (Stack.size() != Other.Stack.size()) 1307 return false; 1308 // Not equal if different cumulative strings. 1309 if (!CumulativeString.equals(Other.CumulativeString)) 1310 return false; 1311 // Equal if all nodes in both stacks match. 1312 for (unsigned i=0; i < Stack.size(); ++i) { 1313 if (Stack[i].Start != Other.Stack[i].Start) 1314 return false; 1315 } 1316 return true; 1317 } 1318 1319 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { 1320 unsigned Count; 1321 uint64_t Result = decodeULEB128(Ptr, &Count); 1322 Ptr += Count; 1323 if (Ptr > Trie.end()) { 1324 Ptr = Trie.end(); 1325 Malformed = true; 1326 } 1327 return Result; 1328 } 1329 1330 StringRef ExportEntry::name() const { 1331 return CumulativeString; 1332 } 1333 1334 uint64_t ExportEntry::flags() const { 1335 return Stack.back().Flags; 1336 } 1337 1338 uint64_t ExportEntry::address() const { 1339 return Stack.back().Address; 1340 } 1341 1342 uint64_t ExportEntry::other() const { 1343 return Stack.back().Other; 1344 } 1345 1346 StringRef ExportEntry::otherName() const { 1347 const char* ImportName = Stack.back().ImportName; 1348 if (ImportName) 1349 return StringRef(ImportName); 1350 return StringRef(); 1351 } 1352 1353 uint32_t ExportEntry::nodeOffset() const { 1354 return Stack.back().Start - Trie.begin(); 1355 } 1356 1357 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 1358 : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), 1359 ImportName(nullptr), ChildCount(0), NextChildIndex(0), 1360 ParentStringLength(0), IsExportNode(false) { 1361 } 1362 1363 void ExportEntry::pushNode(uint64_t offset) { 1364 const uint8_t *Ptr = Trie.begin() + offset; 1365 NodeState State(Ptr); 1366 uint64_t ExportInfoSize = readULEB128(State.Current); 1367 State.IsExportNode = (ExportInfoSize != 0); 1368 const uint8_t* Children = State.Current + ExportInfoSize; 1369 if (State.IsExportNode) { 1370 State.Flags = readULEB128(State.Current); 1371 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 1372 State.Address = 0; 1373 State.Other = readULEB128(State.Current); // dylib ordinal 1374 State.ImportName = reinterpret_cast<const char*>(State.Current); 1375 } else { 1376 State.Address = readULEB128(State.Current); 1377 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) 1378 State.Other = readULEB128(State.Current); 1379 } 1380 } 1381 State.ChildCount = *Children; 1382 State.Current = Children + 1; 1383 State.NextChildIndex = 0; 1384 State.ParentStringLength = CumulativeString.size(); 1385 Stack.push_back(State); 1386 } 1387 1388 void ExportEntry::pushDownUntilBottom() { 1389 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 1390 NodeState &Top = Stack.back(); 1391 CumulativeString.resize(Top.ParentStringLength); 1392 for (;*Top.Current != 0; Top.Current++) { 1393 char C = *Top.Current; 1394 CumulativeString.push_back(C); 1395 } 1396 Top.Current += 1; 1397 uint64_t childNodeIndex = readULEB128(Top.Current); 1398 Top.NextChildIndex += 1; 1399 pushNode(childNodeIndex); 1400 } 1401 if (!Stack.back().IsExportNode) { 1402 Malformed = true; 1403 moveToEnd(); 1404 } 1405 } 1406 1407 // We have a trie data structure and need a way to walk it that is compatible 1408 // with the C++ iterator model. The solution is a non-recursive depth first 1409 // traversal where the iterator contains a stack of parent nodes along with a 1410 // string that is the accumulation of all edge strings along the parent chain 1411 // to this point. 1412 // 1413 // There is one "export" node for each exported symbol. But because some 1414 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 1415 // node may have child nodes too. 1416 // 1417 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 1418 // child until hitting a node with no children (which is an export node or 1419 // else the trie is malformed). On the way down, each node is pushed on the 1420 // stack ivar. If there is no more ways down, it pops up one and tries to go 1421 // down a sibling path until a childless node is reached. 1422 void ExportEntry::moveNext() { 1423 if (Stack.empty() || !Stack.back().IsExportNode) { 1424 Malformed = true; 1425 moveToEnd(); 1426 return; 1427 } 1428 1429 Stack.pop_back(); 1430 while (!Stack.empty()) { 1431 NodeState &Top = Stack.back(); 1432 if (Top.NextChildIndex < Top.ChildCount) { 1433 pushDownUntilBottom(); 1434 // Now at the next export node. 1435 return; 1436 } else { 1437 if (Top.IsExportNode) { 1438 // This node has no children but is itself an export node. 1439 CumulativeString.resize(Top.ParentStringLength); 1440 return; 1441 } 1442 Stack.pop_back(); 1443 } 1444 } 1445 Done = true; 1446 } 1447 1448 iterator_range<export_iterator> 1449 MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { 1450 ExportEntry Start(Trie); 1451 if (Trie.size() == 0) 1452 Start.moveToEnd(); 1453 else 1454 Start.moveToFirst(); 1455 1456 ExportEntry Finish(Trie); 1457 Finish.moveToEnd(); 1458 1459 return iterator_range<export_iterator>(export_iterator(Start), 1460 export_iterator(Finish)); 1461 } 1462 1463 iterator_range<export_iterator> MachOObjectFile::exports() const { 1464 return exports(getDyldInfoExportsTrie()); 1465 } 1466 1467 1468 MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit) 1469 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1470 RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0), 1471 PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {} 1472 1473 void MachORebaseEntry::moveToFirst() { 1474 Ptr = Opcodes.begin(); 1475 moveNext(); 1476 } 1477 1478 void MachORebaseEntry::moveToEnd() { 1479 Ptr = Opcodes.end(); 1480 RemainingLoopCount = 0; 1481 Done = true; 1482 } 1483 1484 void MachORebaseEntry::moveNext() { 1485 // If in the middle of some loop, move to next rebasing in loop. 1486 SegmentOffset += AdvanceAmount; 1487 if (RemainingLoopCount) { 1488 --RemainingLoopCount; 1489 return; 1490 } 1491 if (Ptr == Opcodes.end()) { 1492 Done = true; 1493 return; 1494 } 1495 bool More = true; 1496 while (More && !Malformed) { 1497 // Parse next opcode and set up next loop. 1498 uint8_t Byte = *Ptr++; 1499 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 1500 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 1501 switch (Opcode) { 1502 case MachO::REBASE_OPCODE_DONE: 1503 More = false; 1504 Done = true; 1505 moveToEnd(); 1506 DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n"); 1507 break; 1508 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 1509 RebaseType = ImmValue; 1510 DEBUG_WITH_TYPE( 1511 "mach-o-rebase", 1512 llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 1513 << "RebaseType=" << (int) RebaseType << "\n"); 1514 break; 1515 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1516 SegmentIndex = ImmValue; 1517 SegmentOffset = readULEB128(); 1518 DEBUG_WITH_TYPE( 1519 "mach-o-rebase", 1520 llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1521 << "SegmentIndex=" << SegmentIndex << ", " 1522 << format("SegmentOffset=0x%06X", SegmentOffset) 1523 << "\n"); 1524 break; 1525 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 1526 SegmentOffset += readULEB128(); 1527 DEBUG_WITH_TYPE("mach-o-rebase", 1528 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 1529 << format("SegmentOffset=0x%06X", 1530 SegmentOffset) << "\n"); 1531 break; 1532 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 1533 SegmentOffset += ImmValue * PointerSize; 1534 DEBUG_WITH_TYPE("mach-o-rebase", 1535 llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 1536 << format("SegmentOffset=0x%06X", 1537 SegmentOffset) << "\n"); 1538 break; 1539 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 1540 AdvanceAmount = PointerSize; 1541 RemainingLoopCount = ImmValue - 1; 1542 DEBUG_WITH_TYPE( 1543 "mach-o-rebase", 1544 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 1545 << format("SegmentOffset=0x%06X", SegmentOffset) 1546 << ", AdvanceAmount=" << AdvanceAmount 1547 << ", RemainingLoopCount=" << RemainingLoopCount 1548 << "\n"); 1549 return; 1550 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 1551 AdvanceAmount = PointerSize; 1552 RemainingLoopCount = readULEB128() - 1; 1553 DEBUG_WITH_TYPE( 1554 "mach-o-rebase", 1555 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 1556 << format("SegmentOffset=0x%06X", SegmentOffset) 1557 << ", AdvanceAmount=" << AdvanceAmount 1558 << ", RemainingLoopCount=" << RemainingLoopCount 1559 << "\n"); 1560 return; 1561 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 1562 AdvanceAmount = readULEB128() + PointerSize; 1563 RemainingLoopCount = 0; 1564 DEBUG_WITH_TYPE( 1565 "mach-o-rebase", 1566 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 1567 << format("SegmentOffset=0x%06X", SegmentOffset) 1568 << ", AdvanceAmount=" << AdvanceAmount 1569 << ", RemainingLoopCount=" << RemainingLoopCount 1570 << "\n"); 1571 return; 1572 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 1573 RemainingLoopCount = readULEB128() - 1; 1574 AdvanceAmount = readULEB128() + PointerSize; 1575 DEBUG_WITH_TYPE( 1576 "mach-o-rebase", 1577 llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 1578 << format("SegmentOffset=0x%06X", SegmentOffset) 1579 << ", AdvanceAmount=" << AdvanceAmount 1580 << ", RemainingLoopCount=" << RemainingLoopCount 1581 << "\n"); 1582 return; 1583 default: 1584 Malformed = true; 1585 } 1586 } 1587 } 1588 1589 uint64_t MachORebaseEntry::readULEB128() { 1590 unsigned Count; 1591 uint64_t Result = decodeULEB128(Ptr, &Count); 1592 Ptr += Count; 1593 if (Ptr > Opcodes.end()) { 1594 Ptr = Opcodes.end(); 1595 Malformed = true; 1596 } 1597 return Result; 1598 } 1599 1600 uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 1601 1602 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 1603 1604 StringRef MachORebaseEntry::typeName() const { 1605 switch (RebaseType) { 1606 case MachO::REBASE_TYPE_POINTER: 1607 return "pointer"; 1608 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 1609 return "text abs32"; 1610 case MachO::REBASE_TYPE_TEXT_PCREL32: 1611 return "text rel32"; 1612 } 1613 return "unknown"; 1614 } 1615 1616 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 1617 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1618 return (Ptr == Other.Ptr) && 1619 (RemainingLoopCount == Other.RemainingLoopCount) && 1620 (Done == Other.Done); 1621 } 1622 1623 iterator_range<rebase_iterator> 1624 MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) { 1625 MachORebaseEntry Start(Opcodes, is64); 1626 Start.moveToFirst(); 1627 1628 MachORebaseEntry Finish(Opcodes, is64); 1629 Finish.moveToEnd(); 1630 1631 return iterator_range<rebase_iterator>(rebase_iterator(Start), 1632 rebase_iterator(Finish)); 1633 } 1634 1635 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const { 1636 return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit()); 1637 } 1638 1639 1640 MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, 1641 Kind BK) 1642 : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), 1643 Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0), 1644 BindType(0), PointerSize(is64Bit ? 8 : 4), 1645 TableKind(BK), Malformed(false), Done(false) {} 1646 1647 void MachOBindEntry::moveToFirst() { 1648 Ptr = Opcodes.begin(); 1649 moveNext(); 1650 } 1651 1652 void MachOBindEntry::moveToEnd() { 1653 Ptr = Opcodes.end(); 1654 RemainingLoopCount = 0; 1655 Done = true; 1656 } 1657 1658 void MachOBindEntry::moveNext() { 1659 // If in the middle of some loop, move to next binding in loop. 1660 SegmentOffset += AdvanceAmount; 1661 if (RemainingLoopCount) { 1662 --RemainingLoopCount; 1663 return; 1664 } 1665 if (Ptr == Opcodes.end()) { 1666 Done = true; 1667 return; 1668 } 1669 bool More = true; 1670 while (More && !Malformed) { 1671 // Parse next opcode and set up next loop. 1672 uint8_t Byte = *Ptr++; 1673 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK; 1674 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK; 1675 int8_t SignExtended; 1676 const uint8_t *SymStart; 1677 switch (Opcode) { 1678 case MachO::BIND_OPCODE_DONE: 1679 if (TableKind == Kind::Lazy) { 1680 // Lazying bindings have a DONE opcode between entries. Need to ignore 1681 // it to advance to next entry. But need not if this is last entry. 1682 bool NotLastEntry = false; 1683 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) { 1684 if (*P) { 1685 NotLastEntry = true; 1686 } 1687 } 1688 if (NotLastEntry) 1689 break; 1690 } 1691 More = false; 1692 Done = true; 1693 moveToEnd(); 1694 DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n"); 1695 break; 1696 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 1697 Ordinal = ImmValue; 1698 DEBUG_WITH_TYPE( 1699 "mach-o-bind", 1700 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 1701 << "Ordinal=" << Ordinal << "\n"); 1702 break; 1703 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 1704 Ordinal = readULEB128(); 1705 DEBUG_WITH_TYPE( 1706 "mach-o-bind", 1707 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 1708 << "Ordinal=" << Ordinal << "\n"); 1709 break; 1710 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 1711 if (ImmValue) { 1712 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue; 1713 Ordinal = SignExtended; 1714 } else 1715 Ordinal = 0; 1716 DEBUG_WITH_TYPE( 1717 "mach-o-bind", 1718 llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 1719 << "Ordinal=" << Ordinal << "\n"); 1720 break; 1721 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 1722 Flags = ImmValue; 1723 SymStart = Ptr; 1724 while (*Ptr) { 1725 ++Ptr; 1726 } 1727 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart), 1728 Ptr-SymStart); 1729 ++Ptr; 1730 DEBUG_WITH_TYPE( 1731 "mach-o-bind", 1732 llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 1733 << "SymbolName=" << SymbolName << "\n"); 1734 if (TableKind == Kind::Weak) { 1735 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) 1736 return; 1737 } 1738 break; 1739 case MachO::BIND_OPCODE_SET_TYPE_IMM: 1740 BindType = ImmValue; 1741 DEBUG_WITH_TYPE( 1742 "mach-o-bind", 1743 llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: " 1744 << "BindType=" << (int)BindType << "\n"); 1745 break; 1746 case MachO::BIND_OPCODE_SET_ADDEND_SLEB: 1747 Addend = readSLEB128(); 1748 if (TableKind == Kind::Lazy) 1749 Malformed = true; 1750 DEBUG_WITH_TYPE( 1751 "mach-o-bind", 1752 llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: " 1753 << "Addend=" << Addend << "\n"); 1754 break; 1755 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 1756 SegmentIndex = ImmValue; 1757 SegmentOffset = readULEB128(); 1758 DEBUG_WITH_TYPE( 1759 "mach-o-bind", 1760 llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 1761 << "SegmentIndex=" << SegmentIndex << ", " 1762 << format("SegmentOffset=0x%06X", SegmentOffset) 1763 << "\n"); 1764 break; 1765 case MachO::BIND_OPCODE_ADD_ADDR_ULEB: 1766 SegmentOffset += readULEB128(); 1767 DEBUG_WITH_TYPE("mach-o-bind", 1768 llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: " 1769 << format("SegmentOffset=0x%06X", 1770 SegmentOffset) << "\n"); 1771 break; 1772 case MachO::BIND_OPCODE_DO_BIND: 1773 AdvanceAmount = PointerSize; 1774 RemainingLoopCount = 0; 1775 DEBUG_WITH_TYPE("mach-o-bind", 1776 llvm::dbgs() << "BIND_OPCODE_DO_BIND: " 1777 << format("SegmentOffset=0x%06X", 1778 SegmentOffset) << "\n"); 1779 return; 1780 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 1781 AdvanceAmount = readULEB128() + PointerSize; 1782 RemainingLoopCount = 0; 1783 if (TableKind == Kind::Lazy) 1784 Malformed = true; 1785 DEBUG_WITH_TYPE( 1786 "mach-o-bind", 1787 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 1788 << format("SegmentOffset=0x%06X", SegmentOffset) 1789 << ", AdvanceAmount=" << AdvanceAmount 1790 << ", RemainingLoopCount=" << RemainingLoopCount 1791 << "\n"); 1792 return; 1793 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 1794 AdvanceAmount = ImmValue * PointerSize + PointerSize; 1795 RemainingLoopCount = 0; 1796 if (TableKind == Kind::Lazy) 1797 Malformed = true; 1798 DEBUG_WITH_TYPE("mach-o-bind", 1799 llvm::dbgs() 1800 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 1801 << format("SegmentOffset=0x%06X", 1802 SegmentOffset) << "\n"); 1803 return; 1804 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 1805 RemainingLoopCount = readULEB128() - 1; 1806 AdvanceAmount = readULEB128() + PointerSize; 1807 if (TableKind == Kind::Lazy) 1808 Malformed = true; 1809 DEBUG_WITH_TYPE( 1810 "mach-o-bind", 1811 llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 1812 << format("SegmentOffset=0x%06X", SegmentOffset) 1813 << ", AdvanceAmount=" << AdvanceAmount 1814 << ", RemainingLoopCount=" << RemainingLoopCount 1815 << "\n"); 1816 return; 1817 default: 1818 Malformed = true; 1819 } 1820 } 1821 } 1822 1823 uint64_t MachOBindEntry::readULEB128() { 1824 unsigned Count; 1825 uint64_t Result = decodeULEB128(Ptr, &Count); 1826 Ptr += Count; 1827 if (Ptr > Opcodes.end()) { 1828 Ptr = Opcodes.end(); 1829 Malformed = true; 1830 } 1831 return Result; 1832 } 1833 1834 int64_t MachOBindEntry::readSLEB128() { 1835 unsigned Count; 1836 int64_t Result = decodeSLEB128(Ptr, &Count); 1837 Ptr += Count; 1838 if (Ptr > Opcodes.end()) { 1839 Ptr = Opcodes.end(); 1840 Malformed = true; 1841 } 1842 return Result; 1843 } 1844 1845 1846 uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; } 1847 1848 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; } 1849 1850 StringRef MachOBindEntry::typeName() const { 1851 switch (BindType) { 1852 case MachO::BIND_TYPE_POINTER: 1853 return "pointer"; 1854 case MachO::BIND_TYPE_TEXT_ABSOLUTE32: 1855 return "text abs32"; 1856 case MachO::BIND_TYPE_TEXT_PCREL32: 1857 return "text rel32"; 1858 } 1859 return "unknown"; 1860 } 1861 1862 StringRef MachOBindEntry::symbolName() const { return SymbolName; } 1863 1864 int64_t MachOBindEntry::addend() const { return Addend; } 1865 1866 uint32_t MachOBindEntry::flags() const { return Flags; } 1867 1868 int MachOBindEntry::ordinal() const { return Ordinal; } 1869 1870 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const { 1871 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 1872 return (Ptr == Other.Ptr) && 1873 (RemainingLoopCount == Other.RemainingLoopCount) && 1874 (Done == Other.Done); 1875 } 1876 1877 iterator_range<bind_iterator> 1878 MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64, 1879 MachOBindEntry::Kind BKind) { 1880 MachOBindEntry Start(Opcodes, is64, BKind); 1881 Start.moveToFirst(); 1882 1883 MachOBindEntry Finish(Opcodes, is64, BKind); 1884 Finish.moveToEnd(); 1885 1886 return iterator_range<bind_iterator>(bind_iterator(Start), 1887 bind_iterator(Finish)); 1888 } 1889 1890 iterator_range<bind_iterator> MachOObjectFile::bindTable() const { 1891 return bindTable(getDyldInfoBindOpcodes(), is64Bit(), 1892 MachOBindEntry::Kind::Regular); 1893 } 1894 1895 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const { 1896 return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(), 1897 MachOBindEntry::Kind::Lazy); 1898 } 1899 1900 iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const { 1901 return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(), 1902 MachOBindEntry::Kind::Weak); 1903 } 1904 1905 MachOObjectFile::load_command_iterator 1906 MachOObjectFile::begin_load_commands() const { 1907 return LoadCommands.begin(); 1908 } 1909 1910 MachOObjectFile::load_command_iterator 1911 MachOObjectFile::end_load_commands() const { 1912 return LoadCommands.end(); 1913 } 1914 1915 iterator_range<MachOObjectFile::load_command_iterator> 1916 MachOObjectFile::load_commands() const { 1917 return iterator_range<load_command_iterator>(begin_load_commands(), 1918 end_load_commands()); 1919 } 1920 1921 StringRef 1922 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 1923 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 1924 return parseSegmentOrSectionName(Raw.data()); 1925 } 1926 1927 ArrayRef<char> 1928 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 1929 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1930 const section_base *Base = 1931 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1932 return makeArrayRef(Base->sectname); 1933 } 1934 1935 ArrayRef<char> 1936 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 1937 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 1938 const section_base *Base = 1939 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1940 return makeArrayRef(Base->segname); 1941 } 1942 1943 bool 1944 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 1945 const { 1946 if (getCPUType(this) == MachO::CPU_TYPE_X86_64) 1947 return false; 1948 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 1949 } 1950 1951 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 1952 const MachO::any_relocation_info &RE) const { 1953 if (isLittleEndian()) 1954 return RE.r_word1 & 0xffffff; 1955 return RE.r_word1 >> 8; 1956 } 1957 1958 bool MachOObjectFile::getPlainRelocationExternal( 1959 const MachO::any_relocation_info &RE) const { 1960 if (isLittleEndian()) 1961 return (RE.r_word1 >> 27) & 1; 1962 return (RE.r_word1 >> 4) & 1; 1963 } 1964 1965 bool MachOObjectFile::getScatteredRelocationScattered( 1966 const MachO::any_relocation_info &RE) const { 1967 return RE.r_word0 >> 31; 1968 } 1969 1970 uint32_t MachOObjectFile::getScatteredRelocationValue( 1971 const MachO::any_relocation_info &RE) const { 1972 return RE.r_word1; 1973 } 1974 1975 uint32_t MachOObjectFile::getScatteredRelocationType( 1976 const MachO::any_relocation_info &RE) const { 1977 return (RE.r_word0 >> 24) & 0xf; 1978 } 1979 1980 unsigned MachOObjectFile::getAnyRelocationAddress( 1981 const MachO::any_relocation_info &RE) const { 1982 if (isRelocationScattered(RE)) 1983 return getScatteredRelocationAddress(RE); 1984 return getPlainRelocationAddress(RE); 1985 } 1986 1987 unsigned MachOObjectFile::getAnyRelocationPCRel( 1988 const MachO::any_relocation_info &RE) const { 1989 if (isRelocationScattered(RE)) 1990 return getScatteredRelocationPCRel(this, RE); 1991 return getPlainRelocationPCRel(this, RE); 1992 } 1993 1994 unsigned MachOObjectFile::getAnyRelocationLength( 1995 const MachO::any_relocation_info &RE) const { 1996 if (isRelocationScattered(RE)) 1997 return getScatteredRelocationLength(RE); 1998 return getPlainRelocationLength(this, RE); 1999 } 2000 2001 unsigned 2002 MachOObjectFile::getAnyRelocationType( 2003 const MachO::any_relocation_info &RE) const { 2004 if (isRelocationScattered(RE)) 2005 return getScatteredRelocationType(RE); 2006 return getPlainRelocationType(this, RE); 2007 } 2008 2009 SectionRef 2010 MachOObjectFile::getAnyRelocationSection( 2011 const MachO::any_relocation_info &RE) const { 2012 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 2013 return *section_end(); 2014 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; 2015 DataRefImpl DRI; 2016 DRI.d.a = SecNum; 2017 return SectionRef(DRI, this); 2018 } 2019 2020 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 2021 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 2022 return getStruct<MachO::section>(this, Sections[DRI.d.a]); 2023 } 2024 2025 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 2026 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 2027 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]); 2028 } 2029 2030 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 2031 unsigned Index) const { 2032 const char *Sec = getSectionPtr(this, L, Index); 2033 return getStruct<MachO::section>(this, Sec); 2034 } 2035 2036 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 2037 unsigned Index) const { 2038 const char *Sec = getSectionPtr(this, L, Index); 2039 return getStruct<MachO::section_64>(this, Sec); 2040 } 2041 2042 MachO::nlist 2043 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 2044 const char *P = reinterpret_cast<const char *>(DRI.p); 2045 return getStruct<MachO::nlist>(this, P); 2046 } 2047 2048 MachO::nlist_64 2049 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 2050 const char *P = reinterpret_cast<const char *>(DRI.p); 2051 return getStruct<MachO::nlist_64>(this, P); 2052 } 2053 2054 MachO::linkedit_data_command 2055 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 2056 return getStruct<MachO::linkedit_data_command>(this, L.Ptr); 2057 } 2058 2059 MachO::segment_command 2060 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 2061 return getStruct<MachO::segment_command>(this, L.Ptr); 2062 } 2063 2064 MachO::segment_command_64 2065 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 2066 return getStruct<MachO::segment_command_64>(this, L.Ptr); 2067 } 2068 2069 MachO::linker_option_command 2070 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const { 2071 return getStruct<MachO::linker_option_command>(this, L.Ptr); 2072 } 2073 2074 MachO::version_min_command 2075 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 2076 return getStruct<MachO::version_min_command>(this, L.Ptr); 2077 } 2078 2079 MachO::dylib_command 2080 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 2081 return getStruct<MachO::dylib_command>(this, L.Ptr); 2082 } 2083 2084 MachO::dyld_info_command 2085 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const { 2086 return getStruct<MachO::dyld_info_command>(this, L.Ptr); 2087 } 2088 2089 MachO::dylinker_command 2090 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const { 2091 return getStruct<MachO::dylinker_command>(this, L.Ptr); 2092 } 2093 2094 MachO::uuid_command 2095 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const { 2096 return getStruct<MachO::uuid_command>(this, L.Ptr); 2097 } 2098 2099 MachO::rpath_command 2100 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const { 2101 return getStruct<MachO::rpath_command>(this, L.Ptr); 2102 } 2103 2104 MachO::source_version_command 2105 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const { 2106 return getStruct<MachO::source_version_command>(this, L.Ptr); 2107 } 2108 2109 MachO::entry_point_command 2110 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const { 2111 return getStruct<MachO::entry_point_command>(this, L.Ptr); 2112 } 2113 2114 MachO::encryption_info_command 2115 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const { 2116 return getStruct<MachO::encryption_info_command>(this, L.Ptr); 2117 } 2118 2119 MachO::encryption_info_command_64 2120 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const { 2121 return getStruct<MachO::encryption_info_command_64>(this, L.Ptr); 2122 } 2123 2124 MachO::sub_framework_command 2125 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const { 2126 return getStruct<MachO::sub_framework_command>(this, L.Ptr); 2127 } 2128 2129 MachO::sub_umbrella_command 2130 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const { 2131 return getStruct<MachO::sub_umbrella_command>(this, L.Ptr); 2132 } 2133 2134 MachO::sub_library_command 2135 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const { 2136 return getStruct<MachO::sub_library_command>(this, L.Ptr); 2137 } 2138 2139 MachO::sub_client_command 2140 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const { 2141 return getStruct<MachO::sub_client_command>(this, L.Ptr); 2142 } 2143 2144 MachO::routines_command 2145 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const { 2146 return getStruct<MachO::routines_command>(this, L.Ptr); 2147 } 2148 2149 MachO::routines_command_64 2150 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const { 2151 return getStruct<MachO::routines_command_64>(this, L.Ptr); 2152 } 2153 2154 MachO::thread_command 2155 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { 2156 return getStruct<MachO::thread_command>(this, L.Ptr); 2157 } 2158 2159 MachO::any_relocation_info 2160 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 2161 DataRefImpl Sec; 2162 Sec.d.a = Rel.d.a; 2163 uint32_t Offset; 2164 if (is64Bit()) { 2165 MachO::section_64 Sect = getSection64(Sec); 2166 Offset = Sect.reloff; 2167 } else { 2168 MachO::section Sect = getSection(Sec); 2169 Offset = Sect.reloff; 2170 } 2171 2172 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 2173 getPtr(this, Offset)) + Rel.d.b; 2174 return getStruct<MachO::any_relocation_info>( 2175 this, reinterpret_cast<const char *>(P)); 2176 } 2177 2178 MachO::data_in_code_entry 2179 MachOObjectFile::getDice(DataRefImpl Rel) const { 2180 const char *P = reinterpret_cast<const char *>(Rel.p); 2181 return getStruct<MachO::data_in_code_entry>(this, P); 2182 } 2183 2184 const MachO::mach_header &MachOObjectFile::getHeader() const { 2185 return Header; 2186 } 2187 2188 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const { 2189 assert(is64Bit()); 2190 return Header64; 2191 } 2192 2193 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 2194 const MachO::dysymtab_command &DLC, 2195 unsigned Index) const { 2196 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 2197 return getStruct<uint32_t>(this, getPtr(this, Offset)); 2198 } 2199 2200 MachO::data_in_code_entry 2201 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 2202 unsigned Index) const { 2203 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 2204 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset)); 2205 } 2206 2207 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 2208 if (SymtabLoadCmd) 2209 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd); 2210 2211 // If there is no SymtabLoadCmd return a load command with zero'ed fields. 2212 MachO::symtab_command Cmd; 2213 Cmd.cmd = MachO::LC_SYMTAB; 2214 Cmd.cmdsize = sizeof(MachO::symtab_command); 2215 Cmd.symoff = 0; 2216 Cmd.nsyms = 0; 2217 Cmd.stroff = 0; 2218 Cmd.strsize = 0; 2219 return Cmd; 2220 } 2221 2222 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 2223 if (DysymtabLoadCmd) 2224 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd); 2225 2226 // If there is no DysymtabLoadCmd return a load command with zero'ed fields. 2227 MachO::dysymtab_command Cmd; 2228 Cmd.cmd = MachO::LC_DYSYMTAB; 2229 Cmd.cmdsize = sizeof(MachO::dysymtab_command); 2230 Cmd.ilocalsym = 0; 2231 Cmd.nlocalsym = 0; 2232 Cmd.iextdefsym = 0; 2233 Cmd.nextdefsym = 0; 2234 Cmd.iundefsym = 0; 2235 Cmd.nundefsym = 0; 2236 Cmd.tocoff = 0; 2237 Cmd.ntoc = 0; 2238 Cmd.modtaboff = 0; 2239 Cmd.nmodtab = 0; 2240 Cmd.extrefsymoff = 0; 2241 Cmd.nextrefsyms = 0; 2242 Cmd.indirectsymoff = 0; 2243 Cmd.nindirectsyms = 0; 2244 Cmd.extreloff = 0; 2245 Cmd.nextrel = 0; 2246 Cmd.locreloff = 0; 2247 Cmd.nlocrel = 0; 2248 return Cmd; 2249 } 2250 2251 MachO::linkedit_data_command 2252 MachOObjectFile::getDataInCodeLoadCommand() const { 2253 if (DataInCodeLoadCmd) 2254 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd); 2255 2256 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 2257 MachO::linkedit_data_command Cmd; 2258 Cmd.cmd = MachO::LC_DATA_IN_CODE; 2259 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2260 Cmd.dataoff = 0; 2261 Cmd.datasize = 0; 2262 return Cmd; 2263 } 2264 2265 MachO::linkedit_data_command 2266 MachOObjectFile::getLinkOptHintsLoadCommand() const { 2267 if (LinkOptHintsLoadCmd) 2268 return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd); 2269 2270 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed 2271 // fields. 2272 MachO::linkedit_data_command Cmd; 2273 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; 2274 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 2275 Cmd.dataoff = 0; 2276 Cmd.datasize = 0; 2277 return Cmd; 2278 } 2279 2280 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { 2281 if (!DyldInfoLoadCmd) 2282 return ArrayRef<uint8_t>(); 2283 2284 MachO::dyld_info_command DyldInfo 2285 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2286 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2287 getPtr(this, DyldInfo.rebase_off)); 2288 return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size); 2289 } 2290 2291 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 2292 if (!DyldInfoLoadCmd) 2293 return ArrayRef<uint8_t>(); 2294 2295 MachO::dyld_info_command DyldInfo 2296 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2297 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2298 getPtr(this, DyldInfo.bind_off)); 2299 return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size); 2300 } 2301 2302 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 2303 if (!DyldInfoLoadCmd) 2304 return ArrayRef<uint8_t>(); 2305 2306 MachO::dyld_info_command DyldInfo 2307 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2308 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2309 getPtr(this, DyldInfo.weak_bind_off)); 2310 return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size); 2311 } 2312 2313 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 2314 if (!DyldInfoLoadCmd) 2315 return ArrayRef<uint8_t>(); 2316 2317 MachO::dyld_info_command DyldInfo 2318 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2319 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2320 getPtr(this, DyldInfo.lazy_bind_off)); 2321 return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size); 2322 } 2323 2324 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 2325 if (!DyldInfoLoadCmd) 2326 return ArrayRef<uint8_t>(); 2327 2328 MachO::dyld_info_command DyldInfo 2329 = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); 2330 const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( 2331 getPtr(this, DyldInfo.export_off)); 2332 return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size); 2333 } 2334 2335 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 2336 if (!UuidLoadCmd) 2337 return ArrayRef<uint8_t>(); 2338 // Returning a pointer is fine as uuid doesn't need endian swapping. 2339 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); 2340 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16); 2341 } 2342 2343 StringRef MachOObjectFile::getStringTableData() const { 2344 MachO::symtab_command S = getSymtabLoadCommand(); 2345 return getData().substr(S.stroff, S.strsize); 2346 } 2347 2348 bool MachOObjectFile::is64Bit() const { 2349 return getType() == getMachOType(false, true) || 2350 getType() == getMachOType(true, true); 2351 } 2352 2353 void MachOObjectFile::ReadULEB128s(uint64_t Index, 2354 SmallVectorImpl<uint64_t> &Out) const { 2355 DataExtractor extractor(ObjectFile::getData(), true, 0); 2356 2357 uint32_t offset = Index; 2358 uint64_t data = 0; 2359 while (uint64_t delta = extractor.getULEB128(&offset)) { 2360 data += delta; 2361 Out.push_back(data); 2362 } 2363 } 2364 2365 bool MachOObjectFile::isRelocatableObject() const { 2366 return getHeader().filetype == MachO::MH_OBJECT; 2367 } 2368 2369 ErrorOr<std::unique_ptr<MachOObjectFile>> 2370 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) { 2371 StringRef Magic = Buffer.getBuffer().slice(0, 4); 2372 std::error_code EC; 2373 std::unique_ptr<MachOObjectFile> Ret; 2374 if (Magic == "\xFE\xED\xFA\xCE") 2375 Ret.reset(new MachOObjectFile(Buffer, false, false, EC)); 2376 else if (Magic == "\xCE\xFA\xED\xFE") 2377 Ret.reset(new MachOObjectFile(Buffer, true, false, EC)); 2378 else if (Magic == "\xFE\xED\xFA\xCF") 2379 Ret.reset(new MachOObjectFile(Buffer, false, true, EC)); 2380 else if (Magic == "\xCF\xFA\xED\xFE") 2381 Ret.reset(new MachOObjectFile(Buffer, true, true, EC)); 2382 else 2383 return object_error::parse_failed; 2384 2385 if (EC) 2386 return EC; 2387 return std::move(Ret); 2388 } 2389 2390