Remove dead code.
[oota-llvm.git] / lib / Object / MachOObjectFile.cpp
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