1 //===- MachOUniversal.h - Mach-O universal binaries -------------*- 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 declares Mach-O fat/universal binaries. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OBJECT_MACHOUNIVERSAL_H 15 #define LLVM_OBJECT_MACHOUNIVERSAL_H 16 17 #include "llvm/ADT/Triple.h" 18 #include "llvm/ADT/iterator_range.h" 19 #include "llvm/BinaryFormat/MachO.h" 20 #include "llvm/Object/Archive.h" 21 #include "llvm/Object/Binary.h" 22 #include "llvm/Object/MachO.h" 23 24 namespace llvm { 25 class StringRef; 26 27 namespace object { 28 29 class MachOUniversalBinary : public Binary { 30 virtual void anchor(); 31 32 uint32_t Magic; 33 uint32_t NumberOfObjects; 34 public: 35 class ObjectForArch { 36 const MachOUniversalBinary *Parent; 37 /// Index of object in the universal binary. 38 uint32_t Index; 39 /// Descriptor of the object. 40 MachO::fat_arch Header; 41 MachO::fat_arch_64 Header64; 42 43 public: 44 ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index); 45 clear()46 void clear() { 47 Parent = nullptr; 48 Index = 0; 49 } 50 51 bool operator==(const ObjectForArch &Other) const { 52 return (Parent == Other.Parent) && (Index == Other.Index); 53 } 54 getNext()55 ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); } getCPUType()56 uint32_t getCPUType() const { 57 if (Parent->getMagic() == MachO::FAT_MAGIC) 58 return Header.cputype; 59 else // Parent->getMagic() == MachO::FAT_MAGIC_64 60 return Header64.cputype; 61 } getCPUSubType()62 uint32_t getCPUSubType() const { 63 if (Parent->getMagic() == MachO::FAT_MAGIC) 64 return Header.cpusubtype; 65 else // Parent->getMagic() == MachO::FAT_MAGIC_64 66 return Header64.cpusubtype; 67 } getOffset()68 uint32_t getOffset() const { 69 if (Parent->getMagic() == MachO::FAT_MAGIC) 70 return Header.offset; 71 else // Parent->getMagic() == MachO::FAT_MAGIC_64 72 return Header64.offset; 73 } getSize()74 uint32_t getSize() const { 75 if (Parent->getMagic() == MachO::FAT_MAGIC) 76 return Header.size; 77 else // Parent->getMagic() == MachO::FAT_MAGIC_64 78 return Header64.size; 79 } getAlign()80 uint32_t getAlign() const { 81 if (Parent->getMagic() == MachO::FAT_MAGIC) 82 return Header.align; 83 else // Parent->getMagic() == MachO::FAT_MAGIC_64 84 return Header64.align; 85 } getReserved()86 uint32_t getReserved() const { 87 if (Parent->getMagic() == MachO::FAT_MAGIC) 88 return 0; 89 else // Parent->getMagic() == MachO::FAT_MAGIC_64 90 return Header64.reserved; 91 } getArchFlagName()92 std::string getArchFlagName() const { 93 const char *McpuDefault, *ArchFlag; 94 if (Parent->getMagic() == MachO::FAT_MAGIC) { 95 Triple T = 96 MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype, 97 &McpuDefault, &ArchFlag); 98 } else { // Parent->getMagic() == MachO::FAT_MAGIC_64 99 Triple T = 100 MachOObjectFile::getArchTriple(Header64.cputype, 101 Header64.cpusubtype, 102 &McpuDefault, &ArchFlag); 103 } 104 if (ArchFlag) { 105 std::string ArchFlagName(ArchFlag); 106 return ArchFlagName; 107 } else { 108 std::string ArchFlagName(""); 109 return ArchFlagName; 110 } 111 } 112 113 Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const; 114 115 Expected<std::unique_ptr<Archive>> getAsArchive() const; 116 }; 117 118 class object_iterator { 119 ObjectForArch Obj; 120 public: object_iterator(const ObjectForArch & Obj)121 object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} 122 const ObjectForArch *operator->() const { return &Obj; } 123 const ObjectForArch &operator*() const { return Obj; } 124 125 bool operator==(const object_iterator &Other) const { 126 return Obj == Other.Obj; 127 } 128 bool operator!=(const object_iterator &Other) const { 129 return !(*this == Other); 130 } 131 132 object_iterator& operator++() { // Preincrement 133 Obj = Obj.getNext(); 134 return *this; 135 } 136 }; 137 138 MachOUniversalBinary(MemoryBufferRef Souce, Error &Err); 139 static Expected<std::unique_ptr<MachOUniversalBinary>> 140 create(MemoryBufferRef Source); 141 begin_objects()142 object_iterator begin_objects() const { 143 return ObjectForArch(this, 0); 144 } end_objects()145 object_iterator end_objects() const { 146 return ObjectForArch(nullptr, 0); 147 } 148 objects()149 iterator_range<object_iterator> objects() const { 150 return make_range(begin_objects(), end_objects()); 151 } 152 getMagic()153 uint32_t getMagic() const { return Magic; } getNumberOfObjects()154 uint32_t getNumberOfObjects() const { return NumberOfObjects; } 155 156 // Cast methods. classof(Binary const * V)157 static bool classof(Binary const *V) { 158 return V->isMachOUniversalBinary(); 159 } 160 161 Expected<std::unique_ptr<MachOObjectFile>> 162 getObjectForArch(StringRef ArchName) const; 163 }; 164 165 } 166 } 167 168 #endif 169