llvm-project

Форк
0
/
COFFObjectFile.cpp 
1990 строк · 70.1 Кб
1
//===- COFFObjectFile.cpp - COFF object file implementation ---------------===//
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 COFFObjectFile class.
10
//
11
//===----------------------------------------------------------------------===//
12

13
#include "llvm/ADT/ArrayRef.h"
14
#include "llvm/ADT/StringRef.h"
15
#include "llvm/ADT/StringSwitch.h"
16
#include "llvm/ADT/iterator_range.h"
17
#include "llvm/Object/Binary.h"
18
#include "llvm/Object/COFF.h"
19
#include "llvm/Object/Error.h"
20
#include "llvm/Object/ObjectFile.h"
21
#include "llvm/Object/WindowsMachineFlag.h"
22
#include "llvm/Support/BinaryStreamReader.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/MemoryBufferRef.h"
28
#include <algorithm>
29
#include <cassert>
30
#include <cinttypes>
31
#include <cstddef>
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
static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
47
  if (M.getBufferSize() < Size) {
48
    EC = object_error::unexpected_eof;
49
    return false;
50
  }
51
  return true;
52
}
53

54
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
55
// Returns unexpected_eof if error.
56
template <typename T>
57
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
58
                       const uint64_t Size = sizeof(T)) {
59
  uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
60
  if (Error E = Binary::checkOffset(M, Addr, Size))
61
    return E;
62
  Obj = reinterpret_cast<const T *>(Addr);
63
  return Error::success();
64
}
65

66
// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
67
// prefixed slashes.
68
static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
69
  assert(Str.size() <= 6 && "String too long, possible overflow.");
70
  if (Str.size() > 6)
71
    return true;
72

73
  uint64_t Value = 0;
74
  while (!Str.empty()) {
75
    unsigned CharVal;
76
    if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
77
      CharVal = Str[0] - 'A';
78
    else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
79
      CharVal = Str[0] - 'a' + 26;
80
    else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
81
      CharVal = Str[0] - '0' + 52;
82
    else if (Str[0] == '+') // 62
83
      CharVal = 62;
84
    else if (Str[0] == '/') // 63
85
      CharVal = 63;
86
    else
87
      return true;
88

89
    Value = (Value * 64) + CharVal;
90
    Str = Str.substr(1);
91
  }
92

93
  if (Value > std::numeric_limits<uint32_t>::max())
94
    return true;
95

96
  Result = static_cast<uint32_t>(Value);
97
  return false;
98
}
99

100
template <typename coff_symbol_type>
101
const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
102
  const coff_symbol_type *Addr =
103
      reinterpret_cast<const coff_symbol_type *>(Ref.p);
104

105
  assert(!checkOffset(Data, reinterpret_cast<uintptr_t>(Addr), sizeof(*Addr)));
106
#ifndef NDEBUG
107
  // Verify that the symbol points to a valid entry in the symbol table.
108
  uintptr_t Offset =
109
      reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());
110

111
  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
112
         "Symbol did not point to the beginning of a symbol");
113
#endif
114

115
  return Addr;
116
}
117

118
const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
119
  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
120

121
#ifndef NDEBUG
122
  // Verify that the section points to a valid entry in the section table.
123
  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
124
    report_fatal_error("Section was outside of section table.");
125

126
  uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -
127
                     reinterpret_cast<uintptr_t>(SectionTable);
128
  assert(Offset % sizeof(coff_section) == 0 &&
129
         "Section did not point to the beginning of a section");
130
#endif
131

132
  return Addr;
133
}
134

135
void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
136
  auto End = reinterpret_cast<uintptr_t>(StringTable);
137
  if (SymbolTable16) {
138
    const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
139
    Symb += 1 + Symb->NumberOfAuxSymbols;
140
    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
141
  } else if (SymbolTable32) {
142
    const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
143
    Symb += 1 + Symb->NumberOfAuxSymbols;
144
    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
145
  } else {
146
    llvm_unreachable("no symbol table pointer!");
147
  }
148
}
149

150
Expected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
151
  return getSymbolName(getCOFFSymbol(Ref));
152
}
153

154
uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
155
  return getCOFFSymbol(Ref).getValue();
156
}
157

158
uint32_t COFFObjectFile::getSymbolAlignment(DataRefImpl Ref) const {
159
  // MSVC/link.exe seems to align symbols to the next-power-of-2
160
  // up to 32 bytes.
161
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
162
  return std::min(uint64_t(32), PowerOf2Ceil(Symb.getValue()));
163
}
164

165
Expected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
166
  uint64_t Result = cantFail(getSymbolValue(Ref));
167
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
168
  int32_t SectionNumber = Symb.getSectionNumber();
169

170
  if (Symb.isAnyUndefined() || Symb.isCommon() ||
171
      COFF::isReservedSectionNumber(SectionNumber))
172
    return Result;
173

174
  Expected<const coff_section *> Section = getSection(SectionNumber);
175
  if (!Section)
176
    return Section.takeError();
177
  Result += (*Section)->VirtualAddress;
178

179
  // The section VirtualAddress does not include ImageBase, and we want to
180
  // return virtual addresses.
181
  Result += getImageBase();
182

183
  return Result;
184
}
185

186
Expected<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
187
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
188
  int32_t SectionNumber = Symb.getSectionNumber();
189

190
  if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
191
    return SymbolRef::ST_Function;
192
  if (Symb.isAnyUndefined())
193
    return SymbolRef::ST_Unknown;
194
  if (Symb.isCommon())
195
    return SymbolRef::ST_Data;
196
  if (Symb.isFileRecord())
197
    return SymbolRef::ST_File;
198

199
  // TODO: perhaps we need a new symbol type ST_Section.
200
  if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
201
    return SymbolRef::ST_Debug;
202

203
  if (!COFF::isReservedSectionNumber(SectionNumber))
204
    return SymbolRef::ST_Data;
205

206
  return SymbolRef::ST_Other;
207
}
208

209
Expected<uint32_t> COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
210
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
211
  uint32_t Result = SymbolRef::SF_None;
212

213
  if (Symb.isExternal() || Symb.isWeakExternal())
214
    Result |= SymbolRef::SF_Global;
215

216
  if (const coff_aux_weak_external *AWE = Symb.getWeakExternal()) {
217
    Result |= SymbolRef::SF_Weak;
218
    if (AWE->Characteristics != COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS)
219
      Result |= SymbolRef::SF_Undefined;
220
  }
221

222
  if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE)
223
    Result |= SymbolRef::SF_Absolute;
224

225
  if (Symb.isFileRecord())
226
    Result |= SymbolRef::SF_FormatSpecific;
227

228
  if (Symb.isSectionDefinition())
229
    Result |= SymbolRef::SF_FormatSpecific;
230

231
  if (Symb.isCommon())
232
    Result |= SymbolRef::SF_Common;
233

234
  if (Symb.isUndefined())
235
    Result |= SymbolRef::SF_Undefined;
236

237
  return Result;
238
}
239

240
uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
241
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
242
  return Symb.getValue();
243
}
244

245
Expected<section_iterator>
246
COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
247
  COFFSymbolRef Symb = getCOFFSymbol(Ref);
248
  if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
249
    return section_end();
250
  Expected<const coff_section *> Sec = getSection(Symb.getSectionNumber());
251
  if (!Sec)
252
    return Sec.takeError();
253
  DataRefImpl Ret;
254
  Ret.p = reinterpret_cast<uintptr_t>(*Sec);
255
  return section_iterator(SectionRef(Ret, this));
256
}
257

258
unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
259
  COFFSymbolRef Symb = getCOFFSymbol(Sym.getRawDataRefImpl());
260
  return Symb.getSectionNumber();
261
}
262

263
void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
264
  const coff_section *Sec = toSec(Ref);
265
  Sec += 1;
266
  Ref.p = reinterpret_cast<uintptr_t>(Sec);
267
}
268

269
Expected<StringRef> COFFObjectFile::getSectionName(DataRefImpl Ref) const {
270
  const coff_section *Sec = toSec(Ref);
271
  return getSectionName(Sec);
272
}
273

274
uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
275
  const coff_section *Sec = toSec(Ref);
276
  uint64_t Result = Sec->VirtualAddress;
277

278
  // The section VirtualAddress does not include ImageBase, and we want to
279
  // return virtual addresses.
280
  Result += getImageBase();
281
  return Result;
282
}
283

284
uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
285
  return toSec(Sec) - SectionTable;
286
}
287

288
uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
289
  return getSectionSize(toSec(Ref));
290
}
291

292
Expected<ArrayRef<uint8_t>>
293
COFFObjectFile::getSectionContents(DataRefImpl Ref) const {
294
  const coff_section *Sec = toSec(Ref);
295
  ArrayRef<uint8_t> Res;
296
  if (Error E = getSectionContents(Sec, Res))
297
    return E;
298
  return Res;
299
}
300

