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