Coverage Report

Created: 2017-04-30 07:14

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Object/COFFObjectFile.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- COFFObjectFile.cpp - COFF object file implementation ---------------===//
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 COFFObjectFile class.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/ADT/ArrayRef.h"
15
#include "llvm/ADT/StringRef.h"
16
#include "llvm/ADT/Triple.h"
17
#include "llvm/ADT/iterator_range.h"
18
#include "llvm/Object/Binary.h"
19
#include "llvm/Object/COFF.h"
20
#include "llvm/Object/Error.h"
21
#include "llvm/Object/ObjectFile.h"
22
#include "llvm/Support/COFF.h"
23
#include "llvm/Support/Endian.h"
24
#include "llvm/Support/Error.h"
25
#include "llvm/Support/ErrorHandling.h"
26
#include "llvm/Support/MathExtras.h"
27
#include "llvm/Support/MemoryBuffer.h"
28
#include <algorithm>
29
#include <cassert>
30
#include <cstddef>
31
#include <cstdint>
32
#include <cstring>
33
#include <limits>
34
#include <memory>
35
#include <system_error>
36
37
using namespace llvm;
38
using namespace object;
39
40
using support::ulittle16_t;
41
using support::ulittle32_t;
42
using support::ulittle64_t;
43
using support::little16_t;
44
45
// Returns false if size is greater than the buffer size. And sets ec.
46
1.50k
static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
47
1.50k
  if (
M.getBufferSize() < Size1.50k
)
{0
48
0
    EC = object_error::unexpected_eof;
49
0
    return false;
50
0
  }
51
1.50k
  return true;
52
1.50k
}
53
54
static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
55
5.79k
                                   const uint64_t Size) {
56
5.79k
  if (
Addr + Size < Addr || 5.79k
Addr + Size < Size5.79k
||
57
5.79k
      Addr + Size > uintptr_t(M.getBufferEnd()) ||
58
5.79k
      
Addr < uintptr_t(M.getBufferStart())5.79k
)
{0
59
0
    return object_error::unexpected_eof;
60
0
  }
61
5.79k
  return std::error_code();
62
5.79k
}
63
64
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
65
// Returns unexpected_eof if error.
66
template <typename T>
67
static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
68
                                 const void *Ptr,
69
3.66k
                                 const uint64_t Size = sizeof(T)) {
70
3.66k
  uintptr_t Addr = uintptr_t(Ptr);
71
3.66k
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
3.66k
  Obj = reinterpret_cast<const T *>(Addr);
74
3.66k
  return std::error_code();
75
3.66k
}
COFFObjectFile.cpp:std::__1::error_code getObject<char>(char const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
613
                                 const uint64_t Size = sizeof(T)) {
70
613
  uintptr_t Addr = uintptr_t(Ptr);
71
613
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
613
  Obj = reinterpret_cast<const T *>(Addr);
74
613
  return std::error_code();
75
613
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_section>(llvm::object::coff_section const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
753
                                 const uint64_t Size = sizeof(T)) {
70
753
  uintptr_t Addr = uintptr_t(Ptr);
71
753
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
753
  Obj = reinterpret_cast<const T *>(Addr);
74
753
  return std::error_code();
75
753
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_relocation>(llvm::object::coff_relocation const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
6
                                 const uint64_t Size = sizeof(T)) {
70
6
  uintptr_t Addr = uintptr_t(Ptr);
71
6
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
6
  Obj = reinterpret_cast<const T *>(Addr);
74
6
  return std::error_code();
75
6
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul> > >(llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul> > const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
612
                                 const uint64_t Size = sizeof(T)) {
70
612
  uintptr_t Addr = uintptr_t(Ptr);
71
612
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
612
  Obj = reinterpret_cast<const T *>(Addr);
74
612
  return std::error_code();
75
612
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> > >(llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> > const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
1
                                 const uint64_t Size = sizeof(T)) {
70
1
  uintptr_t Addr = uintptr_t(Ptr);
71
1
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
1
  Obj = reinterpret_cast<const T *>(Addr);
74
1
  return std::error_code();
75
1
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> >(llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
613
                                 const uint64_t Size = sizeof(T)) {
70
613
  uintptr_t Addr = uintptr_t(Ptr);
71
613
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
613
  Obj = reinterpret_cast<const T *>(Addr);
74
613
  return std::error_code();
75
613
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_import_directory_table_entry>(llvm::object::coff_import_directory_table_entry const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
4
                                 const uint64_t Size = sizeof(T)) {
70
4
  uintptr_t Addr = uintptr_t(Ptr);
71
4
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
4
  Obj = reinterpret_cast<const T *>(Addr);
74
4
  return std::error_code();
75
4
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_file_header>(llvm::object::coff_file_header const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
753
                                 const uint64_t Size = sizeof(T)) {
70
753
  uintptr_t Addr = uintptr_t(Ptr);
71
753
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
753
  Obj = reinterpret_cast<const T *>(Addr);
74
753
  return std::error_code();
75
753
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::coff_bigobj_file_header>(llvm::object::coff_bigobj_file_header const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
1
                                 const uint64_t Size = sizeof(T)) {
70
1
  uintptr_t Addr = uintptr_t(Ptr);
71
1
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
1
  Obj = reinterpret_cast<const T *>(Addr);
74
1
  return std::error_code();
75
1
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::pe32_header>(llvm::object::pe32_header const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
155
                                 const uint64_t Size = sizeof(T)) {
70
155
  uintptr_t Addr = uintptr_t(Ptr);
71
155
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
155
  Obj = reinterpret_cast<const T *>(Addr);
74
155
  return std::error_code();
75
155
}
COFFObjectFile.cpp:std::__1::error_code getObject<llvm::object::data_directory>(llvm::object::data_directory const*&, llvm::MemoryBufferRef, void const*, unsigned long long)
Line
Count
Source
69
155
                                 const uint64_t Size = sizeof(T)) {
70
155
  uintptr_t Addr = uintptr_t(Ptr);
71
155
  if (std::error_code EC = checkOffset(M, Addr, Size))
72
0
    return EC;
73
155
  Obj = reinterpret_cast<const T *>(Addr);
74
155
  return std::error_code();
75
155
}
76
77
// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
78
// prefixed slashes.
79
1
static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
80
1
  assert(Str.size() <= 6 && "String too long, possible overflow.");
81
1
  if (Str.size() > 6)
82
0
    return true;
83
1
84
1
  uint64_t Value = 0;
85
7
  while (
!Str.empty()7
)
{6
86
6
    unsigned CharVal;
87
6
    if (
Str[0] >= 'A' && 6
Str[0] <= 'Z'5
) // 0..25
88
3
      CharVal = Str[0] - 'A';
89
3
    else 
if (3
Str[0] >= 'a' && 3
Str[0] <= 'z'2
) // 26..51
90
2
      CharVal = Str[0] - 'a' + 26;
91
1
    else 
if (1
Str[0] >= '0' && 1
Str[0] <= '9'1
) // 52..61
92
1
      CharVal = Str[0] - '0' + 52;
93
0
    else 
if (0
Str[0] == '+'0
) // 62
94
0
      CharVal = 62;
95
0
    else 
if (0
Str[0] == '/'0
) // 63
96
0
      CharVal = 63;
97
0
    else
98
0
      return true;
99
6
100
6
    Value = (Value * 64) + CharVal;
101
6
    Str = Str.substr(1);
102
6
  }
103
1
104
1
  
if (1
Value > std::numeric_limits<uint32_t>::max()1
)
105
0
    return true;
106
1
107
1
  Result = static_cast<uint32_t>(Value);
108
1
  return false;
109
1
}
110
111
template <typename coff_symbol_type>
112
13.1k
const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
113
13.1k
  const coff_symbol_type *Addr =
114
13.1k
      reinterpret_cast<const coff_symbol_type *>(Ref.p);
115
13.1k
116
13.1k
  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
117
13.1k
#ifndef NDEBUG
118
  // Verify that the symbol points to a valid entry in the symbol table.
119
  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
120
121
  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
122
         "Symbol did not point to the beginning of a symbol");
123
#endif
124
13.1k
125
13.1k
  return Addr;
126
13.1k
}
llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> > const* llvm::object::COFFObjectFile::toSymb<llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> > >(llvm::object::DataRefImpl) const
Line
Count
Source
112
8
const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
113
8
  const coff_symbol_type *Addr =
114
8
      reinterpret_cast<const coff_symbol_type *>(Ref.p);
115
8
116
8
  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
117
8
#ifndef NDEBUG
118
  // Verify that the symbol points to a valid entry in the symbol table.
119
  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
120
121
  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
122
         "Symbol did not point to the beginning of a symbol");
123
#endif
124
8
125
8
  return Addr;
126
8
}
llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul> > const* llvm::object::COFFObjectFile::toSymb<llvm::object::coff_symbol<llvm::support::detail::packed_endian_specific_integral<unsigned short, (llvm::support::endianness)1, 1ul> > >(llvm::object::DataRefImpl) const
Line
Count
Source
112
13.1k
const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
113
13.1k
  const coff_symbol_type *Addr =
114
13.1k
      reinterpret_cast<const coff_symbol_type *>(Ref.p);
115
13.1k
116
13.1k
  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
117
13.1k
#ifndef NDEBUG
118
  // Verify that the symbol points to a valid entry in the symbol table.
119
  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
120
121
  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
122
         "Symbol did not point to the beginning of a symbol");
123
#endif
124
13.1k
125
13.1k
  return Addr;
126
13.1k
}
127
128
170k
const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
129
170k
  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
130
170k
131
170k
#ifndef NDEBUG
132
  // Verify that the section points to a valid entry in the section table.
133
  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
134
    report_fatal_error("Section was outside of section table.");
135
136
  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
137
  assert(Offset % sizeof(coff_section) == 0 &&
138
         "Section did not point to the beginning of a section");
139
#endif
140
170k
141
170k
  return Addr;
142
170k
}
143
144
2.43k
void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
145
2.43k
  auto End = reinterpret_cast<uintptr_t>(StringTable);