301
uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
302
  const coff_section *Sec = toSec(Ref);
303
  return Sec->getAlignment();
304
}
305

306
bool COFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
307
  return false;
308
}
309

310
bool COFFObjectFile::isSectionText(DataRefImpl Ref) const {
311
  const coff_section *Sec = toSec(Ref);
312
  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
313
}
314

315
bool COFFObjectFile::isSectionData(DataRefImpl Ref) const {
316
  const coff_section *Sec = toSec(Ref);
317
  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
318
}
319

320
bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
321
  const coff_section *Sec = toSec(Ref);
322
  const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
323
                            COFF::IMAGE_SCN_MEM_READ |
324
                            COFF::IMAGE_SCN_MEM_WRITE;
325
  return (Sec->Characteristics & BssFlags) == BssFlags;
326
}
327

328
// The .debug sections are the only debug sections for COFF
329
// (\see MCObjectFileInfo.cpp).
330
bool COFFObjectFile::isDebugSection(DataRefImpl Ref) const {
331
  Expected<StringRef> SectionNameOrErr = getSectionName(Ref);
332
  if (!SectionNameOrErr) {
333
    // TODO: Report the error message properly.
334
    consumeError(SectionNameOrErr.takeError());
335
    return false;
336
  }
337
  StringRef SectionName = SectionNameOrErr.get();
338
  return SectionName.starts_with(".debug");
339
}
340

341
unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
342
  uintptr_t Offset =
343
      Sec.getRawDataRefImpl().p - reinterpret_cast<uintptr_t>(SectionTable);
344
  assert((Offset % sizeof(coff_section)) == 0);
345
  return (Offset / sizeof(coff_section)) + 1;
346
}
347

348
bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
349
  const coff_section *Sec = toSec(Ref);
350
  // In COFF, a virtual section won't have any in-file
351
  // content, so the file pointer to the content will be zero.
352
  return Sec->PointerToRawData == 0;
353
}
354

355
static uint32_t getNumberOfRelocations(const coff_section *Sec,
356
                                       MemoryBufferRef M, const uint8_t *base) {
357
  // The field for the number of relocations in COFF section table is only
358
  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
359
  // NumberOfRelocations field, and the actual relocation count is stored in the
360
  // VirtualAddress field in the first relocation entry.
361
  if (Sec->hasExtendedRelocations()) {
362
    const coff_relocation *FirstReloc;
363
    if (Error E = getObject(FirstReloc, M,
364
                            reinterpret_cast<const coff_relocation *>(
365
                                base + Sec->PointerToRelocations))) {
366
      consumeError(std::move(E));
367
      return 0;
368
    }
369
    // -1 to exclude this first relocation entry.
370
    return FirstReloc->VirtualAddress - 1;
371
  }
372
  return Sec->NumberOfRelocations;
373
}
374

375
static const coff_relocation *
376
getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
377
  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
378
  if (!NumRelocs)
379
    return nullptr;
380
  auto begin = reinterpret_cast<const coff_relocation *>(
381
      Base + Sec->PointerToRelocations);
382
  if (Sec->hasExtendedRelocations()) {
383
    // Skip the first relocation entry repurposed to store the number of
384
    // relocations.
385
    begin++;
386
  }
387
  if (auto E = Binary::checkOffset(M, reinterpret_cast<uintptr_t>(begin),
388
                                   sizeof(coff_relocation) * NumRelocs)) {
389
    consumeError(std::move(E));
390
    return nullptr;
391
  }
392
  return begin;
393
}
394

395
relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
396
  const coff_section *Sec = toSec(Ref);
397
  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
398
  if (begin && Sec->VirtualAddress != 0)
399
    report_fatal_error("Sections with relocations should have an address of 0");
400
  DataRefImpl Ret;
401
  Ret.p = reinterpret_cast<uintptr_t>(begin);
402
  return relocation_iterator(RelocationRef(Ret, this));
403
}
404

405
relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
406
  const coff_section *Sec = toSec(Ref);
407
  const coff_relocation *I = getFirstReloc(Sec, Data, base());
408
  if (I)
409
    I += getNumberOfRelocations(Sec, Data, base());
410
  DataRefImpl Ret;
411
  Ret.p = reinterpret_cast<uintptr_t>(I);
412
  return relocation_iterator(RelocationRef(Ret, this));
413
}
414

415
// Initialize the pointer to the symbol table.
416
Error COFFObjectFile::initSymbolTablePtr() {
417
  if (COFFHeader)
418
    if (Error E = getObject(
419
            SymbolTable16, Data, base() + getPointerToSymbolTable(),
420
            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
421
      return E;
422

423
  if (COFFBigObjHeader)
424
    if (Error E = getObject(
425
            SymbolTable32, Data, base() + getPointerToSymbolTable(),
426
            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
427
      return E;
428

429
  // Find string table. The first four byte of the string table contains the
430
  // total size of the string table, including the size field itself. If the
431
  // string table is empty, the value of the first four byte would be 4.
432
  uint32_t StringTableOffset = getPointerToSymbolTable() +
433
                               getNumberOfSymbols() * getSymbolTableEntrySize();
434
  const uint8_t *StringTableAddr = base() + StringTableOffset;
435
  const ulittle32_t *StringTableSizePtr;
436
  if (Error E = getObject(StringTableSizePtr, Data, StringTableAddr))
437
    return E;
438
  StringTableSize = *StringTableSizePtr;
439
  if (Error E = getObject(StringTable, Data, StringTableAddr, StringTableSize))
440
    return E;
441

442
  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
443
  // tools like cvtres write a size of 0 for an empty table instead of 4.
444
  if (StringTableSize < 4)
445
    StringTableSize = 4;
446

447
  // Check that the string table is null terminated if has any in it.
448
  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
449
    return createStringError(object_error::parse_failed,
450
                             "string table missing null terminator");
451
  return Error::success();
452
}
453

454
uint64_t COFFObjectFile::getImageBase() const {
455
  if (PE32Header)
456
    return PE32Header->ImageBase;
457
  else if (PE32PlusHeader)
458
    return PE32PlusHeader->ImageBase;
459
  // This actually comes up in practice.
460
  return 0;
461
}
462

463
// Returns the file offset for the given VA.
464
Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
465
  uint64_t ImageBase = getImageBase();
466
  uint64_t Rva = Addr - ImageBase;
467
  assert(Rva <= UINT32_MAX);
468
  return getRvaPtr((uint32_t)Rva, Res);
469
}
470

471
// Returns the file offset for the given RVA.
472
Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res,
473
                                const char *ErrorContext) const {
474
  for (const SectionRef &S : sections()) {
475
    const coff_section *Section = getCOFFSection(S);
476
    uint32_t SectionStart = Section->VirtualAddress;
477
    uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
478
    if (SectionStart <= Addr && Addr < SectionEnd) {
479
      // A table/directory entry can be pointing to somewhere in a stripped
480
      // section, in an object that went through `objcopy --only-keep-debug`.
481
      // In this case we don't want to cause the parsing of the object file to
482
      // fail, otherwise it will be impossible to use this object as debug info
483
      // in LLDB. Return SectionStrippedError here so that
484
      // COFFObjectFile::initialize can ignore the error.
485
      // Somewhat common binaries may have RVAs pointing outside of the
486
      // provided raw data. Instead of rejecting the binaries, just
487
      // treat the section as stripped for these purposes.
488
      if (Section->SizeOfRawData < Section->VirtualSize &&
489
          Addr >= SectionStart + Section->SizeOfRawData) {
490
        return make_error<SectionStrippedError>();
491
      }
492
      uint32_t Offset = Addr - SectionStart;
493
      Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
494
            Offset;
495
      return Error::success();
496
    }
497
  }
498
  if (ErrorContext)
499
    return createStringError(object_error::parse_failed,
500
                             "RVA 0x%" PRIx32 " for %s not found", Addr,
501
                             ErrorContext);
502
  return createStringError(object_error::parse_failed,
503
                           "RVA 0x%" PRIx32 " not found", Addr);
504
}
505

506
Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
507
                                           ArrayRef<uint8_t> &Contents,
508
                                           const char *ErrorContext) const {
509
  for (const SectionRef &S : sections()) {
510
    const coff_section *Section = getCOFFSection(S);
511
    uint32_t SectionStart = Section->VirtualAddress;
512
    // Check if this RVA is within the section bounds. Be careful about integer
513
    // overflow.
514
    uint32_t OffsetIntoSection = RVA - SectionStart;
515
    if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
516
        Size <= Section->VirtualSize - OffsetIntoSection) {
517
      uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +
518
                        Section->PointerToRawData + OffsetIntoSection;
519
      Contents =
520
          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
521
      return Error::success();
522
    }
523
  }
524
  if (ErrorContext)
525
    return createStringError(object_error::parse_failed,
526
                             "RVA 0x%" PRIx32 " for %s not found", RVA,
527
                             ErrorContext);
528
  return createStringError(object_error::parse_failed,
529
                           "RVA 0x%" PRIx32 " not found", RVA);
530
}
531

