diff options
Diffstat (limited to 'include/llvm/Object/COFF.h')
-rw-r--r-- | include/llvm/Object/COFF.h | 186 |
1 files changed, 175 insertions, 11 deletions
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 6f42d76ee9960..e05ae6c654c74 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -23,6 +23,31 @@ namespace llvm { class ArrayRef; namespace object { +class ImportDirectoryEntryRef; +typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator; + +/// The DOS compatible header at the front of all PE/COFF executables. +struct dos_header { + support::ulittle16_t Magic; + support::ulittle16_t UsedBytesInTheLastPage; + support::ulittle16_t FileSizeInPages; + support::ulittle16_t NumberOfRelocationItems; + support::ulittle16_t HeaderSizeInParagraphs; + support::ulittle16_t MinimumExtraParagraphs; + support::ulittle16_t MaximumExtraParagraphs; + support::ulittle16_t InitialRelativeSS; + support::ulittle16_t InitialSP; + support::ulittle16_t Checksum; + support::ulittle16_t InitialIP; + support::ulittle16_t InitialRelativeCS; + support::ulittle16_t AddressOfRelocationTable; + support::ulittle16_t OverlayNumber; + support::ulittle16_t Reserved[4]; + support::ulittle16_t OEMid; + support::ulittle16_t OEMinfo; + support::ulittle16_t Reserved2[10]; + support::ulittle32_t AddressOfNewExeHeader; +}; struct coff_file_header { support::ulittle16_t Machine; @@ -32,6 +57,104 @@ struct coff_file_header { support::ulittle32_t NumberOfSymbols; support::ulittle16_t SizeOfOptionalHeader; support::ulittle16_t Characteristics; + + bool isImportLibrary() const { return NumberOfSections == 0xffff; } +}; + +/// The 32-bit PE header that follows the COFF header. +struct pe32_header { + support::ulittle16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + support::ulittle32_t SizeOfCode; + support::ulittle32_t SizeOfInitializedData; + support::ulittle32_t SizeOfUninitializedData; + support::ulittle32_t AddressOfEntryPoint; + support::ulittle32_t BaseOfCode; + support::ulittle32_t BaseOfData; + support::ulittle32_t ImageBase; + support::ulittle32_t SectionAlignment; + support::ulittle32_t FileAlignment; + support::ulittle16_t MajorOperatingSystemVersion; + support::ulittle16_t MinorOperatingSystemVersion; + support::ulittle16_t MajorImageVersion; + support::ulittle16_t MinorImageVersion; + support::ulittle16_t MajorSubsystemVersion; + support::ulittle16_t MinorSubsystemVersion; + support::ulittle32_t Win32VersionValue; + support::ulittle32_t SizeOfImage; + support::ulittle32_t SizeOfHeaders; + support::ulittle32_t CheckSum; + support::ulittle16_t Subsystem; + support::ulittle16_t DLLCharacteristics; + support::ulittle32_t SizeOfStackReserve; + support::ulittle32_t SizeOfStackCommit; + support::ulittle32_t SizeOfHeapReserve; + support::ulittle32_t SizeOfHeapCommit; + support::ulittle32_t LoaderFlags; + support::ulittle32_t NumberOfRvaAndSize; +}; + +/// The 64-bit PE header that follows the COFF header. +struct pe32plus_header { + support::ulittle16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + support::ulittle32_t SizeOfCode; + support::ulittle32_t SizeOfInitializedData; + support::ulittle32_t SizeOfUninitializedData; + support::ulittle32_t AddressOfEntryPoint; + support::ulittle32_t BaseOfCode; + support::ulittle64_t ImageBase; + support::ulittle32_t SectionAlignment; + support::ulittle32_t FileAlignment; + support::ulittle16_t MajorOperatingSystemVersion; + support::ulittle16_t MinorOperatingSystemVersion; + support::ulittle16_t MajorImageVersion; + support::ulittle16_t MinorImageVersion; + support::ulittle16_t MajorSubsystemVersion; + support::ulittle16_t MinorSubsystemVersion; + support::ulittle32_t Win32VersionValue; + support::ulittle32_t SizeOfImage; + support::ulittle32_t SizeOfHeaders; + support::ulittle32_t CheckSum; + support::ulittle16_t Subsystem; + support::ulittle16_t DLLCharacteristics; + support::ulittle64_t SizeOfStackReserve; + support::ulittle64_t SizeOfStackCommit; + support::ulittle64_t SizeOfHeapReserve; + support::ulittle64_t SizeOfHeapCommit; + support::ulittle32_t LoaderFlags; + support::ulittle32_t NumberOfRvaAndSize; +}; + +struct data_directory { + support::ulittle32_t RelativeVirtualAddress; + support::ulittle32_t Size; +}; + +struct 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 import_lookup_table_entry32 { + support::ulittle32_t data; + + bool isOrdinal() const { return data & 0x80000000; } + + uint16_t getOrdinal() const { + assert(isOrdinal() && "ILT entry is not an ordinal!"); + return data & 0xFFFF; + } + + uint32_t getHintNameRVA() const { + assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); + return data; + } }; struct coff_symbol { @@ -81,6 +204,12 @@ struct coff_relocation { support::ulittle16_t Type; }; +struct coff_aux_weak_external { + support::ulittle32_t TagIndex; + support::ulittle32_t Characteristics; + char Unused[10]; +}; + struct coff_aux_section_definition { support::ulittle32_t Length; support::ulittle16_t NumberOfRelocations; @@ -93,11 +222,16 @@ struct coff_aux_section_definition { class COFFObjectFile : public ObjectFile { private: - const coff_file_header *Header; + friend class ImportDirectoryEntryRef; + const coff_file_header *COFFHeader; + const pe32_header *PE32Header; + const data_directory *DataDirectory; const coff_section *SectionTable; const coff_symbol *SymbolTable; const char *StringTable; uint32_t StringTableSize; + const import_directory_table_entry *ImportDirectory; + uint32_t NumberOfImportDirectory; error_code getString(uint32_t offset, StringRef &Res) const; @@ -105,13 +239,15 @@ private: const coff_section *toSec(DataRefImpl Sec) const; const coff_relocation *toRel(DataRefImpl Rel) const; + error_code initSymbolTablePtr(); + error_code initImportTablePtr(); + protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; virtual error_code getSymbolSection(DataRefImpl Symb, @@ -134,8 +270,8 @@ protected: bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; - virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; - virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; + virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const; + virtual relocation_iterator section_rel_end(DataRefImpl Sec) const; virtual error_code getRelocationNext(DataRefImpl Rel, RelocationRef &Res) const; @@ -143,14 +279,11 @@ protected: uint64_t &Res) const; virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const; - virtual error_code getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const; + virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; virtual error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const; - virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const; virtual error_code getRelocationValueString(DataRefImpl Rel, SmallVectorImpl<char> &Result) const; @@ -173,13 +306,19 @@ public: const coff_section *getCOFFSection(section_iterator &It) const; const coff_symbol *getCOFFSymbol(symbol_iterator &It) const; const coff_relocation *getCOFFRelocation(relocation_iterator &It) const; - + virtual uint8_t getBytesInAddress() const; virtual StringRef getFileFormatName() const; virtual unsigned getArch() const; virtual StringRef getLoadName() const; + import_directory_iterator import_directory_begin() const; + import_directory_iterator import_directory_end() const; + error_code getHeader(const coff_file_header *&Res) const; + error_code getCOFFHeader(const coff_file_header *&Res) const; + error_code getPE32Header(const pe32_header *&Res) const; + error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; error_code getSection(int32_t index, const coff_section *&Res) const; error_code getSymbol(uint32_t index, const coff_symbol *&Res) const; template <typename T> @@ -196,12 +335,37 @@ public: error_code getSectionContents(const coff_section *Sec, ArrayRef<uint8_t> &Res) const; + error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const; + error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const; + static inline bool classof(const Binary *v) { return v->isCOFF(); } }; -} -} +// The iterator for the import directory table. +class ImportDirectoryEntryRef { +public: + ImportDirectoryEntryRef() : OwningObject(0) {} + ImportDirectoryEntryRef(DataRefImpl ImportDirectory, + const COFFObjectFile *Owner) + : ImportDirectoryPimpl(ImportDirectory), OwningObject(Owner) {} + + bool operator==(const ImportDirectoryEntryRef &Other) const; + error_code getNext(ImportDirectoryEntryRef &Result) const; + error_code getName(StringRef &Result) const; + + error_code + getImportTableEntry(const import_directory_table_entry *&Result) const; + + error_code + getImportLookupEntry(const import_lookup_table_entry32 *&Result) const; + +private: + DataRefImpl ImportDirectoryPimpl; + const COFFObjectFile *OwningObject; +}; +} // end namespace object +} // end namespace llvm #endif |