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/ADT/Triple.h" 16 #include "llvm/Object/MachO.h" 17 #include "llvm/Object/MachOFormat.h" 18 #include "llvm/Support/MemoryBuffer.h" 19 20 #include <cctype> 21 #include <cstring> 22 #include <limits> 23 24 using namespace llvm; 25 using namespace object; 26 27 namespace llvm { 28 namespace object { 29 30 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, 31 error_code &ec) 32 : ObjectFile(Binary::isMachO, Object, ec), 33 MachOObj(MOO), 34 RegisteredStringTable(std::numeric_limits<uint32_t>::max()) { 35 DataRefImpl DRI; 36 DRI.d.a = DRI.d.b = 0; 37 moveToNextSection(DRI); 38 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; 39 while (DRI.d.a < LoadCommandCount) { 40 Sections.push_back(DRI); 41 DRI.d.b++; 42 moveToNextSection(DRI); 43 } 44 } 45 46 47 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { 48 error_code ec; 49 std::string Err; 50 MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err); 51 if (!MachOObj) 52 return NULL; 53 return new MachOObjectFile(Buffer, MachOObj, ec); 54 } 55 56 /*===-- Symbols -----------------------------------------------------------===*/ 57 58 void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { 59 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; 60 while (DRI.d.a < LoadCommandCount) { 61 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 62 if (LCI.Command.Type == macho::LCT_Symtab) { 63 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; 64 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); 65 if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) 66 return; 67 } 68 69 DRI.d.a++; 70 DRI.d.b = 0; 71 } 72 } 73 74 void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, 75 InMemoryStruct<macho::SymbolTableEntry> &Res) const { 76 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; 77 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 78 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); 79 80 if (RegisteredStringTable != DRI.d.a) { 81 MachOObj->RegisterStringTable(*SymtabLoadCmd); 82 RegisteredStringTable = DRI.d.a; 83 } 84 85 MachOObj->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, 86 Res); 87 } 88 89 void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, 90 InMemoryStruct<macho::Symbol64TableEntry> &Res) const { 91 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; 92 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 93 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); 94 95 if (RegisteredStringTable != DRI.d.a) { 96 MachOObj->RegisterStringTable(*SymtabLoadCmd); 97 RegisteredStringTable = DRI.d.a; 98 } 99 100 MachOObj->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, 101 Res); 102 } 103 104 105 error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, 106 SymbolRef &Result) const { 107 DRI.d.b++; 108 moveToNextSymbol(DRI); 109 Result = SymbolRef(DRI, this); 110 return object_error::success; 111 } 112 113 error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, 114 StringRef &Result) const { 115 if (MachOObj->is64Bit()) { 116 InMemoryStruct<macho::Symbol64TableEntry> Entry; 117 getSymbol64TableEntry(DRI, Entry); 118 Result = MachOObj->getStringAtIndex(Entry->StringIndex); 119 } else { 120 InMemoryStruct<macho::SymbolTableEntry> Entry; 121 getSymbolTableEntry(DRI, Entry); 122 Result = MachOObj->getStringAtIndex(Entry->StringIndex); 123 } 124 return object_error::success; 125 } 126 127 error_code MachOObjectFile::getSymbolOffset(DataRefImpl DRI, 128 uint64_t &Result) const { 129 uint64_t SectionOffset; 130 uint8_t SectionIndex; 131 if (MachOObj->is64Bit()) { 132 InMemoryStruct<macho::Symbol64TableEntry> Entry; 133 getSymbol64TableEntry(DRI, Entry); 134 Result = Entry->Value; 135 SectionIndex = Entry->SectionIndex; 136 } else { 137 InMemoryStruct<macho::SymbolTableEntry> Entry; 138 getSymbolTableEntry(DRI, Entry); 139 Result = Entry->Value; 140 SectionIndex = Entry->SectionIndex; 141 } 142 getSectionAddress(Sections[SectionIndex-1], SectionOffset); 143 Result -= SectionOffset; 144 145 return object_error::success; 146 } 147 148 error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, 149 uint64_t &Result) const { 150 if (MachOObj->is64Bit()) { 151 InMemoryStruct<macho::Symbol64TableEntry> Entry; 152 getSymbol64TableEntry(DRI, Entry); 153 Result = Entry->Value; 154 } else { 155 InMemoryStruct<macho::SymbolTableEntry> Entry; 156 getSymbolTableEntry(DRI, Entry); 157 Result = Entry->Value; 158 } 159 return object_error::success; 160 } 161 162 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, 163 uint64_t &Result) const { 164 Result = UnknownAddressOrSize; 165 return object_error::success; 166 } 167 168 error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, 169 char &Result) const { 170 uint8_t Type, Flags; 171 if (MachOObj->is64Bit()) { 172 InMemoryStruct<macho::Symbol64TableEntry> Entry; 173 getSymbol64TableEntry(DRI, Entry); 174 Type = Entry->Type; 175 Flags = Entry->Flags; 176 } else { 177 InMemoryStruct<macho::SymbolTableEntry> Entry; 178 getSymbolTableEntry(DRI, Entry); 179 Type = Entry->Type; 180 Flags = Entry->Flags; 181 } 182 183 char Char; 184 switch (Type & macho::STF_TypeMask) { 185 case macho::STT_Undefined: 186 Char = 'u'; 187 break; 188 case macho::STT_Absolute: 189 case macho::STT_Section: 190 Char = 's'; 191 break; 192 default: 193 Char = '?'; 194 break; 195 } 196 197 if (Flags & (macho::STF_External | macho::STF_PrivateExtern)) 198 Char = toupper(Char); 199 Result = Char; 200 return object_error::success; 201 } 202 203 error_code MachOObjectFile::isSymbolInternal(DataRefImpl DRI, 204 bool &Result) const { 205 if (MachOObj->is64Bit()) { 206 InMemoryStruct<macho::Symbol64TableEntry> Entry; 207 getSymbol64TableEntry(DRI, Entry); 208 Result = Entry->Flags & macho::STF_StabsEntryMask; 209 } else { 210 InMemoryStruct<macho::SymbolTableEntry> Entry; 211 getSymbolTableEntry(DRI, Entry); 212 Result = Entry->Flags & macho::STF_StabsEntryMask; 213 } 214 return object_error::success; 215 } 216 217 error_code MachOObjectFile::isSymbolGlobal(DataRefImpl Symb, bool &Res) const { 218 219 if (MachOObj->is64Bit()) { 220 InMemoryStruct<macho::Symbol64TableEntry> Entry; 221 getSymbol64TableEntry(Symb, Entry); 222 Res = Entry->Type & MachO::NlistMaskExternal; 223 } else { 224 InMemoryStruct<macho::SymbolTableEntry> Entry; 225 getSymbolTableEntry(Symb, Entry); 226 Res = Entry->Type & MachO::NlistMaskExternal; 227 } 228 return object_error::success; 229 } 230 231 error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, 232 SymbolRef::Type &Res) const { 233 uint8_t n_type; 234 if (MachOObj->is64Bit()) { 235 InMemoryStruct<macho::Symbol64TableEntry> Entry; 236 getSymbol64TableEntry(Symb, Entry); 237 n_type = Entry->Type; 238 } else { 239 InMemoryStruct<macho::SymbolTableEntry> Entry; 240 getSymbolTableEntry(Symb, Entry); 241 n_type = Entry->Type; 242 } 243 Res = SymbolRef::ST_Other; 244 245 // If this is a STAB debugging symbol, we can do nothing more. 246 if (n_type & MachO::NlistMaskStab) 247 return object_error::success; 248 249 switch (n_type & MachO::NlistMaskType) { 250 case MachO::NListTypeUndefined : 251 Res = SymbolRef::ST_External; 252 break; 253 case MachO::NListTypeSection : 254 Res = SymbolRef::ST_Function; 255 break; 256 } 257 return object_error::success; 258 } 259 260 261 symbol_iterator MachOObjectFile::begin_symbols() const { 262 // DRI.d.a = segment number; DRI.d.b = symbol index. 263 DataRefImpl DRI; 264 DRI.d.a = DRI.d.b = 0; 265 moveToNextSymbol(DRI); 266 return symbol_iterator(SymbolRef(DRI, this)); 267 } 268 269 symbol_iterator MachOObjectFile::end_symbols() const { 270 DataRefImpl DRI; 271 DRI.d.a = MachOObj->getHeader().NumLoadCommands; 272 DRI.d.b = 0; 273 return symbol_iterator(SymbolRef(DRI, this)); 274 } 275 276 277 /*===-- Sections ----------------------------------------------------------===*/ 278 279 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { 280 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; 281 while (DRI.d.a < LoadCommandCount) { 282 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 283 if (LCI.Command.Type == macho::LCT_Segment) { 284 InMemoryStruct<macho::SegmentLoadCommand> SegmentLoadCmd; 285 MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd); 286 if (DRI.d.b < SegmentLoadCmd->NumSections) 287 return; 288 } else if (LCI.Command.Type == macho::LCT_Segment64) { 289 InMemoryStruct<macho::Segment64LoadCommand> Segment64LoadCmd; 290 MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd); 291 if (DRI.d.b < Segment64LoadCmd->NumSections) 292 return; 293 } 294 295 DRI.d.a++; 296 DRI.d.b = 0; 297 } 298 } 299 300 error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, 301 SectionRef &Result) const { 302 DRI.d.b++; 303 moveToNextSection(DRI); 304 Result = SectionRef(DRI, this); 305 return object_error::success; 306 } 307 308 void 309 MachOObjectFile::getSection(DataRefImpl DRI, 310 InMemoryStruct<macho::Section> &Res) const { 311 InMemoryStruct<macho::SegmentLoadCommand> SLC; 312 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 313 MachOObj->ReadSegmentLoadCommand(LCI, SLC); 314 MachOObj->ReadSection(LCI, DRI.d.b, Res); 315 } 316 317 std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { 318 SectionList::const_iterator loc = 319 std::find(Sections.begin(), Sections.end(), Sec); 320 assert(loc != Sections.end() && "Sec is not a valid section!"); 321 return std::distance(Sections.begin(), loc); 322 } 323 324 void 325 MachOObjectFile::getSection64(DataRefImpl DRI, 326 InMemoryStruct<macho::Section64> &Res) const { 327 InMemoryStruct<macho::Segment64LoadCommand> SLC; 328 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 329 MachOObj->ReadSegment64LoadCommand(LCI, SLC); 330 MachOObj->ReadSection64(LCI, DRI.d.b, Res); 331 } 332 333 static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { 334 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 335 if (LCI.Command.Type == macho::LCT_Segment64) 336 return true; 337 assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); 338 return false; 339 } 340 341 error_code MachOObjectFile::getSectionName(DataRefImpl DRI, 342 StringRef &Result) const { 343 // FIXME: thread safety. 344 static char result[34]; 345 if (is64BitLoadCommand(MachOObj, DRI)) { 346 InMemoryStruct<macho::Segment64LoadCommand> SLC; 347 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 348 MachOObj->ReadSegment64LoadCommand(LCI, SLC); 349 InMemoryStruct<macho::Section64> Sect; 350 MachOObj->ReadSection64(LCI, DRI.d.b, Sect); 351 352 strcpy(result, Sect->SegmentName); 353 strcat(result, ","); 354 strcat(result, Sect->Name); 355 } else { 356 InMemoryStruct<macho::SegmentLoadCommand> SLC; 357 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 358 MachOObj->ReadSegmentLoadCommand(LCI, SLC); 359 InMemoryStruct<macho::Section> Sect; 360 MachOObj->ReadSection(LCI, DRI.d.b, Sect); 361 362 strcpy(result, Sect->SegmentName); 363 strcat(result, ","); 364 strcat(result, Sect->Name); 365 } 366 Result = StringRef(result); 367 return object_error::success; 368 } 369 370 error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, 371 uint64_t &Result) const { 372 if (is64BitLoadCommand(MachOObj, DRI)) { 373 InMemoryStruct<macho::Section64> Sect; 374 getSection64(DRI, Sect); 375 Result = Sect->Address; 376 } else { 377 InMemoryStruct<macho::Section> Sect; 378 getSection(DRI, Sect); 379 Result = Sect->Address; 380 } 381 return object_error::success; 382 } 383 384 error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, 385 uint64_t &Result) const { 386 if (is64BitLoadCommand(MachOObj, DRI)) { 387 InMemoryStruct<macho::Section64> Sect; 388 getSection64(DRI, Sect); 389 Result = Sect->Size; 390 } else { 391 InMemoryStruct<macho::Section> Sect; 392 getSection(DRI, Sect); 393 Result = Sect->Size; 394 } 395 return object_error::success; 396 } 397 398 error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, 399 StringRef &Result) const { 400 if (is64BitLoadCommand(MachOObj, DRI)) { 401 InMemoryStruct<macho::Section64> Sect; 402 getSection64(DRI, Sect); 403 Result = MachOObj->getData(Sect->Offset, Sect->Size); 404 } else { 405 InMemoryStruct<macho::Section> Sect; 406 getSection(DRI, Sect); 407 Result = MachOObj->getData(Sect->Offset, Sect->Size); 408 } 409 return object_error::success; 410 } 411 412 error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, 413 uint64_t &Result) const { 414 if (is64BitLoadCommand(MachOObj, DRI)) { 415 InMemoryStruct<macho::Section64> Sect; 416 getSection64(DRI, Sect); 417 Result = uint64_t(1) << Sect->Align; 418 } else { 419 InMemoryStruct<macho::Section> Sect; 420 getSection(DRI, Sect); 421 Result = uint64_t(1) << Sect->Align; 422 } 423 return object_error::success; 424 } 425 426 error_code MachOObjectFile::isSectionText(DataRefImpl DRI, 427 bool &Result) const { 428 if (is64BitLoadCommand(MachOObj, DRI)) { 429 InMemoryStruct<macho::Section64> Sect; 430 getSection64(DRI, Sect); 431 Result = !strcmp(Sect->Name, "__text"); 432 } else { 433 InMemoryStruct<macho::Section> Sect; 434 getSection(DRI, Sect); 435 Result = !strcmp(Sect->Name, "__text"); 436 } 437 return object_error::success; 438 } 439 440 error_code MachOObjectFile::isSectionData(DataRefImpl DRI, 441 bool &Result) const { 442 // FIXME: Unimplemented. 443 Result = false; 444 return object_error::success; 445 } 446 447 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, 448 bool &Result) const { 449 // FIXME: Unimplemented. 450 Result = false; 451 return object_error::success; 452 } 453 454 error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, 455 DataRefImpl Symb, 456 bool &Result) const { 457 SymbolRef::Type ST; 458 getSymbolType(Symb, ST); 459 if (ST == SymbolRef::ST_External) { 460 Result = false; 461 return object_error::success; 462 } 463 464 uint64_t SectBegin, SectEnd; 465 getSectionAddress(Sec, SectBegin); 466 getSectionSize(Sec, SectEnd); 467 SectEnd += SectBegin; 468 469 if (MachOObj->is64Bit()) { 470 InMemoryStruct<macho::Symbol64TableEntry> Entry; 471 getSymbol64TableEntry(Symb, Entry); 472 uint64_t SymAddr= Entry->Value; 473 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); 474 } else { 475 InMemoryStruct<macho::SymbolTableEntry> Entry; 476 getSymbolTableEntry(Symb, Entry); 477 uint64_t SymAddr= Entry->Value; 478 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); 479 } 480 481 return object_error::success; 482 } 483 484 relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { 485 DataRefImpl ret; 486 ret.d.a = 0; 487 ret.d.b = getSectionIndex(Sec); 488 return relocation_iterator(RelocationRef(ret, this)); 489 } 490 relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { 491 uint32_t last_reloc; 492 if (is64BitLoadCommand(MachOObj, Sec)) { 493 InMemoryStruct<macho::Section64> Sect; 494 getSection64(Sec, Sect); 495 last_reloc = Sect->NumRelocationTableEntries; 496 } else { 497 InMemoryStruct<macho::Section> Sect; 498 getSection(Sec, Sect); 499 last_reloc = Sect->NumRelocationTableEntries; 500 } 501 DataRefImpl ret; 502 ret.d.a = last_reloc; 503 ret.d.b = getSectionIndex(Sec); 504 return relocation_iterator(RelocationRef(ret, this)); 505 } 506 507 section_iterator MachOObjectFile::begin_sections() const { 508 DataRefImpl DRI; 509 DRI.d.a = DRI.d.b = 0; 510 moveToNextSection(DRI); 511 return section_iterator(SectionRef(DRI, this)); 512 } 513 514 section_iterator MachOObjectFile::end_sections() const { 515 DataRefImpl DRI; 516 DRI.d.a = MachOObj->getHeader().NumLoadCommands; 517 DRI.d.b = 0; 518 return section_iterator(SectionRef(DRI, this)); 519 } 520 521 /*===-- Relocations -------------------------------------------------------===*/ 522 523 void MachOObjectFile:: 524 getRelocation(DataRefImpl Rel, 525 InMemoryStruct<macho::RelocationEntry> &Res) const { 526 uint32_t relOffset; 527 if (MachOObj->is64Bit()) { 528 InMemoryStruct<macho::Section64> Sect; 529 getSection64(Sections[Rel.d.b], Sect); 530 relOffset = Sect->RelocationTableOffset; 531 } else { 532 InMemoryStruct<macho::Section> Sect; 533 getSection(Sections[Rel.d.b], Sect); 534 relOffset = Sect->RelocationTableOffset; 535 } 536 MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); 537 } 538 error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, 539 RelocationRef &Res) const { 540 ++Rel.d.a; 541 Res = RelocationRef(Rel, this); 542 return object_error::success; 543 } 544 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, 545 uint64_t &Res) const { 546 const uint8_t* sectAddress = base(); 547 if (MachOObj->is64Bit()) { 548 InMemoryStruct<macho::Section64> Sect; 549 getSection64(Sections[Rel.d.b], Sect); 550 sectAddress += Sect->Offset; 551 } else { 552 InMemoryStruct<macho::Section> Sect; 553 getSection(Sections[Rel.d.b], Sect); 554 sectAddress += Sect->Offset; 555 } 556 InMemoryStruct<macho::RelocationEntry> RE; 557 getRelocation(Rel, RE); 558 Res = reinterpret_cast<uintptr_t>(sectAddress + RE->Word0); 559 return object_error::success; 560 } 561 error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, 562 SymbolRef &Res) const { 563 InMemoryStruct<macho::RelocationEntry> RE; 564 getRelocation(Rel, RE); 565 uint32_t SymbolIdx = RE->Word1 & 0xffffff; 566 bool isExtern = (RE->Word1 >> 27) & 1; 567 568 DataRefImpl Sym; 569 Sym.d.a = Sym.d.b = 0; 570 moveToNextSymbol(Sym); 571 if (isExtern) { 572 for (unsigned i = 0; i < SymbolIdx; i++) { 573 Sym.d.b++; 574 moveToNextSymbol(Sym); 575 assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands && 576 "Relocation symbol index out of range!"); 577 } 578 } 579 Res = SymbolRef(Sym, this); 580 return object_error::success; 581 } 582 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, 583 uint32_t &Res) const { 584 InMemoryStruct<macho::RelocationEntry> RE; 585 getRelocation(Rel, RE); 586 Res = RE->Word1; 587 return object_error::success; 588 } 589 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, 590 SmallVectorImpl<char> &Result) const { 591 return object_error::success; 592 } 593 error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, 594 int64_t &Res) const { 595 InMemoryStruct<macho::RelocationEntry> RE; 596 getRelocation(Rel, RE); 597 bool isExtern = (RE->Word1 >> 27) & 1; 598 Res = 0; 599 if (!isExtern) { 600 const uint8_t* sectAddress = base(); 601 if (MachOObj->is64Bit()) { 602 InMemoryStruct<macho::Section64> Sect; 603 getSection64(Sections[Rel.d.b], Sect); 604 sectAddress += Sect->Offset; 605 } else { 606 InMemoryStruct<macho::Section> Sect; 607 getSection(Sections[Rel.d.b], Sect); 608 sectAddress += Sect->Offset; 609 } 610 Res = reinterpret_cast<uintptr_t>(sectAddress); 611 } 612 return object_error::success; 613 } 614 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, 615 SmallVectorImpl<char> &Result) const { 616 return object_error::success; 617 } 618 619 /*===-- Miscellaneous -----------------------------------------------------===*/ 620 621 uint8_t MachOObjectFile::getBytesInAddress() const { 622 return MachOObj->is64Bit() ? 8 : 4; 623 } 624 625 StringRef MachOObjectFile::getFileFormatName() const { 626 if (!MachOObj->is64Bit()) { 627 switch (MachOObj->getHeader().CPUType) { 628 case llvm::MachO::CPUTypeI386: 629 return "Mach-O 32-bit i386"; 630 case llvm::MachO::CPUTypeARM: 631 return "Mach-O arm"; 632 case llvm::MachO::CPUTypePowerPC: 633 return "Mach-O 32-bit ppc"; 634 default: 635 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && 636 "64-bit object file when we're not 64-bit?"); 637 return "Mach-O 32-bit unknown"; 638 } 639 } 640 641 switch (MachOObj->getHeader().CPUType) { 642 case llvm::MachO::CPUTypeX86_64: 643 return "Mach-O 64-bit x86-64"; 644 case llvm::MachO::CPUTypePowerPC64: 645 return "Mach-O 64-bit ppc64"; 646 default: 647 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 && 648 "32-bit object file when we're 64-bit?"); 649 return "Mach-O 64-bit unknown"; 650 } 651 } 652 653 unsigned MachOObjectFile::getArch() const { 654 switch (MachOObj->getHeader().CPUType) { 655 case llvm::MachO::CPUTypeI386: 656 return Triple::x86; 657 case llvm::MachO::CPUTypeX86_64: 658 return Triple::x86_64; 659 case llvm::MachO::CPUTypeARM: 660 return Triple::arm; 661 case llvm::MachO::CPUTypePowerPC: 662 return Triple::ppc; 663 case llvm::MachO::CPUTypePowerPC64: 664 return Triple::ppc64; 665 default: 666 return Triple::UnknownArch; 667 } 668 } 669 670 } // end namespace object 671 } // end namespace llvm 672