532
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
533
// table entry.
534
Error COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
535
                                  StringRef &Name) const {
536
  uintptr_t IntPtr = 0;
537
  if (Error E = getRvaPtr(Rva, IntPtr))
538
    return E;
539
  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
540
  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
541
  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
542
  return Error::success();
543
}
544

545
Error COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
546
                                      const codeview::DebugInfo *&PDBInfo,
547
                                      StringRef &PDBFileName) const {
548
  ArrayRef<uint8_t> InfoBytes;
549
  if (Error E =
550
          getRvaAndSizeAsBytes(DebugDir->AddressOfRawData, DebugDir->SizeOfData,
551
                               InfoBytes, "PDB info"))
552
    return E;
553
  if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
554
    return createStringError(object_error::parse_failed, "PDB info too small");
555
  PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
556
  InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
557
  PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
558
                          InfoBytes.size());
559
  // Truncate the name at the first null byte. Ignore any padding.
560
  PDBFileName = PDBFileName.split('\0').first;
561
  return Error::success();
562
}
563

564
Error COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
565
                                      StringRef &PDBFileName) const {
566
  for (const debug_directory &D : debug_directories())
567
    if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
568
      return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
569
  // If we get here, there is no PDB info to return.
570
  PDBInfo = nullptr;
571
  PDBFileName = StringRef();
572
  return Error::success();
573
}
574

575
// Find the import table.
576
Error COFFObjectFile::initImportTablePtr() {
577
  // First, we get the RVA of the import table. If the file lacks a pointer to
578
  // the import table, do nothing.
579
  const data_directory *DataEntry = getDataDirectory(COFF::IMPORT_TABLE);
580
  if (!DataEntry)
581
    return Error::success();
582

583
  // Do nothing if the pointer to import table is NULL.
584
  if (DataEntry->RelativeVirtualAddress == 0)
585
    return Error::success();
586

587
  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
588

589
  // Find the section that contains the RVA. This is needed because the RVA is
590
  // the import table's memory address which is different from its file offset.
591
  uintptr_t IntPtr = 0;
592
  if (Error E = getRvaPtr(ImportTableRva, IntPtr, "import table"))
593
    return E;
594
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
595
    return E;
596
  ImportDirectory = reinterpret_cast<
597
      const coff_import_directory_table_entry *>(IntPtr);
598
  return Error::success();
599
}
600

601
// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
602
Error COFFObjectFile::initDelayImportTablePtr() {
603
  const data_directory *DataEntry =
604
      getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR);
605
  if (!DataEntry)
606
    return Error::success();
607
  if (DataEntry->RelativeVirtualAddress == 0)
608
    return Error::success();
609

610
  uint32_t RVA = DataEntry->RelativeVirtualAddress;
611
  NumberOfDelayImportDirectory = DataEntry->Size /
612
      sizeof(delay_import_directory_table_entry) - 1;
613

614
  uintptr_t IntPtr = 0;
615
  if (Error E = getRvaPtr(RVA, IntPtr, "delay import table"))
616
    return E;
617
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
618
    return E;
619

620
  DelayImportDirectory = reinterpret_cast<
621
      const delay_import_directory_table_entry *>(IntPtr);
622
  return Error::success();
623
}
624

625
// Find the export table.
626
Error COFFObjectFile::initExportTablePtr() {
627
  // First, we get the RVA of the export table. If the file lacks a pointer to
628
  // the export table, do nothing.
629
  const data_directory *DataEntry = getDataDirectory(COFF::EXPORT_TABLE);
630
  if (!DataEntry)
631
    return Error::success();
632

633
  // Do nothing if the pointer to export table is NULL.
634
  if (DataEntry->RelativeVirtualAddress == 0)
635
    return Error::success();
636

637
  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
638
  uintptr_t IntPtr = 0;
639
  if (Error E = getRvaPtr(ExportTableRva, IntPtr, "export table"))
640
    return E;
641
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
642
    return E;
643

644
  ExportDirectory =
645
      reinterpret_cast<const export_directory_table_entry *>(IntPtr);
646
  return Error::success();
647
}
648

649
Error COFFObjectFile::initBaseRelocPtr() {
650
  const data_directory *DataEntry =
651
      getDataDirectory(COFF::BASE_RELOCATION_TABLE);
652
  if (!DataEntry)
653
    return Error::success();
654
  if (DataEntry->RelativeVirtualAddress == 0)
655
    return Error::success();
656

657
  uintptr_t IntPtr = 0;
658
  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
659
                          "base reloc table"))
660
    return E;
661
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
662
    return E;
663

664
  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
665
      IntPtr);
666
  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
667
      IntPtr + DataEntry->Size);
668
  // FIXME: Verify the section containing BaseRelocHeader has at least
669
  // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
670
  return Error::success();
671
}
672

673
Error COFFObjectFile::initDebugDirectoryPtr() {
674
  // Get the RVA of the debug directory. Do nothing if it does not exist.
675
  const data_directory *DataEntry = getDataDirectory(COFF::DEBUG_DIRECTORY);
676
  if (!DataEntry)
677
    return Error::success();
678

679
  // Do nothing if the RVA is NULL.
680
  if (DataEntry->RelativeVirtualAddress == 0)
681
    return Error::success();
682

683
  // Check that the size is a multiple of the entry size.
684
  if (DataEntry->Size % sizeof(debug_directory) != 0)
685
    return createStringError(object_error::parse_failed,
686
                             "debug directory has uneven size");
687

688
  uintptr_t IntPtr = 0;
689
  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
690
                          "debug directory"))
691
    return E;
692
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
693
    return E;
694

695
  DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
696
  DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(
697
      IntPtr + DataEntry->Size);
698
  // FIXME: Verify the section containing DebugDirectoryBegin has at least
699
  // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
700
  return Error::success();
701
}
702

703
Error COFFObjectFile::initTLSDirectoryPtr() {
704
  // Get the RVA of the TLS directory. Do nothing if it does not exist.
705
  const data_directory *DataEntry = getDataDirectory(COFF::TLS_TABLE);
706
  if (!DataEntry)
707
    return Error::success();
708

709
  // Do nothing if the RVA is NULL.
710
  if (DataEntry->RelativeVirtualAddress == 0)
711
    return Error::success();
712

713
  uint64_t DirSize =
714
      is64() ? sizeof(coff_tls_directory64) : sizeof(coff_tls_directory32);
715

716
  // Check that the size is correct.
717
  if (DataEntry->Size != DirSize)
718
    return createStringError(
719
        object_error::parse_failed,
720
        "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",
721
        static_cast<uint32_t>(DataEntry->Size), DirSize);
722

723
  uintptr_t IntPtr = 0;
724
  if (Error E =
725
          getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr, "TLS directory"))
726
    return E;
727
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
728
    return E;
729

730
  if (is64())
731
    TLSDirectory64 = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
732
  else
733
    TLSDirectory32 = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
734

735
  return Error::success();
736
}
737

738
Error COFFObjectFile::initLoadConfigPtr() {
739
  // Get the RVA of the debug directory. Do nothing if it does not exist.
740
  const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
741
  if (!DataEntry)
742
    return Error::success();
743

744
  // Do nothing if the RVA is NULL.
745
  if (DataEntry->RelativeVirtualAddress == 0)
746
    return Error::success();
747
  uintptr_t IntPtr = 0;
748
  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
749
                          "load config table"))
750
    return E;
751
  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
752
    return E;
753

754
  LoadConfig = (const void *)IntPtr;
755

756
  if (is64()) {
757
    auto Config = getLoadConfig64();
758
    if (Config->Size >=
759
            offsetof(coff_load_configuration64, CHPEMetadataPointer) +
760
                sizeof(Config->CHPEMetadataPointer) &&
761
        Config->CHPEMetadataPointer) {
762
      uint64_t ChpeOff = Config->CHPEMetadataPointer;
763
      if (Error E =
764
              getRvaPtr(ChpeOff - getImageBase(), IntPtr, "CHPE metadata"))
765
        return E;
766
      if (Error E = checkOffset(Data, IntPtr, sizeof(CHPEMetadata)))
767
        return E;
768

769
      CHPEMetadata = reinterpret_cast<const chpe_metadata *>(IntPtr);
770

771
      // Validate CHPE metadata
772
      if (CHPEMetadata->CodeMapCount) {
773
        if (Error E = getRvaPtr(CHPEMetadata->CodeMap, IntPtr, "CHPE code map"))
774
          return E;
775
        if (Error E = checkOffset(Data, IntPtr,
776
                                  CHPEMetadata->CodeMapCount *
777
                                      sizeof(chpe_range_entry)))
778
          return E;
779
      }
780

781
      if (CHPEMetadata->CodeRangesToEntryPointsCount) {
782
        if (Error E = getRvaPtr(CHPEMetadata->CodeRangesToEntryPoints, IntPtr,
783
                                "CHPE entry point ranges"))
784
          return E;
785
        if (Error E = checkOffset(Data, IntPtr,
786
                                  CHPEMetadata->CodeRangesToEntryPointsCount *
787
                                      sizeof(chpe_code_range_entry)))
788
          return E;
789
      }
790

791
      if (CHPEMetadata->RedirectionMetadataCount) {
792
        if (Error E = getRvaPtr(CHPEMetadata->RedirectionMetadata, IntPtr,
793
                                "CHPE redirection metadata"))
794
          return E;
795
        if (Error E = checkOffset(Data, IntPtr,
796
                                  CHPEMetadata->RedirectionMetadataCount *
797
                                      sizeof(chpe_redirection_entry)))
798
          return E;
799
      }
800
    }
801
  }
