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