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