File indexing completed on 2026-05-10 08:44:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_OBJECT_COFF_H
0014 #define LLVM_OBJECT_COFF_H
0015
0016 #include "llvm/ADT/iterator_range.h"
0017 #include "llvm/BinaryFormat/COFF.h"
0018 #include "llvm/Object/Binary.h"
0019 #include "llvm/Object/CVDebugRecord.h"
0020 #include "llvm/Object/Error.h"
0021 #include "llvm/Object/ObjectFile.h"
0022 #include "llvm/Support/BinaryByteStream.h"
0023 #include "llvm/Support/ConvertUTF.h"
0024 #include "llvm/Support/Endian.h"
0025 #include "llvm/Support/ErrorHandling.h"
0026 #include "llvm/TargetParser/SubtargetFeature.h"
0027 #include <cassert>
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <system_error>
0031
0032 namespace llvm {
0033
0034 template <typename T> class ArrayRef;
0035
0036 namespace object {
0037
0038 class Arm64XRelocRef;
0039 class BaseRelocRef;
0040 class DelayImportDirectoryEntryRef;
0041 class DynamicRelocRef;
0042 class ExportDirectoryEntryRef;
0043 class ImportDirectoryEntryRef;
0044 class ImportedSymbolRef;
0045 class ResourceSectionRef;
0046
0047 using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
0048 using delay_import_directory_iterator =
0049 content_iterator<DelayImportDirectoryEntryRef>;
0050 using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
0051 using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
0052 using base_reloc_iterator = content_iterator<BaseRelocRef>;
0053 using dynamic_reloc_iterator = content_iterator<DynamicRelocRef>;
0054 using arm64x_reloc_iterator = content_iterator<Arm64XRelocRef>;
0055
0056
0057 struct dos_header {
0058 char Magic[2];
0059 support::ulittle16_t UsedBytesInTheLastPage;
0060 support::ulittle16_t FileSizeInPages;
0061 support::ulittle16_t NumberOfRelocationItems;
0062 support::ulittle16_t HeaderSizeInParagraphs;
0063 support::ulittle16_t MinimumExtraParagraphs;
0064 support::ulittle16_t MaximumExtraParagraphs;
0065 support::ulittle16_t InitialRelativeSS;
0066 support::ulittle16_t InitialSP;
0067 support::ulittle16_t Checksum;
0068 support::ulittle16_t InitialIP;
0069 support::ulittle16_t InitialRelativeCS;
0070 support::ulittle16_t AddressOfRelocationTable;
0071 support::ulittle16_t OverlayNumber;
0072 support::ulittle16_t Reserved[4];
0073 support::ulittle16_t OEMid;
0074 support::ulittle16_t OEMinfo;
0075 support::ulittle16_t Reserved2[10];
0076 support::ulittle32_t AddressOfNewExeHeader;
0077 };
0078
0079 struct coff_file_header {
0080 support::ulittle16_t Machine;
0081 support::ulittle16_t NumberOfSections;
0082 support::ulittle32_t TimeDateStamp;
0083 support::ulittle32_t PointerToSymbolTable;
0084 support::ulittle32_t NumberOfSymbols;
0085 support::ulittle16_t SizeOfOptionalHeader;
0086 support::ulittle16_t Characteristics;
0087
0088 bool isImportLibrary() const { return NumberOfSections == 0xffff; }
0089 };
0090
0091 struct coff_bigobj_file_header {
0092 support::ulittle16_t Sig1;
0093 support::ulittle16_t Sig2;
0094 support::ulittle16_t Version;
0095 support::ulittle16_t Machine;
0096 support::ulittle32_t TimeDateStamp;
0097 uint8_t UUID[16];
0098 support::ulittle32_t unused1;
0099 support::ulittle32_t unused2;
0100 support::ulittle32_t unused3;
0101 support::ulittle32_t unused4;
0102 support::ulittle32_t NumberOfSections;
0103 support::ulittle32_t PointerToSymbolTable;
0104 support::ulittle32_t NumberOfSymbols;
0105 };
0106
0107
0108 struct pe32_header {
0109 support::ulittle16_t Magic;
0110 uint8_t MajorLinkerVersion;
0111 uint8_t MinorLinkerVersion;
0112 support::ulittle32_t SizeOfCode;
0113 support::ulittle32_t SizeOfInitializedData;
0114 support::ulittle32_t SizeOfUninitializedData;
0115 support::ulittle32_t AddressOfEntryPoint;
0116 support::ulittle32_t BaseOfCode;
0117 support::ulittle32_t BaseOfData;
0118 support::ulittle32_t ImageBase;
0119 support::ulittle32_t SectionAlignment;
0120 support::ulittle32_t FileAlignment;
0121 support::ulittle16_t MajorOperatingSystemVersion;
0122 support::ulittle16_t MinorOperatingSystemVersion;
0123 support::ulittle16_t MajorImageVersion;
0124 support::ulittle16_t MinorImageVersion;
0125 support::ulittle16_t MajorSubsystemVersion;
0126 support::ulittle16_t MinorSubsystemVersion;
0127 support::ulittle32_t Win32VersionValue;
0128 support::ulittle32_t SizeOfImage;
0129 support::ulittle32_t SizeOfHeaders;
0130 support::ulittle32_t CheckSum;
0131 support::ulittle16_t Subsystem;
0132
0133 support::ulittle16_t DLLCharacteristics;
0134 support::ulittle32_t SizeOfStackReserve;
0135 support::ulittle32_t SizeOfStackCommit;
0136 support::ulittle32_t SizeOfHeapReserve;
0137 support::ulittle32_t SizeOfHeapCommit;
0138 support::ulittle32_t LoaderFlags;
0139
0140 support::ulittle32_t NumberOfRvaAndSize;
0141 };
0142
0143
0144 struct pe32plus_header {
0145 support::ulittle16_t Magic;
0146 uint8_t MajorLinkerVersion;
0147 uint8_t MinorLinkerVersion;
0148 support::ulittle32_t SizeOfCode;
0149 support::ulittle32_t SizeOfInitializedData;
0150 support::ulittle32_t SizeOfUninitializedData;
0151 support::ulittle32_t AddressOfEntryPoint;
0152 support::ulittle32_t BaseOfCode;
0153 support::ulittle64_t ImageBase;
0154 support::ulittle32_t SectionAlignment;
0155 support::ulittle32_t FileAlignment;
0156 support::ulittle16_t MajorOperatingSystemVersion;
0157 support::ulittle16_t MinorOperatingSystemVersion;
0158 support::ulittle16_t MajorImageVersion;
0159 support::ulittle16_t MinorImageVersion;
0160 support::ulittle16_t MajorSubsystemVersion;
0161 support::ulittle16_t MinorSubsystemVersion;
0162 support::ulittle32_t Win32VersionValue;
0163 support::ulittle32_t SizeOfImage;
0164 support::ulittle32_t SizeOfHeaders;
0165 support::ulittle32_t CheckSum;
0166 support::ulittle16_t Subsystem;
0167 support::ulittle16_t DLLCharacteristics;
0168 support::ulittle64_t SizeOfStackReserve;
0169 support::ulittle64_t SizeOfStackCommit;
0170 support::ulittle64_t SizeOfHeapReserve;
0171 support::ulittle64_t SizeOfHeapCommit;
0172 support::ulittle32_t LoaderFlags;
0173 support::ulittle32_t NumberOfRvaAndSize;
0174 };
0175
0176 struct data_directory {
0177 support::ulittle32_t RelativeVirtualAddress;
0178 support::ulittle32_t Size;
0179 };
0180
0181 struct debug_directory {
0182 support::ulittle32_t Characteristics;
0183 support::ulittle32_t TimeDateStamp;
0184 support::ulittle16_t MajorVersion;
0185 support::ulittle16_t MinorVersion;
0186 support::ulittle32_t Type;
0187 support::ulittle32_t SizeOfData;
0188 support::ulittle32_t AddressOfRawData;
0189 support::ulittle32_t PointerToRawData;
0190 };
0191
0192 template <typename IntTy>
0193 struct import_lookup_table_entry {
0194 IntTy Data;
0195
0196 bool isOrdinal() const { return Data < 0; }
0197
0198 uint16_t getOrdinal() const {
0199 assert(isOrdinal() && "ILT entry is not an ordinal!");
0200 return Data & 0xFFFF;
0201 }
0202
0203 uint32_t getHintNameRVA() const {
0204 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
0205 return Data & 0xFFFFFFFF;
0206 }
0207 };
0208
0209 using import_lookup_table_entry32 =
0210 import_lookup_table_entry<support::little32_t>;
0211 using import_lookup_table_entry64 =
0212 import_lookup_table_entry<support::little64_t>;
0213
0214 struct delay_import_directory_table_entry {
0215
0216 support::ulittle32_t Attributes;
0217 support::ulittle32_t Name;
0218 support::ulittle32_t ModuleHandle;
0219 support::ulittle32_t DelayImportAddressTable;
0220 support::ulittle32_t DelayImportNameTable;
0221 support::ulittle32_t BoundDelayImportTable;
0222 support::ulittle32_t UnloadDelayImportTable;
0223 support::ulittle32_t TimeStamp;
0224 };
0225
0226 struct export_directory_table_entry {
0227 support::ulittle32_t ExportFlags;
0228 support::ulittle32_t TimeDateStamp;
0229 support::ulittle16_t MajorVersion;
0230 support::ulittle16_t MinorVersion;
0231 support::ulittle32_t NameRVA;
0232 support::ulittle32_t OrdinalBase;
0233 support::ulittle32_t AddressTableEntries;
0234 support::ulittle32_t NumberOfNamePointers;
0235 support::ulittle32_t ExportAddressTableRVA;
0236 support::ulittle32_t NamePointerRVA;
0237 support::ulittle32_t OrdinalTableRVA;
0238 };
0239
0240 union export_address_table_entry {
0241 support::ulittle32_t ExportRVA;
0242 support::ulittle32_t ForwarderRVA;
0243 };
0244
0245 using export_name_pointer_table_entry = support::ulittle32_t;
0246 using export_ordinal_table_entry = support::ulittle16_t;
0247
0248 struct StringTableOffset {
0249 support::ulittle32_t Zeroes;
0250 support::ulittle32_t Offset;
0251 };
0252
0253 template <typename SectionNumberType>
0254 struct coff_symbol {
0255 union {
0256 char ShortName[COFF::NameSize];
0257 StringTableOffset Offset;
0258 } Name;
0259
0260 support::ulittle32_t Value;
0261 SectionNumberType SectionNumber;
0262
0263 support::ulittle16_t Type;
0264
0265 uint8_t StorageClass;
0266 uint8_t NumberOfAuxSymbols;
0267 };
0268
0269 using coff_symbol16 = coff_symbol<support::ulittle16_t>;
0270 using coff_symbol32 = coff_symbol<support::ulittle32_t>;
0271
0272
0273 struct coff_symbol_generic {
0274 union {
0275 char ShortName[COFF::NameSize];
0276 StringTableOffset Offset;
0277 } Name;
0278 support::ulittle32_t Value;
0279 };
0280
0281 struct coff_aux_section_definition;
0282 struct coff_aux_weak_external;
0283
0284 class COFFSymbolRef {
0285 public:
0286 COFFSymbolRef() = default;
0287 COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
0288 COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
0289
0290 const void *getRawPtr() const {
0291 return CS16 ? static_cast<const void *>(CS16) : CS32;
0292 }
0293
0294 const coff_symbol_generic *getGeneric() const {
0295 if (CS16)
0296 return reinterpret_cast<const coff_symbol_generic *>(CS16);
0297 return reinterpret_cast<const coff_symbol_generic *>(CS32);
0298 }
0299
0300 friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
0301 return A.getRawPtr() < B.getRawPtr();
0302 }
0303
0304 bool isBigObj() const {
0305 if (CS16)
0306 return false;
0307 if (CS32)
0308 return true;
0309 llvm_unreachable("COFFSymbolRef points to nothing!");
0310 }
0311
0312 const char *getShortName() const {
0313 return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
0314 }
0315
0316 const StringTableOffset &getStringTableOffset() const {
0317 assert(isSet() && "COFFSymbolRef points to nothing!");
0318 return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
0319 }
0320
0321 uint32_t getValue() const {
0322 assert(isSet() && "COFFSymbolRef points to nothing!");
0323 return CS16 ? CS16->Value : CS32->Value;
0324 }
0325
0326 int32_t getSectionNumber() const {
0327 assert(isSet() && "COFFSymbolRef points to nothing!");
0328 if (CS16) {
0329
0330 if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
0331 return CS16->SectionNumber;
0332 return static_cast<int16_t>(CS16->SectionNumber);
0333 }
0334 return static_cast<int32_t>(CS32->SectionNumber);
0335 }
0336
0337 uint16_t getType() const {
0338 assert(isSet() && "COFFSymbolRef points to nothing!");
0339 return CS16 ? CS16->Type : CS32->Type;
0340 }
0341
0342 uint8_t getStorageClass() const {
0343 assert(isSet() && "COFFSymbolRef points to nothing!");
0344 return CS16 ? CS16->StorageClass : CS32->StorageClass;
0345 }
0346
0347 uint8_t getNumberOfAuxSymbols() const {
0348 assert(isSet() && "COFFSymbolRef points to nothing!");
0349 return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
0350 }
0351
0352 uint8_t getBaseType() const { return getType() & 0x0F; }
0353
0354 uint8_t getComplexType() const {
0355 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
0356 }
0357
0358 template <typename T> const T *getAux() const {
0359 return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
0360 : reinterpret_cast<const T *>(CS32 + 1);
0361 }
0362
0363 const coff_aux_section_definition *getSectionDefinition() const {
0364 if (!getNumberOfAuxSymbols() ||
0365 getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
0366 return nullptr;
0367 return getAux<coff_aux_section_definition>();
0368 }
0369
0370 const coff_aux_weak_external *getWeakExternal() const {
0371 if (!getNumberOfAuxSymbols() ||
0372 getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
0373 return nullptr;
0374 return getAux<coff_aux_weak_external>();
0375 }
0376
0377 bool isAbsolute() const {
0378 return getSectionNumber() == -1;
0379 }
0380
0381 bool isExternal() const {
0382 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
0383 }
0384
0385 bool isCommon() const {
0386 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
0387 getValue() != 0;
0388 }
0389
0390 bool isUndefined() const {
0391 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
0392 getValue() == 0;
0393 }
0394
0395 bool isEmptySectionDeclaration() const {
0396 return isSection() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED;
0397 }
0398
0399 bool isWeakExternal() const {
0400 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
0401 }
0402
0403 bool isFunctionDefinition() const {
0404 return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
0405 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
0406 !COFF::isReservedSectionNumber(getSectionNumber());
0407 }
0408
0409 bool isFunctionLineInfo() const {
0410 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
0411 }
0412
0413 bool isAnyUndefined() const {
0414 return isUndefined() || isWeakExternal();
0415 }
0416
0417 bool isFileRecord() const {
0418 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
0419 }
0420
0421 bool isSection() const {
0422 return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
0423 }
0424
0425 bool isSectionDefinition() const {
0426
0427
0428 bool isAppdomainGlobal =
0429 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
0430 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
0431 bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
0432 if (!getNumberOfAuxSymbols())
0433 return false;
0434 return isAppdomainGlobal || isOrdinarySection;
0435 }
0436
0437 bool isCLRToken() const {
0438 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
0439 }
0440
0441 private:
0442 bool isSet() const { return CS16 || CS32; }
0443
0444 const coff_symbol16 *CS16 = nullptr;
0445 const coff_symbol32 *CS32 = nullptr;
0446 };
0447
0448 struct coff_section {
0449 char Name[COFF::NameSize];
0450 support::ulittle32_t VirtualSize;
0451 support::ulittle32_t VirtualAddress;
0452 support::ulittle32_t SizeOfRawData;
0453 support::ulittle32_t PointerToRawData;
0454 support::ulittle32_t PointerToRelocations;
0455 support::ulittle32_t PointerToLinenumbers;
0456 support::ulittle16_t NumberOfRelocations;
0457 support::ulittle16_t NumberOfLinenumbers;
0458 support::ulittle32_t Characteristics;
0459
0460
0461
0462 bool hasExtendedRelocations() const {
0463 return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
0464 NumberOfRelocations == UINT16_MAX;
0465 }
0466
0467 uint32_t getAlignment() const {
0468
0469
0470 if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
0471 return 1;
0472
0473
0474
0475 uint32_t Shift = (Characteristics >> 20) & 0xF;
0476 if (Shift > 0)
0477 return 1U << (Shift - 1);
0478 return 16;
0479 }
0480 };
0481
0482 struct coff_relocation {
0483 support::ulittle32_t VirtualAddress;
0484 support::ulittle32_t SymbolTableIndex;
0485 support::ulittle16_t Type;
0486 };
0487
0488 struct coff_aux_function_definition {
0489 support::ulittle32_t TagIndex;
0490 support::ulittle32_t TotalSize;
0491 support::ulittle32_t PointerToLinenumber;
0492 support::ulittle32_t PointerToNextFunction;
0493 char Unused1[2];
0494 };
0495
0496 static_assert(sizeof(coff_aux_function_definition) == 18,
0497 "auxiliary entry must be 18 bytes");
0498
0499 struct coff_aux_bf_and_ef_symbol {
0500 char Unused1[4];
0501 support::ulittle16_t Linenumber;
0502 char Unused2[6];
0503 support::ulittle32_t PointerToNextFunction;
0504 char Unused3[2];
0505 };
0506
0507 static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
0508 "auxiliary entry must be 18 bytes");
0509
0510 struct coff_aux_weak_external {
0511 support::ulittle32_t TagIndex;
0512 support::ulittle32_t Characteristics;
0513 char Unused1[10];
0514 };
0515
0516 static_assert(sizeof(coff_aux_weak_external) == 18,
0517 "auxiliary entry must be 18 bytes");
0518
0519 struct coff_aux_section_definition {
0520 support::ulittle32_t Length;
0521 support::ulittle16_t NumberOfRelocations;
0522 support::ulittle16_t NumberOfLinenumbers;
0523 support::ulittle32_t CheckSum;
0524 support::ulittle16_t NumberLowPart;
0525 uint8_t Selection;
0526 uint8_t Unused;
0527 support::ulittle16_t NumberHighPart;
0528 int32_t getNumber(bool IsBigObj) const {
0529 uint32_t Number = static_cast<uint32_t>(NumberLowPart);
0530 if (IsBigObj)
0531 Number |= static_cast<uint32_t>(NumberHighPart) << 16;
0532 return static_cast<int32_t>(Number);
0533 }
0534 };
0535
0536 static_assert(sizeof(coff_aux_section_definition) == 18,
0537 "auxiliary entry must be 18 bytes");
0538
0539 struct coff_aux_clr_token {
0540 uint8_t AuxType;
0541 uint8_t Reserved;
0542 support::ulittle32_t SymbolTableIndex;
0543 char MBZ[12];
0544 };
0545
0546 static_assert(sizeof(coff_aux_clr_token) == 18,
0547 "auxiliary entry must be 18 bytes");
0548
0549 struct coff_import_header {
0550 support::ulittle16_t Sig1;
0551 support::ulittle16_t Sig2;
0552 support::ulittle16_t Version;
0553 support::ulittle16_t Machine;
0554 support::ulittle32_t TimeDateStamp;
0555 support::ulittle32_t SizeOfData;
0556 support::ulittle16_t OrdinalHint;
0557 support::ulittle16_t TypeInfo;
0558
0559 int getType() const { return TypeInfo & 0x3; }
0560 int getNameType() const { return (TypeInfo >> 2) & 0x7; }
0561 };
0562
0563 struct coff_import_directory_table_entry {
0564 support::ulittle32_t ImportLookupTableRVA;
0565 support::ulittle32_t TimeDateStamp;
0566 support::ulittle32_t ForwarderChain;
0567 support::ulittle32_t NameRVA;
0568 support::ulittle32_t ImportAddressTableRVA;
0569
0570 bool isNull() const {
0571 return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
0572 ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
0573 }
0574 };
0575
0576 template <typename IntTy>
0577 struct coff_tls_directory {
0578 IntTy StartAddressOfRawData;
0579 IntTy EndAddressOfRawData;
0580 IntTy AddressOfIndex;
0581 IntTy AddressOfCallBacks;
0582 support::ulittle32_t SizeOfZeroFill;
0583 support::ulittle32_t Characteristics;
0584
0585 uint32_t getAlignment() const {
0586
0587 uint32_t Shift = (Characteristics & COFF::IMAGE_SCN_ALIGN_MASK) >> 20;
0588 if (Shift > 0)
0589 return 1U << (Shift - 1);
0590 return 0;
0591 }
0592
0593 void setAlignment(uint32_t Align) {
0594 uint32_t AlignBits = 0;
0595 if (Align) {
0596 assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2");
0597 assert(llvm::Log2_32(Align) <= 13 && "alignment requested is too large");
0598 AlignBits = (llvm::Log2_32(Align) + 1) << 20;
0599 }
0600 Characteristics =
0601 (Characteristics & ~COFF::IMAGE_SCN_ALIGN_MASK) | AlignBits;
0602 }
0603 };
0604
0605 using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
0606 using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
0607
0608 enum class frame_type : uint16_t { Fpo = 0, Trap = 1, Tss = 2, NonFpo = 3 };
0609
0610 struct coff_load_config_code_integrity {
0611 support::ulittle16_t Flags;
0612 support::ulittle16_t Catalog;
0613 support::ulittle32_t CatalogOffset;
0614 support::ulittle32_t Reserved;
0615 };
0616
0617
0618 struct coff_load_configuration32 {
0619 support::ulittle32_t Size;
0620 support::ulittle32_t TimeDateStamp;
0621 support::ulittle16_t MajorVersion;
0622 support::ulittle16_t MinorVersion;
0623 support::ulittle32_t GlobalFlagsClear;
0624 support::ulittle32_t GlobalFlagsSet;
0625 support::ulittle32_t CriticalSectionDefaultTimeout;
0626 support::ulittle32_t DeCommitFreeBlockThreshold;
0627 support::ulittle32_t DeCommitTotalFreeThreshold;
0628 support::ulittle32_t LockPrefixTable;
0629 support::ulittle32_t MaximumAllocationSize;
0630 support::ulittle32_t VirtualMemoryThreshold;
0631 support::ulittle32_t ProcessAffinityMask;
0632 support::ulittle32_t ProcessHeapFlags;
0633 support::ulittle16_t CSDVersion;
0634 support::ulittle16_t DependentLoadFlags;
0635 support::ulittle32_t EditList;
0636 support::ulittle32_t SecurityCookie;
0637 support::ulittle32_t SEHandlerTable;
0638 support::ulittle32_t SEHandlerCount;
0639
0640
0641 support::ulittle32_t GuardCFCheckFunction;
0642 support::ulittle32_t GuardCFCheckDispatch;
0643 support::ulittle32_t GuardCFFunctionTable;
0644 support::ulittle32_t GuardCFFunctionCount;
0645 support::ulittle32_t GuardFlags;
0646
0647
0648 coff_load_config_code_integrity CodeIntegrity;
0649 support::ulittle32_t GuardAddressTakenIatEntryTable;
0650 support::ulittle32_t GuardAddressTakenIatEntryCount;
0651 support::ulittle32_t GuardLongJumpTargetTable;
0652 support::ulittle32_t GuardLongJumpTargetCount;
0653 support::ulittle32_t DynamicValueRelocTable;
0654 support::ulittle32_t CHPEMetadataPointer;
0655 support::ulittle32_t GuardRFFailureRoutine;
0656 support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
0657 support::ulittle32_t DynamicValueRelocTableOffset;
0658 support::ulittle16_t DynamicValueRelocTableSection;
0659 support::ulittle16_t Reserved2;
0660 support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
0661 support::ulittle32_t HotPatchTableOffset;
0662
0663
0664 support::ulittle32_t Reserved3;
0665 support::ulittle32_t EnclaveConfigurationPointer;
0666 support::ulittle32_t VolatileMetadataPointer;
0667 support::ulittle32_t GuardEHContinuationTable;
0668 support::ulittle32_t GuardEHContinuationCount;
0669 support::ulittle32_t GuardXFGCheckFunctionPointer;
0670 support::ulittle32_t GuardXFGDispatchFunctionPointer;
0671 support::ulittle32_t GuardXFGTableDispatchFunctionPointer;
0672 support::ulittle32_t CastGuardOsDeterminedFailureMode;
0673 };
0674
0675
0676 struct coff_load_configuration64 {
0677 support::ulittle32_t Size;
0678 support::ulittle32_t TimeDateStamp;
0679 support::ulittle16_t MajorVersion;
0680 support::ulittle16_t MinorVersion;
0681 support::ulittle32_t GlobalFlagsClear;
0682 support::ulittle32_t GlobalFlagsSet;
0683 support::ulittle32_t CriticalSectionDefaultTimeout;
0684 support::ulittle64_t DeCommitFreeBlockThreshold;
0685 support::ulittle64_t DeCommitTotalFreeThreshold;
0686 support::ulittle64_t LockPrefixTable;
0687 support::ulittle64_t MaximumAllocationSize;
0688 support::ulittle64_t VirtualMemoryThreshold;
0689 support::ulittle64_t ProcessAffinityMask;
0690 support::ulittle32_t ProcessHeapFlags;
0691 support::ulittle16_t CSDVersion;
0692 support::ulittle16_t DependentLoadFlags;
0693 support::ulittle64_t EditList;
0694 support::ulittle64_t SecurityCookie;
0695 support::ulittle64_t SEHandlerTable;
0696 support::ulittle64_t SEHandlerCount;
0697
0698
0699 support::ulittle64_t GuardCFCheckFunction;
0700 support::ulittle64_t GuardCFCheckDispatch;
0701 support::ulittle64_t GuardCFFunctionTable;
0702 support::ulittle64_t GuardCFFunctionCount;
0703 support::ulittle32_t GuardFlags;
0704
0705
0706 coff_load_config_code_integrity CodeIntegrity;
0707 support::ulittle64_t GuardAddressTakenIatEntryTable;
0708 support::ulittle64_t GuardAddressTakenIatEntryCount;
0709 support::ulittle64_t GuardLongJumpTargetTable;
0710 support::ulittle64_t GuardLongJumpTargetCount;
0711 support::ulittle64_t DynamicValueRelocTable;
0712 support::ulittle64_t CHPEMetadataPointer;
0713 support::ulittle64_t GuardRFFailureRoutine;
0714 support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
0715 support::ulittle32_t DynamicValueRelocTableOffset;
0716 support::ulittle16_t DynamicValueRelocTableSection;
0717 support::ulittle16_t Reserved2;
0718 support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
0719 support::ulittle32_t HotPatchTableOffset;
0720
0721
0722 support::ulittle32_t Reserved3;
0723 support::ulittle64_t EnclaveConfigurationPointer;
0724 support::ulittle64_t VolatileMetadataPointer;
0725 support::ulittle64_t GuardEHContinuationTable;
0726 support::ulittle64_t GuardEHContinuationCount;
0727 support::ulittle64_t GuardXFGCheckFunctionPointer;
0728 support::ulittle64_t GuardXFGDispatchFunctionPointer;
0729 support::ulittle64_t GuardXFGTableDispatchFunctionPointer;
0730 support::ulittle64_t CastGuardOsDeterminedFailureMode;
0731 };
0732
0733 struct chpe_metadata {
0734 support::ulittle32_t Version;
0735 support::ulittle32_t CodeMap;
0736 support::ulittle32_t CodeMapCount;
0737 support::ulittle32_t CodeRangesToEntryPoints;
0738 support::ulittle32_t RedirectionMetadata;
0739 support::ulittle32_t __os_arm64x_dispatch_call_no_redirect;
0740 support::ulittle32_t __os_arm64x_dispatch_ret;
0741 support::ulittle32_t __os_arm64x_dispatch_call;
0742 support::ulittle32_t __os_arm64x_dispatch_icall;
0743 support::ulittle32_t __os_arm64x_dispatch_icall_cfg;
0744 support::ulittle32_t AlternateEntryPoint;
0745 support::ulittle32_t AuxiliaryIAT;
0746 support::ulittle32_t CodeRangesToEntryPointsCount;
0747 support::ulittle32_t RedirectionMetadataCount;
0748 support::ulittle32_t GetX64InformationFunctionPointer;
0749 support::ulittle32_t SetX64InformationFunctionPointer;
0750 support::ulittle32_t ExtraRFETable;
0751 support::ulittle32_t ExtraRFETableSize;
0752 support::ulittle32_t __os_arm64x_dispatch_fptr;
0753 support::ulittle32_t AuxiliaryIATCopy;
0754
0755
0756 support::ulittle32_t AuxiliaryDelayloadIAT;
0757 support::ulittle32_t AuxiliaryDelayloadIATCopy;
0758 support::ulittle32_t HybridImageInfoBitfield;
0759 };
0760
0761 enum chpe_range_type { Arm64 = 0, Arm64EC = 1, Amd64 = 2 };
0762
0763 struct chpe_range_entry {
0764 support::ulittle32_t StartOffset;
0765 support::ulittle32_t Length;
0766
0767
0768 static constexpr uint32_t TypeMask = 3;
0769
0770 uint32_t getStart() const { return StartOffset & ~TypeMask; }
0771 uint16_t getType() const { return StartOffset & TypeMask; }
0772 };
0773
0774 struct chpe_code_range_entry {
0775 support::ulittle32_t StartRva;
0776 support::ulittle32_t EndRva;
0777 support::ulittle32_t EntryPoint;
0778 };
0779
0780 struct chpe_redirection_entry {
0781 support::ulittle32_t Source;
0782 support::ulittle32_t Destination;
0783 };
0784
0785 struct coff_runtime_function_x64 {
0786 support::ulittle32_t BeginAddress;
0787 support::ulittle32_t EndAddress;
0788 support::ulittle32_t UnwindInformation;
0789 };
0790
0791 struct coff_base_reloc_block_header {
0792 support::ulittle32_t PageRVA;
0793 support::ulittle32_t BlockSize;
0794 };
0795
0796 struct coff_base_reloc_block_entry {
0797 support::ulittle16_t Data;
0798
0799 int getType() const { return Data >> 12; }
0800 int getOffset() const { return Data & ((1 << 12) - 1); }
0801 };
0802
0803 struct coff_resource_dir_entry {
0804 union {
0805 support::ulittle32_t NameOffset;
0806 support::ulittle32_t ID;
0807 uint32_t getNameOffset() const {
0808 return maskTrailingOnes<uint32_t>(31) & NameOffset;
0809 }
0810
0811
0812 void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
0813 } Identifier;
0814 union {
0815 support::ulittle32_t DataEntryOffset;
0816 support::ulittle32_t SubdirOffset;
0817
0818 bool isSubDir() const { return SubdirOffset >> 31; }
0819 uint32_t value() const {
0820 return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
0821 }
0822
0823 } Offset;
0824 };
0825
0826 struct coff_resource_data_entry {
0827 support::ulittle32_t DataRVA;
0828 support::ulittle32_t DataSize;
0829 support::ulittle32_t Codepage;
0830 support::ulittle32_t Reserved;
0831 };
0832
0833 struct coff_resource_dir_table {
0834 support::ulittle32_t Characteristics;
0835 support::ulittle32_t TimeDateStamp;
0836 support::ulittle16_t MajorVersion;
0837 support::ulittle16_t MinorVersion;
0838 support::ulittle16_t NumberOfNameEntries;
0839 support::ulittle16_t NumberOfIDEntries;
0840 };
0841
0842 struct debug_h_header {
0843 support::ulittle32_t Magic;
0844 support::ulittle16_t Version;
0845 support::ulittle16_t HashAlgorithm;
0846 };
0847
0848 struct coff_dynamic_reloc_table {
0849 support::ulittle32_t Version;
0850 support::ulittle32_t Size;
0851 };
0852
0853 struct coff_dynamic_relocation32 {
0854 support::ulittle32_t Symbol;
0855 support::ulittle32_t BaseRelocSize;
0856 };
0857
0858 struct coff_dynamic_relocation64 {
0859 support::ulittle64_t Symbol;
0860 support::ulittle32_t BaseRelocSize;
0861 };
0862
0863 struct coff_dynamic_relocation32_v2 {
0864 support::ulittle32_t HeaderSize;
0865 support::ulittle32_t FixupInfoSize;
0866 support::ulittle32_t Symbol;
0867 support::ulittle32_t SymbolGroup;
0868 support::ulittle32_t Flags;
0869 };
0870
0871 struct coff_dynamic_relocation64_v2 {
0872 support::ulittle32_t HeaderSize;
0873 support::ulittle32_t FixupInfoSize;
0874 support::ulittle64_t Symbol;
0875 support::ulittle32_t SymbolGroup;
0876 support::ulittle32_t Flags;
0877 };
0878
0879 class COFFObjectFile : public ObjectFile {
0880 private:
0881 COFFObjectFile(MemoryBufferRef Object);
0882
0883 friend class ImportDirectoryEntryRef;
0884 friend class ExportDirectoryEntryRef;
0885 const coff_file_header *COFFHeader;
0886 const coff_bigobj_file_header *COFFBigObjHeader;
0887 const pe32_header *PE32Header;
0888 const pe32plus_header *PE32PlusHeader;
0889 const data_directory *DataDirectory;
0890 const coff_section *SectionTable;
0891 const coff_symbol16 *SymbolTable16;
0892 const coff_symbol32 *SymbolTable32;
0893 const char *StringTable;
0894 uint32_t StringTableSize;
0895 const coff_import_directory_table_entry *ImportDirectory;
0896 const delay_import_directory_table_entry *DelayImportDirectory;
0897 uint32_t NumberOfDelayImportDirectory;
0898 const export_directory_table_entry *ExportDirectory;
0899 const coff_base_reloc_block_header *BaseRelocHeader;
0900 const coff_base_reloc_block_header *BaseRelocEnd;
0901 const debug_directory *DebugDirectoryBegin;
0902 const debug_directory *DebugDirectoryEnd;
0903 const coff_tls_directory32 *TLSDirectory32;
0904 const coff_tls_directory64 *TLSDirectory64;
0905
0906 const void *LoadConfig = nullptr;
0907 const chpe_metadata *CHPEMetadata = nullptr;
0908 const coff_dynamic_reloc_table *DynamicRelocTable = nullptr;
0909
0910 Expected<StringRef> getString(uint32_t offset) const;
0911
0912 template <typename coff_symbol_type>
0913 const coff_symbol_type *toSymb(DataRefImpl Symb) const;
0914 const coff_section *toSec(DataRefImpl Sec) const;
0915 const coff_relocation *toRel(DataRefImpl Rel) const;
0916
0917
0918 Error initialize();
0919
0920 Error initSymbolTablePtr();
0921 Error initImportTablePtr();
0922 Error initDelayImportTablePtr();
0923 Error initExportTablePtr();
0924 Error initBaseRelocPtr();
0925 Error initDebugDirectoryPtr();
0926 Error initTLSDirectoryPtr();
0927 Error initLoadConfigPtr();
0928 Error initDynamicRelocPtr(uint32_t SectionIndex, uint32_t SectionOffset);
0929
0930 public:
0931 static Expected<std::unique_ptr<COFFObjectFile>>
0932 create(MemoryBufferRef Object);
0933
0934 uintptr_t getSymbolTable() const {
0935 if (SymbolTable16)
0936 return reinterpret_cast<uintptr_t>(SymbolTable16);
0937 if (SymbolTable32)
0938 return reinterpret_cast<uintptr_t>(SymbolTable32);
0939 return uintptr_t(0);
0940 }
0941
0942 uint16_t getMachine() const {
0943 if (COFFHeader) {
0944 if (CHPEMetadata) {
0945 switch (COFFHeader->Machine) {
0946 case COFF::IMAGE_FILE_MACHINE_AMD64:
0947 return COFF::IMAGE_FILE_MACHINE_ARM64EC;
0948 case COFF::IMAGE_FILE_MACHINE_ARM64:
0949 return COFF::IMAGE_FILE_MACHINE_ARM64X;
0950 }
0951 }
0952 return COFFHeader->Machine;
0953 }
0954 if (COFFBigObjHeader)
0955 return COFFBigObjHeader->Machine;
0956 llvm_unreachable("no COFF header!");
0957 }
0958
0959 uint16_t getSizeOfOptionalHeader() const {
0960 if (COFFHeader)
0961 return COFFHeader->isImportLibrary() ? 0
0962 : COFFHeader->SizeOfOptionalHeader;
0963
0964 if (COFFBigObjHeader)
0965 return 0;
0966 llvm_unreachable("no COFF header!");
0967 }
0968
0969 uint16_t getCharacteristics() const {
0970 if (COFFHeader)
0971 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
0972
0973
0974 if (COFFBigObjHeader)
0975 return 0;
0976 llvm_unreachable("no COFF header!");
0977 }
0978
0979 uint32_t getTimeDateStamp() const {
0980 if (COFFHeader)
0981 return COFFHeader->TimeDateStamp;
0982 if (COFFBigObjHeader)
0983 return COFFBigObjHeader->TimeDateStamp;
0984 llvm_unreachable("no COFF header!");
0985 }
0986
0987 uint32_t getNumberOfSections() const {
0988 if (COFFHeader)
0989 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
0990 if (COFFBigObjHeader)
0991 return COFFBigObjHeader->NumberOfSections;
0992 llvm_unreachable("no COFF header!");
0993 }
0994
0995 uint32_t getPointerToSymbolTable() const {
0996 if (COFFHeader)
0997 return COFFHeader->isImportLibrary() ? 0
0998 : COFFHeader->PointerToSymbolTable;
0999 if (COFFBigObjHeader)
1000 return COFFBigObjHeader->PointerToSymbolTable;
1001 llvm_unreachable("no COFF header!");
1002 }
1003
1004 uint32_t getRawNumberOfSymbols() const {
1005 if (COFFHeader)
1006 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
1007 if (COFFBigObjHeader)
1008 return COFFBigObjHeader->NumberOfSymbols;
1009 llvm_unreachable("no COFF header!");
1010 }
1011
1012 uint32_t getNumberOfSymbols() const {
1013 if (!SymbolTable16 && !SymbolTable32)
1014 return 0;
1015 return getRawNumberOfSymbols();
1016 }
1017
1018 uint32_t getStringTableSize() const { return StringTableSize; }
1019
1020 const export_directory_table_entry *getExportTable() const {
1021 return ExportDirectory;
1022 }
1023
1024 const coff_load_configuration32 *getLoadConfig32() const {
1025 assert(!is64());
1026 return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
1027 }
1028
1029 const coff_load_configuration64 *getLoadConfig64() const {
1030 assert(is64());
1031 return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
1032 }
1033
1034 const chpe_metadata *getCHPEMetadata() const { return CHPEMetadata; }
1035 const coff_dynamic_reloc_table *getDynamicRelocTable() const {
1036 return DynamicRelocTable;
1037 }
1038
1039 StringRef getRelocationTypeName(uint16_t Type) const;
1040
1041 protected:
1042 void moveSymbolNext(DataRefImpl &Symb) const override;
1043 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
1044 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
1045 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
1046 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
1047 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
1048 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
1049 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
1050 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
1051 void moveSectionNext(DataRefImpl &Sec) const override;
1052 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
1053 uint64_t getSectionAddress(DataRefImpl Sec) const override;
1054 uint64_t getSectionIndex(DataRefImpl Sec) const override;
1055 uint64_t getSectionSize(DataRefImpl Sec) const override;
1056 Expected<ArrayRef<uint8_t>>
1057 getSectionContents(DataRefImpl Sec) const override;
1058 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
1059 bool isSectionCompressed(DataRefImpl Sec) const override;
1060 bool isSectionText(DataRefImpl Sec) const override;
1061 bool isSectionData(DataRefImpl Sec) const override;
1062 bool isSectionBSS(DataRefImpl Sec) const override;
1063 bool isSectionVirtual(DataRefImpl Sec) const override;
1064 bool isDebugSection(DataRefImpl Sec) const override;
1065 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
1066 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
1067
1068 void moveRelocationNext(DataRefImpl &Rel) const override;
1069 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
1070 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
1071 uint64_t getRelocationType(DataRefImpl Rel) const override;
1072 void getRelocationTypeName(DataRefImpl Rel,
1073 SmallVectorImpl<char> &Result) const override;
1074
1075 public:
1076 basic_symbol_iterator symbol_begin() const override;
1077 basic_symbol_iterator symbol_end() const override;
1078 section_iterator section_begin() const override;
1079 section_iterator section_end() const override;
1080
1081 bool is64Bit() const override { return false; }
1082
1083 const coff_section *getCOFFSection(const SectionRef &Section) const;
1084 COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
1085 COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
1086 const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
1087 unsigned getSectionID(SectionRef Sec) const;
1088 unsigned getSymbolSectionID(SymbolRef Sym) const;
1089
1090 uint8_t getBytesInAddress() const override;
1091 StringRef getFileFormatName() const override;
1092 Triple::ArchType getArch() const override;
1093 Expected<uint64_t> getStartAddress() const override;
1094 Expected<SubtargetFeatures> getFeatures() const override {
1095 return SubtargetFeatures();
1096 }
1097 std::unique_ptr<MemoryBuffer> getHybridObjectView() const;
1098
1099 import_directory_iterator import_directory_begin() const;
1100 import_directory_iterator import_directory_end() const;
1101 delay_import_directory_iterator delay_import_directory_begin() const;
1102 delay_import_directory_iterator delay_import_directory_end() const;
1103 export_directory_iterator export_directory_begin() const;
1104 export_directory_iterator export_directory_end() const;
1105 base_reloc_iterator base_reloc_begin() const;
1106 base_reloc_iterator base_reloc_end() const;
1107 dynamic_reloc_iterator dynamic_reloc_begin() const;
1108 dynamic_reloc_iterator dynamic_reloc_end() const;
1109 const debug_directory *debug_directory_begin() const {
1110 return DebugDirectoryBegin;
1111 }
1112 const debug_directory *debug_directory_end() const {
1113 return DebugDirectoryEnd;
1114 }
1115
1116 iterator_range<import_directory_iterator> import_directories() const;
1117 iterator_range<delay_import_directory_iterator>
1118 delay_import_directories() const;
1119 iterator_range<export_directory_iterator> export_directories() const;
1120 iterator_range<base_reloc_iterator> base_relocs() const;
1121 iterator_range<dynamic_reloc_iterator> dynamic_relocs() const;
1122 iterator_range<const debug_directory *> debug_directories() const {
1123 return make_range(debug_directory_begin(), debug_directory_end());
1124 }
1125
1126 const coff_tls_directory32 *getTLSDirectory32() const {
1127 return TLSDirectory32;
1128 }
1129 const coff_tls_directory64 *getTLSDirectory64() const {
1130 return TLSDirectory64;
1131 }
1132
1133 const dos_header *getDOSHeader() const {
1134 if (!PE32Header && !PE32PlusHeader)
1135 return nullptr;
1136 return reinterpret_cast<const dos_header *>(base());
1137 }
1138
1139 const coff_file_header *getCOFFHeader() const { return COFFHeader; }
1140 const coff_bigobj_file_header *getCOFFBigObjHeader() const {
1141 return COFFBigObjHeader;
1142 }
1143 const pe32_header *getPE32Header() const { return PE32Header; }
1144 const pe32plus_header *getPE32PlusHeader() const { return PE32PlusHeader; }
1145
1146 const data_directory *getDataDirectory(uint32_t index) const;
1147 Expected<const coff_section *> getSection(int32_t index) const;
1148
1149 Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
1150 if (index >= getNumberOfSymbols())
1151 return errorCodeToError(object_error::parse_failed);
1152 if (SymbolTable16)
1153 return COFFSymbolRef(SymbolTable16 + index);
1154 if (SymbolTable32)
1155 return COFFSymbolRef(SymbolTable32 + index);
1156 return errorCodeToError(object_error::parse_failed);
1157 }
1158
1159 template <typename T>
1160 Error getAuxSymbol(uint32_t index, const T *&Res) const {
1161 Expected<COFFSymbolRef> S = getSymbol(index);
1162 if (Error E = S.takeError())
1163 return E;
1164 Res = reinterpret_cast<const T *>(S->getRawPtr());
1165 return Error::success();
1166 }
1167
1168 Expected<StringRef> getSymbolName(COFFSymbolRef Symbol) const;
1169 Expected<StringRef> getSymbolName(const coff_symbol_generic *Symbol) const;
1170
1171 ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
1172
1173 uint32_t getSymbolIndex(COFFSymbolRef Symbol) const;
1174
1175 size_t getSymbolTableEntrySize() const {
1176 if (COFFHeader)
1177 return sizeof(coff_symbol16);
1178 if (COFFBigObjHeader)
1179 return sizeof(coff_symbol32);
1180 llvm_unreachable("null symbol table pointer!");
1181 }
1182
1183 ArrayRef<coff_relocation> getRelocations(const coff_section *Sec) const;
1184
1185 Expected<StringRef> getSectionName(const coff_section *Sec) const;
1186 uint64_t getSectionSize(const coff_section *Sec) const;
1187 Error getSectionContents(const coff_section *Sec,
1188 ArrayRef<uint8_t> &Res) const;
1189
1190 uint64_t getImageBase() const;
1191 Error getVaPtr(uint64_t VA, uintptr_t &Res) const;
1192 Error getRvaPtr(uint32_t Rva, uintptr_t &Res,
1193 const char *ErrorContext = nullptr) const;
1194
1195
1196
1197
1198 Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
1199 ArrayRef<uint8_t> &Contents,
1200 const char *ErrorContext = nullptr) const;
1201
1202 Error getHintName(uint32_t Rva, uint16_t &Hint,
1203 StringRef &Name) const;
1204
1205
1206 Error getDebugPDBInfo(const debug_directory *DebugDir,
1207 const codeview::DebugInfo *&Info,
1208 StringRef &PDBFileName) const;
1209
1210
1211
1212
1213
1214 Error getDebugPDBInfo(const codeview::DebugInfo *&Info,
1215 StringRef &PDBFileName) const;
1216
1217 bool isRelocatableObject() const override;
1218 bool is64() const { return PE32PlusHeader; }
1219
1220 StringRef mapDebugSectionName(StringRef Name) const override;
1221
1222 static bool classof(const Binary *v) { return v->isCOFF(); }
1223 };
1224
1225
1226 class ImportDirectoryEntryRef {
1227 public:
1228 ImportDirectoryEntryRef() = default;
1229 ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
1230 uint32_t I, const COFFObjectFile *Owner)
1231 : ImportTable(Table), Index(I), OwningObject(Owner) {}
1232
1233 bool operator==(const ImportDirectoryEntryRef &Other) const;
1234 void moveNext();
1235
1236 imported_symbol_iterator imported_symbol_begin() const;
1237 imported_symbol_iterator imported_symbol_end() const;
1238 iterator_range<imported_symbol_iterator> imported_symbols() const;
1239
1240 imported_symbol_iterator lookup_table_begin() const;
1241 imported_symbol_iterator lookup_table_end() const;
1242 iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
1243
1244 Error getName(StringRef &Result) const;
1245 Error getImportLookupTableRVA(uint32_t &Result) const;
1246 Error getImportAddressTableRVA(uint32_t &Result) const;
1247
1248 Error
1249 getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
1250
1251 private:
1252 const coff_import_directory_table_entry *ImportTable;
1253 uint32_t Index;
1254 const COFFObjectFile *OwningObject = nullptr;
1255 };
1256
1257 class DelayImportDirectoryEntryRef {
1258 public:
1259 DelayImportDirectoryEntryRef() = default;
1260 DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
1261 uint32_t I, const COFFObjectFile *Owner)
1262 : Table(T), Index(I), OwningObject(Owner) {}
1263
1264 bool operator==(const DelayImportDirectoryEntryRef &Other) const;
1265 void moveNext();
1266
1267 imported_symbol_iterator imported_symbol_begin() const;
1268 imported_symbol_iterator imported_symbol_end() const;
1269 iterator_range<imported_symbol_iterator> imported_symbols() const;
1270
1271 Error getName(StringRef &Result) const;
1272 Error getDelayImportTable(
1273 const delay_import_directory_table_entry *&Result) const;
1274 Error getImportAddress(int AddrIndex, uint64_t &Result) const;
1275
1276 private:
1277 const delay_import_directory_table_entry *Table;
1278 uint32_t Index;
1279 const COFFObjectFile *OwningObject = nullptr;
1280 };
1281
1282
1283 class ExportDirectoryEntryRef {
1284 public:
1285 ExportDirectoryEntryRef() = default;
1286 ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
1287 const COFFObjectFile *Owner)
1288 : ExportTable(Table), Index(I), OwningObject(Owner) {}
1289
1290 bool operator==(const ExportDirectoryEntryRef &Other) const;
1291 void moveNext();
1292
1293 Error getDllName(StringRef &Result) const;
1294 Error getOrdinalBase(uint32_t &Result) const;
1295 Error getOrdinal(uint32_t &Result) const;
1296 Error getExportRVA(uint32_t &Result) const;
1297 Error getSymbolName(StringRef &Result) const;
1298
1299 Error isForwarder(bool &Result) const;
1300 Error getForwardTo(StringRef &Result) const;
1301
1302 private:
1303 const export_directory_table_entry *ExportTable;
1304 uint32_t Index;
1305 const COFFObjectFile *OwningObject = nullptr;
1306 };
1307
1308 class ImportedSymbolRef {
1309 public:
1310 ImportedSymbolRef() = default;
1311 ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
1312 const COFFObjectFile *Owner)
1313 : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
1314 ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
1315 const COFFObjectFile *Owner)
1316 : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
1317
1318 bool operator==(const ImportedSymbolRef &Other) const;
1319 void moveNext();
1320
1321 Error getSymbolName(StringRef &Result) const;
1322 Error isOrdinal(bool &Result) const;
1323 Error getOrdinal(uint16_t &Result) const;
1324 Error getHintNameRVA(uint32_t &Result) const;
1325
1326 private:
1327 const import_lookup_table_entry32 *Entry32;
1328 const import_lookup_table_entry64 *Entry64;
1329 uint32_t Index;
1330 const COFFObjectFile *OwningObject = nullptr;
1331 };
1332
1333 class BaseRelocRef {
1334 public:
1335 BaseRelocRef() = default;
1336 BaseRelocRef(const coff_base_reloc_block_header *Header,
1337 const COFFObjectFile *Owner)
1338 : Header(Header), Index(0) {}
1339
1340 bool operator==(const BaseRelocRef &Other) const;
1341 void moveNext();
1342
1343 Error getType(uint8_t &Type) const;
1344 Error getRVA(uint32_t &Result) const;
1345
1346 private:
1347 const coff_base_reloc_block_header *Header;
1348 uint32_t Index;
1349 };
1350
1351 class DynamicRelocRef {
1352 public:
1353 DynamicRelocRef() = default;
1354 DynamicRelocRef(const void *Header, const COFFObjectFile *Owner)
1355 : Obj(Owner), Header(reinterpret_cast<const uint8_t *>(Header)) {}
1356
1357 bool operator==(const DynamicRelocRef &Other) const;
1358 void moveNext();
1359 uint32_t getType() const;
1360 void getContents(ArrayRef<uint8_t> &Ref) const;
1361
1362 arm64x_reloc_iterator arm64x_reloc_begin() const;
1363 arm64x_reloc_iterator arm64x_reloc_end() const;
1364 iterator_range<arm64x_reloc_iterator> arm64x_relocs() const;
1365
1366 private:
1367 Error validate() const;
1368
1369 const COFFObjectFile *Obj;
1370 const uint8_t *Header;
1371
1372 friend class COFFObjectFile;
1373 };
1374
1375 class Arm64XRelocRef {
1376 public:
1377 Arm64XRelocRef() = default;
1378 Arm64XRelocRef(const coff_base_reloc_block_header *Header, uint32_t Index = 0)
1379 : Header(Header), Index(Index) {}
1380
1381 bool operator==(const Arm64XRelocRef &Other) const;
1382 void moveNext();
1383
1384 COFF::Arm64XFixupType getType() const {
1385 return COFF::Arm64XFixupType((getReloc() >> 12) & 3);
1386 }
1387 uint32_t getRVA() const { return Header->PageRVA + (getReloc() & 0xfff); }
1388 uint8_t getSize() const;
1389 uint64_t getValue() const;
1390
1391 private:
1392 const support::ulittle16_t &getReloc(uint32_t Offset = 0) const {
1393 return reinterpret_cast<const support::ulittle16_t *>(Header +
1394 1)[Index + Offset];
1395 }
1396
1397 uint16_t getArg() const { return getReloc() >> 14; }
1398 uint8_t getEntrySize() const;
1399 Error validate(const COFFObjectFile *Obj) const;
1400
1401 const coff_base_reloc_block_header *Header;
1402 uint32_t Index;
1403
1404 friend class DynamicRelocRef;
1405 };
1406
1407 class ResourceSectionRef {
1408 public:
1409 ResourceSectionRef() = default;
1410 explicit ResourceSectionRef(StringRef Ref)
1411 : BBS(Ref, llvm::endianness::little) {}
1412
1413 Error load(const COFFObjectFile *O);
1414 Error load(const COFFObjectFile *O, const SectionRef &S);
1415
1416 Expected<ArrayRef<UTF16>>
1417 getEntryNameString(const coff_resource_dir_entry &Entry);
1418 Expected<const coff_resource_dir_table &>
1419 getEntrySubDir(const coff_resource_dir_entry &Entry);
1420 Expected<const coff_resource_data_entry &>
1421 getEntryData(const coff_resource_dir_entry &Entry);
1422 Expected<const coff_resource_dir_table &> getBaseTable();
1423 Expected<const coff_resource_dir_entry &>
1424 getTableEntry(const coff_resource_dir_table &Table, uint32_t Index);
1425
1426 Expected<StringRef> getContents(const coff_resource_data_entry &Entry);
1427
1428 private:
1429 BinaryByteStream BBS;
1430
1431 SectionRef Section;
1432 const COFFObjectFile *Obj = nullptr;
1433
1434 std::vector<const coff_relocation *> Relocs;
1435
1436 Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
1437 Expected<const coff_resource_dir_entry &>
1438 getTableEntryAtOffset(uint32_t Offset);
1439 Expected<const coff_resource_data_entry &>
1440 getDataEntryAtOffset(uint32_t Offset);
1441 Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
1442 };
1443
1444
1445 struct FpoData {
1446 support::ulittle32_t Offset;
1447 support::ulittle32_t Size;
1448 support::ulittle32_t NumLocals;
1449 support::ulittle16_t NumParams;
1450 support::ulittle16_t Attributes;
1451
1452
1453 int getPrologSize() const { return Attributes & 0xF; }
1454
1455
1456 int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
1457
1458
1459 bool hasSEH() const { return (Attributes >> 9) & 1; }
1460
1461
1462 bool useBP() const { return (Attributes >> 10) & 1; }
1463
1464
1465 frame_type getFP() const { return static_cast<frame_type>(Attributes >> 14); }
1466 };
1467
1468 class SectionStrippedError
1469 : public ErrorInfo<SectionStrippedError, BinaryError> {
1470 public:
1471 SectionStrippedError() { setErrorCode(object_error::section_stripped); }
1472 };
1473
1474 }
1475
1476 }
1477
1478 #endif