146
2.43k
  if (
SymbolTable162.43k
)
{2.43k
147
2.43k
    const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
148
2.43k
    Symb += 1 + Symb->NumberOfAuxSymbols;
149
2.43k
    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
150
4
  } else 
if (4
SymbolTable324
)
{4
151
4
    const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
152
4
    Symb += 1 + Symb->NumberOfAuxSymbols;
153
4
    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
154
0
  } else {
155
0
    llvm_unreachable("no symbol table pointer!");
156
0
  }
157
2.43k
}
158
159
1.77k
Expected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
160
1.77k
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
161
1.77k
  StringRef Result;
162
1.77k
  std::error_code EC = getSymbolName(Symb, Result);
163
1.77k
  if (EC)
164
0
    return errorCodeToError(EC);
165
1.77k
  return Result;
166
1.77k
}
167
168
869
uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
169
869
  return getCOFFSymbol(Ref).getValue();
170
869
}
171
172
0
uint32_t COFFObjectFile::getSymbolAlignment(DataRefImpl Ref) const {
173
0
  // MSVC/link.exe seems to align symbols to the next-power-of-2
174
0
  // up to 32 bytes.
175
0
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
176
0
  return std::min(uint64_t(32), PowerOf2Ceil(Symb.getValue()));
177
0
}
178
179
690
Expected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
180
690
  uint64_t Result = getSymbolValue(Ref);
181
690
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
182
690
  int32_t SectionNumber = Symb.getSectionNumber();
183
690
184
690
  if (
Symb.isAnyUndefined() || 690
Symb.isCommon()650
||
185
648
      COFF::isReservedSectionNumber(SectionNumber))
186
62
    return Result;
187
690
188
628
  const coff_section *Section = nullptr;
189
628
  if (std::error_code EC = getSection(SectionNumber, Section))
190
0
    return errorCodeToError(EC);
191
628
  Result += Section->VirtualAddress;
192
628
193
628
  // The section VirtualAddress does not include ImageBase, and we want to
194
628
  // return virtual addresses.
195
628
  Result += getImageBase();
196
628
197
628
  return Result;
198
628
}
199
200
65
Expected<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
201
65
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
202
65
  int32_t SectionNumber = Symb.getSectionNumber();
203
65
204
65
  if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
205
8
    return SymbolRef::ST_Function;
206
57
  
if (57
Symb.isAnyUndefined()57
)
207
0
    return SymbolRef::ST_Unknown;
208
57
  
if (57
Symb.isCommon()57
)
209
0
    return SymbolRef::ST_Data;
210
57
  
if (57
Symb.isFileRecord()57
)
211
0
    return SymbolRef::ST_File;
212
57
213
57
  // TODO: perhaps we need a new symbol type ST_Section.
214
57
  
if (57
SectionNumber == COFF::IMAGE_SYM_DEBUG || 57
Symb.isSectionDefinition()57
)
215
13
    return SymbolRef::ST_Debug;
216
57
217
44
  
if (44
!COFF::isReservedSectionNumber(SectionNumber)44
)
218
44
    return SymbolRef::ST_Data;
219
44
220
0
  return SymbolRef::ST_Other;
221
44
}
222
223
4.57k
uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
224
4.57k
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
225
4.57k
  uint32_t Result = SymbolRef::SF_None;
226
4.57k
227
4.57k
  if (
Symb.isExternal() || 4.57k
Symb.isWeakExternal()2.49k
)
228
2.11k
    Result |= SymbolRef::SF_Global;
229
4.57k
230
4.57k
  if (Symb.isWeakExternal())
231
38
    Result |= SymbolRef::SF_Weak;
232
4.57k
233
4.57k
  if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE)
234
94
    Result |= SymbolRef::SF_Absolute;
235
4.57k
236
4.57k
  if (Symb.isFileRecord())
237
8
    Result |= SymbolRef::SF_FormatSpecific;
238
4.57k
239
4.57k
  if (Symb.isSectionDefinition())
240
1.90k
    Result |= SymbolRef::SF_FormatSpecific;
241
4.57k
242
4.57k
  if (Symb.isCommon())
243
5
    Result |= SymbolRef::SF_Common;
244
4.57k
245
4.57k
  if (Symb.isAnyUndefined())
246
437
    Result |= SymbolRef::SF_Undefined;
247
4.57k
248
4.57k
  return Result;
249
4.57k
}
250
251
2
uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
252
2
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
253
2
  return Symb.getValue();
254
2
}
255
256
Expected<section_iterator>
257
1.84k
COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
258
1.84k
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
259
1.84k
  if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
260
266
    return section_end();
261
1.57k
  const coff_section *Sec = nullptr;
262
1.57k
  if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
263
0
    return errorCodeToError(EC);
264
1.57k
  DataRefImpl Ret;
265
1.57k
  Ret.p = reinterpret_cast<uintptr_t>(Sec);
266
1.57k
  return section_iterator(SectionRef(Ret, this));
267
1.57k
}
268
269
210
unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
270
210
  COFFSymbolRef Symb = getCOFFSymbol(Sym.getRawDataRefImpl());
271
210
  return Symb.getSectionNumber();
272
210
}
273
274
6.31k
void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
275
6.31k
  const coff_section *Sec = toSec(Ref);
276
6.31k
  Sec += 1;
277
6.31k
  Ref.p = reinterpret_cast<uintptr_t>(Sec);
278
6.31k
}
279
280
std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
281
2.61k
                                               StringRef &Result) const {
282
2.61k
  const coff_section *Sec = toSec(Ref);
283
2.61k
  return getSectionName(Sec, Result);
284
2.61k
}
285
286
501
uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
287
501
  const coff_section *Sec = toSec(Ref);
288
501
  uint64_t Result = Sec->VirtualAddress;
289
501
290
501
  // The section VirtualAddress does not include ImageBase, and we want to
291
501
  // return virtual addresses.
292
501
  Result += getImageBase();
293
501
  return Result;
294
501
}
295
296
150k
uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
297
150k
  return getSectionSize(toSec(Ref));
298
150k
}
299
300
std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
301
615
                                                   StringRef &Result) const {
302
615
  const coff_section *Sec = toSec(Ref);
303
615
  ArrayRef<uint8_t> Res;
304
615
  std::error_code EC = getSectionContents(Sec, Res);
305
615
  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
306
615
  return EC;
307
615
}
308
309
34
uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
310
34
  const coff_section *Sec = toSec(Ref);
311
34
  return Sec->getAlignment();
312
34
}
313
314
122
bool COFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
315
122
  return false;
316
122
}
317
318
231
bool COFFObjectFile::isSectionText(DataRefImpl Ref) const {
319
231
  const coff_section *Sec = toSec(Ref);
320
231
  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
321
231
}
322
323
12
bool COFFObjectFile::isSectionData(DataRefImpl Ref) const {
324
12
  const coff_section *Sec = toSec(Ref);
325
12
  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
326
12
}
327
328
366
bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
329
366
  const coff_section *Sec = toSec(Ref);
330
366
  const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
331
366
                            COFF::IMAGE_SCN_MEM_READ |