802

803
  return Error::success();
804
}
805

806
Expected<std::unique_ptr<COFFObjectFile>>
807
COFFObjectFile::create(MemoryBufferRef Object) {
808
  std::unique_ptr<COFFObjectFile> Obj(new COFFObjectFile(std::move(Object)));
809
  if (Error E = Obj->initialize())
810
    return E;
811
  return std::move(Obj);
812
}
813

814
COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
815
    : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
816
      COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
817
      DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
818
      SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
819
      ImportDirectory(nullptr), DelayImportDirectory(nullptr),
820
      NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),
821
      BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
822
      DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
823
      TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
824

825
static Error ignoreStrippedErrors(Error E) {
826
  if (E.isA<SectionStrippedError>()) {
827
    consumeError(std::move(E));
828
    return Error::success();
829
  }
830
  return E;
831
}
832

833
Error COFFObjectFile::initialize() {
834
  // Check that we at least have enough room for a header.
835
  std::error_code EC;
836
  if (!checkSize(Data, EC, sizeof(coff_file_header)))
837
    return errorCodeToError(EC);
838

839
  // The current location in the file where we are looking at.
840
  uint64_t CurPtr = 0;
841

842
  // PE header is optional and is present only in executables. If it exists,
843
  // it is placed right after COFF header.
844
  bool HasPEHeader = false;
845

846
  // Check if this is a PE/COFF file.
847
  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
848
    // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
849
    // PE signature to find 'normal' COFF header.
850
    const auto *DH = reinterpret_cast<const dos_header *>(base());
851
    if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
852
      CurPtr = DH->AddressOfNewExeHeader;
853
      // Check the PE magic bytes. ("PE\0\0")
854
      if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
855
        return createStringError(object_error::parse_failed,
856
                                 "incorrect PE magic");
857
      }
858
      CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
859
      HasPEHeader = true;
860
    }
861
  }
862

863
  if (Error E = getObject(COFFHeader, Data, base() + CurPtr))
864
    return E;
865

866
  // It might be a bigobj file, let's check.  Note that COFF bigobj and COFF
867
  // import libraries share a common prefix but bigobj is more restrictive.
868
  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
869
      COFFHeader->NumberOfSections == uint16_t(0xffff) &&
870
      checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
871
    if (Error E = getObject(COFFBigObjHeader, Data, base() + CurPtr))
872
      return E;
873

874
    // Verify that we are dealing with bigobj.
875
    if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
876
        std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
877
                    sizeof(COFF::BigObjMagic)) == 0) {
878
      COFFHeader = nullptr;
879
      CurPtr += sizeof(coff_bigobj_file_header);
880
    } else {
881
      // It's not a bigobj.
882
      COFFBigObjHeader = nullptr;
883
    }
884
  }
885
  if (COFFHeader) {
886
    // The prior checkSize call may have failed.  This isn't a hard error
887
    // because we were just trying to sniff out bigobj.
888
    EC = std::error_code();
889
    CurPtr += sizeof(coff_file_header);
890

891
    if (COFFHeader->isImportLibrary())
892
      return errorCodeToError(EC);
893
  }
894

895
  if (HasPEHeader) {
896
    const pe32_header *Header;
897
    if (Error E = getObject(Header, Data, base() + CurPtr))
898
      return E;
899

900
    const uint8_t *DataDirAddr;
901
    uint64_t DataDirSize;
902
    if (Header->Magic == COFF::PE32Header::PE32) {
903
      PE32Header = Header;
904
      DataDirAddr = base() + CurPtr + sizeof(pe32_header);
905
      DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
906
    } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
907
      PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
908
      DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
909
      DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
910
    } else {
911
      // It's neither PE32 nor PE32+.
912
      return createStringError(object_error::parse_failed,
913
                               "incorrect PE magic");
914
    }
915
    if (Error E = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))
916
      return E;
917
  }
918

919
  if (COFFHeader)
920
    CurPtr += COFFHeader->SizeOfOptionalHeader;
921

922
  assert(COFFHeader || COFFBigObjHeader);
923

924
  if (Error E =
925
          getObject(SectionTable, Data, base() + CurPtr,
926
                    (uint64_t)getNumberOfSections() * sizeof(coff_section)))
927
    return E;
928

929
  // Initialize the pointer to the symbol table.
930
  if (getPointerToSymbolTable() != 0) {
931
    if (Error E = initSymbolTablePtr()) {
932
      // Recover from errors reading the symbol table.
933
      consumeError(std::move(E));
934
      SymbolTable16 = nullptr;
935
      SymbolTable32 = nullptr;
936
      StringTable = nullptr;
937
      StringTableSize = 0;
938
    }
939
  } else {
940
    // We had better not have any symbols if we don't have a symbol table.
941
    if (getNumberOfSymbols() != 0) {
942
      return createStringError(object_error::parse_failed,
943
                               "symbol table missing");
944
    }
945
  }
946

947
  // Initialize the pointer to the beginning of the import table.
948
  if (Error E = ignoreStrippedErrors(initImportTablePtr()))
949
    return E;
950
  if (Error E = ignoreStrippedErrors(initDelayImportTablePtr()))
951
    return E;
952

953
  // Initialize the pointer to the export table.
954
  if (Error E = ignoreStrippedErrors(initExportTablePtr()))
955
    return E;
956

957
  // Initialize the pointer to the base relocation table.
958
  if (Error E = ignoreStrippedErrors(initBaseRelocPtr()))
959
    return E;
960

961
  // Initialize the pointer to the debug directory.
962
  if (Error E = ignoreStrippedErrors(initDebugDirectoryPtr()))
963
    return E;
964

965
  // Initialize the pointer to the TLS directory.
966
  if (Error E = ignoreStrippedErrors(initTLSDirectoryPtr()))
967
    return E;
968

969
  if (Error E = ignoreStrippedErrors(initLoadConfigPtr()))
970
    return E;
971

972
  return Error::success();
973
}
974

975
basic_symbol_iterator COFFObjectFile::symbol_begin() const {
976
  DataRefImpl Ret;
977
  Ret.p = getSymbolTable();
978
  return basic_symbol_iterator(SymbolRef(Ret, this));
979
}
980

981
basic_symbol_iterator COFFObjectFile::symbol_end() const {
982
  // The symbol table ends where the string table begins.
983
  DataRefImpl Ret;
984
  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
985
  return basic_symbol_iterator(SymbolRef(Ret, this));
986
}
987

988
import_directory_iterator COFFObjectFile::import_directory_begin() const {
989
  if (!ImportDirectory)
990
    return import_directory_end();
991
  if (ImportDirectory->isNull())
992
    return import_directory_end();
993
  return import_directory_iterator(
994
      ImportDirectoryEntryRef(ImportDirectory, 0, this));
995
}
996

997
import_directory_iterator COFFObjectFile::import_directory_end() const {
998
  return import_directory_iterator(
999
      ImportDirectoryEntryRef(nullptr, -1, this));
1000
}
1001

