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