332
366
                            COFF::IMAGE_SCN_MEM_WRITE;
333
366
  return (Sec->Characteristics & BssFlags) == BssFlags;
334
366
}
335
336
275
unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
337
275
  uintptr_t Offset =
338
275
      uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
339
275
  assert((Offset % sizeof(coff_section)) == 0);
340
275
  return (Offset / sizeof(coff_section)) + 1;
341
275
}
342
343
372
bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
344
372
  const coff_section *Sec = toSec(Ref);
345
372
  // In COFF, a virtual section won't have any in-file 
346
372
  // content, so the file pointer to the content will be zero.
347
372
  return Sec->PointerToRawData == 0;
348
372
}
349
350
static uint32_t getNumberOfRelocations(const coff_section *Sec,
351
3.09k
                                       MemoryBufferRef M, const uint8_t *base) {
352
3.09k
  // The field for the number of relocations in COFF section table is only
353
3.09k
  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
354
3.09k
  // NumberOfRelocations field, and the actual relocation count is stored in the
355
3.09k
  // VirtualAddress field in the first relocation entry.
356
3.09k
  if (
Sec->hasExtendedRelocations()3.09k
)
{6
357
6
    const coff_relocation *FirstReloc;
358
6
    if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
359
6
        base + Sec->PointerToRelocations)))
360
0
      return 0;
361
6
    // -1 to exclude this first relocation entry.
362
6
    return FirstReloc->VirtualAddress - 1;
363
6
  }
364
3.08k
  return Sec->NumberOfRelocations;
365
3.09k
}
366
367
static const coff_relocation *
368
2.49k
getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
369
2.49k
  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
370
2.49k
  if (!NumRelocs)
371
1.38k
    return nullptr;
372
1.10k
  auto begin = reinterpret_cast<const coff_relocation *>(
373
1.10k
      Base + Sec->PointerToRelocations);
374
1.10k
  if (
Sec->hasExtendedRelocations()1.10k
)
{4
375
4
    // Skip the first relocation entry repurposed to store the number of
376
4
    // relocations.
377
4
    begin++;
378
4
  }
379
1.10k
  if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs))
380
0
    return nullptr;
381
1.10k
  return begin;
382
1.10k
}
383
384
990
relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
385
990
  const coff_section *Sec = toSec(Ref);
386
990
  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
387
990
  if (
begin && 990
Sec->VirtualAddress != 0506
)
388
1
    report_fatal_error("Sections with relocations should have an address of 0");
389
990
  DataRefImpl Ret;
390
990
  Ret.p = reinterpret_cast<uintptr_t>(begin);
391
990
  return relocation_iterator(RelocationRef(Ret, this));
392
990
}
393
394
989
relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
395
989
  const coff_section *Sec = toSec(Ref);
396
989
  const coff_relocation *I = getFirstReloc(Sec, Data, base());
397
989
  if (I)
398
505
    I += getNumberOfRelocations(Sec, Data, base());
399
989
  DataRefImpl Ret;
400
989
  Ret.p = reinterpret_cast<uintptr_t>(I);
401
989
  return relocation_iterator(RelocationRef(Ret, this));
402
989
}
403
404
// Initialize the pointer to the symbol table.
405
613
std::error_code COFFObjectFile::initSymbolTablePtr() {
406
613
  if (COFFHeader)
407
612
    
if (std::error_code 612
EC612
= getObject(
408
612
            SymbolTable16, Data, base() + getPointerToSymbolTable(),
409
612
            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
410
0
      return EC;
411
613
412
613
  
if (613
COFFBigObjHeader613
)
413
1
    
if (std::error_code 1
EC1
= getObject(
414
1
            SymbolTable32, Data, base() + getPointerToSymbolTable(),
415
1
            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
416
0
      return EC;
417
613
418
613
  // Find string table. The first four byte of the string table contains the
419
613
  // total size of the string table, including the size field itself. If the
420
613
  // string table is empty, the value of the first four byte would be 4.
421
613
  uint32_t StringTableOffset = getPointerToSymbolTable() +
422
613
                               getNumberOfSymbols() * getSymbolTableEntrySize();
423
613
  const uint8_t *StringTableAddr = base() + StringTableOffset;
424
613
  const ulittle32_t *StringTableSizePtr;
425
613
  if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
426
0
    return EC;
427
613
  StringTableSize = *StringTableSizePtr;
428
613
  if (std::error_code EC =
429
613
          getObject(StringTable, Data, StringTableAddr, StringTableSize))
430
0
    return EC;
431
613
432
613
  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
433
613
  // tools like cvtres write a size of 0 for an empty table instead of 4.
434
613
  
if (613
StringTableSize < 4613
)
435
2
      StringTableSize = 4;
436
613
437
613
  // Check that the string table is null terminated if has any in it.
438
613
  if (
StringTableSize > 4 && 613
StringTable[StringTableSize - 1] != 0308
)
439
0
    return  object_error::parse_failed;
440
613
  return std::error_code();
441
613
}
442
443
1.38k
uint64_t COFFObjectFile::getImageBase() const {
444
1.38k
  if (PE32Header)
445
51
    return PE32Header->ImageBase;
446
1.32k
  else 
if (1.32k
PE32PlusHeader1.32k
)
447
347
    return PE32PlusHeader->ImageBase;
448
1.38k
  // This actually comes up in practice.
449
982
  return 0;
450
1.38k
}
451
452
// Returns the file offset for the given VA.
453
2
std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
454
2
  uint64_t ImageBase = getImageBase();
455
2
  uint64_t Rva = Addr - ImageBase;
456
2
  assert(Rva <= UINT32_MAX);
457
2
  return getRvaPtr((uint32_t)Rva, Res);
458
2
}
459
460
// Returns the file offset for the given RVA.
461
2.61k
std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
462
5.41k
  for (const SectionRef &S : sections()) {
463
5.41k
    const coff_section *Section = getCOFFSection(S);
464
5.41k
    uint32_t SectionStart = Section->VirtualAddress;
465
5.41k
    uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
466
5.41k
    if (
SectionStart <= Addr && 5.41k
Addr < SectionEnd5.41k
)
{2.61k
467
2.61k
      uint32_t Offset = Addr - SectionStart;
468
2.61k
      Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
469
2.61k
      return std::error_code();
470
2.61k
    }
471
5.41k
  }
472
0
  return object_error::parse_failed;
473
2.61k
}
474
475
std::error_code
476
COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
477
4
                                     ArrayRef<uint8_t> &Contents) const {
478
8
  for (const SectionRef &S : sections()) {
479
8
    const coff_section *Section = getCOFFSection(S);
480
8
    uint32_t SectionStart = Section->VirtualAddress;
481
8
    // Check if this RVA is within the section bounds. Be careful about integer
482
8
    // overflow.
483
8
    uint32_t OffsetIntoSection = RVA - SectionStart;
484
8
    if (
SectionStart <= RVA && 8
OffsetIntoSection < Section->VirtualSize8
&&
485
4
        
Size <= Section->VirtualSize - OffsetIntoSection4
)
{4
486
4
      uintptr_t Begin =
487
4
          uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
488
4
      Contents =
489
4
          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
490
4
      return std::error_code();
491
4
    }
492
8
  }
493
0
  return object_error::parse_failed;
494
4
}
495
496
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
497
// table entry.
498
std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
499
70
                                            StringRef &Name) const {
500
70
  uintptr_t IntPtr = 0;
501
70
  if (std::error_code EC = getRvaPtr(Rva, IntPtr))
502
0
    return EC;
503
70
  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
504
70
  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
505
70
  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
506
70
  return std::error_code();
507
70
}
508
509
std::error_code
510
COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
511
                                const codeview::DebugInfo *&PDBInfo,