1002
delay_import_directory_iterator
1003
COFFObjectFile::delay_import_directory_begin() const {
1004
  return delay_import_directory_iterator(
1005
      DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
1006
}
1007

1008
delay_import_directory_iterator
1009
COFFObjectFile::delay_import_directory_end() const {
1010
  return delay_import_directory_iterator(
1011
      DelayImportDirectoryEntryRef(
1012
          DelayImportDirectory, NumberOfDelayImportDirectory, this));
1013
}
1014

1015
export_directory_iterator COFFObjectFile::export_directory_begin() const {
1016
  return export_directory_iterator(
1017
      ExportDirectoryEntryRef(ExportDirectory, 0, this));
1018
}
1019

1020
export_directory_iterator COFFObjectFile::export_directory_end() const {
1021
  if (!ExportDirectory)
1022
    return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
1023
  ExportDirectoryEntryRef Ref(ExportDirectory,
1024
                              ExportDirectory->AddressTableEntries, this);
1025
  return export_directory_iterator(Ref);
1026
}
1027

1028
section_iterator COFFObjectFile::section_begin() const {
1029
  DataRefImpl Ret;
1030
  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
1031
  return section_iterator(SectionRef(Ret, this));
1032
}
1033

1034
section_iterator COFFObjectFile::section_end() const {
1035
  DataRefImpl Ret;
1036
  int NumSections =
1037
      COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
1038
  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
1039
  return section_iterator(SectionRef(Ret, this));
1040
}
1041

1042
base_reloc_iterator COFFObjectFile::base_reloc_begin() const {
1043
  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
1044
}
1045

1046
base_reloc_iterator COFFObjectFile::base_reloc_end() const {
1047
  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
1048
}
1049

1050
uint8_t COFFObjectFile::getBytesInAddress() const {
1051
  return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4;
1052
}
1053

1054
StringRef COFFObjectFile::getFileFormatName() const {
1055
  switch(getMachine()) {
1056
  case COFF::IMAGE_FILE_MACHINE_I386:
1057
    return "COFF-i386";
1058
  case COFF::IMAGE_FILE_MACHINE_AMD64:
1059
    return "COFF-x86-64";
1060
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
1061
    return "COFF-ARM";
1062
  case COFF::IMAGE_FILE_MACHINE_ARM64:
1063
    return "COFF-ARM64";
1064
  case COFF::IMAGE_FILE_MACHINE_ARM64EC:
1065
    return "COFF-ARM64EC";
1066
  case COFF::IMAGE_FILE_MACHINE_ARM64X:
1067
    return "COFF-ARM64X";
1068
  default:
1069
    return "COFF-<unknown arch>";
1070
  }
1071
}
1072

1073
Triple::ArchType COFFObjectFile::getArch() const {
1074
  return getMachineArchType(getMachine());
1075
}
1076

1077
Expected<uint64_t> COFFObjectFile::getStartAddress() const {
1078
  if (PE32Header)
1079
    return PE32Header->AddressOfEntryPoint;
1080
  return 0;
1081
}
1082

1083
iterator_range<import_directory_iterator>
1084
COFFObjectFile::import_directories() const {
1085
  return make_range(import_directory_begin(), import_directory_end());
1086
}
1087

1088
iterator_range<delay_import_directory_iterator>
1089
COFFObjectFile::delay_import_directories() const {
1090
  return make_range(delay_import_directory_begin(),
1091
                    delay_import_directory_end());
1092
}
1093

1094
iterator_range<export_directory_iterator>
1095
COFFObjectFile::export_directories() const {
1096
  return make_range(export_directory_begin(), export_directory_end());
1097
}
1098

1099
iterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
1100
  return make_range(base_reloc_begin(), base_reloc_end());
1101
}
1102

1103
const data_directory *COFFObjectFile::getDataDirectory(uint32_t Index) const {
1104
  if (!DataDirectory)
1105
    return nullptr;
1106
  assert(PE32Header || PE32PlusHeader);
1107
  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
1108
                               : PE32PlusHeader->NumberOfRvaAndSize;
1109
  if (Index >= NumEnt)
1110
    return nullptr;
1111
  return &DataDirectory[Index];
1112
}
1113

1114
Expected<const coff_section *> COFFObjectFile::getSection(int32_t Index) const {
1115
  // Perhaps getting the section of a reserved section index should be an error,
1116
  // but callers rely on this to return null.
1117
  if (COFF::isReservedSectionNumber(Index))
1118
    return (const coff_section *)nullptr;
1119
  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
1120
    // We already verified the section table data, so no need to check again.
1121
    return SectionTable + (Index - 1);
1122
  }
1123
  return createStringError(object_error::parse_failed,
1124
                           "section index out of bounds");
1125
}
1126

1127
Expected<StringRef> COFFObjectFile::getString(uint32_t Offset) const {
1128
  if (StringTableSize <= 4)
1129
    // Tried to get a string from an empty string table.
1130
    return createStringError(object_error::parse_failed, "string table empty");
1131
  if (Offset >= StringTableSize)
1132
    return errorCodeToError(object_error::unexpected_eof);
1133
  return StringRef(StringTable + Offset);
1134
}
1135

1136
Expected<StringRef> COFFObjectFile::getSymbolName(COFFSymbolRef Symbol) const {
1137
  return getSymbolName(Symbol.getGeneric());
1138
}
1139

1140
Expected<StringRef>
1141
COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol) const {
1142
  // Check for string table entry. First 4 bytes are 0.
1143
  if (Symbol->Name.Offset.Zeroes == 0)
1144
    return getString(Symbol->Name.Offset.Offset);
1145

1146
  // Null terminated, let ::strlen figure out the length.
1147
  if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
1148
    return StringRef(Symbol->Name.ShortName);
1149

1150
  // Not null terminated, use all 8 bytes.
1151
  return StringRef(Symbol->Name.ShortName, COFF::NameSize);
1152
}
1153

1154
ArrayRef<uint8_t>
1155
COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const {
1156
  const uint8_t *Aux = nullptr;
1157

1158
  size_t SymbolSize = getSymbolTableEntrySize();
1159
  if (Symbol.getNumberOfAuxSymbols() > 0) {
1160
    // AUX data comes immediately after the symbol in COFF
1161
    Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
1162
#ifndef NDEBUG
1163
    // Verify that the Aux symbol points to a valid entry in the symbol table.
1164
    uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
1165
    if (Offset < getPointerToSymbolTable() ||
1166
        Offset >=
1167
            getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
1168
      report_fatal_error("Aux Symbol data was outside of symbol table.");
1169

1170
    assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
1171
           "Aux Symbol data did not point to the beginning of a symbol");
1172
#endif
1173
  }
1174
  return ArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
1175
}
1176

1177
uint32_t COFFObjectFile::getSymbolIndex(COFFSymbolRef Symbol) const {
1178
  uintptr_t Offset =
1179
      reinterpret_cast<uintptr_t>(Symbol.getRawPtr()) - getSymbolTable();
1180
  assert(Offset % getSymbolTableEntrySize() == 0 &&
1181
         "Symbol did not point to the beginning of a symbol");
1182
  size_t Index = Offset / getSymbolTableEntrySize();
1183
  assert(Index < getNumberOfSymbols());
1184
  return Index;
1185
}
1186

1187
Expected<StringRef>
1188
COFFObjectFile::getSectionName(const coff_section *Sec) const {
1189
  StringRef Name = StringRef(Sec->Name, COFF::NameSize).split('\0').first;
1190

1191
  // Check for string table entry. First byte is '/'.
1192
  if (Name.starts_with("/")) {
1193
    uint32_t Offset;
1194
    if (Name.starts_with("//")) {
1195
      if (decodeBase64StringEntry(Name.substr(2), Offset))
1196
        return createStringError(object_error::parse_failed,
1197
                                 "invalid section name");
1198
    } else {
1199
      if (Name.substr(1).getAsInteger(10, Offset))
1200
        return createStringError(object_error::parse_failed,
1201
                                 "invalid section name");
1202
    }
1203
    return getString(Offset);
1204
  }
1205

1206
  return Name;
1207
}
1208

1209
uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
1210
  // SizeOfRawData and VirtualSize change what they represent depending on
1211
  // whether or not we have an executable image.
1212
  //
1213
  // For object files, SizeOfRawData contains the size of section's data;
1214
  // VirtualSize should be zero but isn't due to buggy COFF writers.
1215
  //
1216
  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
1217
  // actual section size is in VirtualSize.  It is possible for VirtualSize to
1218
  // be greater than SizeOfRawData; the contents past that point should be
1219
  // considered to be zero.
1220
  if (getDOSHeader())
1221
    return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
1222
  return Sec->SizeOfRawData;
1223
}
1224

1225
Error COFFObjectFile::getSectionContents(const coff_section *Sec,
1226
                                         ArrayRef<uint8_t> &Res) const {
1227
  // In COFF, a virtual section won't have any in-file
1228
  // content, so the file pointer to the content will be zero.
1229
  if (Sec->PointerToRawData == 0)
1230
    return Error::success();
1231
  // The only thing that we need to verify is that the contents is contained
1232
  // within the file bounds. We don't need to make sure it doesn't cover other
1233
  // data, as there's nothing that says that is not allowed.
1234
  uintptr_t ConStart =
1235
      reinterpret_cast<uintptr_t>(base()) + Sec->PointerToRawData;
1236
  uint32_t SectionSize = getSectionSize(Sec);
1237
  if (Error E = checkOffset(Data, ConStart, SectionSize))
1238
    return E;
1239
  Res = ArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
1240
  return Error::success();
1241
}
1242

1243
const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
1244
  return reinterpret_cast<const coff_relocation*>(Rel.p);
1245
}
1246

1247
void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
1248
  Rel.p = reinterpret_cast<uintptr_t>(
1249
            reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
1250
}
1251

1252
uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
1253
  const coff_relocation *R = toRel(Rel);
