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