512
3
                                StringRef &PDBFileName) const {
513
3
  ArrayRef<uint8_t> InfoBytes;
514
3
  if (std::error_code EC = getRvaAndSizeAsBytes(
515
3
          DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
516
0
    return EC;
517
3
  
if (3
InfoBytes.size() < sizeof(*PDBInfo) + 13
)
518
0
    return object_error::parse_failed;
519
3
  PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
520
3
  InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
521
3
  PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
522
3
                          InfoBytes.size());
523
3
  // Truncate the name at the first null byte. Ignore any padding.
524
3
  PDBFileName = PDBFileName.split('\0').first;
525
3
  return std::error_code();
526
3
}
527
528
std::error_code
529
COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
530
0
                                StringRef &PDBFileName) const {
531
0
  for (const debug_directory &D : debug_directories())
532
0
    
if (0
D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW0
)
533
0
      return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
534
0
  // If we get here, there is no PDB info to return.
535
0
  PDBInfo = nullptr;
536
0
  PDBFileName = StringRef();
537
0
  return std::error_code();
538
0
}
539
540
// Find the import table.
541
753
std::error_code COFFObjectFile::initImportTablePtr() {
542
753
  // First, we get the RVA of the import table. If the file lacks a pointer to
543
753
  // the import table, do nothing.
544
753
  const data_directory *DataEntry;
545
753
  if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
546
598
    return std::error_code();
547
753
548
753
  // Do nothing if the pointer to import table is NULL.
549
155
  
if (155
DataEntry->RelativeVirtualAddress == 0155
)
550
128
    return std::error_code();
551
155
552
27
  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
553
27
554
27
  // Find the section that contains the RVA. This is needed because the RVA is
555
27
  // the import table's memory address which is different from its file offset.
556
27
  uintptr_t IntPtr = 0;
557
27
  if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
558
0
    return EC;
559
27
  
if (std::error_code 27
EC27
= checkOffset(Data, IntPtr, DataEntry->Size))
560
0
    return EC;
561
27
  ImportDirectory = reinterpret_cast<
562
27
      const coff_import_directory_table_entry *>(IntPtr);
563
27
  return std::error_code();
564
27
}
565
566
// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
567
753
std::error_code COFFObjectFile::initDelayImportTablePtr() {
568
753
  const data_directory *DataEntry;
569
753
  if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
570
598
    return std::error_code();
571
155
  
if (155
DataEntry->RelativeVirtualAddress == 0155
)
572
148
    return std::error_code();
573
155
574
7
  uint32_t RVA = DataEntry->RelativeVirtualAddress;
575
7
  NumberOfDelayImportDirectory = DataEntry->Size /
576
7
      sizeof(delay_import_directory_table_entry) - 1;
577
7
578
7
  uintptr_t IntPtr = 0;
579
7
  if (std::error_code EC = getRvaPtr(RVA, IntPtr))
580
0
    return EC;
581
7
  DelayImportDirectory = reinterpret_cast<
582
7
      const delay_import_directory_table_entry *>(IntPtr);
583
7
  return std::error_code();
584
7
}
585
586
// Find the export table.
587
753
std::error_code COFFObjectFile::initExportTablePtr() {
588
753
  // First, we get the RVA of the export table. If the file lacks a pointer to
589
753
  // the export table, do nothing.
590
753
  const data_directory *DataEntry;
591
753
  if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
592
598
    return std::error_code();
593
753
594
753
  // Do nothing if the pointer to export table is NULL.
595
155
  
if (155
DataEntry->RelativeVirtualAddress == 0155
)
596
135
    return std::error_code();
597
155
598
20
  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
599
20
  uintptr_t IntPtr = 0;
600
20
  if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
601
0
    return EC;
602
20
  ExportDirectory =
603
20
      reinterpret_cast<const export_directory_table_entry *>(IntPtr);
604
20
  return std::error_code();
605
20
}
606
607
753
std::error_code COFFObjectFile::initBaseRelocPtr() {
608
753
  const data_directory *DataEntry;
609
753
  if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
610
598
    return std::error_code();
611
155
  
if (155
DataEntry->RelativeVirtualAddress == 0155
)
612
116
    return std::error_code();
613
155
614
39
  uintptr_t IntPtr = 0;
615
39
  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
616
0
    return EC;
617
39
  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
618
39
      IntPtr);
619
39
  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
620
39
      IntPtr + DataEntry->Size);
621
39
  return std::error_code();
622
39
}
623
624
753
std::error_code COFFObjectFile::initDebugDirectoryPtr() {
625
753
  // Get the RVA of the debug directory. Do nothing if it does not exist.
626
753
  const data_directory *DataEntry;
627
753
  if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
628
598
    return std::error_code();
629
753
630
753
  // Do nothing if the RVA is NULL.
631
155
  
if (155
DataEntry->RelativeVirtualAddress == 0155
)
632
138
    return std::error_code();
633
155
634
155
  // Check that the size is a multiple of the entry size.
635
17
  
if (17
DataEntry->Size % sizeof(debug_directory) != 017
)
636
0
    return object_error::parse_failed;
637
17
638
17
  uintptr_t IntPtr = 0;
639
17
  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
640
0
    return EC;
641
17
  DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
642
17
  if (std::error_code EC = getRvaPtr(
643
17
          DataEntry->RelativeVirtualAddress + DataEntry->Size, IntPtr))
644
0
    return EC;
645
17
  DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(IntPtr);
646
17
  return std::error_code();
647
17
}
648
649
COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
650
    : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
651
      COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
652
      DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
653
      SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
654
      ImportDirectory(nullptr),
655
      DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
656
      ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
657
753
      DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
658
753
  // Check that we at least have enough room for a header.
659
753
  if (!checkSize(Data, EC, sizeof(coff_file_header)))
660
0
    return;
661
753
662
753
  // The current location in the file where we are looking at.
663
753
  uint64_t CurPtr = 0;
664
753
665
753
  // PE header is optional and is present only in executables. If it exists,
666
753
  // it is placed right after COFF header.
667
753
  bool HasPEHeader = false;
668
753
669
753
  // Check if this is a PE/COFF file.
670
753
  if (
checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))753
)
{753
671
753
    // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
672
753
    // PE signature to find 'normal' COFF header.
673
753
    const auto *DH = reinterpret_cast<const dos_header *>(base());
674
753
    if (
DH->Magic[0] == 'M' && 753
DH->Magic[1] == 'Z'155
)
{155
675
155
      CurPtr = DH->AddressOfNewExeHeader;
676
155
      // Check the PE magic bytes. ("PE\0\0")
677
155
      if (
memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0155
)
{0
678
0
        EC = object_error::parse_failed;
679
0
        return;
680
0
      }
681
155
      CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
682
155
      HasPEHeader = true;
683
155
    }
684
753
  }
685
753
686
753
  
if (753
(EC = getObject(COFFHeader, Data, base() + CurPtr))753
)
687
0
    return;
688
753
689
753
  // It might be a bigobj file, let's check.  Note that COFF bigobj and COFF
690
753
  // import libraries share a common prefix but bigobj is more restrictive.
691
753
  
if (753
!HasPEHeader && 753
COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN598
&&
692
2
      COFFHeader->NumberOfSections == uint16_t(0xffff) &&
693
1
      
checkSize(Data, EC, sizeof(coff_bigobj_file_header))1
)
{1
694
1
    if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
695
0
      return;
696
1
697
1
    // Verify that we are dealing with bigobj.
698
1
    
if (1
COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&1
699
1
        std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
700
1
                    sizeof(COFF::BigObjMagic)) == 0) {
701
1
      COFFHeader = nullptr;
702
1
      CurPtr += sizeof(coff_bigobj_file_header);
703
0
    } else {
704
0
      // It's not a bigobj.
705
0
      COFFBigObjHeader = nullptr;
706
0
    }
707
1
  }
708
753
  
if (753
COFFHeader753
)
{752
709
752
    // The prior checkSize call may have failed.  This isn't a hard error
710
752
    // because we were just trying to sniff out bigobj.
711
752
    EC = std::error_code();
712
752
    CurPtr += sizeof(coff_file_header);
713
752
714
752
    if (COFFHeader->isImportLibrary())
715
0
      return;
716
752
  }
717
753
718
753
  
if (753
HasPEHeader753
)
{155
719
155
    const pe32_header *Header;
720
155
    if ((EC = getObject(Header, Data, base() + CurPtr)))
721
0
      return;
722
155
723
155
    const uint8_t *DataDirAddr;
724
155
    uint64_t DataDirSize;
725
155
    if (
Header->Magic == COFF::PE32Header::PE32155
)
{44
726
44
      PE32Header = Header;
727
44
      DataDirAddr = base() + CurPtr + sizeof(pe32_header);
728
44
      DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
729
111
    } else 
if (111
Header->Magic == COFF::PE32Header::PE32_PLUS111
)
{111
730
111
      PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
731
111
      DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
732
111
      DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
733
0
    } else {
734
0
      // It's neither PE32 nor PE32+.
735
0
      EC = object_error::parse_failed;
736
0
      return;
737
0
    }
738
155
    
if (155
(EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))155
)
739
0
      return;
740
155
  }
741
753
742
753
  
if (753
COFFHeader753
)
743
752
    CurPtr += COFFHeader->SizeOfOptionalHeader;
