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