1 //===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares the COFFObjectFile class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_OBJECT_COFF_H
14 #define LLVM_OBJECT_COFF_H
16 #include "llvm/ADT/iterator_range.h"
17 #include "llvm/BinaryFormat/COFF.h"
18 #include "llvm/MC/SubtargetFeature.h"
19 #include "llvm/Object/Binary.h"
20 #include "llvm/Object/CVDebugRecord.h"
21 #include "llvm/Object/Error.h"
22 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/BinaryByteStream.h"
24 #include "llvm/Support/ConvertUTF.h"
25 #include "llvm/Support/Endian.h"
26 #include "llvm/Support/ErrorHandling.h"
30 #include <system_error>
34 template <typename T
> class ArrayRef
;
39 class DelayImportDirectoryEntryRef
;
40 class ExportDirectoryEntryRef
;
41 class ImportDirectoryEntryRef
;
42 class ImportedSymbolRef
;
43 class ResourceSectionRef
;
45 using import_directory_iterator
= content_iterator
<ImportDirectoryEntryRef
>;
46 using delay_import_directory_iterator
=
47 content_iterator
<DelayImportDirectoryEntryRef
>;
48 using export_directory_iterator
= content_iterator
<ExportDirectoryEntryRef
>;
49 using imported_symbol_iterator
= content_iterator
<ImportedSymbolRef
>;
50 using base_reloc_iterator
= content_iterator
<BaseRelocRef
>;
52 /// The DOS compatible header at the front of all PE/COFF executables.
55 support::ulittle16_t UsedBytesInTheLastPage
;
56 support::ulittle16_t FileSizeInPages
;
57 support::ulittle16_t NumberOfRelocationItems
;
58 support::ulittle16_t HeaderSizeInParagraphs
;
59 support::ulittle16_t MinimumExtraParagraphs
;
60 support::ulittle16_t MaximumExtraParagraphs
;
61 support::ulittle16_t InitialRelativeSS
;
62 support::ulittle16_t InitialSP
;
63 support::ulittle16_t Checksum
;
64 support::ulittle16_t InitialIP
;
65 support::ulittle16_t InitialRelativeCS
;
66 support::ulittle16_t AddressOfRelocationTable
;
67 support::ulittle16_t OverlayNumber
;
68 support::ulittle16_t Reserved
[4];
69 support::ulittle16_t OEMid
;
70 support::ulittle16_t OEMinfo
;
71 support::ulittle16_t Reserved2
[10];
72 support::ulittle32_t AddressOfNewExeHeader
;
75 struct coff_file_header
{
76 support::ulittle16_t Machine
;
77 support::ulittle16_t NumberOfSections
;
78 support::ulittle32_t TimeDateStamp
;
79 support::ulittle32_t PointerToSymbolTable
;
80 support::ulittle32_t NumberOfSymbols
;
81 support::ulittle16_t SizeOfOptionalHeader
;
82 support::ulittle16_t Characteristics
;
84 bool isImportLibrary() const { return NumberOfSections
== 0xffff; }
87 struct coff_bigobj_file_header
{
88 support::ulittle16_t Sig1
;
89 support::ulittle16_t Sig2
;
90 support::ulittle16_t Version
;
91 support::ulittle16_t Machine
;
92 support::ulittle32_t TimeDateStamp
;
94 support::ulittle32_t unused1
;
95 support::ulittle32_t unused2
;
96 support::ulittle32_t unused3
;
97 support::ulittle32_t unused4
;
98 support::ulittle32_t NumberOfSections
;
99 support::ulittle32_t PointerToSymbolTable
;
100 support::ulittle32_t NumberOfSymbols
;
103 /// The 32-bit PE header that follows the COFF header.
105 support::ulittle16_t Magic
;
106 uint8_t MajorLinkerVersion
;
107 uint8_t MinorLinkerVersion
;
108 support::ulittle32_t SizeOfCode
;
109 support::ulittle32_t SizeOfInitializedData
;
110 support::ulittle32_t SizeOfUninitializedData
;
111 support::ulittle32_t AddressOfEntryPoint
;
112 support::ulittle32_t BaseOfCode
;
113 support::ulittle32_t BaseOfData
;
114 support::ulittle32_t ImageBase
;
115 support::ulittle32_t SectionAlignment
;
116 support::ulittle32_t FileAlignment
;
117 support::ulittle16_t MajorOperatingSystemVersion
;
118 support::ulittle16_t MinorOperatingSystemVersion
;
119 support::ulittle16_t MajorImageVersion
;
120 support::ulittle16_t MinorImageVersion
;
121 support::ulittle16_t MajorSubsystemVersion
;
122 support::ulittle16_t MinorSubsystemVersion
;
123 support::ulittle32_t Win32VersionValue
;
124 support::ulittle32_t SizeOfImage
;
125 support::ulittle32_t SizeOfHeaders
;
126 support::ulittle32_t CheckSum
;
127 support::ulittle16_t Subsystem
;
128 // FIXME: This should be DllCharacteristics.
129 support::ulittle16_t DLLCharacteristics
;
130 support::ulittle32_t SizeOfStackReserve
;
131 support::ulittle32_t SizeOfStackCommit
;
132 support::ulittle32_t SizeOfHeapReserve
;
133 support::ulittle32_t SizeOfHeapCommit
;
134 support::ulittle32_t LoaderFlags
;
135 // FIXME: This should be NumberOfRvaAndSizes.
136 support::ulittle32_t NumberOfRvaAndSize
;
139 /// The 64-bit PE header that follows the COFF header.
140 struct pe32plus_header
{
141 support::ulittle16_t Magic
;
142 uint8_t MajorLinkerVersion
;
143 uint8_t MinorLinkerVersion
;
144 support::ulittle32_t SizeOfCode
;
145 support::ulittle32_t SizeOfInitializedData
;
146 support::ulittle32_t SizeOfUninitializedData
;
147 support::ulittle32_t AddressOfEntryPoint
;
148 support::ulittle32_t BaseOfCode
;
149 support::ulittle64_t ImageBase
;
150 support::ulittle32_t SectionAlignment
;
151 support::ulittle32_t FileAlignment
;
152 support::ulittle16_t MajorOperatingSystemVersion
;
153 support::ulittle16_t MinorOperatingSystemVersion
;
154 support::ulittle16_t MajorImageVersion
;
155 support::ulittle16_t MinorImageVersion
;
156 support::ulittle16_t MajorSubsystemVersion
;
157 support::ulittle16_t MinorSubsystemVersion
;
158 support::ulittle32_t Win32VersionValue
;
159 support::ulittle32_t SizeOfImage
;
160 support::ulittle32_t SizeOfHeaders
;
161 support::ulittle32_t CheckSum
;
162 support::ulittle16_t Subsystem
;
163 support::ulittle16_t DLLCharacteristics
;
164 support::ulittle64_t SizeOfStackReserve
;
165 support::ulittle64_t SizeOfStackCommit
;
166 support::ulittle64_t SizeOfHeapReserve
;
167 support::ulittle64_t SizeOfHeapCommit
;
168 support::ulittle32_t LoaderFlags
;
169 support::ulittle32_t NumberOfRvaAndSize
;
172 struct data_directory
{
173 support::ulittle32_t RelativeVirtualAddress
;
174 support::ulittle32_t Size
;
177 struct debug_directory
{
178 support::ulittle32_t Characteristics
;
179 support::ulittle32_t TimeDateStamp
;
180 support::ulittle16_t MajorVersion
;
181 support::ulittle16_t MinorVersion
;
182 support::ulittle32_t Type
;
183 support::ulittle32_t SizeOfData
;
184 support::ulittle32_t AddressOfRawData
;
185 support::ulittle32_t PointerToRawData
;
188 template <typename IntTy
>
189 struct import_lookup_table_entry
{
192 bool isOrdinal() const { return Data
< 0; }
194 uint16_t getOrdinal() const {
195 assert(isOrdinal() && "ILT entry is not an ordinal!");
196 return Data
& 0xFFFF;
199 uint32_t getHintNameRVA() const {
200 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
201 return Data
& 0xFFFFFFFF;
205 using import_lookup_table_entry32
=
206 import_lookup_table_entry
<support::little32_t
>;
207 using import_lookup_table_entry64
=
208 import_lookup_table_entry
<support::little64_t
>;
210 struct delay_import_directory_table_entry
{
211 // dumpbin reports this field as "Characteristics" instead of "Attributes".
212 support::ulittle32_t Attributes
;
213 support::ulittle32_t Name
;
214 support::ulittle32_t ModuleHandle
;
215 support::ulittle32_t DelayImportAddressTable
;
216 support::ulittle32_t DelayImportNameTable
;
217 support::ulittle32_t BoundDelayImportTable
;
218 support::ulittle32_t UnloadDelayImportTable
;
219 support::ulittle32_t TimeStamp
;
222 struct export_directory_table_entry
{
223 support::ulittle32_t ExportFlags
;
224 support::ulittle32_t TimeDateStamp
;
225 support::ulittle16_t MajorVersion
;
226 support::ulittle16_t MinorVersion
;
227 support::ulittle32_t NameRVA
;
228 support::ulittle32_t OrdinalBase
;
229 support::ulittle32_t AddressTableEntries
;
230 support::ulittle32_t NumberOfNamePointers
;
231 support::ulittle32_t ExportAddressTableRVA
;
232 support::ulittle32_t NamePointerRVA
;
233 support::ulittle32_t OrdinalTableRVA
;
236 union export_address_table_entry
{
237 support::ulittle32_t ExportRVA
;
238 support::ulittle32_t ForwarderRVA
;
241 using export_name_pointer_table_entry
= support::ulittle32_t
;
242 using export_ordinal_table_entry
= support::ulittle16_t
;
244 struct StringTableOffset
{
245 support::ulittle32_t Zeroes
;
246 support::ulittle32_t Offset
;
249 template <typename SectionNumberType
>
252 char ShortName
[COFF::NameSize
];
253 StringTableOffset Offset
;
256 support::ulittle32_t Value
;
257 SectionNumberType SectionNumber
;
259 support::ulittle16_t Type
;
261 uint8_t StorageClass
;
262 uint8_t NumberOfAuxSymbols
;
265 using coff_symbol16
= coff_symbol
<support::ulittle16_t
>;
266 using coff_symbol32
= coff_symbol
<support::ulittle32_t
>;
268 // Contains only common parts of coff_symbol16 and coff_symbol32.
269 struct coff_symbol_generic
{
271 char ShortName
[COFF::NameSize
];
272 StringTableOffset Offset
;
274 support::ulittle32_t Value
;
277 struct coff_aux_section_definition
;
278 struct coff_aux_weak_external
;
280 class COFFSymbolRef
{
282 COFFSymbolRef() = default;
283 COFFSymbolRef(const coff_symbol16
*CS
) : CS16(CS
) {}
284 COFFSymbolRef(const coff_symbol32
*CS
) : CS32(CS
) {}
286 const void *getRawPtr() const {
287 return CS16
? static_cast<const void *>(CS16
) : CS32
;
290 const coff_symbol_generic
*getGeneric() const {
292 return reinterpret_cast<const coff_symbol_generic
*>(CS16
);
293 return reinterpret_cast<const coff_symbol_generic
*>(CS32
);
296 friend bool operator<(COFFSymbolRef A
, COFFSymbolRef B
) {
297 return A
.getRawPtr() < B
.getRawPtr();
300 bool isBigObj() const {
305 llvm_unreachable("COFFSymbolRef points to nothing!");
308 const char *getShortName() const {
309 return CS16
? CS16
->Name
.ShortName
: CS32
->Name
.ShortName
;
312 const StringTableOffset
&getStringTableOffset() const {
313 assert(isSet() && "COFFSymbolRef points to nothing!");
314 return CS16
? CS16
->Name
.Offset
: CS32
->Name
.Offset
;
317 uint32_t getValue() const { return CS16
? CS16
->Value
: CS32
->Value
; }
319 int32_t getSectionNumber() const {
320 assert(isSet() && "COFFSymbolRef points to nothing!");
322 // Reserved sections are returned as negative numbers.
323 if (CS16
->SectionNumber
<= COFF::MaxNumberOfSections16
)
324 return CS16
->SectionNumber
;
325 return static_cast<int16_t>(CS16
->SectionNumber
);
327 return static_cast<int32_t>(CS32
->SectionNumber
);
330 uint16_t getType() const {
331 assert(isSet() && "COFFSymbolRef points to nothing!");
332 return CS16
? CS16
->Type
: CS32
->Type
;
335 uint8_t getStorageClass() const {
336 assert(isSet() && "COFFSymbolRef points to nothing!");
337 return CS16
? CS16
->StorageClass
: CS32
->StorageClass
;
340 uint8_t getNumberOfAuxSymbols() const {
341 assert(isSet() && "COFFSymbolRef points to nothing!");
342 return CS16
? CS16
->NumberOfAuxSymbols
: CS32
->NumberOfAuxSymbols
;
345 uint8_t getBaseType() const { return getType() & 0x0F; }
347 uint8_t getComplexType() const {
348 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT
;
351 template <typename T
> const T
*getAux() const {
352 return CS16
? reinterpret_cast<const T
*>(CS16
+ 1)
353 : reinterpret_cast<const T
*>(CS32
+ 1);
356 const coff_aux_section_definition
*getSectionDefinition() const {
357 if (!getNumberOfAuxSymbols() ||
358 getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC
)
360 return getAux
<coff_aux_section_definition
>();
363 const coff_aux_weak_external
*getWeakExternal() const {
364 if (!getNumberOfAuxSymbols() ||
365 getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
)
367 return getAux
<coff_aux_weak_external
>();
370 bool isAbsolute() const {
371 return getSectionNumber() == -1;
374 bool isExternal() const {
375 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
;
378 bool isCommon() const {
379 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
383 bool isUndefined() const {
384 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
388 bool isWeakExternal() const {
389 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
392 bool isFunctionDefinition() const {
393 return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL
&&
394 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION
&&
395 !COFF::isReservedSectionNumber(getSectionNumber());
398 bool isFunctionLineInfo() const {
399 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION
;
402 bool isAnyUndefined() const {
403 return isUndefined() || isWeakExternal();
406 bool isFileRecord() const {
407 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE
;
410 bool isSection() const {
411 return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION
;
414 bool isSectionDefinition() const {
415 // C++/CLI creates external ABS symbols for non-const appdomain globals.
416 // These are also followed by an auxiliary section definition.
417 bool isAppdomainGlobal
=
418 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
&&
419 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE
;
420 bool isOrdinarySection
= getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC
;
421 if (!getNumberOfAuxSymbols())
423 return isAppdomainGlobal
|| isOrdinarySection
;
426 bool isCLRToken() const {
427 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN
;
431 bool isSet() const { return CS16
|| CS32
; }
433 const coff_symbol16
*CS16
= nullptr;
434 const coff_symbol32
*CS32
= nullptr;
437 struct coff_section
{
438 char Name
[COFF::NameSize
];
439 support::ulittle32_t VirtualSize
;
440 support::ulittle32_t VirtualAddress
;
441 support::ulittle32_t SizeOfRawData
;
442 support::ulittle32_t PointerToRawData
;
443 support::ulittle32_t PointerToRelocations
;
444 support::ulittle32_t PointerToLinenumbers
;
445 support::ulittle16_t NumberOfRelocations
;
446 support::ulittle16_t NumberOfLinenumbers
;
447 support::ulittle32_t Characteristics
;
449 // Returns true if the actual number of relocations is stored in
450 // VirtualAddress field of the first relocation table entry.
451 bool hasExtendedRelocations() const {
452 return (Characteristics
& COFF::IMAGE_SCN_LNK_NRELOC_OVFL
) &&
453 NumberOfRelocations
== UINT16_MAX
;
456 uint32_t getAlignment() const {
457 // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
458 // IMAGE_SCN_ALIGN_1BYTES.
459 if (Characteristics
& COFF::IMAGE_SCN_TYPE_NO_PAD
)
462 // Bit [20:24] contains section alignment. 0 means use a default alignment
464 uint32_t Shift
= (Characteristics
>> 20) & 0xF;
466 return 1U << (Shift
- 1);
471 struct coff_relocation
{
472 support::ulittle32_t VirtualAddress
;
473 support::ulittle32_t SymbolTableIndex
;
474 support::ulittle16_t Type
;
477 struct coff_aux_function_definition
{
478 support::ulittle32_t TagIndex
;
479 support::ulittle32_t TotalSize
;
480 support::ulittle32_t PointerToLinenumber
;
481 support::ulittle32_t PointerToNextFunction
;
485 static_assert(sizeof(coff_aux_function_definition
) == 18,
486 "auxiliary entry must be 18 bytes");
488 struct coff_aux_bf_and_ef_symbol
{
490 support::ulittle16_t Linenumber
;
492 support::ulittle32_t PointerToNextFunction
;
496 static_assert(sizeof(coff_aux_bf_and_ef_symbol
) == 18,
497 "auxiliary entry must be 18 bytes");
499 struct coff_aux_weak_external
{
500 support::ulittle32_t TagIndex
;
501 support::ulittle32_t Characteristics
;
505 static_assert(sizeof(coff_aux_weak_external
) == 18,
506 "auxiliary entry must be 18 bytes");
508 struct coff_aux_section_definition
{
509 support::ulittle32_t Length
;
510 support::ulittle16_t NumberOfRelocations
;
511 support::ulittle16_t NumberOfLinenumbers
;
512 support::ulittle32_t CheckSum
;
513 support::ulittle16_t NumberLowPart
;
516 support::ulittle16_t NumberHighPart
;
517 int32_t getNumber(bool IsBigObj
) const {
518 uint32_t Number
= static_cast<uint32_t>(NumberLowPart
);
520 Number
|= static_cast<uint32_t>(NumberHighPart
) << 16;
521 return static_cast<int32_t>(Number
);
525 static_assert(sizeof(coff_aux_section_definition
) == 18,
526 "auxiliary entry must be 18 bytes");
528 struct coff_aux_clr_token
{
531 support::ulittle32_t SymbolTableIndex
;
535 static_assert(sizeof(coff_aux_clr_token
) == 18,
536 "auxiliary entry must be 18 bytes");
538 struct coff_import_header
{
539 support::ulittle16_t Sig1
;
540 support::ulittle16_t Sig2
;
541 support::ulittle16_t Version
;
542 support::ulittle16_t Machine
;
543 support::ulittle32_t TimeDateStamp
;
544 support::ulittle32_t SizeOfData
;
545 support::ulittle16_t OrdinalHint
;
546 support::ulittle16_t TypeInfo
;
548 int getType() const { return TypeInfo
& 0x3; }
549 int getNameType() const { return (TypeInfo
>> 2) & 0x7; }
552 struct coff_import_directory_table_entry
{
553 support::ulittle32_t ImportLookupTableRVA
;
554 support::ulittle32_t TimeDateStamp
;
555 support::ulittle32_t ForwarderChain
;
556 support::ulittle32_t NameRVA
;
557 support::ulittle32_t ImportAddressTableRVA
;
559 bool isNull() const {
560 return ImportLookupTableRVA
== 0 && TimeDateStamp
== 0 &&
561 ForwarderChain
== 0 && NameRVA
== 0 && ImportAddressTableRVA
== 0;
565 template <typename IntTy
>
566 struct coff_tls_directory
{
567 IntTy StartAddressOfRawData
;
568 IntTy EndAddressOfRawData
;
569 IntTy AddressOfIndex
;
570 IntTy AddressOfCallBacks
;
571 support::ulittle32_t SizeOfZeroFill
;
572 support::ulittle32_t Characteristics
;
574 uint32_t getAlignment() const {
575 // Bit [20:24] contains section alignment.
576 uint32_t Shift
= (Characteristics
& 0x00F00000) >> 20;
578 return 1U << (Shift
- 1);
583 using coff_tls_directory32
= coff_tls_directory
<support::little32_t
>;
584 using coff_tls_directory64
= coff_tls_directory
<support::little64_t
>;
586 /// Bits in control flow guard flags as we understand them.
587 enum class coff_guard_flags
: uint32_t {
588 CFInstrumented
= 0x00000100,
589 HasFidTable
= 0x00000400,
590 ProtectDelayLoadIAT
= 0x00001000,
591 DelayLoadIATSection
= 0x00002000, // Delay load in separate section
592 HasLongJmpTable
= 0x00010000,
593 FidTableHasFlags
= 0x10000000, // Indicates that fid tables are 5 bytes
596 enum class frame_type
: uint16_t { Fpo
= 0, Trap
= 1, Tss
= 2, NonFpo
= 3 };
598 struct coff_load_config_code_integrity
{
599 support::ulittle16_t Flags
;
600 support::ulittle16_t Catalog
;
601 support::ulittle32_t CatalogOffset
;
602 support::ulittle32_t Reserved
;
605 /// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
606 struct coff_load_configuration32
{
607 support::ulittle32_t Size
;
608 support::ulittle32_t TimeDateStamp
;
609 support::ulittle16_t MajorVersion
;
610 support::ulittle16_t MinorVersion
;
611 support::ulittle32_t GlobalFlagsClear
;
612 support::ulittle32_t GlobalFlagsSet
;
613 support::ulittle32_t CriticalSectionDefaultTimeout
;
614 support::ulittle32_t DeCommitFreeBlockThreshold
;
615 support::ulittle32_t DeCommitTotalFreeThreshold
;
616 support::ulittle32_t LockPrefixTable
;
617 support::ulittle32_t MaximumAllocationSize
;
618 support::ulittle32_t VirtualMemoryThreshold
;
619 support::ulittle32_t ProcessAffinityMask
;
620 support::ulittle32_t ProcessHeapFlags
;
621 support::ulittle16_t CSDVersion
;
622 support::ulittle16_t DependentLoadFlags
;
623 support::ulittle32_t EditList
;
624 support::ulittle32_t SecurityCookie
;
625 support::ulittle32_t SEHandlerTable
;
626 support::ulittle32_t SEHandlerCount
;
628 // Added in MSVC 2015 for /guard:cf.
629 support::ulittle32_t GuardCFCheckFunction
;
630 support::ulittle32_t GuardCFCheckDispatch
;
631 support::ulittle32_t GuardCFFunctionTable
;
632 support::ulittle32_t GuardCFFunctionCount
;
633 support::ulittle32_t GuardFlags
; // coff_guard_flags
635 // Added in MSVC 2017
636 coff_load_config_code_integrity CodeIntegrity
;
637 support::ulittle32_t GuardAddressTakenIatEntryTable
;
638 support::ulittle32_t GuardAddressTakenIatEntryCount
;
639 support::ulittle32_t GuardLongJumpTargetTable
;
640 support::ulittle32_t GuardLongJumpTargetCount
;
641 support::ulittle32_t DynamicValueRelocTable
;
642 support::ulittle32_t CHPEMetadataPointer
;
643 support::ulittle32_t GuardRFFailureRoutine
;
644 support::ulittle32_t GuardRFFailureRoutineFunctionPointer
;
645 support::ulittle32_t DynamicValueRelocTableOffset
;
646 support::ulittle16_t DynamicValueRelocTableSection
;
647 support::ulittle16_t Reserved2
;
648 support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer
;
649 support::ulittle32_t HotPatchTableOffset
;
652 /// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
653 struct coff_load_configuration64
{
654 support::ulittle32_t Size
;
655 support::ulittle32_t TimeDateStamp
;
656 support::ulittle16_t MajorVersion
;
657 support::ulittle16_t MinorVersion
;
658 support::ulittle32_t GlobalFlagsClear
;
659 support::ulittle32_t GlobalFlagsSet
;
660 support::ulittle32_t CriticalSectionDefaultTimeout
;
661 support::ulittle64_t DeCommitFreeBlockThreshold
;
662 support::ulittle64_t DeCommitTotalFreeThreshold
;
663 support::ulittle64_t LockPrefixTable
;
664 support::ulittle64_t MaximumAllocationSize
;
665 support::ulittle64_t VirtualMemoryThreshold
;
666 support::ulittle64_t ProcessAffinityMask
;
667 support::ulittle32_t ProcessHeapFlags
;
668 support::ulittle16_t CSDVersion
;
669 support::ulittle16_t DependentLoadFlags
;
670 support::ulittle64_t EditList
;
671 support::ulittle64_t SecurityCookie
;
672 support::ulittle64_t SEHandlerTable
;
673 support::ulittle64_t SEHandlerCount
;
675 // Added in MSVC 2015 for /guard:cf.
676 support::ulittle64_t GuardCFCheckFunction
;
677 support::ulittle64_t GuardCFCheckDispatch
;
678 support::ulittle64_t GuardCFFunctionTable
;
679 support::ulittle64_t GuardCFFunctionCount
;
680 support::ulittle32_t GuardFlags
;
682 // Added in MSVC 2017
683 coff_load_config_code_integrity CodeIntegrity
;
684 support::ulittle64_t GuardAddressTakenIatEntryTable
;
685 support::ulittle64_t GuardAddressTakenIatEntryCount
;
686 support::ulittle64_t GuardLongJumpTargetTable
;
687 support::ulittle64_t GuardLongJumpTargetCount
;
688 support::ulittle64_t DynamicValueRelocTable
;
689 support::ulittle64_t CHPEMetadataPointer
;
690 support::ulittle64_t GuardRFFailureRoutine
;
691 support::ulittle64_t GuardRFFailureRoutineFunctionPointer
;
692 support::ulittle32_t DynamicValueRelocTableOffset
;
693 support::ulittle16_t DynamicValueRelocTableSection
;
694 support::ulittle16_t Reserved2
;
695 support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer
;
696 support::ulittle32_t HotPatchTableOffset
;
699 struct coff_runtime_function_x64
{
700 support::ulittle32_t BeginAddress
;
701 support::ulittle32_t EndAddress
;
702 support::ulittle32_t UnwindInformation
;
705 struct coff_base_reloc_block_header
{
706 support::ulittle32_t PageRVA
;
707 support::ulittle32_t BlockSize
;
710 struct coff_base_reloc_block_entry
{
711 support::ulittle16_t Data
;
713 int getType() const { return Data
>> 12; }
714 int getOffset() const { return Data
& ((1 << 12) - 1); }
717 struct coff_resource_dir_entry
{
719 support::ulittle32_t NameOffset
;
720 support::ulittle32_t ID
;
721 uint32_t getNameOffset() const {
722 return maskTrailingOnes
<uint32_t>(31) & NameOffset
;
724 // Even though the PE/COFF spec doesn't mention this, the high bit of a name
726 void setNameOffset(uint32_t Offset
) { NameOffset
= Offset
| (1 << 31); }
729 support::ulittle32_t DataEntryOffset
;
730 support::ulittle32_t SubdirOffset
;
732 bool isSubDir() const { return SubdirOffset
>> 31; }
733 uint32_t value() const {
734 return maskTrailingOnes
<uint32_t>(31) & SubdirOffset
;
740 struct coff_resource_data_entry
{
741 support::ulittle32_t DataRVA
;
742 support::ulittle32_t DataSize
;
743 support::ulittle32_t Codepage
;
744 support::ulittle32_t Reserved
;
747 struct coff_resource_dir_table
{
748 support::ulittle32_t Characteristics
;
749 support::ulittle32_t TimeDateStamp
;
750 support::ulittle16_t MajorVersion
;
751 support::ulittle16_t MinorVersion
;
752 support::ulittle16_t NumberOfNameEntries
;
753 support::ulittle16_t NumberOfIDEntries
;
756 struct debug_h_header
{
757 support::ulittle32_t Magic
;
758 support::ulittle16_t Version
;
759 support::ulittle16_t HashAlgorithm
;
762 class COFFObjectFile
: public ObjectFile
{
764 friend class ImportDirectoryEntryRef
;
765 friend class ExportDirectoryEntryRef
;
766 const coff_file_header
*COFFHeader
;
767 const coff_bigobj_file_header
*COFFBigObjHeader
;
768 const pe32_header
*PE32Header
;
769 const pe32plus_header
*PE32PlusHeader
;
770 const data_directory
*DataDirectory
;
771 const coff_section
*SectionTable
;
772 const coff_symbol16
*SymbolTable16
;
773 const coff_symbol32
*SymbolTable32
;
774 const char *StringTable
;
775 uint32_t StringTableSize
;
776 const coff_import_directory_table_entry
*ImportDirectory
;
777 const delay_import_directory_table_entry
*DelayImportDirectory
;
778 uint32_t NumberOfDelayImportDirectory
;
779 const export_directory_table_entry
*ExportDirectory
;
780 const coff_base_reloc_block_header
*BaseRelocHeader
;
781 const coff_base_reloc_block_header
*BaseRelocEnd
;
782 const debug_directory
*DebugDirectoryBegin
;
783 const debug_directory
*DebugDirectoryEnd
;
784 // Either coff_load_configuration32 or coff_load_configuration64.
785 const void *LoadConfig
= nullptr;
787 std::error_code
getString(uint32_t offset
, StringRef
&Res
) const;
789 template <typename coff_symbol_type
>
790 const coff_symbol_type
*toSymb(DataRefImpl Symb
) const;
791 const coff_section
*toSec(DataRefImpl Sec
) const;
792 const coff_relocation
*toRel(DataRefImpl Rel
) const;
794 std::error_code
initSymbolTablePtr();
795 std::error_code
initImportTablePtr();
796 std::error_code
initDelayImportTablePtr();
797 std::error_code
initExportTablePtr();
798 std::error_code
initBaseRelocPtr();
799 std::error_code
initDebugDirectoryPtr();
800 std::error_code
initLoadConfigPtr();
803 uintptr_t getSymbolTable() const {
805 return reinterpret_cast<uintptr_t>(SymbolTable16
);
807 return reinterpret_cast<uintptr_t>(SymbolTable32
);
811 uint16_t getMachine() const {
813 return COFFHeader
->Machine
;
814 if (COFFBigObjHeader
)
815 return COFFBigObjHeader
->Machine
;
816 llvm_unreachable("no COFF header!");
819 uint16_t getSizeOfOptionalHeader() const {
821 return COFFHeader
->isImportLibrary() ? 0
822 : COFFHeader
->SizeOfOptionalHeader
;
823 // bigobj doesn't have this field.
824 if (COFFBigObjHeader
)
826 llvm_unreachable("no COFF header!");
829 uint16_t getCharacteristics() const {
831 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->Characteristics
;
832 // bigobj doesn't have characteristics to speak of,
833 // editbin will silently lie to you if you attempt to set any.
834 if (COFFBigObjHeader
)
836 llvm_unreachable("no COFF header!");
839 uint32_t getTimeDateStamp() const {
841 return COFFHeader
->TimeDateStamp
;
842 if (COFFBigObjHeader
)
843 return COFFBigObjHeader
->TimeDateStamp
;
844 llvm_unreachable("no COFF header!");
847 uint32_t getNumberOfSections() const {
849 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSections
;
850 if (COFFBigObjHeader
)
851 return COFFBigObjHeader
->NumberOfSections
;
852 llvm_unreachable("no COFF header!");
855 uint32_t getPointerToSymbolTable() const {
857 return COFFHeader
->isImportLibrary() ? 0
858 : COFFHeader
->PointerToSymbolTable
;
859 if (COFFBigObjHeader
)
860 return COFFBigObjHeader
->PointerToSymbolTable
;
861 llvm_unreachable("no COFF header!");
864 uint32_t getRawNumberOfSymbols() const {
866 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSymbols
;
867 if (COFFBigObjHeader
)
868 return COFFBigObjHeader
->NumberOfSymbols
;
869 llvm_unreachable("no COFF header!");
872 uint32_t getNumberOfSymbols() const {
873 if (!SymbolTable16
&& !SymbolTable32
)
875 return getRawNumberOfSymbols();
878 const coff_load_configuration32
*getLoadConfig32() const {
880 return reinterpret_cast<const coff_load_configuration32
*>(LoadConfig
);
883 const coff_load_configuration64
*getLoadConfig64() const {
885 return reinterpret_cast<const coff_load_configuration64
*>(LoadConfig
);
887 StringRef
getRelocationTypeName(uint16_t Type
) const;
890 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
891 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
892 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
893 uint32_t getSymbolAlignment(DataRefImpl Symb
) const override
;
894 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
895 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
896 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
897 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
898 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
899 void moveSectionNext(DataRefImpl
&Sec
) const override
;
900 Expected
<StringRef
> getSectionName(DataRefImpl Sec
) const override
;
901 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
902 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
903 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
904 Expected
<ArrayRef
<uint8_t>>
905 getSectionContents(DataRefImpl Sec
) const override
;
906 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
907 bool isSectionCompressed(DataRefImpl Sec
) const override
;
908 bool isSectionText(DataRefImpl Sec
) const override
;
909 bool isSectionData(DataRefImpl Sec
) const override
;
910 bool isSectionBSS(DataRefImpl Sec
) const override
;
911 bool isSectionVirtual(DataRefImpl Sec
) const override
;
912 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
913 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
915 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
916 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
917 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
918 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
919 void getRelocationTypeName(DataRefImpl Rel
,
920 SmallVectorImpl
<char> &Result
) const override
;
923 COFFObjectFile(MemoryBufferRef Object
, std::error_code
&EC
);
925 basic_symbol_iterator
symbol_begin() const override
;
926 basic_symbol_iterator
symbol_end() const override
;
927 section_iterator
section_begin() const override
;
928 section_iterator
section_end() const override
;
930 const coff_section
*getCOFFSection(const SectionRef
&Section
) const;
931 COFFSymbolRef
getCOFFSymbol(const DataRefImpl
&Ref
) const;
932 COFFSymbolRef
getCOFFSymbol(const SymbolRef
&Symbol
) const;
933 const coff_relocation
*getCOFFRelocation(const RelocationRef
&Reloc
) const;
934 unsigned getSectionID(SectionRef Sec
) const;
935 unsigned getSymbolSectionID(SymbolRef Sym
) const;
937 uint8_t getBytesInAddress() const override
;
938 StringRef
getFileFormatName() const override
;
939 Triple::ArchType
getArch() const override
;
940 Expected
<uint64_t> getStartAddress() const override
;
941 SubtargetFeatures
getFeatures() const override
{ return SubtargetFeatures(); }
943 import_directory_iterator
import_directory_begin() const;
944 import_directory_iterator
import_directory_end() const;
945 delay_import_directory_iterator
delay_import_directory_begin() const;
946 delay_import_directory_iterator
delay_import_directory_end() const;
947 export_directory_iterator
export_directory_begin() const;
948 export_directory_iterator
export_directory_end() const;
949 base_reloc_iterator
base_reloc_begin() const;
950 base_reloc_iterator
base_reloc_end() const;
951 const debug_directory
*debug_directory_begin() const {
952 return DebugDirectoryBegin
;
954 const debug_directory
*debug_directory_end() const {
955 return DebugDirectoryEnd
;
958 iterator_range
<import_directory_iterator
> import_directories() const;
959 iterator_range
<delay_import_directory_iterator
>
960 delay_import_directories() const;
961 iterator_range
<export_directory_iterator
> export_directories() const;
962 iterator_range
<base_reloc_iterator
> base_relocs() const;
963 iterator_range
<const debug_directory
*> debug_directories() const {
964 return make_range(debug_directory_begin(), debug_directory_end());
967 const dos_header
*getDOSHeader() const {
968 if (!PE32Header
&& !PE32PlusHeader
)
970 return reinterpret_cast<const dos_header
*>(base());
973 const coff_file_header
*getCOFFHeader() const { return COFFHeader
; }
974 const coff_bigobj_file_header
*getCOFFBigObjHeader() const {
975 return COFFBigObjHeader
;
977 const pe32_header
*getPE32Header() const { return PE32Header
; }
978 const pe32plus_header
*getPE32PlusHeader() const { return PE32PlusHeader
; }
980 std::error_code
getDataDirectory(uint32_t index
,
981 const data_directory
*&Res
) const;
982 std::error_code
getSection(int32_t index
, const coff_section
*&Res
) const;
983 std::error_code
getSection(StringRef SectionName
,
984 const coff_section
*&Res
) const;
986 template <typename coff_symbol_type
>
987 std::error_code
getSymbol(uint32_t Index
,
988 const coff_symbol_type
*&Res
) const {
989 if (Index
>= getNumberOfSymbols())
990 return object_error::parse_failed
;
992 Res
= reinterpret_cast<coff_symbol_type
*>(getSymbolTable()) + Index
;
993 return std::error_code();
995 Expected
<COFFSymbolRef
> getSymbol(uint32_t index
) const {
997 const coff_symbol16
*Symb
= nullptr;
998 if (std::error_code EC
= getSymbol(index
, Symb
))
999 return errorCodeToError(EC
);
1000 return COFFSymbolRef(Symb
);
1002 if (SymbolTable32
) {
1003 const coff_symbol32
*Symb
= nullptr;
1004 if (std::error_code EC
= getSymbol(index
, Symb
))
1005 return errorCodeToError(EC
);
1006 return COFFSymbolRef(Symb
);
1008 return errorCodeToError(object_error::parse_failed
);
1011 template <typename T
>
1012 std::error_code
getAuxSymbol(uint32_t index
, const T
*&Res
) const {
1013 Expected
<COFFSymbolRef
> S
= getSymbol(index
);
1014 if (Error E
= S
.takeError())
1015 return errorToErrorCode(std::move(E
));
1016 Res
= reinterpret_cast<const T
*>(S
->getRawPtr());
1017 return std::error_code();
1020 std::error_code
getSymbolName(COFFSymbolRef Symbol
, StringRef
&Res
) const;
1021 std::error_code
getSymbolName(const coff_symbol_generic
*Symbol
,
1022 StringRef
&Res
) const;
1024 ArrayRef
<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol
) const;
1026 uint32_t getSymbolIndex(COFFSymbolRef Symbol
) const;
1028 size_t getSymbolTableEntrySize() const {
1030 return sizeof(coff_symbol16
);
1031 if (COFFBigObjHeader
)
1032 return sizeof(coff_symbol32
);
1033 llvm_unreachable("null symbol table pointer!");
1036 ArrayRef
<coff_relocation
> getRelocations(const coff_section
*Sec
) const;
1038 Expected
<StringRef
> getSectionName(const coff_section
*Sec
) const;
1039 uint64_t getSectionSize(const coff_section
*Sec
) const;
1040 Error
getSectionContents(const coff_section
*Sec
,
1041 ArrayRef
<uint8_t> &Res
) const;
1043 uint64_t getImageBase() const;
1044 std::error_code
getVaPtr(uint64_t VA
, uintptr_t &Res
) const;
1045 std::error_code
getRvaPtr(uint32_t Rva
, uintptr_t &Res
) const;
1047 /// Given an RVA base and size, returns a valid array of bytes or an error
1048 /// code if the RVA and size is not contained completely within a valid
1050 std::error_code
getRvaAndSizeAsBytes(uint32_t RVA
, uint32_t Size
,
1051 ArrayRef
<uint8_t> &Contents
) const;
1053 std::error_code
getHintName(uint32_t Rva
, uint16_t &Hint
,
1054 StringRef
&Name
) const;
1056 /// Get PDB information out of a codeview debug directory entry.
1057 std::error_code
getDebugPDBInfo(const debug_directory
*DebugDir
,
1058 const codeview::DebugInfo
*&Info
,
1059 StringRef
&PDBFileName
) const;
1061 /// Get PDB information from an executable. If the information is not present,
1062 /// Info will be set to nullptr and PDBFileName will be empty. An error is
1063 /// returned only on corrupt object files. Convenience accessor that can be
1064 /// used if the debug directory is not already handy.
1065 std::error_code
getDebugPDBInfo(const codeview::DebugInfo
*&Info
,
1066 StringRef
&PDBFileName
) const;
1068 bool isRelocatableObject() const override
;
1069 bool is64() const { return PE32PlusHeader
; }
1071 StringRef
mapDebugSectionName(StringRef Name
) const override
;
1073 static bool classof(const Binary
*v
) { return v
->isCOFF(); }
1076 // The iterator for the import directory table.
1077 class ImportDirectoryEntryRef
{
1079 ImportDirectoryEntryRef() = default;
1080 ImportDirectoryEntryRef(const coff_import_directory_table_entry
*Table
,
1081 uint32_t I
, const COFFObjectFile
*Owner
)
1082 : ImportTable(Table
), Index(I
), OwningObject(Owner
) {}
1084 bool operator==(const ImportDirectoryEntryRef
&Other
) const;
1087 imported_symbol_iterator
imported_symbol_begin() const;
1088 imported_symbol_iterator
imported_symbol_end() const;
1089 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1091 imported_symbol_iterator
lookup_table_begin() const;
1092 imported_symbol_iterator
lookup_table_end() const;
1093 iterator_range
<imported_symbol_iterator
> lookup_table_symbols() const;
1095 std::error_code
getName(StringRef
&Result
) const;
1096 std::error_code
getImportLookupTableRVA(uint32_t &Result
) const;
1097 std::error_code
getImportAddressTableRVA(uint32_t &Result
) const;
1100 getImportTableEntry(const coff_import_directory_table_entry
*&Result
) const;
1103 const coff_import_directory_table_entry
*ImportTable
;
1105 const COFFObjectFile
*OwningObject
= nullptr;
1108 class DelayImportDirectoryEntryRef
{
1110 DelayImportDirectoryEntryRef() = default;
1111 DelayImportDirectoryEntryRef(const delay_import_directory_table_entry
*T
,
1112 uint32_t I
, const COFFObjectFile
*Owner
)
1113 : Table(T
), Index(I
), OwningObject(Owner
) {}
1115 bool operator==(const DelayImportDirectoryEntryRef
&Other
) const;
1118 imported_symbol_iterator
imported_symbol_begin() const;
1119 imported_symbol_iterator
imported_symbol_end() const;
1120 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1122 std::error_code
getName(StringRef
&Result
) const;
1123 std::error_code
getDelayImportTable(
1124 const delay_import_directory_table_entry
*&Result
) const;
1125 std::error_code
getImportAddress(int AddrIndex
, uint64_t &Result
) const;
1128 const delay_import_directory_table_entry
*Table
;
1130 const COFFObjectFile
*OwningObject
= nullptr;
1133 // The iterator for the export directory table entry.
1134 class ExportDirectoryEntryRef
{
1136 ExportDirectoryEntryRef() = default;
1137 ExportDirectoryEntryRef(const export_directory_table_entry
*Table
, uint32_t I
,
1138 const COFFObjectFile
*Owner
)
1139 : ExportTable(Table
), Index(I
), OwningObject(Owner
) {}
1141 bool operator==(const ExportDirectoryEntryRef
&Other
) const;
1144 std::error_code
getDllName(StringRef
&Result
) const;
1145 std::error_code
getOrdinalBase(uint32_t &Result
) const;
1146 std::error_code
getOrdinal(uint32_t &Result
) const;
1147 std::error_code
getExportRVA(uint32_t &Result
) const;
1148 std::error_code
getSymbolName(StringRef
&Result
) const;
1150 std::error_code
isForwarder(bool &Result
) const;
1151 std::error_code
getForwardTo(StringRef
&Result
) const;
1154 const export_directory_table_entry
*ExportTable
;
1156 const COFFObjectFile
*OwningObject
= nullptr;
1159 class ImportedSymbolRef
{
1161 ImportedSymbolRef() = default;
1162 ImportedSymbolRef(const import_lookup_table_entry32
*Entry
, uint32_t I
,
1163 const COFFObjectFile
*Owner
)
1164 : Entry32(Entry
), Entry64(nullptr), Index(I
), OwningObject(Owner
) {}
1165 ImportedSymbolRef(const import_lookup_table_entry64
*Entry
, uint32_t I
,
1166 const COFFObjectFile
*Owner
)
1167 : Entry32(nullptr), Entry64(Entry
), Index(I
), OwningObject(Owner
) {}
1169 bool operator==(const ImportedSymbolRef
&Other
) const;
1172 std::error_code
getSymbolName(StringRef
&Result
) const;
1173 std::error_code
isOrdinal(bool &Result
) const;
1174 std::error_code
getOrdinal(uint16_t &Result
) const;
1175 std::error_code
getHintNameRVA(uint32_t &Result
) const;
1178 const import_lookup_table_entry32
*Entry32
;
1179 const import_lookup_table_entry64
*Entry64
;
1181 const COFFObjectFile
*OwningObject
= nullptr;
1184 class BaseRelocRef
{
1186 BaseRelocRef() = default;
1187 BaseRelocRef(const coff_base_reloc_block_header
*Header
,
1188 const COFFObjectFile
*Owner
)
1189 : Header(Header
), Index(0) {}
1191 bool operator==(const BaseRelocRef
&Other
) const;
1194 std::error_code
getType(uint8_t &Type
) const;
1195 std::error_code
getRVA(uint32_t &Result
) const;
1198 const coff_base_reloc_block_header
*Header
;
1202 class ResourceSectionRef
{
1204 ResourceSectionRef() = default;
1205 explicit ResourceSectionRef(StringRef Ref
) : BBS(Ref
, support::little
) {}
1207 Error
load(const COFFObjectFile
*O
);
1208 Error
load(const COFFObjectFile
*O
, const SectionRef
&S
);
1210 Expected
<ArrayRef
<UTF16
>>
1211 getEntryNameString(const coff_resource_dir_entry
&Entry
);
1212 Expected
<const coff_resource_dir_table
&>
1213 getEntrySubDir(const coff_resource_dir_entry
&Entry
);
1214 Expected
<const coff_resource_data_entry
&>
1215 getEntryData(const coff_resource_dir_entry
&Entry
);
1216 Expected
<const coff_resource_dir_table
&> getBaseTable();
1217 Expected
<const coff_resource_dir_entry
&>
1218 getTableEntry(const coff_resource_dir_table
&Table
, uint32_t Index
);
1220 Expected
<StringRef
> getContents(const coff_resource_data_entry
&Entry
);
1223 BinaryByteStream BBS
;
1226 const COFFObjectFile
*Obj
;
1228 std::vector
<const coff_relocation
*> Relocs
;
1230 Expected
<const coff_resource_dir_table
&> getTableAtOffset(uint32_t Offset
);
1231 Expected
<const coff_resource_dir_entry
&>
1232 getTableEntryAtOffset(uint32_t Offset
);
1233 Expected
<const coff_resource_data_entry
&>
1234 getDataEntryAtOffset(uint32_t Offset
);
1235 Expected
<ArrayRef
<UTF16
>> getDirStringAtOffset(uint32_t Offset
);
1238 // Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
1240 support::ulittle32_t Offset
; // ulOffStart: Offset 1st byte of function code
1241 support::ulittle32_t Size
; // cbProcSize: # bytes in function
1242 support::ulittle32_t NumLocals
; // cdwLocals: # bytes in locals/4
1243 support::ulittle16_t NumParams
; // cdwParams: # bytes in params/4
1244 support::ulittle16_t Attributes
;
1246 // cbProlog: # bytes in prolog
1247 int getPrologSize() const { return Attributes
& 0xF; }
1249 // cbRegs: # regs saved
1250 int getNumSavedRegs() const { return (Attributes
>> 8) & 0x7; }
1252 // fHasSEH: true if seh is func
1253 bool hasSEH() const { return (Attributes
>> 9) & 1; }
1255 // fUseBP: true if EBP has been allocated
1256 bool useBP() const { return (Attributes
>> 10) & 1; }
1258 // cbFrame: frame pointer
1259 frame_type
getFP() const { return static_cast<frame_type
>(Attributes
>> 14); }
1262 } // end namespace object
1264 } // end namespace llvm
1266 #endif // LLVM_OBJECT_COFF_H