LLVM  4.0.0
COFFObjectFile.cpp
Go to the documentation of this file.
1 //===- COFFObjectFile.cpp - COFF object file implementation -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the COFFObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Object/COFF.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/COFF.h"
20 #include "llvm/Support/Debug.h"
22 #include <cctype>
23 #include <limits>
24 
25 using namespace llvm;
26 using namespace object;
27 
32 
33 // Returns false if size is greater than the buffer size. And sets ec.
34 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
35  if (M.getBufferSize() < Size) {
37  return false;
38  }
39  return true;
40 }
41 
42 static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
43  const uint64_t Size) {
44  if (Addr + Size < Addr || Addr + Size < Size ||
45  Addr + Size > uintptr_t(M.getBufferEnd()) ||
46  Addr < uintptr_t(M.getBufferStart())) {
48  }
49  return std::error_code();
50 }
51 
52 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
53 // Returns unexpected_eof if error.
54 template <typename T>
55 static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
56  const void *Ptr,
57  const uint64_t Size = sizeof(T)) {
58  uintptr_t Addr = uintptr_t(Ptr);
59  if (std::error_code EC = checkOffset(M, Addr, Size))
60  return EC;
61  Obj = reinterpret_cast<const T *>(Addr);
62  return std::error_code();
63 }
64 
65 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
66 // prefixed slashes.
67 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
68  assert(Str.size() <= 6 && "String too long, possible overflow.");
69  if (Str.size() > 6)
70  return true;
71 
72  uint64_t Value = 0;
73  while (!Str.empty()) {
74  unsigned CharVal;
75  if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
76  CharVal = Str[0] - 'A';
77  else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
78  CharVal = Str[0] - 'a' + 26;
79  else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
80  CharVal = Str[0] - '0' + 52;
81  else if (Str[0] == '+') // 62
82  CharVal = 62;
83  else if (Str[0] == '/') // 63
84  CharVal = 63;
85  else
86  return true;
87 
88  Value = (Value * 64) + CharVal;
89  Str = Str.substr(1);
90  }
91 
92  if (Value > std::numeric_limits<uint32_t>::max())
93  return true;
94 
95  Result = static_cast<uint32_t>(Value);
96  return false;
97 }
98 
99 template <typename coff_symbol_type>
100 const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
101  const coff_symbol_type *Addr =
102  reinterpret_cast<const coff_symbol_type *>(Ref.p);
103 
104  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
105 #ifndef NDEBUG
106  // Verify that the symbol points to a valid entry in the symbol table.
107  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
108 
109  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
110  "Symbol did not point to the beginning of a symbol");
111 #endif
112 
113  return Addr;
114 }
115 
116 const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
117  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
118 
119 # ifndef NDEBUG
120  // Verify that the section points to a valid entry in the section table.
121  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
122  report_fatal_error("Section was outside of section table.");
123 
124  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
125  assert(Offset % sizeof(coff_section) == 0 &&
126  "Section did not point to the beginning of a section");
127 # endif
128 
129  return Addr;
130 }
131 
133  auto End = reinterpret_cast<uintptr_t>(StringTable);
134  if (SymbolTable16) {
135  const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
136  Symb += 1 + Symb->NumberOfAuxSymbols;
137  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
138  } else if (SymbolTable32) {
139  const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
140  Symb += 1 + Symb->NumberOfAuxSymbols;
141  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
142  } else {
143  llvm_unreachable("no symbol table pointer!");
144  }
145 }
146 
148  COFFSymbolRef Symb = getCOFFSymbol(Ref);
149  StringRef Result;
150  std::error_code EC = getSymbolName(Symb, Result);
151  if (EC)
152  return errorCodeToError(EC);
153  return Result;
154 }
155 
157  return getCOFFSymbol(Ref).getValue();
158 }
159 
161  // MSVC/link.exe seems to align symbols to the next-power-of-2
162  // up to 32 bytes.
163  COFFSymbolRef Symb = getCOFFSymbol(Ref);
164  return std::min(uint64_t(32), PowerOf2Ceil(Symb.getValue()));
165 }
166 
168  uint64_t Result = getSymbolValue(Ref);
169  COFFSymbolRef Symb = getCOFFSymbol(Ref);
170  int32_t SectionNumber = Symb.getSectionNumber();
171 
172  if (Symb.isAnyUndefined() || Symb.isCommon() ||
173  COFF::isReservedSectionNumber(SectionNumber))
174  return Result;
175 
176  const coff_section *Section = nullptr;
177  if (std::error_code EC = getSection(SectionNumber, Section))
178  return errorCodeToError(EC);
179  Result += Section->VirtualAddress;
180 
181  // The section VirtualAddress does not include ImageBase, and we want to
182  // return virtual addresses.
183  Result += getImageBase();
184 
185  return Result;
186 }
187 
189  COFFSymbolRef Symb = getCOFFSymbol(Ref);
190  int32_t SectionNumber = Symb.getSectionNumber();
191 
193  return SymbolRef::ST_Function;
194  if (Symb.isAnyUndefined())
195  return SymbolRef::ST_Unknown;
196  if (Symb.isCommon())
197  return SymbolRef::ST_Data;
198  if (Symb.isFileRecord())
199  return SymbolRef::ST_File;
200 
201  // TODO: perhaps we need a new symbol type ST_Section.
202  if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
203  return SymbolRef::ST_Debug;
204 
205  if (!COFF::isReservedSectionNumber(SectionNumber))
206  return SymbolRef::ST_Data;
207 
208  return SymbolRef::ST_Other;
209 }
210 
212  COFFSymbolRef Symb = getCOFFSymbol(Ref);
213  uint32_t Result = SymbolRef::SF_None;
214 
215  if (Symb.isExternal() || Symb.isWeakExternal())
216  Result |= SymbolRef::SF_Global;
217 
218  if (Symb.isWeakExternal())
219  Result |= SymbolRef::SF_Weak;
220 
222  Result |= SymbolRef::SF_Absolute;
223 
224  if (Symb.isFileRecord())
226 
227  if (Symb.isSectionDefinition())
229 
230  if (Symb.isCommon())
231  Result |= SymbolRef::SF_Common;
232 
233  if (Symb.isAnyUndefined())
234  Result |= SymbolRef::SF_Undefined;
235 
236  return Result;
237 }
238 
240  COFFSymbolRef Symb = getCOFFSymbol(Ref);
241  return Symb.getValue();
242 }
243 
246  COFFSymbolRef Symb = getCOFFSymbol(Ref);
248  return section_end();
249  const coff_section *Sec = nullptr;
250  if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
251  return errorCodeToError(EC);
253  Ret.p = reinterpret_cast<uintptr_t>(Sec);
254  return section_iterator(SectionRef(Ret, this));
255 }
256 
259  return Symb.getSectionNumber();
260 }
261 
263  const coff_section *Sec = toSec(Ref);
264  Sec += 1;
265  Ref.p = reinterpret_cast<uintptr_t>(Sec);
266 }
267 
268 std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
269  StringRef &Result) const {
270  const coff_section *Sec = toSec(Ref);
271  return getSectionName(Sec, Result);
272 }
273 
275  const coff_section *Sec = toSec(Ref);
276  uint64_t Result = Sec->VirtualAddress;
277 
278  // The section VirtualAddress does not include ImageBase, and we want to
279  // return virtual addresses.
280  Result += getImageBase();
281  return Result;
282 }
283 
284 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
285  return getSectionSize(toSec(Ref));
286 }
287 
289  StringRef &Result) const {
290  const coff_section *Sec = toSec(Ref);
291  ArrayRef<uint8_t> Res;
292  std::error_code EC = getSectionContents(Sec, Res);
293  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
294  return EC;
295 }
296 
298  const coff_section *Sec = toSec(Ref);
299  return Sec->getAlignment();
300 }
301 
303  return false;
304 }
305 
307  const coff_section *Sec = toSec(Ref);
309 }
310 
312  const coff_section *Sec = toSec(Ref);
314 }
315 
317  const coff_section *Sec = toSec(Ref);
321  return (Sec->Characteristics & BssFlags) == BssFlags;
322 }
323 
325  uintptr_t Offset =
326  uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
327  assert((Offset % sizeof(coff_section)) == 0);
328  return (Offset / sizeof(coff_section)) + 1;
329 }
330 
332  const coff_section *Sec = toSec(Ref);
333  // In COFF, a virtual section won't have any in-file
334  // content, so the file pointer to the content will be zero.
335  return Sec->PointerToRawData == 0;
336 }
337 
339  MemoryBufferRef M, const uint8_t *base) {
340  // The field for the number of relocations in COFF section table is only
341  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
342  // NumberOfRelocations field, and the actual relocation count is stored in the
343  // VirtualAddress field in the first relocation entry.
344  if (Sec->hasExtendedRelocations()) {
345  const coff_relocation *FirstReloc;
346  if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
347  base + Sec->PointerToRelocations)))
348  return 0;
349  // -1 to exclude this first relocation entry.
350  return FirstReloc->VirtualAddress - 1;
351  }
352  return Sec->NumberOfRelocations;
353 }
354 
355 static const coff_relocation *
356 getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
357  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
358  if (!NumRelocs)
359  return nullptr;
360  auto begin = reinterpret_cast<const coff_relocation *>(
361  Base + Sec->PointerToRelocations);
362  if (Sec->hasExtendedRelocations()) {
363  // Skip the first relocation entry repurposed to store the number of
364  // relocations.
365  begin++;
366  }
367  if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs))
368  return nullptr;
369  return begin;
370 }
371 
373  const coff_section *Sec = toSec(Ref);
374  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
375  if (begin && Sec->VirtualAddress != 0)
376  report_fatal_error("Sections with relocations should have an address of 0");
378  Ret.p = reinterpret_cast<uintptr_t>(begin);
379  return relocation_iterator(RelocationRef(Ret, this));
380 }
381 
383  const coff_section *Sec = toSec(Ref);
384  const coff_relocation *I = getFirstReloc(Sec, Data, base());
385  if (I)
386  I += getNumberOfRelocations(Sec, Data, base());
388  Ret.p = reinterpret_cast<uintptr_t>(I);
389  return relocation_iterator(RelocationRef(Ret, this));
390 }
391 
392 // Initialize the pointer to the symbol table.
393 std::error_code COFFObjectFile::initSymbolTablePtr() {
394  if (COFFHeader)
395  if (std::error_code EC = getObject(
396  SymbolTable16, Data, base() + getPointerToSymbolTable(),
398  return EC;
399 
400  if (COFFBigObjHeader)
401  if (std::error_code EC = getObject(
402  SymbolTable32, Data, base() + getPointerToSymbolTable(),
404  return EC;
405 
406  // Find string table. The first four byte of the string table contains the
407  // total size of the string table, including the size field itself. If the
408  // string table is empty, the value of the first four byte would be 4.
411  const uint8_t *StringTableAddr = base() + StringTableOffset;
412  const ulittle32_t *StringTableSizePtr;
413  if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
414  return EC;
415  StringTableSize = *StringTableSizePtr;
416  if (std::error_code EC =
417  getObject(StringTable, Data, StringTableAddr, StringTableSize))
418  return EC;
419 
420  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
421  // tools like cvtres write a size of 0 for an empty table instead of 4.
422  if (StringTableSize < 4)
423  StringTableSize = 4;
424 
425  // Check that the string table is null terminated if has any in it.
426  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
428  return std::error_code();
429 }
430 
432  if (PE32Header)
433  return PE32Header->ImageBase;
434  else if (PE32PlusHeader)
435  return PE32PlusHeader->ImageBase;
436  // This actually comes up in practice.
437  return 0;
438 }
439 
440 // Returns the file offset for the given VA.
441 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
442  uint64_t ImageBase = getImageBase();
443  uint64_t Rva = Addr - ImageBase;
444  assert(Rva <= UINT32_MAX);
445  return getRvaPtr((uint32_t)Rva, Res);
446 }
447 
448 // Returns the file offset for the given RVA.
449 std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
450  for (const SectionRef &S : sections()) {
451  const coff_section *Section = getCOFFSection(S);
452  uint32_t SectionStart = Section->VirtualAddress;
453  uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
454  if (SectionStart <= Addr && Addr < SectionEnd) {
455  uint32_t Offset = Addr - SectionStart;
456  Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
457  return std::error_code();
458  }
459  }
461 }
462 
463 std::error_code
465  ArrayRef<uint8_t> &Contents) const {
466  for (const SectionRef &S : sections()) {
467  const coff_section *Section = getCOFFSection(S);
468  uint32_t SectionStart = Section->VirtualAddress;
469  // Check if this RVA is within the section bounds. Be careful about integer
470  // overflow.
471  uint32_t OffsetIntoSection = RVA - SectionStart;
472  if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
473  Size <= Section->VirtualSize - OffsetIntoSection) {
474  uintptr_t Begin =
475  uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
476  Contents =
477  ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
478  return std::error_code();
479  }
480  }
482 }
483 
484 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
485 // table entry.
486 std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
487  StringRef &Name) const {
488  uintptr_t IntPtr = 0;
489  if (std::error_code EC = getRvaPtr(Rva, IntPtr))
490  return EC;
491  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
492  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
493  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
494  return std::error_code();
495 }
496 
497 std::error_code
499  const codeview::DebugInfo *&PDBInfo,
500  StringRef &PDBFileName) const {
501  ArrayRef<uint8_t> InfoBytes;
502  if (std::error_code EC = getRvaAndSizeAsBytes(
503  DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
504  return EC;
505  if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
507  PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
508  InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
509  PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
510  InfoBytes.size());
511  // Truncate the name at the first null byte. Ignore any padding.
512  PDBFileName = PDBFileName.split('\0').first;
513  return std::error_code();
514 }
515 
516 std::error_code
518  StringRef &PDBFileName) const {
519  for (const debug_directory &D : debug_directories())
521  return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
522  // If we get here, there is no PDB info to return.
523  PDBInfo = nullptr;
524  PDBFileName = StringRef();
525  return std::error_code();
526 }
527 
528 // Find the import table.
529 std::error_code COFFObjectFile::initImportTablePtr() {
530  // First, we get the RVA of the import table. If the file lacks a pointer to
531  // the import table, do nothing.
532  const data_directory *DataEntry;
533  if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
534  return std::error_code();
535 
536  // Do nothing if the pointer to import table is NULL.
537  if (DataEntry->RelativeVirtualAddress == 0)
538  return std::error_code();
539 
540  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
541 
542  // Find the section that contains the RVA. This is needed because the RVA is
543  // the import table's memory address which is different from its file offset.
544  uintptr_t IntPtr = 0;
545  if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
546  return EC;
547  if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
548  return EC;
549  ImportDirectory = reinterpret_cast<
550  const coff_import_directory_table_entry *>(IntPtr);
551  return std::error_code();
552 }
553 
554 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
555 std::error_code COFFObjectFile::initDelayImportTablePtr() {
556  const data_directory *DataEntry;
558  return std::error_code();
559  if (DataEntry->RelativeVirtualAddress == 0)
560  return std::error_code();
561 
562  uint32_t RVA = DataEntry->RelativeVirtualAddress;
563  NumberOfDelayImportDirectory = DataEntry->Size /
565 
566  uintptr_t IntPtr = 0;
567  if (std::error_code EC = getRvaPtr(RVA, IntPtr))
568  return EC;
569  DelayImportDirectory = reinterpret_cast<
570  const delay_import_directory_table_entry *>(IntPtr);
571  return std::error_code();
572 }
573 
574 // Find the export table.
575 std::error_code COFFObjectFile::initExportTablePtr() {
576  // First, we get the RVA of the export table. If the file lacks a pointer to
577  // the export table, do nothing.
578  const data_directory *DataEntry;
579  if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
580  return std::error_code();
581 
582  // Do nothing if the pointer to export table is NULL.
583  if (DataEntry->RelativeVirtualAddress == 0)
584  return std::error_code();
585 
586  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
587  uintptr_t IntPtr = 0;
588  if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
589  return EC;
590  ExportDirectory =
591  reinterpret_cast<const export_directory_table_entry *>(IntPtr);
592  return std::error_code();
593 }
594 
595 std::error_code COFFObjectFile::initBaseRelocPtr() {
596  const data_directory *DataEntry;
598  return std::error_code();
599  if (DataEntry->RelativeVirtualAddress == 0)
600  return std::error_code();
601 
602  uintptr_t IntPtr = 0;
603  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
604  return EC;
605  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
606  IntPtr);
607  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
608  IntPtr + DataEntry->Size);
609  return std::error_code();
610 }
611 
612 std::error_code COFFObjectFile::initDebugDirectoryPtr() {
613  // Get the RVA of the debug directory. Do nothing if it does not exist.
614  const data_directory *DataEntry;
615  if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
616  return std::error_code();
617 
618  // Do nothing if the RVA is NULL.
619  if (DataEntry->RelativeVirtualAddress == 0)
620  return std::error_code();
621 
622  // Check that the size is a multiple of the entry size.
623  if (DataEntry->Size % sizeof(debug_directory) != 0)
625 
626  uintptr_t IntPtr = 0;
627  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
628  return EC;
629  DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
630  if (std::error_code EC = getRvaPtr(
631  DataEntry->RelativeVirtualAddress + DataEntry->Size, IntPtr))
632  return EC;
633  DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(IntPtr);
634  return std::error_code();
635 }
636 
638  : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
639  COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
640  DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
641  SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
642  ImportDirectory(nullptr),
643  DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
644  ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
645  DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
646  // Check that we at least have enough room for a header.
647  if (!checkSize(Data, EC, sizeof(coff_file_header)))
648  return;
649 
650  // The current location in the file where we are looking at.
651  uint64_t CurPtr = 0;
652 
653  // PE header is optional and is present only in executables. If it exists,
654  // it is placed right after COFF header.
655  bool HasPEHeader = false;
656 
657  // Check if this is a PE/COFF file.
658  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
659  // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
660  // PE signature to find 'normal' COFF header.
661  const auto *DH = reinterpret_cast<const dos_header *>(base());
662  if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
663  CurPtr = DH->AddressOfNewExeHeader;
664  // Check the PE magic bytes. ("PE\0\0")
665  if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
667  return;
668  }
669  CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
670  HasPEHeader = true;
671  }
672  }
673 
674  if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
675  return;
676 
677  // It might be a bigobj file, let's check. Note that COFF bigobj and COFF
678  // import libraries share a common prefix but bigobj is more restrictive.
679  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
680  COFFHeader->NumberOfSections == uint16_t(0xffff) &&
681  checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
682  if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
683  return;
684 
685  // Verify that we are dealing with bigobj.
686  if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
687  std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
688  sizeof(COFF::BigObjMagic)) == 0) {
689  COFFHeader = nullptr;
690  CurPtr += sizeof(coff_bigobj_file_header);
691  } else {
692  // It's not a bigobj.
693  COFFBigObjHeader = nullptr;
694  }
695  }
696  if (COFFHeader) {
697  // The prior checkSize call may have failed. This isn't a hard error
698  // because we were just trying to sniff out bigobj.
699  EC = std::error_code();
700  CurPtr += sizeof(coff_file_header);
701 
702  if (COFFHeader->isImportLibrary())
703  return;
704  }
705 
706  if (HasPEHeader) {
707  const pe32_header *Header;
708  if ((EC = getObject(Header, Data, base() + CurPtr)))
709  return;
710 
711  const uint8_t *DataDirAddr;
712  uint64_t DataDirSize;
713  if (Header->Magic == COFF::PE32Header::PE32) {
714  PE32Header = Header;
715  DataDirAddr = base() + CurPtr + sizeof(pe32_header);
716  DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
717  } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
718  PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
719  DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
720  DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
721  } else {
722  // It's neither PE32 nor PE32+.
724  return;
725  }
726  if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
727  return;
728  }
729 
730  if (COFFHeader)
731  CurPtr += COFFHeader->SizeOfOptionalHeader;
732 
733  if ((EC = getObject(SectionTable, Data, base() + CurPtr,
734  (uint64_t)getNumberOfSections() * sizeof(coff_section))))
735  return;
736 
737  // Initialize the pointer to the symbol table.
738  if (getPointerToSymbolTable() != 0) {
739  if ((EC = initSymbolTablePtr())) {
740  SymbolTable16 = nullptr;
741  SymbolTable32 = nullptr;
742  StringTable = nullptr;
743  StringTableSize = 0;
744  }
745  } else {
746  // We had better not have any symbols if we don't have a symbol table.
747  if (getNumberOfSymbols() != 0) {
749  return;
750  }
751  }
752 
753  // Initialize the pointer to the beginning of the import table.
754  if ((EC = initImportTablePtr()))
755  return;
756  if ((EC = initDelayImportTablePtr()))
757  return;
758 
759  // Initialize the pointer to the export table.
760  if ((EC = initExportTablePtr()))
761  return;
762 
763  // Initialize the pointer to the base relocation table.
764  if ((EC = initBaseRelocPtr()))
765  return;
766 
767  // Initialize the pointer to the export table.
768  if ((EC = initDebugDirectoryPtr()))
769  return;
770 
771  EC = std::error_code();
772 }
773 
776  Ret.p = getSymbolTable();
777  return basic_symbol_iterator(SymbolRef(Ret, this));
778 }
779 
781  // The symbol table ends where the string table begins.
783  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
784  return basic_symbol_iterator(SymbolRef(Ret, this));
785 }
786 
788  if (!ImportDirectory)
789  return import_directory_end();
790  if (ImportDirectory->isNull())
791  return import_directory_end();
793  ImportDirectoryEntryRef(ImportDirectory, 0, this));
794 }
795 
798  ImportDirectoryEntryRef(nullptr, -1, this));
799 }
800 
804  DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
805 }
806 
811  DelayImportDirectory, NumberOfDelayImportDirectory, this));
812 }
813 
816  ExportDirectoryEntryRef(ExportDirectory, 0, this));
817 }
818 
820  if (!ExportDirectory)
821  return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
822  ExportDirectoryEntryRef Ref(ExportDirectory,
823  ExportDirectory->AddressTableEntries, this);
824  return export_directory_iterator(Ref);
825 }
826 
829  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
830  return section_iterator(SectionRef(Ret, this));
831 }
832 
835  int NumSections =
836  COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
837  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
838  return section_iterator(SectionRef(Ret, this));
839 }
840 
842  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
843 }
844 
846  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
847 }
848 
850  return getArch() == Triple::x86_64 ? 8 : 4;
851 }
852 
854  switch(getMachine()) {
856  return "COFF-i386";
858  return "COFF-x86-64";
860  return "COFF-ARM";
862  return "COFF-ARM64";
863  default:
864  return "COFF-<unknown arch>";
865  }
866 }
867 
868 unsigned COFFObjectFile::getArch() const {
869  switch (getMachine()) {
871  return Triple::x86;
873  return Triple::x86_64;
875  return Triple::thumb;
877  return Triple::aarch64;
878  default:
879  return Triple::UnknownArch;
880  }
881 }
882 
886 }
887 
892 }
893 
897 }
898 
901 }
902 
903 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
904  Res = PE32Header;
905  return std::error_code();
906 }
907 
908 std::error_code
910  Res = PE32PlusHeader;
911  return std::error_code();
912 }
913 
914 std::error_code
916  const data_directory *&Res) const {
917  // Error if if there's no data directory or the index is out of range.
918  if (!DataDirectory) {
919  Res = nullptr;
921  }
922  assert(PE32Header || PE32PlusHeader);
923  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
924  : PE32PlusHeader->NumberOfRvaAndSize;
925  if (Index >= NumEnt) {
926  Res = nullptr;
928  }
929  Res = &DataDirectory[Index];
930  return std::error_code();
931 }
932 
933 std::error_code COFFObjectFile::getSection(int32_t Index,
934  const coff_section *&Result) const {
935  Result = nullptr;
937  return std::error_code();
938  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
939  // We already verified the section table data, so no need to check again.
940  Result = SectionTable + (Index - 1);
941  return std::error_code();
942  }
944 }
945 
946 std::error_code COFFObjectFile::getString(uint32_t Offset,
947  StringRef &Result) const {
948  if (StringTableSize <= 4)
949  // Tried to get a string from an empty string table.
951  if (Offset >= StringTableSize)
953  Result = StringRef(StringTable + Offset);
954  return std::error_code();
955 }
956 
958  StringRef &Res) const {
959  return getSymbolName(Symbol.getGeneric(), Res);
960 }
961 
962 std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
963  StringRef &Res) const {
964  // Check for string table entry. First 4 bytes are 0.
965  if (Symbol->Name.Offset.Zeroes == 0) {
966  if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
967  return EC;
968  return std::error_code();
969  }
970 
971  if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
972  // Null terminated, let ::strlen figure out the length.
973  Res = StringRef(Symbol->Name.ShortName);
974  else
975  // Not null terminated, use all 8 bytes.
976  Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
977  return std::error_code();
978 }
979 
982  const uint8_t *Aux = nullptr;
983 
984  size_t SymbolSize = getSymbolTableEntrySize();
985  if (Symbol.getNumberOfAuxSymbols() > 0) {
986  // AUX data comes immediately after the symbol in COFF
987  Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
988 # ifndef NDEBUG
989  // Verify that the Aux symbol points to a valid entry in the symbol table.
990  uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
991  if (Offset < getPointerToSymbolTable() ||
992  Offset >=
993  getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
994  report_fatal_error("Aux Symbol data was outside of symbol table.");
995 
996  assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
997  "Aux Symbol data did not point to the beginning of a symbol");
998 # endif
999  }
1000  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
1001 }
1002 
1003 std::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
1004  StringRef &Res) const {
1005  StringRef Name;
1006  if (Sec->Name[COFF::NameSize - 1] == 0)
1007  // Null terminated, let ::strlen figure out the length.
1008  Name = Sec->Name;
1009  else
1010  // Not null terminated, use all 8 bytes.
1011  Name = StringRef(Sec->Name, COFF::NameSize);
1012 
1013  // Check for string table entry. First byte is '/'.
1014  if (Name.startswith("/")) {
1015  uint32_t Offset;
1016  if (Name.startswith("//")) {
1017  if (decodeBase64StringEntry(Name.substr(2), Offset))
1019  } else {
1020  if (Name.substr(1).getAsInteger(10, Offset))
1022  }
1023  if (std::error_code EC = getString(Offset, Name))
1024  return EC;
1025  }
1026 
1027  Res = Name;
1028  return std::error_code();
1029 }
1030 
1031 uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
1032  // SizeOfRawData and VirtualSize change what they represent depending on
1033  // whether or not we have an executable image.
1034  //
1035  // For object files, SizeOfRawData contains the size of section's data;
1036  // VirtualSize should be zero but isn't due to buggy COFF writers.
1037  //
1038  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
1039  // actual section size is in VirtualSize. It is possible for VirtualSize to
1040  // be greater than SizeOfRawData; the contents past that point should be
1041  // considered to be zero.
1042  if (getDOSHeader())
1043  return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
1044  return Sec->SizeOfRawData;
1045 }
1046 
1047 std::error_code
1049  ArrayRef<uint8_t> &Res) const {
1050  // In COFF, a virtual section won't have any in-file
1051  // content, so the file pointer to the content will be zero.
1052  if (Sec->PointerToRawData == 0)
1054  // The only thing that we need to verify is that the contents is contained
1055  // within the file bounds. We don't need to make sure it doesn't cover other
1056  // data, as there's nothing that says that is not allowed.
1057  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
1059  if (checkOffset(Data, ConStart, SectionSize))
1061  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
1062  return std::error_code();
1063 }
1064 
1065 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
1066  return reinterpret_cast<const coff_relocation*>(Rel.p);
1067 }
1068 
1070  Rel.p = reinterpret_cast<uintptr_t>(
1071  reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
1072 }
1073 
1075  const coff_relocation *R = toRel(Rel);
1076  return R->VirtualAddress;
1077 }
1078 
1080  const coff_relocation *R = toRel(Rel);
1081  DataRefImpl Ref;
1083  return symbol_end();
1084  if (SymbolTable16)
1085  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
1086  else if (SymbolTable32)
1087  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
1088  else
1089  llvm_unreachable("no symbol table pointer!");
1090  return symbol_iterator(SymbolRef(Ref, this));
1091 }
1092 
1094  const coff_relocation* R = toRel(Rel);
1095  return R->Type;
1096 }
1097 
1098 const coff_section *
1100  return toSec(Section.getRawDataRefImpl());
1101 }
1102 
1104  if (SymbolTable16)
1105  return toSymb<coff_symbol16>(Ref);
1106  if (SymbolTable32)
1107  return toSymb<coff_symbol32>(Ref);
1108  llvm_unreachable("no symbol table pointer!");
1109 }
1110 
1112  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1113 }
1114 
1115 const coff_relocation *
1117  return toRel(Reloc.getRawDataRefImpl());
1118 }
1119 
1122  const coff_relocation *I = getFirstReloc(Sec, Data, base());
1123  const coff_relocation *E = I;
1124  if (I)
1125  E += getNumberOfRelocations(Sec, Data, base());
1126  return make_range(I, E);
1127 }
1128 
1129 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
1130  case COFF::reloc_type: \
1131  Res = #reloc_type; \
1132  break;
1133 
1135  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1136  const coff_relocation *Reloc = toRel(Rel);
1137  StringRef Res;
1138  switch (getMachine()) {
1140  switch (Reloc->Type) {
1158  default:
1159  Res = "Unknown";
1160  }
1161  break;
1163  switch (Reloc->Type) {
1179  default:
1180  Res = "Unknown";
1181  }
1182  break;
1184  switch (Reloc->Type) {
1196  default:
1197  Res = "Unknown";
1198  }
1199  break;
1200  default:
1201  Res = "Unknown";
1202  }
1203  Result.append(Res.begin(), Res.end());
1204 }
1205 
1206 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1207 
1209  return !DataDirectory;
1210 }
1211 
1214  return ImportTable == Other.ImportTable && Index == Other.Index;
1215 }
1216 
1218  ++Index;
1219  if (ImportTable[Index].isNull()) {
1220  Index = -1;
1221  ImportTable = nullptr;
1222  }
1223 }
1224 
1226  const coff_import_directory_table_entry *&Result) const {
1227  return getObject(Result, OwningObject->Data, ImportTable + Index);
1228 }
1229 
1231 makeImportedSymbolIterator(const COFFObjectFile *Object,
1232  uintptr_t Ptr, int Index) {
1233  if (Object->getBytesInAddress() == 4) {
1234  auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
1235  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1236  }
1237  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
1238  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1239 }
1240 
1242 importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
1243  uintptr_t IntPtr = 0;
1244  Object->getRvaPtr(RVA, IntPtr);
1245  return makeImportedSymbolIterator(Object, IntPtr, 0);
1246 }
1247 
1249 importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
1250  uintptr_t IntPtr = 0;
1251  Object->getRvaPtr(RVA, IntPtr);
1252  // Forward the pointer to the last entry which is null.
1253  int Index = 0;
1254  if (Object->getBytesInAddress() == 4) {
1255  auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
1256  while (*Entry++)
1257  ++Index;
1258  } else {
1259  auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
1260  while (*Entry++)
1261  ++Index;
1262  }
1263  return makeImportedSymbolIterator(Object, IntPtr, Index);
1264 }
1265 
1268  return importedSymbolBegin(ImportTable[Index].ImportAddressTableRVA,
1269  OwningObject);
1270 }
1271 
1274  return importedSymbolEnd(ImportTable[Index].ImportAddressTableRVA,
1275  OwningObject);
1276 }
1277 
1281 }
1282 
1284  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
1285  OwningObject);
1286 }
1287 
1289  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
1290  OwningObject);
1291 }
1292 
1296 }
1297 
1298 std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
1299  uintptr_t IntPtr = 0;
1300  if (std::error_code EC =
1301  OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
1302  return EC;
1303  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1304  return std::error_code();
1305 }
1306 
1307 std::error_code
1309  Result = ImportTable[Index].ImportLookupTableRVA;
1310  return std::error_code();
1311 }
1312 
1313 std::error_code
1315  Result = ImportTable[Index].ImportAddressTableRVA;
1316  return std::error_code();
1317 }
1318 
1321  return Table == Other.Table && Index == Other.Index;
1322 }
1323 
1325  ++Index;
1326 }
1327 
1330  return importedSymbolBegin(Table[Index].DelayImportNameTable,
1331  OwningObject);
1332 }
1333 
1336  return importedSymbolEnd(Table[Index].DelayImportNameTable,
1337  OwningObject);
1338 }
1339 
1343 }
1344 
1345 std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
1346  uintptr_t IntPtr = 0;
1347  if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
1348  return EC;
1349  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1350  return std::error_code();
1351 }
1352 
1353 std::error_code DelayImportDirectoryEntryRef::
1355  Result = Table;
1356  return std::error_code();
1357 }
1358 
1359 std::error_code DelayImportDirectoryEntryRef::
1360 getImportAddress(int AddrIndex, uint64_t &Result) const {
1361  uint32_t RVA = Table[Index].DelayImportAddressTable +
1362  AddrIndex * (OwningObject->is64() ? 8 : 4);
1363  uintptr_t IntPtr = 0;
1364  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1365  return EC;
1366  if (OwningObject->is64())
1367  Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1368  else
1369  Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1370  return std::error_code();
1371 }
1372 
1375  return ExportTable == Other.ExportTable && Index == Other.Index;
1376 }
1377 
1379  ++Index;
1380 }
1381 
1382 // Returns the name of the current export symbol. If the symbol is exported only
1383 // by ordinal, the empty string is set as a result.
1384 std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
1385  uintptr_t IntPtr = 0;
1386  if (std::error_code EC =
1387  OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
1388  return EC;
1389  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1390  return std::error_code();
1391 }
1392 
1393 // Returns the starting ordinal number.
1394 std::error_code
1396  Result = ExportTable->OrdinalBase;
1397  return std::error_code();
1398 }
1399 
1400 // Returns the export ordinal of the current export symbol.
1401 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1402  Result = ExportTable->OrdinalBase + Index;
1403  return std::error_code();
1404 }
1405 
1406 // Returns the address of the current export symbol.
1407 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1408  uintptr_t IntPtr = 0;
1409  if (std::error_code EC =
1410  OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
1411  return EC;
1412  const export_address_table_entry *entry =
1413  reinterpret_cast<const export_address_table_entry *>(IntPtr);
1414  Result = entry[Index].ExportRVA;
1415  return std::error_code();
1416 }
1417 
1418 // Returns the name of the current export symbol. If the symbol is exported only
1419 // by ordinal, the empty string is set as a result.
1420 std::error_code
1422  uintptr_t IntPtr = 0;
1423  if (std::error_code EC =
1424  OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
1425  return EC;
1426  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
1427 
1428  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
1429  int Offset = 0;
1430  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
1431  I < E; ++I, ++Offset) {
1432  if (*I != Index)
1433  continue;
1434  if (std::error_code EC =
1435  OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
1436  return EC;
1437  const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1438  if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
1439  return EC;
1440  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1441  return std::error_code();
1442  }
1443  Result = "";
1444  return std::error_code();
1445 }
1446 
1447 std::error_code ExportDirectoryEntryRef::isForwarder(bool &Result) const {
1448  const data_directory *DataEntry;
1449  if (auto EC = OwningObject->getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
1450  return EC;
1451  uint32_t RVA;
1452  if (auto EC = getExportRVA(RVA))
1453  return EC;
1454  uint32_t Begin = DataEntry->RelativeVirtualAddress;
1455  uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
1456  Result = (Begin <= RVA && RVA < End);
1457  return std::error_code();
1458 }
1459 
1460 std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
1461  uint32_t RVA;
1462  if (auto EC = getExportRVA(RVA))
1463  return EC;
1464  uintptr_t IntPtr = 0;
1465  if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
1466  return EC;
1467  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1468  return std::error_code();
1469 }
1470 
1472 operator==(const ImportedSymbolRef &Other) const {
1473  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1474  && Index == Other.Index;
1475 }
1476 
1478  ++Index;
1479 }
1480 
1481 std::error_code
1483  uint32_t RVA;
1484  if (Entry32) {
1485  // If a symbol is imported only by ordinal, it has no name.
1486  if (Entry32[Index].isOrdinal())
1487  return std::error_code();
1488  RVA = Entry32[Index].getHintNameRVA();
1489  } else {
1490  if (Entry64[Index].isOrdinal())
1491  return std::error_code();
1492  RVA = Entry64[Index].getHintNameRVA();
1493  }
1494  uintptr_t IntPtr = 0;
1495  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1496  return EC;
1497  // +2 because the first two bytes is hint.
1498  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1499  return std::error_code();
1500 }
1501 
1502 std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
1503  if (Entry32)
1504  Result = Entry32[Index].isOrdinal();
1505  else
1506  Result = Entry64[Index].isOrdinal();
1507  return std::error_code();
1508 }
1509 
1510 std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
1511  if (Entry32)
1512  Result = Entry32[Index].getHintNameRVA();
1513  else
1514  Result = Entry64[Index].getHintNameRVA();
1515  return std::error_code();
1516 }
1517 
1518 std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1519  uint32_t RVA;
1520  if (Entry32) {
1521  if (Entry32[Index].isOrdinal()) {
1522  Result = Entry32[Index].getOrdinal();
1523  return std::error_code();
1524  }
1525  RVA = Entry32[Index].getHintNameRVA();
1526  } else {
1527  if (Entry64[Index].isOrdinal()) {
1528  Result = Entry64[Index].getOrdinal();
1529  return std::error_code();
1530  }
1531  RVA = Entry64[Index].getHintNameRVA();
1532  }
1533  uintptr_t IntPtr = 0;
1534  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1535  return EC;
1536  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1537  return std::error_code();
1538 }
1539 
1542  std::error_code EC;
1543  std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
1544  if (EC)
1545  return EC;
1546  return std::move(Ret);
1547 }
1548 
1549 bool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
1550  return Header == Other.Header && Index == Other.Index;
1551 }
1552 
1554  // Header->BlockSize is the size of the current block, including the
1555  // size of the header itself.
1556  uint32_t Size = sizeof(*Header) +
1557  sizeof(coff_base_reloc_block_entry) * (Index + 1);
1558  if (Size == Header->BlockSize) {
1559  // .reloc contains a list of base relocation blocks. Each block
1560  // consists of the header followed by entries. The header contains
1561  // how many entories will follow. When we reach the end of the
1562  // current block, proceed to the next block.
1563  Header = reinterpret_cast<const coff_base_reloc_block_header *>(
1564  reinterpret_cast<const uint8_t *>(Header) + Size);
1565  Index = 0;
1566  } else {
1567  ++Index;
1568  }
1569 }
1570 
1571 std::error_code BaseRelocRef::getType(uint8_t &Type) const {
1572  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1573  Type = Entry[Index].getType();
1574  return std::error_code();
1575 }
1576 
1577 std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
1578  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1579  Result = Header->PageRVA + Entry[Index].getOffset();
1580  return std::error_code();
1581 }
std::error_code getRVA(uint32_t &Result) const
uint32_t getNumberOfSections() const
Definition: Object/COFF.h:687
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:494
bool operator==(const ImportDirectoryEntryRef &Other) const
bool isOrdinal() const
Definition: Object/COFF.h:180
static uint32_t getNumberOfRelocations(const coff_section *Sec, MemoryBufferRef M, const uint8_t *base)
std::error_code getImportTableEntry(const coff_import_directory_table_entry *&Result) const
Represents either an error or a value T.
Definition: ErrorOr.h:68
The 64-bit PE header that follows the COFF header.
Definition: Object/COFF.h:128
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
section_iterator section_begin() const override
support::ulittle16_t Machine
Definition: Object/COFF.h:64
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:192
friend class SymbolRef
Definition: ObjectFile.h:198
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
iterator_range< imported_symbol_iterator > imported_symbols() const
bool isNull() const
Definition: Object/COFF.h:521
support::ulittle32_t Name
Definition: Object/COFF.h:201
support::ulittle32_t OrdinalBase
Definition: Object/COFF.h:216
const void * getRawPtr() const
Definition: Object/COFF.h:271
std::error_code getDelayImportTable(const delay_import_directory_table_entry *&Result) const
friend class SectionRef
Definition: ObjectFile.h:211
COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool hasExtendedRelocations() const
Definition: Object/COFF.h:417
std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const
imported_symbol_iterator imported_symbol_begin() const
const uint8_t * base() const
Definition: ObjectFile.h:186
support::ulittle32_t VirtualAddress
Definition: Object/COFF.h:406
import_directory_iterator import_directory_end() const
Definition: Object/COFF.h:210
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
void moveSectionNext(DataRefImpl &Sec) const override
static std::error_code getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
std::error_code getDebugPDBInfo(const debug_directory *DebugDir, const codeview::DebugInfo *&Info, StringRef &PDBFileName) const
Get PDB information out of a codeview debug directory entry.
void moveRelocationNext(DataRefImpl &Rel) const override
static ErrorOr< std::unique_ptr< COFFObjectFile > > createCOFFObjectFile(MemoryBufferRef Object)
This class is the base class for all object file types.
Definition: ObjectFile.h:178
support::ulittle16_t NumberOfSections
Definition: Object/COFF.h:65
static const coff_relocation * getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base)
support::ulittle32_t PointerToRelocations
Definition: Object/COFF.h:409
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
const char * getBufferStart() const
Definition: MemoryBuffer.h:173
bool isSectionCompressed(DataRefImpl Sec) const override
Definition: Object/COFF.h:224
uint32_t getValue() const
Definition: Object/COFF.h:302
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:428
std::error_code getImportAddressTableRVA(uint32_t &Result) const
uint32_t getAlignment() const
Definition: Object/COFF.h:421
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
const coff_section * getCOFFSection(const SectionRef &Section) const
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const
static const char BigObjMagic[]
Definition: Support/COFF.h:39
support::ulittle32_t DelayImportAddressTable
Definition: Object/COFF.h:203
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
basic_symbol_iterator symbol_end() const override
char ShortName[COFF::NameSize]
Definition: Object/COFF.h:259
std::error_code isOrdinal(bool &Result) const
support::ulittle64_t ImageBase
Definition: Object/COFF.h:137
support::ulittle32_t NameRVA
Definition: Object/COFF.h:215
uint16_t getOrdinal() const
Definition: Object/COFF.h:182
friend class ExportDirectoryEntryRef
Definition: Object/COFF.h:613
Definition: Object/COFF.h:177
uint64_t getSectionAlignment(DataRefImpl Sec) const override
char Name[COFF::NameSize]
Definition: Object/COFF.h:404
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:41
support::ulittle16_t SizeOfOptionalHeader
Definition: Object/COFF.h:69
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
bool operator==(const ExportDirectoryEntryRef &Other) const
iterator_range< base_reloc_iterator > base_relocs() const
std::error_code getOrdinal(uint32_t &Result) const
Tagged union holding either a T or a Error.
content_iterator< ImportedSymbolRef > imported_symbol_iterator
Definition: Object/COFF.h:37
static imported_symbol_iterator importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object)
iterator_range< import_directory_iterator > import_directories() const
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: Support/COFF.h:673
union llvm::object::coff_symbol_generic::@114 Name
support::ulittle32_t VirtualSize
Definition: Object/COFF.h:405
#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
uint32_t getSymbolFlags(DataRefImpl Symb) const override
std::error_code getName(StringRef &Result) const
uint64_t getSectionAddress(DataRefImpl Sec) const override
iterator_range< const coff_relocation * > getRelocations(const coff_section *Sec) const
std::error_code getSymbolName(StringRef &Result) const
void moveSymbolNext(DataRefImpl &Symb) const override
support::ulittle32_t NamePointerRVA
Definition: Object/COFF.h:220
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
support::ulittle32_t ExportRVA
Definition: Object/COFF.h:225
support::ulittle32_t NameRVA
Definition: Object/COFF.h:519
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getArch() const override
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
imported_symbol_iterator imported_symbol_end() const
iterator begin() const
Definition: StringRef.h:103
unsigned getSectionID(SectionRef Sec) const
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:36
static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
support::ulittle16_t Magic
Definition: Object/COFF.h:93
std::error_code getForwardTo(StringRef &Result) const
#define P(N)
support::ulittle32_t Characteristics
Definition: Object/COFF.h:413
support::ulittle32_t NumberOfRvaAndSize
Definition: Object/COFF.h:157
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
uint16_t getMachine() const
Definition: Object/COFF.h:655
int getType() const
Definition: Object/COFF.h:606
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code getDataDirectory(uint32_t index, const data_directory *&Res) const
const char * getBufferEnd() const
Definition: MemoryBuffer.h:174
int32_t getSectionNumber() const
Definition: Object/COFF.h:304
The 32-bit PE header that follows the COFF header.
Definition: Object/COFF.h:92
std::error_code getImportLookupTableRVA(uint32_t &Result) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
export_directory_iterator export_directory_end() const
base_reloc_iterator base_reloc_begin() const
support::ulittle32_t RelativeVirtualAddress
Definition: Object/COFF.h:161
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
uint32_t Offset
std::error_code getOrdinal(uint16_t &Result) const
uint8_t getComplexType() const
Definition: Object/COFF.h:332
std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const
static const unsigned End
A function that returns a base type.
Definition: Support/COFF.h:229
support::ulittle32_t ImportAddressTableRVA
Definition: Object/COFF.h:520
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
iterator_range< const debug_directory * > debug_directories() const
Definition: Object/COFF.h:786
support::ulittle16_t Type
Definition: Object/COFF.h:438
support::ulittle32_t OrdinalTableRVA
Definition: Object/COFF.h:221
COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const
section_iterator_range sections() const
Definition: ObjectFile.h:257
export_directory_iterator export_directory_begin() const
static imported_symbol_iterator makeImportedSymbolIterator(const COFFObjectFile *Object, uintptr_t Ptr, int Index)
support::ulittle32_t SizeOfRawData
Definition: Object/COFF.h:407
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:66
uint64_t getRelocationType(DataRefImpl Rel) const override
imported_symbol_iterator lookup_table_end() const
StringRef getFileFormatName() const override
content_iterator< ImportDirectoryEntryRef > import_directory_iterator
Definition: Object/COFF.h:32
support::ulittle32_t VirtualAddress
Definition: Object/COFF.h:436
support::ulittle32_t SymbolTableIndex
Definition: Object/COFF.h:437
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: Object/COFF.h:515
size_t getBufferSize() const
Definition: MemoryBuffer.h:175
friend class ImportDirectoryEntryRef
Definition: Object/COFF.h:612
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:126
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
import_directory_iterator import_directory_begin() const
support::ulittle32_t PointerToRawData
Definition: Object/COFF.h:408
friend class RelocationRef
Definition: ObjectFile.h:232
bool isWeakExternal() const
Definition: Object/COFF.h:354
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
basic_symbol_iterator symbol_begin() const override
std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size, ArrayRef< uint8_t > &Contents) const
Given an RVA base and size, returns a valid array of bytes or an error code if the RVA and size is no...
static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result)
iterator_range< imported_symbol_iterator > lookup_table_symbols() const
Definition: Object/COFF.h:604
imported_symbol_iterator imported_symbol_end() const
content_iterator< ExportDirectoryEntryRef > export_directory_iterator
Definition: Object/COFF.h:36
bool isSectionData(DataRefImpl Sec) const override
detail::packed_endian_specific_integral< int16_t, little, unaligned > little16_t
Definition: Endian.h:240
const dos_header * getDOSHeader() const
Definition: Object/COFF.h:790
imported_symbol_iterator lookup_table_begin() const
The DOS compatible header at the front of all PE/COFF executables.
Definition: Object/COFF.h:41
A range adaptor for a pair of iterators.
section_iterator section_end() const override
support::ulittle32_t AddressOfRawData
Definition: Object/COFF.h:172
MemoryBufferRef Data
Definition: Binary.h:37
delay_import_directory_iterator delay_import_directory_begin() const
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:716
support::ulittle32_t Size
Definition: Object/COFF.h:162
uint8_t getNumberOfAuxSymbols() const
Definition: Object/COFF.h:325
unsigned getSymbolSectionID(SymbolRef Sym) const
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Definition: Endian.h:233
std::error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: ObjectFile.h:116
support::ulittle32_t ImageBase
Definition: Object/COFF.h:102
support::ulittle32_t Zeroes
Definition: Object/COFF.h:233
std::error_code getHintNameRVA(uint32_t &Result) const
const coff_relocation * getCOFFRelocation(const RelocationRef &Reloc) const
imported_symbol_iterator imported_symbol_begin() const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
delay_import_directory_iterator delay_import_directory_end() const
support::ulittle32_t NumberOfNamePointers
Definition: Object/COFF.h:218
std::error_code getPE32Header(const pe32_header *&Res) const
bool isSectionDefinition() const
Definition: Object/COFF.h:380
iterator_range< imported_symbol_iterator > imported_symbols() const
bool isSectionText(DataRefImpl Sec) const override
bool operator==(const DelayImportDirectoryEntryRef &Other) const
uintptr_t getSymbolTable() const
Definition: Object/COFF.h:648
const coff_symbol_generic * getGeneric() const
Definition: Object/COFF.h:275
std::error_code getDllName(StringRef &Result) const
bool operator==(const BaseRelocRef &Other) const
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
uint64_t getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:42
detail::packed_endian_specific_integral< uint64_t, little, unaligned > ulittle64_t
Definition: Endian.h:237
support::ulittle32_t ImportLookupTableRVA
Definition: Object/COFF.h:516
content_iterator< DelayImportDirectoryEntryRef > delay_import_directory_iterator
Definition: Object/COFF.h:35
support::ulittle32_t AddressTableEntries
Definition: Object/COFF.h:217
#define I(x, y, z)
Definition: MD5.cpp:54
static const char PEMagic[]
Definition: Support/COFF.h:37
size_t getSymbolTableEntrySize() const
Definition: Object/COFF.h:838
Definition: Object/COFF.h:198
iterator_range< export_directory_iterator > export_directories() const
bool isSectionVirtual(DataRefImpl Sec) const override
static imported_symbol_iterator importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object)
bool operator==(const ImportedSymbolRef &Other) const
uint64_t getSectionSize(DataRefImpl Sec) const override
support::ulittle16_t NumberOfRelocations
Definition: Object/COFF.h:411
uint32_t getNumberOfSymbols() const
Definition: Object/COFF.h:709
bool isAnyUndefined() const
Definition: Object/COFF.h:368
support::ulittle32_t SizeOfData
Definition: Object/COFF.h:171
bool isSectionBSS(DataRefImpl Sec) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
base_reloc_iterator base_reloc_end() const
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:235
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:180
std::error_code getSymbolName(StringRef &Result) const
std::error_code getOrdinalBase(uint32_t &Result) const
bool isNull(StringRef S)
Definition: YAMLTraits.h:479
LLVM Value Representation.
Definition: Value.h:71
support::ulittle32_t ExportAddressTableRVA
Definition: Object/COFF.h:219
iterator end() const
Definition: StringRef.h:105
support::ulittle32_t NumberOfRvaAndSize
Definition: Object/COFF.h:124
static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
std::error_code getType(uint8_t &Type) const
content_iterator< BaseRelocRef > base_reloc_iterator
Definition: Object/COFF.h:38
int * Ptr
uint32_t getPointerToSymbolTable() const
Definition: Object/COFF.h:694
std::error_code getName(StringRef &Result) const
uint32_t getHintNameRVA() const
Definition: Object/COFF.h:187
ArrayRef< uint8_t > getSymbolAuxData(COFFSymbolRef Symbol) const
const T * data() const
Definition: ArrayRef.h:138
std::error_code getSection(int32_t index, const coff_section *&Res) const
std::error_code isForwarder(bool &Result) const
std::error_code getExportRVA(uint32_t &Result) const
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:70
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition: MathExtras.h:638
iterator_range< delay_import_directory_iterator > delay_import_directories() const
support::ulittle32_t Offset
Definition: Object/COFF.h:234
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:466