1 //===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file declares Mach-O fat/universal binaries.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
14 #define LLVM_OBJECT_MACHOUNIVERSAL_H
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/BinaryFormat/MachO.h"
19 #include "llvm/Object/Archive.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Object/MachO.h"
28 class MachOUniversalBinary
: public Binary
{
29 virtual void anchor();
32 uint32_t NumberOfObjects
;
35 const MachOUniversalBinary
*Parent
;
36 /// Index of object in the universal binary.
38 /// Descriptor of the object.
39 MachO::fat_arch Header
;
40 MachO::fat_arch_64 Header64
;
43 ObjectForArch(const MachOUniversalBinary
*Parent
, uint32_t Index
);
50 bool operator==(const ObjectForArch
&Other
) const {
51 return (Parent
== Other
.Parent
) && (Index
== Other
.Index
);
54 ObjectForArch
getNext() const { return ObjectForArch(Parent
, Index
+ 1); }
55 uint32_t getCPUType() const {
56 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
57 return Header
.cputype
;
58 else // Parent->getMagic() == MachO::FAT_MAGIC_64
59 return Header64
.cputype
;
61 uint32_t getCPUSubType() const {
62 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
63 return Header
.cpusubtype
;
64 else // Parent->getMagic() == MachO::FAT_MAGIC_64
65 return Header64
.cpusubtype
;
67 uint32_t getOffset() const {
68 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
70 else // Parent->getMagic() == MachO::FAT_MAGIC_64
71 return Header64
.offset
;
73 uint32_t getSize() const {
74 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
76 else // Parent->getMagic() == MachO::FAT_MAGIC_64
79 uint32_t getAlign() const {
80 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
82 else // Parent->getMagic() == MachO::FAT_MAGIC_64
83 return Header64
.align
;
85 uint32_t getReserved() const {
86 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
88 else // Parent->getMagic() == MachO::FAT_MAGIC_64
89 return Header64
.reserved
;
91 std::string
getArchFlagName() const {
92 const char *McpuDefault
, *ArchFlag
;
93 if (Parent
->getMagic() == MachO::FAT_MAGIC
) {
95 MachOObjectFile::getArchTriple(Header
.cputype
, Header
.cpusubtype
,
96 &McpuDefault
, &ArchFlag
);
97 } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
99 MachOObjectFile::getArchTriple(Header64
.cputype
,
101 &McpuDefault
, &ArchFlag
);
104 std::string
ArchFlagName(ArchFlag
);
107 std::string
ArchFlagName("");
112 Expected
<std::unique_ptr
<MachOObjectFile
>> getAsObjectFile() const;
114 Expected
<std::unique_ptr
<Archive
>> getAsArchive() const;
117 class object_iterator
{
120 object_iterator(const ObjectForArch
&Obj
) : Obj(Obj
) {}
121 const ObjectForArch
*operator->() const { return &Obj
; }
122 const ObjectForArch
&operator*() const { return Obj
; }
124 bool operator==(const object_iterator
&Other
) const {
125 return Obj
== Other
.Obj
;
127 bool operator!=(const object_iterator
&Other
) const {
128 return !(*this == Other
);
131 object_iterator
& operator++() { // Preincrement
137 MachOUniversalBinary(MemoryBufferRef Souce
, Error
&Err
);
138 static Expected
<std::unique_ptr
<MachOUniversalBinary
>>
139 create(MemoryBufferRef Source
);
141 object_iterator
begin_objects() const {
142 return ObjectForArch(this, 0);
144 object_iterator
end_objects() const {
145 return ObjectForArch(nullptr, 0);
148 iterator_range
<object_iterator
> objects() const {
149 return make_range(begin_objects(), end_objects());
152 uint32_t getMagic() const { return Magic
; }
153 uint32_t getNumberOfObjects() const { return NumberOfObjects
; }
156 static bool classof(Binary
const *V
) {
157 return V
->isMachOUniversalBinary();
160 Expected
<std::unique_ptr
<MachOObjectFile
>>
161 getObjectForArch(StringRef ArchName
) const;