xref: /aosp_15_r20/external/llvm/include/llvm/Object/Binary.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file declares the Binary class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_OBJECT_BINARY_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_OBJECT_BINARY_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Error.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorOr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker namespace llvm {
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker class LLVMContext;
25*9880d681SAndroid Build Coastguard Worker class StringRef;
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker namespace object {
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker class Binary {
30*9880d681SAndroid Build Coastguard Worker private:
31*9880d681SAndroid Build Coastguard Worker   Binary() = delete;
32*9880d681SAndroid Build Coastguard Worker   Binary(const Binary &other) = delete;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker   unsigned int TypeID;
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker protected:
37*9880d681SAndroid Build Coastguard Worker   MemoryBufferRef Data;
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker   Binary(unsigned int Type, MemoryBufferRef Source);
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker   enum {
42*9880d681SAndroid Build Coastguard Worker     ID_Archive,
43*9880d681SAndroid Build Coastguard Worker     ID_MachOUniversalBinary,
44*9880d681SAndroid Build Coastguard Worker     ID_COFFImportFile,
45*9880d681SAndroid Build Coastguard Worker     ID_IR,                 // LLVM IR
46*9880d681SAndroid Build Coastguard Worker     ID_ModuleSummaryIndex, // Module summary index
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker     // Object and children.
49*9880d681SAndroid Build Coastguard Worker     ID_StartObjects,
50*9880d681SAndroid Build Coastguard Worker     ID_COFF,
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker     ID_ELF32L, // ELF 32-bit, little endian
53*9880d681SAndroid Build Coastguard Worker     ID_ELF32B, // ELF 32-bit, big endian
54*9880d681SAndroid Build Coastguard Worker     ID_ELF64L, // ELF 64-bit, little endian
55*9880d681SAndroid Build Coastguard Worker     ID_ELF64B, // ELF 64-bit, big endian
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker     ID_MachO32L, // MachO 32-bit, little endian
58*9880d681SAndroid Build Coastguard Worker     ID_MachO32B, // MachO 32-bit, big endian
59*9880d681SAndroid Build Coastguard Worker     ID_MachO64L, // MachO 64-bit, little endian
60*9880d681SAndroid Build Coastguard Worker     ID_MachO64B, // MachO 64-bit, big endian
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker     ID_EndObjects
63*9880d681SAndroid Build Coastguard Worker   };
64*9880d681SAndroid Build Coastguard Worker 
getELFType(bool isLE,bool is64Bits)65*9880d681SAndroid Build Coastguard Worker   static inline unsigned int getELFType(bool isLE, bool is64Bits) {
66*9880d681SAndroid Build Coastguard Worker     if (isLE)
67*9880d681SAndroid Build Coastguard Worker       return is64Bits ? ID_ELF64L : ID_ELF32L;
68*9880d681SAndroid Build Coastguard Worker     else
69*9880d681SAndroid Build Coastguard Worker       return is64Bits ? ID_ELF64B : ID_ELF32B;
70*9880d681SAndroid Build Coastguard Worker   }
71*9880d681SAndroid Build Coastguard Worker 
getMachOType(bool isLE,bool is64Bits)72*9880d681SAndroid Build Coastguard Worker   static unsigned int getMachOType(bool isLE, bool is64Bits) {
73*9880d681SAndroid Build Coastguard Worker     if (isLE)
74*9880d681SAndroid Build Coastguard Worker       return is64Bits ? ID_MachO64L : ID_MachO32L;
75*9880d681SAndroid Build Coastguard Worker     else
76*9880d681SAndroid Build Coastguard Worker       return is64Bits ? ID_MachO64B : ID_MachO32B;
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker public:
80*9880d681SAndroid Build Coastguard Worker   virtual ~Binary();
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   StringRef getData() const;
83*9880d681SAndroid Build Coastguard Worker   StringRef getFileName() const;
84*9880d681SAndroid Build Coastguard Worker   MemoryBufferRef getMemoryBufferRef() const;
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   // Cast methods.
getType()87*9880d681SAndroid Build Coastguard Worker   unsigned int getType() const { return TypeID; }
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   // Convenience methods
isObject()90*9880d681SAndroid Build Coastguard Worker   bool isObject() const {
91*9880d681SAndroid Build Coastguard Worker     return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
92*9880d681SAndroid Build Coastguard Worker   }
93*9880d681SAndroid Build Coastguard Worker 
isSymbolic()94*9880d681SAndroid Build Coastguard Worker   bool isSymbolic() const {
95*9880d681SAndroid Build Coastguard Worker     return isIR() || isObject();
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker 
isArchive()98*9880d681SAndroid Build Coastguard Worker   bool isArchive() const {
99*9880d681SAndroid Build Coastguard Worker     return TypeID == ID_Archive;
100*9880d681SAndroid Build Coastguard Worker   }
101*9880d681SAndroid Build Coastguard Worker 
isMachOUniversalBinary()102*9880d681SAndroid Build Coastguard Worker   bool isMachOUniversalBinary() const {
103*9880d681SAndroid Build Coastguard Worker     return TypeID == ID_MachOUniversalBinary;
104*9880d681SAndroid Build Coastguard Worker   }
105*9880d681SAndroid Build Coastguard Worker 
isELF()106*9880d681SAndroid Build Coastguard Worker   bool isELF() const {
107*9880d681SAndroid Build Coastguard Worker     return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
108*9880d681SAndroid Build Coastguard Worker   }
109*9880d681SAndroid Build Coastguard Worker 
isMachO()110*9880d681SAndroid Build Coastguard Worker   bool isMachO() const {
111*9880d681SAndroid Build Coastguard Worker     return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
112*9880d681SAndroid Build Coastguard Worker   }
113*9880d681SAndroid Build Coastguard Worker 
isCOFF()114*9880d681SAndroid Build Coastguard Worker   bool isCOFF() const {
115*9880d681SAndroid Build Coastguard Worker     return TypeID == ID_COFF;
116*9880d681SAndroid Build Coastguard Worker   }
117*9880d681SAndroid Build Coastguard Worker 
isCOFFImportFile()118*9880d681SAndroid Build Coastguard Worker   bool isCOFFImportFile() const {
119*9880d681SAndroid Build Coastguard Worker     return TypeID == ID_COFFImportFile;
120*9880d681SAndroid Build Coastguard Worker   }
121*9880d681SAndroid Build Coastguard Worker 
isIR()122*9880d681SAndroid Build Coastguard Worker   bool isIR() const {
123*9880d681SAndroid Build Coastguard Worker     return TypeID == ID_IR;
124*9880d681SAndroid Build Coastguard Worker   }
125*9880d681SAndroid Build Coastguard Worker 
isModuleSummaryIndex()126*9880d681SAndroid Build Coastguard Worker   bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
127*9880d681SAndroid Build Coastguard Worker 
isLittleEndian()128*9880d681SAndroid Build Coastguard Worker   bool isLittleEndian() const {
129*9880d681SAndroid Build Coastguard Worker     return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
130*9880d681SAndroid Build Coastguard Worker              TypeID == ID_MachO32B || TypeID == ID_MachO64B);
131*9880d681SAndroid Build Coastguard Worker   }
132*9880d681SAndroid Build Coastguard Worker };
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker /// @brief Create a Binary from Source, autodetecting the file type.
135*9880d681SAndroid Build Coastguard Worker ///
136*9880d681SAndroid Build Coastguard Worker /// @param Source The data to create the Binary from.
137*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
138*9880d681SAndroid Build Coastguard Worker                                                LLVMContext *Context = nullptr);
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker template <typename T> class OwningBinary {
141*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<T> Bin;
142*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<MemoryBuffer> Buf;
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker public:
145*9880d681SAndroid Build Coastguard Worker   OwningBinary();
146*9880d681SAndroid Build Coastguard Worker   OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
147*9880d681SAndroid Build Coastguard Worker   OwningBinary(OwningBinary<T>&& Other);
148*9880d681SAndroid Build Coastguard Worker   OwningBinary<T> &operator=(OwningBinary<T> &&Other);
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker   T* getBinary();
153*9880d681SAndroid Build Coastguard Worker   const T* getBinary() const;
154*9880d681SAndroid Build Coastguard Worker };
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker template <typename T>
OwningBinary(std::unique_ptr<T> Bin,std::unique_ptr<MemoryBuffer> Buf)157*9880d681SAndroid Build Coastguard Worker OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
158*9880d681SAndroid Build Coastguard Worker                               std::unique_ptr<MemoryBuffer> Buf)
159*9880d681SAndroid Build Coastguard Worker     : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
160*9880d681SAndroid Build Coastguard Worker 
OwningBinary()161*9880d681SAndroid Build Coastguard Worker template <typename T> OwningBinary<T>::OwningBinary() {}
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker template <typename T>
OwningBinary(OwningBinary && Other)164*9880d681SAndroid Build Coastguard Worker OwningBinary<T>::OwningBinary(OwningBinary &&Other)
165*9880d681SAndroid Build Coastguard Worker     : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
166*9880d681SAndroid Build Coastguard Worker 
167*9880d681SAndroid Build Coastguard Worker template <typename T>
168*9880d681SAndroid Build Coastguard Worker OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
169*9880d681SAndroid Build Coastguard Worker   Bin = std::move(Other.Bin);
170*9880d681SAndroid Build Coastguard Worker   Buf = std::move(Other.Buf);
171*9880d681SAndroid Build Coastguard Worker   return *this;
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker template <typename T>
175*9880d681SAndroid Build Coastguard Worker std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
takeBinary()176*9880d681SAndroid Build Coastguard Worker OwningBinary<T>::takeBinary() {
177*9880d681SAndroid Build Coastguard Worker   return std::make_pair(std::move(Bin), std::move(Buf));
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker 
getBinary()180*9880d681SAndroid Build Coastguard Worker template <typename T> T* OwningBinary<T>::getBinary() {
181*9880d681SAndroid Build Coastguard Worker   return Bin.get();
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker 
getBinary()184*9880d681SAndroid Build Coastguard Worker template <typename T> const T* OwningBinary<T>::getBinary() const {
185*9880d681SAndroid Build Coastguard Worker   return Bin.get();
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker Expected<OwningBinary<Binary>> createBinary(StringRef Path);
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker #endif
193