744
753
745
753
  if ((EC = getObject(SectionTable, Data, base() + CurPtr,
746
753
                      (uint64_t)getNumberOfSections() * sizeof(coff_section))))
747
0
    return;
748
753
749
753
  // Initialize the pointer to the symbol table.
750
753
  
if (753
getPointerToSymbolTable() != 0753
)
{613
751
613
    if (
(EC = initSymbolTablePtr())613
)
{0
752
0
      SymbolTable16 = nullptr;
753
0
      SymbolTable32 = nullptr;
754
0
      StringTable = nullptr;
755
0
      StringTableSize = 0;
756
0
    }
757
140
  } else {
758
140
    // We had better not have any symbols if we don't have a symbol table.
759
140
    if (
getNumberOfSymbols() != 0140
)
{0
760
0
      EC = object_error::parse_failed;
761
0
      return;
762
0
    }
763
140
  }
764
753
765
753
  // Initialize the pointer to the beginning of the import table.
766
753
  
if (753
(EC = initImportTablePtr())753
)
767
0
    return;
768
753
  
if (753
(EC = initDelayImportTablePtr())753
)
769
0
    return;
770
753
771
753
  // Initialize the pointer to the export table.
772
753
  
if (753
(EC = initExportTablePtr())753
)
773
0
    return;
774
753
775
753
  // Initialize the pointer to the base relocation table.
776
753
  
if (753
(EC = initBaseRelocPtr())753
)
777
0
    return;
778
753
779
753
  // Initialize the pointer to the export table.
780
753
  
if (753
(EC = initDebugDirectoryPtr())753
)
781
0
    return;
782
753
783
753
  EC = std::error_code();
784
753
}
785
786
330
basic_symbol_iterator COFFObjectFile::symbol_begin() const {
787
330
  DataRefImpl Ret;
788
330
  Ret.p = getSymbolTable();
789
330
  return basic_symbol_iterator(SymbolRef(Ret, this));
790
330
}
791
792
2.36k
basic_symbol_iterator COFFObjectFile::symbol_end() const {
793
2.36k
  // The symbol table ends where the string table begins.
794
2.36k
  DataRefImpl Ret;
795
2.36k
  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
796
2.36k
  return basic_symbol_iterator(SymbolRef(Ret, this));
797
2.36k
}
798
799
28
import_directory_iterator COFFObjectFile::import_directory_begin() const {
800
28
  if (!ImportDirectory)
801
17
    return import_directory_end();
802
11
  
if (11
ImportDirectory->isNull()11
)
803
0
    return import_directory_end();
804
11
  return import_directory_iterator(
805
11
      ImportDirectoryEntryRef(ImportDirectory, 0, this));
806
11
}
807
808
45
import_directory_iterator COFFObjectFile::import_directory_end() const {
809
45
  return import_directory_iterator(
810
45
      ImportDirectoryEntryRef(nullptr, -1, this));
811
45
}
812
813
delay_import_directory_iterator
814
9
COFFObjectFile::delay_import_directory_begin() const {
815
9
  return delay_import_directory_iterator(
816
9
      DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
817
9
}
818
819
delay_import_directory_iterator
820
9
COFFObjectFile::delay_import_directory_end() const {
821
9
  return delay_import_directory_iterator(
822
9
      DelayImportDirectoryEntryRef(
823
9
          DelayImportDirectory, NumberOfDelayImportDirectory, this));
824
9
}
825
826
72
export_directory_iterator COFFObjectFile::export_directory_begin() const {
827
72
  return export_directory_iterator(
828
72
      ExportDirectoryEntryRef(ExportDirectory, 0, this));
829
72
}
830
831
72
export_directory_iterator COFFObjectFile::export_directory_end() const {
832
72
  if (!ExportDirectory)
833
52
    return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
834
20
  ExportDirectoryEntryRef Ref(ExportDirectory,
835
20
                              ExportDirectory->AddressTableEntries, this);
836
20
  return export_directory_iterator(Ref);
837
72
}
838
839
3.27k
section_iterator COFFObjectFile::section_begin() const {
840
3.27k
  DataRefImpl Ret;
841
3.27k
  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
842
3.27k
  return section_iterator(SectionRef(Ret, this));
843
3.27k
}
844
845
4.59k
section_iterator COFFObjectFile::section_end() const {
846
4.59k
  DataRefImpl Ret;
847
4.59k
  int NumSections =
848
4.59k
      COFFHeader && 
COFFHeader->isImportLibrary()4.59k
?
00
:
getNumberOfSections()4.59k
;
849
4.59k
  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
850
4.59k
  return section_iterator(SectionRef(Ret, this));
851
4.59k
}
852
853
8
base_reloc_iterator COFFObjectFile::base_reloc_begin() const {
854
8
  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
855
8
}
856
857
8
base_reloc_iterator COFFObjectFile::base_reloc_end() const {
858
8
  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
859
8
}
860
861
399
uint8_t COFFObjectFile::getBytesInAddress() const {
862
204
  return getArch() == Triple::x86_64 ? 
8204
:
4195
;
863
399
}
864
865
377
StringRef COFFObjectFile::getFileFormatName() const {
866
377
  switch(getMachine()) {
867
149
  case COFF::IMAGE_FILE_MACHINE_I386:
868
149
    return "COFF-i386";
869
195
  case COFF::IMAGE_FILE_MACHINE_AMD64:
870
195
    return "COFF-x86-64";
871
32
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
872
32
    return "COFF-ARM";
873
0
  case COFF::IMAGE_FILE_MACHINE_ARM64:
874
0
    return "COFF-ARM64";
875
1
  default:
876
1
    return "COFF-<unknown arch>";
877
377
  }
878
377
}
879
880
887
unsigned COFFObjectFile::getArch() const {
881
887
  switch (getMachine()) {
882
355
  case COFF::IMAGE_FILE_MACHINE_I386:
883
355
    return Triple::x86;
884
455
  case COFF::IMAGE_FILE_MACHINE_AMD64:
885
455
    return Triple::x86_64;
886
75
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
887
75
    return Triple::thumb;
888
0
  case COFF::IMAGE_FILE_MACHINE_ARM64:
889
0
    return Triple::aarch64;
890
2
  default:
891
2
    return Triple::UnknownArch;
892
887
  }
893
887
}
894
895
iterator_range<import_directory_iterator>
896
11
COFFObjectFile::import_directories() const {
897
11
  return make_range(import_directory_begin(), import_directory_end());
898
11
}
899
900
iterator_range<delay_import_directory_iterator>
901
9
COFFObjectFile::delay_import_directories() const {
902
9
  return make_range(delay_import_directory_begin(),
903
9
                    delay_import_directory_end());
904
9
}
905
906
iterator_range<export_directory_iterator>
907
55
COFFObjectFile::export_directories() const {
908
55
  return make_range(export_directory_begin(), export_directory_end());
909
55
}
910
911
8
iterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
912
8
  return make_range(base_reloc_begin(), base_reloc_end());
913
8
}
914
915
119
std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
916
119
  Res = PE32Header;
917
119
  return std::error_code();
