19c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov//===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===// 29c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// 39c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// The LLVM Compiler Infrastructure 49c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// 59c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// This file is distributed under the University of Illinois Open Source 69c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// License. See LICENSE.TXT for details. 79c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// 89c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov//===----------------------------------------------------------------------===// 99c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// 109c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// This file declares Mach-O fat/universal binaries. 119c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov// 129c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov//===----------------------------------------------------------------------===// 139c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 149c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H 159c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#define LLVM_OBJECT_MACHOUNIVERSAL_H 169c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 179c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#include "llvm/ADT/StringRef.h" 189c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#include "llvm/ADT/Triple.h" 199c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#include "llvm/Object/Binary.h" 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Object/Archive.h" 21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Object/MachO.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorOr.h" 235510728d28bb1ee04abc32da3d21b7df12948053Charles Davis#include "llvm/Support/MachO.h" 249c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 259c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonovnamespace llvm { 269c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonovnamespace object { 279c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 289c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonovclass ObjectFile; 299c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 309c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonovclass MachOUniversalBinary : public Binary { 319c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov virtual void anchor(); 329c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 339c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov uint32_t NumberOfObjects; 349c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonovpublic: 359c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov class ObjectForArch { 369c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov const MachOUniversalBinary *Parent; 379c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov /// \brief Index of object in the universal binary. 389c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov uint32_t Index; 399c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov /// \brief Descriptor of the object. 405510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::fat_arch Header; 419c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 429c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov public: 439c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index); 449c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 459c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov void clear() { 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Parent = nullptr; 479c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov Index = 0; 489c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 499c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 509c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov bool operator==(const ObjectForArch &Other) const { 519c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return (Parent == Other.Parent) && (Index == Other.Index); 529c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 539c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 549c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); } 555510728d28bb1ee04abc32da3d21b7df12948053Charles Davis uint32_t getCPUType() const { return Header.cputype; } 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string getArchTypeName() const { 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype); 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return T.getArchName(); 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 609c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<ObjectFile>> getAsObjectFile() const; 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code getAsArchive(std::unique_ptr<Archive> &Result) const; 649c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov }; 659c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 669c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov class object_iterator { 679c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov ObjectForArch Obj; 689c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov public: 699c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} 709c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov const ObjectForArch* operator->() const { 719c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return &Obj; 729c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 739c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 749c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov bool operator==(const object_iterator &Other) const { 759c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return Obj == Other.Obj; 769c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 779c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov bool operator!=(const object_iterator &Other) const { 789c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return !(*this == Other); 799c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 809c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 819c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov object_iterator& operator++() { // Preincrement 829c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov Obj = Obj.getNext(); 839c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return *this; 849c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 859c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov }; 869c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source, 88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code &ec); 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static ErrorOr<MachOUniversalBinary *> 90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines create(std::unique_ptr<MemoryBuffer> Source); 919c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 929c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov object_iterator begin_objects() const { 939c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return ObjectForArch(this, 0); 949c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 959c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov object_iterator end_objects() const { 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ObjectForArch(nullptr, 0); 979c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 989c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 999c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov uint32_t getNumberOfObjects() const { return NumberOfObjects; } 1009c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 1019c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov // Cast methods. 1029c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov static inline bool classof(Binary const *V) { 1039c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov return V->isMachOUniversalBinary(); 1049c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 1059c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<ObjectFile>> 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getObjectForArch(Triple::ArchType Arch) const; 1089c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov}; 1099c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 1109c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov} 1119c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov} 1129c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 1139c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#endif 114