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