918
119
}
919
920
std::error_code
921
100
COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const {
922
100
  Res = PE32PlusHeader;
923
100
  return std::error_code();
924
100
}
925
926
std::error_code
927
COFFObjectFile::getDataDirectory(uint32_t Index,
928
4.90k
                                 const data_directory *&Res) const {
929
4.90k
  // Error if if there's no data directory or the index is out of range.
930
4.90k
  if (
!DataDirectory4.90k
)
{2.99k
931
2.99k
    Res = nullptr;
932
2.99k
    return object_error::parse_failed;
933
2.99k
  }
934
1.91k
  assert(PE32Header || PE32PlusHeader);
935
401
  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
936
1.50k
                               : PE32PlusHeader->NumberOfRvaAndSize;
937
1.91k
  if (
Index >= NumEnt1.91k
)
{0
938
0
    Res = nullptr;
939
0
    return object_error::parse_failed;
940
0
  }
941
1.91k
  Res = &DataDirectory[Index];
942
1.91k
  return std::error_code();
943
1.91k
}
944
945
std::error_code COFFObjectFile::getSection(int32_t Index,
946
3.22k
                                           const coff_section *&Result) const {
947
3.22k
  Result = nullptr;
948
3.22k
  if (COFF::isReservedSectionNumber(Index))
949
53
    return std::error_code();
950
3.17k
  
if (3.17k
static_cast<uint32_t>(Index) <= getNumberOfSections()3.17k
)
{3.17k
951
3.17k
    // We already verified the section table data, so no need to check again.
952
3.17k
    Result = SectionTable + (Index - 1);
953
3.17k
    return std::error_code();
954
3.17k
  }
955
0
  return object_error::parse_failed;
956
3.17k
}
957
958
std::error_code COFFObjectFile::getString(uint32_t Offset,
959
1.37k
                                          StringRef &Result) const {
960
1.37k
  if (StringTableSize <= 4)
961
1.37k
    // Tried to get a string from an empty string table.
962
0
    return object_error::parse_failed;
963
1.37k
  
if (1.37k
Offset >= StringTableSize1.37k
)
964
0
    return object_error::unexpected_eof;
965
1.37k
  Result = StringRef(StringTable + Offset);
966
1.37k
  return std::error_code();
967
1.37k
}
968
969
std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
970
2.80k
                                              StringRef &Res) const {
971
2.80k
  return getSymbolName(Symbol.getGeneric(), Res);
972
2.80k
}
973
974
std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
975
2.87k
                                              StringRef &Res) const {
976
2.87k
  // Check for string table entry. First 4 bytes are 0.
977
2.87k
  if (
Symbol->Name.Offset.Zeroes == 02.87k
)
{999
978
999
    if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
979
0
      return EC;
980
999
    return std::error_code();
981
999
  }
982
2.87k
983
1.87k
  
if (1.87k
Symbol->Name.ShortName[COFF::NameSize - 1] == 01.87k
)
984
1.87k
    // Null terminated, let ::strlen figure out the length.
985
1.49k
    Res = StringRef(Symbol->Name.ShortName);
986
1.87k
  else
987
1.87k
    // Not null terminated, use all 8 bytes.
988
383
    Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
989
1.87k
  return std::error_code();
990
2.87k
}
991
992
ArrayRef<uint8_t>
993
288
COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const {
994
288
  const uint8_t *Aux = nullptr;
995
288
996
288
  size_t SymbolSize = getSymbolTableEntrySize();
997
288
  if (
Symbol.getNumberOfAuxSymbols() > 0288
)
{288
998
288
    // AUX data comes immediately after the symbol in COFF
999
288
    Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
1000
288
#ifndef NDEBUG
1001
    // Verify that the Aux symbol points to a valid entry in the symbol table.
1002
    uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
1003
    if (Offset < getPointerToSymbolTable() ||
1004
        Offset >=
1005
            getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
1006
      report_fatal_error("Aux Symbol data was outside of symbol table.");
1007
1008
    assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
1009
           "Aux Symbol data did not point to the beginning of a symbol");
1010
#endif
1011
288
  }
1012
288
  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
1013
288
}
1014
1015
std::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
1016
4.09k
                                               StringRef &Res) const {
1017
4.09k
  StringRef Name;
1018
4.09k
  if (Sec->Name[COFF::NameSize - 1] == 0)
1019
4.09k
    // Null terminated, let ::strlen figure out the length.
1020
2.95k
    Name = Sec->Name;
1021
4.09k
  else
1022
4.09k
    // Not null terminated, use all 8 bytes.
1023
1.13k
    Name = StringRef(Sec->Name, COFF::NameSize);
1024
4.09k
1025
4.09k
  // Check for string table entry. First byte is '/'.
1026
4.09k
  if (
Name.startswith("/")4.09k
)
{380
1027
380
    uint32_t Offset;
1028
380
    if (
Name.startswith("//")380
)
{1
1029
1
      if (decodeBase64StringEntry(Name.substr(2), Offset))
1030
0
        return object_error::parse_failed;
1031
379
    } else {
1032
379
      if (Name.substr(1).getAsInteger(10, Offset))
1033
0
        return object_error::parse_failed;
1034
379
    }
1035
380
    
if (std::error_code 380
EC380
= getString(Offset, Name))
1036
0
      return EC;
1037
380
  }
1038
4.09k
1039
4.09k
  Res = Name;
1040
4.09k
  return std::error_code();
1041
4.09k
}
1042
1043
151k
uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
1044
151k
  // SizeOfRawData and VirtualSize change what they represent depending on
1045
151k
  // whether or not we have an executable image.
1046
151k
  //
1047
151k
  // For object files, SizeOfRawData contains the size of section's data;
1048
151k
  // VirtualSize should be zero but isn't due to buggy COFF writers.
1049
151k
  //
1050
151k
  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
1051
151k
  // actual section size is in VirtualSize.  It is possible for VirtualSize to
1052
151k
  // be greater than SizeOfRawData; the contents past that point should be
1053
151k
  // considered to be zero.
1054
151k
  if (getDOSHeader())
1055
150k
    return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
1056
1.29k
  return Sec->SizeOfRawData;
1057
151k
}
1058
1059
std::error_code
1060
COFFObjectFile::getSectionContents(const coff_section *Sec,
1061
1.00k
                                   ArrayRef<uint8_t> &Res) const {
1062
1.00k
  // In COFF, a virtual section won't have any in-file
1063
1.00k
  // content, so the file pointer to the content will be zero.
1064
1.00k
  if (Sec->PointerToRawData == 0)
1065
1
    return object_error::parse_failed;
1066
1.00k
  // The only thing that we need to verify is that the contents is contained
1067
1.00k
  // within the file bounds. We don't need to make sure it doesn't cover other
1068
1.00k
  // data, as there's nothing that says that is not allowed.
1069
1.00k
  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
1070
1.00k
  uint32_t SectionSize = getSectionSize(Sec);
1071
1.00k
  if (checkOffset(Data, ConStart, SectionSize))
1072
0
    return object_error::parse_failed;
1073
1.00k
  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
1074
1.00k
  return std::error_code();
1075
1.00k
}
1076
1077
7.37k
const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
1078
7.37k
  return reinterpret_cast<const coff_relocation*>(Rel.p);
1079
7.37k
}
1080
1081
1.85k
void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
1082
1.85k
  Rel.p = reinterpret_cast<uintptr_t>(
1083
1.85k
            reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
1084
1.85k
}
1085
1086
5.69k
uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
1087
5.69k
  const coff_relocation *R = toRel(Rel);
1088
5.69k
  return R->VirtualAddress;
1089
5.69k
}
1090
1091
982
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
1092
982
  const coff_relocation *R = toRel(Rel);
1093
982
  DataRefImpl Ref;
1094
982
  if (R->SymbolTableIndex >= getNumberOfSymbols())
1095
2
    return symbol_end();
1096
980
  
if (980
SymbolTable16980
)
1097
980
    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
1098
0
  else 
if (0
SymbolTable320
)
1099
0
    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
1100
0
  else
1101
0
    llvm_unreachable("no symbol table pointer!");
1102
980
  return symbol_iterator(SymbolRef(Ref, this));
1103
982
}
1104
1105
398
uint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel) const {
1106
398
  const coff_relocation* R = toRel(Rel);
1107
398
  return R->Type;
1108
398
}
1109
1110
const coff_section *
1111
7.09k
COFFObjectFile::getCOFFSection(const SectionRef &Section) const {
1112
7.09k
  return toSec(Section.getRawDataRefImpl());
1113
7.09k
}
1114
1115
10.7k
COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const {
1116
10.7k
  if (SymbolTable16)
1117
10.7k
    return toSymb<coff_symbol16>(Ref);
1118
4
  
if (4
SymbolTable324
)
1119
4
    return toSymb<coff_symbol32>(Ref);
1120
0
  
llvm_unreachable0
("no symbol table pointer!");0
1121
0
}
1122
1123
681
COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const {
1124
681
  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1125
681
}
1126
1127
const coff_relocation *
1128
8
COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
1129
8
  return toRel(Reloc.getRawDataRefImpl());
1130
8
}
1131
1132
iterator_range<const coff_relocation *>
1133
514
COFFObjectFile::getRelocations(const coff_section *Sec) const {
1134
514
  const coff_relocation *I = getFirstReloc(Sec, Data, base());
1135
514
  const coff_relocation *E = I;
1136
514
  if (I)
1137
95
    E += getNumberOfRelocations(Sec, Data, base());
1138
514
  return make_range(I, E);
1139
514
}
1140
1141
#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)                           \
1142
288
  case COFF::reloc_type:                                                       \
1143
288
    Res = #reloc_type;                                                         \
1144
288
    break;
