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