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/Triple.h" 18 #include "llvm/Support/DataExtractor.h" 19 #include "llvm/Support/Format.h" 20 #include "llvm/Support/Host.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include <cctype> 24 #include <cstring> 25 #include <limits> 26 27 using namespace llvm; 28 using namespace object; 29 30 namespace { 31 struct section_base { 32 char sectname[16]; 33 char segname[16]; 34 }; 35 } 36 37 template<typename T> 38 static T getStruct(const MachOObjectFile *O, const char *P) { 39 T Cmd; 40 memcpy(&Cmd, P, sizeof(T)); 41 if (O->isLittleEndian() != sys::IsLittleEndianHost) 42 MachO::swapStruct(Cmd); 43 return Cmd; 44 } 45 46 static uint32_t 47 getSegmentLoadCommandNumSections(const MachOObjectFile *O, 48 const MachOObjectFile::LoadCommandInfo &L) { 49 if (O->is64Bit()) { 50 MachO::segment_command_64 S = O->getSegment64LoadCommand(L); 51 return S.nsects; 52 } 53 MachO::segment_command S = O->getSegmentLoadCommand(L); 54 return S.nsects; 55 } 56 57 static const char * 58 getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, 59 unsigned Sec) { 60 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr); 61 62 bool Is64 = O->is64Bit(); 63 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) : 64 sizeof(MachO::segment_command); 65 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) : 66 sizeof(MachO::section); 67 68 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; 69 return reinterpret_cast<const char*>(SectionAddr); 70 } 71 72 static const char *getPtr(const MachOObjectFile *O, size_t Offset) { 73 return O->getData().substr(Offset, 1).data(); 74 } 75 76 static MachO::nlist_base 77 getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { 78 const char *P = reinterpret_cast<const char *>(DRI.p); 79 return getStruct<MachO::nlist_base>(O, P); 80 } 81 82 static StringRef parseSegmentOrSectionName(const char *P) { 83 if (P[15] == 0) 84 // Null terminated. 85 return P; 86 // Not null terminated, so this is a 16 char string. 87 return StringRef(P, 16); 88 } 89 90 // Helper to advance a section or symbol iterator multiple increments at a time. 91 template<class T> 92 static void advance(T &it, size_t Val) { 93 while (Val--) 94 ++it; 95 } 96 97 static unsigned getCPUType(const MachOObjectFile *O) { 98 return O->getHeader().cputype; 99 } 100 101 static void printRelocationTargetName(const MachOObjectFile *O, 102 const MachO::any_relocation_info &RE, 103 raw_string_ostream &fmt) { 104 bool IsScattered = O->isRelocationScattered(RE); 105 106 // Target of a scattered relocation is an address. In the interest of 107 // generating pretty output, scan through the symbol table looking for a 108 // symbol that aligns with that address. If we find one, print it. 109 // Otherwise, we just print the hex address of the target. 110 if (IsScattered) { 111 uint32_t Val = O->getPlainRelocationSymbolNum(RE); 112 113 for (const SymbolRef &Symbol : O->symbols()) { 114 std::error_code ec; 115 uint64_t Addr; 116 StringRef Name; 117 118 if ((ec = Symbol.getAddress(Addr))) 119 report_fatal_error(ec.message()); 120 if (Addr != Val) 121 continue; 122 if ((ec = Symbol.getName(Name))) 123 report_fatal_error(ec.message()); 124 fmt << Name; 125 return; 126 } 127 128 // If we couldn't find a symbol that this relocation refers to, try 129 // to find a section beginning instead. 130 for (const SectionRef &Section : O->sections()) { 131 std::error_code ec; 132 uint64_t Addr; 133 StringRef Name; 134 135 if ((ec = Section.getAddress(Addr))) 136 report_fatal_error(ec.message()); 137 if (Addr != Val) 138 continue; 139 if ((ec = Section.getName(Name))) 140 report_fatal_error(ec.message()); 141 fmt << Name; 142 return; 143 } 144 145 fmt << format("0x%x", Val); 146 return; 147 } 148 149 StringRef S; 150 bool isExtern = O->getPlainRelocationExternal(RE); 151 uint64_t Val = O->getPlainRelocationSymbolNum(RE); 152 153 if (isExtern) { 154 symbol_iterator SI = O->symbol_begin(); 155 advance(SI, Val); 156 SI->getName(S); 157 } else { 158 section_iterator SI = O->section_begin(); 159 // Adjust for the fact that sections are 1-indexed. 160 advance(SI, Val - 1); 161 SI->getName(S); 162 } 163 164 fmt << S; 165 } 166 167 static uint32_t 168 getPlainRelocationAddress(const MachO::any_relocation_info &RE) { 169 return RE.r_word0; 170 } 171 172 static unsigned 173 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) { 174 return RE.r_word0 & 0xffffff; 175 } 176 177 static bool getPlainRelocationPCRel(const MachOObjectFile *O, 178 const MachO::any_relocation_info &RE) { 179 if (O->isLittleEndian()) 180 return (RE.r_word1 >> 24) & 1; 181 return (RE.r_word1 >> 7) & 1; 182 } 183 184 static bool 185 getScatteredRelocationPCRel(const MachOObjectFile *O, 186 const MachO::any_relocation_info &RE) { 187 return (RE.r_word0 >> 30) & 1; 188 } 189 190 static unsigned getPlainRelocationLength(const MachOObjectFile *O, 191 const MachO::any_relocation_info &RE) { 192 if (O->isLittleEndian()) 193 return (RE.r_word1 >> 25) & 3; 194 return (RE.r_word1 >> 5) & 3; 195 } 196 197 static unsigned 198 getScatteredRelocationLength(const MachO::any_relocation_info &RE) { 199 return (RE.r_word0 >> 28) & 3; 200 } 201 202 static unsigned getPlainRelocationType(const MachOObjectFile *O, 203 const MachO::any_relocation_info &RE) { 204 if (O->isLittleEndian()) 205 return RE.r_word1 >> 28; 206 return RE.r_word1 & 0xf; 207 } 208 209 static unsigned 210 getScatteredRelocationType(const MachO::any_relocation_info &RE) { 211 return (RE.r_word0 >> 24) & 0xf; 212 } 213 214 static uint32_t getSectionFlags(const MachOObjectFile *O, 215 DataRefImpl Sec) { 216 if (O->is64Bit()) { 217 MachO::section_64 Sect = O->getSection64(Sec); 218 return Sect.flags; 219 } 220 MachO::section Sect = O->getSection(Sec); 221 return Sect.flags; 222 } 223 224 MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, 225 bool IsLittleEndian, bool Is64bits, 226 std::error_code &EC) 227 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)), 228 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), 229 DataInCodeLoadCmd(nullptr) { 230 uint32_t LoadCommandCount = this->getHeader().ncmds; 231 MachO::LoadCommandType SegmentLoadType = is64Bit() ? 232 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT; 233 234 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo(); 235 for (unsigned I = 0; ; ++I) { 236 if (Load.C.cmd == MachO::LC_SYMTAB) { 237 assert(!SymtabLoadCmd && "Multiple symbol tables"); 238 SymtabLoadCmd = Load.Ptr; 239 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) { 240 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables"); 241 DysymtabLoadCmd = Load.Ptr; 242 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) { 243 assert(!DataInCodeLoadCmd && "Multiple data in code tables"); 244 DataInCodeLoadCmd = Load.Ptr; 245 } else if (Load.C.cmd == SegmentLoadType) { 246 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); 247 for (unsigned J = 0; J < NumSections; ++J) { 248 const char *Sec = getSectionPtr(this, Load, J); 249 Sections.push_back(Sec); 250 } 251 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB || 252 Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB || 253 Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB || 254 Load.C.cmd == MachO::LC_REEXPORT_DYLIB || 255 Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) { 256 Libraries.push_back(Load.Ptr); 257 } 258 259 if (I == LoadCommandCount - 1) 260 break; 261 else 262 Load = getNextLoadCommandInfo(Load); 263 } 264 } 265 266 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 267 unsigned SymbolTableEntrySize = is64Bit() ? 268 sizeof(MachO::nlist_64) : 269 sizeof(MachO::nlist); 270 Symb.p += SymbolTableEntrySize; 271 } 272 273 std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, 274 StringRef &Res) const { 275 StringRef StringTable = getStringTableData(); 276 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 277 const char *Start = &StringTable.data()[Entry.n_strx]; 278 Res = StringRef(Start); 279 return object_error::success; 280 } 281 282 // getIndirectName() returns the name of the alias'ed symbol who's string table 283 // index is in the n_value field. 284 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb, 285 StringRef &Res) const { 286 StringRef StringTable = getStringTableData(); 287 uint64_t NValue; 288 if (is64Bit()) { 289 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb); 290 NValue = Entry.n_value; 291 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 292 return object_error::parse_failed; 293 } else { 294 MachO::nlist Entry = getSymbolTableEntry(Symb); 295 NValue = Entry.n_value; 296 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 297 return object_error::parse_failed; 298 } 299 if (NValue >= StringTable.size()) 300 return object_error::parse_failed; 301 const char *Start = &StringTable.data()[NValue]; 302 Res = StringRef(Start); 303 return object_error::success; 304 } 305 306 std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, 307 uint64_t &Res) const { 308 if (is64Bit()) { 309 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb); 310 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && 311 Entry.n_value == 0) 312 Res = UnknownAddressOrSize; 313 else 314 Res = Entry.n_value; 315 } else { 316 MachO::nlist Entry = getSymbolTableEntry(Symb); 317 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF && 318 Entry.n_value == 0) 319 Res = UnknownAddressOrSize; 320 else 321 Res = Entry.n_value; 322 } 323 return object_error::success; 324 } 325 326 std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI, 327 uint32_t &Result) const { 328 uint32_t flags = getSymbolFlags(DRI); 329 if (flags & SymbolRef::SF_Common) { 330 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 331 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); 332 } else { 333 Result = 0; 334 } 335 return object_error::success; 336 } 337 338 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, 339 uint64_t &Result) const { 340 uint64_t BeginOffset; 341 uint64_t EndOffset = 0; 342 uint8_t SectionIndex; 343 344 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 345 uint64_t Value; 346 getSymbolAddress(DRI, Value); 347 if (Value == UnknownAddressOrSize) { 348 Result = UnknownAddressOrSize; 349 return object_error::success; 350 } 351 352 BeginOffset = Value; 353 354 SectionIndex = Entry.n_sect; 355 if (!SectionIndex) { 356 uint32_t flags = getSymbolFlags(DRI); 357 if (flags & SymbolRef::SF_Common) 358 Result = Value; 359 else 360 Result = UnknownAddressOrSize; 361 return object_error::success; 362 } 363 // Unfortunately symbols are unsorted so we need to touch all 364 // symbols from load command 365 for (const SymbolRef &Symbol : symbols()) { 366 DataRefImpl DRI = Symbol.getRawDataRefImpl(); 367 Entry = getSymbolTableEntryBase(this, DRI); 368 getSymbolAddress(DRI, Value); 369 if (Value == UnknownAddressOrSize) 370 continue; 371 if (Entry.n_sect == SectionIndex && Value > BeginOffset) 372 if (!EndOffset || Value < EndOffset) 373 EndOffset = Value; 374 } 375 if (!EndOffset) { 376 uint64_t Size; 377 DataRefImpl Sec; 378 Sec.d.a = SectionIndex-1; 379 getSectionSize(Sec, Size); 380 getSectionAddress(Sec, EndOffset); 381 EndOffset += Size; 382 } 383 Result = EndOffset - BeginOffset; 384 return object_error::success; 385 } 386 387 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, 388 SymbolRef::Type &Res) const { 389 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 390 uint8_t n_type = Entry.n_type; 391 392 Res = SymbolRef::ST_Other; 393 394 // If this is a STAB debugging symbol, we can do nothing more. 395 if (n_type & MachO::N_STAB) { 396 Res = SymbolRef::ST_Debug; 397 return object_error::success; 398 } 399 400 switch (n_type & MachO::N_TYPE) { 401 case MachO::N_UNDF : 402 Res = SymbolRef::ST_Unknown; 403 break; 404 case MachO::N_SECT : 405 Res = SymbolRef::ST_Function; 406 break; 407 } 408 return object_error::success; 409 } 410 411 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { 412 MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); 413 414 uint8_t MachOType = Entry.n_type; 415 uint16_t MachOFlags = Entry.n_desc; 416 417 uint32_t Result = SymbolRef::SF_None; 418 419 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) 420 Result |= SymbolRef::SF_Undefined; 421 422 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR) 423 Result |= SymbolRef::SF_Indirect; 424 425 if (MachOType & MachO::N_STAB) 426 Result |= SymbolRef::SF_FormatSpecific; 427 428 if (MachOType & MachO::N_EXT) { 429 Result |= SymbolRef::SF_Global; 430 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { 431 uint64_t Value; 432 getSymbolAddress(DRI, Value); 433 if (Value && Value != UnknownAddressOrSize) 434 Result |= SymbolRef::SF_Common; 435 } 436 } 437 438 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 439 Result |= SymbolRef::SF_Weak; 440 441 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) 442 Result |= SymbolRef::SF_Absolute; 443 444 return Result; 445 } 446 447 std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, 448 section_iterator &Res) const { 449 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); 450 uint8_t index = Entry.n_sect; 451 452 if (index == 0) { 453 Res = section_end(); 454 } else { 455 DataRefImpl DRI; 456 DRI.d.a = index - 1; 457 Res = section_iterator(SectionRef(DRI, this)); 458 } 459 460 return object_error::success; 461 } 462 463 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { 464 Sec.d.a++; 465 } 466 467 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec, 468 StringRef &Result) const { 469 ArrayRef<char> Raw = getSectionRawName(Sec); 470 Result = parseSegmentOrSectionName(Raw.data()); 471 return object_error::success; 472 } 473 474 std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec, 475 uint64_t &Res) const { 476 if (is64Bit()) { 477 MachO::section_64 Sect = getSection64(Sec); 478 Res = Sect.addr; 479 } else { 480 MachO::section Sect = getSection(Sec); 481 Res = Sect.addr; 482 } 483 return object_error::success; 484 } 485 486 std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec, 487 uint64_t &Res) const { 488 if (is64Bit()) { 489 MachO::section_64 Sect = getSection64(Sec); 490 Res = Sect.size; 491 } else { 492 MachO::section Sect = getSection(Sec); 493 Res = Sect.size; 494 } 495 496 return object_error::success; 497 } 498 499 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, 500 StringRef &Res) const { 501 uint32_t Offset; 502 uint64_t Size; 503 504 if (is64Bit()) { 505 MachO::section_64 Sect = getSection64(Sec); 506 Offset = Sect.offset; 507 Size = Sect.size; 508 } else { 509 MachO::section Sect = getSection(Sec); 510 Offset = Sect.offset; 511 Size = Sect.size; 512 } 513 514 Res = this->getData().substr(Offset, Size); 515 return object_error::success; 516 } 517 518 std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec, 519 uint64_t &Res) const { 520 uint32_t Align; 521 if (is64Bit()) { 522 MachO::section_64 Sect = getSection64(Sec); 523 Align = Sect.align; 524 } else { 525 MachO::section Sect = getSection(Sec); 526 Align = Sect.align; 527 } 528 529 Res = uint64_t(1) << Align; 530 return object_error::success; 531 } 532 533 std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec, 534 bool &Res) const { 535 uint32_t Flags = getSectionFlags(this, Sec); 536 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; 537 return object_error::success; 538 } 539 540 std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec, 541 bool &Result) const { 542 uint32_t Flags = getSectionFlags(this, Sec); 543 unsigned SectionType = Flags & MachO::SECTION_TYPE; 544 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 545 !(SectionType == MachO::S_ZEROFILL || 546 SectionType == MachO::S_GB_ZEROFILL); 547 return object_error::success; 548 } 549 550 std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, 551 bool &Result) const { 552 uint32_t Flags = getSectionFlags(this, Sec); 553 unsigned SectionType = Flags & MachO::SECTION_TYPE; 554 Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 555 (SectionType == MachO::S_ZEROFILL || 556 SectionType == MachO::S_GB_ZEROFILL); 557 return object_error::success; 558 } 559 560 std::error_code 561 MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, 562 bool &Result) const { 563 // FIXME: Unimplemented. 564 Result = true; 565 return object_error::success; 566 } 567 568 std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, 569 bool &Result) const { 570 // FIXME: Unimplemented. 571 Result = false; 572 return object_error::success; 573 } 574 575 std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, 576 bool &Res) const { 577 uint32_t Flags = getSectionFlags(this, Sec); 578 unsigned SectionType = Flags & MachO::SECTION_TYPE; 579 Res = SectionType == MachO::S_ZEROFILL || 580 SectionType == MachO::S_GB_ZEROFILL; 581 return object_error::success; 582 } 583 584 std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, 585 bool &Result) const { 586 // Consider using the code from isSectionText to look for __const sections. 587 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS 588 // to use section attributes to distinguish code from data. 589 590 // FIXME: Unimplemented. 591 Result = false; 592 return object_error::success; 593 } 594 595 std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, 596 DataRefImpl Symb, 597 bool &Result) const { 598 SymbolRef::Type ST; 599 this->getSymbolType(Symb, ST); 600 if (ST == SymbolRef::ST_Unknown) { 601 Result = false; 602 return object_error::success; 603 } 604 605 uint64_t SectBegin, SectEnd; 606 getSectionAddress(Sec, SectBegin); 607 getSectionSize(Sec, SectEnd); 608 SectEnd += SectBegin; 609 610 uint64_t SymAddr; 611 getSymbolAddress(Symb, SymAddr); 612 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); 613 614 return object_error::success; 615 } 616 617 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 618 DataRefImpl Ret; 619 Ret.d.a = Sec.d.a; 620 Ret.d.b = 0; 621 return relocation_iterator(RelocationRef(Ret, this)); 622 } 623 624 relocation_iterator 625 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 626 uint32_t Num; 627 if (is64Bit()) { 628 MachO::section_64 Sect = getSection64(Sec); 629 Num = Sect.nreloc; 630 } else { 631 MachO::section Sect = getSection(Sec); 632 Num = Sect.nreloc; 633 } 634 635 DataRefImpl Ret; 636 Ret.d.a = Sec.d.a; 637 Ret.d.b = Num; 638 return relocation_iterator(RelocationRef(Ret, this)); 639 } 640 641 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 642 ++Rel.d.b; 643 } 644 645 std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, 646 uint64_t &Res) const { 647 uint64_t Offset; 648 getRelocationOffset(Rel, Offset); 649 650 DataRefImpl Sec; 651 Sec.d.a = Rel.d.a; 652 uint64_t SecAddress; 653 getSectionAddress(Sec, SecAddress); 654 Res = SecAddress + Offset; 655 return object_error::success; 656 } 657 658 std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, 659 uint64_t &Res) const { 660 assert(getHeader().filetype == MachO::MH_OBJECT && 661 "Only implemented for MH_OBJECT"); 662 MachO::any_relocation_info RE = getRelocation(Rel); 663 Res = getAnyRelocationAddress(RE); 664 return object_error::success; 665 } 666 667 symbol_iterator 668 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 669 MachO::any_relocation_info RE = getRelocation(Rel); 670 if (isRelocationScattered(RE)) 671 return symbol_end(); 672 673 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 674 bool isExtern = getPlainRelocationExternal(RE); 675 if (!isExtern) 676 return symbol_end(); 677 678 MachO::symtab_command S = getSymtabLoadCommand(); 679 unsigned SymbolTableEntrySize = is64Bit() ? 680 sizeof(MachO::nlist_64) : 681 sizeof(MachO::nlist); 682 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 683 DataRefImpl Sym; 684 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 685 return symbol_iterator(SymbolRef(Sym, this)); 686 } 687 688 std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, 689 uint64_t &Res) const { 690 MachO::any_relocation_info RE = getRelocation(Rel); 691 Res = getAnyRelocationType(RE); 692 return object_error::success; 693 } 694 695 std::error_code 696 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, 697 SmallVectorImpl<char> &Result) const { 698 StringRef res; 699 uint64_t RType; 700 getRelocationType(Rel, RType); 701 702 unsigned Arch = this->getArch(); 703 704 switch (Arch) { 705 case Triple::x86: { 706 static const char *const Table[] = { 707 "GENERIC_RELOC_VANILLA", 708 "GENERIC_RELOC_PAIR", 709 "GENERIC_RELOC_SECTDIFF", 710 "GENERIC_RELOC_PB_LA_PTR", 711 "GENERIC_RELOC_LOCAL_SECTDIFF", 712 "GENERIC_RELOC_TLV" }; 713 714 if (RType > 5) 715 res = "Unknown"; 716 else 717 res = Table[RType]; 718 break; 719 } 720 case Triple::x86_64: { 721 static const char *const Table[] = { 722 "X86_64_RELOC_UNSIGNED", 723 "X86_64_RELOC_SIGNED", 724 "X86_64_RELOC_BRANCH", 725 "X86_64_RELOC_GOT_LOAD", 726 "X86_64_RELOC_GOT", 727 "X86_64_RELOC_SUBTRACTOR", 728 "X86_64_RELOC_SIGNED_1", 729 "X86_64_RELOC_SIGNED_2", 730 "X86_64_RELOC_SIGNED_4", 731 "X86_64_RELOC_TLV" }; 732 733 if (RType > 9) 734 res = "Unknown"; 735 else 736 res = Table[RType]; 737 break; 738 } 739 case Triple::arm: { 740 static const char *const Table[] = { 741 "ARM_RELOC_VANILLA", 742 "ARM_RELOC_PAIR", 743 "ARM_RELOC_SECTDIFF", 744 "ARM_RELOC_LOCAL_SECTDIFF", 745 "ARM_RELOC_PB_LA_PTR", 746 "ARM_RELOC_BR24", 747 "ARM_THUMB_RELOC_BR22", 748 "ARM_THUMB_32BIT_BRANCH", 749 "ARM_RELOC_HALF", 750 "ARM_RELOC_HALF_SECTDIFF" }; 751 752 if (RType > 9) 753 res = "Unknown"; 754 else 755 res = Table[RType]; 756 break; 757 } 758 case Triple::arm64: 759 case Triple::aarch64: { 760 static const char *const Table[] = { 761 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 762 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 763 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 764 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 765 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 766 "ARM64_RELOC_ADDEND" 767 }; 768 769 if (RType >= array_lengthof(Table)) 770 res = "Unknown"; 771 else 772 res = Table[RType]; 773 break; 774 } 775 case Triple::ppc: { 776 static const char *const Table[] = { 777 "PPC_RELOC_VANILLA", 778 "PPC_RELOC_PAIR", 779 "PPC_RELOC_BR14", 780 "PPC_RELOC_BR24", 781 "PPC_RELOC_HI16", 782 "PPC_RELOC_LO16", 783 "PPC_RELOC_HA16", 784 "PPC_RELOC_LO14", 785 "PPC_RELOC_SECTDIFF", 786 "PPC_RELOC_PB_LA_PTR", 787 "PPC_RELOC_HI16_SECTDIFF", 788 "PPC_RELOC_LO16_SECTDIFF", 789 "PPC_RELOC_HA16_SECTDIFF", 790 "PPC_RELOC_JBSR", 791 "PPC_RELOC_LO14_SECTDIFF", 792 "PPC_RELOC_LOCAL_SECTDIFF" }; 793 794 if (RType > 15) 795 res = "Unknown"; 796 else 797 res = Table[RType]; 798 break; 799 } 800 case Triple::UnknownArch: 801 res = "Unknown"; 802 break; 803 } 804 Result.append(res.begin(), res.end()); 805 return object_error::success; 806 } 807 808 std::error_code 809 MachOObjectFile::getRelocationValueString(DataRefImpl Rel, 810 SmallVectorImpl<char> &Result) const { 811 MachO::any_relocation_info RE = getRelocation(Rel); 812 813 unsigned Arch = this->getArch(); 814 815 std::string fmtbuf; 816 raw_string_ostream fmt(fmtbuf); 817 unsigned Type = this->getAnyRelocationType(RE); 818 bool IsPCRel = this->getAnyRelocationPCRel(RE); 819 820 // Determine any addends that should be displayed with the relocation. 821 // These require decoding the relocation type, which is triple-specific. 822 823 // X86_64 has entirely custom relocation types. 824 if (Arch == Triple::x86_64) { 825 bool isPCRel = getAnyRelocationPCRel(RE); 826 827 switch (Type) { 828 case MachO::X86_64_RELOC_GOT_LOAD: 829 case MachO::X86_64_RELOC_GOT: { 830 printRelocationTargetName(this, RE, fmt); 831 fmt << "@GOT"; 832 if (isPCRel) fmt << "PCREL"; 833 break; 834 } 835 case MachO::X86_64_RELOC_SUBTRACTOR: { 836 DataRefImpl RelNext = Rel; 837 moveRelocationNext(RelNext); 838 MachO::any_relocation_info RENext = getRelocation(RelNext); 839 840 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type 841 // X86_64_RELOC_UNSIGNED. 842 // NOTE: Scattered relocations don't exist on x86_64. 843 unsigned RType = getAnyRelocationType(RENext); 844 if (RType != MachO::X86_64_RELOC_UNSIGNED) 845 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " 846 "X86_64_RELOC_SUBTRACTOR."); 847 848 // The X86_64_RELOC_UNSIGNED contains the minuend symbol; 849 // X86_64_RELOC_SUBTRACTOR contains the subtrahend. 850 printRelocationTargetName(this, RENext, fmt); 851 fmt << "-"; 852 printRelocationTargetName(this, RE, fmt); 853 break; 854 } 855 case MachO::X86_64_RELOC_TLV: 856 printRelocationTargetName(this, RE, fmt); 857 fmt << "@TLV"; 858 if (isPCRel) fmt << "P"; 859 break; 860 case MachO::X86_64_RELOC_SIGNED_1: 861 printRelocationTargetName(this, RE, fmt); 862 fmt << "-1"; 863 break; 864 case MachO::X86_64_RELOC_SIGNED_2: 865 printRelocationTargetName(this, RE, fmt); 866 fmt << "-2"; 867 break; 868 case MachO::X86_64_RELOC_SIGNED_4: 869 printRelocationTargetName(this, RE, fmt); 870 fmt << "-4"; 871 break; 872 default: 873 printRelocationTargetName(this, RE, fmt); 874 break; 875 } 876 // X86 and ARM share some relocation types in common. 877 } else if (Arch == Triple::x86 || Arch == Triple::arm || 878 Arch == Triple::ppc) { 879 // Generic relocation types... 880 switch (Type) { 881 case MachO::GENERIC_RELOC_PAIR: // prints no info 882 return object_error::success; 883 case MachO::GENERIC_RELOC_SECTDIFF: { 884 DataRefImpl RelNext = Rel; 885 moveRelocationNext(RelNext); 886 MachO::any_relocation_info RENext = getRelocation(RelNext); 887 888 // X86 sect diff's must be followed by a relocation of type 889 // GENERIC_RELOC_PAIR. 890 unsigned RType = getAnyRelocationType(RENext); 891 892 if (RType != MachO::GENERIC_RELOC_PAIR) 893 report_fatal_error("Expected GENERIC_RELOC_PAIR after " 894 "GENERIC_RELOC_SECTDIFF."); 895 896 printRelocationTargetName(this, RE, fmt); 897 fmt << "-"; 898 printRelocationTargetName(this, RENext, fmt); 899 break; 900 } 901 } 902 903 if (Arch == Triple::x86 || Arch == Triple::ppc) { 904 switch (Type) { 905 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: { 906 DataRefImpl RelNext = Rel; 907 moveRelocationNext(RelNext); 908 MachO::any_relocation_info RENext = getRelocation(RelNext); 909 910 // X86 sect diff's must be followed by a relocation of type 911 // GENERIC_RELOC_PAIR. 912 unsigned RType = getAnyRelocationType(RENext); 913 if (RType != MachO::GENERIC_RELOC_PAIR) 914 report_fatal_error("Expected GENERIC_RELOC_PAIR after " 915 "GENERIC_RELOC_LOCAL_SECTDIFF."); 916 917 printRelocationTargetName(this, RE, fmt); 918 fmt << "-"; 919 printRelocationTargetName(this, RENext, fmt); 920 break; 921 } 922 case MachO::GENERIC_RELOC_TLV: { 923 printRelocationTargetName(this, RE, fmt); 924 fmt << "@TLV"; 925 if (IsPCRel) fmt << "P"; 926 break; 927 } 928 default: 929 printRelocationTargetName(this, RE, fmt); 930 } 931 } else { // ARM-specific relocations 932 switch (Type) { 933 case MachO::ARM_RELOC_HALF: 934 case MachO::ARM_RELOC_HALF_SECTDIFF: { 935 // Half relocations steal a bit from the length field to encode 936 // whether this is an upper16 or a lower16 relocation. 937 bool isUpper = getAnyRelocationLength(RE) >> 1; 938 939 if (isUpper) 940 fmt << ":upper16:("; 941 else 942 fmt << ":lower16:("; 943 printRelocationTargetName(this, RE, fmt); 944 945 DataRefImpl RelNext = Rel; 946 moveRelocationNext(RelNext); 947 MachO::any_relocation_info RENext = getRelocation(RelNext); 948 949 // ARM half relocs must be followed by a relocation of type 950 // ARM_RELOC_PAIR. 951 unsigned RType = getAnyRelocationType(RENext); 952 if (RType != MachO::ARM_RELOC_PAIR) 953 report_fatal_error("Expected ARM_RELOC_PAIR after " 954 "ARM_RELOC_HALF"); 955 956 // NOTE: The half of the target virtual address is stashed in the 957 // address field of the secondary relocation, but we can't reverse 958 // engineer the constant offset from it without decoding the movw/movt 959 // instruction to find the other half in its immediate field. 960 961 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the 962 // symbol/section pointer of the follow-on relocation. 963 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) { 964 fmt << "-"; 965 printRelocationTargetName(this, RENext, fmt); 966 } 967 968 fmt << ")"; 969 break; 970 } 971 default: { 972 printRelocationTargetName(this, RE, fmt); 973 } 974 } 975 } 976 } else 977 printRelocationTargetName(this, RE, fmt); 978 979 fmt.flush(); 980 Result.append(fmtbuf.begin(), fmtbuf.end()); 981 return object_error::success; 982 } 983 984 std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, 985 bool &Result) const { 986 unsigned Arch = getArch(); 987 uint64_t Type; 988 getRelocationType(Rel, Type); 989 990 Result = false; 991 992 // On arches that use the generic relocations, GENERIC_RELOC_PAIR 993 // is always hidden. 994 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { 995 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true; 996 } else if (Arch == Triple::x86_64) { 997 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows 998 // an X86_64_RELOC_SUBTRACTOR. 999 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { 1000 DataRefImpl RelPrev = Rel; 1001 RelPrev.d.a--; 1002 uint64_t PrevType; 1003 getRelocationType(RelPrev, PrevType); 1004 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) 1005 Result = true; 1006 } 1007 } 1008 1009 return object_error::success; 1010 } 1011 1012 std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, 1013 LibraryRef &Res) const { 1014 report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); 1015 } 1016 1017 std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, 1018 StringRef &Res) const { 1019 report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); 1020 } 1021 1022 // 1023 // guessLibraryShortName() is passed a name of a dynamic library and returns a 1024 // guess on what the short name is. Then name is returned as a substring of the 1025 // StringRef Name passed in. The name of the dynamic library is recognized as 1026 // a framework if it has one of the two following forms: 1027 // Foo.framework/Versions/A/Foo 1028 // Foo.framework/Foo 1029 // Where A and Foo can be any string. And may contain a trailing suffix 1030 // starting with an underbar. If the Name is recognized as a framework then 1031 // isFramework is set to true else it is set to false. If the Name has a 1032 // suffix then Suffix is set to the substring in Name that contains the suffix 1033 // else it is set to a NULL StringRef. 1034 // 1035 // The Name of the dynamic library is recognized as a library name if it has 1036 // one of the two following forms: 1037 // libFoo.A.dylib 1038 // libFoo.dylib 1039 // The library may have a suffix trailing the name Foo of the form: 1040 // libFoo_profile.A.dylib 1041 // libFoo_profile.dylib 1042 // 1043 // The Name of the dynamic library is also recognized as a library name if it 1044 // has the following form: 1045 // Foo.qtx 1046 // 1047 // If the Name of the dynamic library is none of the forms above then a NULL 1048 // StringRef is returned. 1049 // 1050 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 1051 bool &isFramework, 1052 StringRef &Suffix) { 1053 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 1054 size_t a, b, c, d, Idx; 1055 1056 isFramework = false; 1057 Suffix = StringRef(); 1058 1059 // Pull off the last component and make Foo point to it 1060 a = Name.rfind('/'); 1061 if (a == Name.npos || a == 0) 1062 goto guess_library; 1063 Foo = Name.slice(a+1, Name.npos); 1064 1065 // Look for a suffix starting with a '_' 1066 Idx = Foo.rfind('_'); 1067 if (Idx != Foo.npos && Foo.size() >= 2) { 1068 Suffix = Foo.slice(Idx, Foo.npos); 1069 Foo = Foo.slice(0, Idx); 1070 } 1071 1072 // First look for the form Foo.framework/Foo 1073 b = Name.rfind('/', a); 1074 if (b == Name.npos) 1075 Idx = 0; 1076 else 1077 Idx = b+1; 1078 F = Name.slice(Idx, Idx + Foo.size()); 1079 DotFramework = Name.slice(Idx + Foo.size(), 1080 Idx + Foo.size() + sizeof(".framework/")-1); 1081 if (F == Foo && DotFramework == ".framework/") { 1082 isFramework = true; 1083 return Foo; 1084 } 1085 1086 // Next look for the form Foo.framework/Versions/A/Foo 1087 if (b == Name.npos) 1088 goto guess_library; 1089 c = Name.rfind('/', b); 1090 if (c == Name.npos || c == 0) 1091 goto guess_library; 1092 V = Name.slice(c+1, Name.npos); 1093 if (!V.startswith("Versions/")) 1094 goto guess_library; 1095 d = Name.rfind('/', c); 1096 if (d == Name.npos) 1097 Idx = 0; 1098 else 1099 Idx = d+1; 1100 F = Name.slice(Idx, Idx + Foo.size()); 1101 DotFramework = Name.slice(Idx + Foo.size(), 1102 Idx + Foo.size() + sizeof(".framework/")-1); 1103 if (F == Foo && DotFramework == ".framework/") { 1104 isFramework = true; 1105 return Foo; 1106 } 1107 1108 guess_library: 1109 // pull off the suffix after the "." and make a point to it 1110 a = Name.rfind('.'); 1111 if (a == Name.npos || a == 0) 1112 return StringRef(); 1113 Dylib = Name.slice(a, Name.npos); 1114 if (Dylib != ".dylib") 1115 goto guess_qtx; 1116 1117 // First pull off the version letter for the form Foo.A.dylib if any. 1118 if (a >= 3) { 1119 Dot = Name.slice(a-2, a-1); 1120 if (Dot == ".") 1121 a = a - 2; 1122 } 1123 1124 b = Name.rfind('/', a); 1125 if (b == Name.npos) 1126 b = 0; 1127 else 1128 b = b+1; 1129 // ignore any suffix after an underbar like Foo_profile.A.dylib 1130 Idx = Name.find('_', b); 1131 if (Idx != Name.npos && Idx != b) { 1132 Lib = Name.slice(b, Idx); 1133 Suffix = Name.slice(Idx, a); 1134 } 1135 else 1136 Lib = Name.slice(b, a); 1137 // There are incorrect library names of the form: 1138 // libATS.A_profile.dylib so check for these. 1139 if (Lib.size() >= 3) { 1140 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 1141 if (Dot == ".") 1142 Lib = Lib.slice(0, Lib.size()-2); 1143 } 1144 return Lib; 1145 1146 guess_qtx: 1147 Qtx = Name.slice(a, Name.npos); 1148 if (Qtx != ".qtx") 1149 return StringRef(); 1150 b = Name.rfind('/', a); 1151 if (b == Name.npos) 1152 Lib = Name.slice(0, a); 1153 else 1154 Lib = Name.slice(b+1, a); 1155 // There are library names of the form: QT.A.qtx so check for these. 1156 if (Lib.size() >= 3) { 1157 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 1158 if (Dot == ".") 1159 Lib = Lib.slice(0, Lib.size()-2); 1160 } 1161 return Lib; 1162 } 1163 1164 // getLibraryShortNameByIndex() is used to get the short name of the library 1165 // for an undefined symbol in a linked Mach-O binary that was linked with the 1166 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 1167 // It is passed the index (0 - based) of the library as translated from 1168 // GET_LIBRARY_ORDINAL (1 - based). 1169 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 1170 StringRef &Res) { 1171 if (Index >= Libraries.size()) 1172 return object_error::parse_failed; 1173 1174 MachO::dylib_command D = 1175 getStruct<MachO::dylib_command>(this, Libraries[Index]); 1176 if (D.dylib.name >= D.cmdsize) 1177 return object_error::parse_failed; 1178 1179 // If the cache of LibrariesShortNames is not built up do that first for 1180 // all the Libraries. 1181 if (LibrariesShortNames.size() == 0) { 1182 for (unsigned i = 0; i < Libraries.size(); i++) { 1183 MachO::dylib_command D = 1184 getStruct<MachO::dylib_command>(this, Libraries[i]); 1185 if (D.dylib.name >= D.cmdsize) { 1186 LibrariesShortNames.push_back(StringRef()); 1187 continue; 1188 } 1189 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 1190 StringRef Name = StringRef(P); 1191 StringRef Suffix; 1192 bool isFramework; 1193 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 1194 if (shortName == StringRef()) 1195 LibrariesShortNames.push_back(Name); 1196 else 1197 LibrariesShortNames.push_back(shortName); 1198 } 1199 } 1200 1201 Res = LibrariesShortNames[Index]; 1202 return object_error::success; 1203 } 1204 1205 basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { 1206 return getSymbolByIndex(0); 1207 } 1208 1209 basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { 1210 DataRefImpl DRI; 1211 if (!SymtabLoadCmd) 1212 return basic_symbol_iterator(SymbolRef(DRI, this)); 1213 1214 MachO::symtab_command Symtab = getSymtabLoadCommand(); 1215 unsigned SymbolTableEntrySize = is64Bit() ? 1216 sizeof(MachO::nlist_64) : 1217 sizeof(MachO::nlist); 1218 unsigned Offset = Symtab.symoff + 1219 Symtab.nsyms * SymbolTableEntrySize; 1220 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1221 return basic_symbol_iterator(SymbolRef(DRI, this)); 1222 } 1223 1224 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 1225 DataRefImpl DRI; 1226 if (!SymtabLoadCmd) 1227 return basic_symbol_iterator(SymbolRef(DRI, this)); 1228 1229 MachO::symtab_command Symtab = getSymtabLoadCommand(); 1230 assert(Index < Symtab.nsyms && "Requested symbol index is out of range."); 1231 unsigned SymbolTableEntrySize = 1232 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 1233 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); 1234 DRI.p += Index * SymbolTableEntrySize; 1235 return basic_symbol_iterator(SymbolRef(DRI, this)); 1236 } 1237 1238 section_iterator MachOObjectFile::section_begin() const { 1239 DataRefImpl DRI; 1240 return section_iterator(SectionRef(DRI, this)); 1241 } 1242 1243 section_iterator MachOObjectFile::section_end() const { 1244 DataRefImpl DRI; 1245 DRI.d.a = Sections.size(); 1246 return section_iterator(SectionRef(DRI, this)); 1247 } 1248 1249 library_iterator MachOObjectFile::needed_library_begin() const { 1250 // TODO: implement 1251 report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); 1252 } 1253 1254 library_iterator MachOObjectFile::needed_library_end() const { 1255 // TODO: implement 1256 report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); 1257 } 1258 1259 uint8_t MachOObjectFile::getBytesInAddress() const { 1260 return is64Bit() ? 8 : 4; 1261 } 1262 1263 StringRef MachOObjectFile::getFileFormatName() const { 1264 unsigned CPUType = getCPUType(this); 1265 if (!is64Bit()) { 1266 switch (CPUType) { 1267 case llvm::MachO::CPU_TYPE_I386: 1268 return "Mach-O 32-bit i386"; 1269 case llvm::MachO::CPU_TYPE_ARM: 1270 return "Mach-O arm"; 1271 case llvm::MachO::CPU_TYPE_POWERPC: 1272 return "Mach-O 32-bit ppc"; 1273 default: 1274 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 && 1275 "64-bit object file when we're not 64-bit?"); 1276 return "Mach-O 32-bit unknown"; 1277 } 1278 } 1279 1280 // Make sure the cpu type has the correct mask. 1281 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) 1282 == llvm::MachO::CPU_ARCH_ABI64 && 1283 "32-bit object file when we're 64-bit?"); 1284 1285 switch (CPUType) { 1286 case llvm::MachO::CPU_TYPE_X86_64: 1287 return "Mach-O 64-bit x86-64"; 1288 case llvm::MachO::CPU_TYPE_ARM64: 1289 return "Mach-O arm64"; 1290 case llvm::MachO::CPU_TYPE_POWERPC64: 1291 return "Mach-O 64-bit ppc64"; 1292 default: 1293 return "Mach-O 64-bit unknown"; 1294 } 1295 } 1296 1297 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 1298 switch (CPUType) { 1299 case llvm::MachO::CPU_TYPE_I386: 1300 return Triple::x86; 1301 case llvm::MachO::CPU_TYPE_X86_64: 1302 return Triple::x86_64; 1303 case llvm::MachO::CPU_TYPE_ARM: 1304 return Triple::arm; 1305 case llvm::MachO::CPU_TYPE_ARM64: 1306 return Triple::arm64; 1307 case llvm::MachO::CPU_TYPE_POWERPC: 1308 return Triple::ppc; 1309 case llvm::MachO::CPU_TYPE_POWERPC64: 1310 return Triple::ppc64; 1311 default: 1312 return Triple::UnknownArch; 1313 } 1314 } 1315 1316 Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) { 1317 switch (CPUType) { 1318 case MachO::CPU_TYPE_I386: 1319 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1320 case MachO::CPU_SUBTYPE_I386_ALL: 1321 return Triple("i386-apple-darwin"); 1322 default: 1323 return Triple(); 1324 } 1325 case MachO::CPU_TYPE_X86_64: 1326 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1327 case MachO::CPU_SUBTYPE_X86_64_ALL: 1328 return Triple("x86_64-apple-darwin"); 1329 case MachO::CPU_SUBTYPE_X86_64_H: 1330 return Triple("x86_64h-apple-darwin"); 1331 default: 1332 return Triple(); 1333 } 1334 case MachO::CPU_TYPE_ARM: 1335 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1336 case MachO::CPU_SUBTYPE_ARM_V4T: 1337 return Triple("armv4t-apple-darwin"); 1338 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 1339 return Triple("armv5e-apple-darwin"); 1340 case MachO::CPU_SUBTYPE_ARM_V6: 1341 return Triple("armv6-apple-darwin"); 1342 case MachO::CPU_SUBTYPE_ARM_V6M: 1343 return Triple("armv6m-apple-darwin"); 1344 case MachO::CPU_SUBTYPE_ARM_V7EM: 1345 return Triple("armv7em-apple-darwin"); 1346 case MachO::CPU_SUBTYPE_ARM_V7K: 1347 return Triple("armv7k-apple-darwin"); 1348 case MachO::CPU_SUBTYPE_ARM_V7M: 1349 return Triple("armv7m-apple-darwin"); 1350 case MachO::CPU_SUBTYPE_ARM_V7S: 1351 return Triple("armv7s-apple-darwin"); 1352 default: 1353 return Triple(); 1354 } 1355 case MachO::CPU_TYPE_ARM64: 1356 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1357 case MachO::CPU_SUBTYPE_ARM64_ALL: 1358 return Triple("arm64-apple-darwin"); 1359 default: 1360 return Triple(); 1361 } 1362 case MachO::CPU_TYPE_POWERPC: 1363 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1364 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1365 return Triple("ppc-apple-darwin"); 1366 default: 1367 return Triple(); 1368 } 1369 case MachO::CPU_TYPE_POWERPC64: 1370 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 1371 case MachO::CPU_SUBTYPE_POWERPC_ALL: 1372 return Triple("ppc64-apple-darwin"); 1373 default: 1374 return Triple(); 1375 } 1376 default: 1377 return Triple(); 1378 } 1379 } 1380 1381 Triple MachOObjectFile::getHostArch() { 1382 return Triple(sys::getDefaultTargetTriple()); 1383 } 1384 1385 Triple MachOObjectFile::getArch(StringRef ArchFlag) { 1386 if (ArchFlag == "i386") 1387 return Triple("i386-apple-darwin"); 1388 else if (ArchFlag == "x86_64") 1389 return Triple("x86_64-apple-darwin"); 1390 else if (ArchFlag == "x86_64h") 1391 return Triple("x86_64h-apple-darwin"); 1392 else if (ArchFlag == "armv4t" || ArchFlag == "arm") 1393 return Triple("armv4t-apple-darwin"); 1394 else if (ArchFlag == "armv5e") 1395 return Triple("armv5e-apple-darwin"); 1396 else if (ArchFlag == "armv6") 1397 return Triple("armv6-apple-darwin"); 1398 else if (ArchFlag == "armv6m") 1399 return Triple("armv6m-apple-darwin"); 1400 else if (ArchFlag == "armv7em") 1401 return Triple("armv7em-apple-darwin"); 1402 else if (ArchFlag == "armv7k") 1403 return Triple("armv7k-apple-darwin"); 1404 else if (ArchFlag == "armv7k") 1405 return Triple("armv7m-apple-darwin"); 1406 else if (ArchFlag == "armv7s") 1407 return Triple("armv7s-apple-darwin"); 1408 else if (ArchFlag == "arm64") 1409 return Triple("arm64-apple-darwin"); 1410 else if (ArchFlag == "ppc") 1411 return Triple("ppc-apple-darwin"); 1412 else if (ArchFlag == "ppc64") 1413 return Triple("ppc64-apple-darwin"); 1414 else 1415 return Triple(); 1416 } 1417 1418 unsigned MachOObjectFile::getArch() const { 1419 return getArch(getCPUType(this)); 1420 } 1421 1422 StringRef MachOObjectFile::getLoadName() const { 1423 // TODO: Implement 1424 report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); 1425 } 1426 1427 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 1428 DataRefImpl DRI; 1429 DRI.d.a = Index; 1430 return section_rel_begin(DRI); 1431 } 1432 1433 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 1434 DataRefImpl DRI; 1435 DRI.d.a = Index; 1436 return section_rel_end(DRI); 1437 } 1438 1439 dice_iterator MachOObjectFile::begin_dices() const { 1440 DataRefImpl DRI; 1441 if (!DataInCodeLoadCmd) 1442 return dice_iterator(DiceRef(DRI, this)); 1443 1444 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1445 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff)); 1446 return dice_iterator(DiceRef(DRI, this)); 1447 } 1448 1449 dice_iterator MachOObjectFile::end_dices() const { 1450 DataRefImpl DRI; 1451 if (!DataInCodeLoadCmd) 1452 return dice_iterator(DiceRef(DRI, this)); 1453 1454 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 1455 unsigned Offset = DicLC.dataoff + DicLC.datasize; 1456 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); 1457 return dice_iterator(DiceRef(DRI, this)); 1458 } 1459 1460 StringRef 1461 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 1462 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 1463 return parseSegmentOrSectionName(Raw.data()); 1464 } 1465 1466 ArrayRef<char> 1467 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 1468 const section_base *Base = 1469 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1470 return ArrayRef<char>(Base->sectname); 1471 } 1472 1473 ArrayRef<char> 1474 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 1475 const section_base *Base = 1476 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 1477 return ArrayRef<char>(Base->segname); 1478 } 1479 1480 bool 1481 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 1482 const { 1483 if (getCPUType(this) == MachO::CPU_TYPE_X86_64) 1484 return false; 1485 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 1486 } 1487 1488 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 1489 const MachO::any_relocation_info &RE) const { 1490 if (isLittleEndian()) 1491 return RE.r_word1 & 0xffffff; 1492 return RE.r_word1 >> 8; 1493 } 1494 1495 bool MachOObjectFile::getPlainRelocationExternal( 1496 const MachO::any_relocation_info &RE) const { 1497 if (isLittleEndian()) 1498 return (RE.r_word1 >> 27) & 1; 1499 return (RE.r_word1 >> 4) & 1; 1500 } 1501 1502 bool MachOObjectFile::getScatteredRelocationScattered( 1503 const MachO::any_relocation_info &RE) const { 1504 return RE.r_word0 >> 31; 1505 } 1506 1507 uint32_t MachOObjectFile::getScatteredRelocationValue( 1508 const MachO::any_relocation_info &RE) const { 1509 return RE.r_word1; 1510 } 1511 1512 unsigned MachOObjectFile::getAnyRelocationAddress( 1513 const MachO::any_relocation_info &RE) const { 1514 if (isRelocationScattered(RE)) 1515 return getScatteredRelocationAddress(RE); 1516 return getPlainRelocationAddress(RE); 1517 } 1518 1519 unsigned MachOObjectFile::getAnyRelocationPCRel( 1520 const MachO::any_relocation_info &RE) const { 1521 if (isRelocationScattered(RE)) 1522 return getScatteredRelocationPCRel(this, RE); 1523 return getPlainRelocationPCRel(this, RE); 1524 } 1525 1526 unsigned MachOObjectFile::getAnyRelocationLength( 1527 const MachO::any_relocation_info &RE) const { 1528 if (isRelocationScattered(RE)) 1529 return getScatteredRelocationLength(RE); 1530 return getPlainRelocationLength(this, RE); 1531 } 1532 1533 unsigned 1534 MachOObjectFile::getAnyRelocationType( 1535 const MachO::any_relocation_info &RE) const { 1536 if (isRelocationScattered(RE)) 1537 return getScatteredRelocationType(RE); 1538 return getPlainRelocationType(this, RE); 1539 } 1540 1541 SectionRef 1542 MachOObjectFile::getRelocationSection( 1543 const MachO::any_relocation_info &RE) const { 1544 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 1545 return *section_end(); 1546 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; 1547 DataRefImpl DRI; 1548 DRI.d.a = SecNum; 1549 return SectionRef(DRI, this); 1550 } 1551 1552 MachOObjectFile::LoadCommandInfo 1553 MachOObjectFile::getFirstLoadCommandInfo() const { 1554 MachOObjectFile::LoadCommandInfo Load; 1555 1556 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) : 1557 sizeof(MachO::mach_header); 1558 Load.Ptr = getPtr(this, HeaderSize); 1559 Load.C = getStruct<MachO::load_command>(this, Load.Ptr); 1560 return Load; 1561 } 1562 1563 MachOObjectFile::LoadCommandInfo 1564 MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const { 1565 MachOObjectFile::LoadCommandInfo Next; 1566 Next.Ptr = L.Ptr + L.C.cmdsize; 1567 Next.C = getStruct<MachO::load_command>(this, Next.Ptr); 1568 return Next; 1569 } 1570 1571 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 1572 return getStruct<MachO::section>(this, Sections[DRI.d.a]); 1573 } 1574 1575 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 1576 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]); 1577 } 1578 1579 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 1580 unsigned Index) const { 1581 const char *Sec = getSectionPtr(this, L, Index); 1582 return getStruct<MachO::section>(this, Sec); 1583 } 1584 1585 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 1586 unsigned Index) const { 1587 const char *Sec = getSectionPtr(this, L, Index); 1588 return getStruct<MachO::section_64>(this, Sec); 1589 } 1590 1591 MachO::nlist 1592 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 1593 const char *P = reinterpret_cast<const char *>(DRI.p); 1594 return getStruct<MachO::nlist>(this, P); 1595 } 1596 1597 MachO::nlist_64 1598 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 1599 const char *P = reinterpret_cast<const char *>(DRI.p); 1600 return getStruct<MachO::nlist_64>(this, P); 1601 } 1602 1603 MachO::linkedit_data_command 1604 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 1605 return getStruct<MachO::linkedit_data_command>(this, L.Ptr); 1606 } 1607 1608 MachO::segment_command 1609 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 1610 return getStruct<MachO::segment_command>(this, L.Ptr); 1611 } 1612 1613 MachO::segment_command_64 1614 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 1615 return getStruct<MachO::segment_command_64>(this, L.Ptr); 1616 } 1617 1618 MachO::linker_options_command 1619 MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const { 1620 return getStruct<MachO::linker_options_command>(this, L.Ptr); 1621 } 1622 1623 MachO::version_min_command 1624 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 1625 return getStruct<MachO::version_min_command>(this, L.Ptr); 1626 } 1627 1628 MachO::dylib_command 1629 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 1630 return getStruct<MachO::dylib_command>(this, L.Ptr); 1631 } 1632 1633 1634 MachO::any_relocation_info 1635 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 1636 DataRefImpl Sec; 1637 Sec.d.a = Rel.d.a; 1638 uint32_t Offset; 1639 if (is64Bit()) { 1640 MachO::section_64 Sect = getSection64(Sec); 1641 Offset = Sect.reloff; 1642 } else { 1643 MachO::section Sect = getSection(Sec); 1644 Offset = Sect.reloff; 1645 } 1646 1647 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 1648 getPtr(this, Offset)) + Rel.d.b; 1649 return getStruct<MachO::any_relocation_info>( 1650 this, reinterpret_cast<const char *>(P)); 1651 } 1652 1653 MachO::data_in_code_entry 1654 MachOObjectFile::getDice(DataRefImpl Rel) const { 1655 const char *P = reinterpret_cast<const char *>(Rel.p); 1656 return getStruct<MachO::data_in_code_entry>(this, P); 1657 } 1658 1659 MachO::mach_header MachOObjectFile::getHeader() const { 1660 return getStruct<MachO::mach_header>(this, getPtr(this, 0)); 1661 } 1662 1663 MachO::mach_header_64 MachOObjectFile::getHeader64() const { 1664 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0)); 1665 } 1666 1667 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 1668 const MachO::dysymtab_command &DLC, 1669 unsigned Index) const { 1670 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 1671 return getStruct<uint32_t>(this, getPtr(this, Offset)); 1672 } 1673 1674 MachO::data_in_code_entry 1675 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 1676 unsigned Index) const { 1677 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 1678 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset)); 1679 } 1680 1681 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 1682 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd); 1683 } 1684 1685 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 1686 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd); 1687 } 1688 1689 MachO::linkedit_data_command 1690 MachOObjectFile::getDataInCodeLoadCommand() const { 1691 if (DataInCodeLoadCmd) 1692 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd); 1693 1694 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 1695 MachO::linkedit_data_command Cmd; 1696 Cmd.cmd = MachO::LC_DATA_IN_CODE; 1697 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 1698 Cmd.dataoff = 0; 1699 Cmd.datasize = 0; 1700 return Cmd; 1701 } 1702 1703 StringRef MachOObjectFile::getStringTableData() const { 1704 MachO::symtab_command S = getSymtabLoadCommand(); 1705 return getData().substr(S.stroff, S.strsize); 1706 } 1707 1708 bool MachOObjectFile::is64Bit() const { 1709 return getType() == getMachOType(false, true) || 1710 getType() == getMachOType(true, true); 1711 } 1712 1713 void MachOObjectFile::ReadULEB128s(uint64_t Index, 1714 SmallVectorImpl<uint64_t> &Out) const { 1715 DataExtractor extractor(ObjectFile::getData(), true, 0); 1716 1717 uint32_t offset = Index; 1718 uint64_t data = 0; 1719 while (uint64_t delta = extractor.getULEB128(&offset)) { 1720 data += delta; 1721 Out.push_back(data); 1722 } 1723 } 1724 1725 ErrorOr<ObjectFile *> 1726 ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) { 1727 StringRef Magic = Buffer->getBuffer().slice(0, 4); 1728 std::error_code EC; 1729 std::unique_ptr<MachOObjectFile> Ret; 1730 if (Magic == "\xFE\xED\xFA\xCE") 1731 Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC)); 1732 else if (Magic == "\xCE\xFA\xED\xFE") 1733 Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC)); 1734 else if (Magic == "\xFE\xED\xFA\xCF") 1735 Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC)); 1736 else if (Magic == "\xCF\xFA\xED\xFE") 1737 Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC)); 1738 else 1739 return object_error::parse_failed; 1740 1741 if (EC) 1742 return EC; 1743 return Ret.release(); 1744 } 1745 1746