File indexing completed on 2026-05-10 08:44:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
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,
0046 ID_TapiUniversal,
0047 ID_TapiFile,
0048
0049 ID_Minidump,
0050
0051 ID_WinRes,
0052
0053 ID_Offload,
0054
0055
0056 ID_StartObjects,
0057 ID_COFF,
0058
0059 ID_XCOFF32,
0060 ID_XCOFF64,
0061
0062 ID_ELF32L,
0063 ID_ELF32B,
0064 ID_ELF64L,
0065 ID_ELF64B,
0066
0067 ID_MachO32L,
0068 ID_MachO32B,
0069 ID_MachO64L,
0070 ID_MachO64B,
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
0104 unsigned int getType() const { return TypeID; }
0105
0106
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
0187 DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
0188
0189
0190
0191
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 }
0249
0250 }
0251
0252 #endif