Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:19

0001 //===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares Mach-O fat/universal binaries.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
0014 #define LLVM_OBJECT_MACHOUNIVERSAL_H
0015 
0016 #include "llvm/ADT/iterator_range.h"
0017 #include "llvm/BinaryFormat/MachO.h"
0018 #include "llvm/Object/Binary.h"
0019 #include "llvm/Object/MachO.h"
0020 #include "llvm/TargetParser/Triple.h"
0021 
0022 namespace llvm {
0023 class StringRef;
0024 class LLVMContext;
0025 
0026 namespace object {
0027 class Archive;
0028 class IRObjectFile;
0029 
0030 class MachOUniversalBinary : public Binary {
0031   virtual void anchor();
0032 
0033   uint32_t Magic;
0034   uint32_t NumberOfObjects;
0035 public:
0036   static constexpr uint32_t MaxSectionAlignment = 15; /* 2**15 or 0x8000 */
0037 
0038   class ObjectForArch {
0039     const MachOUniversalBinary *Parent;
0040     /// Index of object in the universal binary.
0041     uint32_t Index;
0042     /// Descriptor of the object.
0043     MachO::fat_arch Header;
0044     MachO::fat_arch_64 Header64;
0045 
0046   public:
0047     ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
0048 
0049     void clear() {
0050       Parent = nullptr;
0051       Index = 0;
0052     }
0053 
0054     bool operator==(const ObjectForArch &Other) const {
0055       return (Parent == Other.Parent) && (Index == Other.Index);
0056     }
0057 
0058     ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
0059     uint32_t getCPUType() const {
0060       if (Parent->getMagic() == MachO::FAT_MAGIC)
0061         return Header.cputype;
0062       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0063         return Header64.cputype;
0064     }
0065     uint32_t getCPUSubType() const {
0066       if (Parent->getMagic() == MachO::FAT_MAGIC)
0067         return Header.cpusubtype;
0068       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0069         return Header64.cpusubtype;
0070     }
0071     uint64_t getOffset() const {
0072       if (Parent->getMagic() == MachO::FAT_MAGIC)
0073         return Header.offset;
0074       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0075         return Header64.offset;
0076     }
0077     uint64_t getSize() const {
0078       if (Parent->getMagic() == MachO::FAT_MAGIC)
0079         return Header.size;
0080       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0081         return Header64.size;
0082     }
0083     uint32_t getAlign() const {
0084       if (Parent->getMagic() == MachO::FAT_MAGIC)
0085         return Header.align;
0086       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0087         return Header64.align;
0088     }
0089     uint32_t getReserved() const {
0090       if (Parent->getMagic() == MachO::FAT_MAGIC)
0091         return 0;
0092       else // Parent->getMagic() == MachO::FAT_MAGIC_64
0093         return Header64.reserved;
0094     }
0095     Triple getTriple() const {
0096       return MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType());
0097     }
0098     std::string getArchFlagName() const {
0099       const char *McpuDefault, *ArchFlag;
0100       MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType(),
0101                                      &McpuDefault, &ArchFlag);
0102       return ArchFlag ? ArchFlag : std::string();
0103     }
0104 
0105     Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
0106     Expected<std::unique_ptr<IRObjectFile>>
0107     getAsIRObject(LLVMContext &Ctx) const;
0108 
0109     Expected<std::unique_ptr<Archive>> getAsArchive() const;
0110   };
0111 
0112   class object_iterator {
0113     ObjectForArch Obj;
0114   public:
0115     object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
0116     const ObjectForArch *operator->() const { return &Obj; }
0117     const ObjectForArch &operator*() const { return Obj; }
0118 
0119     bool operator==(const object_iterator &Other) const {
0120       return Obj == Other.Obj;
0121     }
0122     bool operator!=(const object_iterator &Other) const {
0123       return !(*this == Other);
0124     }
0125 
0126     object_iterator& operator++() {  // Preincrement
0127       Obj = Obj.getNext();
0128       return *this;
0129     }
0130   };
0131 
0132   MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
0133   static Expected<std::unique_ptr<MachOUniversalBinary>>
0134   create(MemoryBufferRef Source);
0135 
0136   object_iterator begin_objects() const {
0137     return ObjectForArch(this, 0);
0138   }
0139   object_iterator end_objects() const {
0140     return ObjectForArch(nullptr, 0);
0141   }
0142 
0143   iterator_range<object_iterator> objects() const {
0144     return make_range(begin_objects(), end_objects());
0145   }
0146 
0147   uint32_t getMagic() const { return Magic; }
0148   uint32_t getNumberOfObjects() const { return NumberOfObjects; }
0149 
0150   // Cast methods.
0151   static bool classof(Binary const *V) {
0152     return V->isMachOUniversalBinary();
0153   }
0154 
0155   Expected<ObjectForArch>
0156   getObjectForArch(StringRef ArchName) const;
0157 
0158   Expected<std::unique_ptr<MachOObjectFile>>
0159   getMachOObjectForArch(StringRef ArchName) const;
0160 
0161   Expected<std::unique_ptr<IRObjectFile>>
0162   getIRObjectForArch(StringRef ArchName, LLVMContext &Ctx) const;
0163 
0164   Expected<std::unique_ptr<Archive>>
0165   getArchiveForArch(StringRef ArchName) const;
0166 };
0167 
0168 }
0169 }
0170 
0171 #endif