Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- Binary.h - A generic binary file -------------------------*- 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 the Binary class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_OBJECT_BINARY_H
0014 #define LLVM_OBJECT_BINARY_H
0015 
0016 #include "llvm-c/Types.h"
0017 #include "llvm/Object/Error.h"
0018 #include "llvm/Support/CBindingWrapping.h"
0019 #include "llvm/Support/Error.h"
0020 #include "llvm/Support/MemoryBuffer.h"
0021 #include "llvm/TargetParser/Triple.h"
0022 #include <memory>
0023 #include <utility>
0024 
0025 namespace llvm {
0026 
0027 class LLVMContext;
0028 class StringRef;
0029 
0030 namespace object {
0031 
0032 class Binary {
0033 private:
0034   unsigned int TypeID;
0035 
0036 protected:
0037   MemoryBufferRef Data;
0038 
0039   Binary(unsigned int Type, MemoryBufferRef Source);
0040 
0041   enum {
0042     ID_Archive,
0043     ID_MachOUniversalBinary,
0044     ID_COFFImportFile,
0045     ID_IR,            // LLVM IR
0046     ID_TapiUniversal, // Text-based Dynamic Library Stub file.
0047     ID_TapiFile,      // Text-based Dynamic Library Stub file.
0048 
0049     ID_Minidump,
0050 
0051     ID_WinRes, // Windows resource (.res) file.
0052 
0053     ID_Offload, // Offloading binary file.
0054 
0055     // Object and children.
0056     ID_StartObjects,
0057     ID_COFF,
0058 
0059     ID_XCOFF32, // AIX XCOFF 32-bit
0060     ID_XCOFF64, // AIX XCOFF 64-bit
0061 
0062     ID_ELF32L, // ELF 32-bit, little endian
0063     ID_ELF32B, // ELF 32-bit, big endian
0064     ID_ELF64L, // ELF 64-bit, little endian
0065     ID_ELF64B, // ELF 64-bit, big endian
0066 
0067     ID_MachO32L, // MachO 32-bit, little endian
0068     ID_MachO32B, // MachO 32-bit, big endian
0069     ID_MachO64L, // MachO 64-bit, little endian
0070     ID_MachO64B, // MachO 64-bit, big endian
0071 
0072     ID_GOFF,
0073     ID_Wasm,
0074 
0075     ID_EndObjects
0076   };
0077 
0078   static inline unsigned int getELFType(bool isLE, bool is64Bits) {
0079     if (isLE)
0080       return is64Bits ? ID_ELF64L : ID_ELF32L;
0081     else
0082       return is64Bits ? ID_ELF64B : ID_ELF32B;
0083   }
0084 
0085   static unsigned int getMachOType(bool isLE, bool is64Bits) {
0086     if (isLE)
0087       return is64Bits ? ID_MachO64L : ID_MachO32L;
0088     else
0089       return is64Bits ? ID_MachO64B : ID_MachO32B;
0090   }
0091 
0092 public:
0093   Binary() = delete;
0094   Binary(const Binary &other) = delete;
0095   virtual ~Binary();
0096 
0097   virtual Error initContent() { return Error::success(); };
0098 
0099   StringRef getData() const;
0100   StringRef getFileName() const;
0101   MemoryBufferRef getMemoryBufferRef() const;
0102 
0103   // Cast methods.
0104   unsigned int getType() const { return TypeID; }
0105 
0106   // Convenience methods
0107   bool isObject() const {
0108     return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
0109   }
0110 
0111   bool isSymbolic() const {
0112     return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
0113   }
0114 
0115   bool isArchive() const { return TypeID == ID_Archive; }
0116 
0117   bool isMachOUniversalBinary() const {
0118     return TypeID == ID_MachOUniversalBinary;
0119   }
0120 
0121   bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
0122 
0123   bool isELF() const {
0124     return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
0125   }
0126 
0127   bool isMachO() const {
0128     return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
0129   }
0130 
0131   bool isCOFF() const {
0132     return TypeID == ID_COFF;
0133   }
0134 
0135   bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
0136 
0137   bool isWasm() const { return TypeID == ID_Wasm; }
0138 
0139   bool isOffloadFile() const { return TypeID == ID_Offload; }
0140 
0141   bool isCOFFImportFile() const {
0142     return TypeID == ID_COFFImportFile;
0143   }
0144 
0145   bool isIR() const {
0146     return TypeID == ID_IR;
0147   }
0148 
0149   bool isGOFF() const { return TypeID == ID_GOFF; }
0150 
0151   bool isMinidump() const { return TypeID == ID_Minidump; }
0152 
0153   bool isTapiFile() const { return TypeID == ID_TapiFile; }
0154 
0155   bool isLittleEndian() const {
0156     return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
0157              TypeID == ID_MachO32B || TypeID == ID_MachO64B ||
0158              TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64);
0159   }
0160 
0161   bool isWinRes() const { return TypeID == ID_WinRes; }
0162 
0163   Triple::ObjectFormatType getTripleObjectFormat() const {
0164     if (isCOFF())
0165       return Triple::COFF;
0166     if (isMachO())
0167       return Triple::MachO;
0168     if (isELF())
0169       return Triple::ELF;
0170     if (isGOFF())
0171       return Triple::GOFF;
0172     return Triple::UnknownObjectFormat;
0173   }
0174 
0175   static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
0176                            const uint64_t Size) {
0177     if (Addr + Size < Addr || Addr + Size < Size ||
0178         Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
0179         Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
0180       return errorCodeToError(object_error::unexpected_eof);
0181     }
0182     return Error::success();
0183   }
0184 };
0185 
0186 // Create wrappers for C Binding types (see CBindingWrapping.h).
0187 DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
0188 
0189 /// Create a Binary from Source, autodetecting the file type.
0190 ///
0191 /// @param Source The data to create the Binary from.
0192 Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
0193                                                LLVMContext *Context = nullptr,
0194                                                bool InitContent = true);
0195 
0196 template <typename T> class OwningBinary {
0197   std::unique_ptr<T> Bin;
0198   std::unique_ptr<MemoryBuffer> Buf;
0199 
0200 public:
0201   OwningBinary();
0202   OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
0203   OwningBinary(OwningBinary<T>&& Other);
0204   OwningBinary<T> &operator=(OwningBinary<T> &&Other);
0205 
0206   std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
0207 
0208   T* getBinary();
0209   const T* getBinary() const;
0210 };
0211 
0212 template <typename T>
0213 OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
0214                               std::unique_ptr<MemoryBuffer> Buf)
0215     : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
0216 
0217 template <typename T> OwningBinary<T>::OwningBinary() = default;
0218 
0219 template <typename T>
0220 OwningBinary<T>::OwningBinary(OwningBinary &&Other)
0221     : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
0222 
0223 template <typename T>
0224 OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
0225   Bin = std::move(Other.Bin);
0226   Buf = std::move(Other.Buf);
0227   return *this;
0228 }
0229 
0230 template <typename T>
0231 std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
0232 OwningBinary<T>::takeBinary() {
0233   return std::make_pair(std::move(Bin), std::move(Buf));
0234 }
0235 
0236 template <typename T> T* OwningBinary<T>::getBinary() {
0237   return Bin.get();
0238 }
0239 
0240 template <typename T> const T* OwningBinary<T>::getBinary() const {
0241   return Bin.get();
0242 }
0243 
0244 Expected<OwningBinary<Binary>> createBinary(StringRef Path,
0245                                             LLVMContext *Context = nullptr,
0246                                             bool InitContent = true);
0247 
0248 } // end namespace object
0249 
0250 } // end namespace llvm
0251 
0252 #endif // LLVM_OBJECT_BINARY_H