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