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/Object/Archive.h" 20 #include "llvm/Object/Binary.h" 21 #include "llvm/Object/MachO.h" 22 #include "llvm/Support/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 /// \brief Index of object in the universal binary. 38 uint32_t Index; 39 /// \brief 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 } getArchTypeName()92 std::string getArchTypeName() const { 93 if (Parent->getMagic() == MachO::FAT_MAGIC) { 94 Triple T = 95 MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype); 96 return T.getArchName(); 97 } else { // Parent->getMagic() == MachO::FAT_MAGIC_64 98 Triple T = 99 MachOObjectFile::getArchTriple(Header64.cputype, 100 Header64.cpusubtype); 101 return T.getArchName(); 102 } 103 } 104 105 Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const; 106 107 Expected<std::unique_ptr<Archive>> getAsArchive() const; 108 }; 109 110 class object_iterator { 111 ObjectForArch Obj; 112 public: object_iterator(const ObjectForArch & Obj)113 object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} 114 const ObjectForArch *operator->() const { return &Obj; } 115 const ObjectForArch &operator*() const { return Obj; } 116 117 bool operator==(const object_iterator &Other) const { 118 return Obj == Other.Obj; 119 } 120 bool operator!=(const object_iterator &Other) const { 121 return !(*this == Other); 122 } 123 124 object_iterator& operator++() { // Preincrement 125 Obj = Obj.getNext(); 126 return *this; 127 } 128 }; 129 130 MachOUniversalBinary(MemoryBufferRef Souce, Error &Err); 131 static Expected<std::unique_ptr<MachOUniversalBinary>> 132 create(MemoryBufferRef Source); 133 begin_objects()134 object_iterator begin_objects() const { 135 return ObjectForArch(this, 0); 136 } end_objects()137 object_iterator end_objects() const { 138 return ObjectForArch(nullptr, 0); 139 } 140 objects()141 iterator_range<object_iterator> objects() const { 142 return make_range(begin_objects(), end_objects()); 143 } 144 getMagic()145 uint32_t getMagic() const { return Magic; } getNumberOfObjects()146 uint32_t getNumberOfObjects() const { return NumberOfObjects; } 147 148 // Cast methods. classof(Binary const * V)149 static inline bool classof(Binary const *V) { 150 return V->isMachOUniversalBinary(); 151 } 152 153 Expected<std::unique_ptr<MachOObjectFile>> 154 getObjectForArch(StringRef ArchName) const; 155 }; 156 157 } 158 } 159 160 #endif 161