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 if (MachOObj->is64Bit()) { 130 InMemoryStruct<macho::Symbol64TableEntry> Entry; 131 getSymbol64TableEntry(DRI, Entry); 132 Result = Entry->Value; 133 } else { 134 InMemoryStruct<macho::SymbolTableEntry> Entry; 135 getSymbolTableEntry(DRI, Entry); 136 Result = Entry->Value; 137 } 138 return object_error::success; 139 } 140 141 error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, 142 uint64_t &Result) const { 143 uint64_t SymbolOffset; 144 uint8_t SectionIndex; 145 if (MachOObj->is64Bit()) { 146 InMemoryStruct<macho::Symbol64TableEntry> Entry; 147 getSymbol64TableEntry(DRI, Entry); 148 SymbolOffset = Entry->Value; 149 SectionIndex = Entry->SectionIndex; 150 } else { 151 InMemoryStruct<macho::SymbolTableEntry> Entry; 152 getSymbolTableEntry(DRI, Entry); 153 SymbolOffset = Entry->Value; 154 SectionIndex = Entry->SectionIndex; 155 } 156 getSectionAddress(Sections[SectionIndex-1], Result); 157 Result += SymbolOffset; 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::SymbolType &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 switch (n_type & MachO::NlistMaskType) { 245 case MachO::NListTypeUndefined : 246 Res = SymbolRef::ST_External; 247 break; 248 case MachO::NListTypeSection : 249 Res = SymbolRef::ST_Function; 250 break; 251 } 252 return object_error::success; 253 } 254 255 256 symbol_iterator MachOObjectFile::begin_symbols() const { 257 // DRI.d.a = segment number; DRI.d.b = symbol index. 258 DataRefImpl DRI; 259 DRI.d.a = DRI.d.b = 0; 260 moveToNextSymbol(DRI); 261 return symbol_iterator(SymbolRef(DRI, this)); 262 } 263 264 symbol_iterator MachOObjectFile::end_symbols() const { 265 DataRefImpl DRI; 266 DRI.d.a = MachOObj->getHeader().NumLoadCommands; 267 DRI.d.b = 0; 268 return symbol_iterator(SymbolRef(DRI, this)); 269 } 270 271 272 /*===-- Sections ----------------------------------------------------------===*/ 273 274 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { 275 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; 276 while (DRI.d.a < LoadCommandCount) { 277 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 278 if (LCI.Command.Type == macho::LCT_Segment) { 279 InMemoryStruct<macho::SegmentLoadCommand> SegmentLoadCmd; 280 MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd); 281 if (DRI.d.b < SegmentLoadCmd->NumSections) 282 return; 283 } else if (LCI.Command.Type == macho::LCT_Segment64) { 284 InMemoryStruct<macho::Segment64LoadCommand> Segment64LoadCmd; 285 MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd); 286 if (DRI.d.b < Segment64LoadCmd->NumSections) 287 return; 288 } 289 290 DRI.d.a++; 291 DRI.d.b = 0; 292 } 293 } 294 295 error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, 296 SectionRef &Result) const { 297 DRI.d.b++; 298 moveToNextSection(DRI); 299 Result = SectionRef(DRI, this); 300 return object_error::success; 301 } 302 303 void 304 MachOObjectFile::getSection(DataRefImpl DRI, 305 InMemoryStruct<macho::Section> &Res) const { 306 InMemoryStruct<macho::SegmentLoadCommand> SLC; 307 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 308 MachOObj->ReadSegmentLoadCommand(LCI, SLC); 309 MachOObj->ReadSection(LCI, DRI.d.b, Res); 310 } 311 312 std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { 313 SectionList::const_iterator loc = 314 std::find(Sections.begin(), Sections.end(), Sec); 315 assert(loc != Sections.end() && "Sec is not a valid section!"); 316 return std::distance(Sections.begin(), loc); 317 } 318 319 void 320 MachOObjectFile::getSection64(DataRefImpl DRI, 321 InMemoryStruct<macho::Section64> &Res) const { 322 InMemoryStruct<macho::Segment64LoadCommand> SLC; 323 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 324 MachOObj->ReadSegment64LoadCommand(LCI, SLC); 325 MachOObj->ReadSection64(LCI, DRI.d.b, Res); 326 } 327 328 static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { 329 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 330 if (LCI.Command.Type == macho::LCT_Segment64) 331 return true; 332 assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); 333 return false; 334 } 335 336 error_code MachOObjectFile::getSectionName(DataRefImpl DRI, 337 StringRef &Result) const { 338 // FIXME: thread safety. 339 static char result[34]; 340 if (is64BitLoadCommand(MachOObj, DRI)) { 341 InMemoryStruct<macho::Segment64LoadCommand> SLC; 342 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 343 MachOObj->ReadSegment64LoadCommand(LCI, SLC); 344 InMemoryStruct<macho::Section64> Sect; 345 MachOObj->ReadSection64(LCI, DRI.d.b, Sect); 346 347 strcpy(result, Sect->SegmentName); 348 strcat(result, ","); 349 strcat(result, Sect->Name); 350 } else { 351 InMemoryStruct<macho::SegmentLoadCommand> SLC; 352 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 353 MachOObj->ReadSegmentLoadCommand(LCI, SLC); 354 InMemoryStruct<macho::Section> Sect; 355 MachOObj->ReadSection(LCI, DRI.d.b, Sect); 356 357 strcpy(result, Sect->SegmentName); 358 strcat(result, ","); 359 strcat(result, Sect->Name); 360 } 361 Result = StringRef(result); 362 return object_error::success; 363 } 364 365 error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, 366 uint64_t &Result) const { 367 if (is64BitLoadCommand(MachOObj, DRI)) { 368 InMemoryStruct<macho::Section64> Sect; 369 getSection64(DRI, Sect); 370 Result = Sect->Address; 371 } else { 372 InMemoryStruct<macho::Section> Sect; 373 getSection(DRI, Sect); 374 Result = Sect->Address; 375 } 376 return object_error::success; 377 } 378 379 error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, 380 uint64_t &Result) const { 381 if (is64BitLoadCommand(MachOObj, DRI)) { 382 InMemoryStruct<macho::Section64> Sect; 383 getSection64(DRI, Sect); 384 Result = Sect->Size; 385 } else { 386 InMemoryStruct<macho::Section> Sect; 387 getSection(DRI, Sect); 388 Result = Sect->Size; 389 } 390 return object_error::success; 391 } 392 393 error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, 394 StringRef &Result) const { 395 if (is64BitLoadCommand(MachOObj, DRI)) { 396 InMemoryStruct<macho::Section64> Sect; 397 getSection64(DRI, Sect); 398 Result = MachOObj->getData(Sect->Offset, Sect->Size); 399 } else { 400 InMemoryStruct<macho::Section> Sect; 401 getSection(DRI, Sect); 402 Result = MachOObj->getData(Sect->Offset, Sect->Size); 403 } 404 return object_error::success; 405 } 406 407 error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, 408 uint64_t &Result) const { 409 if (is64BitLoadCommand(MachOObj, DRI)) { 410 InMemoryStruct<macho::Section64> Sect; 411 getSection64(DRI, Sect); 412 Result = uint64_t(1) << Sect->Align; 413 } else { 414 InMemoryStruct<macho::Section> Sect; 415 getSection(DRI, Sect); 416 Result = uint64_t(1) << Sect->Align; 417 } 418 return object_error::success; 419 } 420 421 error_code MachOObjectFile::isSectionText(DataRefImpl DRI, 422 bool &Result) const { 423 if (is64BitLoadCommand(MachOObj, DRI)) { 424 InMemoryStruct<macho::Section64> Sect; 425 getSection64(DRI, Sect); 426 Result = !strcmp(Sect->Name, "__text"); 427 } else { 428 InMemoryStruct<macho::Section> Sect; 429 getSection(DRI, Sect); 430 Result = !strcmp(Sect->Name, "__text"); 431 } 432 return object_error::success; 433 } 434 435 error_code MachOObjectFile::isSectionData(DataRefImpl DRI, 436 bool &Result) const { 437 // FIXME: Unimplemented. 438 Result = false; 439 return object_error::success; 440 } 441 442 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, 443 bool &Result) const { 444 // FIXME: Unimplemented. 445 Result = false; 446 return object_error::success; 447 } 448 449 error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, 450 DataRefImpl Symb, 451 bool &Result) const { 452 SymbolRef::SymbolType ST; 453 getSymbolType(Symb, ST); 454 if (ST == SymbolRef::ST_External) { 455 Result = false; 456 return object_error::success; 457 } 458 459 uint64_t SectBegin, SectEnd; 460 getSectionAddress(Sec, SectBegin); 461 getSectionSize(Sec, SectEnd); 462 SectEnd += SectBegin; 463 464 if (MachOObj->is64Bit()) { 465 InMemoryStruct<macho::Symbol64TableEntry> Entry; 466 getSymbol64TableEntry(Symb, Entry); 467 uint64_t SymAddr= Entry->Value; 468 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); 469 } else { 470 InMemoryStruct<macho::SymbolTableEntry> Entry; 471 getSymbolTableEntry(Symb, Entry); 472 uint64_t SymAddr= Entry->Value; 473 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); 474 } 475 476 return object_error::success; 477 } 478 479 relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { 480 DataRefImpl ret; 481 ret.d.a = 0; 482 ret.d.b = getSectionIndex(Sec); 483 return relocation_iterator(RelocationRef(ret, this)); 484 } 485 relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { 486 uint32_t last_reloc; 487 if (is64BitLoadCommand(MachOObj, Sec)) { 488 InMemoryStruct<macho::Section64> Sect; 489 getSection64(Sec, Sect); 490 last_reloc = Sect->NumRelocationTableEntries; 491 } else { 492 InMemoryStruct<macho::Section> Sect; 493 getSection(Sec, Sect); 494 last_reloc = Sect->NumRelocationTableEntries; 495 } 496 DataRefImpl ret; 497 ret.d.a = last_reloc; 498 ret.d.b = getSectionIndex(Sec); 499 return relocation_iterator(RelocationRef(ret, this)); 500 } 501 502 section_iterator MachOObjectFile::begin_sections() const { 503 DataRefImpl DRI; 504 DRI.d.a = DRI.d.b = 0; 505 moveToNextSection(DRI); 506 return section_iterator(SectionRef(DRI, this)); 507 } 508 509 section_iterator MachOObjectFile::end_sections() const { 510 DataRefImpl DRI; 511 DRI.d.a = MachOObj->getHeader().NumLoadCommands; 512 DRI.d.b = 0; 513 return section_iterator(SectionRef(DRI, this)); 514 } 515 516 /*===-- Relocations -------------------------------------------------------===*/ 517 518 void MachOObjectFile:: 519 getRelocation(DataRefImpl Rel, 520 InMemoryStruct<macho::RelocationEntry> &Res) const { 521 uint32_t relOffset; 522 if (MachOObj->is64Bit()) { 523 InMemoryStruct<macho::Section64> Sect; 524 getSection64(Sections[Rel.d.b], Sect); 525 relOffset = Sect->RelocationTableOffset; 526 } else { 527 InMemoryStruct<macho::Section> Sect; 528 getSection(Sections[Rel.d.b], Sect); 529 relOffset = Sect->RelocationTableOffset; 530 } 531 MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); 532 } 533 error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, 534 RelocationRef &Res) const { 535 ++Rel.d.a; 536 Res = RelocationRef(Rel, this); 537 return object_error::success; 538 } 539 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, 540 uint64_t &Res) const { 541 const uint8_t* sectAddress = base(); 542 if (MachOObj->is64Bit()) { 543 InMemoryStruct<macho::Section64> Sect; 544 getSection64(Sections[Rel.d.b], Sect); 545 sectAddress += Sect->Offset; 546 } else { 547 InMemoryStruct<macho::Section> Sect; 548 getSection(Sections[Rel.d.b], Sect); 549 sectAddress += Sect->Offset; 550 } 551 InMemoryStruct<macho::RelocationEntry> RE; 552 getRelocation(Rel, RE); 553 Res = reinterpret_cast<uintptr_t>(sectAddress + RE->Word0); 554 return object_error::success; 555 } 556 error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, 557 SymbolRef &Res) const { 558 InMemoryStruct<macho::RelocationEntry> RE; 559 getRelocation(Rel, RE); 560 uint32_t SymbolIdx = RE->Word1 & 0xffffff; 561 bool isExtern = (RE->Word1 >> 27) & 1; 562 563 DataRefImpl Sym; 564 Sym.d.a = Sym.d.b = 0; 565 moveToNextSymbol(Sym); 566 if (isExtern) { 567 for (unsigned i = 0; i < SymbolIdx; i++) { 568 Sym.d.b++; 569 moveToNextSymbol(Sym); 570 assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands && 571 "Relocation symbol index out of range!"); 572 } 573 } 574 Res = SymbolRef(Sym, this); 575 return object_error::success; 576 } 577 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, 578 uint32_t &Res) const { 579 InMemoryStruct<macho::RelocationEntry> RE; 580 getRelocation(Rel, RE); 581 Res = RE->Word1; 582 return object_error::success; 583 } 584 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, 585 SmallVectorImpl<char> &Result) const { 586 return object_error::success; 587 } 588 error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, 589 int64_t &Res) const { 590 InMemoryStruct<macho::RelocationEntry> RE; 591 getRelocation(Rel, RE); 592 bool isExtern = (RE->Word1 >> 27) & 1; 593 Res = 0; 594 if (!isExtern) { 595 const uint8_t* sectAddress = base(); 596 if (MachOObj->is64Bit()) { 597 InMemoryStruct<macho::Section64> Sect; 598 getSection64(Sections[Rel.d.b], Sect); 599 sectAddress += Sect->Offset; 600 } else { 601 InMemoryStruct<macho::Section> Sect; 602 getSection(Sections[Rel.d.b], Sect); 603 sectAddress += Sect->Offset; 604 } 605 Res = reinterpret_cast<uintptr_t>(sectAddress); 606 } 607 return object_error::success; 608 } 609 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, 610 SmallVectorImpl<char> &Result) const { 611 return object_error::success; 612 } 613 614 /*===-- Miscellaneous -----------------------------------------------------===*/ 615 616 uint8_t MachOObjectFile::getBytesInAddress() const { 617 return MachOObj->is64Bit() ? 8 : 4; 618 } 619 620 StringRef MachOObjectFile::getFileFormatName() const { 621 if (!MachOObj->is64Bit()) { 622 switch (MachOObj->getHeader().CPUType) { 623 case llvm::MachO::CPUTypeI386: 624 return "Mach-O 32-bit i386"; 625 case llvm::MachO::CPUTypeARM: 626 return "Mach-O arm"; 627 case llvm::MachO::CPUTypePowerPC: 628 return "Mach-O 32-bit ppc"; 629 default: 630 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && 631 "64-bit object file when we're not 64-bit?"); 632 return "Mach-O 32-bit unknown"; 633 } 634 } 635 636 switch (MachOObj->getHeader().CPUType) { 637 case llvm::MachO::CPUTypeX86_64: 638 return "Mach-O 64-bit x86-64"; 639 case llvm::MachO::CPUTypePowerPC64: 640 return "Mach-O 64-bit ppc64"; 641 default: 642 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 && 643 "32-bit object file when we're 64-bit?"); 644 return "Mach-O 64-bit unknown"; 645 } 646 } 647 648 unsigned MachOObjectFile::getArch() const { 649 switch (MachOObj->getHeader().CPUType) { 650 case llvm::MachO::CPUTypeI386: 651 return Triple::x86; 652 case llvm::MachO::CPUTypeX86_64: 653 return Triple::x86_64; 654 case llvm::MachO::CPUTypeARM: 655 return Triple::arm; 656 case llvm::MachO::CPUTypePowerPC: 657 return Triple::ppc; 658 case llvm::MachO::CPUTypePowerPC64: 659 return Triple::ppc64; 660 default: 661 return Triple::UnknownArch; 662 } 663 } 664 665 } // end namespace object 666 } // end namespace llvm 667