Line data Source code
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 :
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 : /// Index of object in the universal binary.
38 : uint32_t Index;
39 : /// 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 0 : void clear() {
47 168 : Parent = nullptr;
48 168 : Index = 0;
49 0 : }
50 :
51 0 : bool operator==(const ObjectForArch &Other) const {
52 40 : return (Parent == Other.Parent) && (Index == Other.Index);
53 : }
54 :
55 0 : ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
56 : uint32_t getCPUType() const {
57 447 : if (Parent->getMagic() == MachO::FAT_MAGIC)
58 438 : return Header.cputype;
59 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
60 9 : return Header64.cputype;
61 : }
62 : uint32_t getCPUSubType() const {
63 143 : if (Parent->getMagic() == MachO::FAT_MAGIC)
64 140 : return Header.cpusubtype;
65 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
66 3 : return Header64.cpusubtype;
67 : }
68 : uint32_t getOffset() const {
69 701 : if (Parent->getMagic() == MachO::FAT_MAGIC)
70 681 : return Header.offset;
71 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
72 20 : return Header64.offset;
73 : }
74 : uint32_t getSize() const {
75 723 : if (Parent->getMagic() == MachO::FAT_MAGIC)
76 707 : return Header.size;
77 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
78 16 : return Header64.size;
79 : }
80 : uint32_t getAlign() const {
81 264 : if (Parent->getMagic() == MachO::FAT_MAGIC)
82 252 : return Header.align;
83 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
84 12 : return Header64.align;
85 : }
86 0 : uint32_t getReserved() const {
87 2 : if (Parent->getMagic() == MachO::FAT_MAGIC)
88 0 : return 0;
89 : else // Parent->getMagic() == MachO::FAT_MAGIC_64
90 0 : return Header64.reserved;
91 : }
92 121 : std::string getArchFlagName() const {
93 : const char *McpuDefault, *ArchFlag;
94 121 : if (Parent->getMagic() == MachO::FAT_MAGIC) {
95 : Triple T =
96 114 : MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype,
97 114 : &McpuDefault, &ArchFlag);
98 : } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
99 : Triple T =
100 7 : MachOObjectFile::getArchTriple(Header64.cputype,
101 7 : Header64.cpusubtype,
102 7 : &McpuDefault, &ArchFlag);
103 : }
104 121 : if (ArchFlag) {
105 120 : std::string ArchFlagName(ArchFlag);
106 : return ArchFlagName;
107 : } else {
108 1 : 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 128 : 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 168 : return Obj == Other.Obj;
127 : }
128 : bool operator!=(const object_iterator &Other) const {
129 : return !(*this == Other);
130 : }
131 :
132 200 : object_iterator& operator++() { // Preincrement
133 200 : Obj = Obj.getNext();
134 200 : 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 92 : return ObjectForArch(this, 0);
144 : }
145 0 : object_iterator end_objects() const {
146 64 : return ObjectForArch(nullptr, 0);
147 : }
148 :
149 28 : iterator_range<object_iterator> objects() const {
150 28 : return make_range(begin_objects(), end_objects());
151 : }
152 :
153 0 : uint32_t getMagic() const { return Magic; }
154 0 : uint32_t getNumberOfObjects() const { return NumberOfObjects; }
155 :
156 : // Cast methods.
157 : static bool classof(Binary const *V) {
158 248 : return V->isMachOUniversalBinary();
159 : }
160 :
161 : Expected<std::unique_ptr<MachOObjectFile>>
162 : getObjectForArch(StringRef ArchName) const;
163 : };
164 :
165 : }
166 : }
167 :
168 : #endif
|