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