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
;
34 static constexpr uint32_t MaxSectionAlignment
= 15; /* 2**15 or 0x8000 */
37 const MachOUniversalBinary
*Parent
;
38 /// Index of object in the universal binary.
40 /// Descriptor of the object.
41 MachO::fat_arch Header
;
42 MachO::fat_arch_64 Header64
;
45 ObjectForArch(const MachOUniversalBinary
*Parent
, uint32_t Index
);
52 bool operator==(const ObjectForArch
&Other
) const {
53 return (Parent
== Other
.Parent
) && (Index
== Other
.Index
);
56 ObjectForArch
getNext() const { return ObjectForArch(Parent
, Index
+ 1); }
57 uint32_t getCPUType() const {
58 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
59 return Header
.cputype
;
60 else // Parent->getMagic() == MachO::FAT_MAGIC_64
61 return Header64
.cputype
;
63 uint32_t getCPUSubType() const {
64 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
65 return Header
.cpusubtype
;
66 else // Parent->getMagic() == MachO::FAT_MAGIC_64
67 return Header64
.cpusubtype
;
69 uint32_t getOffset() const {
70 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
72 else // Parent->getMagic() == MachO::FAT_MAGIC_64
73 return Header64
.offset
;
75 uint32_t getSize() const {
76 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
78 else // Parent->getMagic() == MachO::FAT_MAGIC_64
81 uint32_t getAlign() const {
82 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
84 else // Parent->getMagic() == MachO::FAT_MAGIC_64
85 return Header64
.align
;
87 uint32_t getReserved() const {
88 if (Parent
->getMagic() == MachO::FAT_MAGIC
)
90 else // Parent->getMagic() == MachO::FAT_MAGIC_64
91 return Header64
.reserved
;
93 std::string
getArchFlagName() const {
94 const char *McpuDefault
, *ArchFlag
;
95 if (Parent
->getMagic() == MachO::FAT_MAGIC
) {
97 MachOObjectFile::getArchTriple(Header
.cputype
, Header
.cpusubtype
,
98 &McpuDefault
, &ArchFlag
);
99 } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
101 MachOObjectFile::getArchTriple(Header64
.cputype
,
103 &McpuDefault
, &ArchFlag
);
106 std::string
ArchFlagName(ArchFlag
);
109 std::string
ArchFlagName("");
114 Expected
<std::unique_ptr
<MachOObjectFile
>> getAsObjectFile() const;
116 Expected
<std::unique_ptr
<Archive
>> getAsArchive() const;
119 class object_iterator
{
122 object_iterator(const ObjectForArch
&Obj
) : Obj(Obj
) {}
123 const ObjectForArch
*operator->() const { return &Obj
; }
124 const ObjectForArch
&operator*() const { return Obj
; }
126 bool operator==(const object_iterator
&Other
) const {
127 return Obj
== Other
.Obj
;
129 bool operator!=(const object_iterator
&Other
) const {
130 return !(*this == Other
);
133 object_iterator
& operator++() { // Preincrement
139 MachOUniversalBinary(MemoryBufferRef Souce
, Error
&Err
);
140 static Expected
<std::unique_ptr
<MachOUniversalBinary
>>
141 create(MemoryBufferRef Source
);
143 object_iterator
begin_objects() const {
144 return ObjectForArch(this, 0);
146 object_iterator
end_objects() const {
147 return ObjectForArch(nullptr, 0);
150 iterator_range
<object_iterator
> objects() const {
151 return make_range(begin_objects(), end_objects());
154 uint32_t getMagic() const { return Magic
; }
155 uint32_t getNumberOfObjects() const { return NumberOfObjects
; }
158 static bool classof(Binary
const *V
) {
159 return V
->isMachOUniversalBinary();
162 Expected
<std::unique_ptr
<MachOObjectFile
>>
163 getObjectForArch(StringRef ArchName
) const;