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/StringRef.h"
18#include "llvm/ADT/Triple.h"
19#include "llvm/ADT/iterator_range.h"
20#include "llvm/Object/Archive.h"
21#include "llvm/Object/Binary.h"
22#include "llvm/Object/MachO.h"
23#include "llvm/Support/ErrorOr.h"
24#include "llvm/Support/MachO.h"
25
26namespace llvm {
27namespace object {
28
29class MachOUniversalBinary : public Binary {
30  virtual void anchor();
31
32  uint32_t NumberOfObjects;
33public:
34  class ObjectForArch {
35    const MachOUniversalBinary *Parent;
36    /// \brief Index of object in the universal binary.
37    uint32_t Index;
38    /// \brief Descriptor of the object.
39    MachO::fat_arch Header;
40
41  public:
42    ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
43
44    void clear() {
45      Parent = nullptr;
46      Index = 0;
47    }
48
49    bool operator==(const ObjectForArch &Other) const {
50      return (Parent == Other.Parent) && (Index == Other.Index);
51    }
52
53    ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
54    uint32_t getCPUType() const { return Header.cputype; }
55    uint32_t getCPUSubType() const { return Header.cpusubtype; }
56    uint32_t getOffset() const { return Header.offset; }
57    uint32_t getSize() const { return Header.size; }
58    uint32_t getAlign() const { return Header.align; }
59    std::string getArchTypeName() const {
60      Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
61      return T.getArchName();
62    }
63
64    ErrorOr<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
65
66    ErrorOr<std::unique_ptr<Archive>> getAsArchive() const;
67  };
68
69  class object_iterator {
70    ObjectForArch Obj;
71  public:
72    object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
73    const ObjectForArch *operator->() const { return &Obj; }
74    const ObjectForArch &operator*() const { return Obj; }
75
76    bool operator==(const object_iterator &Other) const {
77      return Obj == Other.Obj;
78    }
79    bool operator!=(const object_iterator &Other) const {
80      return !(*this == Other);
81    }
82
83    object_iterator& operator++() {  // Preincrement
84      Obj = Obj.getNext();
85      return *this;
86    }
87  };
88
89  MachOUniversalBinary(MemoryBufferRef Souce, std::error_code &EC);
90  static ErrorOr<std::unique_ptr<MachOUniversalBinary>>
91  create(MemoryBufferRef Source);
92
93  object_iterator begin_objects() const {
94    return ObjectForArch(this, 0);
95  }
96  object_iterator end_objects() const {
97    return ObjectForArch(nullptr, 0);
98  }
99
100  iterator_range<object_iterator> objects() const {
101    return make_range(begin_objects(), end_objects());
102  }
103
104  uint32_t getNumberOfObjects() const { return NumberOfObjects; }
105
106  // Cast methods.
107  static inline bool classof(Binary const *V) {
108    return V->isMachOUniversalBinary();
109  }
110
111  ErrorOr<std::unique_ptr<MachOObjectFile>>
112  getObjectForArch(StringRef ArchName) const;
113};
114
115}
116}
117
118#endif
119