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 24namespace llvm { 25class StringRef; 26 27namespace object { 28 29class MachOUniversalBinary : public Binary { 30 virtual void anchor(); 31 32 uint32_t Magic; 33 uint32_t NumberOfObjects; 34public: 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 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 55 ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); } 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 } 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 } 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 } 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 } 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 } 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 } 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: 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 142 object_iterator begin_objects() const { 143 return ObjectForArch(this, 0); 144 } 145 object_iterator end_objects() const { 146 return ObjectForArch(nullptr, 0); 147 } 148 149 iterator_range<object_iterator> objects() const { 150 return make_range(begin_objects(), end_objects()); 151 } 152 153 uint32_t getMagic() const { return Magic; } 154 uint32_t getNumberOfObjects() const { return NumberOfObjects; } 155 156 // Cast methods. 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