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