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