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/Object/Error.h"
18#include "llvm/Support/ErrorOr.h"
19#include "llvm/Support/FileSystem.h"
20#include "llvm/Support/MemoryBuffer.h"
21
22namespace llvm {
23
24class LLVMContext;
25class StringRef;
26
27namespace object {
28
29class Binary {
30private:
31  Binary() = delete;
32  Binary(const Binary &other) = delete;
33
34  unsigned int TypeID;
35
36protected:
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    ID_FunctionIndex, // Function summary index
47
48    // Object and children.
49    ID_StartObjects,
50    ID_COFF,
51
52    ID_ELF32L, // ELF 32-bit, little endian
53    ID_ELF32B, // ELF 32-bit, big endian
54    ID_ELF64L, // ELF 64-bit, little endian
55    ID_ELF64B, // ELF 64-bit, big endian
56
57    ID_MachO32L, // MachO 32-bit, little endian
58    ID_MachO32B, // MachO 32-bit, big endian
59    ID_MachO64L, // MachO 64-bit, little endian
60    ID_MachO64B, // MachO 64-bit, big endian
61
62    ID_EndObjects
63  };
64
65  static inline unsigned int getELFType(bool isLE, bool is64Bits) {
66    if (isLE)
67      return is64Bits ? ID_ELF64L : ID_ELF32L;
68    else
69      return is64Bits ? ID_ELF64B : ID_ELF32B;
70  }
71
72  static unsigned int getMachOType(bool isLE, bool is64Bits) {
73    if (isLE)
74      return is64Bits ? ID_MachO64L : ID_MachO32L;
75    else
76      return is64Bits ? ID_MachO64B : ID_MachO32B;
77  }
78
79public:
80  virtual ~Binary();
81
82  StringRef getData() const;
83  StringRef getFileName() const;
84  MemoryBufferRef getMemoryBufferRef() const;
85
86  // Cast methods.
87  unsigned int getType() const { return TypeID; }
88
89  // Convenience methods
90  bool isObject() const {
91    return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
92  }
93
94  bool isSymbolic() const {
95    return isIR() || isObject();
96  }
97
98  bool isArchive() const {
99    return TypeID == ID_Archive;
100  }
101
102  bool isMachOUniversalBinary() const {
103    return TypeID == ID_MachOUniversalBinary;
104  }
105
106  bool isELF() const {
107    return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
108  }
109
110  bool isMachO() const {
111    return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
112  }
113
114  bool isCOFF() const {
115    return TypeID == ID_COFF;
116  }
117
118  bool isCOFFImportFile() const {
119    return TypeID == ID_COFFImportFile;
120  }
121
122  bool isIR() const {
123    return TypeID == ID_IR;
124  }
125
126  bool isFunctionIndex() const { return TypeID == ID_FunctionIndex; }
127
128  bool isLittleEndian() const {
129    return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
130             TypeID == ID_MachO32B || TypeID == ID_MachO64B);
131  }
132};
133
134/// @brief Create a Binary from Source, autodetecting the file type.
135///
136/// @param Source The data to create the Binary from.
137ErrorOr<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
138                                              LLVMContext *Context = nullptr);
139
140template <typename T> class OwningBinary {
141  std::unique_ptr<T> Bin;
142  std::unique_ptr<MemoryBuffer> Buf;
143
144public:
145  OwningBinary();
146  OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
147  OwningBinary(OwningBinary<T>&& Other);
148  OwningBinary<T> &operator=(OwningBinary<T> &&Other);
149
150  std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
151
152  T* getBinary();
153  const T* getBinary() const;
154};
155
156template <typename T>
157OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
158                              std::unique_ptr<MemoryBuffer> Buf)
159    : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
160
161template <typename T> OwningBinary<T>::OwningBinary() {}
162
163template <typename T>
164OwningBinary<T>::OwningBinary(OwningBinary &&Other)
165    : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
166
167template <typename T>
168OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
169  Bin = std::move(Other.Bin);
170  Buf = std::move(Other.Buf);
171  return *this;
172}
173
174template <typename T>
175std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
176OwningBinary<T>::takeBinary() {
177  return std::make_pair(std::move(Bin), std::move(Buf));
178}
179
180template <typename T> T* OwningBinary<T>::getBinary() {
181  return Bin.get();
182}
183
184template <typename T> const T* OwningBinary<T>::getBinary() const {
185  return Bin.get();
186}
187
188ErrorOr<OwningBinary<Binary>> createBinary(StringRef Path);
189}
190}
191
192#endif
193