Coverage Report

Created: 2019-03-22 08:08

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