1145
1146
void COFFObjectFile::getRelocationTypeName(
1147
292
    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1148
292
  const coff_relocation *Reloc = toRel(Rel);
1149
292
  StringRef Res;
1150
292
  switch (getMachine()) {
1151
132
  case COFF::IMAGE_FILE_MACHINE_AMD64:
1152
132
    switch (Reloc->Type) {
1153
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_ABSOLUTE)1
;0
1154
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_AMD64_ADDR64)
;0
1155
6
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME6
(IMAGE_REL_AMD64_ADDR32)
;0
1156
45
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME45
(IMAGE_REL_AMD64_ADDR32NB)
;0
1157
27
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME27
(IMAGE_REL_AMD64_REL32)
;0
1158
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_REL32_1)
;0
1159
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_REL32_2)
;0
1160
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_REL32_3)
;0
1161
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_REL32_4)
;0
1162
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_REL32_5)
;0
1163
19
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME19
(IMAGE_REL_AMD64_SECTION)
;0
1164
22
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME22
(IMAGE_REL_AMD64_SECREL)
;0
1165
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_SECREL7)
;0
1166
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_TOKEN)
;0
1167
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_SREL32)
;0
1168
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_PAIR)
;0
1169
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_AMD64_SSPAN32)
;0
1170
0
    default:
1171
0
      Res = "Unknown";
1172
132
    }
1173
132
    break;
1174
22
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
1175
22
    switch (Reloc->Type) {
1176
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_ABSOLUTE)0
;0
1177
4
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME4
(IMAGE_REL_ARM_ADDR32)
;0
1178
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_ARM_ADDR32NB)
;0
1179
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_BRANCH24)
;0
1180
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_BRANCH11)
;0
1181
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_TOKEN)
;0
1182
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_BLX24)
;0
1183
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_BLX11)
;0
1184
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_ARM_SECTION)
;0
1185
10
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME10
(IMAGE_REL_ARM_SECREL)
;0
1186
0
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME0
(IMAGE_REL_ARM_MOV32A)
;0
1187
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_ARM_MOV32T)
;0
1188
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_ARM_BRANCH20T)
;0
1189
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_ARM_BRANCH24T)
;0
1190
1
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME1
(IMAGE_REL_ARM_BLX23T)
;0
1191
0
    default:
1192
0
      Res = "Unknown";
1193
22
    }
1194
22
    break;
1195
138
  case COFF::IMAGE_FILE_MACHINE_I386:
1196
138
    switch (Reloc->Type) {
1197
3
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME3
(IMAGE_REL_I386_ABSOLUTE)3
;0
1198
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_I386_DIR16)
;0
1199
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_I386_REL16)
;0
1200
35
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME35
(IMAGE_REL_I386_DIR32)
;0
1201
5
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME5
(IMAGE_REL_I386_DIR32NB)
;0
1202
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_I386_SEG12)
;0
1203
24
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME24
(IMAGE_REL_I386_SECTION)
;0
1204
32
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME32
(IMAGE_REL_I386_SECREL)
;0
1205
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_I386_TOKEN)
;0
1206
2
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME2
(IMAGE_REL_I386_SECREL7)
;0
1207
29
    
LLVM_COFF_SWITCH_RELOC_TYPE_NAME29
(IMAGE_REL_I386_REL32)
;0
1208
0
    default:
1209
0
      Res = "Unknown";
1210
138
    }
1211
138
    break;
1212
0
  default:
1213
0
    Res = "Unknown";
1214
292
  }
1215
292
  Result.append(Res.begin(), Res.end());
1216
292
}
1217
1218
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1219
1220
27.8k
bool COFFObjectFile::isRelocatableObject() const {
1221
27.8k
  return !DataDirectory;
1222
27.8k
}
1223
1224
bool ImportDirectoryEntryRef::
1225
43
operator==(const ImportDirectoryEntryRef &Other) const {
1226
26
  return ImportTable == Other.ImportTable && Index == Other.Index;
1227
43
}
1228
1229
15
void ImportDirectoryEntryRef::moveNext() {
1230
15
  ++Index;
1231
15
  if (
ImportTable[Index].isNull()15
)
{9
1232
9
    Index = -1;
1233
9
    ImportTable = nullptr;
1234
9
  }
1235
15
}
1236
1237
std::error_code ImportDirectoryEntryRef::getImportTableEntry(
1238
4
    const coff_import_directory_table_entry *&Result) const {
1239
4
  return getObject(Result, OwningObject->Data, ImportTable + Index);
1240
4
}
1241
1242
static imported_symbol_iterator
1243
makeImportedSymbolIterator(const COFFObjectFile *Object,
1244
38
                           uintptr_t Ptr, int Index) {
1245
38
  if (
Object->getBytesInAddress() == 438
)
{22
1246
22
    auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
1247
22
    return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1248
22
  }
1249
16
  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
1250
16
  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1251
38
}
1252
1253
static imported_symbol_iterator
1254
19
importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
1255
19
  uintptr_t IntPtr = 0;
1256
19
  Object->getRvaPtr(RVA, IntPtr);
1257
19
  return makeImportedSymbolIterator(Object, IntPtr, 0);
1258
19
}
1259
1260
static imported_symbol_iterator
1261
19
importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
1262
19
  uintptr_t IntPtr = 0;
1263
19
  Object->getRvaPtr(RVA, IntPtr);
1264
19
  // Forward the pointer to the last entry which is null.
1265
19
  int Index = 0;
1266
19
  if (
Object->getBytesInAddress() == 419
)
{11
1267
11
    auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
1268
98
    while (*Entry++)
1269
87
      ++Index;
1270
8
  } else {
1271
8
    auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
1272
33
    while (*Entry++)
1273
25
      ++Index;
1274
8
  }
1275
19
  return makeImportedSymbolIterator(Object, IntPtr, Index);
1276
19
}
1277
1278
imported_symbol_iterator
1279
4
ImportDirectoryEntryRef::imported_symbol_begin() const {
1280
4
  return importedSymbolBegin(ImportTable[Index].ImportAddressTableRVA,
1281
4
                             OwningObject);
1282
4
}
1283
1284
imported_symbol_iterator
1285
4
ImportDirectoryEntryRef::imported_symbol_end() const {
1286
4
  return importedSymbolEnd(ImportTable[Index].ImportAddressTableRVA,
1287
4
                           OwningObject);
1288
4
}
1289
1290
iterator_range<imported_symbol_iterator>
1291
4
ImportDirectoryEntryRef::imported_symbols() const {
1292
4
  return make_range(imported_symbol_begin(), imported_symbol_end());
1293
4
}
1294
1295
11
imported_symbol_iterator ImportDirectoryEntryRef::lookup_table_begin() const {
1296
11
  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
1297
11
                             OwningObject);
1298
11
}
1299
1300
11
imported_symbol_iterator ImportDirectoryEntryRef::lookup_table_end() const {
1301
11
  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
1302
11
                           OwningObject);
1303
11
}
1304
1305
iterator_range<imported_symbol_iterator>
1306
11
ImportDirectoryEntryRef::lookup_table_symbols() const {
1307
11
  return make_range(lookup_table_begin(), lookup_table_end());
1308
11
}
1309
1310
15
std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
1311
15
  uintptr_t IntPtr = 0;
1312
15
  if (std::error_code EC =
1313
15
          OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
1314
0
    return EC;
1315
15
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1316
15
  return std::error_code();
1317
15
}
1318
1319
std::error_code
1320
11
ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t  &Result) const {
1321
11
  Result = ImportTable[Index].ImportLookupTableRVA;
1322
11
  return std::error_code();
1323
11
}
1324
1325
std::error_code
1326
11
ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
1327
11
  Result = ImportTable[Index].ImportAddressTableRVA;
1328
11
  return std::error_code();
1329
11
}
1330
1331
bool DelayImportDirectoryEntryRef::
1332
13
operator==(const DelayImportDirectoryEntryRef &Other) const {
1333
13
  return Table == Other.Table && Index == Other.Index;
1334
13
}
1335
1336
4
void DelayImportDirectoryEntryRef::moveNext() {
1337
4
  ++Index;
1338
4
}
1339
1340
imported_symbol_iterator
1341
4
DelayImportDirectoryEntryRef::imported_symbol_begin() const {
1342
4
  return importedSymbolBegin(Table[Index].DelayImportNameTable,
1343
4
                             OwningObject);
1344
4
}
1345
1346
imported_symbol_iterator
1347
4
DelayImportDirectoryEntryRef::imported_symbol_end() const {
1348
4
  return importedSymbolEnd(Table[Index].DelayImportNameTable,
1349
4
                           OwningObject);
1350
4
}
1351
1352
iterator_range<imported_symbol_iterator>
1353
4
DelayImportDirectoryEntryRef::imported_symbols() const {
1354
4
  return make_range(imported_symbol_begin(), imported_symbol_end());
1355
4
}
1356
1357
4
std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
1358
4
  uintptr_t IntPtr = 0;
