LLVM  16.0.0git
COFFObjectFile.cpp
Go to the documentation of this file.
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/Triple.h"
18 #include "llvm/BinaryFormat/COFF.h"
19 #include "llvm/Object/Binary.h"
20 #include "llvm/Object/COFF.h"
21 #include "llvm/Object/Error.h"
22 #include "llvm/Object/ObjectFile.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/Error.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <cinttypes>
32 #include <cstddef>
33 #include <cstring>
34 #include <limits>
35 #include <memory>
36 #include <system_error>
37 
38 using namespace llvm;
39 using namespace object;
40 
45 
46 // Returns false if size is greater than the buffer size. And sets ec.
47 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
48  if (M.getBufferSize() < Size) {
50  return false;
51  }
52  return true;
53 }
54 
55 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
56 // Returns unexpected_eof if error.
57 template <typename T>
58 static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
59  const uint64_t Size = sizeof(T)) {
60  uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
61  if (Error E = Binary::checkOffset(M, Addr, Size))
62  return E;
63  Obj = reinterpret_cast<const T *>(Addr);
64  return Error::success();
65 }
66 
67 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
68 // prefixed slashes.
69 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
70  assert(Str.size() <= 6 && "String too long, possible overflow.");
71  if (Str.size() > 6)
72  return true;
73 
74  uint64_t Value = 0;
75  while (!Str.empty()) {
76  unsigned CharVal;
77  if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
78  CharVal = Str[0] - 'A';
79  else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
80  CharVal = Str[0] - 'a' + 26;
81  else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
82  CharVal = Str[0] - '0' + 52;
83  else if (Str[0] == '+') // 62
84  CharVal = 62;
85  else if (Str[0] == '/') // 63
86  CharVal = 63;
87  else
88  return true;
89 
90  Value = (Value * 64) + CharVal;
91  Str = Str.substr(1);
92  }
93 
95  return true;
96 
97  Result = static_cast<uint32_t>(Value);
98  return false;
99 }
100 
101 template <typename coff_symbol_type>
102 const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
103  const coff_symbol_type *Addr =
104  reinterpret_cast<const coff_symbol_type *>(Ref.p);
105 
106  assert(!checkOffset(Data, reinterpret_cast<uintptr_t>(Addr), sizeof(*Addr)));
107 #ifndef NDEBUG
108  // Verify that the symbol points to a valid entry in the symbol table.
109  uintptr_t Offset =
110  reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());
111 
112  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
113  "Symbol did not point to the beginning of a symbol");
114 #endif
115 
116  return Addr;
117 }
118 
119 const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
120  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
121 
122 #ifndef NDEBUG
123  // Verify that the section points to a valid entry in the section table.
124  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
125  report_fatal_error("Section was outside of section table.");
126 
127  uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -
128  reinterpret_cast<uintptr_t>(SectionTable);
129  assert(Offset % sizeof(coff_section) == 0 &&
130  "Section did not point to the beginning of a section");
131 #endif
132 
133  return Addr;
134 }
135 
137  auto End = reinterpret_cast<uintptr_t>(StringTable);
138  if (SymbolTable16) {
139  const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
140  Symb += 1 + Symb->NumberOfAuxSymbols;
141  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
142  } else if (SymbolTable32) {
143  const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
144  Symb += 1 + Symb->NumberOfAuxSymbols;
145  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
146  } else {
147  llvm_unreachable("no symbol table pointer!");
148  }
149 }
150 
152  return getSymbolName(getCOFFSymbol(Ref));
153 }
154 
156  return getCOFFSymbol(Ref).getValue();
157 }
158 
160  // MSVC/link.exe seems to align symbols to the next-power-of-2
161  // up to 32 bytes.
163  return std::min(uint64_t(32), PowerOf2Ceil(Symb.getValue()));
164 }
165 
167  uint64_t Result = cantFail(getSymbolValue(Ref));
169  int32_t SectionNumber = Symb.getSectionNumber();
170 
171  if (Symb.isAnyUndefined() || Symb.isCommon() ||
172  COFF::isReservedSectionNumber(SectionNumber))
173  return Result;
174 
175  Expected<const coff_section *> Section = getSection(SectionNumber);
176  if (!Section)
177  return Section.takeError();
178  Result += (*Section)->VirtualAddress;
179 
180  // The section VirtualAddress does not include ImageBase, and we want to
181  // return virtual addresses.
182  Result += getImageBase();
183 
184  return Result;
185 }
186 
189  int32_t SectionNumber = Symb.getSectionNumber();
190 
192  return SymbolRef::ST_Function;
193  if (Symb.isAnyUndefined())
194  return SymbolRef::ST_Unknown;
195  if (Symb.isCommon())
196  return SymbolRef::ST_Data;
197  if (Symb.isFileRecord())
198  return SymbolRef::ST_File;
199 
200  // TODO: perhaps we need a new symbol type ST_Section.
201  if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
202  return SymbolRef::ST_Debug;
203 
204  if (!COFF::isReservedSectionNumber(SectionNumber))
205  return SymbolRef::ST_Data;
206 
207  return SymbolRef::ST_Other;
208 }
209 
212  uint32_t Result = SymbolRef::SF_None;
213 
214  if (Symb.isExternal() || Symb.isWeakExternal())
215  Result |= SymbolRef::SF_Global;
216 
217  if (const coff_aux_weak_external *AWE = Symb.getWeakExternal()) {
218  Result |= SymbolRef::SF_Weak;
219  if (AWE->Characteristics != COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS)
220  Result |= SymbolRef::SF_Undefined;
221  }
222 
224  Result |= SymbolRef::SF_Absolute;
225 
226  if (Symb.isFileRecord())
228 
229  if (Symb.isSectionDefinition())
231 
232  if (Symb.isCommon())
233  Result |= SymbolRef::SF_Common;
234 
235  if (Symb.isUndefined())
236  Result |= SymbolRef::SF_Undefined;
237 
238  return Result;
239 }
240 
243  return Symb.getValue();
244 }
245 
250  return section_end();
252  if (!Sec)
253  return Sec.takeError();
255  Ret.p = reinterpret_cast<uintptr_t>(*Sec);
256  return section_iterator(SectionRef(Ret, this));
257 }
258 
261  return Symb.getSectionNumber();
262 }
263 
265  const coff_section *Sec = toSec(Ref);
266  Sec += 1;
267  Ref.p = reinterpret_cast<uintptr_t>(Sec);
268 }
269 
271  const coff_section *Sec = toSec(Ref);
272  return getSectionName(Sec);
273 }
274 
276  const coff_section *Sec = toSec(Ref);
277  uint64_t Result = Sec->VirtualAddress;
278 
279  // The section VirtualAddress does not include ImageBase, and we want to
280  // return virtual addresses.
281  Result += getImageBase();
282  return Result;
283 }
284 
286  return toSec(Sec) - SectionTable;
287 }
288 
290  return getSectionSize(toSec(Ref));
291 }
292 
294 COFFObjectFile::getSectionContents(DataRefImpl Ref) const {
295  const coff_section *Sec = toSec(Ref);
296  ArrayRef<uint8_t> Res;
297  if (Error E = getSectionContents(Sec, Res))
298  return std::move(E);
299  return Res;
300 }
301 
303  const coff_section *Sec = toSec(Ref);
304  return Sec->getAlignment();
305 }
306 
308  return false;
309 }
310 
312  const coff_section *Sec = toSec(Ref);
314 }
315 
317  const coff_section *Sec = toSec(Ref);
319 }
320 
322  const coff_section *Sec = toSec(Ref);
326  return (Sec->Characteristics & BssFlags) == BssFlags;
327 }
328 
329 // The .debug sections are the only debug sections for COFF
330 // (\see MCObjectFileInfo.cpp).
332  Expected<StringRef> SectionNameOrErr = getSectionName(Ref);
333  if (!SectionNameOrErr) {
334  // TODO: Report the error message properly.
335  consumeError(SectionNameOrErr.takeError());
336  return false;
337  }
338  StringRef SectionName = SectionNameOrErr.get();
339  return SectionName.startswith(".debug");
340 }
341 
343  uintptr_t Offset =
344  Sec.getRawDataRefImpl().p - reinterpret_cast<uintptr_t>(SectionTable);
345  assert((Offset % sizeof(coff_section)) == 0);
346  return (Offset / sizeof(coff_section)) + 1;
347 }
348 
350  const coff_section *Sec = toSec(Ref);
351  // In COFF, a virtual section won't have any in-file
352  // content, so the file pointer to the content will be zero.
353  return Sec->PointerToRawData == 0;
354 }
355 
356 static uint32_t getNumberOfRelocations(const coff_section *Sec,
357  MemoryBufferRef M, const uint8_t *base) {
358  // The field for the number of relocations in COFF section table is only
359  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
360  // NumberOfRelocations field, and the actual relocation count is stored in the
361  // VirtualAddress field in the first relocation entry.
362  if (Sec->hasExtendedRelocations()) {
363  const coff_relocation *FirstReloc;
364  if (Error E = getObject(FirstReloc, M,
365  reinterpret_cast<const coff_relocation *>(
366  base + Sec->PointerToRelocations))) {
368  return 0;
369  }
370  // -1 to exclude this first relocation entry.
371  return FirstReloc->VirtualAddress - 1;
372  }
373  return Sec->NumberOfRelocations;
374 }
375 
376 static const coff_relocation *
377 getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
378  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
379  if (!NumRelocs)
380  return nullptr;
381  auto begin = reinterpret_cast<const coff_relocation *>(
382  Base + Sec->PointerToRelocations);
383  if (Sec->hasExtendedRelocations()) {
384  // Skip the first relocation entry repurposed to store the number of
385  // relocations.
386  begin++;
387  }
388  if (auto E = Binary::checkOffset(M, reinterpret_cast<uintptr_t>(begin),
389  sizeof(coff_relocation) * NumRelocs)) {
391  return nullptr;
392  }
393  return begin;
394 }
395 
397  const coff_section *Sec = toSec(Ref);
398  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
399  if (begin && Sec->VirtualAddress != 0)
400  report_fatal_error("Sections with relocations should have an address of 0");
402  Ret.p = reinterpret_cast<uintptr_t>(begin);
403  return relocation_iterator(RelocationRef(Ret, this));
404 }
405 
407  const coff_section *Sec = toSec(Ref);
408  const coff_relocation *I = getFirstReloc(Sec, Data, base());
409  if (I)
410  I += getNumberOfRelocations(Sec, Data, base());
412  Ret.p = reinterpret_cast<uintptr_t>(I);
413  return relocation_iterator(RelocationRef(Ret, this));
414 }
415 
416 // Initialize the pointer to the symbol table.
417 Error COFFObjectFile::initSymbolTablePtr() {
418  if (COFFHeader)
419  if (Error E = getObject(
420  SymbolTable16, Data, base() + getPointerToSymbolTable(),
422  return E;
423 
424  if (COFFBigObjHeader)
425  if (Error E = getObject(
426  SymbolTable32, Data, base() + getPointerToSymbolTable(),
428  return E;
429 
430  // Find string table. The first four byte of the string table contains the
431  // total size of the string table, including the size field itself. If the
432  // string table is empty, the value of the first four byte would be 4.
435  const uint8_t *StringTableAddr = base() + StringTableOffset;
436  const ulittle32_t *StringTableSizePtr;
437  if (Error E = getObject(StringTableSizePtr, Data, StringTableAddr))
438  return E;
439  StringTableSize = *StringTableSizePtr;
440  if (Error E = getObject(StringTable, Data, StringTableAddr, StringTableSize))
441  return E;
442 
443  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
444  // tools like cvtres write a size of 0 for an empty table instead of 4.
445  if (StringTableSize < 4)
446  StringTableSize = 4;
447 
448  // Check that the string table is null terminated if has any in it.
449  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
451  "string table missing null terminator");
452  return Error::success();
453 }
454 
456  if (PE32Header)
457  return PE32Header->ImageBase;
458  else if (PE32PlusHeader)
459  return PE32PlusHeader->ImageBase;
460  // This actually comes up in practice.
461  return 0;
462 }
463 
464 // Returns the file offset for the given VA.
465 Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
466  uint64_t ImageBase = getImageBase();
467  uint64_t Rva = Addr - ImageBase;
468  assert(Rva <= UINT32_MAX);
469  return getRvaPtr((uint32_t)Rva, Res);
470 }
471 
472 // Returns the file offset for the given RVA.
474  const char *ErrorContext) const {
475  for (const SectionRef &S : sections()) {
476  const coff_section *Section = getCOFFSection(S);
477  uint32_t SectionStart = Section->VirtualAddress;
478  uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
479  if (SectionStart <= Addr && Addr < SectionEnd) {
480  // A table/directory entry can be pointing to somewhere in a stripped
481  // section, in an object that went through `objcopy --only-keep-debug`.
482  // In this case we don't want to cause the parsing of the object file to
483  // fail, otherwise it will be impossible to use this object as debug info
484  // in LLDB. Return SectionStrippedError here so that
485  // COFFObjectFile::initialize can ignore the error.
486  // Somewhat common binaries may have RVAs pointing outside of the
487  // provided raw data. Instead of rejecting the binaries, just
488  // treat the section as stripped for these purposes.
489  if (Section->SizeOfRawData < Section->VirtualSize &&
490  Addr >= SectionStart + Section->SizeOfRawData) {
491  return make_error<SectionStrippedError>();
492  }
493  uint32_t Offset = Addr - SectionStart;
494  Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
495  Offset;
496  return Error::success();
497  }
498  }
499  if (ErrorContext)
501  "RVA 0x%" PRIx32 " for %s not found", Addr,
502  ErrorContext);
504  "RVA 0x%" PRIx32 " not found", Addr);
505 }
506 
508  ArrayRef<uint8_t> &Contents,
509  const char *ErrorContext) const {
510  for (const SectionRef &S : sections()) {
511  const coff_section *Section = getCOFFSection(S);
512  uint32_t SectionStart = Section->VirtualAddress;
513  // Check if this RVA is within the section bounds. Be careful about integer
514  // overflow.
515  uint32_t OffsetIntoSection = RVA - SectionStart;
516  if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
517  Size <= Section->VirtualSize - OffsetIntoSection) {
518  uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +
519  Section->PointerToRawData + OffsetIntoSection;
520  Contents =
521  ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
522  return Error::success();
523  }
524  }
525  if (ErrorContext)
527  "RVA 0x%" PRIx32 " for %s not found", RVA,
528  ErrorContext);
530  "RVA 0x%" PRIx32 " not found", RVA);
531 }
532 
533 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
534 // table entry.
536  StringRef &Name) const {
537  uintptr_t IntPtr = 0;
538  if (Error E = getRvaPtr(Rva, IntPtr))
539  return E;
540  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
541  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
542  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
543  return Error::success();
544 }
545 
547  const codeview::DebugInfo *&PDBInfo,
548  StringRef &PDBFileName) const {
549  ArrayRef<uint8_t> InfoBytes;
550  if (Error E =
551  getRvaAndSizeAsBytes(DebugDir->AddressOfRawData, DebugDir->SizeOfData,
552  InfoBytes, "PDB info"))
553  return E;
554  if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
555  return createStringError(object_error::parse_failed, "PDB info too small");
556  PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
557  InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
558  PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
559  InfoBytes.size());
560  // Truncate the name at the first null byte. Ignore any padding.
561  PDBFileName = PDBFileName.split('\0').first;
562  return Error::success();
563 }
564 
566  StringRef &PDBFileName) const {
567  for (const debug_directory &D : debug_directories())
569  return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
570  // If we get here, there is no PDB info to return.
571  PDBInfo = nullptr;
572  PDBFileName = StringRef();
573  return Error::success();
574 }
575 
576 // Find the import table.
577 Error COFFObjectFile::initImportTablePtr() {
578  // First, we get the RVA of the import table. If the file lacks a pointer to
579  // the import table, do nothing.
580  const data_directory *DataEntry = getDataDirectory(COFF::IMPORT_TABLE);
581  if (!DataEntry)
582  return Error::success();
583 
584  // Do nothing if the pointer to import table is NULL.
585  if (DataEntry->RelativeVirtualAddress == 0)
586  return Error::success();
587 
588  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
589 
590  // Find the section that contains the RVA. This is needed because the RVA is
591  // the import table's memory address which is different from its file offset.
592  uintptr_t IntPtr = 0;
593  if (Error E = getRvaPtr(ImportTableRva, IntPtr, "import table"))
594  return E;
595  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
596  return E;
597  ImportDirectory = reinterpret_cast<
598  const coff_import_directory_table_entry *>(IntPtr);
599  return Error::success();
600 }
601 
602 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
603 Error COFFObjectFile::initDelayImportTablePtr() {
604  const data_directory *DataEntry =
606  if (!DataEntry)
607  return Error::success();
608  if (DataEntry->RelativeVirtualAddress == 0)
609  return Error::success();
610 
611  uint32_t RVA = DataEntry->RelativeVirtualAddress;
612  NumberOfDelayImportDirectory = DataEntry->Size /
613  sizeof(delay_import_directory_table_entry) - 1;
614 
615  uintptr_t IntPtr = 0;
616  if (Error E = getRvaPtr(RVA, IntPtr, "delay import table"))
617  return E;
618  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
619  return E;
620 
621  DelayImportDirectory = reinterpret_cast<
622  const delay_import_directory_table_entry *>(IntPtr);
623  return Error::success();
624 }
625 
626 // Find the export table.
627 Error COFFObjectFile::initExportTablePtr() {
628  // First, we get the RVA of the export table. If the file lacks a pointer to
629  // the export table, do nothing.
630  const data_directory *DataEntry = getDataDirectory(COFF::EXPORT_TABLE);
631  if (!DataEntry)
632  return Error::success();
633 
634  // Do nothing if the pointer to export table is NULL.
635  if (DataEntry->RelativeVirtualAddress == 0)
636  return Error::success();
637 
638  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
639  uintptr_t IntPtr = 0;
640  if (Error E = getRvaPtr(ExportTableRva, IntPtr, "export table"))
641  return E;
642  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
643  return E;
644 
645  ExportDirectory =
646  reinterpret_cast<const export_directory_table_entry *>(IntPtr);
647  return Error::success();
648 }
649 
650 Error COFFObjectFile::initBaseRelocPtr() {
651  const data_directory *DataEntry =
653  if (!DataEntry)
654  return Error::success();
655  if (DataEntry->RelativeVirtualAddress == 0)
656  return Error::success();
657 
658  uintptr_t IntPtr = 0;
659  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
660  "base reloc table"))
661  return E;
662  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
663  return E;
664 
665  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
666  IntPtr);
667  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
668  IntPtr + DataEntry->Size);
669  // FIXME: Verify the section containing BaseRelocHeader has at least
670  // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
671  return Error::success();
672 }
673 
674 Error COFFObjectFile::initDebugDirectoryPtr() {
675  // Get the RVA of the debug directory. Do nothing if it does not exist.
676  const data_directory *DataEntry = getDataDirectory(COFF::DEBUG_DIRECTORY);
677  if (!DataEntry)
678  return Error::success();
679 
680  // Do nothing if the RVA is NULL.
681  if (DataEntry->RelativeVirtualAddress == 0)
682  return Error::success();
683 
684  // Check that the size is a multiple of the entry size.
685  if (DataEntry->Size % sizeof(debug_directory) != 0)
687  "debug directory has uneven size");
688 
689  uintptr_t IntPtr = 0;
690  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
691  "debug directory"))
692  return E;
693  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
694  return E;
695 
696  DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
697  DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(
698  IntPtr + DataEntry->Size);
699  // FIXME: Verify the section containing DebugDirectoryBegin has at least
700  // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
701  return Error::success();
702 }
703 
704 Error COFFObjectFile::initTLSDirectoryPtr() {
705  // Get the RVA of the TLS directory. Do nothing if it does not exist.
706  const data_directory *DataEntry = getDataDirectory(COFF::TLS_TABLE);
707  if (!DataEntry)
708  return Error::success();
709 
710  // Do nothing if the RVA is NULL.
711  if (DataEntry->RelativeVirtualAddress == 0)
712  return Error::success();
713 
714  uint64_t DirSize =
715  is64() ? sizeof(coff_tls_directory64) : sizeof(coff_tls_directory32);
716 
717  // Check that the size is correct.
718  if (DataEntry->Size != DirSize)
719  return createStringError(
721  "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",
722  static_cast<uint32_t>(DataEntry->Size), DirSize);
723 
724  uintptr_t IntPtr = 0;
725  if (Error E =
726  getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr, "TLS directory"))
727  return E;
728  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
729  return E;
730 
731  if (is64())
732  TLSDirectory64 = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
733  else
734  TLSDirectory32 = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
735 
736  return Error::success();
737 }
738 
739 Error COFFObjectFile::initLoadConfigPtr() {
740  // Get the RVA of the debug directory. Do nothing if it does not exist.
741  const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
742  if (!DataEntry)
743  return Error::success();
744 
745  // Do nothing if the RVA is NULL.
746  if (DataEntry->RelativeVirtualAddress == 0)
747  return Error::success();
748  uintptr_t IntPtr = 0;
749  if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
750  "load config table"))
751  return E;
752  if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
753  return E;
754 
755  LoadConfig = (const void *)IntPtr;
756  return Error::success();
757 }
758 
761  std::unique_ptr<COFFObjectFile> Obj(new COFFObjectFile(std::move(Object)));
762  if (Error E = Obj->initialize())
763  return std::move(E);
764  return std::move(Obj);
765 }
766 
767 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
768  : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
769  COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
770  DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
771  SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
772  ImportDirectory(nullptr), DelayImportDirectory(nullptr),
773  NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),
774  BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
775  DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
776  TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
777 
779  if (E.isA<SectionStrippedError>()) {
781  return Error::success();
782  }
783  return E;
784 }
785 
786 Error COFFObjectFile::initialize() {
787  // Check that we at least have enough room for a header.
788  std::error_code EC;
789  if (!checkSize(Data, EC, sizeof(coff_file_header)))
790  return errorCodeToError(EC);
791 
792  // The current location in the file where we are looking at.
793  uint64_t CurPtr = 0;
794 
795  // PE header is optional and is present only in executables. If it exists,
796  // it is placed right after COFF header.
797  bool HasPEHeader = false;
798 
799  // Check if this is a PE/COFF file.
800  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
801  // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
802  // PE signature to find 'normal' COFF header.
803  const auto *DH = reinterpret_cast<const dos_header *>(base());
804  if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
805  CurPtr = DH->AddressOfNewExeHeader;
806  // Check the PE magic bytes. ("PE\0\0")
807  if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
809  "incorrect PE magic");
810  }
811  CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
812  HasPEHeader = true;
813  }
814  }
815 
816  if (Error E = getObject(COFFHeader, Data, base() + CurPtr))
817  return E;
818 
819  // It might be a bigobj file, let's check. Note that COFF bigobj and COFF
820  // import libraries share a common prefix but bigobj is more restrictive.
821  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
822  COFFHeader->NumberOfSections == uint16_t(0xffff) &&
823  checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
824  if (Error E = getObject(COFFBigObjHeader, Data, base() + CurPtr))
825  return E;
826 
827  // Verify that we are dealing with bigobj.
828  if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
829  std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
830  sizeof(COFF::BigObjMagic)) == 0) {
831  COFFHeader = nullptr;
832  CurPtr += sizeof(coff_bigobj_file_header);
833  } else {
834  // It's not a bigobj.
835  COFFBigObjHeader = nullptr;
836  }
837  }
838  if (COFFHeader) {
839  // The prior checkSize call may have failed. This isn't a hard error
840  // because we were just trying to sniff out bigobj.
841  EC = std::error_code();
842  CurPtr += sizeof(coff_file_header);
843 
844  if (COFFHeader->isImportLibrary())
845  return errorCodeToError(EC);
846  }
847 
848  if (HasPEHeader) {
849  const pe32_header *Header;
850  if (Error E = getObject(Header, Data, base() + CurPtr))
851  return E;
852 
853  const uint8_t *DataDirAddr;
854  uint64_t DataDirSize;
855  if (Header->Magic == COFF::PE32Header::PE32) {
856  PE32Header = Header;
857  DataDirAddr = base() + CurPtr + sizeof(pe32_header);
858  DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
859  } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
860  PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
861  DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
862  DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
863  } else {
864  // It's neither PE32 nor PE32+.
866  "incorrect PE magic");
867  }
868  if (Error E = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))
869  return E;
870  }
871 
872  if (COFFHeader)
873  CurPtr += COFFHeader->SizeOfOptionalHeader;
874 
875  assert(COFFHeader || COFFBigObjHeader);
876 
877  if (Error E =
878  getObject(SectionTable, Data, base() + CurPtr,
879  (uint64_t)getNumberOfSections() * sizeof(coff_section)))
880  return E;
881 
882  // Initialize the pointer to the symbol table.
883  if (getPointerToSymbolTable() != 0) {
884  if (Error E = initSymbolTablePtr()) {
885  // Recover from errors reading the symbol table.
887  SymbolTable16 = nullptr;
888  SymbolTable32 = nullptr;
889  StringTable = nullptr;
890  StringTableSize = 0;
891  }
892  } else {
893  // We had better not have any symbols if we don't have a symbol table.
894  if (getNumberOfSymbols() != 0) {
896  "symbol table missing");
897  }
898  }
899 
900  // Initialize the pointer to the beginning of the import table.
901  if (Error E = ignoreStrippedErrors(initImportTablePtr()))
902  return E;
903  if (Error E = ignoreStrippedErrors(initDelayImportTablePtr()))
904  return E;
905 
906  // Initialize the pointer to the export table.
907  if (Error E = ignoreStrippedErrors(initExportTablePtr()))
908  return E;
909 
910  // Initialize the pointer to the base relocation table.
911  if (Error E = ignoreStrippedErrors(initBaseRelocPtr()))
912  return E;
913 
914  // Initialize the pointer to the debug directory.
915  if (Error E = ignoreStrippedErrors(initDebugDirectoryPtr()))
916  return E;
917 
918  // Initialize the pointer to the TLS directory.
919  if (Error E = ignoreStrippedErrors(initTLSDirectoryPtr()))
920  return E;
921 
922  if (Error E = ignoreStrippedErrors(initLoadConfigPtr()))
923  return E;
924 
925  return Error::success();
926 }
927 
930  Ret.p = getSymbolTable();
931  return basic_symbol_iterator(SymbolRef(Ret, this));
932 }
933 
935  // The symbol table ends where the string table begins.
937  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
938  return basic_symbol_iterator(SymbolRef(Ret, this));
939 }
940 
942  if (!ImportDirectory)
943  return import_directory_end();
944  if (ImportDirectory->isNull())
945  return import_directory_end();
947  ImportDirectoryEntryRef(ImportDirectory, 0, this));
948 }
949 
952  ImportDirectoryEntryRef(nullptr, -1, this));
953 }
954 
958  DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
959 }
960 
965  DelayImportDirectory, NumberOfDelayImportDirectory, this));
966 }
967 
970  ExportDirectoryEntryRef(ExportDirectory, 0, this));
971 }
972 
974  if (!ExportDirectory)
975  return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
976  ExportDirectoryEntryRef Ref(ExportDirectory,
977  ExportDirectory->AddressTableEntries, this);
979 }
980 
983  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
984  return section_iterator(SectionRef(Ret, this));
985 }
986 
989  int NumSections =
990  COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
991  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
992  return section_iterator(SectionRef(Ret, this));
993 }
994 
996  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
997 }
998 
1000  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
1001 }
1002 
1004  return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4;
1005 }
1006 
1008  switch(getMachine()) {
1010  return "COFF-i386";
1012  return "COFF-x86-64";
1014  return "COFF-ARM";
1016  return "COFF-ARM64";
1018  return "COFF-ARM64EC";
1019  default:
1020  return "COFF-<unknown arch>";
1021  }
1022 }
1023 
1025  switch (getMachine()) {
1027  return Triple::x86;
1029  return Triple::x86_64;
1031  return Triple::thumb;
1034  return Triple::aarch64;
1035  default:
1036  return Triple::UnknownArch;
1037  }
1038 }
1039 
1041  if (PE32Header)
1042  return PE32Header->AddressOfEntryPoint;
1043  return 0;
1044 }
1045 
1049 }
1050 
1055 }
1056 
1060 }
1061 
1064 }
1065 
1067  if (!DataDirectory)
1068  return nullptr;
1069  assert(PE32Header || PE32PlusHeader);
1070  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
1071  : PE32PlusHeader->NumberOfRvaAndSize;
1072  if (Index >= NumEnt)
1073  return nullptr;
1074  return &DataDirectory[Index];
1075 }
1076 
1078  // Perhaps getting the section of a reserved section index should be an error,
1079  // but callers rely on this to return null.
1081  return (const coff_section *)nullptr;
1082  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
1083  // We already verified the section table data, so no need to check again.
1084  return SectionTable + (Index - 1);
1085  }
1087  "section index out of bounds");
1088 }
1089 
1090 Expected<StringRef> COFFObjectFile::getString(uint32_t Offset) const {
1091  if (StringTableSize <= 4)
1092  // Tried to get a string from an empty string table.
1093  return createStringError(object_error::parse_failed, "string table empty");
1094  if (Offset >= StringTableSize)
1096  return StringRef(StringTable + Offset);
1097 }
1098 
1100  return getSymbolName(Symbol.getGeneric());
1101 }
1102 
1105  // Check for string table entry. First 4 bytes are 0.
1106  if (Symbol->Name.Offset.Zeroes == 0)
1107  return getString(Symbol->Name.Offset.Offset);
1108 
1109  // Null terminated, let ::strlen figure out the length.
1110  if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
1111  return StringRef(Symbol->Name.ShortName);
1112 
1113  // Not null terminated, use all 8 bytes.
1114  return StringRef(Symbol->Name.ShortName, COFF::NameSize);
1115 }
1116 
1119  const uint8_t *Aux = nullptr;
1120 
1121  size_t SymbolSize = getSymbolTableEntrySize();
1122  if (Symbol.getNumberOfAuxSymbols() > 0) {
1123  // AUX data comes immediately after the symbol in COFF
1124  Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
1125 #ifndef NDEBUG
1126  // Verify that the Aux symbol points to a valid entry in the symbol table.
1127  uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
1128  if (Offset < getPointerToSymbolTable() ||
1129  Offset >=
1130  getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
1131  report_fatal_error("Aux Symbol data was outside of symbol table.");
1132 
1133  assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
1134  "Aux Symbol data did not point to the beginning of a symbol");
1135 #endif
1136  }
1137  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
1138 }
1139 
1141  uintptr_t Offset =
1142  reinterpret_cast<uintptr_t>(Symbol.getRawPtr()) - getSymbolTable();
1143  assert(Offset % getSymbolTableEntrySize() == 0 &&
1144  "Symbol did not point to the beginning of a symbol");
1145  size_t Index = Offset / getSymbolTableEntrySize();
1147  return Index;
1148 }
1149 
1152  StringRef Name = StringRef(Sec->Name, COFF::NameSize).split('\0').first;
1153 
1154  // Check for string table entry. First byte is '/'.
1155  if (Name.startswith("/")) {
1156  uint32_t Offset;
1157  if (Name.startswith("//")) {
1158  if (decodeBase64StringEntry(Name.substr(2), Offset))
1160  "invalid section name");
1161  } else {
1162  if (Name.substr(1).getAsInteger(10, Offset))
1164  "invalid section name");
1165  }
1166  return getString(Offset);
1167  }
1168 
1169  return Name;
1170 }
1171 
1173  // SizeOfRawData and VirtualSize change what they represent depending on
1174  // whether or not we have an executable image.
1175  //
1176  // For object files, SizeOfRawData contains the size of section's data;
1177  // VirtualSize should be zero but isn't due to buggy COFF writers.
1178  //
1179  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
1180  // actual section size is in VirtualSize. It is possible for VirtualSize to
1181  // be greater than SizeOfRawData; the contents past that point should be
1182  // considered to be zero.
1183  if (getDOSHeader())
1184  return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
1185  return Sec->SizeOfRawData;
1186 }
1187 
1189  ArrayRef<uint8_t> &Res) const {
1190  // In COFF, a virtual section won't have any in-file
1191  // content, so the file pointer to the content will be zero.
1192  if (Sec->PointerToRawData == 0)
1193  return Error::success();
1194  // The only thing that we need to verify is that the contents is contained
1195  // within the file bounds. We don't need to make sure it doesn't cover other
1196  // data, as there's nothing that says that is not allowed.
1197  uintptr_t ConStart =
1198  reinterpret_cast<uintptr_t>(base()) + Sec->PointerToRawData;
1200  if (Error E = checkOffset(Data, ConStart, SectionSize))
1201  return E;
1202  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
1203  return Error::success();
1204 }
1205 
1206 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
1207  return reinterpret_cast<const coff_relocation*>(Rel.p);
1208 }
1209 
1211  Rel.p = reinterpret_cast<uintptr_t>(
1212  reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
1213 }
1214 
1216  const coff_relocation *R = toRel(Rel);
1217  return R->VirtualAddress;
1218 }
1219 
1221  const coff_relocation *R = toRel(Rel);
1222  DataRefImpl Ref;
1223  if (R->SymbolTableIndex >= getNumberOfSymbols())
1224  return symbol_end();
1225  if (SymbolTable16)
1226  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
1227  else if (SymbolTable32)
1228  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
1229  else
1230  llvm_unreachable("no symbol table pointer!");
1231  return symbol_iterator(SymbolRef(Ref, this));
1232 }
1233 
1235  const coff_relocation* R = toRel(Rel);
1236  return R->Type;
1237 }
1238 
1239 const coff_section *
1241  return toSec(Section.getRawDataRefImpl());
1242 }
1243 
1245  if (SymbolTable16)
1246  return toSymb<coff_symbol16>(Ref);
1247  if (SymbolTable32)
1248  return toSymb<coff_symbol32>(Ref);
1249  llvm_unreachable("no symbol table pointer!");
1250 }
1251 
1253  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1254 }
1255 
1256 const coff_relocation *
1258  return toRel(Reloc.getRawDataRefImpl());
1259 }
1260 
1263  return {getFirstReloc(Sec, Data, base()),
1264  getNumberOfRelocations(Sec, Data, base())};
1265 }
1266 
1267 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
1268  case COFF::reloc_type: \
1269  return #reloc_type;
1270 
1272  switch (getMachine()) {
1274  switch (Type) {
1292  default:
1293  return "Unknown";
1294  }
1295  break;
1297  switch (Type) {
1315  default:
1316  return "Unknown";
1317  }
1318  break;
1321  switch (Type) {
1340  default:
1341  return "Unknown";
1342  }
1343  break;
1345  switch (Type) {
1357  default:
1358  return "Unknown";
1359  }
1360  break;
1361  default:
1362  return "Unknown";
1363  }
1364 }
1365 
1366 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1367 
1369  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1370  const coff_relocation *Reloc = toRel(Rel);
1371  StringRef Res = getRelocationTypeName(Reloc->Type);
1372  Result.append(Res.begin(), Res.end());
1373 }
1374 
1376  return !DataDirectory;
1377 }
1378 
1381  .Case("eh_fram", "eh_frame")
1382  .Default(Name);
1383 }
1384 
1387  return ImportTable == Other.ImportTable && Index == Other.Index;
1388 }
1389 
1391  ++Index;
1392  if (ImportTable[Index].isNull()) {
1393  Index = -1;
1394  ImportTable = nullptr;
1395  }
1396 }
1397 
1399  const coff_import_directory_table_entry *&Result) const {
1400  return getObject(Result, OwningObject->Data, ImportTable + Index);
1401 }
1402 
1404 makeImportedSymbolIterator(const COFFObjectFile *Object,
1405  uintptr_t Ptr, int Index) {
1406  if (Object->getBytesInAddress() == 4) {
1407  auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
1408  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1409  }
1410  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
1411  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1412 }
1413 
1415 importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
1416  uintptr_t IntPtr = 0;
1417  // FIXME: Handle errors.
1418  cantFail(Object->getRvaPtr(RVA, IntPtr));
1419  return makeImportedSymbolIterator(Object, IntPtr, 0);
1420 }
1421 
1423 importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
1424  uintptr_t IntPtr = 0;
1425  // FIXME: Handle errors.
1426  cantFail(Object->getRvaPtr(RVA, IntPtr));
1427  // Forward the pointer to the last entry which is null.
1428  int Index = 0;
1429  if (Object->getBytesInAddress() == 4) {
1430  auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
1431  while (*Entry++)
1432  ++Index;
1433  } else {
1434  auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
1435  while (*Entry++)
1436  ++Index;
1437  }
1438  return makeImportedSymbolIterator(Object, IntPtr, Index);
1439 }
1440 
1443  return importedSymbolBegin(ImportTable[Index].ImportAddressTableRVA,
1444  OwningObject);
1445 }
1446 
1449  return importedSymbolEnd(ImportTable[Index].ImportAddressTableRVA,
1450  OwningObject);
1451 }
1452 
1456 }
1457 
1459  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
1460  OwningObject);
1461 }
1462 
1464  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
1465  OwningObject);
1466 }
1467 
1471 }
1472 
1474  uintptr_t IntPtr = 0;
1475  if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr,
1476  "import directory name"))
1477  return E;
1478  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1479  return Error::success();
1480 }
1481 
1482 Error
1484  Result = ImportTable[Index].ImportLookupTableRVA;
1485  return Error::success();
1486 }
1487 
1489  uint32_t &Result) const {
1490  Result = ImportTable[Index].ImportAddressTableRVA;
1491  return Error::success();
1492 }
1493 
1496  return Table == Other.Table && Index == Other.Index;
1497 }
1498 
1500  ++Index;
1501 }
1502 
1505  return importedSymbolBegin(Table[Index].DelayImportNameTable,
1506  OwningObject);
1507 }
1508 
1511  return importedSymbolEnd(Table[Index].DelayImportNameTable,
1512  OwningObject);
1513 }
1514 
1518 }
1519 
1521  uintptr_t IntPtr = 0;
1522  if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr,
1523  "delay import directory name"))
1524  return E;
1525  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1526  return Error::success();
1527 }
1528 
1530  const delay_import_directory_table_entry *&Result) const {
1531  Result = &Table[Index];
1532  return Error::success();
1533 }
1534 
1536  uint64_t &Result) const {
1537  uint32_t RVA = Table[Index].DelayImportAddressTable +
1538  AddrIndex * (OwningObject->is64() ? 8 : 4);
1539  uintptr_t IntPtr = 0;
1540  if (Error E = OwningObject->getRvaPtr(RVA, IntPtr, "import address"))
1541  return E;
1542  if (OwningObject->is64())
1543  Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1544  else
1545  Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1546  return Error::success();
1547 }
1548 
1551  return ExportTable == Other.ExportTable && Index == Other.Index;
1552 }
1553 
1555  ++Index;
1556 }
1557 
1558 // Returns the name of the current export symbol. If the symbol is exported only
1559 // by ordinal, the empty string is set as a result.
1561  uintptr_t IntPtr = 0;
1562  if (Error E =
1563  OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr, "dll name"))
1564  return E;
1565  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1566  return Error::success();
1567 }
1568 
1569 // Returns the starting ordinal number.
1571  Result = ExportTable->OrdinalBase;
1572  return Error::success();
1573 }
1574 
1575 // Returns the export ordinal of the current export symbol.
1577  Result = ExportTable->OrdinalBase + Index;
1578  return Error::success();
1579 }
1580 
1581 // Returns the address of the current export symbol.
1583  uintptr_t IntPtr = 0;
1584  if (Error EC = OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA,
1585  IntPtr, "export address"))
1586  return EC;
1588  reinterpret_cast<const export_address_table_entry *>(IntPtr);
1589  Result = entry[Index].ExportRVA;
1590  return Error::success();
1591 }
1592 
1593 // Returns the name of the current export symbol. If the symbol is exported only
1594 // by ordinal, the empty string is set as a result.
1595 Error
1597  uintptr_t IntPtr = 0;
1598  if (Error EC = OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr,
1599  "export ordinal table"))
1600  return EC;
1601  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
1602 
1603  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
1604  int Offset = 0;
1605  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
1606  I < E; ++I, ++Offset) {
1607  if (*I != Index)
1608  continue;
1609  if (Error EC = OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr,
1610  "export table entry"))
1611  return EC;
1612  const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1613  if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr,
1614  "export symbol name"))
1615  return EC;
1616  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1617  return Error::success();
1618  }
1619  Result = "";
1620  return Error::success();
1621 }
1622 
1624  const data_directory *DataEntry =
1625  OwningObject->getDataDirectory(COFF::EXPORT_TABLE);
1626  if (!DataEntry)
1628  "export table missing");
1629  uint32_t RVA;
1630  if (auto EC = getExportRVA(RVA))
1631  return EC;
1632  uint32_t Begin = DataEntry->RelativeVirtualAddress;
1633  uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
1634  Result = (Begin <= RVA && RVA < End);
1635  return Error::success();
1636 }
1637 
1639  uint32_t RVA;
1640  if (auto EC = getExportRVA(RVA))
1641  return EC;
1642  uintptr_t IntPtr = 0;
1643  if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr, "export forward target"))
1644  return EC;
1645  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1646  return Error::success();
1647 }
1648 
1650 operator==(const ImportedSymbolRef &Other) const {
1651  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1652  && Index == Other.Index;
1653 }
1654 
1656  ++Index;
1657 }
1658 
1660  uint32_t RVA;
1661  if (Entry32) {
1662  // If a symbol is imported only by ordinal, it has no name.
1663  if (Entry32[Index].isOrdinal())
1664  return Error::success();
1665  RVA = Entry32[Index].getHintNameRVA();
1666  } else {
1667  if (Entry64[Index].isOrdinal())
1668  return Error::success();
1669  RVA = Entry64[Index].getHintNameRVA();
1670  }
1671  uintptr_t IntPtr = 0;
1672  if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol name"))
1673  return EC;
1674  // +2 because the first two bytes is hint.
1675  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1676  return Error::success();
1677 }
1678 
1680  if (Entry32)
1681  Result = Entry32[Index].isOrdinal();
1682  else
1683  Result = Entry64[Index].isOrdinal();
1684  return Error::success();
1685 }
1686 
1688  if (Entry32)
1689  Result = Entry32[Index].getHintNameRVA();
1690  else
1691  Result = Entry64[Index].getHintNameRVA();
1692  return Error::success();
1693 }
1694 
1696  uint32_t RVA;
1697  if (Entry32) {
1698  if (Entry32[Index].isOrdinal()) {
1699  Result = Entry32[Index].getOrdinal();
1700  return Error::success();
1701  }
1702  RVA = Entry32[Index].getHintNameRVA();
1703  } else {
1704  if (Entry64[Index].isOrdinal()) {
1705  Result = Entry64[Index].getOrdinal();
1706  return Error::success();
1707  }
1708  RVA = Entry64[Index].getHintNameRVA();
1709  }
1710  uintptr_t IntPtr = 0;
1711  if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol ordinal"))
1712  return EC;
1713  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1714  return Error::success();
1715 }
1716 
1720 }
1721 
1722 bool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
1723  return Header == Other.Header && Index == Other.Index;
1724 }
1725 
1727  // Header->BlockSize is the size of the current block, including the
1728  // size of the header itself.
1729  uint32_t Size = sizeof(*Header) +
1730  sizeof(coff_base_reloc_block_entry) * (Index + 1);
1731  if (Size == Header->BlockSize) {
1732  // .reloc contains a list of base relocation blocks. Each block
1733  // consists of the header followed by entries. The header contains
1734  // how many entories will follow. When we reach the end of the
1735  // current block, proceed to the next block.
1736  Header = reinterpret_cast<const coff_base_reloc_block_header *>(
1737  reinterpret_cast<const uint8_t *>(Header) + Size);
1738  Index = 0;
1739  } else {
1740  ++Index;
1741  }
1742 }
1743 
1745  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1746  Type = Entry[Index].getType();
1747  return Error::success();
1748 }
1749 
1751  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1752  Result = Header->PageRVA + Entry[Index].getOffset();
1753  return Error::success();
1754 }
1755 
1756 #define RETURN_IF_ERROR(Expr) \
1757  do { \
1758  Error E = (Expr); \
1759  if (E) \
1760  return std::move(E); \
1761  } while (0)
1762 
1764 ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {
1765  BinaryStreamReader Reader = BinaryStreamReader(BBS);
1766  Reader.setOffset(Offset);
1767  uint16_t Length;
1768  RETURN_IF_ERROR(Reader.readInteger(Length));
1769  ArrayRef<UTF16> RawDirString;
1770  RETURN_IF_ERROR(Reader.readArray(RawDirString, Length));
1771  return RawDirString;
1772 }
1773 
1776  return getDirStringAtOffset(Entry.Identifier.getNameOffset());
1777 }
1778 
1780 ResourceSectionRef::getTableAtOffset(uint32_t Offset) {
1781  const coff_resource_dir_table *Table = nullptr;
1782 
1783  BinaryStreamReader Reader(BBS);
1784  Reader.setOffset(Offset);
1785  RETURN_IF_ERROR(Reader.readObject(Table));
1786  assert(Table != nullptr);
1787  return *Table;
1788 }
1789 
1791 ResourceSectionRef::getTableEntryAtOffset(uint32_t Offset) {
1792  const coff_resource_dir_entry *Entry = nullptr;
1793 
1794  BinaryStreamReader Reader(BBS);
1795  Reader.setOffset(Offset);
1796  RETURN_IF_ERROR(Reader.readObject(Entry));
1797  assert(Entry != nullptr);
1798  return *Entry;
1799 }
1800 
1802 ResourceSectionRef::getDataEntryAtOffset(uint32_t Offset) {
1803  const coff_resource_data_entry *Entry = nullptr;
1804 
1805  BinaryStreamReader Reader(BBS);
1806  Reader.setOffset(Offset);
1807  RETURN_IF_ERROR(Reader.readObject(Entry));
1808  assert(Entry != nullptr);
1809  return *Entry;
1810 }
1811 
1814  assert(Entry.Offset.isSubDir());
1815  return getTableAtOffset(Entry.Offset.value());
1816 }
1817 
1820  assert(!Entry.Offset.isSubDir());
1821  return getDataEntryAtOffset(Entry.Offset.value());
1822 }
1823 
1825  return getTableAtOffset(0);
1826 }
1827 
1830  uint32_t Index) {
1831  if (Index >= (uint32_t)(Table.NumberOfNameEntries + Table.NumberOfIDEntries))
1832  return createStringError(object_error::parse_failed, "index out of range");
1833  const uint8_t *TablePtr = reinterpret_cast<const uint8_t *>(&Table);
1834  ptrdiff_t TableOffset = TablePtr - BBS.data().data();
1835  return getTableEntryAtOffset(TableOffset + sizeof(Table) +
1836  Index * sizeof(coff_resource_dir_entry));
1837 }
1838 
1840  for (const SectionRef &S : O->sections()) {
1841  Expected<StringRef> Name = S.getName();
1842  if (!Name)
1843  return Name.takeError();
1844 
1845  if (*Name == ".rsrc" || *Name == ".rsrc$01")
1846  return load(O, S);
1847  }
1849  "no resource section found");
1850 }
1851 
1853  Obj = O;
1854  Section = S;
1855  Expected<StringRef> Contents = Section.getContents();
1856  if (!Contents)
1857  return Contents.takeError();
1858  BBS = BinaryByteStream(*Contents, support::little);
1859  const coff_section *COFFSect = Obj->getCOFFSection(Section);
1860  ArrayRef<coff_relocation> OrigRelocs = Obj->getRelocations(COFFSect);
1861  Relocs.reserve(OrigRelocs.size());
1862  for (const coff_relocation &R : OrigRelocs)
1863  Relocs.push_back(&R);
1864  llvm::sort(Relocs, [](const coff_relocation *A, const coff_relocation *B) {
1865  return A->VirtualAddress < B->VirtualAddress;
1866  });
1867  return Error::success();
1868 }
1869 
1872  if (!Obj)
1873  return createStringError(object_error::parse_failed, "no object provided");
1874 
1875  // Find a potential relocation at the DataRVA field (first member of
1876  // the coff_resource_data_entry struct).
1877  const uint8_t *EntryPtr = reinterpret_cast<const uint8_t *>(&Entry);
1878  ptrdiff_t EntryOffset = EntryPtr - BBS.data().data();
1879  coff_relocation RelocTarget{ulittle32_t(EntryOffset), ulittle32_t(0),
1880  ulittle16_t(0)};
1881  auto RelocsForOffset =
1882  std::equal_range(Relocs.begin(), Relocs.end(), &RelocTarget,
1883  [](const coff_relocation *A, const coff_relocation *B) {
1884  return A->VirtualAddress < B->VirtualAddress;
1885  });
1886 
1887  if (RelocsForOffset.first != RelocsForOffset.second) {
1888  // We found a relocation with the right offset. Check that it does have
1889  // the expected type.
1890  const coff_relocation &R = **RelocsForOffset.first;
1891  uint16_t RVAReloc;
1892  switch (Obj->getMachine()) {
1894  RVAReloc = COFF::IMAGE_REL_I386_DIR32NB;
1895  break;
1897  RVAReloc = COFF::IMAGE_REL_AMD64_ADDR32NB;
1898  break;
1900  RVAReloc = COFF::IMAGE_REL_ARM_ADDR32NB;
1901  break;
1904  RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB;
1905  break;
1906  default:
1908  "unsupported architecture");
1909  }
1910  if (R.Type != RVAReloc)
1912  "unexpected relocation type");
1913  // Get the relocation's symbol
1914  Expected<COFFSymbolRef> Sym = Obj->getSymbol(R.SymbolTableIndex);
1915  if (!Sym)
1916  return Sym.takeError();
1917  // And the symbol's section
1919  Obj->getSection(Sym->getSectionNumber());
1920  if (!Section)
1921  return Section.takeError();
1922  // Add the initial value of DataRVA to the symbol's offset to find the
1923  // data it points at.
1924  uint64_t Offset = Entry.DataRVA + Sym->getValue();
1925  ArrayRef<uint8_t> Contents;
1926  if (Error E = Obj->getSectionContents(*Section, Contents))
1927  return std::move(E);
1928  if (Offset + Entry.DataSize > Contents.size())
1930  "data outside of section");
1931  // Return a reference to the data inside the section.
1932  return StringRef(reinterpret_cast<const char *>(Contents.data()) + Offset,
1933  Entry.DataSize);
1934  } else {
1935  // Relocatable objects need a relocation for the DataRVA field.
1936  if (Obj->isRelocatableObject())
1938  "no relocation found for DataRVA");
1939 
1940  // Locate the section that contains the address that DataRVA points at.
1941  uint64_t VA = Entry.DataRVA + Obj->getImageBase();
1942  for (const SectionRef &S : Obj->sections()) {
1943  if (VA >= S.getAddress() &&
1944  VA + Entry.DataSize <= S.getAddress() + S.getSize()) {
1945  uint64_t Offset = VA - S.getAddress();
1946  Expected<StringRef> Contents = S.getContents();
1947  if (!Contents)
1948  return Contents.takeError();
1949  return Contents->slice(Offset, Offset + Entry.DataSize);
1950  }
1951  }
1953  "address not found in image");
1954  }
1955 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm::object::COFFObjectFile::base_relocs
iterator_range< base_reloc_iterator > base_relocs() const
Definition: COFFObjectFile.cpp:1062
llvm::object::object_error::unexpected_eof
@ unexpected_eof
BinaryStreamReader.h
llvm::object::COFFObjectFile::getBytesInAddress
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
Definition: COFFObjectFile.cpp:1003
llvm::object::DelayImportDirectoryEntryRef::imported_symbol_begin
imported_symbol_iterator imported_symbol_begin() const
Definition: COFFObjectFile.cpp:1504
llvm::object::DelayImportDirectoryEntryRef::getName
Error getName(StringRef &Result) const
Definition: COFFObjectFile.cpp:1520
llvm::object::COFFObjectFile::getSectionAlignment
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:302
llvm::object::BaseRelocRef::getRVA
Error getRVA(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1750
llvm::COFF::IMAGE_REL_I386_SECTION
@ IMAGE_REL_I386_SECTION
Definition: COFF.h:338
llvm::COFF::IMAGE_REL_AMD64_PAIR
@ IMAGE_REL_AMD64_PAIR
Definition: COFF.h:361
llvm::object::coff_base_reloc_block_entry
Definition: COFF.h:736
llvm::COFF::IMAGE_REL_AMD64_ADDR32
@ IMAGE_REL_AMD64_ADDR32
Definition: COFF.h:348
llvm::BinaryStreamReader::setOffset
void setOffset(uint64_t Off)
Definition: BinaryStreamReader.h:247
llvm::COFF::BigObjHeader::MinBigObjectVersion
@ MinBigObjectVersion
Definition: COFF.h:75
llvm::object::debug_directory::SizeOfData
support::ulittle32_t SizeOfData
Definition: COFF.h:183
llvm::COFF::IMAGE_REL_ARM64_SECREL
@ IMAGE_REL_ARM64_SECREL
Definition: COFF.h:394
MathExtras.h
llvm::object::import_lookup_table_entry64
import_lookup_table_entry< support::little64_t > import_lookup_table_entry64
Definition: COFF.h:208
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition: COFF.h:290
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::object::COFFObjectFile::getSymbolAddress
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:166
llvm::object::COFFObjectFile::ExportDirectoryEntryRef
friend class ExportDirectoryEntryRef
Definition: COFF.h:793
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::COFF::IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_ADDR32NB
Definition: COFF.h:388
llvm::object::delay_import_directory_table_entry::DelayImportAddressTable
support::ulittle32_t DelayImportAddressTable
Definition: COFF.h:215
llvm::object::COFFObjectFile::section_begin
section_iterator section_begin() const override
Definition: COFFObjectFile.cpp:981
llvm::object::COFFSymbolRef::getWeakExternal
const coff_aux_weak_external * getWeakExternal() const
Definition: COFF.h:366
llvm::object::COFFSymbolRef::getSectionNumber
int32_t getSectionNumber() const
Definition: COFF.h:322
llvm::object::COFFObjectFile::getRelocationType
uint64_t getRelocationType(DataRefImpl Rel) const override
Definition: COFFObjectFile.cpp:1234
llvm::Triple::UnknownArch
@ UnknownArch
Definition: Triple.h:47
llvm::object::COFFObjectFile::getCOFFRelocation
const coff_relocation * getCOFFRelocation(const RelocationRef &Reloc) const
Definition: COFFObjectFile.cpp:1257
getFirstReloc
static const coff_relocation * getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base)
Definition: COFFObjectFile.cpp:377
importedSymbolEnd
static imported_symbol_iterator importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object)
Definition: COFFObjectFile.cpp:1423
llvm::object::COFFObjectFile::getSectionAddress
uint64_t getSectionAddress(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:275
llvm::object::COFFObjectFile::getDataDirectory
const data_directory * getDataDirectory(uint32_t index) const
Definition: COFFObjectFile.cpp:1066
llvm::object::COFFObjectFile::getHintName
Error getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const
Definition: COFFObjectFile.cpp:535
llvm::COFF::IMAGE_REL_ARM64_PAGEBASE_REL21
@ IMAGE_REL_ARM64_PAGEBASE_REL21
Definition: COFF.h:390
llvm::object::coff_section::VirtualAddress
support::ulittle32_t VirtualAddress
Definition: COFF.h:443
llvm::object::COFFObjectFile::isSectionVirtual
bool isSectionVirtual(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:349
T
llvm::object::COFFObjectFile::getCommonSymbolSizeImpl
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:241
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::object::coff_file_header::Machine
support::ulittle16_t Machine
Definition: COFF.h:76
llvm::object::BasicSymbolRef::SF_Common
@ SF_Common
Definition: SymbolicFile.h:114
llvm::Triple::x86
@ x86
Definition: Triple.h:85
llvm::object::coff_tls_directory32
coff_tls_directory< support::little32_t > coff_tls_directory32
Definition: COFF.h:597
llvm::object::ObjectFile::RelocationRef
friend class RelocationRef
Definition: ObjectFile.h:286
llvm::object::ImportedSymbolRef::moveNext
void moveNext()
Definition: COFFObjectFile.cpp:1655
RETURN_IF_ERROR
#define RETURN_IF_ERROR(Expr)
Definition: COFFObjectFile.cpp:1756
llvm::object::export_directory_table_entry::OrdinalTableRVA
support::ulittle32_t OrdinalTableRVA
Definition: COFF.h:233
llvm::object::COFFObjectFile::debug_directories
iterator_range< const debug_directory * > debug_directories() const
Definition: COFF.h:1001
LLVM_COFF_SWITCH_RELOC_TYPE_NAME
#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)
Definition: COFFObjectFile.cpp:1267
llvm::COFF::IMAGE_REL_ARM64_PAGEOFFSET_12L
@ IMAGE_REL_ARM64_PAGEOFFSET_12L
Definition: COFF.h:393
llvm::object::COFFObjectFile::getStartAddress
Expected< uint64_t > getStartAddress() const override
Definition: COFFObjectFile.cpp:1040
llvm::object::COFFObjectFile::getSymbolSection
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:247
llvm::object::ImportDirectoryEntryRef::getImportAddressTableRVA
Error getImportAddressTableRVA(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1488
llvm::object::coff_section::getAlignment
uint32_t getAlignment() const
Definition: COFF.h:459
llvm::object::SectionRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:536
llvm::object::COFFObjectFile::import_directories
iterator_range< import_directory_iterator > import_directories() const
Definition: COFFObjectFile.cpp:1047
ErrorHandling.h
llvm::object::COFFObjectFile::section_rel_end
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:406
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::COFF::IMAGE_REL_I386_ABSOLUTE
@ IMAGE_REL_I386_ABSOLUTE
Definition: COFF.h:332
llvm::COFF::IMAGE_REL_ARM_MOV32A
@ IMAGE_REL_ARM_MOV32A
Definition: COFF.h:377
llvm::object::BaseRelocRef::operator==
bool operator==(const BaseRelocRef &Other) const
Definition: COFFObjectFile.cpp:1722
llvm::COFF::IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN
@ IMAGE_FILE_MACHINE_UNKNOWN
Definition: COFF.h:95
memcmp
Merge contiguous icmps into a memcmp
Definition: MergeICmps.cpp:899
Error.h
llvm::COFF::IMAGE_REL_ARM64_REL21
@ IMAGE_REL_ARM64_REL21
Definition: COFF.h:391
llvm::object::COFFObjectFile::getSectionID
unsigned getSectionID(SectionRef Sec) const
Definition: COFFObjectFile.cpp:342
COFF.h
llvm::object::COFFObjectFile::getVaPtr
Error getVaPtr(uint64_t VA, uintptr_t &Res) const
Definition: COFFObjectFile.cpp:465
llvm::object::ObjectFile::getSymbolValue
Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:56
llvm::object::ResourceSectionRef::getTableEntry
Expected< const coff_resource_dir_entry & > getTableEntry(const coff_resource_dir_table &Table, uint32_t Index)
Definition: COFFObjectFile.cpp:1829
llvm::object::relocation_iterator
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:76
llvm::object::import_lookup_table_entry::getOrdinal
uint16_t getOrdinal() const
Definition: COFF.h:194
MemoryBufferRef.h
llvm::object::ExportDirectoryEntryRef::getSymbolName
Error getSymbolName(StringRef &Result) const
Definition: COFFObjectFile.cpp:1596
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::COFF::IMAGE_REL_I386_DIR32NB
@ IMAGE_REL_I386_DIR32NB
Definition: COFF.h:336
llvm::object::SymbolRef::ST_Unknown
@ ST_Unknown
Definition: ObjectFile.h:172
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::COFF::IMAGE_REL_AMD64_REL32
@ IMAGE_REL_AMD64_REL32
Definition: COFF.h:350
llvm::object::ImportDirectoryEntryRef::lookup_table_begin
imported_symbol_iterator lookup_table_begin() const
Definition: COFFObjectFile.cpp:1458
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
llvm::object::getObject
static Expected< const T * > getObject(MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
Definition: XCOFFObjectFile.cpp:33
llvm::object::ObjectFile::createCOFFObjectFile
static Expected< std::unique_ptr< COFFObjectFile > > createCOFFObjectFile(MemoryBufferRef Object)
Definition: COFFObjectFile.cpp:1718
llvm::COFF::IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
getNumberOfRelocations
static uint32_t getNumberOfRelocations(const coff_section *Sec, MemoryBufferRef M, const uint8_t *base)
Definition: COFFObjectFile.cpp:356
llvm::object::COFFSymbolRef::isExternal
bool isExternal() const
Definition: COFF.h:377
llvm::object::delay_import_directory_iterator
content_iterator< DelayImportDirectoryEntryRef > delay_import_directory_iterator
Definition: COFF.h:47
llvm::object::ExportDirectoryEntryRef::getExportRVA
Error getExportRVA(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1582
llvm::object::coff_section::VirtualSize
support::ulittle32_t VirtualSize
Definition: COFF.h:442
llvm::object::COFFObjectFile::getArch
Triple::ArchType getArch() const override
Definition: COFFObjectFile.cpp:1024
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::object::ImportDirectoryEntryRef::imported_symbol_begin
imported_symbol_iterator imported_symbol_begin() const
Definition: COFFObjectFile.cpp:1442
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::object::SymbolRef::ST_Data
@ ST_Data
Definition: ObjectFile.h:174
llvm::COFF::IMAGE_REL_ARM64_SECREL_HIGH12A
@ IMAGE_REL_ARM64_SECREL_HIGH12A
Definition: COFF.h:396
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::object::COFFObjectFile::export_directory_end
export_directory_iterator export_directory_end() const
Definition: COFFObjectFile.cpp:973
llvm::object::ImportDirectoryEntryRef::getName
Error getName(StringRef &Result) const
Definition: COFFObjectFile.cpp:1473
llvm::PowerOf2Ceil
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition: MathExtras.h:631
llvm::object::SymbolRef::ST_File
@ ST_File
Definition: ObjectFile.h:176
llvm::COFF::IMAGE_REL_ARM_BRANCH20T
@ IMAGE_REL_ARM_BRANCH20T
Definition: COFF.h:379
llvm::object::BasicSymbolRef::SF_Weak
@ SF_Weak
Definition: SymbolicFile.h:112
llvm::COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
Definition: COFF.h:442
llvm::object::coff_base_reloc_block_header
Definition: COFF.h:731
llvm::object::import_lookup_table_entry32
import_lookup_table_entry< support::little32_t > import_lookup_table_entry32
Definition: COFF.h:206
llvm::COFF::IMAGE_SYM_ABSOLUTE
@ IMAGE_SYM_ABSOLUTE
Definition: COFF.h:198
llvm::object::ExportDirectoryEntryRef::getForwardTo
Error getForwardTo(StringRef &Result) const
Definition: COFFObjectFile.cpp:1638
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::COFF::IMAGE_REL_ARM64_BRANCH26
@ IMAGE_REL_ARM64_BRANCH26
Definition: COFF.h:389
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::object::export_directory_table_entry::ExportAddressTableRVA
support::ulittle32_t ExportAddressTableRVA
Definition: COFF.h:231
llvm::COFF::IMAGE_REL_ARM64_ABSOLUTE
@ IMAGE_REL_ARM64_ABSOLUTE
Definition: COFF.h:386
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:161
llvm::COFF::IMAGE_REL_ARM64_SECREL_LOW12A
@ IMAGE_REL_ARM64_SECREL_LOW12A
Definition: COFF.h:395
llvm::object::COFFSymbolRef::isFileRecord
bool isFileRecord() const
Definition: COFF.h:409
llvm::object::coff_import_directory_table_entry::ImportAddressTableRVA
support::ulittle32_t ImportAddressTableRVA
Definition: COFF.h:560
llvm::object::COFFObjectFile::getRelocations
ArrayRef< coff_relocation > getRelocations(const coff_section *Sec) const
Definition: COFFObjectFile.cpp:1262
llvm::object::coff_file_header::NumberOfSections
support::ulittle16_t NumberOfSections
Definition: COFF.h:77
llvm::object::ImportDirectoryEntryRef::lookup_table_symbols
iterator_range< imported_symbol_iterator > lookup_table_symbols() const
Definition: COFFObjectFile.cpp:1469
llvm::COFF::PEMagic
static const char PEMagic[]
Definition: COFF.h:35
llvm::object::ResourceSectionRef::getEntryData
Expected< const coff_resource_data_entry & > getEntryData(const coff_resource_dir_entry &Entry)
Definition: COFFObjectFile.cpp:1819
llvm::object::COFFSymbolRef::isWeakExternal
bool isWeakExternal() const
Definition: COFF.h:391
llvm::COFF::IMAGE_REL_I386_DIR16
@ IMAGE_REL_I386_DIR16
Definition: COFF.h:333
llvm::object::ImportedSymbolRef::getOrdinal
Error getOrdinal(uint16_t &Result) const
Definition: COFFObjectFile.cpp:1695
llvm::object::COFFObjectFile::getFileFormatName
StringRef getFileFormatName() const override
Definition: COFFObjectFile.cpp:1007
llvm::object::COFFObjectFile::section_end
section_iterator section_end() const override
Definition: COFFObjectFile.cpp:987
llvm::COFF::DELAY_IMPORT_DESCRIPTOR
@ DELAY_IMPORT_DESCRIPTOR
Definition: COFF.h:596
llvm::COFF::IMAGE_REL_ARM_SECREL
@ IMAGE_REL_ARM_SECREL
Definition: COFF.h:376
llvm::object::COFFObjectFile::getSectionSize
uint64_t getSectionSize(DataRefImpl Sec) const override
llvm::COFF::IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:103
llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:289
llvm::object::ImportedSymbolRef::getSymbolName
Error getSymbolName(StringRef &Result) const
Definition: COFFObjectFile.cpp:1659
Error.h
llvm::object::data_directory::RelativeVirtualAddress
support::ulittle32_t RelativeVirtualAddress
Definition: COFF.h:173
llvm::object::COFFSymbolRef
Definition: COFF.h:280
llvm::object::ImportedSymbolRef::getHintNameRVA
Error getHintNameRVA(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1687
llvm::Triple::ArchType
ArchType
Definition: Triple.h:46
llvm::COFF::IMAGE_REL_ARM_MOV32T
@ IMAGE_REL_ARM_MOV32T
Definition: COFF.h:378
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
ptrdiff_t
llvm::object::coff_import_directory_table_entry::NameRVA
support::ulittle32_t NameRVA
Definition: COFF.h:559
llvm::object::import_lookup_table_entry::isOrdinal
bool isOrdinal() const
Definition: COFF.h:192
llvm::COFF::LOAD_CONFIG_TABLE
@ LOAD_CONFIG_TABLE
Definition: COFF.h:593
llvm::object::COFFObjectFile::getMachine
uint16_t getMachine() const
Definition: COFF.h:848
llvm::object::BasicSymbolRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:208
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::support::little
@ little
Definition: Endian.h:27
llvm::object::COFFObjectFile::getSymbolAlignment
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:159
llvm::COFF::NameSize
@ NameSize
Definition: COFF.h:57
llvm::object::export_directory_table_entry::OrdinalBase
support::ulittle32_t OrdinalBase
Definition: COFF.h:228
llvm::COFF::IMAGE_DEBUG_TYPE_CODEVIEW
@ IMAGE_DEBUG_TYPE_CODEVIEW
Definition: COFF.h:655
llvm::object::coff_symbol::NumberOfAuxSymbols
uint8_t NumberOfAuxSymbols
Definition: COFF.h:262
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:92
llvm::object::COFFObjectFile::getPointerToSymbolTable
uint32_t getPointerToSymbolTable() const
Definition: COFF.h:892
llvm::BinaryByteStream
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Definition: BinaryByteStream.h:30
llvm::object::coff_resource_data_entry
Definition: COFF.h:766
llvm::COFF::IMAGE_SCN_MEM_READ
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:321
llvm::object::export_directory_table_entry::AddressTableEntries
support::ulittle32_t AddressTableEntries
Definition: COFF.h:229
llvm::object::ExportDirectoryEntryRef::isForwarder
Error isForwarder(bool &Result) const
Definition: COFFObjectFile.cpp:1623
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::object::export_directory_table_entry::NamePointerRVA
support::ulittle32_t NamePointerRVA
Definition: COFF.h:232
llvm::object::coff_section::Name
char Name[COFF::NameSize]
Definition: COFF.h:441
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::object::coff_section::PointerToRawData
support::ulittle32_t PointerToRawData
Definition: COFF.h:445
llvm::COFF::IMAGE_REL_ARM_ADDR32NB
@ IMAGE_REL_ARM_ADDR32NB
Definition: COFF.h:368
llvm::COFF::IMAGE_REL_ARM_TOKEN
@ IMAGE_REL_ARM_TOKEN
Definition: COFF.h:371
llvm::COFF::IMAGE_REL_ARM64_ADDR32
@ IMAGE_REL_ARM64_ADDR32
Definition: COFF.h:387
llvm::object::pe32plus_header::ImageBase
support::ulittle64_t ImageBase
Definition: COFF.h:149
llvm::object::export_directory_table_entry::NumberOfNamePointers
support::ulittle32_t NumberOfNamePointers
Definition: COFF.h:230
llvm::object::COFFObjectFile::getRelocationOffset
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition: COFFObjectFile.cpp:1215
llvm::BinaryStreamReader::readInteger
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
Definition: BinaryStreamReader.h:68
llvm::object::ResourceSectionRef::getEntrySubDir
Expected< const coff_resource_dir_table & > getEntrySubDir(const coff_resource_dir_entry &Entry)
Definition: COFFObjectFile.cpp:1813
llvm::BinaryByteStream::data
ArrayRef< uint8_t > data() const
Definition: BinaryByteStream.h:58
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::COFF::IMAGE_REL_I386_DIR32
@ IMAGE_REL_I386_DIR32
Definition: COFF.h:335
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::DataRefImpl::p
uintptr_t p
Definition: SymbolicFile.h:41
llvm::object::coff_file_header::isImportLibrary
bool isImportLibrary() const
Definition: COFF.h:84
llvm::object::export_address_table_entry
Definition: COFF.h:236
llvm::object::coff_symbol
Definition: COFF.h:250
llvm::object::coff_section::Characteristics
support::ulittle32_t Characteristics
Definition: COFF.h:450
llvm::object::export_directory_table_entry::NameRVA
support::ulittle32_t NameRVA
Definition: COFF.h:227
llvm::object::pe32_header::ImageBase
support::ulittle32_t ImageBase
Definition: COFF.h:114
llvm::object::coff_relocation
Definition: COFF.h:474
llvm::COFF::IMAGE_REL_AMD64_SREL32
@ IMAGE_REL_AMD64_SREL32
Definition: COFF.h:360
llvm::object::COFFObjectFile::getSymbolTableEntrySize
size_t getSymbolTableEntrySize() const
Definition: COFF.h:1054
llvm::object::COFFObjectFile::getSymbolFlags
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:210
llvm::object::COFFObjectFile::getSymbolIndex
uint32_t getSymbolIndex(COFFSymbolRef Symbol) const
Definition: COFFObjectFile.cpp:1140
llvm::object::COFFObjectFile::getSymbolSectionID
unsigned getSymbolSectionID(SymbolRef Sym) const
Definition: COFFObjectFile.cpp:259
llvm::object::COFFObjectFile::section_rel_begin
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:396
llvm::object::import_lookup_table_entry::getHintNameRVA
uint32_t getHintNameRVA() const
Definition: COFF.h:199
llvm::object::COFFObjectFile::moveSectionNext
void moveSectionNext(DataRefImpl &Sec) const override
Definition: COFFObjectFile.cpp:264
llvm::object::RelocationRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:574
llvm::COFF::IMAGE_REL_AMD64_SSPAN32
@ IMAGE_REL_AMD64_SSPAN32
Definition: COFF.h:362
llvm::object::coff_resource_dir_entry
Definition: COFF.h:743
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::object::ImportedSymbolRef
Definition: COFF.h:1187
llvm::object::COFFSymbolRef::isSectionDefinition
bool isSectionDefinition() const
Definition: COFF.h:417
llvm::COFF::TLS_TABLE
@ TLS_TABLE
Definition: COFF.h:592
llvm::object::COFFSymbolRef::isUndefined
bool isUndefined() const
Definition: COFF.h:386
llvm::OutputFileType::Object
@ Object
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::object::COFFObjectFile::export_directory_begin
export_directory_iterator export_directory_begin() const
Definition: COFFObjectFile.cpp:968
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1538
llvm::support::ulittle32_t
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:272
llvm::object::COFFSymbolRef::isAnyUndefined
bool isAnyUndefined() const
Definition: COFF.h:405
llvm::object::COFFObjectFile::isSectionData
bool isSectionData(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:316
llvm::object::COFFObjectFile::base_reloc_end
base_reloc_iterator base_reloc_end() const
Definition: COFFObjectFile.cpp:999
llvm::COFF::IMAGE_REL_ARM64_SECREL_LOW12L
@ IMAGE_REL_ARM64_SECREL_LOW12L
Definition: COFF.h:397
llvm::COFF::IMAGE_REL_ARM_PAIR
@ IMAGE_REL_ARM_PAIR
Definition: COFF.h:382
llvm::object::ObjectFile::SymbolRef
friend class SymbolRef
Definition: ObjectFile.h:246
llvm::object::coff_bigobj_file_header::UUID
uint8_t UUID[16]
Definition: COFF.h:93
llvm::object::COFFObjectFile::getSymbolTable
uintptr_t getSymbolTable() const
Definition: COFF.h:840
llvm::object::data_directory
Definition: COFF.h:172
llvm::object::COFFObjectFile::getImageBase
uint64_t getImageBase() const
Definition: COFFObjectFile.cpp:455
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:264
llvm::support::ulittle16_t
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Definition: Endian.h:270
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::object::BasicSymbolRef::SF_FormatSpecific
@ SF_FormatSpecific
Definition: SymbolicFile.h:117
llvm::COFF::IMAGE_REL_AMD64_ABSOLUTE
@ IMAGE_REL_AMD64_ABSOLUTE
Definition: COFF.h:346
llvm::ArrayRef::drop_front
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:203
makeImportedSymbolIterator
static imported_symbol_iterator makeImportedSymbolIterator(const COFFObjectFile *Object, uintptr_t Ptr, int Index)
Definition: COFFObjectFile.cpp:1404
llvm::COFF::IMAGE_REL_I386_REL32
@ IMAGE_REL_I386_REL32
Definition: COFF.h:342
llvm::object::coff_import_directory_table_entry::isNull
bool isNull() const
Definition: COFF.h:562
Index
uint32_t Index
Definition: ELFObjHandler.cpp:82
uint64_t
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::object::pe32plus_header::NumberOfRvaAndSize
support::ulittle32_t NumberOfRvaAndSize
Definition: COFF.h:169
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:113
importedSymbolBegin
static imported_symbol_iterator importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object)
Definition: COFFObjectFile.cpp:1415
llvm::object::SymbolRef::ST_Function
@ ST_Function
Definition: ObjectFile.h:177
llvm::COFF::IMAGE_REL_ARM_BRANCH24T
@ IMAGE_REL_ARM_BRANCH24T
Definition: COFF.h:380
llvm::object::coff_aux_weak_external
Definition: COFF.h:502
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::COFF::IMAGE_REL_AMD64_REL32_4
@ IMAGE_REL_AMD64_REL32_4
Definition: COFF.h:354
llvm::COFF::IMAGE_REL_ARM_BRANCH24
@ IMAGE_REL_ARM_BRANCH24
Definition: COFF.h:369
llvm::COFF::IMAGE_REL_ARM_BRANCH11
@ IMAGE_REL_ARM_BRANCH11
Definition: COFF.h:370
llvm::object::ImportedSymbolRef::isOrdinal
Error isOrdinal(bool &Result) const
Definition: COFFObjectFile.cpp:1679
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::object::BasicSymbolRef::SF_None
@ SF_None
Definition: SymbolicFile.h:109
llvm::object::ExportDirectoryEntryRef::operator==
bool operator==(const ExportDirectoryEntryRef &Other) const
Definition: COFFObjectFile.cpp:1550
llvm::COFF::IMAGE_REL_AMD64_REL32_5
@ IMAGE_REL_AMD64_REL32_5
Definition: COFF.h:355
llvm::object::ObjectFile::SectionRef
friend class SectionRef
Definition: ObjectFile.h:260
llvm::COFF::SectionSize
@ SectionSize
Definition: COFF.h:60
llvm::object::ResourceSectionRef::getBaseTable
Expected< const coff_resource_dir_table & > getBaseTable()
Definition: COFFObjectFile.cpp:1824
llvm::object::imported_symbol_iterator
content_iterator< ImportedSymbolRef > imported_symbol_iterator
Definition: COFF.h:49
llvm::object::ExportDirectoryEntryRef
Definition: COFF.h:1162
llvm::object::COFFObjectFile::mapDebugSectionName
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
Definition: COFFObjectFile.cpp:1379
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:110
llvm::object::StringTableOffset
Definition: COFF.h:244
llvm::COFF::IMAGE_REL_AMD64_ADDR64
@ IMAGE_REL_AMD64_ADDR64
Definition: COFF.h:347
llvm::object::COFFObjectFile::create
static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)
Definition: COFFObjectFile.cpp:760
llvm::object::COFFObjectFile::getNumberOfSections
uint32_t getNumberOfSections() const
Definition: COFF.h:884
llvm::object::BaseRelocRef::getType
Error getType(uint8_t &Type) const
Definition: COFFObjectFile.cpp:1744
ArrayRef.h
llvm::object::ResourceSectionRef::getContents
Expected< StringRef > getContents(const coff_resource_data_entry &Entry)
Definition: COFFObjectFile.cpp:1871
llvm::object::pe32_header::AddressOfEntryPoint
support::ulittle32_t AddressOfEntryPoint
Definition: COFF.h:111
llvm::COFF::PE32Header::PE32
@ PE32
Definition: COFF.h:541
llvm::COFF::IMAGE_REL_AMD64_SECREL7
@ IMAGE_REL_AMD64_SECREL7
Definition: COFF.h:358
llvm::object::SymbolRef::ST_Debug
@ ST_Debug
Definition: ObjectFile.h:175
llvm::object::COFFObjectFile::moveSymbolNext
void moveSymbolNext(DataRefImpl &Symb) const override
Definition: COFFObjectFile.cpp:136
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::object::ResourceSectionRef::getEntryNameString
Expected< ArrayRef< UTF16 > > getEntryNameString(const coff_resource_dir_entry &Entry)
Definition: COFFObjectFile.cpp:1775
ObjectFile.h
llvm::object::BaseRelocRef
Definition: COFF.h:1212
base
therefore end up llgh r3 lr r0 br r14 but truncating the load would lh r3 br r14 Functions ret i64 and ought to be implemented ngr r0 br r14 but two address optimizations reverse the order of the AND and ngr r2 lgr r0 br r14 CodeGen SystemZ and ll has several examples of this Out of range displacements are usually handled by loading the full address into a register In many cases it would be better to create an anchor point instead E g i64 base
Definition: README.txt:125
llvm::object::content_iterator
Definition: SymbolicFile.h:69
llvm::object::pe32_header::NumberOfRvaAndSize
support::ulittle32_t NumberOfRvaAndSize
Definition: COFF.h:136
llvm::object::ImportDirectoryEntryRef::imported_symbol_end
imported_symbol_iterator imported_symbol_end() const
Definition: COFFObjectFile.cpp:1448
llvm::object::coff_symbol_generic
Definition: COFF.h:269
llvm::codeview::CompileSym2Flags::EC
@ EC
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
checkSize
static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size)
Definition: COFFObjectFile.cpp:47
llvm::object::ObjectFile::base
const uint8_t * base() const
Definition: ObjectFile.h:234
iterator_range.h
llvm::object::DelayImportDirectoryEntryRef::getDelayImportTable
Error getDelayImportTable(const delay_import_directory_table_entry *&Result) const
Definition: COFFObjectFile.cpp:1529
decodeBase64StringEntry
static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result)
Definition: COFFObjectFile.cpp:69
llvm::object::COFFObjectFile::getNumberOfSymbols
uint32_t getNumberOfSymbols() const
Definition: COFF.h:909
llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
llvm::COFF::IMAGE_REL_ARM_ABSOLUTE
@ IMAGE_REL_ARM_ABSOLUTE
Definition: COFF.h:366
llvm::object::SectionRef::getContents
Expected< StringRef > getContents() const
Definition: ObjectFile.h:472
llvm::COFF::DEBUG_DIRECTORY
@ DEBUG_DIRECTORY
Definition: COFF.h:589
llvm::object::COFFObjectFile::getCOFFSymbol
COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const
Definition: COFFObjectFile.cpp:1244
llvm::object::ExportDirectoryEntryRef::getOrdinalBase
Error getOrdinalBase(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1570
llvm::object::ResourceSectionRef::load
Error load(const COFFObjectFile *O)
Definition: COFFObjectFile.cpp:1839
llvm::object::COFFObjectFile::moveRelocationNext
void moveRelocationNext(DataRefImpl &Rel) const override
Definition: COFFObjectFile.cpp:1210
llvm::object::COFFObjectFile::getSectionContents
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
llvm::object::ImportDirectoryEntryRef::getImportLookupTableRVA
Error getImportLookupTableRVA(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1483
Triple.h
llvm::object::coff_bigobj_file_header::Version
support::ulittle16_t Version
Definition: COFF.h:90
llvm::object::COFFObjectFile::base_reloc_begin
base_reloc_iterator base_reloc_begin() const
Definition: COFFObjectFile.cpp:995
llvm::object::ImportDirectoryEntryRef::imported_symbols
iterator_range< imported_symbol_iterator > imported_symbols() const
Definition: COFFObjectFile.cpp:1454
llvm::ArrayRef< uint8_t >
llvm::COFF::BigObjMagic
static const char BigObjMagic[]
Definition: COFF.h:37
llvm::object::COFFSymbolRef::getValue
uint32_t getValue() const
Definition: COFF.h:317
llvm::object::section_iterator
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::object::COFFSymbolRef::isCommon
bool isCommon() const
Definition: COFF.h:381
llvm::object::COFFObjectFile::getSymbolAuxData
ArrayRef< uint8_t > getSymbolAuxData(COFFSymbolRef Symbol) const
Definition: COFFObjectFile.cpp:1118
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::object::export_directory_iterator
content_iterator< ExportDirectoryEntryRef > export_directory_iterator
Definition: COFF.h:48
llvm::object::COFFObjectFile::isDebugSection
bool isDebugSection(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:331
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
llvm::object::coff_resource_dir_table::NumberOfIDEntries
support::ulittle16_t NumberOfIDEntries
Definition: COFF.h:779
llvm::object::Binary
Definition: Binary.h:32
llvm::object::COFFObjectFile::getDebugPDBInfo
Error getDebugPDBInfo(const debug_directory *DebugDir, const codeview::DebugInfo *&Info, StringRef &PDBFileName) const
Get PDB information out of a codeview debug directory entry.
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::object::COFFObjectFile::getSectionIndex
uint64_t getSectionIndex(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:285
llvm::object::COFFObjectFile::getCOFFSection
const coff_section * getCOFFSection(const SectionRef &Section) const
Definition: COFFObjectFile.cpp:1240
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
llvm::object::COFFObjectFile::isSectionText
bool isSectionText(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:311
uint32_t
llvm::Triple::thumb
@ thumb
Definition: Triple.h:83
llvm::object::COFFObjectFile::getRvaAndSizeAsBytes
Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size, ArrayRef< uint8_t > &Contents, const char *ErrorContext=nullptr) const
Given an RVA base and size, returns a valid array of bytes or an error code if the RVA and size is no...
Definition: COFFObjectFile.cpp:507
llvm::object::coff_section::SizeOfRawData
support::ulittle32_t SizeOfRawData
Definition: COFF.h:444
llvm::object::debug_directory
Definition: COFF.h:177
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::COFF::IMAGE_REL_AMD64_REL32_2
@ IMAGE_REL_AMD64_REL32_2
Definition: COFF.h:352
llvm::object::COFFObjectFile::getDOSHeader
const dos_header * getDOSHeader() const
Definition: COFF.h:1012
llvm::object::DataRefImpl
Definition: SymbolicFile.h:35
llvm::object::import_directory_iterator
content_iterator< ImportDirectoryEntryRef > import_directory_iterator
Definition: COFF.h:45
llvm::object::ImportedSymbolRef::operator==
bool operator==(const ImportedSymbolRef &Other) const
Definition: COFFObjectFile.cpp:1650
llvm::COFF::IMAGE_REL_ARM64_PAGEOFFSET_12A
@ IMAGE_REL_ARM64_PAGEOFFSET_12A
Definition: COFF.h:392
llvm::object::COFFObjectFile::getSection
Expected< const coff_section * > getSection(int32_t index) const
Definition: COFFObjectFile.cpp:1077
llvm::COFF::IMAGE_REL_AMD64_SECREL
@ IMAGE_REL_AMD64_SECREL
Definition: COFF.h:357
llvm::COFF::IMAGE_REL_ARM_REL32
@ IMAGE_REL_ARM_REL32
Definition: COFF.h:374
llvm::codeview::DebugInfo
Definition: CVDebugRecord.h:45
llvm::COFF::IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
llvm::object::COFFObjectFile::ImportDirectoryEntryRef
friend class ImportDirectoryEntryRef
Definition: COFF.h:792
llvm::COFF::IMAGE_REL_ARM_BLX24
@ IMAGE_REL_ARM_BLX24
Definition: COFF.h:372
llvm::COFF::IMAGE_REL_I386_TOKEN
@ IMAGE_REL_I386_TOKEN
Definition: COFF.h:340
llvm::COFF::IMAGE_REL_ARM64_REL32
@ IMAGE_REL_ARM64_REL32
Definition: COFF.h:403
llvm::object::DelayImportDirectoryEntryRef::operator==
bool operator==(const DelayImportDirectoryEntryRef &Other) const
Definition: COFFObjectFile.cpp:1495
llvm::object::base_reloc_iterator
content_iterator< BaseRelocRef > base_reloc_iterator
Definition: COFF.h:50
llvm::object::coff_tls_directory64
coff_tls_directory< support::little64_t > coff_tls_directory64
Definition: COFF.h:598
llvm::object::coff_relocation::Type
support::ulittle16_t Type
Definition: COFF.h:477
llvm::COFF::IMPORT_TABLE
@ IMPORT_TABLE
Definition: COFF.h:584
llvm::object::coff_import_directory_table_entry
Definition: COFF.h:555
llvm::COFF::BASE_RELOCATION_TABLE
@ BASE_RELOCATION_TABLE
Definition: COFF.h:588
llvm::COFF::IMAGE_REL_ARM_SECTION
@ IMAGE_REL_ARM_SECTION
Definition: COFF.h:375
llvm::object::COFFObjectFile::isRelocatableObject
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Definition: COFFObjectFile.cpp:1375
llvm::object::ExportDirectoryEntryRef::getOrdinal
Error getOrdinal(uint32_t &Result) const
Definition: COFFObjectFile.cpp:1576
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::object::ImportDirectoryEntryRef::getImportTableEntry
Error getImportTableEntry(const coff_import_directory_table_entry *&Result) const
Definition: COFFObjectFile.cpp:1398
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::object::COFFObjectFile::getRelocationSymbol
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Definition: COFFObjectFile.cpp:1220
uint16_t
llvm::object::COFFObjectFile::delay_import_directory_end
delay_import_directory_iterator delay_import_directory_end() const
Definition: COFFObjectFile.cpp:962
llvm::COFF::EXPORT_TABLE
@ EXPORT_TABLE
Definition: COFF.h:583
llvm::object::COFFObjectFile::symbol_begin
basic_symbol_iterator symbol_begin() const override
Definition: COFFObjectFile.cpp:928
llvm::COFF::IMAGE_REL_ARM64_TOKEN
@ IMAGE_REL_ARM64_TOKEN
Definition: COFF.h:398
llvm::SectionName
Definition: DWARFSection.h:21
llvm::object::COFFObjectFile::isSectionBSS
bool isSectionBSS(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:321
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::COFF::IMAGE_REL_ARM64_BRANCH14
@ IMAGE_REL_ARM64_BRANCH14
Definition: COFF.h:402
llvm::object::coff_section
Definition: COFF.h:440
llvm::COFF::IMAGE_SCN_CNT_CODE
@ IMAGE_SCN_CNT_CODE
Definition: COFF.h:288
llvm::COFF::IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_REL_AMD64_ADDR32NB
Definition: COFF.h:349
llvm::object::ImportDirectoryEntryRef
Definition: COFF.h:1105
llvm::object::DelayImportDirectoryEntryRef::getImportAddress
Error getImportAddress(int AddrIndex, uint64_t &Result) const
Definition: COFFObjectFile.cpp:1535
llvm::COFF::IMAGE_REL_I386_REL16
@ IMAGE_REL_I386_REL16
Definition: COFF.h:334
llvm::object::COFFObjectFile::getRvaPtr
Error getRvaPtr(uint32_t Rva, uintptr_t &Res, const char *ErrorContext=nullptr) const
Definition: COFFObjectFile.cpp:473
llvm::object::COFFObjectFile::isSectionCompressed
bool isSectionCompressed(DataRefImpl Sec) const override
Definition: COFFObjectFile.cpp:307
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::object::BasicSymbolRef::SF_Absolute
@ SF_Absolute
Definition: SymbolicFile.h:113
llvm::COFF::IMAGE_REL_I386_SEG12
@ IMAGE_REL_I386_SEG12
Definition: COFF.h:337
llvm::object::delay_import_directory_table_entry
Definition: COFF.h:210
llvm::COFF::IMAGE_REL_ARM_BLX23T
@ IMAGE_REL_ARM_BLX23T
Definition: COFF.h:381
llvm::object::COFFObjectFile::getSymbolValueImpl
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:155
llvm::COFF::IMAGE_REL_AMD64_REL32_1
@ IMAGE_REL_AMD64_REL32_1
Definition: COFF.h:351
llvm::object::DelayImportDirectoryEntryRef::imported_symbols
iterator_range< imported_symbol_iterator > imported_symbols() const
Definition: COFFObjectFile.cpp:1516
llvm::object::COFFObjectFile
Definition: COFF.h:788
llvm::object::BaseRelocRef::moveNext
void moveNext()
Definition: COFFObjectFile.cpp:1726
StringSwitch.h
llvm::object::coff_resource_dir_table::NumberOfNameEntries
support::ulittle16_t NumberOfNameEntries
Definition: COFF.h:778
llvm::object::SymbolRef::ST_Other
@ ST_Other
Definition: ObjectFile.h:173
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::support::ulittle64_t
detail::packed_endian_specific_integral< uint64_t, little, unaligned > ulittle64_t
Definition: Endian.h:274
llvm::object::ExportDirectoryEntryRef::moveNext
void moveNext()
Definition: COFFObjectFile.cpp:1554
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::object::COFFObjectFile::getSymbolType
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Definition: COFFObjectFile.cpp:187
ignoreStrippedErrors
static Error ignoreStrippedErrors(Error E)
Definition: COFFObjectFile.cpp:778
llvm::object::COFFObjectFile::delay_import_directories
iterator_range< delay_import_directory_iterator > delay_import_directories() const
Definition: COFFObjectFile.cpp:1052
llvm::COFF::IMAGE_REL_AMD64_REL32_3
@ IMAGE_REL_AMD64_REL32_3
Definition: COFF.h:353
Binary.h
llvm::COFF::IMAGE_REL_I386_SECREL
@ IMAGE_REL_I386_SECREL
Definition: COFF.h:339
llvm::support::little16_t
detail::packed_endian_specific_integral< int16_t, little, unaligned > little16_t
Definition: Endian.h:277
llvm::object::COFFObjectFile::delay_import_directory_begin
delay_import_directory_iterator delay_import_directory_begin() const
Definition: COFFObjectFile.cpp:956
COFF.h
llvm::object::DelayImportDirectoryEntryRef::moveNext
void moveNext()
Definition: COFFObjectFile.cpp:1499
llvm::COFF::isReservedSectionNumber
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: COFF.h:792
llvm::COFF::PE32Header::PE32_PLUS
@ PE32_PLUS
Definition: COFF.h:541
llvm::COFF::IMAGE_REL_ARM64_BRANCH19
@ IMAGE_REL_ARM64_BRANCH19
Definition: COFF.h:401
llvm::object::DelayImportDirectoryEntryRef::imported_symbol_end
imported_symbol_iterator imported_symbol_end() const
Definition: COFFObjectFile.cpp:1510
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:111
llvm::object::ExportDirectoryEntryRef::getDllName
Error getDllName(StringRef &Result) const
Definition: COFFObjectFile.cpp:1560
llvm::object::COFFObjectFile::import_directory_begin
import_directory_iterator import_directory_begin() const
Definition: COFFObjectFile.cpp:941
llvm::object::ImportDirectoryEntryRef::operator==
bool operator==(const ImportDirectoryEntryRef &Other) const
Definition: COFFObjectFile.cpp:1386
llvm::object::coff_resource_dir_table
Definition: COFF.h:773
llvm::object::COFFObjectFile::symbol_end
basic_symbol_iterator symbol_end() const override
Definition: COFFObjectFile.cpp:934
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::COFF::IMAGE_REL_AMD64_SECTION
@ IMAGE_REL_AMD64_SECTION
Definition: COFF.h:356
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::object::coff_file_header::SizeOfOptionalHeader
support::ulittle16_t SizeOfOptionalHeader
Definition: COFF.h:81
llvm::object::ObjectFile::sections
section_iterator_range sections() const
Definition: ObjectFile.h:327
llvm::object::Binary::checkOffset
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
Definition: Binary.h:170
llvm::object::debug_directory::AddressOfRawData
support::ulittle32_t AddressOfRawData
Definition: COFF.h:184
llvm::SmallVectorImpl< char >
llvm::object::COFFObjectFile::is64
bool is64() const
Definition: COFF.h:1097
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:167
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:182
llvm::object::data_directory::Size
support::ulittle32_t Size
Definition: COFF.h:174
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
llvm::object::DelayImportDirectoryEntryRef
Definition: COFF.h:1136
llvm::object::ImportDirectoryEntryRef::moveNext
void moveNext()
Definition: COFFObjectFile.cpp:1390
llvm::object::delay_import_directory_table_entry::Name
support::ulittle32_t Name
Definition: COFF.h:213
llvm::object::RelocationRef
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:51
llvm::COFF::IMAGE_REL_AMD64_TOKEN
@ IMAGE_REL_AMD64_TOKEN
Definition: COFF.h:359
llvm::object::COFFObjectFile::getRelocationTypeName
StringRef getRelocationTypeName(uint16_t Type) const
Definition: COFFObjectFile.cpp:1271
llvm::COFF::IMAGE_REL_ARM64_ADDR64
@ IMAGE_REL_ARM64_ADDR64
Definition: COFF.h:400
llvm::object::COFFObjectFile::import_directory_end
import_directory_iterator import_directory_end() const
Definition: COFFObjectFile.cpp:950
llvm::COFF::IMAGE_REL_ARM_BLX11
@ IMAGE_REL_ARM_BLX11
Definition: COFF.h:373
llvm::object::COFFSymbolRef::getComplexType
uint8_t getComplexType() const
Definition: COFF.h:350
llvm::COFF::IMAGE_REL_ARM_ADDR32
@ IMAGE_REL_ARM_ADDR32
Definition: COFF.h:367
llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:261
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:111
llvm::COFF::IMAGE_REL_I386_SECREL7
@ IMAGE_REL_I386_SECREL7
Definition: COFF.h:341
llvm::COFF::IMAGE_SYM_DEBUG
@ IMAGE_SYM_DEBUG
Definition: COFF.h:197
llvm::object::COFFObjectFile::getSymbolName
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
llvm::object::COFFObjectFile::export_directories
iterator_range< export_directory_iterator > export_directories() const
Definition: COFFObjectFile.cpp:1058
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:689
llvm::object::basic_symbol_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:143
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::object::COFFObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
llvm::object::ImportDirectoryEntryRef::lookup_table_end
imported_symbol_iterator lookup_table_end() const
Definition: COFFObjectFile.cpp:1463
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
entry
print Instructions which execute on loop entry
Definition: MustExecute.cpp:337
llvm::BinaryStreamReader::readArray
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...
Definition: BinaryStreamReader.h:180
llvm::COFF::IMAGE_SCN_MEM_WRITE
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:322
llvm::object::coff_import_directory_table_entry::ImportLookupTableRVA
support::ulittle32_t ImportLookupTableRVA
Definition: COFF.h:556
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1247
llvm::COFF::IMAGE_REL_ARM64_SECTION
@ IMAGE_REL_ARM64_SECTION
Definition: COFF.h:399