1254
  return R->VirtualAddress;
1255
}
1256

1257
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
1258
  const coff_relocation *R = toRel(Rel);
1259
  DataRefImpl Ref;
1260
  if (R->SymbolTableIndex >= getNumberOfSymbols())
1261
    return symbol_end();
1262
  if (SymbolTable16)
1263
    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
1264
  else if (SymbolTable32)
1265
    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
1266
  else
1267
    llvm_unreachable("no symbol table pointer!");
1268
  return symbol_iterator(SymbolRef(Ref, this));
1269
}
1270

1271
uint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel) const {
1272
  const coff_relocation* R = toRel(Rel);
1273
  return R->Type;
1274
}
1275

1276
const coff_section *
1277
COFFObjectFile::getCOFFSection(const SectionRef &Section) const {
1278
  return toSec(Section.getRawDataRefImpl());
1279
}
1280

1281
COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const {
1282
  if (SymbolTable16)
1283
    return toSymb<coff_symbol16>(Ref);
1284
  if (SymbolTable32)
1285
    return toSymb<coff_symbol32>(Ref);
1286
  llvm_unreachable("no symbol table pointer!");
1287
}
1288

1289
COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const {
1290
  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1291
}
1292

1293
const coff_relocation *
1294
COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
1295
  return toRel(Reloc.getRawDataRefImpl());
1296
}
1297

1298
ArrayRef<coff_relocation>
1299
COFFObjectFile::getRelocations(const coff_section *Sec) const {
1300
  return {getFirstReloc(Sec, Data, base()),
1301
          getNumberOfRelocations(Sec, Data, base())};
1302
}
1303

1304
#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)                           \
1305
  case COFF::reloc_type:                                                       \
1306
    return #reloc_type;
1307

1308
StringRef COFFObjectFile::getRelocationTypeName(uint16_t Type) const {
1309
  switch (getArch()) {
1310
  case Triple::x86_64:
1311
    switch (Type) {
1312
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
1313
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
1314
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
1315
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB);
1316
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32);
1317
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1);
1318
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2);
1319
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3);
1320
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4);
1321
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5);
1322
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION);
1323
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL);
1324
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7);
1325
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN);
1326
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32);
1327
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
1328
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
1329
    default:
1330
      return "Unknown";
1331
    }
1332
    break;
1333
  case Triple::thumb:
1334
    switch (Type) {
1335
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE);
1336
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32);
1337
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB);
1338
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24);
1339
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11);
1340
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN);
1341
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24);
1342
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11);
1343
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_REL32);
1344
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION);
1345
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL);
1346
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A);
1347
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T);
1348
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T);
1349
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T);
1350
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T);
1351
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_PAIR);
1352
    default:
1353
      return "Unknown";
1354
    }
1355
    break;
1356
  case Triple::aarch64:
1357
    switch (Type) {
1358
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ABSOLUTE);
1359
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32);
1360
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32NB);
1361
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH26);
1362
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEBASE_REL21);
1363
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_REL21);
1364
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEOFFSET_12A);
1365
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEOFFSET_12L);
1366
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL);
1367
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_LOW12A);
1368
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_HIGH12A);
1369
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_LOW12L);
1370
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_TOKEN);
1371
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECTION);
1372
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR64);
1373
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH19);
1374
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH14);
1375
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_REL32);
1376
    default:
1377
      return "Unknown";
1378
    }
1379
    break;
1380
  case Triple::x86:
1381
    switch (Type) {
1382
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
1383
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
1384
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
1385
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32);
1386
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB);
1387
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12);
1388
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION);
1389
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL);
1390
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN);
1391
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
1392
    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
1393
    default:
1394
      return "Unknown";
1395
    }
1396
    break;
1397
  default:
1398
    return "Unknown";
1399
  }
1400
}
1401

1402
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1403

1404
void COFFObjectFile::getRelocationTypeName(
1405
    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1406
  const coff_relocation *Reloc = toRel(Rel);
1407
  StringRef Res = getRelocationTypeName(Reloc->Type);
1408
  Result.append(Res.begin(), Res.end());
1409
}
1410

1411
bool COFFObjectFile::isRelocatableObject() const {
1412
  return !DataDirectory;
1413
}
1414

1415
StringRef COFFObjectFile::mapDebugSectionName(StringRef Name) const {
1416
  return StringSwitch<StringRef>(Name)
1417
      .Case("eh_fram", "eh_frame")
1418
      .Default(Name);
1419
}
1420

1421
bool ImportDirectoryEntryRef::
1422
operator==(const ImportDirectoryEntryRef &Other) const {
1423
  return ImportTable == Other.ImportTable && Index == Other.Index;
1424
}
1425

1426
void ImportDirectoryEntryRef::moveNext() {
1427
  ++Index;
1428
  if (ImportTable[Index].isNull()) {
1429
    Index = -1;
1430
    ImportTable = nullptr;
1431
  }
1432
}
1433

1434
Error ImportDirectoryEntryRef::getImportTableEntry(
1435
    const coff_import_directory_table_entry *&Result) const {
1436
  return getObject(Result, OwningObject->Data, ImportTable + Index);
1437
}
1438

1439
static imported_symbol_iterator
1440
makeImportedSymbolIterator(const COFFObjectFile *Object,
1441
                           uintptr_t Ptr, int Index) {
1442
  if (Object->getBytesInAddress() == 4) {
1443
    auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
1444
    return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1445
  }
1446
  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
1447
  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1448
}
1449

1450
static imported_symbol_iterator
1451
importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
1452
  uintptr_t IntPtr = 0;
1453
  // FIXME: Handle errors.
1454
  cantFail(Object->getRvaPtr(RVA, IntPtr));
1455
  return makeImportedSymbolIterator(Object, IntPtr, 0);
1456
}
1457

1458
static imported_symbol_iterator
1459
importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
1460
  uintptr_t IntPtr = 0;
1461
  // FIXME: Handle errors.
1462
  cantFail(Object->getRvaPtr(RVA, IntPtr));
1463
  // Forward the pointer to the last entry which is null.
1464
  int Index = 0;
1465
  if (Object->getBytesInAddress() == 4) {
1466
    auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
1467
    while (*Entry++)
1468
      ++Index;
1469
  } else {
1470
    auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
1471
    while (*Entry++)
1472
      ++Index;
1473
  }
1474
  return makeImportedSymbolIterator(Object, IntPtr, Index);
1475
}
1476

1477
imported_symbol_iterator
1478
ImportDirectoryEntryRef::imported_symbol_begin() const {
1479
  return importedSymbolBegin(ImportTable[Index].ImportAddressTableRVA,
1480
                             OwningObject);
1481
}
1482

1483
imported_symbol_iterator
1484
ImportDirectoryEntryRef::imported_symbol_end() const {
1485
  return importedSymbolEnd(ImportTable[Index].ImportAddressTableRVA,
1486
                           OwningObject);
1487
}
1488

1489
iterator_range<imported_symbol_iterator>
1490
ImportDirectoryEntryRef::imported_symbols() const {
1491
  return make_range(imported_symbol_begin(), imported_symbol_end());
1492
}
1493

1494
imported_symbol_iterator ImportDirectoryEntryRef::lookup_table_begin() const {
1495
  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
1496
                             OwningObject);
1497
}
1498

1499
imported_symbol_iterator ImportDirectoryEntryRef::lookup_table_end() const {
1500
  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
1501
                           OwningObject);
1502
}
1503

1504
iterator_range<imported_symbol_iterator>
1505
ImportDirectoryEntryRef::lookup_table_symbols() const {
1506
  return make_range(lookup_table_begin(), lookup_table_end());
1507
}
1508

1509
Error ImportDirectoryEntryRef::getName(StringRef &Result) const {
1510
  uintptr_t IntPtr = 0;
1511
  if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr,
1512
                                        "import directory name"))
1513
    return E;
1514
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1515
  return Error::success();
1516
}
1517

1518
Error
1519
ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t  &Result) const {
1520
  Result = ImportTable[Index].ImportLookupTableRVA;
1521
  return Error::success();
1522
}
1523

1524
Error ImportDirectoryEntryRef::getImportAddressTableRVA(
1525
    uint32_t &Result) const {
1526
  Result = ImportTable[Index].ImportAddressTableRVA;
1527
  return Error::success();
1528
}
1529

1530
bool DelayImportDirectoryEntryRef::
1531
operator==(const DelayImportDirectoryEntryRef &Other) const {
1532
  return Table == Other.Table && Index == Other.Index;
1533
}
1534

1535
void DelayImportDirectoryEntryRef::moveNext() {
1536
  ++Index;
1537
}
1538

1539
imported_symbol_iterator
1540
DelayImportDirectoryEntryRef::imported_symbol_begin() const {
1541
  return importedSymbolBegin(Table[Index].DelayImportNameTable,
1542
                             OwningObject);
1543
}
1544

