X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FCOFF.h;h=025a9dbc6bc0b20b6b820b0e625d9ebfd022a5bd;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=51706b4a180700ecca1238f9fe128d92dc8cf819;hpb=8c6dda0b7d7b79aef402a77c75cf24017e56c33b;p=oota-llvm.git diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 51706b4a180..025a9dbc6bc 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -25,13 +25,20 @@ template class ArrayRef; namespace object { class ImportDirectoryEntryRef; +class DelayImportDirectoryEntryRef; class ExportDirectoryEntryRef; +class ImportedSymbolRef; +class BaseRelocRef; typedef content_iterator import_directory_iterator; +typedef content_iterator + delay_import_directory_iterator; typedef content_iterator export_directory_iterator; +typedef content_iterator imported_symbol_iterator; +typedef content_iterator base_reloc_iterator; /// The DOS compatible header at the front of all PE/COFF executables. struct dos_header { - support::ulittle16_t Magic; + char Magic[2]; support::ulittle16_t UsedBytesInTheLastPage; support::ulittle16_t FileSizeInPages; support::ulittle16_t NumberOfRelocationItems; @@ -105,12 +112,14 @@ struct pe32_header { support::ulittle32_t SizeOfHeaders; support::ulittle32_t CheckSum; support::ulittle16_t Subsystem; + // FIXME: This should be DllCharacteristics. support::ulittle16_t DLLCharacteristics; support::ulittle32_t SizeOfStackReserve; support::ulittle32_t SizeOfStackCommit; support::ulittle32_t SizeOfHeapReserve; support::ulittle32_t SizeOfHeapCommit; support::ulittle32_t LoaderFlags; + // FIXME: This should be NumberOfRvaAndSizes. support::ulittle32_t NumberOfRvaAndSize; }; @@ -160,22 +169,40 @@ struct import_directory_table_entry { support::ulittle32_t ImportAddressTableRVA; }; -struct import_lookup_table_entry32 { - support::ulittle32_t data; +template +struct import_lookup_table_entry { + IntTy Data; - bool isOrdinal() const { return data & 0x80000000; } + bool isOrdinal() const { return Data < 0; } uint16_t getOrdinal() const { assert(isOrdinal() && "ILT entry is not an ordinal!"); - return data & 0xFFFF; + return Data & 0xFFFF; } uint32_t getHintNameRVA() const { assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); - return data; + return Data & 0xFFFFFFFF; } }; +typedef import_lookup_table_entry + import_lookup_table_entry32; +typedef import_lookup_table_entry + import_lookup_table_entry64; + +struct delay_import_directory_table_entry { + // dumpbin reports this field as "Characteristics" instead of "Attributes". + support::ulittle32_t Attributes; + support::ulittle32_t Name; + support::ulittle32_t ModuleHandle; + support::ulittle32_t DelayImportAddressTable; + support::ulittle32_t DelayImportNameTable; + support::ulittle32_t BoundDelayImportTable; + support::ulittle32_t UnloadDelayImportTable; + support::ulittle32_t TimeStamp; +}; + struct export_directory_table_entry { support::ulittle32_t ExportFlags; support::ulittle32_t TimeDateStamp; @@ -215,13 +242,22 @@ struct coff_symbol { support::ulittle16_t Type; - support::ulittle8_t StorageClass; - support::ulittle8_t NumberOfAuxSymbols; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; }; typedef coff_symbol coff_symbol16; typedef coff_symbol coff_symbol32; +// Contains only common parts of coff_symbol16 and coff_symbol32. +struct coff_symbol_generic { + union { + char ShortName[COFF::NameSize]; + StringTableOffset Offset; + } Name; + support::ulittle32_t Value; +}; + class COFFSymbolRef { public: COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {} @@ -232,21 +268,37 @@ public: return CS16 ? static_cast(CS16) : CS32; } + const coff_symbol_generic *getGeneric() const { + if (CS16) + return reinterpret_cast(CS16); + return reinterpret_cast(CS32); + } + friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) { return A.getRawPtr() < B.getRawPtr(); } + bool isBigObj() const { + if (CS16) + return false; + if (CS32) + return true; + llvm_unreachable("COFFSymbolRef points to nothing!"); + } + const char *getShortName() const { return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName; } const StringTableOffset &getStringTableOffset() const { + assert(isSet() && "COFFSymbolRef points to nothing!"); return CS16 ? CS16->Name.Offset : CS32->Name.Offset; } uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; } int32_t getSectionNumber() const { + assert(isSet() && "COFFSymbolRef points to nothing!"); if (CS16) { // Reserved sections are returned as negative numbers. if (CS16->SectionNumber <= COFF::MaxNumberOfSections16) @@ -256,23 +308,51 @@ public: return static_cast(CS32->SectionNumber); } - uint16_t getType() const { return CS16 ? CS16->Type : CS32->Type; } + uint16_t getType() const { + assert(isSet() && "COFFSymbolRef points to nothing!"); + return CS16 ? CS16->Type : CS32->Type; + } uint8_t getStorageClass() const { + assert(isSet() && "COFFSymbolRef points to nothing!"); return CS16 ? CS16->StorageClass : CS32->StorageClass; } uint8_t getNumberOfAuxSymbols() const { + assert(isSet() && "COFFSymbolRef points to nothing!"); return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols; } uint8_t getBaseType() const { return getType() & 0x0F; } - uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; } + uint8_t getComplexType() const { + return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT; + } + + bool isAbsolute() const { + return getSectionNumber() == -1; + } + + bool isExternal() const { + return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL; + } + + bool isCommon() const { + return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && + getValue() != 0; + } + + bool isUndefined() const { + return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && + getValue() == 0; + } + + bool isWeakExternal() const { + return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; + } bool isFunctionDefinition() const { - return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && - getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && + return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION && !COFF::isReservedSectionNumber(getSectionNumber()); } @@ -281,24 +361,27 @@ public: return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION; } - bool isWeakExternal() const { - return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || - (getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && - getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && getValue() == 0); + bool isAnyUndefined() const { + return isUndefined() || isWeakExternal(); } bool isFileRecord() const { return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE; } + bool isSection() const { + return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION; + } + bool isSectionDefinition() const { // C++/CLI creates external ABS symbols for non-const appdomain globals. // These are also followed by an auxiliary section definition. bool isAppdomainGlobal = getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE; - bool isOrdinarySection = - getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC && getValue() == 0; + bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC; + if (!getNumberOfAuxSymbols()) + return false; return isAppdomainGlobal || isOrdinarySection; } @@ -307,6 +390,8 @@ public: } private: + bool isSet() const { return CS16 || CS32; } + const coff_symbol16 *CS16; const coff_symbol32 *CS32; }; @@ -326,9 +411,9 @@ struct coff_section { // Returns true if the actual number of relocations is stored in // VirtualAddress field of the first relocation table entry. bool hasExtendedRelocations() const { - return Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL && - NumberOfRelocations == UINT16_MAX; - }; + return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) && + NumberOfRelocations == UINT16_MAX; + } }; struct coff_relocation { @@ -361,16 +446,45 @@ struct coff_aux_section_definition { support::ulittle16_t NumberOfRelocations; support::ulittle16_t NumberOfLinenumbers; support::ulittle32_t CheckSum; - support::ulittle16_t Number; - support::ulittle8_t Selection; + support::ulittle16_t NumberLowPart; + uint8_t Selection; + uint8_t Unused; + support::ulittle16_t NumberHighPart; + int32_t getNumber(bool IsBigObj) const { + uint32_t Number = static_cast(NumberLowPart); + if (IsBigObj) + Number |= static_cast(NumberHighPart) << 16; + return static_cast(Number); + } }; struct coff_aux_clr_token { - support::ulittle8_t AuxType; - support::ulittle8_t Reserved; + uint8_t AuxType; + uint8_t Reserved; support::ulittle32_t SymbolTableIndex; }; +struct coff_import_header { + support::ulittle16_t Sig1; + support::ulittle16_t Sig2; + support::ulittle16_t Version; + support::ulittle16_t Machine; + support::ulittle32_t TimeDateStamp; + support::ulittle32_t SizeOfData; + support::ulittle16_t OrdinalHint; + support::ulittle16_t TypeInfo; + int getType() const { return TypeInfo & 0x3; } + int getNameType() const { return (TypeInfo >> 2) & 0x7; } +}; + +struct coff_import_directory_table_entry { + support::ulittle32_t ImportLookupTableRVA; + support::ulittle32_t TimeDateStamp; + support::ulittle32_t ForwarderChain; + support::ulittle32_t NameRVA; + support::ulittle32_t ImportAddressTableRVA; +}; + struct coff_load_configuration32 { support::ulittle32_t Characteristics; support::ulittle32_t TimeDateStamp; @@ -394,12 +508,46 @@ struct coff_load_configuration32 { support::ulittle32_t SEHandlerCount; }; +struct coff_load_configuration64 { + support::ulittle32_t Characteristics; + support::ulittle32_t TimeDateStamp; + support::ulittle16_t MajorVersion; + support::ulittle16_t MinorVersion; + support::ulittle32_t GlobalFlagsClear; + support::ulittle32_t GlobalFlagsSet; + support::ulittle32_t CriticalSectionDefaultTimeout; + support::ulittle32_t DeCommitFreeBlockThreshold; + support::ulittle32_t DeCommitTotalFreeThreshold; + support::ulittle32_t LockPrefixTable; + support::ulittle32_t MaximumAllocationSize; + support::ulittle32_t VirtualMemoryThreshold; + support::ulittle32_t ProcessAffinityMask; + support::ulittle32_t ProcessHeapFlags; + support::ulittle16_t CSDVersion; + support::ulittle16_t Reserved; + support::ulittle32_t EditList; + support::ulittle64_t SecurityCookie; + support::ulittle64_t SEHandlerTable; + support::ulittle64_t SEHandlerCount; +}; + struct coff_runtime_function_x64 { support::ulittle32_t BeginAddress; support::ulittle32_t EndAddress; support::ulittle32_t UnwindInformation; }; +struct coff_base_reloc_block_header { + support::ulittle32_t PageRVA; + support::ulittle32_t BlockSize; +}; + +struct coff_base_reloc_block_entry { + support::ulittle16_t Data; + int getType() const { return Data >> 12; } + int getOffset() const { return Data & ((1 << 12) - 1); } +}; + class COFFObjectFile : public ObjectFile { private: friend class ImportDirectoryEntryRef; @@ -416,7 +564,11 @@ private: uint32_t StringTableSize; const import_directory_table_entry *ImportDirectory; uint32_t NumberOfImportDirectory; + const delay_import_directory_table_entry *DelayImportDirectory; + uint32_t NumberOfDelayImportDirectory; const export_directory_table_entry *ExportDirectory; + const coff_base_reloc_block_header *BaseRelocHeader; + const coff_base_reloc_block_header *BaseRelocEnd; std::error_code getString(uint32_t offset, StringRef &Res) const; @@ -427,7 +579,9 @@ private: std::error_code initSymbolTablePtr(); std::error_code initImportTablePtr(); + std::error_code initDelayImportTablePtr(); std::error_code initExportTablePtr(); + std::error_code initBaseRelocPtr(); public: uintptr_t getSymbolTable() const { @@ -446,7 +600,8 @@ public: } uint16_t getSizeOfOptionalHeader() const { if (COFFHeader) - return COFFHeader->SizeOfOptionalHeader; + return COFFHeader->isImportLibrary() ? 0 + : COFFHeader->SizeOfOptionalHeader; // bigobj doesn't have this field. if (COFFBigObjHeader) return 0; @@ -454,7 +609,7 @@ public: } uint16_t getCharacteristics() const { if (COFFHeader) - return COFFHeader->Characteristics; + return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics; // bigobj doesn't have characteristics to speak of, // editbin will silently lie to you if you attempt to set any. if (COFFBigObjHeader) @@ -470,75 +625,57 @@ public: } uint32_t getNumberOfSections() const { if (COFFHeader) - return COFFHeader->NumberOfSections; + return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections; if (COFFBigObjHeader) return COFFBigObjHeader->NumberOfSections; llvm_unreachable("no COFF header!"); } uint32_t getPointerToSymbolTable() const { if (COFFHeader) - return COFFHeader->PointerToSymbolTable; + return COFFHeader->isImportLibrary() ? 0 + : COFFHeader->PointerToSymbolTable; if (COFFBigObjHeader) return COFFBigObjHeader->PointerToSymbolTable; llvm_unreachable("no COFF header!"); } uint32_t getNumberOfSymbols() const { if (COFFHeader) - return COFFHeader->NumberOfSymbols; + return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols; if (COFFBigObjHeader) return COFFBigObjHeader->NumberOfSymbols; llvm_unreachable("no COFF header!"); } protected: void moveSymbolNext(DataRefImpl &Symb) const override; - std::error_code getSymbolName(DataRefImpl Symb, - StringRef &Res) const override; - std::error_code getSymbolAddress(DataRefImpl Symb, - uint64_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + ErrorOr getSymbolName(DataRefImpl Symb) const override; + ErrorOr getSymbolAddress(DataRefImpl Symb) const override; + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; - std::error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const override; + SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; void moveSectionNext(DataRefImpl &Sec) const override; std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; - std::error_code getSectionAddress(DataRefImpl Sec, - uint64_t &Res) const override; - std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; + uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionSize(DataRefImpl Sec) const override; std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; - std::error_code getSectionAlignment(DataRefImpl Sec, - uint64_t &Res) const override; - std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionReadOnlyData(DataRefImpl Sec, - bool &Res) const override; - std::error_code isSectionRequiredForExecution(DataRefImpl Sec, - bool &Res) const override; - std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, - bool &Result) const override; + uint64_t getSectionAlignment(DataRefImpl Sec) const override; + bool isSectionText(DataRefImpl Sec) const override; + bool isSectionData(DataRefImpl Sec) const override; + bool isSectionBSS(DataRefImpl Sec) const override; + bool isSectionVirtual(DataRefImpl Sec) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - std::error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; - std::error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code - getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const override; public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); @@ -551,6 +688,8 @@ public: COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const; COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const; const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const; + unsigned getSectionID(SectionRef Sec) const; + unsigned getSymbolSectionID(SymbolRef Sym) const; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -558,9 +697,24 @@ public: import_directory_iterator import_directory_begin() const; import_directory_iterator import_directory_end() const; + delay_import_directory_iterator delay_import_directory_begin() const; + delay_import_directory_iterator delay_import_directory_end() const; export_directory_iterator export_directory_begin() const; export_directory_iterator export_directory_end() const; - + base_reloc_iterator base_reloc_begin() const; + base_reloc_iterator base_reloc_end() const; + + iterator_range import_directories() const; + iterator_range + delay_import_directories() const; + iterator_range export_directories() const; + iterator_range base_relocs() const; + + const dos_header *getDOSHeader() const { + if (!PE32Header && !PE32PlusHeader) + return nullptr; + return reinterpret_cast(base()); + } std::error_code getPE32Header(const pe32_header *&Res) const; std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const; std::error_code getDataDirectory(uint32_t index, @@ -569,11 +723,11 @@ public: template std::error_code getSymbol(uint32_t Index, const coff_symbol_type *&Res) const { - if (Index < getNumberOfSymbols()) - Res = reinterpret_cast(getSymbolTable()) + Index; - else + if (Index >= getNumberOfSymbols()) return object_error::parse_failed; - return object_error::success; + + Res = reinterpret_cast(getSymbolTable()) + Index; + return std::error_code(); } ErrorOr getSymbol(uint32_t index) const { if (SymbolTable16) { @@ -588,7 +742,7 @@ public: return EC; return COFFSymbolRef(Symb); } - llvm_unreachable("no symbol table pointer!"); + return object_error::parse_failed; } template std::error_code getAuxSymbol(uint32_t index, const T *&Res) const { @@ -596,9 +750,11 @@ public: if (std::error_code EC = s.getError()) return EC; Res = reinterpret_cast(s->getRawPtr()); - return object_error::success; + return std::error_code(); } std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; + std::error_code getSymbolName(const coff_symbol_generic *Symbol, + StringRef &Res) const; ArrayRef getSymbolAuxData(COFFSymbolRef Symbol) const; @@ -610,7 +766,11 @@ public: llvm_unreachable("null symbol table pointer!"); } + iterator_range + getRelocations(const coff_section *Sec) const; + std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const; + uint64_t getSectionSize(const coff_section *Sec) const; std::error_code getSectionContents(const coff_section *Sec, ArrayRef &Res) const; @@ -620,6 +780,7 @@ public: StringRef &Name) const; bool isRelocatableObject() const override; + bool is64() const { return PE32PlusHeader; } static inline bool classof(const Binary *v) { return v->isCOFF(); } }; @@ -634,7 +795,14 @@ public: bool operator==(const ImportDirectoryEntryRef &Other) const; void moveNext(); + + imported_symbol_iterator imported_symbol_begin() const; + imported_symbol_iterator imported_symbol_end() const; + iterator_range imported_symbols() const; + std::error_code getName(StringRef &Result) const; + std::error_code getImportLookupTableRVA(uint32_t &Result) const; + std::error_code getImportAddressTableRVA(uint32_t &Result) const; std::error_code getImportTableEntry(const import_directory_table_entry *&Result) const; @@ -648,6 +816,31 @@ private: const COFFObjectFile *OwningObject; }; +class DelayImportDirectoryEntryRef { +public: + DelayImportDirectoryEntryRef() : OwningObject(nullptr) {} + DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T, + uint32_t I, const COFFObjectFile *Owner) + : Table(T), Index(I), OwningObject(Owner) {} + + bool operator==(const DelayImportDirectoryEntryRef &Other) const; + void moveNext(); + + imported_symbol_iterator imported_symbol_begin() const; + imported_symbol_iterator imported_symbol_end() const; + iterator_range imported_symbols() const; + + std::error_code getName(StringRef &Result) const; + std::error_code getDelayImportTable( + const delay_import_directory_table_entry *&Result) const; + std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const; + +private: + const delay_import_directory_table_entry *Table; + uint32_t Index; + const COFFObjectFile *OwningObject; +}; + // The iterator for the export directory table entry. class ExportDirectoryEntryRef { public: @@ -670,6 +863,49 @@ private: uint32_t Index; const COFFObjectFile *OwningObject; }; + +class ImportedSymbolRef { +public: + ImportedSymbolRef() : OwningObject(nullptr) {} + ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I, + const COFFObjectFile *Owner) + : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {} + ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I, + const COFFObjectFile *Owner) + : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {} + + bool operator==(const ImportedSymbolRef &Other) const; + void moveNext(); + + std::error_code getSymbolName(StringRef &Result) const; + std::error_code getOrdinal(uint16_t &Result) const; + +private: + const import_lookup_table_entry32 *Entry32; + const import_lookup_table_entry64 *Entry64; + uint32_t Index; + const COFFObjectFile *OwningObject; +}; + +class BaseRelocRef { +public: + BaseRelocRef() : OwningObject(nullptr) {} + BaseRelocRef(const coff_base_reloc_block_header *Header, + const COFFObjectFile *Owner) + : Header(Header), Index(0), OwningObject(Owner) {} + + bool operator==(const BaseRelocRef &Other) const; + void moveNext(); + + std::error_code getType(uint8_t &Type) const; + std::error_code getRVA(uint32_t &Result) const; + +private: + const coff_base_reloc_block_header *Header; + uint32_t Index; + const COFFObjectFile *OwningObject; +}; + } // end namespace object } // end namespace llvm