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