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