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 {
318 assert(isSet() && "COFFSymbolRef points to nothing!");
319 return CS16
? CS16
->Value
: CS32
->Value
;
322 int32_t getSectionNumber() const {
323 assert(isSet() && "COFFSymbolRef points to nothing!");
325 // Reserved sections are returned as negative numbers.
326 if (CS16
->SectionNumber
<= COFF::MaxNumberOfSections16
)
327 return CS16
->SectionNumber
;
328 return static_cast<int16_t>(CS16
->SectionNumber
);
330 return static_cast<int32_t>(CS32
->SectionNumber
);
333 uint16_t getType() const {
334 assert(isSet() && "COFFSymbolRef points to nothing!");
335 return CS16
? CS16
->Type
: CS32
->Type
;
338 uint8_t getStorageClass() const {
339 assert(isSet() && "COFFSymbolRef points to nothing!");
340 return CS16
? CS16
->StorageClass
: CS32
->StorageClass
;
343 uint8_t getNumberOfAuxSymbols() const {
344 assert(isSet() && "COFFSymbolRef points to nothing!");
345 return CS16
? CS16
->NumberOfAuxSymbols
: CS32
->NumberOfAuxSymbols
;
348 uint8_t getBaseType() const { return getType() & 0x0F; }
350 uint8_t getComplexType() const {
351 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT
;
354 template <typename T
> const T
*getAux() const {
355 return CS16
? reinterpret_cast<const T
*>(CS16
+ 1)
356 : reinterpret_cast<const T
*>(CS32
+ 1);
359 const coff_aux_section_definition
*getSectionDefinition() const {
360 if (!getNumberOfAuxSymbols() ||
361 getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC
)
363 return getAux
<coff_aux_section_definition
>();
366 const coff_aux_weak_external
*getWeakExternal() const {
367 if (!getNumberOfAuxSymbols() ||
368 getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
)
370 return getAux
<coff_aux_weak_external
>();
373 bool isAbsolute() const {
374 return getSectionNumber() == -1;
377 bool isExternal() const {
378 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
;
381 bool isCommon() const {
382 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
386 bool isUndefined() const {
387 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED
&&
391 bool isWeakExternal() const {
392 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL
;
395 bool isFunctionDefinition() const {
396 return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL
&&
397 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION
&&
398 !COFF::isReservedSectionNumber(getSectionNumber());
401 bool isFunctionLineInfo() const {
402 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION
;
405 bool isAnyUndefined() const {
406 return isUndefined() || isWeakExternal();
409 bool isFileRecord() const {
410 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE
;
413 bool isSection() const {
414 return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION
;
417 bool isSectionDefinition() const {
418 // C++/CLI creates external ABS symbols for non-const appdomain globals.
419 // These are also followed by an auxiliary section definition.
420 bool isAppdomainGlobal
=
421 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL
&&
422 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE
;
423 bool isOrdinarySection
= getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC
;
424 if (!getNumberOfAuxSymbols())
426 return isAppdomainGlobal
|| isOrdinarySection
;
429 bool isCLRToken() const {
430 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN
;
434 bool isSet() const { return CS16
|| CS32
; }
436 const coff_symbol16
*CS16
= nullptr;
437 const coff_symbol32
*CS32
= nullptr;
440 struct coff_section
{
441 char Name
[COFF::NameSize
];
442 support::ulittle32_t VirtualSize
;
443 support::ulittle32_t VirtualAddress
;
444 support::ulittle32_t SizeOfRawData
;
445 support::ulittle32_t PointerToRawData
;
446 support::ulittle32_t PointerToRelocations
;
447 support::ulittle32_t PointerToLinenumbers
;
448 support::ulittle16_t NumberOfRelocations
;
449 support::ulittle16_t NumberOfLinenumbers
;
450 support::ulittle32_t Characteristics
;
452 // Returns true if the actual number of relocations is stored in
453 // VirtualAddress field of the first relocation table entry.
454 bool hasExtendedRelocations() const {
455 return (Characteristics
& COFF::IMAGE_SCN_LNK_NRELOC_OVFL
) &&
456 NumberOfRelocations
== UINT16_MAX
;
459 uint32_t getAlignment() const {
460 // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
461 // IMAGE_SCN_ALIGN_1BYTES.
462 if (Characteristics
& COFF::IMAGE_SCN_TYPE_NO_PAD
)
465 // Bit [20:24] contains section alignment. 0 means use a default alignment
467 uint32_t Shift
= (Characteristics
>> 20) & 0xF;
469 return 1U << (Shift
- 1);
474 struct coff_relocation
{
475 support::ulittle32_t VirtualAddress
;
476 support::ulittle32_t SymbolTableIndex
;
477 support::ulittle16_t Type
;
480 struct coff_aux_function_definition
{
481 support::ulittle32_t TagIndex
;
482 support::ulittle32_t TotalSize
;
483 support::ulittle32_t PointerToLinenumber
;
484 support::ulittle32_t PointerToNextFunction
;
488 static_assert(sizeof(coff_aux_function_definition
) == 18,
489 "auxiliary entry must be 18 bytes");
491 struct coff_aux_bf_and_ef_symbol
{
493 support::ulittle16_t Linenumber
;
495 support::ulittle32_t PointerToNextFunction
;
499 static_assert(sizeof(coff_aux_bf_and_ef_symbol
) == 18,
500 "auxiliary entry must be 18 bytes");
502 struct coff_aux_weak_external
{
503 support::ulittle32_t TagIndex
;
504 support::ulittle32_t Characteristics
;
508 static_assert(sizeof(coff_aux_weak_external
) == 18,
509 "auxiliary entry must be 18 bytes");
511 struct coff_aux_section_definition
{
512 support::ulittle32_t Length
;
513 support::ulittle16_t NumberOfRelocations
;
514 support::ulittle16_t NumberOfLinenumbers
;
515 support::ulittle32_t CheckSum
;
516 support::ulittle16_t NumberLowPart
;
519 support::ulittle16_t NumberHighPart
;
520 int32_t getNumber(bool IsBigObj
) const {
521 uint32_t Number
= static_cast<uint32_t>(NumberLowPart
);
523 Number
|= static_cast<uint32_t>(NumberHighPart
) << 16;
524 return static_cast<int32_t>(Number
);
528 static_assert(sizeof(coff_aux_section_definition
) == 18,
529 "auxiliary entry must be 18 bytes");
531 struct coff_aux_clr_token
{
534 support::ulittle32_t SymbolTableIndex
;
538 static_assert(sizeof(coff_aux_clr_token
) == 18,
539 "auxiliary entry must be 18 bytes");
541 struct coff_import_header
{
542 support::ulittle16_t Sig1
;
543 support::ulittle16_t Sig2
;
544 support::ulittle16_t Version
;
545 support::ulittle16_t Machine
;
546 support::ulittle32_t TimeDateStamp
;
547 support::ulittle32_t SizeOfData
;
548 support::ulittle16_t OrdinalHint
;
549 support::ulittle16_t TypeInfo
;
551 int getType() const { return TypeInfo
& 0x3; }
552 int getNameType() const { return (TypeInfo
>> 2) & 0x7; }
555 struct coff_import_directory_table_entry
{
556 support::ulittle32_t ImportLookupTableRVA
;
557 support::ulittle32_t TimeDateStamp
;
558 support::ulittle32_t ForwarderChain
;
559 support::ulittle32_t NameRVA
;
560 support::ulittle32_t ImportAddressTableRVA
;
562 bool isNull() const {
563 return ImportLookupTableRVA
== 0 && TimeDateStamp
== 0 &&
564 ForwarderChain
== 0 && NameRVA
== 0 && ImportAddressTableRVA
== 0;
568 template <typename IntTy
>
569 struct coff_tls_directory
{
570 IntTy StartAddressOfRawData
;
571 IntTy EndAddressOfRawData
;
572 IntTy AddressOfIndex
;
573 IntTy AddressOfCallBacks
;
574 support::ulittle32_t SizeOfZeroFill
;
575 support::ulittle32_t Characteristics
;
577 uint32_t getAlignment() const {
578 // Bit [20:24] contains section alignment.
579 uint32_t Shift
= (Characteristics
& 0x00F00000) >> 20;
581 return 1U << (Shift
- 1);
586 using coff_tls_directory32
= coff_tls_directory
<support::little32_t
>;
587 using coff_tls_directory64
= coff_tls_directory
<support::little64_t
>;
589 /// Bits in control flow guard flags as we understand them.
590 enum class coff_guard_flags
: uint32_t {
591 CFInstrumented
= 0x00000100,
592 HasFidTable
= 0x00000400,
593 ProtectDelayLoadIAT
= 0x00001000,
594 DelayLoadIATSection
= 0x00002000, // Delay load in separate section
595 HasLongJmpTable
= 0x00010000,
596 FidTableHasFlags
= 0x10000000, // Indicates that fid tables are 5 bytes
599 enum class frame_type
: uint16_t { Fpo
= 0, Trap
= 1, Tss
= 2, NonFpo
= 3 };
601 struct coff_load_config_code_integrity
{
602 support::ulittle16_t Flags
;
603 support::ulittle16_t Catalog
;
604 support::ulittle32_t CatalogOffset
;
605 support::ulittle32_t Reserved
;
608 /// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
609 struct coff_load_configuration32
{
610 support::ulittle32_t Size
;
611 support::ulittle32_t TimeDateStamp
;
612 support::ulittle16_t MajorVersion
;
613 support::ulittle16_t MinorVersion
;
614 support::ulittle32_t GlobalFlagsClear
;
615 support::ulittle32_t GlobalFlagsSet
;
616 support::ulittle32_t CriticalSectionDefaultTimeout
;
617 support::ulittle32_t DeCommitFreeBlockThreshold
;
618 support::ulittle32_t DeCommitTotalFreeThreshold
;
619 support::ulittle32_t LockPrefixTable
;
620 support::ulittle32_t MaximumAllocationSize
;
621 support::ulittle32_t VirtualMemoryThreshold
;
622 support::ulittle32_t ProcessAffinityMask
;
623 support::ulittle32_t ProcessHeapFlags
;
624 support::ulittle16_t CSDVersion
;
625 support::ulittle16_t DependentLoadFlags
;
626 support::ulittle32_t EditList
;
627 support::ulittle32_t SecurityCookie
;
628 support::ulittle32_t SEHandlerTable
;
629 support::ulittle32_t SEHandlerCount
;
631 // Added in MSVC 2015 for /guard:cf.
632 support::ulittle32_t GuardCFCheckFunction
;
633 support::ulittle32_t GuardCFCheckDispatch
;
634 support::ulittle32_t GuardCFFunctionTable
;
635 support::ulittle32_t GuardCFFunctionCount
;
636 support::ulittle32_t GuardFlags
; // coff_guard_flags
638 // Added in MSVC 2017
639 coff_load_config_code_integrity CodeIntegrity
;
640 support::ulittle32_t GuardAddressTakenIatEntryTable
;
641 support::ulittle32_t GuardAddressTakenIatEntryCount
;
642 support::ulittle32_t GuardLongJumpTargetTable
;
643 support::ulittle32_t GuardLongJumpTargetCount
;
644 support::ulittle32_t DynamicValueRelocTable
;
645 support::ulittle32_t CHPEMetadataPointer
;
646 support::ulittle32_t GuardRFFailureRoutine
;
647 support::ulittle32_t GuardRFFailureRoutineFunctionPointer
;
648 support::ulittle32_t DynamicValueRelocTableOffset
;
649 support::ulittle16_t DynamicValueRelocTableSection
;
650 support::ulittle16_t Reserved2
;
651 support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer
;
652 support::ulittle32_t HotPatchTableOffset
;
655 /// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
656 struct coff_load_configuration64
{
657 support::ulittle32_t Size
;
658 support::ulittle32_t TimeDateStamp
;
659 support::ulittle16_t MajorVersion
;
660 support::ulittle16_t MinorVersion
;
661 support::ulittle32_t GlobalFlagsClear
;
662 support::ulittle32_t GlobalFlagsSet
;
663 support::ulittle32_t CriticalSectionDefaultTimeout
;
664 support::ulittle64_t DeCommitFreeBlockThreshold
;
665 support::ulittle64_t DeCommitTotalFreeThreshold
;
666 support::ulittle64_t LockPrefixTable
;
667 support::ulittle64_t MaximumAllocationSize
;
668 support::ulittle64_t VirtualMemoryThreshold
;
669 support::ulittle64_t ProcessAffinityMask
;
670 support::ulittle32_t ProcessHeapFlags
;
671 support::ulittle16_t CSDVersion
;
672 support::ulittle16_t DependentLoadFlags
;
673 support::ulittle64_t EditList
;
674 support::ulittle64_t SecurityCookie
;
675 support::ulittle64_t SEHandlerTable
;
676 support::ulittle64_t SEHandlerCount
;
678 // Added in MSVC 2015 for /guard:cf.
679 support::ulittle64_t GuardCFCheckFunction
;
680 support::ulittle64_t GuardCFCheckDispatch
;
681 support::ulittle64_t GuardCFFunctionTable
;
682 support::ulittle64_t GuardCFFunctionCount
;
683 support::ulittle32_t GuardFlags
;
685 // Added in MSVC 2017
686 coff_load_config_code_integrity CodeIntegrity
;
687 support::ulittle64_t GuardAddressTakenIatEntryTable
;
688 support::ulittle64_t GuardAddressTakenIatEntryCount
;
689 support::ulittle64_t GuardLongJumpTargetTable
;
690 support::ulittle64_t GuardLongJumpTargetCount
;
691 support::ulittle64_t DynamicValueRelocTable
;
692 support::ulittle64_t CHPEMetadataPointer
;
693 support::ulittle64_t GuardRFFailureRoutine
;
694 support::ulittle64_t GuardRFFailureRoutineFunctionPointer
;
695 support::ulittle32_t DynamicValueRelocTableOffset
;
696 support::ulittle16_t DynamicValueRelocTableSection
;
697 support::ulittle16_t Reserved2
;
698 support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer
;
699 support::ulittle32_t HotPatchTableOffset
;
702 struct coff_runtime_function_x64
{
703 support::ulittle32_t BeginAddress
;
704 support::ulittle32_t EndAddress
;
705 support::ulittle32_t UnwindInformation
;
708 struct coff_base_reloc_block_header
{
709 support::ulittle32_t PageRVA
;
710 support::ulittle32_t BlockSize
;
713 struct coff_base_reloc_block_entry
{
714 support::ulittle16_t Data
;
716 int getType() const { return Data
>> 12; }
717 int getOffset() const { return Data
& ((1 << 12) - 1); }
720 struct coff_resource_dir_entry
{
722 support::ulittle32_t NameOffset
;
723 support::ulittle32_t ID
;
724 uint32_t getNameOffset() const {
725 return maskTrailingOnes
<uint32_t>(31) & NameOffset
;
727 // Even though the PE/COFF spec doesn't mention this, the high bit of a name
729 void setNameOffset(uint32_t Offset
) { NameOffset
= Offset
| (1 << 31); }
732 support::ulittle32_t DataEntryOffset
;
733 support::ulittle32_t SubdirOffset
;
735 bool isSubDir() const { return SubdirOffset
>> 31; }
736 uint32_t value() const {
737 return maskTrailingOnes
<uint32_t>(31) & SubdirOffset
;
743 struct coff_resource_data_entry
{
744 support::ulittle32_t DataRVA
;
745 support::ulittle32_t DataSize
;
746 support::ulittle32_t Codepage
;
747 support::ulittle32_t Reserved
;
750 struct coff_resource_dir_table
{
751 support::ulittle32_t Characteristics
;
752 support::ulittle32_t TimeDateStamp
;
753 support::ulittle16_t MajorVersion
;
754 support::ulittle16_t MinorVersion
;
755 support::ulittle16_t NumberOfNameEntries
;
756 support::ulittle16_t NumberOfIDEntries
;
759 struct debug_h_header
{
760 support::ulittle32_t Magic
;
761 support::ulittle16_t Version
;
762 support::ulittle16_t HashAlgorithm
;
765 class COFFObjectFile
: public ObjectFile
{
767 friend class ImportDirectoryEntryRef
;
768 friend class ExportDirectoryEntryRef
;
769 const coff_file_header
*COFFHeader
;
770 const coff_bigobj_file_header
*COFFBigObjHeader
;
771 const pe32_header
*PE32Header
;
772 const pe32plus_header
*PE32PlusHeader
;
773 const data_directory
*DataDirectory
;
774 const coff_section
*SectionTable
;
775 const coff_symbol16
*SymbolTable16
;
776 const coff_symbol32
*SymbolTable32
;
777 const char *StringTable
;
778 uint32_t StringTableSize
;
779 const coff_import_directory_table_entry
*ImportDirectory
;
780 const delay_import_directory_table_entry
*DelayImportDirectory
;
781 uint32_t NumberOfDelayImportDirectory
;
782 const export_directory_table_entry
*ExportDirectory
;
783 const coff_base_reloc_block_header
*BaseRelocHeader
;
784 const coff_base_reloc_block_header
*BaseRelocEnd
;
785 const debug_directory
*DebugDirectoryBegin
;
786 const debug_directory
*DebugDirectoryEnd
;
787 // Either coff_load_configuration32 or coff_load_configuration64.
788 const void *LoadConfig
= nullptr;
790 std::error_code
getString(uint32_t offset
, StringRef
&Res
) const;
792 template <typename coff_symbol_type
>
793 const coff_symbol_type
*toSymb(DataRefImpl Symb
) const;
794 const coff_section
*toSec(DataRefImpl Sec
) const;
795 const coff_relocation
*toRel(DataRefImpl Rel
) const;
797 std::error_code
initSymbolTablePtr();
798 std::error_code
initImportTablePtr();
799 std::error_code
initDelayImportTablePtr();
800 std::error_code
initExportTablePtr();
801 std::error_code
initBaseRelocPtr();
802 std::error_code
initDebugDirectoryPtr();
803 std::error_code
initLoadConfigPtr();
806 uintptr_t getSymbolTable() const {
808 return reinterpret_cast<uintptr_t>(SymbolTable16
);
810 return reinterpret_cast<uintptr_t>(SymbolTable32
);
814 uint16_t getMachine() const {
816 return COFFHeader
->Machine
;
817 if (COFFBigObjHeader
)
818 return COFFBigObjHeader
->Machine
;
819 llvm_unreachable("no COFF header!");
822 uint16_t getSizeOfOptionalHeader() const {
824 return COFFHeader
->isImportLibrary() ? 0
825 : COFFHeader
->SizeOfOptionalHeader
;
826 // bigobj doesn't have this field.
827 if (COFFBigObjHeader
)
829 llvm_unreachable("no COFF header!");
832 uint16_t getCharacteristics() const {
834 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->Characteristics
;
835 // bigobj doesn't have characteristics to speak of,
836 // editbin will silently lie to you if you attempt to set any.
837 if (COFFBigObjHeader
)
839 llvm_unreachable("no COFF header!");
842 uint32_t getTimeDateStamp() const {
844 return COFFHeader
->TimeDateStamp
;
845 if (COFFBigObjHeader
)
846 return COFFBigObjHeader
->TimeDateStamp
;
847 llvm_unreachable("no COFF header!");
850 uint32_t getNumberOfSections() const {
852 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSections
;
853 if (COFFBigObjHeader
)
854 return COFFBigObjHeader
->NumberOfSections
;
855 llvm_unreachable("no COFF header!");
858 uint32_t getPointerToSymbolTable() const {
860 return COFFHeader
->isImportLibrary() ? 0
861 : COFFHeader
->PointerToSymbolTable
;
862 if (COFFBigObjHeader
)
863 return COFFBigObjHeader
->PointerToSymbolTable
;
864 llvm_unreachable("no COFF header!");
867 uint32_t getRawNumberOfSymbols() const {
869 return COFFHeader
->isImportLibrary() ? 0 : COFFHeader
->NumberOfSymbols
;
870 if (COFFBigObjHeader
)
871 return COFFBigObjHeader
->NumberOfSymbols
;
872 llvm_unreachable("no COFF header!");
875 uint32_t getNumberOfSymbols() const {
876 if (!SymbolTable16
&& !SymbolTable32
)
878 return getRawNumberOfSymbols();
881 const coff_load_configuration32
*getLoadConfig32() const {
883 return reinterpret_cast<const coff_load_configuration32
*>(LoadConfig
);
886 const coff_load_configuration64
*getLoadConfig64() const {
888 return reinterpret_cast<const coff_load_configuration64
*>(LoadConfig
);
890 StringRef
getRelocationTypeName(uint16_t Type
) const;
893 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
894 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
895 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
896 uint32_t getSymbolAlignment(DataRefImpl Symb
) const override
;
897 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
898 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
899 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
900 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
901 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
902 void moveSectionNext(DataRefImpl
&Sec
) const override
;
903 Expected
<StringRef
> getSectionName(DataRefImpl Sec
) const override
;
904 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
905 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
906 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
907 Expected
<ArrayRef
<uint8_t>>
908 getSectionContents(DataRefImpl Sec
) const override
;
909 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
910 bool isSectionCompressed(DataRefImpl Sec
) const override
;
911 bool isSectionText(DataRefImpl Sec
) const override
;
912 bool isSectionData(DataRefImpl Sec
) const override
;
913 bool isSectionBSS(DataRefImpl Sec
) const override
;
914 bool isSectionVirtual(DataRefImpl Sec
) const override
;
915 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
916 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
918 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
919 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
920 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
921 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
922 void getRelocationTypeName(DataRefImpl Rel
,
923 SmallVectorImpl
<char> &Result
) const override
;
926 COFFObjectFile(MemoryBufferRef Object
, std::error_code
&EC
);
928 basic_symbol_iterator
symbol_begin() const override
;
929 basic_symbol_iterator
symbol_end() const override
;
930 section_iterator
section_begin() const override
;
931 section_iterator
section_end() const override
;
933 const coff_section
*getCOFFSection(const SectionRef
&Section
) const;
934 COFFSymbolRef
getCOFFSymbol(const DataRefImpl
&Ref
) const;
935 COFFSymbolRef
getCOFFSymbol(const SymbolRef
&Symbol
) const;
936 const coff_relocation
*getCOFFRelocation(const RelocationRef
&Reloc
) const;
937 unsigned getSectionID(SectionRef Sec
) const;
938 unsigned getSymbolSectionID(SymbolRef Sym
) const;
940 uint8_t getBytesInAddress() const override
;
941 StringRef
getFileFormatName() const override
;
942 Triple::ArchType
getArch() const override
;
943 Expected
<uint64_t> getStartAddress() const override
;
944 SubtargetFeatures
getFeatures() const override
{ return SubtargetFeatures(); }
946 import_directory_iterator
import_directory_begin() const;
947 import_directory_iterator
import_directory_end() const;
948 delay_import_directory_iterator
delay_import_directory_begin() const;
949 delay_import_directory_iterator
delay_import_directory_end() const;
950 export_directory_iterator
export_directory_begin() const;
951 export_directory_iterator
export_directory_end() const;
952 base_reloc_iterator
base_reloc_begin() const;
953 base_reloc_iterator
base_reloc_end() const;
954 const debug_directory
*debug_directory_begin() const {
955 return DebugDirectoryBegin
;
957 const debug_directory
*debug_directory_end() const {
958 return DebugDirectoryEnd
;
961 iterator_range
<import_directory_iterator
> import_directories() const;
962 iterator_range
<delay_import_directory_iterator
>
963 delay_import_directories() const;
964 iterator_range
<export_directory_iterator
> export_directories() const;
965 iterator_range
<base_reloc_iterator
> base_relocs() const;
966 iterator_range
<const debug_directory
*> debug_directories() const {
967 return make_range(debug_directory_begin(), debug_directory_end());
970 const dos_header
*getDOSHeader() const {
971 if (!PE32Header
&& !PE32PlusHeader
)
973 return reinterpret_cast<const dos_header
*>(base());
976 const coff_file_header
*getCOFFHeader() const { return COFFHeader
; }
977 const coff_bigobj_file_header
*getCOFFBigObjHeader() const {
978 return COFFBigObjHeader
;
980 const pe32_header
*getPE32Header() const { return PE32Header
; }
981 const pe32plus_header
*getPE32PlusHeader() const { return PE32PlusHeader
; }
983 std::error_code
getDataDirectory(uint32_t index
,
984 const data_directory
*&Res
) const;
985 std::error_code
getSection(int32_t index
, const coff_section
*&Res
) const;
986 std::error_code
getSection(StringRef SectionName
,
987 const coff_section
*&Res
) const;
989 template <typename coff_symbol_type
>
990 std::error_code
getSymbol(uint32_t Index
,
991 const coff_symbol_type
*&Res
) const {
992 if (Index
>= getNumberOfSymbols())
993 return object_error::parse_failed
;
995 Res
= reinterpret_cast<coff_symbol_type
*>(getSymbolTable()) + Index
;
996 return std::error_code();
998 Expected
<COFFSymbolRef
> getSymbol(uint32_t index
) const {
1000 const coff_symbol16
*Symb
= nullptr;
1001 if (std::error_code EC
= getSymbol(index
, Symb
))
1002 return errorCodeToError(EC
);
1003 return COFFSymbolRef(Symb
);
1005 if (SymbolTable32
) {
1006 const coff_symbol32
*Symb
= nullptr;
1007 if (std::error_code EC
= getSymbol(index
, Symb
))
1008 return errorCodeToError(EC
);
1009 return COFFSymbolRef(Symb
);
1011 return errorCodeToError(object_error::parse_failed
);
1014 template <typename T
>
1015 std::error_code
getAuxSymbol(uint32_t index
, const T
*&Res
) const {
1016 Expected
<COFFSymbolRef
> S
= getSymbol(index
);
1017 if (Error E
= S
.takeError())
1018 return errorToErrorCode(std::move(E
));
1019 Res
= reinterpret_cast<const T
*>(S
->getRawPtr());
1020 return std::error_code();
1023 std::error_code
getSymbolName(COFFSymbolRef Symbol
, StringRef
&Res
) const;
1024 std::error_code
getSymbolName(const coff_symbol_generic
*Symbol
,
1025 StringRef
&Res
) const;
1027 ArrayRef
<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol
) const;
1029 uint32_t getSymbolIndex(COFFSymbolRef Symbol
) const;
1031 size_t getSymbolTableEntrySize() const {
1033 return sizeof(coff_symbol16
);
1034 if (COFFBigObjHeader
)
1035 return sizeof(coff_symbol32
);
1036 llvm_unreachable("null symbol table pointer!");
1039 ArrayRef
<coff_relocation
> getRelocations(const coff_section
*Sec
) const;
1041 Expected
<StringRef
> getSectionName(const coff_section
*Sec
) const;
1042 uint64_t getSectionSize(const coff_section
*Sec
) const;
1043 Error
getSectionContents(const coff_section
*Sec
,
1044 ArrayRef
<uint8_t> &Res
) const;
1046 uint64_t getImageBase() const;
1047 std::error_code
getVaPtr(uint64_t VA
, uintptr_t &Res
) const;
1048 std::error_code
getRvaPtr(uint32_t Rva
, uintptr_t &Res
) const;
1050 /// Given an RVA base and size, returns a valid array of bytes or an error
1051 /// code if the RVA and size is not contained completely within a valid
1053 std::error_code
getRvaAndSizeAsBytes(uint32_t RVA
, uint32_t Size
,
1054 ArrayRef
<uint8_t> &Contents
) const;
1056 std::error_code
getHintName(uint32_t Rva
, uint16_t &Hint
,
1057 StringRef
&Name
) const;
1059 /// Get PDB information out of a codeview debug directory entry.
1060 std::error_code
getDebugPDBInfo(const debug_directory
*DebugDir
,
1061 const codeview::DebugInfo
*&Info
,
1062 StringRef
&PDBFileName
) const;
1064 /// Get PDB information from an executable. If the information is not present,
1065 /// Info will be set to nullptr and PDBFileName will be empty. An error is
1066 /// returned only on corrupt object files. Convenience accessor that can be
1067 /// used if the debug directory is not already handy.
1068 std::error_code
getDebugPDBInfo(const codeview::DebugInfo
*&Info
,
1069 StringRef
&PDBFileName
) const;
1071 bool isRelocatableObject() const override
;
1072 bool is64() const { return PE32PlusHeader
; }
1074 StringRef
mapDebugSectionName(StringRef Name
) const override
;
1076 static bool classof(const Binary
*v
) { return v
->isCOFF(); }
1079 // The iterator for the import directory table.
1080 class ImportDirectoryEntryRef
{
1082 ImportDirectoryEntryRef() = default;
1083 ImportDirectoryEntryRef(const coff_import_directory_table_entry
*Table
,
1084 uint32_t I
, const COFFObjectFile
*Owner
)
1085 : ImportTable(Table
), Index(I
), OwningObject(Owner
) {}
1087 bool operator==(const ImportDirectoryEntryRef
&Other
) const;
1090 imported_symbol_iterator
imported_symbol_begin() const;
1091 imported_symbol_iterator
imported_symbol_end() const;
1092 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1094 imported_symbol_iterator
lookup_table_begin() const;
1095 imported_symbol_iterator
lookup_table_end() const;
1096 iterator_range
<imported_symbol_iterator
> lookup_table_symbols() const;
1098 std::error_code
getName(StringRef
&Result
) const;
1099 std::error_code
getImportLookupTableRVA(uint32_t &Result
) const;
1100 std::error_code
getImportAddressTableRVA(uint32_t &Result
) const;
1103 getImportTableEntry(const coff_import_directory_table_entry
*&Result
) const;
1106 const coff_import_directory_table_entry
*ImportTable
;
1108 const COFFObjectFile
*OwningObject
= nullptr;
1111 class DelayImportDirectoryEntryRef
{
1113 DelayImportDirectoryEntryRef() = default;
1114 DelayImportDirectoryEntryRef(const delay_import_directory_table_entry
*T
,
1115 uint32_t I
, const COFFObjectFile
*Owner
)
1116 : Table(T
), Index(I
), OwningObject(Owner
) {}
1118 bool operator==(const DelayImportDirectoryEntryRef
&Other
) const;
1121 imported_symbol_iterator
imported_symbol_begin() const;
1122 imported_symbol_iterator
imported_symbol_end() const;
1123 iterator_range
<imported_symbol_iterator
> imported_symbols() const;
1125 std::error_code
getName(StringRef
&Result
) const;
1126 std::error_code
getDelayImportTable(
1127 const delay_import_directory_table_entry
*&Result
) const;
1128 std::error_code
getImportAddress(int AddrIndex
, uint64_t &Result
) const;
1131 const delay_import_directory_table_entry
*Table
;
1133 const COFFObjectFile
*OwningObject
= nullptr;
1136 // The iterator for the export directory table entry.
1137 class ExportDirectoryEntryRef
{
1139 ExportDirectoryEntryRef() = default;
1140 ExportDirectoryEntryRef(const export_directory_table_entry
*Table
, uint32_t I
,
1141 const COFFObjectFile
*Owner
)
1142 : ExportTable(Table
), Index(I
), OwningObject(Owner
) {}
1144 bool operator==(const ExportDirectoryEntryRef
&Other
) const;
1147 std::error_code
getDllName(StringRef
&Result
) const;
1148 std::error_code
getOrdinalBase(uint32_t &Result
) const;
1149 std::error_code
getOrdinal(uint32_t &Result
) const;
1150 std::error_code
getExportRVA(uint32_t &Result
) const;
1151 std::error_code
getSymbolName(StringRef
&Result
) const;
1153 std::error_code
isForwarder(bool &Result
) const;
1154 std::error_code
getForwardTo(StringRef
&Result
) const;
1157 const export_directory_table_entry
*ExportTable
;
1159 const COFFObjectFile
*OwningObject
= nullptr;
1162 class ImportedSymbolRef
{
1164 ImportedSymbolRef() = default;
1165 ImportedSymbolRef(const import_lookup_table_entry32
*Entry
, uint32_t I
,
1166 const COFFObjectFile
*Owner
)
1167 : Entry32(Entry
), Entry64(nullptr), Index(I
), OwningObject(Owner
) {}
1168 ImportedSymbolRef(const import_lookup_table_entry64
*Entry
, uint32_t I
,
1169 const COFFObjectFile
*Owner
)
1170 : Entry32(nullptr), Entry64(Entry
), Index(I
), OwningObject(Owner
) {}
1172 bool operator==(const ImportedSymbolRef
&Other
) const;
1175 std::error_code
getSymbolName(StringRef
&Result
) const;
1176 std::error_code
isOrdinal(bool &Result
) const;
1177 std::error_code
getOrdinal(uint16_t &Result
) const;
1178 std::error_code
getHintNameRVA(uint32_t &Result
) const;
1181 const import_lookup_table_entry32
*Entry32
;
1182 const import_lookup_table_entry64
*Entry64
;
1184 const COFFObjectFile
*OwningObject
= nullptr;
1187 class BaseRelocRef
{
1189 BaseRelocRef() = default;
1190 BaseRelocRef(const coff_base_reloc_block_header
*Header
,
1191 const COFFObjectFile
*Owner
)
1192 : Header(Header
), Index(0) {}
1194 bool operator==(const BaseRelocRef
&Other
) const;
1197 std::error_code
getType(uint8_t &Type
) const;
1198 std::error_code
getRVA(uint32_t &Result
) const;
1201 const coff_base_reloc_block_header
*Header
;
1205 class ResourceSectionRef
{
1207 ResourceSectionRef() = default;
1208 explicit ResourceSectionRef(StringRef Ref
) : BBS(Ref
, support::little
) {}
1210 Error
load(const COFFObjectFile
*O
);
1211 Error
load(const COFFObjectFile
*O
, const SectionRef
&S
);
1213 Expected
<ArrayRef
<UTF16
>>
1214 getEntryNameString(const coff_resource_dir_entry
&Entry
);
1215 Expected
<const coff_resource_dir_table
&>
1216 getEntrySubDir(const coff_resource_dir_entry
&Entry
);
1217 Expected
<const coff_resource_data_entry
&>
1218 getEntryData(const coff_resource_dir_entry
&Entry
);
1219 Expected
<const coff_resource_dir_table
&> getBaseTable();
1220 Expected
<const coff_resource_dir_entry
&>
1221 getTableEntry(const coff_resource_dir_table
&Table
, uint32_t Index
);
1223 Expected
<StringRef
> getContents(const coff_resource_data_entry
&Entry
);
1226 BinaryByteStream BBS
;
1229 const COFFObjectFile
*Obj
;
1231 std::vector
<const coff_relocation
*> Relocs
;
1233 Expected
<const coff_resource_dir_table
&> getTableAtOffset(uint32_t Offset
);
1234 Expected
<const coff_resource_dir_entry
&>
1235 getTableEntryAtOffset(uint32_t Offset
);
1236 Expected
<const coff_resource_data_entry
&>
1237 getDataEntryAtOffset(uint32_t Offset
);
1238 Expected
<ArrayRef
<UTF16
>> getDirStringAtOffset(uint32_t Offset
);
1241 // Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
1243 support::ulittle32_t Offset
; // ulOffStart: Offset 1st byte of function code
1244 support::ulittle32_t Size
; // cbProcSize: # bytes in function
1245 support::ulittle32_t NumLocals
; // cdwLocals: # bytes in locals/4
1246 support::ulittle16_t NumParams
; // cdwParams: # bytes in params/4
1247 support::ulittle16_t Attributes
;
1249 // cbProlog: # bytes in prolog
1250 int getPrologSize() const { return Attributes
& 0xF; }
1252 // cbRegs: # regs saved
1253 int getNumSavedRegs() const { return (Attributes
>> 8) & 0x7; }
1255 // fHasSEH: true if seh is func
1256 bool hasSEH() const { return (Attributes
>> 9) & 1; }
1258 // fUseBP: true if EBP has been allocated
1259 bool useBP() const { return (Attributes
>> 10) & 1; }
1261 // cbFrame: frame pointer
1262 frame_type
getFP() const { return static_cast<frame_type
>(Attributes
>> 14); }
1265 } // end namespace object
1267 } // end namespace llvm
1269 #endif // LLVM_OBJECT_COFF_H