1545
imported_symbol_iterator
1546
DelayImportDirectoryEntryRef::imported_symbol_end() const {
1547
  return importedSymbolEnd(Table[Index].DelayImportNameTable,
1548
                           OwningObject);
1549
}
1550

1551
iterator_range<imported_symbol_iterator>
1552
DelayImportDirectoryEntryRef::imported_symbols() const {
1553
  return make_range(imported_symbol_begin(), imported_symbol_end());
1554
}
1555

1556
Error DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
1557
  uintptr_t IntPtr = 0;
1558
  if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr,
1559
                                        "delay import directory name"))
1560
    return E;
1561
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1562
  return Error::success();
1563
}
1564

1565
Error DelayImportDirectoryEntryRef::getDelayImportTable(
1566
    const delay_import_directory_table_entry *&Result) const {
1567
  Result = &Table[Index];
1568
  return Error::success();
1569
}
1570

1571
Error DelayImportDirectoryEntryRef::getImportAddress(int AddrIndex,
1572
                                                     uint64_t &Result) const {
1573
  uint32_t RVA = Table[Index].DelayImportAddressTable +
1574
      AddrIndex * (OwningObject->is64() ? 8 : 4);
1575
  uintptr_t IntPtr = 0;
1576
  if (Error E = OwningObject->getRvaPtr(RVA, IntPtr, "import address"))
1577
    return E;
1578
  if (OwningObject->is64())
1579
    Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1580
  else
1581
    Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1582
  return Error::success();
1583
}
1584

1585
bool ExportDirectoryEntryRef::
1586
operator==(const ExportDirectoryEntryRef &Other) const {
1587
  return ExportTable == Other.ExportTable && Index == Other.Index;
1588
}
1589

1590
void ExportDirectoryEntryRef::moveNext() {
1591
  ++Index;
1592
}
1593

1594
// Returns the name of the current export symbol. If the symbol is exported only
1595
// by ordinal, the empty string is set as a result.
1596
Error ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
1597
  uintptr_t IntPtr = 0;
1598
  if (Error E =
1599
          OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr, "dll name"))
1600
    return E;
1601
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1602
  return Error::success();
1603
}
1604

1605
// Returns the starting ordinal number.
1606
Error ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
1607
  Result = ExportTable->OrdinalBase;
1608
  return Error::success();
1609
}
1610

1611
// Returns the export ordinal of the current export symbol.
1612
Error ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1613
  Result = ExportTable->OrdinalBase + Index;
1614
  return Error::success();
1615
}
1616

1617
// Returns the address of the current export symbol.
1618
Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1619
  uintptr_t IntPtr = 0;
1620
  if (Error EC = OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA,
1621
                                         IntPtr, "export address"))
1622
    return EC;
1623
  const export_address_table_entry *entry =
1624
      reinterpret_cast<const export_address_table_entry *>(IntPtr);
1625
  Result = entry[Index].ExportRVA;
1626
  return Error::success();
1627
}
1628

1629
// Returns the name of the current export symbol. If the symbol is exported only
1630
// by ordinal, the empty string is set as a result.
1631
Error
1632
ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
1633
  uintptr_t IntPtr = 0;
1634
  if (Error EC = OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr,
1635
                                         "export ordinal table"))
1636
    return EC;
1637
  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
1638

1639
  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
1640
  int Offset = 0;
1641
  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
1642
       I < E; ++I, ++Offset) {
1643
    if (*I != Index)
1644
      continue;
1645
    if (Error EC = OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr,
1646
                                           "export table entry"))
1647
      return EC;
1648
    const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1649
    if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr,
1650
                                           "export symbol name"))
1651
      return EC;
1652
    Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1653
    return Error::success();
1654
  }
1655
  Result = "";
1656
  return Error::success();
1657
}
1658

1659
Error ExportDirectoryEntryRef::isForwarder(bool &Result) const {
1660
  const data_directory *DataEntry =
1661
      OwningObject->getDataDirectory(COFF::EXPORT_TABLE);
1662
  if (!DataEntry)
1663
    return createStringError(object_error::parse_failed,
1664
                             "export table missing");
1665
  uint32_t RVA;
1666
  if (auto EC = getExportRVA(RVA))
1667
    return EC;
1668
  uint32_t Begin = DataEntry->RelativeVirtualAddress;
1669
  uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
1670
  Result = (Begin <= RVA && RVA < End);
1671
  return Error::success();
1672
}
1673

1674
Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
1675
  uint32_t RVA;
1676
  if (auto EC = getExportRVA(RVA))
1677
    return EC;
1678
  uintptr_t IntPtr = 0;
1679
  if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr, "export forward target"))
1680
    return EC;
1681
  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1682
  return Error::success();
1683
}
1684

1685
bool ImportedSymbolRef::
1686
operator==(const ImportedSymbolRef &Other) const {
1687
  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1688
      && Index == Other.Index;
1689
}
1690

1691
void ImportedSymbolRef::moveNext() {
1692
  ++Index;
1693
}
1694

1695
Error ImportedSymbolRef::getSymbolName(StringRef &Result) const {
1696
  uint32_t RVA;
1697
  if (Entry32) {
1698
    // If a symbol is imported only by ordinal, it has no name.
1699
    if (Entry32[Index].isOrdinal())
1700
      return Error::success();
1701
    RVA = Entry32[Index].getHintNameRVA();
1702
  } else {
1703
    if (Entry64[Index].isOrdinal())
1704
      return Error::success();
1705
    RVA = Entry64[Index].getHintNameRVA();
1706
  }
1707
  uintptr_t IntPtr = 0;
1708
  if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol name"))
1709
    return EC;
1710
  // +2 because the first two bytes is hint.
1711
  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1712
  return Error::success();
1713
}
1714

1715
Error ImportedSymbolRef::isOrdinal(bool &Result) const {
1716
  if (Entry32)
1717
    Result = Entry32[Index].isOrdinal();
1718
  else
1719
    Result = Entry64[Index].isOrdinal();
1720
  return Error::success();
1721
}
1722

1723
Error ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
1724
  if (Entry32)
1725
    Result = Entry32[Index].getHintNameRVA();
1726
  else
1727
    Result = Entry64[Index].getHintNameRVA();
1728
  return Error::success();
1729
}
1730

1731
Error ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1732
  uint32_t RVA;
1733
  if (Entry32) {
1734
    if (Entry32[Index].isOrdinal()) {
1735
      Result = Entry32[Index].getOrdinal();
1736
      return Error::success();
1737
    }
1738
    RVA = Entry32[Index].getHintNameRVA();
1739
  } else {
1740
    if (Entry64[Index].isOrdinal()) {
1741
      Result = Entry64[Index].getOrdinal();
1742
      return Error::success();
1743
    }
1744
    RVA = Entry64[Index].getHintNameRVA();
1745
  }
1746
  uintptr_t IntPtr = 0;
1747
  if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol ordinal"))
1748
    return EC;
1749
  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1750
  return Error::success();
1751
}
1752

1753
Expected<std::unique_ptr<COFFObjectFile>>
1754
ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
1755
  return COFFObjectFile::create(Object);
1756
}
1757

1758
bool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
1759
  return Header == Other.Header && Index == Other.Index;
1760
}
1761

1762
void BaseRelocRef::moveNext() {
1763
  // Header->BlockSize is the size of the current block, including the
1764
  // size of the header itself.
1765
  uint32_t Size = sizeof(*Header) +
1766
      sizeof(coff_base_reloc_block_entry) * (Index + 1);
1767
  if (Size == Header->BlockSize) {
1768
    // .reloc contains a list of base relocation blocks. Each block
1769
    // consists of the header followed by entries. The header contains
1770
    // how many entories will follow. When we reach the end of the
1771
    // current block, proceed to the next block.
1772
    Header = reinterpret_cast<const coff_base_reloc_block_header *>(
1773
        reinterpret_cast<const uint8_t *>(Header) + Size);
1774
    Index = 0;
1775
  } else {
1776
    ++Index;
1777
  }
1778
}
1779

1780
Error BaseRelocRef::getType(uint8_t &Type) const {
1781
  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1782
  Type = Entry[Index].getType();
1783
  return Error::success();
1784
}
1785

1786
Error BaseRelocRef::getRVA(uint32_t &Result) const {
1787
  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1788
  Result = Header->PageRVA + Entry[Index].getOffset();
1789
  return Error::success();
1790
}
1791

1792
#define RETURN_IF_ERROR(Expr)                                                  \
1793
  do {                                                                         \
1794
    Error E = (Expr);                                                          \
1795
    if (E)                                                                     \
1796
      return std::move(E);                                                     \
1797
  } while (0)
1798

1799
Expected<ArrayRef<UTF16>>
1800
ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {
1801
  BinaryStreamReader Reader = BinaryStreamReader(BBS);
1802
  Reader.setOffset(Offset);
1803
  uint16_t Length;
1804
  RETURN_IF_ERROR(Reader.readInteger(Length));
1805
  ArrayRef<UTF16> RawDirString;
1806
  RETURN_IF_ERROR(Reader.readArray(RawDirString, Length));
1807
  return RawDirString;
1808
}
1809

