1224133Sdim//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===// 2224133Sdim// 3224133Sdim// The LLVM Compiler Infrastructure 4224133Sdim// 5224133Sdim// This file is distributed under the University of Illinois Open Source 6224133Sdim// License. See LICENSE.TXT for details. 7224133Sdim// 8224133Sdim//===----------------------------------------------------------------------===// 9224133Sdim// 10224133Sdim// This file declares the COFFObjectFile class. 11224133Sdim// 12224133Sdim//===----------------------------------------------------------------------===// 13224133Sdim 14224133Sdim#ifndef LLVM_OBJECT_COFF_H 15224133Sdim#define LLVM_OBJECT_COFF_H 16224133Sdim 17224133Sdim#include "llvm/Object/ObjectFile.h" 18224133Sdim#include "llvm/Support/COFF.h" 19224133Sdim#include "llvm/Support/Endian.h" 20224133Sdim 21224133Sdimnamespace llvm { 22235633Sdim template <typename T> 23235633Sdim class ArrayRef; 24235633Sdim 25224133Sdimnamespace object { 26263509Sdimclass ImportDirectoryEntryRef; 27263509Sdimtypedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator; 28224133Sdim 29263509Sdim/// The DOS compatible header at the front of all PE/COFF executables. 30263509Sdimstruct dos_header { 31263509Sdim support::ulittle16_t Magic; 32263509Sdim support::ulittle16_t UsedBytesInTheLastPage; 33263509Sdim support::ulittle16_t FileSizeInPages; 34263509Sdim support::ulittle16_t NumberOfRelocationItems; 35263509Sdim support::ulittle16_t HeaderSizeInParagraphs; 36263509Sdim support::ulittle16_t MinimumExtraParagraphs; 37263509Sdim support::ulittle16_t MaximumExtraParagraphs; 38263509Sdim support::ulittle16_t InitialRelativeSS; 39263509Sdim support::ulittle16_t InitialSP; 40263509Sdim support::ulittle16_t Checksum; 41263509Sdim support::ulittle16_t InitialIP; 42263509Sdim support::ulittle16_t InitialRelativeCS; 43263509Sdim support::ulittle16_t AddressOfRelocationTable; 44263509Sdim support::ulittle16_t OverlayNumber; 45263509Sdim support::ulittle16_t Reserved[4]; 46263509Sdim support::ulittle16_t OEMid; 47263509Sdim support::ulittle16_t OEMinfo; 48263509Sdim support::ulittle16_t Reserved2[10]; 49263509Sdim support::ulittle32_t AddressOfNewExeHeader; 50263509Sdim}; 51263509Sdim 52224133Sdimstruct coff_file_header { 53224133Sdim support::ulittle16_t Machine; 54224133Sdim support::ulittle16_t NumberOfSections; 55224133Sdim support::ulittle32_t TimeDateStamp; 56224133Sdim support::ulittle32_t PointerToSymbolTable; 57224133Sdim support::ulittle32_t NumberOfSymbols; 58224133Sdim support::ulittle16_t SizeOfOptionalHeader; 59224133Sdim support::ulittle16_t Characteristics; 60263509Sdim 61263509Sdim bool isImportLibrary() const { return NumberOfSections == 0xffff; } 62224133Sdim}; 63224133Sdim 64263509Sdim/// The 32-bit PE header that follows the COFF header. 65263509Sdimstruct pe32_header { 66263509Sdim support::ulittle16_t Magic; 67263509Sdim uint8_t MajorLinkerVersion; 68263509Sdim uint8_t MinorLinkerVersion; 69263509Sdim support::ulittle32_t SizeOfCode; 70263509Sdim support::ulittle32_t SizeOfInitializedData; 71263509Sdim support::ulittle32_t SizeOfUninitializedData; 72263509Sdim support::ulittle32_t AddressOfEntryPoint; 73263509Sdim support::ulittle32_t BaseOfCode; 74263509Sdim support::ulittle32_t BaseOfData; 75263509Sdim support::ulittle32_t ImageBase; 76263509Sdim support::ulittle32_t SectionAlignment; 77263509Sdim support::ulittle32_t FileAlignment; 78263509Sdim support::ulittle16_t MajorOperatingSystemVersion; 79263509Sdim support::ulittle16_t MinorOperatingSystemVersion; 80263509Sdim support::ulittle16_t MajorImageVersion; 81263509Sdim support::ulittle16_t MinorImageVersion; 82263509Sdim support::ulittle16_t MajorSubsystemVersion; 83263509Sdim support::ulittle16_t MinorSubsystemVersion; 84263509Sdim support::ulittle32_t Win32VersionValue; 85263509Sdim support::ulittle32_t SizeOfImage; 86263509Sdim support::ulittle32_t SizeOfHeaders; 87263509Sdim support::ulittle32_t CheckSum; 88263509Sdim support::ulittle16_t Subsystem; 89263509Sdim support::ulittle16_t DLLCharacteristics; 90263509Sdim support::ulittle32_t SizeOfStackReserve; 91263509Sdim support::ulittle32_t SizeOfStackCommit; 92263509Sdim support::ulittle32_t SizeOfHeapReserve; 93263509Sdim support::ulittle32_t SizeOfHeapCommit; 94263509Sdim support::ulittle32_t LoaderFlags; 95263509Sdim support::ulittle32_t NumberOfRvaAndSize; 96263509Sdim}; 97263509Sdim 98263509Sdim/// The 64-bit PE header that follows the COFF header. 99263509Sdimstruct pe32plus_header { 100263509Sdim support::ulittle16_t Magic; 101263509Sdim uint8_t MajorLinkerVersion; 102263509Sdim uint8_t MinorLinkerVersion; 103263509Sdim support::ulittle32_t SizeOfCode; 104263509Sdim support::ulittle32_t SizeOfInitializedData; 105263509Sdim support::ulittle32_t SizeOfUninitializedData; 106263509Sdim support::ulittle32_t AddressOfEntryPoint; 107263509Sdim support::ulittle32_t BaseOfCode; 108263509Sdim support::ulittle64_t ImageBase; 109263509Sdim support::ulittle32_t SectionAlignment; 110263509Sdim support::ulittle32_t FileAlignment; 111263509Sdim support::ulittle16_t MajorOperatingSystemVersion; 112263509Sdim support::ulittle16_t MinorOperatingSystemVersion; 113263509Sdim support::ulittle16_t MajorImageVersion; 114263509Sdim support::ulittle16_t MinorImageVersion; 115263509Sdim support::ulittle16_t MajorSubsystemVersion; 116263509Sdim support::ulittle16_t MinorSubsystemVersion; 117263509Sdim support::ulittle32_t Win32VersionValue; 118263509Sdim support::ulittle32_t SizeOfImage; 119263509Sdim support::ulittle32_t SizeOfHeaders; 120263509Sdim support::ulittle32_t CheckSum; 121263509Sdim support::ulittle16_t Subsystem; 122263509Sdim support::ulittle16_t DLLCharacteristics; 123263509Sdim support::ulittle64_t SizeOfStackReserve; 124263509Sdim support::ulittle64_t SizeOfStackCommit; 125263509Sdim support::ulittle64_t SizeOfHeapReserve; 126263509Sdim support::ulittle64_t SizeOfHeapCommit; 127263509Sdim support::ulittle32_t LoaderFlags; 128263509Sdim support::ulittle32_t NumberOfRvaAndSize; 129263509Sdim}; 130263509Sdim 131263509Sdimstruct data_directory { 132263509Sdim support::ulittle32_t RelativeVirtualAddress; 133263509Sdim support::ulittle32_t Size; 134263509Sdim}; 135263509Sdim 136263509Sdimstruct import_directory_table_entry { 137263509Sdim support::ulittle32_t ImportLookupTableRVA; 138263509Sdim support::ulittle32_t TimeDateStamp; 139263509Sdim support::ulittle32_t ForwarderChain; 140263509Sdim support::ulittle32_t NameRVA; 141263509Sdim support::ulittle32_t ImportAddressTableRVA; 142263509Sdim}; 143263509Sdim 144263509Sdimstruct import_lookup_table_entry32 { 145263509Sdim support::ulittle32_t data; 146263509Sdim 147263509Sdim bool isOrdinal() const { return data & 0x80000000; } 148263509Sdim 149263509Sdim uint16_t getOrdinal() const { 150263509Sdim assert(isOrdinal() && "ILT entry is not an ordinal!"); 151263509Sdim return data & 0xFFFF; 152263509Sdim } 153263509Sdim 154263509Sdim uint32_t getHintNameRVA() const { 155263509Sdim assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); 156263509Sdim return data; 157263509Sdim } 158263509Sdim}; 159263509Sdim 160224133Sdimstruct coff_symbol { 161224133Sdim struct StringTableOffset { 162224133Sdim support::ulittle32_t Zeroes; 163224133Sdim support::ulittle32_t Offset; 164224133Sdim }; 165224133Sdim 166224133Sdim union { 167224133Sdim char ShortName[8]; 168224133Sdim StringTableOffset Offset; 169224133Sdim } Name; 170224133Sdim 171224133Sdim support::ulittle32_t Value; 172224133Sdim support::little16_t SectionNumber; 173224133Sdim 174235633Sdim support::ulittle16_t Type; 175224133Sdim 176224133Sdim support::ulittle8_t StorageClass; 177224133Sdim support::ulittle8_t NumberOfAuxSymbols; 178235633Sdim 179235633Sdim uint8_t getBaseType() const { 180235633Sdim return Type & 0x0F; 181235633Sdim } 182235633Sdim 183235633Sdim uint8_t getComplexType() const { 184235633Sdim return (Type & 0xF0) >> 4; 185235633Sdim } 186224133Sdim}; 187224133Sdim 188224133Sdimstruct coff_section { 189224133Sdim char Name[8]; 190224133Sdim support::ulittle32_t VirtualSize; 191224133Sdim support::ulittle32_t VirtualAddress; 192224133Sdim support::ulittle32_t SizeOfRawData; 193224133Sdim support::ulittle32_t PointerToRawData; 194224133Sdim support::ulittle32_t PointerToRelocations; 195224133Sdim support::ulittle32_t PointerToLinenumbers; 196224133Sdim support::ulittle16_t NumberOfRelocations; 197224133Sdim support::ulittle16_t NumberOfLinenumbers; 198224133Sdim support::ulittle32_t Characteristics; 199224133Sdim}; 200224133Sdim 201226890Sdimstruct coff_relocation { 202226890Sdim support::ulittle32_t VirtualAddress; 203226890Sdim support::ulittle32_t SymbolTableIndex; 204226890Sdim support::ulittle16_t Type; 205226890Sdim}; 206226890Sdim 207263509Sdimstruct coff_aux_weak_external { 208263509Sdim support::ulittle32_t TagIndex; 209263509Sdim support::ulittle32_t Characteristics; 210263509Sdim char Unused[10]; 211263509Sdim}; 212263509Sdim 213235633Sdimstruct coff_aux_section_definition { 214235633Sdim support::ulittle32_t Length; 215235633Sdim support::ulittle16_t NumberOfRelocations; 216235633Sdim support::ulittle16_t NumberOfLinenumbers; 217235633Sdim support::ulittle32_t CheckSum; 218235633Sdim support::ulittle16_t Number; 219235633Sdim support::ulittle8_t Selection; 220235633Sdim char Unused[3]; 221235633Sdim}; 222235633Sdim 223224133Sdimclass COFFObjectFile : public ObjectFile { 224224133Sdimprivate: 225263509Sdim friend class ImportDirectoryEntryRef; 226263509Sdim const coff_file_header *COFFHeader; 227263509Sdim const pe32_header *PE32Header; 228263509Sdim const data_directory *DataDirectory; 229224133Sdim const coff_section *SectionTable; 230224133Sdim const coff_symbol *SymbolTable; 231224133Sdim const char *StringTable; 232224133Sdim uint32_t StringTableSize; 233263509Sdim const import_directory_table_entry *ImportDirectory; 234263509Sdim uint32_t NumberOfImportDirectory; 235224133Sdim 236224133Sdim error_code getString(uint32_t offset, StringRef &Res) const; 237224133Sdim 238224133Sdim const coff_symbol *toSymb(DataRefImpl Symb) const; 239224133Sdim const coff_section *toSec(DataRefImpl Sec) const; 240226890Sdim const coff_relocation *toRel(DataRefImpl Rel) const; 241224133Sdim 242263509Sdim error_code initSymbolTablePtr(); 243263509Sdim error_code initImportTablePtr(); 244263509Sdim 245224133Sdimprotected: 246224133Sdim virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 247224133Sdim virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 248235633Sdim virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 249224133Sdim virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 250224133Sdim virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 251235633Sdim virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 252235633Sdim virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; 253235633Sdim virtual error_code getSymbolSection(DataRefImpl Symb, 254235633Sdim section_iterator &Res) const; 255245431Sdim virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; 256224133Sdim 257224133Sdim virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 258224133Sdim virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 259224133Sdim virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 260224133Sdim virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 261224133Sdim virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 262226890Sdim virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 263224133Sdim virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 264226890Sdim virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 265226890Sdim virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 266235633Sdim virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; 267235633Sdim virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; 268245431Sdim virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; 269235633Sdim virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, 270235633Sdim bool &Res) const; 271224133Sdim virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 272224133Sdim bool &Result) const; 273263509Sdim virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const; 274263509Sdim virtual relocation_iterator section_rel_end(DataRefImpl Sec) const; 275224133Sdim 276226890Sdim virtual error_code getRelocationNext(DataRefImpl Rel, 277226890Sdim RelocationRef &Res) const; 278226890Sdim virtual error_code getRelocationAddress(DataRefImpl Rel, 279226890Sdim uint64_t &Res) const; 280235633Sdim virtual error_code getRelocationOffset(DataRefImpl Rel, 281235633Sdim uint64_t &Res) const; 282263509Sdim virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; 283226890Sdim virtual error_code getRelocationType(DataRefImpl Rel, 284235633Sdim uint64_t &Res) const; 285226890Sdim virtual error_code getRelocationTypeName(DataRefImpl Rel, 286226890Sdim SmallVectorImpl<char> &Result) const; 287226890Sdim virtual error_code getRelocationValueString(DataRefImpl Rel, 288226890Sdim SmallVectorImpl<char> &Result) const; 289226890Sdim 290235633Sdim virtual error_code getLibraryNext(DataRefImpl LibData, 291235633Sdim LibraryRef &Result) const; 292235633Sdim virtual error_code getLibraryPath(DataRefImpl LibData, 293235633Sdim StringRef &Result) const; 294235633Sdim 295224133Sdimpublic: 296224133Sdim COFFObjectFile(MemoryBuffer *Object, error_code &ec); 297224133Sdim virtual symbol_iterator begin_symbols() const; 298224133Sdim virtual symbol_iterator end_symbols() const; 299235633Sdim virtual symbol_iterator begin_dynamic_symbols() const; 300235633Sdim virtual symbol_iterator end_dynamic_symbols() const; 301235633Sdim virtual library_iterator begin_libraries_needed() const; 302235633Sdim virtual library_iterator end_libraries_needed() const; 303224133Sdim virtual section_iterator begin_sections() const; 304224133Sdim virtual section_iterator end_sections() const; 305224133Sdim 306245431Sdim const coff_section *getCOFFSection(section_iterator &It) const; 307245431Sdim const coff_symbol *getCOFFSymbol(symbol_iterator &It) const; 308245431Sdim const coff_relocation *getCOFFRelocation(relocation_iterator &It) const; 309263509Sdim 310224133Sdim virtual uint8_t getBytesInAddress() const; 311224133Sdim virtual StringRef getFileFormatName() const; 312224133Sdim virtual unsigned getArch() const; 313235633Sdim virtual StringRef getLoadName() const; 314235633Sdim 315263509Sdim import_directory_iterator import_directory_begin() const; 316263509Sdim import_directory_iterator import_directory_end() const; 317263509Sdim 318235633Sdim error_code getHeader(const coff_file_header *&Res) const; 319263509Sdim error_code getCOFFHeader(const coff_file_header *&Res) const; 320263509Sdim error_code getPE32Header(const pe32_header *&Res) const; 321263509Sdim error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; 322235633Sdim error_code getSection(int32_t index, const coff_section *&Res) const; 323235633Sdim error_code getSymbol(uint32_t index, const coff_symbol *&Res) const; 324235633Sdim template <typename T> 325235633Sdim error_code getAuxSymbol(uint32_t index, const T *&Res) const { 326235633Sdim const coff_symbol *s; 327235633Sdim error_code ec = getSymbol(index, s); 328235633Sdim Res = reinterpret_cast<const T*>(s); 329235633Sdim return ec; 330235633Sdim } 331235633Sdim error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const; 332245431Sdim ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const; 333245431Sdim 334235633Sdim error_code getSectionName(const coff_section *Sec, StringRef &Res) const; 335235633Sdim error_code getSectionContents(const coff_section *Sec, 336235633Sdim ArrayRef<uint8_t> &Res) const; 337235633Sdim 338263509Sdim error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const; 339263509Sdim error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const; 340263509Sdim 341235633Sdim static inline bool classof(const Binary *v) { 342235633Sdim return v->isCOFF(); 343235633Sdim } 344224133Sdim}; 345224133Sdim 346263509Sdim// The iterator for the import directory table. 347263509Sdimclass ImportDirectoryEntryRef { 348263509Sdimpublic: 349263509Sdim ImportDirectoryEntryRef() : OwningObject(0) {} 350263509Sdim ImportDirectoryEntryRef(DataRefImpl ImportDirectory, 351263509Sdim const COFFObjectFile *Owner) 352263509Sdim : ImportDirectoryPimpl(ImportDirectory), OwningObject(Owner) {} 353224133Sdim 354263509Sdim bool operator==(const ImportDirectoryEntryRef &Other) const; 355263509Sdim error_code getNext(ImportDirectoryEntryRef &Result) const; 356263509Sdim error_code getName(StringRef &Result) const; 357263509Sdim 358263509Sdim error_code 359263509Sdim getImportTableEntry(const import_directory_table_entry *&Result) const; 360263509Sdim 361263509Sdim error_code 362263509Sdim getImportLookupEntry(const import_lookup_table_entry32 *&Result) const; 363263509Sdim 364263509Sdimprivate: 365263509Sdim DataRefImpl ImportDirectoryPimpl; 366263509Sdim const COFFObjectFile *OwningObject; 367263509Sdim}; 368263509Sdim} // end namespace object 369263509Sdim} // end namespace llvm 370263509Sdim 371224133Sdim#endif 372