LLVM  3.7.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/SmallString.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/COFF.h"
21 #include "llvm/Support/Debug.h"
23 #include <cctype>
24 #include <limits>
25 
26 using namespace llvm;
27 using namespace object;
28 
33 
34 // Returns false if size is greater than the buffer size. And sets ec.
35 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
36  if (M.getBufferSize() < Size) {
38  return false;
39  }
40  return true;
41 }
42 
43 static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
44  const uint64_t Size) {
45  if (Addr + Size < Addr || Addr + Size < Size ||
46  Addr + Size > uintptr_t(M.getBufferEnd()) ||
47  Addr < uintptr_t(M.getBufferStart())) {
49  }
50  return std::error_code();
51 }
52 
53 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
54 // Returns unexpected_eof if error.
55 template <typename T>
56 static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
57  const void *Ptr,
58  const uint64_t Size = sizeof(T)) {
59  uintptr_t Addr = uintptr_t(Ptr);
60  if (std::error_code EC = checkOffset(M, Addr, Size))
61  return EC;
62  Obj = reinterpret_cast<const T *>(Addr);
63  return std::error_code();
64 }
65 
66 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
67 // prefixed slashes.
68 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
69  assert(Str.size() <= 6 && "String too long, possible overflow.");
70  if (Str.size() > 6)
71  return true;
72 
73  uint64_t Value = 0;
74  while (!Str.empty()) {
75  unsigned CharVal;
76  if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
77  CharVal = Str[0] - 'A';
78  else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
79  CharVal = Str[0] - 'a' + 26;
80  else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
81  CharVal = Str[0] - '0' + 52;
82  else if (Str[0] == '+') // 62
83  CharVal = 62;
84  else if (Str[0] == '/') // 63
85  CharVal = 63;
86  else
87  return true;
88 
89  Value = (Value * 64) + CharVal;
90  Str = Str.substr(1);
91  }
92 
93  if (Value > std::numeric_limits<uint32_t>::max())
94  return true;
95 
96  Result = static_cast<uint32_t>(Value);
97  return false;
98 }
99 
100 template <typename coff_symbol_type>
101 const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
102  const coff_symbol_type *Addr =
103  reinterpret_cast<const coff_symbol_type *>(Ref.p);
104 
105  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
106 #ifndef NDEBUG
107  // Verify that the symbol points to a valid entry in the symbol table.
108  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
109 
110  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
111  "Symbol did not point to the beginning of a symbol");
112 #endif
113 
114  return Addr;
115 }
116 
117 const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
118  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
119 
120 # ifndef NDEBUG
121  // Verify that the section points to a valid entry in the section table.
122  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
123  report_fatal_error("Section was outside of section table.");
124 
125  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
126  assert(Offset % sizeof(coff_section) == 0 &&
127  "Section did not point to the beginning of a section");
128 # endif
129 
130  return Addr;
131 }
132 
134  auto End = reinterpret_cast<uintptr_t>(StringTable);
135  if (SymbolTable16) {
136  const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
137  Symb += 1 + Symb->NumberOfAuxSymbols;
138  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
139  } else if (SymbolTable32) {
140  const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
141  Symb += 1 + Symb->NumberOfAuxSymbols;
142  Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
143  } else {
144  llvm_unreachable("no symbol table pointer!");
145  }
146 }
147 
149  COFFSymbolRef Symb = getCOFFSymbol(Ref);
150  StringRef Result;
151  std::error_code EC = getSymbolName(Symb, Result);
152  if (EC)
153  return EC;
154  return Result;
155 }
156 
158  return getCOFFSymbol(Ref).getValue();
159 }
160 
162  uint64_t Result = getSymbolValue(Ref);
163  COFFSymbolRef Symb = getCOFFSymbol(Ref);
164  int32_t SectionNumber = Symb.getSectionNumber();
165 
166  if (Symb.isAnyUndefined() || Symb.isCommon() ||
167  COFF::isReservedSectionNumber(SectionNumber))
168  return Result;
169 
170  const coff_section *Section = nullptr;
171  if (std::error_code EC = getSection(SectionNumber, Section))
172  return EC;
173  Result += Section->VirtualAddress;
174  return Result;
175 }
176 
178  COFFSymbolRef Symb = getCOFFSymbol(Ref);
179  int32_t SectionNumber = Symb.getSectionNumber();
180 
181  if (Symb.isAnyUndefined())
182  return SymbolRef::ST_Unknown;
183  if (Symb.isFunctionDefinition())
184  return SymbolRef::ST_Function;
185  if (Symb.isCommon())
186  return SymbolRef::ST_Data;
187  if (Symb.isFileRecord())
188  return SymbolRef::ST_File;
189 
190  // TODO: perhaps we need a new symbol type ST_Section.
191  if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
192  return SymbolRef::ST_Debug;
193 
194  if (!COFF::isReservedSectionNumber(SectionNumber))
195  return SymbolRef::ST_Data;
196 
197  return SymbolRef::ST_Other;
198 }
199 
201  COFFSymbolRef Symb = getCOFFSymbol(Ref);
202  uint32_t Result = SymbolRef::SF_None;
203 
204  if (Symb.isExternal() || Symb.isWeakExternal())
205  Result |= SymbolRef::SF_Global;
206 
207  if (Symb.isWeakExternal())
208  Result |= SymbolRef::SF_Weak;
209 
211  Result |= SymbolRef::SF_Absolute;
212 
213  if (Symb.isFileRecord())
215 
216  if (Symb.isSectionDefinition())
218 
219  if (Symb.isCommon())
220  Result |= SymbolRef::SF_Common;
221 
222  if (Symb.isAnyUndefined())
223  Result |= SymbolRef::SF_Undefined;
224 
225  return Result;
226 }
227 
229  COFFSymbolRef Symb = getCOFFSymbol(Ref);
230  return Symb.getValue();
231 }
232 
233 std::error_code
235  section_iterator &Result) const {
236  COFFSymbolRef Symb = getCOFFSymbol(Ref);
238  Result = section_end();
239  } else {
240  const coff_section *Sec = nullptr;
241  if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
242  return EC;
243  DataRefImpl Ref;
244  Ref.p = reinterpret_cast<uintptr_t>(Sec);
245  Result = section_iterator(SectionRef(Ref, this));
246  }
247  return std::error_code();
248 }
249 
252  return Symb.getSectionNumber();
253 }
254 
256  const coff_section *Sec = toSec(Ref);
257  Sec += 1;
258  Ref.p = reinterpret_cast<uintptr_t>(Sec);
259 }
260 
261 std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
262  StringRef &Result) const {
263  const coff_section *Sec = toSec(Ref);
264  return getSectionName(Sec, Result);
265 }
266 
268  const coff_section *Sec = toSec(Ref);
269  return Sec->VirtualAddress;
270 }
271 
272 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
273  return getSectionSize(toSec(Ref));
274 }
275 
277  StringRef &Result) const {
278  const coff_section *Sec = toSec(Ref);
279  ArrayRef<uint8_t> Res;
280  std::error_code EC = getSectionContents(Sec, Res);
281  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
282  return EC;
283 }
284 
286  const coff_section *Sec = toSec(Ref);
287  return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1);
288 }
289 
291  const coff_section *Sec = toSec(Ref);
293 }
294 
296  const coff_section *Sec = toSec(Ref);
298 }
299 
301  const coff_section *Sec = toSec(Ref);
302  const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
305  return (Sec->Characteristics & BssFlags) == BssFlags;
306 }
307 
309  uintptr_t Offset =
310  uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
311  assert((Offset % sizeof(coff_section)) == 0);
312  return (Offset / sizeof(coff_section)) + 1;
313 }
314 
316  const coff_section *Sec = toSec(Ref);
317  // In COFF, a virtual section won't have any in-file
318  // content, so the file pointer to the content will be zero.
319  return Sec->PointerToRawData == 0;
320 }
321 
322 static uint32_t getNumberOfRelocations(const coff_section *Sec,
323  MemoryBufferRef M, const uint8_t *base) {
324  // The field for the number of relocations in COFF section table is only
325  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
326  // NumberOfRelocations field, and the actual relocation count is stored in the
327  // VirtualAddress field in the first relocation entry.
328  if (Sec->hasExtendedRelocations()) {
329  const coff_relocation *FirstReloc;
330  if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
331  base + Sec->PointerToRelocations)))
332  return 0;
333  // -1 to exclude this first relocation entry.
334  return FirstReloc->VirtualAddress - 1;
335  }
336  return Sec->NumberOfRelocations;
337 }
338 
339 static const coff_relocation *
340 getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
341  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
342  if (!NumRelocs)
343  return nullptr;
344  auto begin = reinterpret_cast<const coff_relocation *>(
345  Base + Sec->PointerToRelocations);
346  if (Sec->hasExtendedRelocations()) {
347  // Skip the first relocation entry repurposed to store the number of
348  // relocations.
349  begin++;
350  }
351  if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs))
352  return nullptr;
353  return begin;
354 }
355 
357  const coff_section *Sec = toSec(Ref);
358  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
359  if (begin && Sec->VirtualAddress != 0)
360  report_fatal_error("Sections with relocations should have an address of 0");
362  Ret.p = reinterpret_cast<uintptr_t>(begin);
363  return relocation_iterator(RelocationRef(Ret, this));
364 }
365 
367  const coff_section *Sec = toSec(Ref);
368  const coff_relocation *I = getFirstReloc(Sec, Data, base());
369  if (I)
370  I += getNumberOfRelocations(Sec, Data, base());
372  Ret.p = reinterpret_cast<uintptr_t>(I);
373  return relocation_iterator(RelocationRef(Ret, this));
374 }
375 
376 // Initialize the pointer to the symbol table.
377 std::error_code COFFObjectFile::initSymbolTablePtr() {
378  if (COFFHeader)
379  if (std::error_code EC = getObject(
380  SymbolTable16, Data, base() + getPointerToSymbolTable(),
382  return EC;
383 
384  if (COFFBigObjHeader)
385  if (std::error_code EC = getObject(
386  SymbolTable32, Data, base() + getPointerToSymbolTable(),
388  return EC;
389 
390  // Find string table. The first four byte of the string table contains the
391  // total size of the string table, including the size field itself. If the
392  // string table is empty, the value of the first four byte would be 4.
395  const uint8_t *StringTableAddr = base() + StringTableOffset;
396  const ulittle32_t *StringTableSizePtr;
397  if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
398  return EC;
399  StringTableSize = *StringTableSizePtr;
400  if (std::error_code EC =
401  getObject(StringTable, Data, StringTableAddr, StringTableSize))
402  return EC;
403 
404  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
405  // tools like cvtres write a size of 0 for an empty table instead of 4.
406  if (StringTableSize < 4)
407  StringTableSize = 4;
408 
409  // Check that the string table is null terminated if has any in it.
410  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
412  return std::error_code();
413 }
414 
415 // Returns the file offset for the given VA.
416 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
417  uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase
418  : (uint64_t)PE32PlusHeader->ImageBase;
419  uint64_t Rva = Addr - ImageBase;
420  assert(Rva <= UINT32_MAX);
421  return getRvaPtr((uint32_t)Rva, Res);
422 }
423 
424 // Returns the file offset for the given RVA.
425 std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
426  for (const SectionRef &S : sections()) {
427  const coff_section *Section = getCOFFSection(S);
428  uint32_t SectionStart = Section->VirtualAddress;
429  uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
430  if (SectionStart <= Addr && Addr < SectionEnd) {
431  uint32_t Offset = Addr - SectionStart;
432  Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
433  return std::error_code();
434  }
435  }
437 }
438 
439 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
440 // table entry.
441 std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
442  StringRef &Name) const {
443  uintptr_t IntPtr = 0;
444  if (std::error_code EC = getRvaPtr(Rva, IntPtr))
445  return EC;
446  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
447  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
448  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
449  return std::error_code();
450 }
451 
452 // Find the import table.
453 std::error_code COFFObjectFile::initImportTablePtr() {
454  // First, we get the RVA of the import table. If the file lacks a pointer to
455  // the import table, do nothing.
456  const data_directory *DataEntry;
457  if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
458  return std::error_code();
459 
460  // Do nothing if the pointer to import table is NULL.
461  if (DataEntry->RelativeVirtualAddress == 0)
462  return std::error_code();
463 
464  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
465  // -1 because the last entry is the null entry.
466  NumberOfImportDirectory = DataEntry->Size /
467  sizeof(import_directory_table_entry) - 1;
468 
469  // Find the section that contains the RVA. This is needed because the RVA is
470  // the import table's memory address which is different from its file offset.
471  uintptr_t IntPtr = 0;
472  if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
473  return EC;
474  ImportDirectory = reinterpret_cast<
475  const import_directory_table_entry *>(IntPtr);
476  return std::error_code();
477 }
478 
479 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
480 std::error_code COFFObjectFile::initDelayImportTablePtr() {
481  const data_directory *DataEntry;
483  return std::error_code();
484  if (DataEntry->RelativeVirtualAddress == 0)
485  return std::error_code();
486 
487  uint32_t RVA = DataEntry->RelativeVirtualAddress;
488  NumberOfDelayImportDirectory = DataEntry->Size /
490 
491  uintptr_t IntPtr = 0;
492  if (std::error_code EC = getRvaPtr(RVA, IntPtr))
493  return EC;
494  DelayImportDirectory = reinterpret_cast<
495  const delay_import_directory_table_entry *>(IntPtr);
496  return std::error_code();
497 }
498 
499 // Find the export table.
500 std::error_code COFFObjectFile::initExportTablePtr() {
501  // First, we get the RVA of the export table. If the file lacks a pointer to
502  // the export table, do nothing.
503  const data_directory *DataEntry;
504  if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
505  return std::error_code();
506 
507  // Do nothing if the pointer to export table is NULL.
508  if (DataEntry->RelativeVirtualAddress == 0)
509  return std::error_code();
510 
511  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
512  uintptr_t IntPtr = 0;
513  if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
514  return EC;
515  ExportDirectory =
516  reinterpret_cast<const export_directory_table_entry *>(IntPtr);
517  return std::error_code();
518 }
519 
520 std::error_code COFFObjectFile::initBaseRelocPtr() {
521  const data_directory *DataEntry;
523  return std::error_code();
524  if (DataEntry->RelativeVirtualAddress == 0)
525  return std::error_code();
526 
527  uintptr_t IntPtr = 0;
528  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
529  return EC;
530  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
531  IntPtr);
532  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
533  IntPtr + DataEntry->Size);
534  return std::error_code();
535 }
536 
538  : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
539  COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
540  DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
541  SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
542  ImportDirectory(nullptr), NumberOfImportDirectory(0),
543  DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
544  ExportDirectory(nullptr), BaseRelocHeader(nullptr),
545  BaseRelocEnd(nullptr) {
546  // Check that we at least have enough room for a header.
547  if (!checkSize(Data, EC, sizeof(coff_file_header)))
548  return;
549 
550  // The current location in the file where we are looking at.
551  uint64_t CurPtr = 0;
552 
553  // PE header is optional and is present only in executables. If it exists,
554  // it is placed right after COFF header.
555  bool HasPEHeader = false;
556 
557  // Check if this is a PE/COFF file.
558  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
559  // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
560  // PE signature to find 'normal' COFF header.
561  const auto *DH = reinterpret_cast<const dos_header *>(base());
562  if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
563  CurPtr = DH->AddressOfNewExeHeader;
564  // Check the PE magic bytes. ("PE\0\0")
565  if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
567  return;
568  }
569  CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
570  HasPEHeader = true;
571  }
572  }
573 
574  if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
575  return;
576 
577  // It might be a bigobj file, let's check. Note that COFF bigobj and COFF
578  // import libraries share a common prefix but bigobj is more restrictive.
579  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
580  COFFHeader->NumberOfSections == uint16_t(0xffff) &&
581  checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
582  if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
583  return;
584 
585  // Verify that we are dealing with bigobj.
586  if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
587  std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
588  sizeof(COFF::BigObjMagic)) == 0) {
589  COFFHeader = nullptr;
590  CurPtr += sizeof(coff_bigobj_file_header);
591  } else {
592  // It's not a bigobj.
593  COFFBigObjHeader = nullptr;
594  }
595  }
596  if (COFFHeader) {
597  // The prior checkSize call may have failed. This isn't a hard error
598  // because we were just trying to sniff out bigobj.
599  EC = std::error_code();
600  CurPtr += sizeof(coff_file_header);
601 
602  if (COFFHeader->isImportLibrary())
603  return;
604  }
605 
606  if (HasPEHeader) {
607  const pe32_header *Header;
608  if ((EC = getObject(Header, Data, base() + CurPtr)))
609  return;
610 
611  const uint8_t *DataDirAddr;
612  uint64_t DataDirSize;
613  if (Header->Magic == COFF::PE32Header::PE32) {
614  PE32Header = Header;
615  DataDirAddr = base() + CurPtr + sizeof(pe32_header);
616  DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
617  } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
618  PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
619  DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
620  DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
621  } else {
622  // It's neither PE32 nor PE32+.
624  return;
625  }
626  if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
627  return;
628  CurPtr += COFFHeader->SizeOfOptionalHeader;
629  }
630 
631  if ((EC = getObject(SectionTable, Data, base() + CurPtr,
632  (uint64_t)getNumberOfSections() * sizeof(coff_section))))
633  return;
634 
635  // Initialize the pointer to the symbol table.
636  if (getPointerToSymbolTable() != 0) {
637  if ((EC = initSymbolTablePtr()))
638  return;
639  } else {
640  // We had better not have any symbols if we don't have a symbol table.
641  if (getNumberOfSymbols() != 0) {
643  return;
644  }
645  }
646 
647  // Initialize the pointer to the beginning of the import table.
648  if ((EC = initImportTablePtr()))
649  return;
650  if ((EC = initDelayImportTablePtr()))
651  return;
652 
653  // Initialize the pointer to the export table.
654  if ((EC = initExportTablePtr()))
655  return;
656 
657  // Initialize the pointer to the base relocation table.
658  if ((EC = initBaseRelocPtr()))
659  return;
660 
661  EC = std::error_code();
662 }
663 
666  Ret.p = getSymbolTable();
667  return basic_symbol_iterator(SymbolRef(Ret, this));
668 }
669 
671  // The symbol table ends where the string table begins.
673  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
674  return basic_symbol_iterator(SymbolRef(Ret, this));
675 }
676 
679  ImportDirectoryEntryRef(ImportDirectory, 0, this));
680 }
681 
684  ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
685 }
686 
690  DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
691 }
692 
697  DelayImportDirectory, NumberOfDelayImportDirectory, this));
698 }
699 
702  ExportDirectoryEntryRef(ExportDirectory, 0, this));
703 }
704 
706  if (!ExportDirectory)
707  return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
708  ExportDirectoryEntryRef Ref(ExportDirectory,
709  ExportDirectory->AddressTableEntries, this);
710  return export_directory_iterator(Ref);
711 }
712 
715  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
716  return section_iterator(SectionRef(Ret, this));
717 }
718 
721  int NumSections =
722  COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
723  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
724  return section_iterator(SectionRef(Ret, this));
725 }
726 
728  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
729 }
730 
732  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
733 }
734 
736  return getArch() == Triple::x86_64 ? 8 : 4;
737 }
738 
740  switch(getMachine()) {
742  return "COFF-i386";
744  return "COFF-x86-64";
746  return "COFF-ARM";
747  default:
748  return "COFF-<unknown arch>";
749  }
750 }
751 
752 unsigned COFFObjectFile::getArch() const {
753  switch (getMachine()) {
755  return Triple::x86;
757  return Triple::x86_64;
759  return Triple::thumb;
760  default:
761  return Triple::UnknownArch;
762  }
763 }
764 
768 }
769 
774 }
775 
779 }
780 
783 }
784 
785 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
786  Res = PE32Header;
787  return std::error_code();
788 }
789 
790 std::error_code
792  Res = PE32PlusHeader;
793  return std::error_code();
794 }
795 
796 std::error_code
798  const data_directory *&Res) const {
799  // Error if if there's no data directory or the index is out of range.
800  if (!DataDirectory) {
801  Res = nullptr;
803  }
804  assert(PE32Header || PE32PlusHeader);
805  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
806  : PE32PlusHeader->NumberOfRvaAndSize;
807  if (Index >= NumEnt) {
808  Res = nullptr;
810  }
811  Res = &DataDirectory[Index];
812  return std::error_code();
813 }
814 
815 std::error_code COFFObjectFile::getSection(int32_t Index,
816  const coff_section *&Result) const {
817  Result = nullptr;
819  return std::error_code();
820  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
821  // We already verified the section table data, so no need to check again.
822  Result = SectionTable + (Index - 1);
823  return std::error_code();
824  }
826 }
827 
828 std::error_code COFFObjectFile::getString(uint32_t Offset,
829  StringRef &Result) const {
830  if (StringTableSize <= 4)
831  // Tried to get a string from an empty string table.
833  if (Offset >= StringTableSize)
835  Result = StringRef(StringTable + Offset);
836  return std::error_code();
837 }
838 
840  StringRef &Res) const {
841  return getSymbolName(Symbol.getGeneric(), Res);
842 }
843 
844 std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
845  StringRef &Res) const {
846  // Check for string table entry. First 4 bytes are 0.
847  if (Symbol->Name.Offset.Zeroes == 0) {
848  if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
849  return EC;
850  return std::error_code();
851  }
852 
853  if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
854  // Null terminated, let ::strlen figure out the length.
855  Res = StringRef(Symbol->Name.ShortName);
856  else
857  // Not null terminated, use all 8 bytes.
858  Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
859  return std::error_code();
860 }
861 
864  const uint8_t *Aux = nullptr;
865 
866  size_t SymbolSize = getSymbolTableEntrySize();
867  if (Symbol.getNumberOfAuxSymbols() > 0) {
868  // AUX data comes immediately after the symbol in COFF
869  Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
870 # ifndef NDEBUG
871  // Verify that the Aux symbol points to a valid entry in the symbol table.
872  uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
873  if (Offset < getPointerToSymbolTable() ||
874  Offset >=
875  getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
876  report_fatal_error("Aux Symbol data was outside of symbol table.");
877 
878  assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
879  "Aux Symbol data did not point to the beginning of a symbol");
880 # endif
881  }
882  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
883 }
884 
885 std::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
886  StringRef &Res) const {
887  StringRef Name;
888  if (Sec->Name[COFF::NameSize - 1] == 0)
889  // Null terminated, let ::strlen figure out the length.
890  Name = Sec->Name;
891  else
892  // Not null terminated, use all 8 bytes.
893  Name = StringRef(Sec->Name, COFF::NameSize);
894 
895  // Check for string table entry. First byte is '/'.
896  if (Name.startswith("/")) {
897  uint32_t Offset;
898  if (Name.startswith("//")) {
899  if (decodeBase64StringEntry(Name.substr(2), Offset))
901  } else {
902  if (Name.substr(1).getAsInteger(10, Offset))
904  }
905  if (std::error_code EC = getString(Offset, Name))
906  return EC;
907  }
908 
909  Res = Name;
910  return std::error_code();
911 }
912 
913 uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
914  // SizeOfRawData and VirtualSize change what they represent depending on
915  // whether or not we have an executable image.
916  //
917  // For object files, SizeOfRawData contains the size of section's data;
918  // VirtualSize should be zero but isn't due to buggy COFF writers.
919  //
920  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
921  // actual section size is in VirtualSize. It is possible for VirtualSize to
922  // be greater than SizeOfRawData; the contents past that point should be
923  // considered to be zero.
924  if (getDOSHeader())
925  return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
926  return Sec->SizeOfRawData;
927 }
928 
929 std::error_code
931  ArrayRef<uint8_t> &Res) const {
932  // PointerToRawData and SizeOfRawData won't make sense for BSS sections,
933  // don't do anything interesting for them.
935  "BSS sections don't have contents!");
936  // The only thing that we need to verify is that the contents is contained
937  // within the file bounds. We don't need to make sure it doesn't cover other
938  // data, as there's nothing that says that is not allowed.
939  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
940  uint32_t SectionSize = getSectionSize(Sec);
941  if (checkOffset(Data, ConStart, SectionSize))
943  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
944  return std::error_code();
945 }
946 
947 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
948  return reinterpret_cast<const coff_relocation*>(Rel.p);
949 }
950 
952  Rel.p = reinterpret_cast<uintptr_t>(
953  reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
954 }
955 
957  const coff_relocation *R = toRel(Rel);
958  return R->VirtualAddress;
959 }
960 
962  const coff_relocation *R = toRel(Rel);
963  DataRefImpl Ref;
965  return symbol_end();
966  if (SymbolTable16)
967  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
968  else if (SymbolTable32)
969  Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
970  else
971  llvm_unreachable("no symbol table pointer!");
972  return symbol_iterator(SymbolRef(Ref, this));
973 }
974 
976  const coff_relocation* R = toRel(Rel);
977  return R->Type;
978 }
979 
980 const coff_section *
982  return toSec(Section.getRawDataRefImpl());
983 }
984 
986  if (SymbolTable16)
987  return toSymb<coff_symbol16>(Ref);
988  if (SymbolTable32)
989  return toSymb<coff_symbol32>(Ref);
990  llvm_unreachable("no symbol table pointer!");
991 }
992 
994  return getCOFFSymbol(Symbol.getRawDataRefImpl());
995 }
996 
997 const coff_relocation *
999  return toRel(Reloc.getRawDataRefImpl());
1000 }
1001 
1004  const coff_relocation *I = getFirstReloc(Sec, Data, base());
1005  const coff_relocation *E = I;
1006  if (I)
1007  E += getNumberOfRelocations(Sec, Data, base());
1008  return make_range(I, E);
1009 }
1010 
1011 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
1012  case COFF::reloc_type: \
1013  Res = #reloc_type; \
1014  break;
1015 
1017  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
1018  const coff_relocation *Reloc = toRel(Rel);
1019  StringRef Res;
1020  switch (getMachine()) {
1022  switch (Reloc->Type) {
1040  default:
1041  Res = "Unknown";
1042  }
1043  break;
1045  switch (Reloc->Type) {
1061  default:
1062  Res = "Unknown";
1063  }
1064  break;
1066  switch (Reloc->Type) {
1078  default:
1079  Res = "Unknown";
1080  }
1081  break;
1082  default:
1083  Res = "Unknown";
1084  }
1085  Result.append(Res.begin(), Res.end());
1086 }
1087 
1088 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1089 
1091  return !DataDirectory;
1092 }
1093 
1096  return ImportTable == Other.ImportTable && Index == Other.Index;
1097 }
1098 
1100  ++Index;
1101 }
1102 
1104  const import_directory_table_entry *&Result) const {
1105  Result = ImportTable + Index;
1106  return std::error_code();
1107 }
1108 
1110 makeImportedSymbolIterator(const COFFObjectFile *Object,
1111  uintptr_t Ptr, int Index) {
1112  if (Object->getBytesInAddress() == 4) {
1113  auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
1114  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1115  }
1116  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
1117  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
1118 }
1119 
1121 importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
1122  uintptr_t IntPtr = 0;
1123  Object->getRvaPtr(RVA, IntPtr);
1124  return makeImportedSymbolIterator(Object, IntPtr, 0);
1125 }
1126 
1128 importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
1129  uintptr_t IntPtr = 0;
1130  Object->getRvaPtr(RVA, IntPtr);
1131  // Forward the pointer to the last entry which is null.
1132  int Index = 0;
1133  if (Object->getBytesInAddress() == 4) {
1134  auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
1135  while (*Entry++)
1136  ++Index;
1137  } else {
1138  auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
1139  while (*Entry++)
1140  ++Index;
1141  }
1142  return makeImportedSymbolIterator(Object, IntPtr, Index);
1143 }
1144 
1147  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
1148  OwningObject);
1149 }
1150 
1153  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
1154  OwningObject);
1155 }
1156 
1160 }
1161 
1162 std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
1163  uintptr_t IntPtr = 0;
1164  if (std::error_code EC =
1165  OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
1166  return EC;
1167  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1168  return std::error_code();
1169 }
1170 
1171 std::error_code
1173  Result = ImportTable[Index].ImportLookupTableRVA;
1174  return std::error_code();
1175 }
1176 
1177 std::error_code
1179  Result = ImportTable[Index].ImportAddressTableRVA;
1180  return std::error_code();
1181 }
1182 
1184  const import_lookup_table_entry32 *&Result) const {
1185  uintptr_t IntPtr = 0;
1186  uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
1187  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1188  return EC;
1189  Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
1190  return std::error_code();
1191 }
1192 
1195  return Table == Other.Table && Index == Other.Index;
1196 }
1197 
1199  ++Index;
1200 }
1201 
1204  return importedSymbolBegin(Table[Index].DelayImportNameTable,
1205  OwningObject);
1206 }
1207 
1210  return importedSymbolEnd(Table[Index].DelayImportNameTable,
1211  OwningObject);
1212 }
1213 
1217 }
1218 
1219 std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
1220  uintptr_t IntPtr = 0;
1221  if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
1222  return EC;
1223  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1224  return std::error_code();
1225 }
1226 
1227 std::error_code DelayImportDirectoryEntryRef::
1229  Result = Table;
1230  return std::error_code();
1231 }
1232 
1233 std::error_code DelayImportDirectoryEntryRef::
1234 getImportAddress(int AddrIndex, uint64_t &Result) const {
1235  uint32_t RVA = Table[Index].DelayImportAddressTable +
1236  AddrIndex * (OwningObject->is64() ? 8 : 4);
1237  uintptr_t IntPtr = 0;
1238  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1239  return EC;
1240  if (OwningObject->is64())
1241  Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
1242  else
1243  Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
1244  return std::error_code();
1245 }
1246 
1249  return ExportTable == Other.ExportTable && Index == Other.Index;
1250 }
1251 
1253  ++Index;
1254 }
1255 
1256 // Returns the name of the current export symbol. If the symbol is exported only
1257 // by ordinal, the empty string is set as a result.
1258 std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
1259  uintptr_t IntPtr = 0;
1260  if (std::error_code EC =
1261  OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
1262  return EC;
1263  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1264  return std::error_code();
1265 }
1266 
1267 // Returns the starting ordinal number.
1268 std::error_code
1270  Result = ExportTable->OrdinalBase;
1271  return std::error_code();
1272 }
1273 
1274 // Returns the export ordinal of the current export symbol.
1275 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1276  Result = ExportTable->OrdinalBase + Index;
1277  return std::error_code();
1278 }
1279 
1280 // Returns the address of the current export symbol.
1281 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1282  uintptr_t IntPtr = 0;
1283  if (std::error_code EC =
1284  OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
1285  return EC;
1286  const export_address_table_entry *entry =
1287  reinterpret_cast<const export_address_table_entry *>(IntPtr);
1288  Result = entry[Index].ExportRVA;
1289  return std::error_code();
1290 }
1291 
1292 // Returns the name of the current export symbol. If the symbol is exported only
1293 // by ordinal, the empty string is set as a result.
1294 std::error_code
1296  uintptr_t IntPtr = 0;
1297  if (std::error_code EC =
1298  OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
1299  return EC;
1300  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
1301 
1302  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
1303  int Offset = 0;
1304  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
1305  I < E; ++I, ++Offset) {
1306  if (*I != Index)
1307  continue;
1308  if (std::error_code EC =
1309  OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
1310  return EC;
1311  const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1312  if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
1313  return EC;
1314  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1315  return std::error_code();
1316  }
1317  Result = "";
1318  return std::error_code();
1319 }
1320 
1323  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
1324  && Index == Other.Index;
1325 }
1326 
1328  ++Index;
1329 }
1330 
1331 std::error_code
1333  uint32_t RVA;
1334  if (Entry32) {
1335  // If a symbol is imported only by ordinal, it has no name.
1336  if (Entry32[Index].isOrdinal())
1337  return std::error_code();
1338  RVA = Entry32[Index].getHintNameRVA();
1339  } else {
1340  if (Entry64[Index].isOrdinal())
1341  return std::error_code();
1342  RVA = Entry64[Index].getHintNameRVA();
1343  }
1344  uintptr_t IntPtr = 0;
1345  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1346  return EC;
1347  // +2 because the first two bytes is hint.
1348  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
1349  return std::error_code();
1350 }
1351 
1352 std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1353  uint32_t RVA;
1354  if (Entry32) {
1355  if (Entry32[Index].isOrdinal()) {
1356  Result = Entry32[Index].getOrdinal();
1357  return std::error_code();
1358  }
1359  RVA = Entry32[Index].getHintNameRVA();
1360  } else {
1361  if (Entry64[Index].isOrdinal()) {
1362  Result = Entry64[Index].getOrdinal();
1363  return std::error_code();
1364  }
1365  RVA = Entry64[Index].getHintNameRVA();
1366  }
1367  uintptr_t IntPtr = 0;
1368  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1369  return EC;
1370  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
1371  return std::error_code();
1372 }
1373 
1376  std::error_code EC;
1377  std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
1378  if (EC)
1379  return EC;
1380  return std::move(Ret);
1381 }
1382 
1384  return Header == Other.Header && Index == Other.Index;
1385 }
1386 
1388  // Header->BlockSize is the size of the current block, including the
1389  // size of the header itself.
1390  uint32_t Size = sizeof(*Header) +
1391  sizeof(coff_base_reloc_block_entry) * (Index + 1);
1392  if (Size == Header->BlockSize) {
1393  // .reloc contains a list of base relocation blocks. Each block
1394  // consists of the header followed by entries. The header contains
1395  // how many entories will follow. When we reach the end of the
1396  // current block, proceed to the next block.
1397  Header = reinterpret_cast<const coff_base_reloc_block_header *>(
1398  reinterpret_cast<const uint8_t *>(Header) + Size);
1399  Index = 0;
1400  } else {
1401  ++Index;
1402  }
1403 }
1404 
1405 std::error_code BaseRelocRef::getType(uint8_t &Type) const {
1406  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1407  Type = Entry[Index].getType();
1408  return std::error_code();
1409 }
1410 
1411 std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
1412  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
1413  Result = Header->PageRVA + Entry[Index].getOffset();
1414  return std::error_code();
1415 }
std::error_code getRVA(uint32_t &Result) const
uint32_t getNumberOfSections() const
Definition: Object/COFF.h:626
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:347
bool operator==(const ImportDirectoryEntryRef &Other) const
static uint32_t getNumberOfRelocations(const coff_section *Sec, MemoryBufferRef M, const uint8_t *base)
Represents either an error or a value T.
Definition: ErrorOr.h:82
support::ulittle32_t ImportAddressTableRVA
Definition: Object/COFF.h:169
The 64-bit PE header that follows the COFF header.
Definition: Object/COFF.h:127
section_iterator section_begin() const override
support::ulittle16_t Machine
Definition: Object/COFF.h:63
ErrorOr< StringRef > getSymbolName(DataRefImpl Symb) const override
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:188
friend class SymbolRef
Definition: ObjectFile.h:196
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
iterator_range< imported_symbol_iterator > imported_symbols() const
support::ulittle32_t Name
Definition: Object/COFF.h:197
support::ulittle32_t OrdinalBase
Definition: Object/COFF.h:212
const void * getRawPtr() const
Definition: Object/COFF.h:267
std::error_code getDelayImportTable(const delay_import_directory_table_entry *&Result) const
friend class SectionRef
Definition: ObjectFile.h:209
COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool hasExtendedRelocations() const
Definition: Object/COFF.h:413
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:184
support::ulittle32_t VirtualAddress
Definition: Object/COFF.h:402
import_directory_iterator import_directory_end() const
Definition: Object/COFF.h:206
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))
void moveRelocationNext(DataRefImpl &Rel) const override
static ErrorOr< std::unique_ptr< COFFObjectFile > > createCOFFObjectFile(MemoryBufferRef Object)
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
This class is the base class for all object file types.
Definition: ObjectFile.h:176
support::ulittle16_t NumberOfSections
Definition: Object/COFF.h:64
static const coff_relocation * getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base)
support::ulittle32_t PointerToRelocations
Definition: Object/COFF.h:405
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:232
const char * getBufferStart() const
Definition: MemoryBuffer.h:161
Definition: Object/COFF.h:220
uint32_t getValue() const
Definition: Object/COFF.h:298
union llvm::object::coff_symbol_generic::@91 Name
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:410
std::error_code getImportAddressTableRVA(uint32_t &Result) const
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
aarch64 collect AArch64 Collect Linker Optimization Hint(LOH)"
support::ulittle32_t DelayImportAddressTable
Definition: Object/COFF.h:199
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
char ShortName[COFF::NameSize]
Definition: Object/COFF.h:255
support::ulittle64_t ImageBase
Definition: Object/COFF.h:136
support::ulittle32_t NameRVA
Definition: Object/COFF.h:211
uint16_t getOrdinal() const
Definition: Object/COFF.h:178
friend class ExportDirectoryEntryRef
Definition: Object/COFF.h:554
Definition: Object/COFF.h:173
uint64_t getSectionAlignment(DataRefImpl Sec) const override
char Name[COFF::NameSize]
Definition: Object/COFF.h:400
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:308
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:40
support::ulittle16_t SizeOfOptionalHeader
Definition: Object/COFF.h:68
bool operator==(const ExportDirectoryEntryRef &Other) const
iterator_range< base_reloc_iterator > base_relocs() const
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
std::error_code getOrdinal(uint32_t &Result) const
content_iterator< ImportedSymbolRef > imported_symbol_iterator
Definition: Object/COFF.h:36
static imported_symbol_iterator importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object)
iterator_range< import_directory_iterator > import_directories() const
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:591
support::ulittle32_t ImportLookupTableRVA
Definition: Object/COFF.h:165
bool isReservedSectionNumber(int32_t SectionNumber)
Definition: Support/COFF.h:670
support::ulittle32_t VirtualSize
Definition: Object/COFF.h:401
#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)
support::ulittle32_t NameRVA
Definition: Object/COFF.h:168
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const
uint32_t getSymbolFlags(DataRefImpl Symb) const override
ErrorOr< uint64_t > getSymbolAddress(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
bool isFunctionDefinition() const
Definition: Object/COFF.h:354
support::ulittle32_t NamePointerRVA
Definition: Object/COFF.h:216
support::ulittle32_t ExportRVA
Definition: Object/COFF.h:221
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:134
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
unsigned getArch() const override
imported_symbol_iterator imported_symbol_end() const
iterator begin() const
Definition: StringRef.h:90
unsigned getSectionID(SectionRef Sec) const
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:35
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:92
#define P(N)
support::ulittle32_t Characteristics
Definition: Object/COFF.h:409
support::ulittle32_t NumberOfRvaAndSize
Definition: Object/COFF.h:156
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:594
int getType() const
Definition: Object/COFF.h:547
std::error_code getDataDirectory(uint32_t index, const data_directory *&Res) const
const char * getBufferEnd() const
Definition: MemoryBuffer.h:162
basic_symbol_iterator symbol_end_impl() const override
int32_t getSectionNumber() const
Definition: Object/COFF.h:300
The 32-bit PE header that follows the COFF header.
Definition: Object/COFF.h:91
std::error_code getImportLookupTableRVA(uint32_t &Result) const
export_directory_iterator export_directory_end() const
base_reloc_iterator base_reloc_begin() const
support::ulittle32_t RelativeVirtualAddress
Definition: Object/COFF.h:160
std::error_code getOrdinal(uint16_t &Result) const
std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
support::ulittle16_t Type
Definition: Object/COFF.h:422
support::ulittle32_t OrdinalTableRVA
Definition: Object/COFF.h:217
COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const
section_iterator_range sections() const
Definition: ObjectFile.h:253
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:403
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:416
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:65
uint64_t getRelocationType(DataRefImpl Rel) const override
StringRef getFileFormatName() const override
content_iterator< ImportDirectoryEntryRef > import_directory_iterator
Definition: Object/COFF.h:31
support::ulittle32_t VirtualAddress
Definition: Object/COFF.h:420
support::ulittle32_t SymbolTableIndex
Definition: Object/COFF.h:421
std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override
size_t getBufferSize() const
Definition: MemoryBuffer.h:163
friend class ImportDirectoryEntryRef
Definition: Object/COFF.h:553
basic_symbol_iterator symbol_end() const
Definition: SymbolicFile.h:139
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:116
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:404
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
friend class RelocationRef
Definition: ObjectFile.h:228
bool isWeakExternal() const
Definition: Object/COFF.h:350
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result)
Definition: Object/COFF.h:545
imported_symbol_iterator imported_symbol_end() const
content_iterator< ExportDirectoryEntryRef > export_directory_iterator
Definition: Object/COFF.h:35
bool isSectionData(DataRefImpl Sec) const override
detail::packed_endian_specific_integral< int16_t, little, unaligned > little16_t
Definition: Endian.h:148
const dos_header * getDOSHeader() const
Definition: Object/COFF.h:713
basic_symbol_iterator symbol_begin_impl() const override
std::error_code getImportLookupEntry(const import_lookup_table_entry32 *&Result) const
The DOS compatible header at the front of all PE/COFF executables.
Definition: Object/COFF.h:40
A range adaptor for a pair of iterators.
section_iterator section_end() const override
MemoryBufferRef Data
Definition: Binary.h:37
delay_import_directory_iterator delay_import_directory_begin() const
support::ulittle32_t Size
Definition: Object/COFF.h:161
uint8_t getNumberOfAuxSymbols() const
Definition: Object/COFF.h:321
unsigned getSymbolSectionID(SymbolRef Sym) const
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
Definition: Endian.h:141
std::error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: ObjectFile.h:114
support::ulittle32_t ImageBase
Definition: Object/COFF.h:101
support::ulittle32_t Zeroes
Definition: Object/COFF.h:229
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:214
std::error_code getPE32Header(const pe32_header *&Res) const
bool isSectionDefinition() const
Definition: Object/COFF.h:376
iterator_range< imported_symbol_iterator > imported_symbols() const
bool isSectionText(DataRefImpl Sec) const override
bool operator==(const DelayImportDirectoryEntryRef &Other) const
std::error_code getImportTableEntry(const import_directory_table_entry *&Result) const
uintptr_t getSymbolTable() const
Definition: Object/COFF.h:587
const coff_symbol_generic * getGeneric() const
Definition: Object/COFF.h:271
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:38
detail::packed_endian_specific_integral< uint64_t, little, unaligned > ulittle64_t
Definition: Endian.h:145
content_iterator< DelayImportDirectoryEntryRef > delay_import_directory_iterator
Definition: Object/COFF.h:34
support::ulittle32_t AddressTableEntries
Definition: Object/COFF.h:213
#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:761
Definition: Object/COFF.h:194
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:407
uint32_t getNumberOfSymbols() const
Definition: Object/COFF.h:641
bool isAnyUndefined() const
Definition: Object/COFF.h:364
bool isSectionBSS(DataRefImpl Sec) const override
base_reloc_iterator base_reloc_end() const
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:143
std::error_code getSymbolName(StringRef &Result) const
std::error_code getOrdinalBase(uint32_t &Result) const
LLVM Value Representation.
Definition: Value.h:69
support::ulittle32_t ExportAddressTableRVA
Definition: Object/COFF.h:215
iterator end() const
Definition: StringRef.h:92
support::ulittle32_t NumberOfRvaAndSize
Definition: Object/COFF.h:123
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:40
std::error_code getType(uint8_t &Type) const
content_iterator< BaseRelocRef > base_reloc_iterator
Definition: Object/COFF.h:37
uint32_t getPointerToSymbolTable() const
Definition: Object/COFF.h:633
std::error_code getName(StringRef &Result) const
uint32_t getHintNameRVA() const
Definition: Object/COFF.h:183
Definition: Object/COFF.h:164
ArrayRef< uint8_t > getSymbolAuxData(COFFSymbolRef Symbol) const
const T * data() const
Definition: ArrayRef.h:131
std::error_code getSection(int32_t index, const coff_section *&Res) 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:69
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110
iterator_range< delay_import_directory_iterator > delay_import_directories() const
support::ulittle32_t Offset
Definition: Object/COFF.h:230
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:448