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