1 //===- COFFObjectFile.cpp - COFF object file implementation ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the COFFObjectFile class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/BinaryFormat/COFF.h"
19 #include "llvm/Object/Binary.h"
20 #include "llvm/Object/COFF.h"
21 #include "llvm/Object/Error.h"
22 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/BinaryStreamReader.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/Error.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/MemoryBuffer.h"
36 #include <system_error>
39 using namespace object
;
41 using support::ulittle16_t
;
42 using support::ulittle32_t
;
43 using support::ulittle64_t
;
44 using support::little16_t
;
46 // Returns false if size is greater than the buffer size. And sets ec.
47 static bool checkSize(MemoryBufferRef M
, std::error_code
&EC
, uint64_t Size
) {
48 if (M
.getBufferSize() < Size
) {
49 EC
= object_error::unexpected_eof
;
55 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
56 // Returns unexpected_eof if error.
58 static std::error_code
getObject(const T
*&Obj
, MemoryBufferRef M
,
60 const uint64_t Size
= sizeof(T
)) {
61 uintptr_t Addr
= uintptr_t(Ptr
);
62 if (std::error_code EC
= Binary::checkOffset(M
, Addr
, Size
))
64 Obj
= reinterpret_cast<const T
*>(Addr
);
65 return std::error_code();
68 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
70 static bool decodeBase64StringEntry(StringRef Str
, uint32_t &Result
) {
71 assert(Str
.size() <= 6 && "String too long, possible overflow.");
76 while (!Str
.empty()) {
78 if (Str
[0] >= 'A' && Str
[0] <= 'Z') // 0..25
79 CharVal
= Str
[0] - 'A';
80 else if (Str
[0] >= 'a' && Str
[0] <= 'z') // 26..51
81 CharVal
= Str
[0] - 'a' + 26;
82 else if (Str
[0] >= '0' && Str
[0] <= '9') // 52..61
83 CharVal
= Str
[0] - '0' + 52;
84 else if (Str
[0] == '+') // 62
86 else if (Str
[0] == '/') // 63
91 Value
= (Value
* 64) + CharVal
;
95 if (Value
> std::numeric_limits
<uint32_t>::max())
98 Result
= static_cast<uint32_t>(Value
);
102 template <typename coff_symbol_type
>
103 const coff_symbol_type
*COFFObjectFile::toSymb(DataRefImpl Ref
) const {
104 const coff_symbol_type
*Addr
=
105 reinterpret_cast<const coff_symbol_type
*>(Ref
.p
);
107 assert(!checkOffset(Data
, uintptr_t(Addr
), sizeof(*Addr
)));
109 // Verify that the symbol points to a valid entry in the symbol table.
110 uintptr_t Offset
= uintptr_t(Addr
) - uintptr_t(base());
112 assert((Offset
- getPointerToSymbolTable()) % sizeof(coff_symbol_type
) == 0 &&
113 "Symbol did not point to the beginning of a symbol");
119 const coff_section
*COFFObjectFile::toSec(DataRefImpl Ref
) const {
120 const coff_section
*Addr
= reinterpret_cast<const coff_section
*>(Ref
.p
);
123 // Verify that the section points to a valid entry in the section table.
124 if (Addr
< SectionTable
|| Addr
>= (SectionTable
+ getNumberOfSections()))
125 report_fatal_error("Section was outside of section table.");
127 uintptr_t Offset
= uintptr_t(Addr
) - uintptr_t(SectionTable
);
128 assert(Offset
% sizeof(coff_section
) == 0 &&
129 "Section did not point to the beginning of a section");
135 void COFFObjectFile::moveSymbolNext(DataRefImpl
&Ref
) const {
136 auto End
= reinterpret_cast<uintptr_t>(StringTable
);
138 const coff_symbol16
*Symb
= toSymb
<coff_symbol16
>(Ref
);
139 Symb
+= 1 + Symb
->NumberOfAuxSymbols
;
140 Ref
.p
= std::min(reinterpret_cast<uintptr_t>(Symb
), End
);
141 } else if (SymbolTable32
) {
142 const coff_symbol32
*Symb
= toSymb
<coff_symbol32
>(Ref
);
143 Symb
+= 1 + Symb
->NumberOfAuxSymbols
;
144 Ref
.p
= std::min(reinterpret_cast<uintptr_t>(Symb
), End
);
146 llvm_unreachable("no symbol table pointer!");
150 Expected
<StringRef
> COFFObjectFile::getSymbolName(DataRefImpl Ref
) const {
151 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
153 if (std::error_code EC
= getSymbolName(Symb
, Result
))
154 return errorCodeToError(EC
);
158 uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref
) const {
159 return getCOFFSymbol(Ref
).getValue();
162 uint32_t COFFObjectFile::getSymbolAlignment(DataRefImpl Ref
) const {
163 // MSVC/link.exe seems to align symbols to the next-power-of-2
165 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
166 return std::min(uint64_t(32), PowerOf2Ceil(Symb
.getValue()));
169 Expected
<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref
) const {
170 uint64_t Result
= getSymbolValue(Ref
);
171 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
172 int32_t SectionNumber
= Symb
.getSectionNumber();
174 if (Symb
.isAnyUndefined() || Symb
.isCommon() ||
175 COFF::isReservedSectionNumber(SectionNumber
))
178 const coff_section
*Section
= nullptr;
179 if (std::error_code EC
= getSection(SectionNumber
, Section
))
180 return errorCodeToError(EC
);
181 Result
+= Section
->VirtualAddress
;
183 // The section VirtualAddress does not include ImageBase, and we want to
184 // return virtual addresses.
185 Result
+= getImageBase();
190 Expected
<SymbolRef::Type
> COFFObjectFile::getSymbolType(DataRefImpl Ref
) const {
191 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
192 int32_t SectionNumber
= Symb
.getSectionNumber();
194 if (Symb
.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION
)
195 return SymbolRef::ST_Function
;
196 if (Symb
.isAnyUndefined())
197 return SymbolRef::ST_Unknown
;
199 return SymbolRef::ST_Data
;
200 if (Symb
.isFileRecord())
201 return SymbolRef::ST_File
;
203 // TODO: perhaps we need a new symbol type ST_Section.
204 if (SectionNumber
== COFF::IMAGE_SYM_DEBUG
|| Symb
.isSectionDefinition())
205 return SymbolRef::ST_Debug
;
207 if (!COFF::isReservedSectionNumber(SectionNumber
))
208 return SymbolRef::ST_Data
;
210 return SymbolRef::ST_Other
;
213 uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref
) const {
214 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
215 uint32_t Result
= SymbolRef::SF_None
;
217 if (Symb
.isExternal() || Symb
.isWeakExternal())
218 Result
|= SymbolRef::SF_Global
;
220 if (const coff_aux_weak_external
*AWE
= Symb
.getWeakExternal()) {
221 Result
|= SymbolRef::SF_Weak
;
222 if (AWE
->Characteristics
!= COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
)
223 Result
|= SymbolRef::SF_Undefined
;
226 if (Symb
.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE
)
227 Result
|= SymbolRef::SF_Absolute
;
229 if (Symb
.isFileRecord())
230 Result
|= SymbolRef::SF_FormatSpecific
;
232 if (Symb
.isSectionDefinition())
233 Result
|= SymbolRef::SF_FormatSpecific
;
236 Result
|= SymbolRef::SF_Common
;
238 if (Symb
.isUndefined())
239 Result
|= SymbolRef::SF_Undefined
;
244 uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref
) const {
245 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
246 return Symb
.getValue();
249 Expected
<section_iterator
>
250 COFFObjectFile::getSymbolSection(DataRefImpl Ref
) const {
251 COFFSymbolRef Symb
= getCOFFSymbol(Ref
);
252 if (COFF::isReservedSectionNumber(Symb
.getSectionNumber()))
253 return section_end();
254 const coff_section
*Sec
= nullptr;
255 if (std::error_code EC
= getSection(Symb
.getSectionNumber(), Sec
))
256 return errorCodeToError(EC
);
258 Ret
.p
= reinterpret_cast<uintptr_t>(Sec
);
259 return section_iterator(SectionRef(Ret
, this));
262 unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym
) const {
263 COFFSymbolRef Symb
= getCOFFSymbol(Sym
.getRawDataRefImpl());
264 return Symb
.getSectionNumber();
267 void COFFObjectFile::moveSectionNext(DataRefImpl
&Ref
) const {
268 const coff_section
*Sec
= toSec(Ref
);
270 Ref
.p
= reinterpret_cast<uintptr_t>(Sec
);
273 std::error_code
COFFObjectFile::getSectionName(DataRefImpl Ref
,
274 StringRef
&Result
) const {
275 const coff_section
*Sec
= toSec(Ref
);
276 return getSectionName(Sec
, Result
);
279 uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref
) const {
280 const coff_section
*Sec
= toSec(Ref
);
281 uint64_t Result
= Sec
->VirtualAddress
;
283 // The section VirtualAddress does not include ImageBase, and we want to
284 // return virtual addresses.
285 Result
+= getImageBase();
289 uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec
) const {
290 return toSec(Sec
) - SectionTable
;
293 uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref
) const {
294 return getSectionSize(toSec(Ref
));
297 std::error_code
COFFObjectFile::getSectionContents(DataRefImpl Ref
,
298 StringRef
&Result
) const {
299 const coff_section
*Sec
= toSec(Ref
);
300 ArrayRef
<uint8_t> Res
;
301 std::error_code EC
= getSectionContents(Sec
, Res
);
302 Result
= StringRef(reinterpret_cast<const char*>(Res
.data()), Res
.size());
306 uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref
) const {
307 const coff_section
*Sec
= toSec(Ref
);
308 return Sec
->getAlignment();
311 bool COFFObjectFile::isSectionCompressed(DataRefImpl Sec
) const {
315 bool COFFObjectFile::isSectionText(DataRefImpl Ref
) const {
316 const coff_section
*Sec
= toSec(Ref
);
317 return Sec
->Characteristics
& COFF::IMAGE_SCN_CNT_CODE
;
320 bool COFFObjectFile::isSectionData(DataRefImpl Ref
) const {
321 const coff_section
*Sec
= toSec(Ref
);
322 return Sec
->Characteristics
& COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
;
325 bool COFFObjectFile::isSectionBSS(DataRefImpl Ref
) const {
326 const coff_section
*Sec
= toSec(Ref
);
327 const uint32_t BssFlags
= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
328 COFF::IMAGE_SCN_MEM_READ
|
329 COFF::IMAGE_SCN_MEM_WRITE
;
330 return (Sec
->Characteristics
& BssFlags
) == BssFlags
;
333 unsigned COFFObjectFile::getSectionID(SectionRef Sec
) const {
335 uintptr_t(Sec
.getRawDataRefImpl().p
) - uintptr_t(SectionTable
);
336 assert((Offset
% sizeof(coff_section
)) == 0);
337 return (Offset
/ sizeof(coff_section
)) + 1;
340 bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref
) const {
341 const coff_section
*Sec
= toSec(Ref
);
342 // In COFF, a virtual section won't have any in-file
343 // content, so the file pointer to the content will be zero.
344 return Sec
->PointerToRawData
== 0;
347 static uint32_t getNumberOfRelocations(const coff_section
*Sec
,
348 MemoryBufferRef M
, const uint8_t *base
) {
349 // The field for the number of relocations in COFF section table is only
350 // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
351 // NumberOfRelocations field, and the actual relocation count is stored in the
352 // VirtualAddress field in the first relocation entry.
353 if (Sec
->hasExtendedRelocations()) {
354 const coff_relocation
*FirstReloc
;
355 if (getObject(FirstReloc
, M
, reinterpret_cast<const coff_relocation
*>(
356 base
+ Sec
->PointerToRelocations
)))
358 // -1 to exclude this first relocation entry.
359 return FirstReloc
->VirtualAddress
- 1;
361 return Sec
->NumberOfRelocations
;
364 static const coff_relocation
*
365 getFirstReloc(const coff_section
*Sec
, MemoryBufferRef M
, const uint8_t *Base
) {
366 uint64_t NumRelocs
= getNumberOfRelocations(Sec
, M
, Base
);
369 auto begin
= reinterpret_cast<const coff_relocation
*>(
370 Base
+ Sec
->PointerToRelocations
);
371 if (Sec
->hasExtendedRelocations()) {
372 // Skip the first relocation entry repurposed to store the number of
376 if (Binary::checkOffset(M
, uintptr_t(begin
),
377 sizeof(coff_relocation
) * NumRelocs
))
382 relocation_iterator
COFFObjectFile::section_rel_begin(DataRefImpl Ref
) const {
383 const coff_section
*Sec
= toSec(Ref
);
384 const coff_relocation
*begin
= getFirstReloc(Sec
, Data
, base());
385 if (begin
&& Sec
->VirtualAddress
!= 0)
386 report_fatal_error("Sections with relocations should have an address of 0");
388 Ret
.p
= reinterpret_cast<uintptr_t>(begin
);
389 return relocation_iterator(RelocationRef(Ret
, this));
392 relocation_iterator
COFFObjectFile::section_rel_end(DataRefImpl Ref
) const {
393 const coff_section
*Sec
= toSec(Ref
);
394 const coff_relocation
*I
= getFirstReloc(Sec
, Data
, base());
396 I
+= getNumberOfRelocations(Sec
, Data
, base());
398 Ret
.p
= reinterpret_cast<uintptr_t>(I
);
399 return relocation_iterator(RelocationRef(Ret
, this));
402 // Initialize the pointer to the symbol table.
403 std::error_code
COFFObjectFile::initSymbolTablePtr() {
405 if (std::error_code EC
= getObject(
406 SymbolTable16
, Data
, base() + getPointerToSymbolTable(),
407 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
410 if (COFFBigObjHeader
)
411 if (std::error_code EC
= getObject(
412 SymbolTable32
, Data
, base() + getPointerToSymbolTable(),
413 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
416 // Find string table. The first four byte of the string table contains the
417 // total size of the string table, including the size field itself. If the
418 // string table is empty, the value of the first four byte would be 4.
419 uint32_t StringTableOffset
= getPointerToSymbolTable() +
420 getNumberOfSymbols() * getSymbolTableEntrySize();
421 const uint8_t *StringTableAddr
= base() + StringTableOffset
;
422 const ulittle32_t
*StringTableSizePtr
;
423 if (std::error_code EC
= getObject(StringTableSizePtr
, Data
, StringTableAddr
))
425 StringTableSize
= *StringTableSizePtr
;
426 if (std::error_code EC
=
427 getObject(StringTable
, Data
, StringTableAddr
, StringTableSize
))
430 // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
431 // tools like cvtres write a size of 0 for an empty table instead of 4.
432 if (StringTableSize
< 4)
435 // Check that the string table is null terminated if has any in it.
436 if (StringTableSize
> 4 && StringTable
[StringTableSize
- 1] != 0)
437 return object_error::parse_failed
;
438 return std::error_code();
441 uint64_t COFFObjectFile::getImageBase() const {
443 return PE32Header
->ImageBase
;
444 else if (PE32PlusHeader
)
445 return PE32PlusHeader
->ImageBase
;
446 // This actually comes up in practice.
450 // Returns the file offset for the given VA.
451 std::error_code
COFFObjectFile::getVaPtr(uint64_t Addr
, uintptr_t &Res
) const {
452 uint64_t ImageBase
= getImageBase();
453 uint64_t Rva
= Addr
- ImageBase
;
454 assert(Rva
<= UINT32_MAX
);
455 return getRvaPtr((uint32_t)Rva
, Res
);
458 // Returns the file offset for the given RVA.
459 std::error_code
COFFObjectFile::getRvaPtr(uint32_t Addr
, uintptr_t &Res
) const {
460 for (const SectionRef
&S
: sections()) {
461 const coff_section
*Section
= getCOFFSection(S
);
462 uint32_t SectionStart
= Section
->VirtualAddress
;
463 uint32_t SectionEnd
= Section
->VirtualAddress
+ Section
->VirtualSize
;
464 if (SectionStart
<= Addr
&& Addr
< SectionEnd
) {
465 uint32_t Offset
= Addr
- SectionStart
;
466 Res
= uintptr_t(base()) + Section
->PointerToRawData
+ Offset
;
467 return std::error_code();
470 return object_error::parse_failed
;
474 COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA
, uint32_t Size
,
475 ArrayRef
<uint8_t> &Contents
) const {
476 for (const SectionRef
&S
: sections()) {
477 const coff_section
*Section
= getCOFFSection(S
);
478 uint32_t SectionStart
= Section
->VirtualAddress
;
479 // Check if this RVA is within the section bounds. Be careful about integer
481 uint32_t OffsetIntoSection
= RVA
- SectionStart
;
482 if (SectionStart
<= RVA
&& OffsetIntoSection
< Section
->VirtualSize
&&
483 Size
<= Section
->VirtualSize
- OffsetIntoSection
) {
485 uintptr_t(base()) + Section
->PointerToRawData
+ OffsetIntoSection
;
487 ArrayRef
<uint8_t>(reinterpret_cast<const uint8_t *>(Begin
), Size
);
488 return std::error_code();
491 return object_error::parse_failed
;
494 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
496 std::error_code
COFFObjectFile::getHintName(uint32_t Rva
, uint16_t &Hint
,
497 StringRef
&Name
) const {
498 uintptr_t IntPtr
= 0;
499 if (std::error_code EC
= getRvaPtr(Rva
, IntPtr
))
501 const uint8_t *Ptr
= reinterpret_cast<const uint8_t *>(IntPtr
);
502 Hint
= *reinterpret_cast<const ulittle16_t
*>(Ptr
);
503 Name
= StringRef(reinterpret_cast<const char *>(Ptr
+ 2));
504 return std::error_code();
508 COFFObjectFile::getDebugPDBInfo(const debug_directory
*DebugDir
,
509 const codeview::DebugInfo
*&PDBInfo
,
510 StringRef
&PDBFileName
) const {
511 ArrayRef
<uint8_t> InfoBytes
;
512 if (std::error_code EC
= getRvaAndSizeAsBytes(
513 DebugDir
->AddressOfRawData
, DebugDir
->SizeOfData
, InfoBytes
))
515 if (InfoBytes
.size() < sizeof(*PDBInfo
) + 1)
516 return object_error::parse_failed
;
517 PDBInfo
= reinterpret_cast<const codeview::DebugInfo
*>(InfoBytes
.data());
518 InfoBytes
= InfoBytes
.drop_front(sizeof(*PDBInfo
));
519 PDBFileName
= StringRef(reinterpret_cast<const char *>(InfoBytes
.data()),
521 // Truncate the name at the first null byte. Ignore any padding.
522 PDBFileName
= PDBFileName
.split('\0').first
;
523 return std::error_code();
527 COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo
*&PDBInfo
,
528 StringRef
&PDBFileName
) const {
529 for (const debug_directory
&D
: debug_directories())
530 if (D
.Type
== COFF::IMAGE_DEBUG_TYPE_CODEVIEW
)
531 return getDebugPDBInfo(&D
, PDBInfo
, PDBFileName
);
532 // If we get here, there is no PDB info to return.
534 PDBFileName
= StringRef();
535 return std::error_code();
538 // Find the import table.
539 std::error_code
COFFObjectFile::initImportTablePtr() {
540 // First, we get the RVA of the import table. If the file lacks a pointer to
541 // the import table, do nothing.
542 const data_directory
*DataEntry
;
543 if (getDataDirectory(COFF::IMPORT_TABLE
, DataEntry
))
544 return std::error_code();
546 // Do nothing if the pointer to import table is NULL.
547 if (DataEntry
->RelativeVirtualAddress
== 0)
548 return std::error_code();
550 uint32_t ImportTableRva
= DataEntry
->RelativeVirtualAddress
;
552 // Find the section that contains the RVA. This is needed because the RVA is
553 // the import table's memory address which is different from its file offset.
554 uintptr_t IntPtr
= 0;
555 if (std::error_code EC
= getRvaPtr(ImportTableRva
, IntPtr
))
557 if (std::error_code EC
= checkOffset(Data
, IntPtr
, DataEntry
->Size
))
559 ImportDirectory
= reinterpret_cast<
560 const coff_import_directory_table_entry
*>(IntPtr
);
561 return std::error_code();
564 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
565 std::error_code
COFFObjectFile::initDelayImportTablePtr() {
566 const data_directory
*DataEntry
;
567 if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR
, DataEntry
))
568 return std::error_code();
569 if (DataEntry
->RelativeVirtualAddress
== 0)
570 return std::error_code();
572 uint32_t RVA
= DataEntry
->RelativeVirtualAddress
;
573 NumberOfDelayImportDirectory
= DataEntry
->Size
/
574 sizeof(delay_import_directory_table_entry
) - 1;
576 uintptr_t IntPtr
= 0;
577 if (std::error_code EC
= getRvaPtr(RVA
, IntPtr
))
579 DelayImportDirectory
= reinterpret_cast<
580 const delay_import_directory_table_entry
*>(IntPtr
);
581 return std::error_code();
584 // Find the export table.
585 std::error_code
COFFObjectFile::initExportTablePtr() {
586 // First, we get the RVA of the export table. If the file lacks a pointer to
587 // the export table, do nothing.
588 const data_directory
*DataEntry
;
589 if (getDataDirectory(COFF::EXPORT_TABLE
, DataEntry
))
590 return std::error_code();
592 // Do nothing if the pointer to export table is NULL.
593 if (DataEntry
->RelativeVirtualAddress
== 0)
594 return std::error_code();
596 uint32_t ExportTableRva
= DataEntry
->RelativeVirtualAddress
;
597 uintptr_t IntPtr
= 0;
598 if (std::error_code EC
= getRvaPtr(ExportTableRva
, IntPtr
))
601 reinterpret_cast<const export_directory_table_entry
*>(IntPtr
);
602 return std::error_code();
605 std::error_code
COFFObjectFile::initBaseRelocPtr() {
606 const data_directory
*DataEntry
;
607 if (getDataDirectory(COFF::BASE_RELOCATION_TABLE
, DataEntry
))
608 return std::error_code();
609 if (DataEntry
->RelativeVirtualAddress
== 0)
610 return std::error_code();
612 uintptr_t IntPtr
= 0;
613 if (std::error_code EC
= getRvaPtr(DataEntry
->RelativeVirtualAddress
, IntPtr
))
615 BaseRelocHeader
= reinterpret_cast<const coff_base_reloc_block_header
*>(
617 BaseRelocEnd
= reinterpret_cast<coff_base_reloc_block_header
*>(
618 IntPtr
+ DataEntry
->Size
);
619 // FIXME: Verify the section containing BaseRelocHeader has at least
620 // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
621 return std::error_code();
624 std::error_code
COFFObjectFile::initDebugDirectoryPtr() {
625 // Get the RVA of the debug directory. Do nothing if it does not exist.
626 const data_directory
*DataEntry
;
627 if (getDataDirectory(COFF::DEBUG_DIRECTORY
, DataEntry
))
628 return std::error_code();
630 // Do nothing if the RVA is NULL.
631 if (DataEntry
->RelativeVirtualAddress
== 0)
632 return std::error_code();
634 // Check that the size is a multiple of the entry size.
635 if (DataEntry
->Size
% sizeof(debug_directory
) != 0)
636 return object_error::parse_failed
;
638 uintptr_t IntPtr
= 0;
639 if (std::error_code EC
= getRvaPtr(DataEntry
->RelativeVirtualAddress
, IntPtr
))
641 DebugDirectoryBegin
= reinterpret_cast<const debug_directory
*>(IntPtr
);
642 DebugDirectoryEnd
= reinterpret_cast<const debug_directory
*>(
643 IntPtr
+ DataEntry
->Size
);
644 // FIXME: Verify the section containing DebugDirectoryBegin has at least
645 // DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
646 return std::error_code();
649 std::error_code
COFFObjectFile::initLoadConfigPtr() {
650 // Get the RVA of the debug directory. Do nothing if it does not exist.
651 const data_directory
*DataEntry
;
652 if (getDataDirectory(COFF::LOAD_CONFIG_TABLE
, DataEntry
))
653 return std::error_code();
655 // Do nothing if the RVA is NULL.
656 if (DataEntry
->RelativeVirtualAddress
== 0)
657 return std::error_code();
658 uintptr_t IntPtr
= 0;
659 if (std::error_code EC
= getRvaPtr(DataEntry
->RelativeVirtualAddress
, IntPtr
))
662 LoadConfig
= (const void *)IntPtr
;
663 return std::error_code();
666 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object
, std::error_code
&EC
)
667 : ObjectFile(Binary::ID_COFF
, Object
), COFFHeader(nullptr),
668 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
669 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
670 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
671 ImportDirectory(nullptr),
672 DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
673 ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
674 DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
675 // Check that we at least have enough room for a header.
676 if (!checkSize(Data
, EC
, sizeof(coff_file_header
)))
679 // The current location in the file where we are looking at.
682 // PE header is optional and is present only in executables. If it exists,
683 // it is placed right after COFF header.
684 bool HasPEHeader
= false;
686 // Check if this is a PE/COFF file.
687 if (checkSize(Data
, EC
, sizeof(dos_header
) + sizeof(COFF::PEMagic
))) {
688 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
689 // PE signature to find 'normal' COFF header.
690 const auto *DH
= reinterpret_cast<const dos_header
*>(base());
691 if (DH
->Magic
[0] == 'M' && DH
->Magic
[1] == 'Z') {
692 CurPtr
= DH
->AddressOfNewExeHeader
;
693 // Check the PE magic bytes. ("PE\0\0")
694 if (memcmp(base() + CurPtr
, COFF::PEMagic
, sizeof(COFF::PEMagic
)) != 0) {
695 EC
= object_error::parse_failed
;
698 CurPtr
+= sizeof(COFF::PEMagic
); // Skip the PE magic bytes.
703 if ((EC
= getObject(COFFHeader
, Data
, base() + CurPtr
)))
706 // It might be a bigobj file, let's check. Note that COFF bigobj and COFF
707 // import libraries share a common prefix but bigobj is more restrictive.
708 if (!HasPEHeader
&& COFFHeader
->Machine
== COFF::IMAGE_FILE_MACHINE_UNKNOWN
&&
709 COFFHeader
->NumberOfSections
== uint16_t(0xffff) &&
710 checkSize(Data
, EC
, sizeof(coff_bigobj_file_header
))) {
711 if ((EC
= getObject(COFFBigObjHeader
, Data
, base() + CurPtr
)))
714 // Verify that we are dealing with bigobj.
715 if (COFFBigObjHeader
->Version
>= COFF::BigObjHeader::MinBigObjectVersion
&&
716 std::memcmp(COFFBigObjHeader
->UUID
, COFF::BigObjMagic
,
717 sizeof(COFF::BigObjMagic
)) == 0) {
718 COFFHeader
= nullptr;
719 CurPtr
+= sizeof(coff_bigobj_file_header
);
721 // It's not a bigobj.
722 COFFBigObjHeader
= nullptr;
726 // The prior checkSize call may have failed. This isn't a hard error
727 // because we were just trying to sniff out bigobj.
728 EC
= std::error_code();
729 CurPtr
+= sizeof(coff_file_header
);
731 if (COFFHeader
->isImportLibrary())
736 const pe32_header
*Header
;
737 if ((EC
= getObject(Header
, Data
, base() + CurPtr
)))
740 const uint8_t *DataDirAddr
;
741 uint64_t DataDirSize
;
742 if (Header
->Magic
== COFF::PE32Header::PE32
) {
744 DataDirAddr
= base() + CurPtr
+ sizeof(pe32_header
);
745 DataDirSize
= sizeof(data_directory
) * PE32Header
->NumberOfRvaAndSize
;
746 } else if (Header
->Magic
== COFF::PE32Header::PE32_PLUS
) {
747 PE32PlusHeader
= reinterpret_cast<const pe32plus_header
*>(Header
);
748 DataDirAddr
= base() + CurPtr
+ sizeof(pe32plus_header
);
749 DataDirSize
= sizeof(data_directory
) * PE32PlusHeader
->NumberOfRvaAndSize
;
751 // It's neither PE32 nor PE32+.
752 EC
= object_error::parse_failed
;
755 if ((EC
= getObject(DataDirectory
, Data
, DataDirAddr
, DataDirSize
)))
760 CurPtr
+= COFFHeader
->SizeOfOptionalHeader
;
762 if ((EC
= getObject(SectionTable
, Data
, base() + CurPtr
,
763 (uint64_t)getNumberOfSections() * sizeof(coff_section
))))
766 // Initialize the pointer to the symbol table.
767 if (getPointerToSymbolTable() != 0) {
768 if ((EC
= initSymbolTablePtr())) {
769 SymbolTable16
= nullptr;
770 SymbolTable32
= nullptr;
771 StringTable
= nullptr;
775 // We had better not have any symbols if we don't have a symbol table.
776 if (getNumberOfSymbols() != 0) {
777 EC
= object_error::parse_failed
;
782 // Initialize the pointer to the beginning of the import table.
783 if ((EC
= initImportTablePtr()))
785 if ((EC
= initDelayImportTablePtr()))
788 // Initialize the pointer to the export table.
789 if ((EC
= initExportTablePtr()))
792 // Initialize the pointer to the base relocation table.
793 if ((EC
= initBaseRelocPtr()))
796 // Initialize the pointer to the export table.
797 if ((EC
= initDebugDirectoryPtr()))
800 if ((EC
= initLoadConfigPtr()))
803 EC
= std::error_code();
806 basic_symbol_iterator
COFFObjectFile::symbol_begin() const {
808 Ret
.p
= getSymbolTable();
809 return basic_symbol_iterator(SymbolRef(Ret
, this));
812 basic_symbol_iterator
COFFObjectFile::symbol_end() const {
813 // The symbol table ends where the string table begins.
815 Ret
.p
= reinterpret_cast<uintptr_t>(StringTable
);
816 return basic_symbol_iterator(SymbolRef(Ret
, this));
819 import_directory_iterator
COFFObjectFile::import_directory_begin() const {
820 if (!ImportDirectory
)
821 return import_directory_end();
822 if (ImportDirectory
->isNull())
823 return import_directory_end();
824 return import_directory_iterator(
825 ImportDirectoryEntryRef(ImportDirectory
, 0, this));
828 import_directory_iterator
COFFObjectFile::import_directory_end() const {
829 return import_directory_iterator(
830 ImportDirectoryEntryRef(nullptr, -1, this));
833 delay_import_directory_iterator
834 COFFObjectFile::delay_import_directory_begin() const {
835 return delay_import_directory_iterator(
836 DelayImportDirectoryEntryRef(DelayImportDirectory
, 0, this));
839 delay_import_directory_iterator
840 COFFObjectFile::delay_import_directory_end() const {
841 return delay_import_directory_iterator(
842 DelayImportDirectoryEntryRef(
843 DelayImportDirectory
, NumberOfDelayImportDirectory
, this));
846 export_directory_iterator
COFFObjectFile::export_directory_begin() const {
847 return export_directory_iterator(
848 ExportDirectoryEntryRef(ExportDirectory
, 0, this));
851 export_directory_iterator
COFFObjectFile::export_directory_end() const {
852 if (!ExportDirectory
)
853 return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
854 ExportDirectoryEntryRef
Ref(ExportDirectory
,
855 ExportDirectory
->AddressTableEntries
, this);
856 return export_directory_iterator(Ref
);
859 section_iterator
COFFObjectFile::section_begin() const {
861 Ret
.p
= reinterpret_cast<uintptr_t>(SectionTable
);
862 return section_iterator(SectionRef(Ret
, this));
865 section_iterator
COFFObjectFile::section_end() const {
868 COFFHeader
&& COFFHeader
->isImportLibrary() ? 0 : getNumberOfSections();
869 Ret
.p
= reinterpret_cast<uintptr_t>(SectionTable
+ NumSections
);
870 return section_iterator(SectionRef(Ret
, this));
873 base_reloc_iterator
COFFObjectFile::base_reloc_begin() const {
874 return base_reloc_iterator(BaseRelocRef(BaseRelocHeader
, this));
877 base_reloc_iterator
COFFObjectFile::base_reloc_end() const {
878 return base_reloc_iterator(BaseRelocRef(BaseRelocEnd
, this));
881 uint8_t COFFObjectFile::getBytesInAddress() const {
882 return getArch() == Triple::x86_64
|| getArch() == Triple::aarch64
? 8 : 4;
885 StringRef
COFFObjectFile::getFileFormatName() const {
886 switch(getMachine()) {
887 case COFF::IMAGE_FILE_MACHINE_I386
:
889 case COFF::IMAGE_FILE_MACHINE_AMD64
:
890 return "COFF-x86-64";
891 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
893 case COFF::IMAGE_FILE_MACHINE_ARM64
:
896 return "COFF-<unknown arch>";
900 Triple::ArchType
COFFObjectFile::getArch() const {
901 switch (getMachine()) {
902 case COFF::IMAGE_FILE_MACHINE_I386
:
904 case COFF::IMAGE_FILE_MACHINE_AMD64
:
905 return Triple::x86_64
;
906 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
907 return Triple::thumb
;
908 case COFF::IMAGE_FILE_MACHINE_ARM64
:
909 return Triple::aarch64
;
911 return Triple::UnknownArch
;
915 Expected
<uint64_t> COFFObjectFile::getStartAddress() const {
917 return PE32Header
->AddressOfEntryPoint
;
921 iterator_range
<import_directory_iterator
>
922 COFFObjectFile::import_directories() const {
923 return make_range(import_directory_begin(), import_directory_end());
926 iterator_range
<delay_import_directory_iterator
>
927 COFFObjectFile::delay_import_directories() const {
928 return make_range(delay_import_directory_begin(),
929 delay_import_directory_end());
932 iterator_range
<export_directory_iterator
>
933 COFFObjectFile::export_directories() const {
934 return make_range(export_directory_begin(), export_directory_end());
937 iterator_range
<base_reloc_iterator
> COFFObjectFile::base_relocs() const {
938 return make_range(base_reloc_begin(), base_reloc_end());
941 std::error_code
COFFObjectFile::getPE32Header(const pe32_header
*&Res
) const {
943 return std::error_code();
947 COFFObjectFile::getPE32PlusHeader(const pe32plus_header
*&Res
) const {
948 Res
= PE32PlusHeader
;
949 return std::error_code();
953 COFFObjectFile::getDataDirectory(uint32_t Index
,
954 const data_directory
*&Res
) const {
955 // Error if there's no data directory or the index is out of range.
956 if (!DataDirectory
) {
958 return object_error::parse_failed
;
960 assert(PE32Header
|| PE32PlusHeader
);
961 uint32_t NumEnt
= PE32Header
? PE32Header
->NumberOfRvaAndSize
962 : PE32PlusHeader
->NumberOfRvaAndSize
;
963 if (Index
>= NumEnt
) {
965 return object_error::parse_failed
;
967 Res
= &DataDirectory
[Index
];
968 return std::error_code();
971 std::error_code
COFFObjectFile::getSection(int32_t Index
,
972 const coff_section
*&Result
) const {
974 if (COFF::isReservedSectionNumber(Index
))
975 return std::error_code();
976 if (static_cast<uint32_t>(Index
) <= getNumberOfSections()) {
977 // We already verified the section table data, so no need to check again.
978 Result
= SectionTable
+ (Index
- 1);
979 return std::error_code();
981 return object_error::parse_failed
;
984 std::error_code
COFFObjectFile::getSection(StringRef SectionName
,
985 const coff_section
*&Result
) const {
988 for (const SectionRef
&Section
: sections()) {
989 if (std::error_code E
= Section
.getName(SecName
))
991 if (SecName
== SectionName
) {
992 Result
= getCOFFSection(Section
);
993 return std::error_code();
996 return object_error::parse_failed
;
999 std::error_code
COFFObjectFile::getString(uint32_t Offset
,
1000 StringRef
&Result
) const {
1001 if (StringTableSize
<= 4)
1002 // Tried to get a string from an empty string table.
1003 return object_error::parse_failed
;
1004 if (Offset
>= StringTableSize
)
1005 return object_error::unexpected_eof
;
1006 Result
= StringRef(StringTable
+ Offset
);
1007 return std::error_code();
1010 std::error_code
COFFObjectFile::getSymbolName(COFFSymbolRef Symbol
,
1011 StringRef
&Res
) const {
1012 return getSymbolName(Symbol
.getGeneric(), Res
);
1015 std::error_code
COFFObjectFile::getSymbolName(const coff_symbol_generic
*Symbol
,
1016 StringRef
&Res
) const {
1017 // Check for string table entry. First 4 bytes are 0.
1018 if (Symbol
->Name
.Offset
.Zeroes
== 0) {
1019 if (std::error_code EC
= getString(Symbol
->Name
.Offset
.Offset
, Res
))
1021 return std::error_code();
1024 if (Symbol
->Name
.ShortName
[COFF::NameSize
- 1] == 0)
1025 // Null terminated, let ::strlen figure out the length.
1026 Res
= StringRef(Symbol
->Name
.ShortName
);
1028 // Not null terminated, use all 8 bytes.
1029 Res
= StringRef(Symbol
->Name
.ShortName
, COFF::NameSize
);
1030 return std::error_code();
1034 COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol
) const {
1035 const uint8_t *Aux
= nullptr;
1037 size_t SymbolSize
= getSymbolTableEntrySize();
1038 if (Symbol
.getNumberOfAuxSymbols() > 0) {
1039 // AUX data comes immediately after the symbol in COFF
1040 Aux
= reinterpret_cast<const uint8_t *>(Symbol
.getRawPtr()) + SymbolSize
;
1042 // Verify that the Aux symbol points to a valid entry in the symbol table.
1043 uintptr_t Offset
= uintptr_t(Aux
) - uintptr_t(base());
1044 if (Offset
< getPointerToSymbolTable() ||
1046 getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize
))
1047 report_fatal_error("Aux Symbol data was outside of symbol table.");
1049 assert((Offset
- getPointerToSymbolTable()) % SymbolSize
== 0 &&
1050 "Aux Symbol data did not point to the beginning of a symbol");
1053 return makeArrayRef(Aux
, Symbol
.getNumberOfAuxSymbols() * SymbolSize
);
1056 std::error_code
COFFObjectFile::getSectionName(const coff_section
*Sec
,
1057 StringRef
&Res
) const {
1059 if (Sec
->Name
[COFF::NameSize
- 1] == 0)
1060 // Null terminated, let ::strlen figure out the length.
1063 // Not null terminated, use all 8 bytes.
1064 Name
= StringRef(Sec
->Name
, COFF::NameSize
);
1066 // Check for string table entry. First byte is '/'.
1067 if (Name
.startswith("/")) {
1069 if (Name
.startswith("//")) {
1070 if (decodeBase64StringEntry(Name
.substr(2), Offset
))
1071 return object_error::parse_failed
;
1073 if (Name
.substr(1).getAsInteger(10, Offset
))
1074 return object_error::parse_failed
;
1076 if (std::error_code EC
= getString(Offset
, Name
))
1081 return std::error_code();
1084 uint64_t COFFObjectFile::getSectionSize(const coff_section
*Sec
) const {
1085 // SizeOfRawData and VirtualSize change what they represent depending on
1086 // whether or not we have an executable image.
1088 // For object files, SizeOfRawData contains the size of section's data;
1089 // VirtualSize should be zero but isn't due to buggy COFF writers.
1091 // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
1092 // actual section size is in VirtualSize. It is possible for VirtualSize to
1093 // be greater than SizeOfRawData; the contents past that point should be
1094 // considered to be zero.
1096 return std::min(Sec
->VirtualSize
, Sec
->SizeOfRawData
);
1097 return Sec
->SizeOfRawData
;
1101 COFFObjectFile::getSectionContents(const coff_section
*Sec
,
1102 ArrayRef
<uint8_t> &Res
) const {
1103 // In COFF, a virtual section won't have any in-file
1104 // content, so the file pointer to the content will be zero.
1105 if (Sec
->PointerToRawData
== 0)
1106 return std::error_code();
1107 // The only thing that we need to verify is that the contents is contained
1108 // within the file bounds. We don't need to make sure it doesn't cover other
1109 // data, as there's nothing that says that is not allowed.
1110 uintptr_t ConStart
= uintptr_t(base()) + Sec
->PointerToRawData
;
1111 uint32_t SectionSize
= getSectionSize(Sec
);
1112 if (checkOffset(Data
, ConStart
, SectionSize
))
1113 return object_error::parse_failed
;
1114 Res
= makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart
), SectionSize
);
1115 return std::error_code();
1118 const coff_relocation
*COFFObjectFile::toRel(DataRefImpl Rel
) const {
1119 return reinterpret_cast<const coff_relocation
*>(Rel
.p
);
1122 void COFFObjectFile::moveRelocationNext(DataRefImpl
&Rel
) const {
1123 Rel
.p
= reinterpret_cast<uintptr_t>(
1124 reinterpret_cast<const coff_relocation
*>(Rel
.p
) + 1);
1127 uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel
) const {
1128 const coff_relocation
*R
= toRel(Rel
);
1129 return R
->VirtualAddress
;
1132 symbol_iterator
COFFObjectFile::getRelocationSymbol(DataRefImpl Rel
) const {
1133 const coff_relocation
*R
= toRel(Rel
);
1135 if (R
->SymbolTableIndex
>= getNumberOfSymbols())
1136 return symbol_end();
1138 Ref
.p
= reinterpret_cast<uintptr_t>(SymbolTable16
+ R
->SymbolTableIndex
);
1139 else if (SymbolTable32
)
1140 Ref
.p
= reinterpret_cast<uintptr_t>(SymbolTable32
+ R
->SymbolTableIndex
);
1142 llvm_unreachable("no symbol table pointer!");
1143 return symbol_iterator(SymbolRef(Ref
, this));
1146 uint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel
) const {
1147 const coff_relocation
* R
= toRel(Rel
);
1151 const coff_section
*
1152 COFFObjectFile::getCOFFSection(const SectionRef
&Section
) const {
1153 return toSec(Section
.getRawDataRefImpl());
1156 COFFSymbolRef
COFFObjectFile::getCOFFSymbol(const DataRefImpl
&Ref
) const {
1158 return toSymb
<coff_symbol16
>(Ref
);
1160 return toSymb
<coff_symbol32
>(Ref
);
1161 llvm_unreachable("no symbol table pointer!");
1164 COFFSymbolRef
COFFObjectFile::getCOFFSymbol(const SymbolRef
&Symbol
) const {
1165 return getCOFFSymbol(Symbol
.getRawDataRefImpl());
1168 const coff_relocation
*
1169 COFFObjectFile::getCOFFRelocation(const RelocationRef
&Reloc
) const {
1170 return toRel(Reloc
.getRawDataRefImpl());
1173 ArrayRef
<coff_relocation
>
1174 COFFObjectFile::getRelocations(const coff_section
*Sec
) const {
1175 return {getFirstReloc(Sec
, Data
, base()),
1176 getNumberOfRelocations(Sec
, Data
, base())};
1179 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
1180 case COFF::reloc_type: \
1183 StringRef
COFFObjectFile::getRelocationTypeName(uint16_t Type
) const {
1184 switch (getMachine()) {
1185 case COFF::IMAGE_FILE_MACHINE_AMD64
:
1187 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE
);
1188 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64
);
1189 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32
);
1190 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB
);
1191 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32
);
1192 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1
);
1193 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2
);
1194 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3
);
1195 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4
);
1196 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5
);
1197 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION
);
1198 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL
);
1199 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7
);
1200 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN
);
1201 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32
);
1202 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR
);
1203 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32
);
1208 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
1210 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE
);
1211 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32
);
1212 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB
);
1213 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24
);
1214 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11
);
1215 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN
);
1216 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24
);
1217 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11
);
1218 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION
);
1219 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL
);
1220 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A
);
1221 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T
);
1222 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T
);
1223 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T
);
1224 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T
);
1229 case COFF::IMAGE_FILE_MACHINE_ARM64
:
1231 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ABSOLUTE
);
1232 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32
);
1233 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32NB
);
1234 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH26
);
1235 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEBASE_REL21
);
1236 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_REL21
);
1237 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEOFFSET_12A
);
1238 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_PAGEOFFSET_12L
);
1239 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL
);
1240 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_LOW12A
);
1241 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_HIGH12A
);
1242 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECREL_LOW12L
);
1243 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_TOKEN
);
1244 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_SECTION
);
1245 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR64
);
1246 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH19
);
1247 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_BRANCH14
);
1252 case COFF::IMAGE_FILE_MACHINE_I386
:
1254 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE
);
1255 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16
);
1256 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16
);
1257 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32
);
1258 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB
);
1259 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12
);
1260 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION
);
1261 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL
);
1262 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN
);
1263 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7
);
1264 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32
);
1274 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
1276 void COFFObjectFile::getRelocationTypeName(
1277 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
1278 const coff_relocation
*Reloc
= toRel(Rel
);
1279 StringRef Res
= getRelocationTypeName(Reloc
->Type
);
1280 Result
.append(Res
.begin(), Res
.end());
1283 bool COFFObjectFile::isRelocatableObject() const {
1284 return !DataDirectory
;
1287 bool ImportDirectoryEntryRef::
1288 operator==(const ImportDirectoryEntryRef
&Other
) const {
1289 return ImportTable
== Other
.ImportTable
&& Index
== Other
.Index
;
1292 void ImportDirectoryEntryRef::moveNext() {
1294 if (ImportTable
[Index
].isNull()) {
1296 ImportTable
= nullptr;
1300 std::error_code
ImportDirectoryEntryRef::getImportTableEntry(
1301 const coff_import_directory_table_entry
*&Result
) const {
1302 return getObject(Result
, OwningObject
->Data
, ImportTable
+ Index
);
1305 static imported_symbol_iterator
1306 makeImportedSymbolIterator(const COFFObjectFile
*Object
,
1307 uintptr_t Ptr
, int Index
) {
1308 if (Object
->getBytesInAddress() == 4) {
1309 auto *P
= reinterpret_cast<const import_lookup_table_entry32
*>(Ptr
);
1310 return imported_symbol_iterator(ImportedSymbolRef(P
, Index
, Object
));
1312 auto *P
= reinterpret_cast<const import_lookup_table_entry64
*>(Ptr
);
1313 return imported_symbol_iterator(ImportedSymbolRef(P
, Index
, Object
));
1316 static imported_symbol_iterator
1317 importedSymbolBegin(uint32_t RVA
, const COFFObjectFile
*Object
) {
1318 uintptr_t IntPtr
= 0;
1319 Object
->getRvaPtr(RVA
, IntPtr
);
1320 return makeImportedSymbolIterator(Object
, IntPtr
, 0);
1323 static imported_symbol_iterator
1324 importedSymbolEnd(uint32_t RVA
, const COFFObjectFile
*Object
) {
1325 uintptr_t IntPtr
= 0;
1326 Object
->getRvaPtr(RVA
, IntPtr
);
1327 // Forward the pointer to the last entry which is null.
1329 if (Object
->getBytesInAddress() == 4) {
1330 auto *Entry
= reinterpret_cast<ulittle32_t
*>(IntPtr
);
1334 auto *Entry
= reinterpret_cast<ulittle64_t
*>(IntPtr
);
1338 return makeImportedSymbolIterator(Object
, IntPtr
, Index
);
1341 imported_symbol_iterator
1342 ImportDirectoryEntryRef::imported_symbol_begin() const {
1343 return importedSymbolBegin(ImportTable
[Index
].ImportAddressTableRVA
,
1347 imported_symbol_iterator
1348 ImportDirectoryEntryRef::imported_symbol_end() const {
1349 return importedSymbolEnd(ImportTable
[Index
].ImportAddressTableRVA
,
1353 iterator_range
<imported_symbol_iterator
>
1354 ImportDirectoryEntryRef::imported_symbols() const {
1355 return make_range(imported_symbol_begin(), imported_symbol_end());
1358 imported_symbol_iterator
ImportDirectoryEntryRef::lookup_table_begin() const {
1359 return importedSymbolBegin(ImportTable
[Index
].ImportLookupTableRVA
,
1363 imported_symbol_iterator
ImportDirectoryEntryRef::lookup_table_end() const {
1364 return importedSymbolEnd(ImportTable
[Index
].ImportLookupTableRVA
,
1368 iterator_range
<imported_symbol_iterator
>
1369 ImportDirectoryEntryRef::lookup_table_symbols() const {
1370 return make_range(lookup_table_begin(), lookup_table_end());
1373 std::error_code
ImportDirectoryEntryRef::getName(StringRef
&Result
) const {
1374 uintptr_t IntPtr
= 0;
1375 if (std::error_code EC
=
1376 OwningObject
->getRvaPtr(ImportTable
[Index
].NameRVA
, IntPtr
))
1378 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
));
1379 return std::error_code();
1383 ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result
) const {
1384 Result
= ImportTable
[Index
].ImportLookupTableRVA
;
1385 return std::error_code();
1389 ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result
) const {
1390 Result
= ImportTable
[Index
].ImportAddressTableRVA
;
1391 return std::error_code();
1394 bool DelayImportDirectoryEntryRef::
1395 operator==(const DelayImportDirectoryEntryRef
&Other
) const {
1396 return Table
== Other
.Table
&& Index
== Other
.Index
;
1399 void DelayImportDirectoryEntryRef::moveNext() {
1403 imported_symbol_iterator
1404 DelayImportDirectoryEntryRef::imported_symbol_begin() const {
1405 return importedSymbolBegin(Table
[Index
].DelayImportNameTable
,
1409 imported_symbol_iterator
1410 DelayImportDirectoryEntryRef::imported_symbol_end() const {
1411 return importedSymbolEnd(Table
[Index
].DelayImportNameTable
,
1415 iterator_range
<imported_symbol_iterator
>
1416 DelayImportDirectoryEntryRef::imported_symbols() const {
1417 return make_range(imported_symbol_begin(), imported_symbol_end());
1420 std::error_code
DelayImportDirectoryEntryRef::getName(StringRef
&Result
) const {
1421 uintptr_t IntPtr
= 0;
1422 if (std::error_code EC
= OwningObject
->getRvaPtr(Table
[Index
].Name
, IntPtr
))
1424 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
));
1425 return std::error_code();
1428 std::error_code
DelayImportDirectoryEntryRef::
1429 getDelayImportTable(const delay_import_directory_table_entry
*&Result
) const {
1431 return std::error_code();
1434 std::error_code
DelayImportDirectoryEntryRef::
1435 getImportAddress(int AddrIndex
, uint64_t &Result
) const {
1436 uint32_t RVA
= Table
[Index
].DelayImportAddressTable
+
1437 AddrIndex
* (OwningObject
->is64() ? 8 : 4);
1438 uintptr_t IntPtr
= 0;
1439 if (std::error_code EC
= OwningObject
->getRvaPtr(RVA
, IntPtr
))
1441 if (OwningObject
->is64())
1442 Result
= *reinterpret_cast<const ulittle64_t
*>(IntPtr
);
1444 Result
= *reinterpret_cast<const ulittle32_t
*>(IntPtr
);
1445 return std::error_code();
1448 bool ExportDirectoryEntryRef::
1449 operator==(const ExportDirectoryEntryRef
&Other
) const {
1450 return ExportTable
== Other
.ExportTable
&& Index
== Other
.Index
;
1453 void ExportDirectoryEntryRef::moveNext() {
1457 // Returns the name of the current export symbol. If the symbol is exported only
1458 // by ordinal, the empty string is set as a result.
1459 std::error_code
ExportDirectoryEntryRef::getDllName(StringRef
&Result
) const {
1460 uintptr_t IntPtr
= 0;
1461 if (std::error_code EC
=
1462 OwningObject
->getRvaPtr(ExportTable
->NameRVA
, IntPtr
))
1464 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
));
1465 return std::error_code();
1468 // Returns the starting ordinal number.
1470 ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result
) const {
1471 Result
= ExportTable
->OrdinalBase
;
1472 return std::error_code();
1475 // Returns the export ordinal of the current export symbol.
1476 std::error_code
ExportDirectoryEntryRef::getOrdinal(uint32_t &Result
) const {
1477 Result
= ExportTable
->OrdinalBase
+ Index
;
1478 return std::error_code();
1481 // Returns the address of the current export symbol.
1482 std::error_code
ExportDirectoryEntryRef::getExportRVA(uint32_t &Result
) const {
1483 uintptr_t IntPtr
= 0;
1484 if (std::error_code EC
=
1485 OwningObject
->getRvaPtr(ExportTable
->ExportAddressTableRVA
, IntPtr
))
1487 const export_address_table_entry
*entry
=
1488 reinterpret_cast<const export_address_table_entry
*>(IntPtr
);
1489 Result
= entry
[Index
].ExportRVA
;
1490 return std::error_code();
1493 // Returns the name of the current export symbol. If the symbol is exported only
1494 // by ordinal, the empty string is set as a result.
1496 ExportDirectoryEntryRef::getSymbolName(StringRef
&Result
) const {
1497 uintptr_t IntPtr
= 0;
1498 if (std::error_code EC
=
1499 OwningObject
->getRvaPtr(ExportTable
->OrdinalTableRVA
, IntPtr
))
1501 const ulittle16_t
*Start
= reinterpret_cast<const ulittle16_t
*>(IntPtr
);
1503 uint32_t NumEntries
= ExportTable
->NumberOfNamePointers
;
1505 for (const ulittle16_t
*I
= Start
, *E
= Start
+ NumEntries
;
1506 I
< E
; ++I
, ++Offset
) {
1509 if (std::error_code EC
=
1510 OwningObject
->getRvaPtr(ExportTable
->NamePointerRVA
, IntPtr
))
1512 const ulittle32_t
*NamePtr
= reinterpret_cast<const ulittle32_t
*>(IntPtr
);
1513 if (std::error_code EC
= OwningObject
->getRvaPtr(NamePtr
[Offset
], IntPtr
))
1515 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
));
1516 return std::error_code();
1519 return std::error_code();
1522 std::error_code
ExportDirectoryEntryRef::isForwarder(bool &Result
) const {
1523 const data_directory
*DataEntry
;
1524 if (auto EC
= OwningObject
->getDataDirectory(COFF::EXPORT_TABLE
, DataEntry
))
1527 if (auto EC
= getExportRVA(RVA
))
1529 uint32_t Begin
= DataEntry
->RelativeVirtualAddress
;
1530 uint32_t End
= DataEntry
->RelativeVirtualAddress
+ DataEntry
->Size
;
1531 Result
= (Begin
<= RVA
&& RVA
< End
);
1532 return std::error_code();
1535 std::error_code
ExportDirectoryEntryRef::getForwardTo(StringRef
&Result
) const {
1537 if (auto EC
= getExportRVA(RVA
))
1539 uintptr_t IntPtr
= 0;
1540 if (auto EC
= OwningObject
->getRvaPtr(RVA
, IntPtr
))
1542 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
));
1543 return std::error_code();
1546 bool ImportedSymbolRef::
1547 operator==(const ImportedSymbolRef
&Other
) const {
1548 return Entry32
== Other
.Entry32
&& Entry64
== Other
.Entry64
1549 && Index
== Other
.Index
;
1552 void ImportedSymbolRef::moveNext() {
1557 ImportedSymbolRef::getSymbolName(StringRef
&Result
) const {
1560 // If a symbol is imported only by ordinal, it has no name.
1561 if (Entry32
[Index
].isOrdinal())
1562 return std::error_code();
1563 RVA
= Entry32
[Index
].getHintNameRVA();
1565 if (Entry64
[Index
].isOrdinal())
1566 return std::error_code();
1567 RVA
= Entry64
[Index
].getHintNameRVA();
1569 uintptr_t IntPtr
= 0;
1570 if (std::error_code EC
= OwningObject
->getRvaPtr(RVA
, IntPtr
))
1572 // +2 because the first two bytes is hint.
1573 Result
= StringRef(reinterpret_cast<const char *>(IntPtr
+ 2));
1574 return std::error_code();
1577 std::error_code
ImportedSymbolRef::isOrdinal(bool &Result
) const {
1579 Result
= Entry32
[Index
].isOrdinal();
1581 Result
= Entry64
[Index
].isOrdinal();
1582 return std::error_code();
1585 std::error_code
ImportedSymbolRef::getHintNameRVA(uint32_t &Result
) const {
1587 Result
= Entry32
[Index
].getHintNameRVA();
1589 Result
= Entry64
[Index
].getHintNameRVA();
1590 return std::error_code();
1593 std::error_code
ImportedSymbolRef::getOrdinal(uint16_t &Result
) const {
1596 if (Entry32
[Index
].isOrdinal()) {
1597 Result
= Entry32
[Index
].getOrdinal();
1598 return std::error_code();
1600 RVA
= Entry32
[Index
].getHintNameRVA();
1602 if (Entry64
[Index
].isOrdinal()) {
1603 Result
= Entry64
[Index
].getOrdinal();
1604 return std::error_code();
1606 RVA
= Entry64
[Index
].getHintNameRVA();
1608 uintptr_t IntPtr
= 0;
1609 if (std::error_code EC
= OwningObject
->getRvaPtr(RVA
, IntPtr
))
1611 Result
= *reinterpret_cast<const ulittle16_t
*>(IntPtr
);
1612 return std::error_code();
1615 Expected
<std::unique_ptr
<COFFObjectFile
>>
1616 ObjectFile::createCOFFObjectFile(MemoryBufferRef Object
) {
1618 std::unique_ptr
<COFFObjectFile
> Ret(new COFFObjectFile(Object
, EC
));
1620 return errorCodeToError(EC
);
1621 return std::move(Ret
);
1624 bool BaseRelocRef::operator==(const BaseRelocRef
&Other
) const {
1625 return Header
== Other
.Header
&& Index
== Other
.Index
;
1628 void BaseRelocRef::moveNext() {
1629 // Header->BlockSize is the size of the current block, including the
1630 // size of the header itself.
1631 uint32_t Size
= sizeof(*Header
) +
1632 sizeof(coff_base_reloc_block_entry
) * (Index
+ 1);
1633 if (Size
== Header
->BlockSize
) {
1634 // .reloc contains a list of base relocation blocks. Each block
1635 // consists of the header followed by entries. The header contains
1636 // how many entories will follow. When we reach the end of the
1637 // current block, proceed to the next block.
1638 Header
= reinterpret_cast<const coff_base_reloc_block_header
*>(
1639 reinterpret_cast<const uint8_t *>(Header
) + Size
);
1646 std::error_code
BaseRelocRef::getType(uint8_t &Type
) const {
1647 auto *Entry
= reinterpret_cast<const coff_base_reloc_block_entry
*>(Header
+ 1);
1648 Type
= Entry
[Index
].getType();
1649 return std::error_code();
1652 std::error_code
BaseRelocRef::getRVA(uint32_t &Result
) const {
1653 auto *Entry
= reinterpret_cast<const coff_base_reloc_block_entry
*>(Header
+ 1);
1654 Result
= Header
->PageRVA
+ Entry
[Index
].getOffset();
1655 return std::error_code();
1658 #define RETURN_IF_ERROR(E) \
1662 Expected
<ArrayRef
<UTF16
>>
1663 ResourceSectionRef::getDirStringAtOffset(uint32_t Offset
) {
1664 BinaryStreamReader Reader
= BinaryStreamReader(BBS
);
1665 Reader
.setOffset(Offset
);
1667 RETURN_IF_ERROR(Reader
.readInteger(Length
));
1668 ArrayRef
<UTF16
> RawDirString
;
1669 RETURN_IF_ERROR(Reader
.readArray(RawDirString
, Length
));
1670 return RawDirString
;
1673 Expected
<ArrayRef
<UTF16
>>
1674 ResourceSectionRef::getEntryNameString(const coff_resource_dir_entry
&Entry
) {
1675 return getDirStringAtOffset(Entry
.Identifier
.getNameOffset());
1678 Expected
<const coff_resource_dir_table
&>
1679 ResourceSectionRef::getTableAtOffset(uint32_t Offset
) {
1680 const coff_resource_dir_table
*Table
= nullptr;
1682 BinaryStreamReader
Reader(BBS
);
1683 Reader
.setOffset(Offset
);
1684 RETURN_IF_ERROR(Reader
.readObject(Table
));
1685 assert(Table
!= nullptr);
1689 Expected
<const coff_resource_dir_table
&>
1690 ResourceSectionRef::getEntrySubDir(const coff_resource_dir_entry
&Entry
) {
1691 return getTableAtOffset(Entry
.Offset
.value());
1694 Expected
<const coff_resource_dir_table
&> ResourceSectionRef::getBaseTable() {
1695 return getTableAtOffset(0);