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