MachOObjectFile.cpp revision 41242942fcbb2e6bc4e5bed3e8041f7b20ece8af
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 24using namespace llvm; 25using namespace object; 26 27namespace llvm { 28namespace object { 29 30MachOObjectFile::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 47ObjectFile *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 58void 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 74void 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 89void 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 105error_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 113error_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 127error_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 141error_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 162error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, 163 uint64_t &Result) const { 164 Result = UnknownAddressOrSize; 165 return object_error::success; 166} 167 168error_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 203error_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 217error_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 231error_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 256symbol_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 264symbol_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 274void 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 295error_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 303void 304MachOObjectFile::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 312std::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 319void 320MachOObjectFile::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 328static 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 336error_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 365error_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 379error_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 393error_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 407error_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 421error_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 435error_code MachOObjectFile::isSectionData(DataRefImpl DRI, 436 bool &Result) const { 437 // FIXME: Unimplemented. 438 Result = false; 439 return object_error::success; 440} 441 442error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, 443 bool &Result) const { 444 // FIXME: Unimplemented. 445 Result = false; 446 return object_error::success; 447} 448 449error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, 450 DataRefImpl Symb, 451 bool &Result) const { 452 if (MachOObj->is64Bit()) { 453 InMemoryStruct<macho::Symbol64TableEntry> Entry; 454 getSymbol64TableEntry(Symb, Entry); 455 Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; 456 } else { 457 InMemoryStruct<macho::SymbolTableEntry> Entry; 458 getSymbolTableEntry(Symb, Entry); 459 Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; 460 } 461 return object_error::success; 462} 463 464relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { 465 DataRefImpl ret; 466 ret.d.a = 0; 467 ret.d.b = getSectionIndex(Sec); 468 return relocation_iterator(RelocationRef(ret, this)); 469} 470relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { 471 uint32_t last_reloc; 472 if (is64BitLoadCommand(MachOObj, Sec)) { 473 InMemoryStruct<macho::Section64> Sect; 474 getSection64(Sec, Sect); 475 last_reloc = Sect->NumRelocationTableEntries; 476 } else { 477 InMemoryStruct<macho::Section> Sect; 478 getSection(Sec, Sect); 479 last_reloc = Sect->NumRelocationTableEntries; 480 } 481 DataRefImpl ret; 482 ret.d.a = last_reloc; 483 ret.d.b = getSectionIndex(Sec); 484 return relocation_iterator(RelocationRef(ret, this)); 485} 486 487section_iterator MachOObjectFile::begin_sections() const { 488 DataRefImpl DRI; 489 DRI.d.a = DRI.d.b = 0; 490 moveToNextSection(DRI); 491 return section_iterator(SectionRef(DRI, this)); 492} 493 494section_iterator MachOObjectFile::end_sections() const { 495 DataRefImpl DRI; 496 DRI.d.a = MachOObj->getHeader().NumLoadCommands; 497 DRI.d.b = 0; 498 return section_iterator(SectionRef(DRI, this)); 499} 500 501/*===-- Relocations -------------------------------------------------------===*/ 502 503void MachOObjectFile:: 504getRelocation(DataRefImpl Rel, 505 InMemoryStruct<macho::RelocationEntry> &Res) const { 506 uint32_t relOffset; 507 if (MachOObj->is64Bit()) { 508 InMemoryStruct<macho::Section64> Sect; 509 getSection64(Sections[Rel.d.b], Sect); 510 relOffset = Sect->RelocationTableOffset; 511 } else { 512 InMemoryStruct<macho::Section> Sect; 513 getSection(Sections[Rel.d.b], Sect); 514 relOffset = Sect->RelocationTableOffset; 515 } 516 MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); 517} 518error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, 519 RelocationRef &Res) const { 520 ++Rel.d.a; 521 Res = RelocationRef(Rel, this); 522 return object_error::success; 523} 524error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, 525 uint64_t &Res) const { 526 const uint8_t* sectAddress = base(); 527 if (MachOObj->is64Bit()) { 528 InMemoryStruct<macho::Section64> Sect; 529 getSection64(Sections[Rel.d.b], Sect); 530 sectAddress += Sect->Offset; 531 } else { 532 InMemoryStruct<macho::Section> Sect; 533 getSection(Sections[Rel.d.b], Sect); 534 sectAddress += Sect->Offset; 535 } 536 InMemoryStruct<macho::RelocationEntry> RE; 537 getRelocation(Rel, RE); 538 Res = reinterpret_cast<uintptr_t>(sectAddress + RE->Word0); 539 return object_error::success; 540} 541error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, 542 SymbolRef &Res) const { 543 InMemoryStruct<macho::RelocationEntry> RE; 544 getRelocation(Rel, RE); 545 uint32_t SymbolIdx = RE->Word1 & 0xffffff; 546 bool isExtern = (RE->Word1 >> 27) & 1; 547 548 DataRefImpl Sym; 549 Sym.d.a = Sym.d.b = 0; 550 moveToNextSymbol(Sym); 551 if (isExtern) { 552 for (unsigned i = 0; i < SymbolIdx; i++) { 553 Sym.d.b++; 554 moveToNextSymbol(Sym); 555 assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands && 556 "Relocation symbol index out of range!"); 557 } 558 } 559 Res = SymbolRef(Sym, this); 560 return object_error::success; 561} 562error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, 563 uint32_t &Res) const { 564 InMemoryStruct<macho::RelocationEntry> RE; 565 getRelocation(Rel, RE); 566 Res = RE->Word1; 567 return object_error::success; 568} 569error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, 570 SmallVectorImpl<char> &Result) const { 571 return object_error::success; 572} 573error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, 574 int64_t &Res) const { 575 InMemoryStruct<macho::RelocationEntry> RE; 576 getRelocation(Rel, RE); 577 bool isExtern = (RE->Word1 >> 27) & 1; 578 Res = 0; 579 if (!isExtern) { 580 const uint8_t* sectAddress = base(); 581 if (MachOObj->is64Bit()) { 582 InMemoryStruct<macho::Section64> Sect; 583 getSection64(Sections[Rel.d.b], Sect); 584 sectAddress += Sect->Offset; 585 } else { 586 InMemoryStruct<macho::Section> Sect; 587 getSection(Sections[Rel.d.b], Sect); 588 sectAddress += Sect->Offset; 589 } 590 Res = reinterpret_cast<uintptr_t>(sectAddress); 591 } 592 return object_error::success; 593} 594error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, 595 SmallVectorImpl<char> &Result) const { 596 return object_error::success; 597} 598 599/*===-- Miscellaneous -----------------------------------------------------===*/ 600 601uint8_t MachOObjectFile::getBytesInAddress() const { 602 return MachOObj->is64Bit() ? 8 : 4; 603} 604 605StringRef MachOObjectFile::getFileFormatName() const { 606 if (!MachOObj->is64Bit()) { 607 switch (MachOObj->getHeader().CPUType) { 608 case llvm::MachO::CPUTypeI386: 609 return "Mach-O 32-bit i386"; 610 case llvm::MachO::CPUTypeARM: 611 return "Mach-O arm"; 612 case llvm::MachO::CPUTypePowerPC: 613 return "Mach-O 32-bit ppc"; 614 default: 615 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && 616 "64-bit object file when we're not 64-bit?"); 617 return "Mach-O 32-bit unknown"; 618 } 619 } 620 621 switch (MachOObj->getHeader().CPUType) { 622 case llvm::MachO::CPUTypeX86_64: 623 return "Mach-O 64-bit x86-64"; 624 case llvm::MachO::CPUTypePowerPC64: 625 return "Mach-O 64-bit ppc64"; 626 default: 627 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 && 628 "32-bit object file when we're 64-bit?"); 629 return "Mach-O 64-bit unknown"; 630 } 631} 632 633unsigned MachOObjectFile::getArch() const { 634 switch (MachOObj->getHeader().CPUType) { 635 case llvm::MachO::CPUTypeI386: 636 return Triple::x86; 637 case llvm::MachO::CPUTypeX86_64: 638 return Triple::x86_64; 639 case llvm::MachO::CPUTypeARM: 640 return Triple::arm; 641 case llvm::MachO::CPUTypePowerPC: 642 return Triple::ppc; 643 case llvm::MachO::CPUTypePowerPC64: 644 return Triple::ppc64; 645 default: 646 return Triple::UnknownArch; 647 } 648} 649 650} // end namespace object 651} // end namespace llvm 652