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