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