Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- MachOUniversalWriter.h - MachO universal binary writer----*- 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 // Declares the Slice class and writeUniversalBinary function for writing a
0010 // MachO universal binary file.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_OBJECT_MACHOUNIVERSALWRITER_H
0015 #define LLVM_OBJECT_MACHOUNIVERSALWRITER_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/Twine.h"
0020 #include "llvm/BinaryFormat/MachO.h"
0021 #include "llvm/Support/Error.h"
0022 #include <cstdint>
0023 #include <string>
0024 
0025 namespace llvm {
0026 class LLVMContext;
0027 
0028 namespace object {
0029 class Archive;
0030 class Binary;
0031 class IRObjectFile;
0032 class MachOObjectFile;
0033 
0034 class Slice {
0035   const Binary *B;
0036   uint32_t CPUType;
0037   uint32_t CPUSubType;
0038   std::string ArchName;
0039 
0040   // P2Alignment field stores slice alignment values from universal
0041   // binaries. This is also needed to order the slices so the total
0042   // file size can be calculated before creating the output buffer.
0043   uint32_t P2Alignment;
0044 
0045   Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
0046         std::string ArchName, uint32_t Align);
0047 
0048 public:
0049   explicit Slice(const MachOObjectFile &O);
0050 
0051   Slice(const MachOObjectFile &O, uint32_t Align);
0052 
0053   /// This constructor takes pre-specified \param CPUType , \param CPUSubType ,
0054   /// \param ArchName , \param Align instead of inferring them from the archive
0055   /// members.
0056   Slice(const Archive &A, uint32_t CPUType, uint32_t CPUSubType,
0057         std::string ArchName, uint32_t Align);
0058 
0059   static Expected<Slice> create(const Archive &A,
0060                                 LLVMContext *LLVMCtx = nullptr);
0061 
0062   static Expected<Slice> create(const IRObjectFile &IRO, uint32_t Align);
0063 
0064   void setP2Alignment(uint32_t Align) { P2Alignment = Align; }
0065 
0066   const Binary *getBinary() const { return B; }
0067 
0068   uint32_t getCPUType() const { return CPUType; }
0069 
0070   uint32_t getCPUSubType() const { return CPUSubType; }
0071 
0072   uint32_t getP2Alignment() const { return P2Alignment; }
0073 
0074   uint64_t getCPUID() const {
0075     return static_cast<uint64_t>(CPUType) << 32 | CPUSubType;
0076   }
0077 
0078   std::string getArchString() const {
0079     if (!ArchName.empty())
0080       return ArchName;
0081     return ("unknown(" + Twine(CPUType) + "," +
0082             Twine(CPUSubType & ~MachO::CPU_SUBTYPE_MASK) + ")")
0083         .str();
0084   }
0085 
0086   friend bool operator<(const Slice &Lhs, const Slice &Rhs) {
0087     if (Lhs.CPUType == Rhs.CPUType)
0088       return Lhs.CPUSubType < Rhs.CPUSubType;
0089     // force arm64-family to follow after all other slices for
0090     // compatibility with cctools lipo
0091     if (Lhs.CPUType == MachO::CPU_TYPE_ARM64)
0092       return false;
0093     if (Rhs.CPUType == MachO::CPU_TYPE_ARM64)
0094       return true;
0095     // Sort by alignment to minimize file size
0096     return Lhs.P2Alignment < Rhs.P2Alignment;
0097   }
0098 };
0099 
0100 enum class FatHeaderType { FatHeader, Fat64Header };
0101 
0102 Error writeUniversalBinary(ArrayRef<Slice> Slices, StringRef OutputFileName,
0103                            FatHeaderType FatHeader = FatHeaderType::FatHeader);
0104 
0105 Error writeUniversalBinaryToStream(
0106     ArrayRef<Slice> Slices, raw_ostream &Out,
0107     FatHeaderType FatHeader = FatHeaderType::FatHeader);
0108 
0109 } // end namespace object
0110 
0111 } // end namespace llvm
0112 
0113 #endif // LLVM_OBJECT_MACHOUNIVERSALWRITER_H