1810
Expected<ArrayRef<UTF16>>
1811
ResourceSectionRef::getEntryNameString(const coff_resource_dir_entry &Entry) {
1812
  return getDirStringAtOffset(Entry.Identifier.getNameOffset());
1813
}
1814

1815
Expected<const coff_resource_dir_table &>
1816
ResourceSectionRef::getTableAtOffset(uint32_t Offset) {
1817
  const coff_resource_dir_table *Table = nullptr;
1818

1819
  BinaryStreamReader Reader(BBS);
1820
  Reader.setOffset(Offset);
1821
  RETURN_IF_ERROR(Reader.readObject(Table));
1822
  assert(Table != nullptr);
1823
  return *Table;
1824
}
1825

1826
Expected<const coff_resource_dir_entry &>
1827
ResourceSectionRef::getTableEntryAtOffset(uint32_t Offset) {
1828
  const coff_resource_dir_entry *Entry = nullptr;
1829

1830
  BinaryStreamReader Reader(BBS);
1831
  Reader.setOffset(Offset);
1832
  RETURN_IF_ERROR(Reader.readObject(Entry));
1833
  assert(Entry != nullptr);
1834
  return *Entry;
1835
}
1836

1837
Expected<const coff_resource_data_entry &>
1838
ResourceSectionRef::getDataEntryAtOffset(uint32_t Offset) {
1839
  const coff_resource_data_entry *Entry = nullptr;
1840

1841
  BinaryStreamReader Reader(BBS);
1842
  Reader.setOffset(Offset);
1843
  RETURN_IF_ERROR(Reader.readObject(Entry));
1844
  assert(Entry != nullptr);
1845
  return *Entry;
1846
}
1847

1848
Expected<const coff_resource_dir_table &>
1849
ResourceSectionRef::getEntrySubDir(const coff_resource_dir_entry &Entry) {
1850
  assert(Entry.Offset.isSubDir());
1851
  return getTableAtOffset(Entry.Offset.value());
1852
}
1853

1854
Expected<const coff_resource_data_entry &>
1855
ResourceSectionRef::getEntryData(const coff_resource_dir_entry &Entry) {
1856
  assert(!Entry.Offset.isSubDir());
1857
  return getDataEntryAtOffset(Entry.Offset.value());
1858
}
1859

1860
Expected<const coff_resource_dir_table &> ResourceSectionRef::getBaseTable() {
1861
  return getTableAtOffset(0);
1862
}
1863

1864
Expected<const coff_resource_dir_entry &>
1865
ResourceSectionRef::getTableEntry(const coff_resource_dir_table &Table,
1866
                                  uint32_t Index) {
1867
  if (Index >= (uint32_t)(Table.NumberOfNameEntries + Table.NumberOfIDEntries))
1868
    return createStringError(object_error::parse_failed, "index out of range");
1869
  const uint8_t *TablePtr = reinterpret_cast<const uint8_t *>(&Table);
1870
  ptrdiff_t TableOffset = TablePtr - BBS.data().data();
1871
  return getTableEntryAtOffset(TableOffset + sizeof(Table) +
1872
                               Index * sizeof(coff_resource_dir_entry));
1873
}
1874

1875
Error ResourceSectionRef::load(const COFFObjectFile *O) {
1876
  for (const SectionRef &S : O->sections()) {
1877
    Expected<StringRef> Name = S.getName();
1878
    if (!Name)
1879
      return Name.takeError();
1880

1881
    if (*Name == ".rsrc" || *Name == ".rsrc$01")
1882
      return load(O, S);
1883
  }
1884
  return createStringError(object_error::parse_failed,
1885
                           "no resource section found");
1886
}
1887

1888
Error ResourceSectionRef::load(const COFFObjectFile *O, const SectionRef &S) {
1889
  Obj = O;
1890
  Section = S;
1891
  Expected<StringRef> Contents = Section.getContents();
1892
  if (!Contents)
1893
    return Contents.takeError();
1894
  BBS = BinaryByteStream(*Contents, llvm::endianness::little);
1895
  const coff_section *COFFSect = Obj->getCOFFSection(Section);
1896
  ArrayRef<coff_relocation> OrigRelocs = Obj->getRelocations(COFFSect);
1897
  Relocs.reserve(OrigRelocs.size());
1898
  for (const coff_relocation &R : OrigRelocs)
1899
    Relocs.push_back(&R);
1900
  llvm::sort(Relocs, [](const coff_relocation *A, const coff_relocation *B) {
1901
    return A->VirtualAddress < B->VirtualAddress;
1902
  });
1903
  return Error::success();
1904
}
1905

1906
Expected<StringRef>
1907
ResourceSectionRef::getContents(const coff_resource_data_entry &Entry) {
1908
  if (!Obj)
1909
    return createStringError(object_error::parse_failed, "no object provided");
1910

1911
  // Find a potential relocation at the DataRVA field (first member of
1912
  // the coff_resource_data_entry struct).
1913
  const uint8_t *EntryPtr = reinterpret_cast<const uint8_t *>(&Entry);
1914
  ptrdiff_t EntryOffset = EntryPtr - BBS.data().data();
1915
  coff_relocation RelocTarget{ulittle32_t(EntryOffset), ulittle32_t(0),
1916
                              ulittle16_t(0)};
1917
  auto RelocsForOffset =
1918
      std::equal_range(Relocs.begin(), Relocs.end(), &RelocTarget,
1919
                       [](const coff_relocation *A, const coff_relocation *B) {
1920
                         return A->VirtualAddress < B->VirtualAddress;
1921
                       });
1922

1923
  if (RelocsForOffset.first != RelocsForOffset.second) {
1924
    // We found a relocation with the right offset. Check that it does have
1925
    // the expected type.
1926
    const coff_relocation &R = **RelocsForOffset.first;
1927
    uint16_t RVAReloc;
1928
    switch (Obj->getArch()) {
1929
    case Triple::x86:
1930
      RVAReloc = COFF::IMAGE_REL_I386_DIR32NB;
1931
      break;
1932
    case Triple::x86_64:
1933
      RVAReloc = COFF::IMAGE_REL_AMD64_ADDR32NB;
1934
      break;
1935
    case Triple::thumb:
1936
      RVAReloc = COFF::IMAGE_REL_ARM_ADDR32NB;
1937
      break;
1938
    case Triple::aarch64:
1939
      RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB;
1940
      break;
1941
    default:
1942
      return createStringError(object_error::parse_failed,
1943
                               "unsupported architecture");
1944
    }
1945
    if (R.Type != RVAReloc)
1946
      return createStringError(object_error::parse_failed,
1947
                               "unexpected relocation type");
1948
    // Get the relocation's symbol
1949
    Expected<COFFSymbolRef> Sym = Obj->getSymbol(R.SymbolTableIndex);
1950
    if (!Sym)
1951
      return Sym.takeError();
1952
    // And the symbol's section
1953
    Expected<const coff_section *> Section =
1954
        Obj->getSection(Sym->getSectionNumber());
1955
    if (!Section)
1956
      return Section.takeError();
1957
    // Add the initial value of DataRVA to the symbol's offset to find the
1958
    // data it points at.
1959
    uint64_t Offset = Entry.DataRVA + Sym->getValue();
1960
    ArrayRef<uint8_t> Contents;
1961
    if (Error E = Obj->getSectionContents(*Section, Contents))
1962
      return E;
1963
    if (Offset + Entry.DataSize > Contents.size())
1964
      return createStringError(object_error::parse_failed,
1965
                               "data outside of section");
1966
    // Return a reference to the data inside the section.
1967
    return StringRef(reinterpret_cast<const char *>(Contents.data()) + Offset,
1968
                     Entry.DataSize);
1969
  } else {
1970
    // Relocatable objects need a relocation for the DataRVA field.
1971
    if (Obj->isRelocatableObject())
1972
      return createStringError(object_error::parse_failed,
1973
                               "no relocation found for DataRVA");
1974

1975
    // Locate the section that contains the address that DataRVA points at.
1976
    uint64_t VA = Entry.DataRVA + Obj->getImageBase();
1977
    for (const SectionRef &S : Obj->sections()) {
1978
      if (VA >= S.getAddress() &&
1979
          VA + Entry.DataSize <= S.getAddress() + S.getSize()) {
1980
        uint64_t Offset = VA - S.getAddress();
1981
        Expected<StringRef> Contents = S.getContents();
1982
        if (!Contents)
1983
          return Contents.takeError();
1984
        return Contents->slice(Offset, Offset + Entry.DataSize);
1985
      }
1986
    }
1987
    return createStringError(object_error::parse_failed,
1988
                             "address not found in image");
1989
  }
1990
}
1991

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.