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