1359
4
  if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
1360
0
    return EC;
1361
4
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1362
4
  return std::error_code();
1363
4
}
1364
1365
std::error_code DelayImportDirectoryEntryRef::
1366
4
getDelayImportTable(const delay_import_directory_table_entry *&Result) const {
1367
4
  Result = Table;
1368
4
  return std::error_code();
1369
4
}
1370
1371
std::error_code DelayImportDirectoryEntryRef::
1372
9
getImportAddress(int AddrIndex, uint64_t &Result) const {
1373
9
  uint32_t RVA = Table[Index].DelayImportAddressTable +
1374
5
      AddrIndex * (OwningObject->is64() ? 
85
:
44
);
1375
9
  uintptr_t IntPtr = 0;
1376
9
  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1377
0
    return EC;
1378
9
  
if (9
OwningObject->is64()9
)
1379
5
    Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1380
9
  else
1381
4
    Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1382
9
  return std::error_code();
1383
9
}
1384
1385
bool ExportDirectoryEntryRef::
1386
648
operator==(const ExportDirectoryEntryRef &Other) const {
1387
648
  return ExportTable == Other.ExportTable && Index == Other.Index;
1388
648
}
1389
1390
562
void ExportDirectoryEntryRef::moveNext() {
1391
562
  ++Index;
1392
562
}
1393
1394
// Returns the name of the current export symbol. If the symbol is exported only
1395
// by ordinal, the empty string is set as a result.
1396
14
std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
1397
14
  uintptr_t IntPtr = 0;
1398
14
  if (std::error_code EC =
1399
14
          OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
1400
0
    return EC;
1401
14
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1402
14
  return std::error_code();
1403
14
}
1404
1405
// Returns the starting ordinal number.
1406
std::error_code
1407
14
ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
1408
14
  Result = ExportTable->OrdinalBase;
1409
14
  return std::error_code();
1410
14
}
1411
1412
// Returns the export ordinal of the current export symbol.
1413
72
std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1414
72
  Result = ExportTable->OrdinalBase + Index;
1415
72
  return std::error_code();
1416
72
}
1417
1418
// Returns the address of the current export symbol.
1419
632
std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1420
632
  uintptr_t IntPtr = 0;
1421
632
  if (std::error_code EC =
1422
632
          OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
1423
0
    return EC;
1424
632
  const export_address_table_entry *entry =
1425
632
      reinterpret_cast<const export_address_table_entry *>(IntPtr);
1426
632
  Result = entry[Index].ExportRVA;
1427
632
  return std::error_code();
1428
632
}
1429
1430
// Returns the name of the current export symbol. If the symbol is exported only
1431
// by ordinal, the empty string is set as a result.
1432
std::error_code
1433
562
ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
1434
562
  uintptr_t IntPtr = 0;
1435
562
  if (std::error_code EC =
1436
562
          OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
1437
0
    return EC;
1438
562
  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
1439
562
1440
562
  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
1441
562
  int Offset = 0;
1442
562
  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
1443
59.9k
       
I < E59.9k
;
++I, ++Offset59.4k
)
{59.9k
1444
59.9k
    if (*I != Index)
1445
59.4k
      continue;
1446
528
    
if (std::error_code 528
EC528
=
1447
528
            OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
1448
0
      return EC;
1449
528
    const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1450
528
    if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
1451
0
      return EC;
1452
528
    Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1453
528
    return std::error_code();
1454
528
  }
1455
34
  Result = "";
1456
34
  return std::error_code();
1457
562
}
1458
1459
69
std::error_code ExportDirectoryEntryRef::isForwarder(bool &Result) const {
1460
69
  const data_directory *DataEntry;
1461
69
  if (auto EC = OwningObject->getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
1462
0
    return EC;
1463
69
  uint32_t RVA;
1464
69
  if (auto EC = getExportRVA(RVA))
1465
0
    return EC;
1466
69
  uint32_t Begin = DataEntry->RelativeVirtualAddress;
1467
69
  uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
1468
3
  Result = (Begin <= RVA && RVA < End);
1469
69
  return std::error_code();
1470
69
}
1471
1472
1
std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
1473
1
  uint32_t RVA;
1474
1
  if (auto EC = getExportRVA(RVA))
1475
0
    return EC;
1476
1
  uintptr_t IntPtr = 0;
1477
1
  if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
1478
0
    return EC;
1479
1
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1480
1
  return std::error_code();
1481
1
}
1482
1483
bool ImportedSymbolRef::
1484
131
operator==(const ImportedSymbolRef &Other) const {
1485
131
  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1486
131
      && Index == Other.Index;
1487
131
}
1488
1489
112
void ImportedSymbolRef::moveNext() {
1490
112
  ++Index;
1491
112
}
1492
1493
std::error_code
1494
42
ImportedSymbolRef::getSymbolName(StringRef &Result) const {
1495
42
  uint32_t RVA;
1496
42
  if (
Entry3242
)
{17
1497
17
    // If a symbol is imported only by ordinal, it has no name.
1498
17
    if (Entry32[Index].isOrdinal())
1499
1
      return std::error_code();
1500
16
    RVA = Entry32[Index].getHintNameRVA();
1501
25
  } else {
1502
25
    if (Entry64[Index].isOrdinal())
1503
5
      return std::error_code();
1504
20
    RVA = Entry64[Index].getHintNameRVA();
1505
20
  }
1506
36
  uintptr_t IntPtr = 0;
1507
36
  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1508
0
    return EC;
1509
36
  // +2 because the first two bytes is hint.
1510
36
  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1511
36
  return std::error_code();
1512
36
}
1513
1514
70
std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
1515
70
  if (Entry32)
1516
70
    Result = Entry32[Index].isOrdinal();
1517
70
  else
1518
0
    Result = Entry64[Index].isOrdinal();
1519
70
  return std::error_code();
1520
70
}
1521
1522
70
std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
1523
70
  if (Entry32)
1524
70
    Result = Entry32[Index].getHintNameRVA();
1525
70
  else
1526
0
    Result = Entry64[Index].getHintNameRVA();
1527
70
  return std::error_code();
1528
70
}
1529
1530
42
std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1531
42
  uint32_t RVA;
1532
42
  if (
Entry3242
)
{17
1533
17
    if (
Entry32[Index].isOrdinal()17
)
{1
1534
1
      Result = Entry32[Index].getOrdinal();
1535
1
      return std::error_code();
1536
1
    }
1537
16
    RVA = Entry32[Index].getHintNameRVA();
1538
25
  } else {
1539
25
    if (
Entry64[Index].isOrdinal()25
)
{5
1540
5
      Result = Entry64[Index].getOrdinal();
1541
5
      return std::error_code();
1542
5
    }
1543
20
    RVA = Entry64[Index].getHintNameRVA();
1544
20
  }
1545
36
  uintptr_t IntPtr = 0;
1546
36
  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1547
0
    return EC;
1548
36
  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1549
36
  return std::error_code();
1550
36
}
1551
1552
ErrorOr<std::unique_ptr<COFFObjectFile>>
1553
753
ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
1554
753
  std::error_code EC;
1555
753
  std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
1556
753
  if (EC)
1557
0
    return EC;
1558
753
  return std::move(Ret);
1559
753
}
1560
1561
96
bool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
1562
8
  return Header == Other.Header && Index == Other.Index;
1563
96
}
1564
1565
88
void BaseRelocRef::moveNext() {
1566
88
  // Header->BlockSize is the size of the current block, including the
1567
88
  // size of the header itself.
1568
88
  uint32_t Size = sizeof(*Header) +
1569
88
      sizeof(coff_base_reloc_block_entry) * (Index + 1);
1570
88
  if (
Size == Header->BlockSize88
)
{10
1571
10
    // .reloc contains a list of base relocation blocks. Each block
1572
10
    // consists of the header followed by entries. The header contains
1573
10
    // how many entories will follow. When we reach the end of the
1574
10
    // current block, proceed to the next block.
1575
10
    Header = reinterpret_cast<const coff_base_reloc_block_header *>(
1576
10
        reinterpret_cast<const uint8_t *>(Header) + Size);
1577
10
    Index = 0;
1578
78
  } else {
1579
78
    ++Index;
1580
78
  }
1581
88
}
1582
1583
88
std::error_code BaseRelocRef::getType(uint8_t &Type) const {
1584
88
  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1585
88
  Type = Entry[Index].getType();
1586
88
  return std::error_code();
1587
88
}
1588
1589
88
std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
1590
88
  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1591
88
  Result = Header->PageRVA + Entry[Index].getOffset();
1592
88
  return std::error_code();
1593
88
}