1 //===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
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 #ifndef LLVM_OBJECT_COFF_H
15 #define LLVM_OBJECT_COFF_H
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/BinaryFormat/COFF.h"
19 #include "llvm/MC/SubtargetFeature.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Object/CVDebugRecord.h"
22 #include "llvm/Object/Error.h"
23 #include "llvm/Object/ObjectFile.h"
24 #include "llvm/Support/BinaryByteStream.h"
25 #include "llvm/Support/ConvertUTF.h"
26 #include "llvm/Support/Endian.h"
27 #include "llvm/Support/ErrorHandling.h"
31 #include <system_error>
35 template <typename T
> class ArrayRef
;
40 class DelayImportDirectoryEntryRef
;
41 class ExportDirectoryEntryRef
;
42 class ImportDirectoryEntryRef
;
43 class ImportedSymbolRef
;
44 class ResourceSectionRef
;
46 using import_directory_iterator
= content_iterator
<ImportDirectoryEntryRef
>;
47 using delay_import_directory_iterator
=
48 content_iterator
<DelayImportDirectoryEntryRef
>;
49 using export_directory_iterator
= content_iterator
<ExportDirectoryEntryRef
>;
50 using imported_symbol_iterator
= content_iterator
<ImportedSymbolRef
>;
51 using base_reloc_iterator
= content_iterator
<BaseRelocRef
>;
53 /// The DOS compatible header at the front of all PE/COFF executables.
56 support::ulittle16_t UsedBytesInTheLastPage
;
57 support::ulittle16_t FileSizeInPages
;
58 support::ulittle16_t NumberOfRelocationItems
;
59 support::ulittle16_t HeaderSizeInParagraphs
;
60 support::ulittle16_t MinimumExtraParagraphs
;
61 support::ulittle16_t MaximumExtraParagraphs
;
62 support::ulittle16_t InitialRelativeSS
;
63 support::ulittle16_t InitialSP
;
64 support::ulittle16_t Checksum
;
65 support::ulittle16_t InitialIP
;
66 support::ulittle16_t InitialRelativeCS
;
67 support::ulittle16_t AddressOfRelocationTable
;
68 support::ulittle16_t OverlayNumber
;
69 support::ulittle16_t Reserved
[4];
70 support::ulittle16_t OEMid
;
71 support::ulittle16_t OEMinfo
;
72 support::ulittle16_t Reserved2
[10];
73 support::ulittle32_t AddressOfNewExeHeader
;
76 struct coff_file_header
{
77 support::ulittle16_t Machine
;
78 support::ulittle16_t NumberOfSections
;
79 support::ulittle32_t TimeDateStamp
;
80 support::ulittle32_t PointerToSymbolTable
;
81 support::ulittle32_t NumberOfSymbols
;
82 support::ulittle16_t SizeOfOptionalHeader
;
83 support::ulittle16_t Characteristics
;
85 bool isImportLibrary() const { return NumberOfSections
== 0xffff; }
88 struct coff_bigobj_file_header
{
89 support::ulittle16_t Sig1
;
90 support::ulittle16_t Sig2
;
91 support::ulittle16_t Version
;
92 support::ulittle16_t Machine
;
93 support::ulittle32_t TimeDateStamp
;
95 support::ulittle32_t unused1
;
96 support::ulittle32_t unused2
;
97 support::ulittle32_t unused3
;
98 support::ulittle32_t unused4
;
99 support::ulittle32_t NumberOfSections
;
100 support::ulittle32_t PointerToSymbolTable
;
101 support::ulittle32_t NumberOfSymbols
;
104 /// The 32-bit PE header that follows the COFF header.
106 support::ulittle16_t Magic
;
107 uint8_t MajorLinkerVersion
;
108 uint8_t MinorLinkerVersion
;
109 support::ulittle32_t SizeOfCode
;
110 support::ulittle32_t SizeOfInitializedData
;
111 support::ulittle32_t SizeOfUninitializedData
;
112 support::ulittle32_t AddressOfEntryPoint
;
113 support::ulittle32_t BaseOfCode
;
114 support::ulittle32_t BaseOfData
;
115 support::ulittle32_t ImageBase
;
116 support::ulittle32_t SectionAlignment
;
117 support::ulittle32_t FileAlignment
;
118 support::ulittle16_t MajorOperatingSystemVersion
;
119 support::ulittle16_t MinorOperatingSystemVersion
;
120 support::ulittle16_t MajorImageVersion
;
121 support::ulittle16_t MinorImageVersion
;
122 support::ulittle16_t MajorSubsystemVersion
;
123 support::ulittle16_t MinorSubsystemVersion
;
124 support::ulittle32_t Win32VersionValue
;
125 support::ulittle32_t SizeOfImage
;
126 support::ulittle32_t SizeOfHeaders
;
127 support::ulittle32_t CheckSum
;
128 support::ulittle16_t Subsystem
;
129 // FIXME: This should be DllCharacteristics.
130 support::ulittle16_t DLLCharacteristics
;
131 support::ulittle32_t SizeOfStackReserve
;
132 support::ulittle32_t SizeOfStackCommit
;
133 support::ulittle32_t SizeOfHeapReserve
;
134 support::ulittle32_t SizeOfHeapCommit
;
135 support::ulittle32_t LoaderFlags
;
136 // FIXME: This should be NumberOfRvaAndSizes.
137 support::ulittle32_t NumberOfRvaAndSize
;
140 /// The 64-bit PE header that follows the COFF header.
141 struct pe32plus_header
{
142 support::ulittle16_t Magic
;
143 uint8_t MajorLinkerVersion
;
144 uint8_t MinorLinkerVersion
;
145 support::ulittle32_t SizeOfCode
;
146 support::ulittle32_t SizeOfInitializedData
;
147 support::ulittle32_t SizeOfUninitializedData
;
148 support::ulittle32_t AddressOfEntryPoint
;
149 support::ulittle32_t BaseOfCode
;
150 support::ulittle64_t ImageBase
;
151 support::ulittle32_t SectionAlignment
;
152 support::ulittle32_t FileAlignment
;
153 support::ulittle16_t MajorOperatingSystemVersion
;
154 support::ulittle16_t MinorOperatingSystemVersion
;
155 support::ulittle16_t MajorImageVersion
;
156 support::ulittle16_t MinorImageVersion
;
157 support::ulittle16_t MajorSubsystemVersion
;
158 support::ulittle16_t MinorSubsystemVersion
;
159 support::ulittle32_t Win32VersionValue
;
160 support::ulittle32_t SizeOfImage
;
161 support::ulittle32_t SizeOfHeaders
;
162 support::ulittle32_t CheckSum
;
163 support::ulittle16_t Subsystem
;
164 support::ulittle16_t DLLCharacteristics
;
165 support::ulittle64_t SizeOfStackReserve
;
166 support::ulittle64_t SizeOfStackCommit
;
167 support::ulittle64_t SizeOfHeapReserve
;
168 support::ulittle64_t SizeOfHeapCommit
;
169 support::ulittle32_t LoaderFlags
;
170 support::ulittle32_t NumberOfRvaAndSize
;
173 struct data_directory
{
174 support::ulittle32_t RelativeVirtualAddress
;
175 support::ulittle32_t Size
;
178 struct debug_directory
{
179 support::ulittle32_t Characteristics
;
180 support::ulittle32_t TimeDateStamp
;
181 support::ulittle16_t MajorVersion
;
182 support::ulittle16_t MinorVersion
;
183 support::ulittle32_t Type
;
184 support::ulittle32_t SizeOfData
;
185 support::ulittle32_t AddressOfRawData
;
186 support::ulittle32_t PointerToRawData
;
189 template <typename IntTy
>
190 struct import_lookup_table_entry
{
193 bool isOrdinal() const { return Data
< 0; }
195 uint16_t getOrdinal() const {
196 assert(isOrdinal() && "ILT entry is not an ordinal!");
197 return Data
& 0xFFFF;
200 uint32_t getHintNameRVA() const {
201 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
202 return Data
& 0xFFFFFFFF;
206 using import_lookup_table_entry32
=
207 import_lookup_table_entry
<support::little32_t
>;
208 using import_lookup_table_entry64
=
209 import_lookup_table_entry
<support::little64_t
>;
211 struct delay_import_directory_table_entry
{
212 // dumpbin reports this field as "Characteristics" instead of "Attributes".
213 support::ulittle32_t Attributes
;
214 support::ulittle32_t Name
;
215 support::ulittle32_t ModuleHandle
;
216 support::ulittle32_t DelayImportAddressTable
;
217 support::ulittle32_t DelayImportNameTable
;
218 support::ulittle32_t BoundDelayImportTable
;
219 support::ulittle32_t UnloadDelayImportTable
;
220 support::ulittle32_t TimeStamp
;
223 struct export_directory_table_entry
{
224 support::ulittle32_t ExportFlags
;
225 support::ulittle32_t TimeDateStamp
;
226 support::ulittle16_t MajorVersion
;
227 support::ulittle16_t MinorVersion
;
228 support::ulittle32_t NameRVA
;
229 support::ulittle32_t OrdinalBase
;
230 support::ulittle32_t AddressTableEntries
;
231 support::ulittle32_t NumberOfNamePointers
;
232 support::ulittle32_t ExportAddressTableRVA
;
233 support::ulittle32_t NamePointerRVA
;
234 support::ulittle32_t OrdinalTableRVA
;
237 union export_address_table_entry
{
238 support::ulittle32_t ExportRVA
;
239 support::ulittle32_t ForwarderRVA
;
242 using export_name_pointer_table_entry
= support::ulittle32_t
;
243 using export_ordinal_table_entry
= support::ulittle16_t
;
245 struct StringTableOffset
{
246 support::ulittle32_t Zeroes
;
247 support::ulittle32_t Offset
;
250 template <typename SectionNumberType
>
253 char ShortName
[COFF::NameSize
];
254 StringTableOffset Offset
;
257 support::ulittle32_t Value
;
258 SectionNumberType SectionNumber
;
260 support::ulittle16_t Type
;
262 uint8_t StorageClass
;
263 uint8_t NumberOfAuxSymbols
;
266 using coff_symbol16
= coff_symbol
<support::ulittle16_t
>;
267 using coff_symbol32
= coff_symbol
<support::ulittle32_t
>;
269 // Contains only common parts of coff_symbol16 and coff_symbol32.
270 struct coff_symbol_generic
{
272 char ShortName
[COFF::NameSize
];
273 StringTableOffset Offset
;
275 support::ulittle32_t Value
;
278 struct coff_aux_section_definition
;
279 struct coff_aux_weak_external
;
281 class COFFSymbolRef
{
283 COFFSymbolRef() = default;
284 COFFSymbolRef(const coff_symbol16
*CS
) : CS16(CS
) {}
285 COFFSymbolRef(const coff_symbol32
*CS
) : CS32(CS
) {}
287 const void *getRawPtr() const {
288 return CS16
? static_cast<const void *>(CS16
) : CS32
;
291 const coff_symbol_generic
*getGeneric() const {
293 return reinterpret_cast<const coff_symbol_generic
*>(CS16
);
294 return reinterpret_cast<const coff_symbol_generic
*>(CS32
);
297 friend bool operator<(COFFSymbolRef A
, COFFSymbolRef B
) {
298 return A
.getRawPtr() < B
.getRawPtr();
301 bool isBigObj() const {
306 llvm_unreachable("COFFSymbolRef points to nothing!");
309 const char *getShortName() const {
310 return CS16
? CS16
->Name
.ShortName
: CS32
->Name
.ShortName
;
313 const StringTableOffset
&getStringTableOffset() const {
314 assert(isSet() && "COFFSymbolRef points to nothing!");
315 return CS16
? CS16
->Name
.Offset
: CS32
->Name
.Offset
;
318 uint32_t getValue() const { return CS16
? CS16
->Value
: CS32
->Value
; }
320 int32_t getSectionNumber() const {
321 assert(isSet() && "COFFSymbolRef points to nothing!");
323 // Reserved sections are returned as negative numbers.
324 if (CS16
->SectionNumber
<= COFF::MaxNumberOfSections16
)
325 return CS16
->SectionNumber
;
326 return static_cast<int16_t>(CS16
->SectionNumber
);
328 return static_cast<int32_t>(CS32
->SectionNumber
);
331 uint16_t getType() const {
332 assert(isSet() && "COFFSymbolRef points to nothing!");
333 return CS16
? CS16
->Type
: CS32
->Type
;
336 uint8_t getStorageClass() const {
337 assert(isSet() && "COFFSymbolRef points to nothing!");
338 return CS16
? CS16
->StorageClass
: CS32
->StorageClass
;
341 uint8_t getNumberOfAuxSymbols() const {
342 assert(isSet() && "COFFSymbolRef points to nothing!");
343 return CS16
? CS16
->NumberOfAuxSymbols
: CS32
->NumberOfAuxSymbols
;
346 uint8_t getBaseType() const { return getType() & 0x0F; }
348 uint8_t getComplexType() const {
349 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT
;
352 template <typename T
> const T
*getAux() const {
353 return CS16
? reinterpret_cast<const T
*>(CS16
+ 1)
354 : reinterpret_cast<const T
*>(CS32
+ 1);
357 const coff_aux_section_definition
*getSectionDefinition() const {
358 if (!getNumberOfAuxSymbols() ||
359 getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC
)
361 return getAux
<coff_aux_section_definition
>();
364 const coff_aux_weak_external
*getWeakExternal() const {
365 if (!getNumberOfAuxSymbols() ||
366 getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
)
368 return getAux
<coff_aux_weak_external
>();
371 bool isAbsolute() const {
372 return getSectionNumber() == -1;
375 bool isExternal() const {
376 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
;
379 bool isCommon() const {
380 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
384 bool isUndefined() const {
385 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
389 bool isWeakExternal() const {
390 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
393 bool isFunctionDefinition() const {
394 return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL
&&
395 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION
&&
396 !COFF::isReservedSectionNumber(getSectionNumber());
399 bool isFunctionLineInfo() const {
400 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION
;
403 bool isAnyUndefined() const {
404 return isUndefined() || isWeakExternal();
407 bool isFileRecord() const {
408 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE
;
411 bool isSection() const {
412 return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION
;
415 bool isSectionDefinition() const {
416 // C++/CLI creates external ABS symbols for non-const appdomain globals.
417 // These are also followed by an auxiliary section definition.
418 bool isAppdomainGlobal
=
419 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
&&
420 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE
;
421 bool isOrdinarySection
= getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC
;
422 if (!getNumberOfAuxSymbols())
424 return isAppdomainGlobal
|| isOrdinarySection
;
427 bool isCLRToken() const {
428 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN
;
432 bool isSet() const { return CS16
|| CS32
; }
434 const coff_symbol16
*CS16
= nullptr;
435 const coff_symbol32
*CS32
= nullptr;
438 struct coff_section
{
439 char Name
[COFF::NameSize
];
440 support::ulittle32_t VirtualSize
;
441 support::ulittle32_t VirtualAddress
;
442 support::ulittle32_t SizeOfRawData
;
443 support::ulittle32_t PointerToRawData
;
444 support::ulittle32_t PointerToRelocations
;
445 support::ulittle32_t PointerToLinenumbers
;
446 support::ulittle16_t NumberOfRelocations
;
447 support::ulittle16_t NumberOfLinenumbers
;
448 support::ulittle32_t Characteristics
;
450 // Returns true if the actual number of relocations is stored in
451 // VirtualAddress field of the first relocation table entry.
452 bool hasExtendedRelocations() const {
453 return (Characteristics
& COFF::IMAGE_SCN_LNK_NRELOC_OVFL
) &&
454 NumberOfRelocations
== UINT16_MAX
;
457 uint32_t getAlignment() const {
458 // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
459 // IMAGE_SCN_ALIGN_1BYTES.
460 if (Characteristics
& COFF::IMAGE_SCN_TYPE_NO_PAD
)
463 // Bit [20:24] contains section alignment. 0 means use a default alignment
465 uint32_t Shift
= (Characteristics
>> 20) & 0xF;
467 return 1U << (Shift
- 1);
472 struct coff_relocation
{
473 support::ulittle32_t VirtualAddress
;
474 support::ulittle32_t SymbolTableIndex
;
475 support::ulittle16_t Type
;
478 struct coff_aux_function_definition
{
479 support::ulittle32_t TagIndex
;
480 support::ulittle32_t TotalSize
;
481 support::ulittle32_t PointerToLinenumber
;
482 support::ulittle32_t PointerToNextFunction
;
486 static_assert(sizeof(coff_aux_function_definition
) == 18,
487 "auxiliary entry must be 18 bytes");
489 struct coff_aux_bf_and_ef_symbol
{
491 support::ulittle16_t Linenumber
;
493 support::ulittle32_t PointerToNextFunction
;
497 static_assert(sizeof(coff_aux_bf_and_ef_symbol
) == 18,
498 "auxiliary entry must be 18 bytes");
500 struct coff_aux_weak_external
{
501 support::ulittle32_t TagIndex
;
502 support::ulittle32_t Characteristics
;
506 static_assert(sizeof(coff_aux_weak_external
) == 18,
507 "auxiliary entry must be 18 bytes");
509 struct coff_aux_section_definition
{
510 support::ulittle32_t Length
;
511 support::ulittle16_t NumberOfRelocations
;
512 support::ulittle16_t NumberOfLinenumbers
;
513 support::ulittle32_t CheckSum
;
514 support::ulittle16_t NumberLowPart
;
517 support::ulittle16_t NumberHighPart
;
518 int32_t getNumber(bool IsBigObj
) const {
519 uint32_t Number
= static_cast<uint32_t>(NumberLowPart
);
521 Number
|= static_cast<uint32_t>(NumberHighPart
) << 16;
522 return static_cast<int32_t>(Number
);
526 static_assert(sizeof(coff_aux_section_definition
) == 18,
527 "auxiliary entry must be 18 bytes");
529 struct coff_aux_clr_token
{
532 support::ulittle32_t SymbolTableIndex
;
536 static_assert(sizeof(coff_aux_clr_token
) == 18,
537 "auxiliary entry must be 18 bytes");
539 struct coff_import_header
{
540 support::ulittle16_t Sig1
;
541 support::ulittle16_t Sig2
;
542 support::ulittle16_t Version
;
543 support::ulittle16_t Machine
;
544 support::ulittle32_t TimeDateStamp
;
545 support::ulittle32_t SizeOfData
;
546 support::ulittle16_t OrdinalHint
;
547 support::ulittle16_t TypeInfo
;
549 int getType() const { return TypeInfo
& 0x3; }
550 int getNameType() const { return (TypeInfo
>> 2) & 0x7; }
553 struct coff_import_directory_table_entry
{
554 support::ulittle32_t ImportLookupTableRVA
;
555 support::ulittle32_t TimeDateStamp
;
556 support::ulittle32_t ForwarderChain
;
557 support::ulittle32_t NameRVA
;
558 support::ulittle32_t ImportAddressTableRVA
;
560 bool isNull() const {
561 return ImportLookupTableRVA
== 0 && TimeDateStamp
== 0 &&
562 ForwarderChain
== 0 && NameRVA
== 0 && ImportAddressTableRVA
== 0;
566 template <typename IntTy
>
567 struct coff_tls_directory
{
568 IntTy StartAddressOfRawData
;
569 IntTy EndAddressOfRawData
;
570 IntTy AddressOfIndex
;
571 IntTy AddressOfCallBacks
;
572 support::ulittle32_t SizeOfZeroFill
;
573 support::ulittle32_t Characteristics
;
575 uint32_t getAlignment() const {
576 // Bit [20:24] contains section alignment.
577 uint32_t Shift
= (Characteristics
& 0x00F00000) >> 20;
579 return 1U << (Shift
- 1);
584 using coff_tls_directory32
= coff_tls_directory
<support::little32_t
>;
585 using coff_tls_directory64
= coff_tls_directory
<support::little64_t
>;
587 /// Bits in control flow guard flags as we understand them.
588 enum class coff_guard_flags
: uint32_t {
589 CFInstrumented
= 0x00000100,
590 HasFidTable
= 0x00000400,
591 ProtectDelayLoadIAT
= 0x00001000,
592 DelayLoadIATSection
= 0x00002000, // Delay load in separate section
593 HasLongJmpTable
= 0x00010000,
594 FidTableHasFlags
= 0x10000000, // Indicates that fid tables are 5 bytes
597 enum class frame_type
: uint16_t { Fpo
= 0, Trap
= 1, Tss
= 2, NonFpo
= 3 };
599 struct coff_load_config_code_integrity
{
600 support::ulittle16_t Flags
;
601 support::ulittle16_t Catalog
;
602 support::ulittle32_t CatalogOffset
;
603 support::ulittle32_t Reserved
;
606 /// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
607 struct coff_load_configuration32
{
608 support::ulittle32_t Size
;
609 support::ulittle32_t TimeDateStamp
;
610 support::ulittle16_t MajorVersion
;
611 support::ulittle16_t MinorVersion
;
612 support::ulittle32_t GlobalFlagsClear
;
613 support::ulittle32_t GlobalFlagsSet
;
614 support::ulittle32_t CriticalSectionDefaultTimeout
;
615 support::ulittle32_t DeCommitFreeBlockThreshold
;
616 support::ulittle32_t DeCommitTotalFreeThreshold
;
617 support::ulittle32_t LockPrefixTable
;
618 support::ulittle32_t MaximumAllocationSize
;
619 support::ulittle32_t VirtualMemoryThreshold
;
620 support::ulittle32_t ProcessAffinityMask
;
621 support::ulittle32_t ProcessHeapFlags
;
622 support::ulittle16_t CSDVersion
;
623 support::ulittle16_t DependentLoadFlags
;
624 support::ulittle32_t EditList
;
625 support::ulittle32_t SecurityCookie
;
626 support::ulittle32_t SEHandlerTable
;
627 support::ulittle32_t SEHandlerCount
;
629 // Added in MSVC 2015 for /guard:cf.
630 support::ulittle32_t GuardCFCheckFunction
;
631 support::ulittle32_t GuardCFCheckDispatch
;
632 support::ulittle32_t GuardCFFunctionTable
;
633 support::ulittle32_t GuardCFFunctionCount
;
634 support::ulittle32_t GuardFlags
; // coff_guard_flags
636 // Added in MSVC 2017
637 coff_load_config_code_integrity CodeIntegrity
;
638 support::ulittle32_t GuardAddressTakenIatEntryTable
;
639 support::ulittle32_t GuardAddressTakenIatEntryCount
;
640 support::ulittle32_t GuardLongJumpTargetTable
;
641 support::ulittle32_t GuardLongJumpTargetCount
;
642 support::ulittle32_t DynamicValueRelocTable
;
643 support::ulittle32_t CHPEMetadataPointer
;
644 support::ulittle32_t GuardRFFailureRoutine
;
645 support::ulittle32_t GuardRFFailureRoutineFunctionPointer
;
646 support::ulittle32_t DynamicValueRelocTableOffset
;
647 support::ulittle16_t DynamicValueRelocTableSection
;
648 support::ulittle16_t Reserved2
;
649 support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer
;
650 support::ulittle32_t HotPatchTableOffset
;
653 /// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
654 struct coff_load_configuration64
{
655 support::ulittle32_t Size
;
656 support::ulittle32_t TimeDateStamp
;
657 support::ulittle16_t MajorVersion
;
658 support::ulittle16_t MinorVersion
;
659 support::ulittle32_t GlobalFlagsClear
;
660 support::ulittle32_t GlobalFlagsSet
;
661 support::ulittle32_t CriticalSectionDefaultTimeout
;
662 support::ulittle64_t DeCommitFreeBlockThreshold
;
663 support::ulittle64_t DeCommitTotalFreeThreshold
;
664 support::ulittle64_t LockPrefixTable
;
665 support::ulittle64_t MaximumAllocationSize
;
666 support::ulittle64_t VirtualMemoryThreshold
;
667 support::ulittle64_t ProcessAffinityMask
;
668 support::ulittle32_t ProcessHeapFlags
;
669 support::ulittle16_t CSDVersion
;
670 support::ulittle16_t DependentLoadFlags
;
671 support::ulittle64_t EditList
;
672 support::ulittle64_t SecurityCookie
;
673 support::ulittle64_t SEHandlerTable
;
674 support::ulittle64_t SEHandlerCount
;
676 // Added in MSVC 2015 for /guard:cf.
677 support::ulittle64_t GuardCFCheckFunction
;
678 support::ulittle64_t GuardCFCheckDispatch
;
679 support::ulittle64_t GuardCFFunctionTable
;
680 support::ulittle64_t GuardCFFunctionCount
;
681 support::ulittle32_t GuardFlags
;
683 // Added in MSVC 2017
684 coff_load_config_code_integrity CodeIntegrity
;
685 support::ulittle64_t GuardAddressTakenIatEntryTable
;
686 support::ulittle64_t GuardAddressTakenIatEntryCount
;
687 support::ulittle64_t GuardLongJumpTargetTable
;
688 support::ulittle64_t GuardLongJumpTargetCount
;
689 support::ulittle64_t DynamicValueRelocTable
;
690 support::ulittle64_t CHPEMetadataPointer
;
691 support::ulittle64_t GuardRFFailureRoutine
;
692 support::ulittle64_t GuardRFFailureRoutineFunctionPointer
;
693 support::ulittle32_t DynamicValueRelocTableOffset
;
694 support::ulittle16_t DynamicValueRelocTableSection
;
695 support::ulittle16_t Reserved2
;
696 support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer
;
697 support::ulittle32_t HotPatchTableOffset
;
700 struct coff_runtime_function_x64
{
701 support::ulittle32_t BeginAddress
;
702 support::ulittle32_t EndAddress
;
703 support::ulittle32_t UnwindInformation
;
706 struct coff_base_reloc_block_header
{
707 support::ulittle32_t PageRVA
;
708 support::ulittle32_t BlockSize
;
711 struct coff_base_reloc_block_entry
{
712 support::ulittle16_t Data
;
714 int getType() const { return Data
>> 12; }
715 int getOffset() const { return Data
& ((1 << 12) - 1); }
718 struct coff_resource_dir_entry
{
720 support::ulittle32_t NameOffset
;
721 support::ulittle32_t ID
;
722 uint32_t getNameOffset() const {
723 return maskTrailingOnes
<uint32_t>(31) & NameOffset
;
725 // Even though the PE/COFF spec doesn't mention this, the high bit of a name
727 void setNameOffset(uint32_t Offset
) { NameOffset
= Offset
| (1 << 31); }
730 support::ulittle32_t DataEntryOffset
;
731 support::ulittle32_t SubdirOffset
;
733 bool isSubDir() const { return SubdirOffset
>> 31; }
734 uint32_t value() const {
735 return maskTrailingOnes
<uint32_t>(31) & SubdirOffset
;
741 struct coff_resource_data_entry
{
742 support::ulittle32_t DataRVA
;
743 support::ulittle32_t DataSize
;
744 support::ulittle32_t Codepage
;
745 support::ulittle32_t Reserved
;
748 struct coff_resource_dir_table
{
749 support::ulittle32_t Characteristics
;
750 support::ulittle32_t TimeDateStamp
;
751 support::ulittle16_t MajorVersion
;
752 support::ulittle16_t MinorVersion
;
753 support::ulittle16_t NumberOfNameEntries
;
754 support::ulittle16_t NumberOfIDEntries
;
757 struct debug_h_header
{
758 support::ulittle32_t Magic
;
759 support::ulittle16_t Version
;
760 support::ulittle16_t HashAlgorithm
;
763 class COFFObjectFile
: public ObjectFile
{
765 friend class ImportDirectoryEntryRef
;
766 friend class ExportDirectoryEntryRef
;
767 const coff_file_header
*COFFHeader
;
768 const coff_bigobj_file_header
*COFFBigObjHeader
;
769 const pe32_header
*PE32Header
;
770 const pe32plus_header
*PE32PlusHeader
;
771 const data_directory
*DataDirectory
;
772 const coff_section
*SectionTable
;
773 const coff_symbol16
*SymbolTable16
;
774 const coff_symbol32
*SymbolTable32
;
775 const char *StringTable
;
776 uint32_t StringTableSize
;
777 const coff_import_directory_table_entry
*ImportDirectory
;
778 const delay_import_directory_table_entry
*DelayImportDirectory
;
779 uint32_t NumberOfDelayImportDirectory
;
780 const export_directory_table_entry
*ExportDirectory
;
781 const coff_base_reloc_block_header
*BaseRelocHeader
;
782 const coff_base_reloc_block_header
*BaseRelocEnd
;
783 const debug_directory
*DebugDirectoryBegin
;
784 const debug_directory
*DebugDirectoryEnd
;
785 // Either coff_load_configuration32 or coff_load_configuration64.
786 const void *LoadConfig
= nullptr;
788 std::error_code
getString(uint32_t offset
, StringRef
&Res
) const;
790 template <typename coff_symbol_type
>
791 const coff_symbol_type
*toSymb(DataRefImpl Symb
) const;
792 const coff_section
*toSec(DataRefImpl Sec
) const;
793 const coff_relocation
*toRel(DataRefImpl Rel
) const;
795 std::error_code
initSymbolTablePtr();
796 std::error_code
initImportTablePtr();
797 std::error_code
initDelayImportTablePtr();
798 std::error_code
initExportTablePtr();
799 std::error_code
initBaseRelocPtr();
800 std::error_code
initDebugDirectoryPtr();
801 std::error_code
initLoadConfigPtr();
804 uintptr_t getSymbolTable() const {
806 return reinterpret_cast<uintptr_t>(SymbolTable16
);
808 return reinterpret_cast<uintptr_t>(SymbolTable32
);
812 uint16_t getMachine() const {
814 return COFFHeader
->Machine
;
815 if (COFFBigObjHeader
)
816 return COFFBigObjHeader
->Machine
;
817 llvm_unreachable("no COFF header!");
820 uint16_t getSizeOfOptionalHeader() const {
822 return COFFHeader
->isImportLibrary() ? 0
823 : COFFHeader
->SizeOfOptionalHeader
;
824 // bigobj doesn't have this field.
825 if (COFFBigObjHeader
)
827 llvm_unreachable("no COFF header!");
830 uint16_t getCharacteristics() const {
832 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->Characteristics
;
833 // bigobj doesn't have characteristics to speak of,
834 // editbin will silently lie to you if you attempt to set any.
835 if (COFFBigObjHeader
)
837 llvm_unreachable("no COFF header!");
840 uint32_t getTimeDateStamp() const {
842 return COFFHeader
->TimeDateStamp
;
843 if (COFFBigObjHeader
)
844 return COFFBigObjHeader
->TimeDateStamp
;
845 llvm_unreachable("no COFF header!");
848 uint32_t getNumberOfSections() const {
850 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSections
;
851 if (COFFBigObjHeader
)
852 return COFFBigObjHeader
->NumberOfSections
;
853 llvm_unreachable("no COFF header!");
856 uint32_t getPointerToSymbolTable() const {
858 return COFFHeader
->isImportLibrary() ? 0
859 : COFFHeader
->PointerToSymbolTable
;
860 if (COFFBigObjHeader
)
861 return COFFBigObjHeader
->PointerToSymbolTable
;
862 llvm_unreachable("no COFF header!");
865 uint32_t getRawNumberOfSymbols() const {
867 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSymbols
;
868 if (COFFBigObjHeader
)
869 return COFFBigObjHeader
->NumberOfSymbols
;
870 llvm_unreachable("no COFF header!");
873 uint32_t getNumberOfSymbols() const {
874 if (!SymbolTable16
&& !SymbolTable32
)
876 return getRawNumberOfSymbols();
879 const coff_load_configuration32
*getLoadConfig32() const {
881 return reinterpret_cast<const coff_load_configuration32
*>(LoadConfig
);
884 const coff_load_configuration64
*getLoadConfig64() const {
886 return reinterpret_cast<const coff_load_configuration64
*>(LoadConfig
);
888 StringRef
getRelocationTypeName(uint16_t Type
) const;
891 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
892 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
893 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
894 uint32_t getSymbolAlignment(DataRefImpl Symb
) const override
;
895 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
896 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
897 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
898 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
899 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
900 void moveSectionNext(DataRefImpl
&Sec
) const override
;
901 std::error_code
getSectionName(DataRefImpl Sec
,
902 StringRef
&Res
) const override
;
903 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
904 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
905 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
906 std::error_code
getSectionContents(DataRefImpl Sec
,
907 StringRef
&Res
) const override
;
908 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
909 bool isSectionCompressed(DataRefImpl Sec
) const override
;
910 bool isSectionText(DataRefImpl Sec
) const override
;
911 bool isSectionData(DataRefImpl Sec
) const override
;
912 bool isSectionBSS(DataRefImpl Sec
) const override
;
913 bool isSectionVirtual(DataRefImpl Sec
) const override
;
914 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
915 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
917 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
918 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
919 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
920 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
921 void getRelocationTypeName(DataRefImpl Rel
,
922 SmallVectorImpl
<char> &Result
) const override
;
925 COFFObjectFile(MemoryBufferRef Object
, std::error_code
&EC
);
927 basic_symbol_iterator
symbol_begin() const override
;
928 basic_symbol_iterator
symbol_end() const override
;
929 section_iterator
section_begin() const override
;
930 section_iterator
section_end() const override
;
932 const coff_section
*getCOFFSection(const SectionRef
&Section
) const;
933 COFFSymbolRef
getCOFFSymbol(const DataRefImpl
&Ref
) const;
934 COFFSymbolRef
getCOFFSymbol(const SymbolRef
&Symbol
) const;
935 const coff_relocation
*getCOFFRelocation(const RelocationRef
&Reloc
) const;
936 unsigned getSectionID(SectionRef Sec
) const;
937 unsigned getSymbolSectionID(SymbolRef Sym
) const;
939 uint8_t getBytesInAddress() const override
;
940 StringRef
getFileFormatName() const override
;
941 Triple::ArchType
getArch() const override
;
942 Expected
<uint64_t> getStartAddress() const override
;
943 SubtargetFeatures
getFeatures() const override
{ return SubtargetFeatures(); }
945 import_directory_iterator
import_directory_begin() const;
946 import_directory_iterator
import_directory_end() const;
947 delay_import_directory_iterator
delay_import_directory_begin() const;
948 delay_import_directory_iterator
delay_import_directory_end() const;
949 export_directory_iterator
export_directory_begin() const;
950 export_directory_iterator
export_directory_end() const;
951 base_reloc_iterator
base_reloc_begin() const;
952 base_reloc_iterator
base_reloc_end() const;
953 const debug_directory
*debug_directory_begin() const {
954 return DebugDirectoryBegin
;
956 const debug_directory
*debug_directory_end() const {
957 return DebugDirectoryEnd
;
960 iterator_range
<import_directory_iterator
> import_directories() const;
961 iterator_range
<delay_import_directory_iterator
>
962 delay_import_directories() const;
963 iterator_range
<export_directory_iterator
> export_directories() const;
964 iterator_range
<base_reloc_iterator
> base_relocs() const;
965 iterator_range
<const debug_directory
*> debug_directories() const {
966 return make_range(debug_directory_begin(), debug_directory_end());
969 const dos_header
*getDOSHeader() const {
970 if (!PE32Header
&& !PE32PlusHeader
)
972 return reinterpret_cast<const dos_header
*>(base());
974 std::error_code
getPE32Header(const pe32_header
*&Res
) const;
975 std::error_code
getPE32PlusHeader(const pe32plus_header
*&Res
) const;
976 std::error_code
getDataDirectory(uint32_t index
,
977 const data_directory
*&Res
) const;
978 std::error_code
getSection(int32_t index
, const coff_section
*&Res
) const;
979 std::error_code
getSection(StringRef SectionName
,
980 const coff_section
*&Res
) const;
982 template <typename coff_symbol_type
>
983 std::error_code
getSymbol(uint32_t Index
,
984 const coff_symbol_type
*&Res
) const {
985 if (Index
>= getNumberOfSymbols())
986 return object_error::parse_failed
;
988 Res
= reinterpret_cast<coff_symbol_type
*>(getSymbolTable()) + Index
;
989 return std::error_code();
991 Expected
<COFFSymbolRef
> getSymbol(uint32_t index
) const {
993 const coff_symbol16
*Symb
= nullptr;
994 if (std::error_code EC
= getSymbol(index
, Symb
))
995 return errorCodeToError(EC
);
996 return COFFSymbolRef(Symb
);
999 const coff_symbol32
*Symb
= nullptr;
1000 if (std::error_code EC
= getSymbol(index
, Symb
))
1001 return errorCodeToError(EC
);
1002 return COFFSymbolRef(Symb
);
1004 return errorCodeToError(object_error::parse_failed
);
1007 template <typename T
>
1008 std::error_code
getAuxSymbol(uint32_t index
, const T
*&Res
) const {
1009 Expected
<COFFSymbolRef
> S
= getSymbol(index
);
1010 if (Error E
= S
.takeError())
1011 return errorToErrorCode(std::move(E
));
1012 Res
= reinterpret_cast<const T
*>(S
->getRawPtr());
1013 return std::error_code();
1016 std::error_code
getSymbolName(COFFSymbolRef Symbol
, StringRef
&Res
) const;
1017 std::error_code
getSymbolName(const coff_symbol_generic
*Symbol
,
1018 StringRef
&Res
) const;
1020 ArrayRef
<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol
) const;
1022 size_t getSymbolTableEntrySize() const {
1024 return sizeof(coff_symbol16
);
1025 if (COFFBigObjHeader
)
1026 return sizeof(coff_symbol32
);
1027 llvm_unreachable("null symbol table pointer!");
1030 ArrayRef
<coff_relocation
> getRelocations(const coff_section
*Sec
) const;
1032 std::error_code
getSectionName(const coff_section
*Sec
, StringRef
&Res
) const;
1033 uint64_t getSectionSize(const coff_section
*Sec
) const;
1034 std::error_code
getSectionContents(const coff_section
*Sec
,
1035 ArrayRef
<uint8_t> &Res
) const;
1037 uint64_t getImageBase() const;
1038 std::error_code
getVaPtr(uint64_t VA
, uintptr_t &Res
) const;
1039 std::error_code
getRvaPtr(uint32_t Rva
, uintptr_t &Res
) const;
1041 /// Given an RVA base and size, returns a valid array of bytes or an error
1042 /// code if the RVA and size is not contained completely within a valid
1044 std::error_code
getRvaAndSizeAsBytes(uint32_t RVA
, uint32_t Size
,
1045 ArrayRef
<uint8_t> &Contents
) const;
1047 std::error_code
getHintName(uint32_t Rva
, uint16_t &Hint
,
1048 StringRef
&Name
) const;
1050 /// Get PDB information out of a codeview debug directory entry.
1051 std::error_code
getDebugPDBInfo(const debug_directory
*DebugDir
,
1052 const codeview::DebugInfo
*&Info
,
1053 StringRef
&PDBFileName
) const;
1055 /// Get PDB information from an executable. If the information is not present,
1056 /// Info will be set to nullptr and PDBFileName will be empty. An error is
1057 /// returned only on corrupt object files. Convenience accessor that can be
1058 /// used if the debug directory is not already handy.
1059 std::error_code
getDebugPDBInfo(const codeview::DebugInfo
*&Info
,
1060 StringRef
&PDBFileName
) const;
1062 bool isRelocatableObject() const override
;
1063 bool is64() const { return PE32PlusHeader
; }
1065 StringRef
mapDebugSectionName(StringRef Name
) const override
;
1067 static bool classof(const Binary
*v
) { return v
->isCOFF(); }
1070 // The iterator for the import directory table.
1071 class ImportDirectoryEntryRef
{
1073 ImportDirectoryEntryRef() = default;
1074 ImportDirectoryEntryRef(const coff_import_directory_table_entry
*Table
,
1075 uint32_t I
, const COFFObjectFile
*Owner
)
1076 : ImportTable(Table
), Index(I
), OwningObject(Owner
) {}
1078 bool operator==(const ImportDirectoryEntryRef
&Other
) const;
1081 imported_symbol_iterator
imported_symbol_begin() const;
1082 imported_symbol_iterator
imported_symbol_end() const;
1083 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1085 imported_symbol_iterator
lookup_table_begin() const;
1086 imported_symbol_iterator
lookup_table_end() const;
1087 iterator_range
<imported_symbol_iterator
> lookup_table_symbols() const;
1089 std::error_code
getName(StringRef
&Result
) const;
1090 std::error_code
getImportLookupTableRVA(uint32_t &Result
) const;
1091 std::error_code
getImportAddressTableRVA(uint32_t &Result
) const;
1094 getImportTableEntry(const coff_import_directory_table_entry
*&Result
) const;
1097 const coff_import_directory_table_entry
*ImportTable
;
1099 const COFFObjectFile
*OwningObject
= nullptr;
1102 class DelayImportDirectoryEntryRef
{
1104 DelayImportDirectoryEntryRef() = default;
1105 DelayImportDirectoryEntryRef(const delay_import_directory_table_entry
*T
,
1106 uint32_t I
, const COFFObjectFile
*Owner
)
1107 : Table(T
), Index(I
), OwningObject(Owner
) {}
1109 bool operator==(const DelayImportDirectoryEntryRef
&Other
) const;
1112 imported_symbol_iterator
imported_symbol_begin() const;
1113 imported_symbol_iterator
imported_symbol_end() const;
1114 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1116 std::error_code
getName(StringRef
&Result
) const;
1117 std::error_code
getDelayImportTable(
1118 const delay_import_directory_table_entry
*&Result
) const;
1119 std::error_code
getImportAddress(int AddrIndex
, uint64_t &Result
) const;
1122 const delay_import_directory_table_entry
*Table
;
1124 const COFFObjectFile
*OwningObject
= nullptr;
1127 // The iterator for the export directory table entry.
1128 class ExportDirectoryEntryRef
{
1130 ExportDirectoryEntryRef() = default;
1131 ExportDirectoryEntryRef(const export_directory_table_entry
*Table
, uint32_t I
,
1132 const COFFObjectFile
*Owner
)
1133 : ExportTable(Table
), Index(I
), OwningObject(Owner
) {}
1135 bool operator==(const ExportDirectoryEntryRef
&Other
) const;
1138 std::error_code
getDllName(StringRef
&Result
) const;
1139 std::error_code
getOrdinalBase(uint32_t &Result
) const;
1140 std::error_code
getOrdinal(uint32_t &Result
) const;
1141 std::error_code
getExportRVA(uint32_t &Result
) const;
1142 std::error_code
getSymbolName(StringRef
&Result
) const;
1144 std::error_code
isForwarder(bool &Result
) const;
1145 std::error_code
getForwardTo(StringRef
&Result
) const;
1148 const export_directory_table_entry
*ExportTable
;
1150 const COFFObjectFile
*OwningObject
= nullptr;
1153 class ImportedSymbolRef
{
1155 ImportedSymbolRef() = default;
1156 ImportedSymbolRef(const import_lookup_table_entry32
*Entry
, uint32_t I
,
1157 const COFFObjectFile
*Owner
)
1158 : Entry32(Entry
), Entry64(nullptr), Index(I
), OwningObject(Owner
) {}
1159 ImportedSymbolRef(const import_lookup_table_entry64
*Entry
, uint32_t I
,
1160 const COFFObjectFile
*Owner
)
1161 : Entry32(nullptr), Entry64(Entry
), Index(I
), OwningObject(Owner
) {}
1163 bool operator==(const ImportedSymbolRef
&Other
) const;
1166 std::error_code
getSymbolName(StringRef
&Result
) const;
1167 std::error_code
isOrdinal(bool &Result
) const;
1168 std::error_code
getOrdinal(uint16_t &Result
) const;
1169 std::error_code
getHintNameRVA(uint32_t &Result
) const;
1172 const import_lookup_table_entry32
*Entry32
;
1173 const import_lookup_table_entry64
*Entry64
;
1175 const COFFObjectFile
*OwningObject
= nullptr;
1178 class BaseRelocRef
{
1180 BaseRelocRef() = default;
1181 BaseRelocRef(const coff_base_reloc_block_header
*Header
,
1182 const COFFObjectFile
*Owner
)
1183 : Header(Header
), Index(0) {}
1185 bool operator==(const BaseRelocRef
&Other
) const;
1188 std::error_code
getType(uint8_t &Type
) const;
1189 std::error_code
getRVA(uint32_t &Result
) const;
1192 const coff_base_reloc_block_header
*Header
;
1196 class ResourceSectionRef
{
1198 ResourceSectionRef() = default;
1199 explicit ResourceSectionRef(StringRef Ref
) : BBS(Ref
, support::little
) {}
1201 Expected
<ArrayRef
<UTF16
>>
1202 getEntryNameString(const coff_resource_dir_entry
&Entry
);
1203 Expected
<const coff_resource_dir_table
&>
1204 getEntrySubDir(const coff_resource_dir_entry
&Entry
);
1205 Expected
<const coff_resource_dir_table
&> getBaseTable();
1208 BinaryByteStream BBS
;
1210 Expected
<const coff_resource_dir_table
&> getTableAtOffset(uint32_t Offset
);
1211 Expected
<ArrayRef
<UTF16
>> getDirStringAtOffset(uint32_t Offset
);
1214 // Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
1216 support::ulittle32_t Offset
; // ulOffStart: Offset 1st byte of function code
1217 support::ulittle32_t Size
; // cbProcSize: # bytes in function
1218 support::ulittle32_t NumLocals
; // cdwLocals: # bytes in locals/4
1219 support::ulittle16_t NumParams
; // cdwParams: # bytes in params/4
1220 support::ulittle16_t Attributes
;
1222 // cbProlog: # bytes in prolog
1223 int getPrologSize() const { return Attributes
& 0xF; }
1225 // cbRegs: # regs saved
1226 int getNumSavedRegs() const { return (Attributes
>> 8) & 0x7; }
1228 // fHasSEH: true if seh is func
1229 bool hasSEH() const { return (Attributes
>> 9) & 1; }
1231 // fUseBP: true if EBP has been allocated
1232 bool useBP() const { return (Attributes
>> 10) & 1; }
1234 // cbFrame: frame pointer
1235 frame_type
getFP() const { return static_cast<frame_type
>(Attributes
>> 14); }
1238 } // end namespace object
1240 } // end namespace llvm
1242 #endif // LLVM_OBJECT_COFF_H