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