Home | History | Annotate | Download | only in Object
      1 //===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares the COFFObjectFile class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_OBJECT_COFF_H
     15 #define LLVM_OBJECT_COFF_H
     16 
     17 #include "llvm/Object/ObjectFile.h"
     18 #include "llvm/Support/COFF.h"
     19 #include "llvm/Support/Endian.h"
     20 
     21 namespace llvm {
     22   template <typename T>
     23   class ArrayRef;
     24 
     25 namespace object {
     26 
     27 /// The DOS compatible header at the front of all PE/COFF executables.
     28 struct dos_header {
     29   support::ulittle16_t Magic;
     30   support::ulittle16_t UsedBytesInTheLastPage;
     31   support::ulittle16_t FileSizeInPages;
     32   support::ulittle16_t NumberOfRelocationItems;
     33   support::ulittle16_t HeaderSizeInParagraphs;
     34   support::ulittle16_t MinimumExtraParagraphs;
     35   support::ulittle16_t MaximumExtraParagraphs;
     36   support::ulittle16_t InitialRelativeSS;
     37   support::ulittle16_t InitialSP;
     38   support::ulittle16_t Checksum;
     39   support::ulittle16_t InitialIP;
     40   support::ulittle16_t InitialRelativeCS;
     41   support::ulittle16_t AddressOfRelocationTable;
     42   support::ulittle16_t OverlayNumber;
     43   support::ulittle16_t Reserved[4];
     44   support::ulittle16_t OEMid;
     45   support::ulittle16_t OEMinfo;
     46   support::ulittle16_t Reserved2[10];
     47   support::ulittle32_t AddressOfNewExeHeader;
     48 };
     49 
     50 struct coff_file_header {
     51   support::ulittle16_t Machine;
     52   support::ulittle16_t NumberOfSections;
     53   support::ulittle32_t TimeDateStamp;
     54   support::ulittle32_t PointerToSymbolTable;
     55   support::ulittle32_t NumberOfSymbols;
     56   support::ulittle16_t SizeOfOptionalHeader;
     57   support::ulittle16_t Characteristics;
     58 };
     59 
     60 /// The 32-bit PE header that follows the COFF header.
     61 struct pe32_header {
     62   support::ulittle16_t Magic;
     63   uint8_t  MajorLinkerVersion;
     64   uint8_t  MinorLinkerVersion;
     65   support::ulittle32_t SizeOfCode;
     66   support::ulittle32_t SizeOfInitializedData;
     67   support::ulittle32_t SizeOfUninitializedData;
     68   support::ulittle32_t AddressOfEntryPoint;
     69   support::ulittle32_t BaseOfCode;
     70   support::ulittle32_t BaseOfData;
     71   support::ulittle32_t ImageBase;
     72   support::ulittle32_t SectionAlignment;
     73   support::ulittle32_t FileAlignment;
     74   support::ulittle16_t MajorOperatingSystemVersion;
     75   support::ulittle16_t MinorOperatingSystemVersion;
     76   support::ulittle16_t MajorImageVersion;
     77   support::ulittle16_t MinorImageVersion;
     78   support::ulittle16_t MajorSubsystemVersion;
     79   support::ulittle16_t MinorSubsystemVersion;
     80   support::ulittle32_t Win32VersionValue;
     81   support::ulittle32_t SizeOfImage;
     82   support::ulittle32_t SizeOfHeaders;
     83   support::ulittle32_t CheckSum;
     84   support::ulittle16_t Subsystem;
     85   support::ulittle16_t DLLCharacteristics;
     86   support::ulittle32_t SizeOfStackReserve;
     87   support::ulittle32_t SizeOfStackCommit;
     88   support::ulittle32_t SizeOfHeapReserve;
     89   support::ulittle32_t SizeOfHeapCommit;
     90   support::ulittle32_t LoaderFlags;
     91   support::ulittle32_t NumberOfRvaAndSize;
     92 };
     93 
     94 /// The 64-bit PE header that follows the COFF header.
     95 struct pe32plus_header {
     96   support::ulittle16_t Magic;
     97   uint8_t  MajorLinkerVersion;
     98   uint8_t  MinorLinkerVersion;
     99   support::ulittle32_t SizeOfCode;
    100   support::ulittle32_t SizeOfInitializedData;
    101   support::ulittle32_t SizeOfUninitializedData;
    102   support::ulittle32_t AddressOfEntryPoint;
    103   support::ulittle32_t BaseOfCode;
    104   support::ulittle64_t ImageBase;
    105   support::ulittle32_t SectionAlignment;
    106   support::ulittle32_t FileAlignment;
    107   support::ulittle16_t MajorOperatingSystemVersion;
    108   support::ulittle16_t MinorOperatingSystemVersion;
    109   support::ulittle16_t MajorImageVersion;
    110   support::ulittle16_t MinorImageVersion;
    111   support::ulittle16_t MajorSubsystemVersion;
    112   support::ulittle16_t MinorSubsystemVersion;
    113   support::ulittle32_t Win32VersionValue;
    114   support::ulittle32_t SizeOfImage;
    115   support::ulittle32_t SizeOfHeaders;
    116   support::ulittle32_t CheckSum;
    117   support::ulittle16_t Subsystem;
    118   support::ulittle16_t DLLCharacteristics;
    119   support::ulittle64_t SizeOfStackReserve;
    120   support::ulittle64_t SizeOfStackCommit;
    121   support::ulittle64_t SizeOfHeapReserve;
    122   support::ulittle64_t SizeOfHeapCommit;
    123   support::ulittle32_t LoaderFlags;
    124   support::ulittle32_t NumberOfRvaAndSize;
    125 };
    126 
    127 struct data_directory {
    128   support::ulittle32_t RelativeVirtualAddress;
    129   support::ulittle32_t Size;
    130 };
    131 
    132 struct import_directory_table_entry {
    133   support::ulittle32_t ImportLookupTableRVA;
    134   support::ulittle32_t TimeDateStamp;
    135   support::ulittle32_t ForwarderChain;
    136   support::ulittle32_t NameRVA;
    137   support::ulittle32_t ImportAddressTableRVA;
    138 };
    139 
    140 struct coff_symbol {
    141   struct StringTableOffset {
    142     support::ulittle32_t Zeroes;
    143     support::ulittle32_t Offset;
    144   };
    145 
    146   union {
    147     char ShortName[8];
    148     StringTableOffset Offset;
    149   } Name;
    150 
    151   support::ulittle32_t Value;
    152   support::little16_t SectionNumber;
    153 
    154   support::ulittle16_t Type;
    155 
    156   support::ulittle8_t  StorageClass;
    157   support::ulittle8_t  NumberOfAuxSymbols;
    158 
    159   uint8_t getBaseType() const {
    160     return Type & 0x0F;
    161   }
    162 
    163   uint8_t getComplexType() const {
    164     return (Type & 0xF0) >> 4;
    165   }
    166 };
    167 
    168 struct coff_section {
    169   char Name[8];
    170   support::ulittle32_t VirtualSize;
    171   support::ulittle32_t VirtualAddress;
    172   support::ulittle32_t SizeOfRawData;
    173   support::ulittle32_t PointerToRawData;
    174   support::ulittle32_t PointerToRelocations;
    175   support::ulittle32_t PointerToLinenumbers;
    176   support::ulittle16_t NumberOfRelocations;
    177   support::ulittle16_t NumberOfLinenumbers;
    178   support::ulittle32_t Characteristics;
    179 };
    180 
    181 struct coff_relocation {
    182   support::ulittle32_t VirtualAddress;
    183   support::ulittle32_t SymbolTableIndex;
    184   support::ulittle16_t Type;
    185 };
    186 
    187 struct coff_aux_section_definition {
    188   support::ulittle32_t Length;
    189   support::ulittle16_t NumberOfRelocations;
    190   support::ulittle16_t NumberOfLinenumbers;
    191   support::ulittle32_t CheckSum;
    192   support::ulittle16_t Number;
    193   support::ulittle8_t Selection;
    194   char Unused[3];
    195 };
    196 
    197 class COFFObjectFile : public ObjectFile {
    198 private:
    199   const coff_file_header *COFFHeader;
    200   const pe32_header      *PE32Header;
    201   const data_directory   *DataDirectory;
    202   const coff_section     *SectionTable;
    203   const coff_symbol      *SymbolTable;
    204   const char             *StringTable;
    205         uint32_t          StringTableSize;
    206 
    207         error_code        getString(uint32_t offset, StringRef &Res) const;
    208 
    209   const coff_symbol      *toSymb(DataRefImpl Symb) const;
    210   const coff_section     *toSec(DataRefImpl Sec) const;
    211   const coff_relocation  *toRel(DataRefImpl Rel) const;
    212 
    213 protected:
    214   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
    215   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
    216   virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
    217   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
    218   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
    219   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
    220   virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
    221   virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
    222   virtual error_code getSymbolSection(DataRefImpl Symb,
    223                                       section_iterator &Res) const;
    224   virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
    225 
    226   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
    227   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
    228   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
    229   virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
    230   virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
    231   virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
    232   virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
    233   virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
    234   virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
    235   virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
    236   virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
    237   virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
    238   virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
    239                                                    bool &Res) const;
    240   virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
    241                                            bool &Result) const;
    242   virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
    243   virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
    244 
    245   virtual error_code getRelocationNext(DataRefImpl Rel,
    246                                        RelocationRef &Res) const;
    247   virtual error_code getRelocationAddress(DataRefImpl Rel,
    248                                           uint64_t &Res) const;
    249   virtual error_code getRelocationOffset(DataRefImpl Rel,
    250                                          uint64_t &Res) const;
    251   virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
    252   virtual error_code getRelocationType(DataRefImpl Rel,
    253                                        uint64_t &Res) const;
    254   virtual error_code getRelocationTypeName(DataRefImpl Rel,
    255                                            SmallVectorImpl<char> &Result) const;
    256   virtual error_code getRelocationValueString(DataRefImpl Rel,
    257                                            SmallVectorImpl<char> &Result) const;
    258 
    259   virtual error_code getLibraryNext(DataRefImpl LibData,
    260                                     LibraryRef &Result) const;
    261   virtual error_code getLibraryPath(DataRefImpl LibData,
    262                                     StringRef &Result) const;
    263 
    264 public:
    265   COFFObjectFile(MemoryBuffer *Object, error_code &ec);
    266   virtual symbol_iterator begin_symbols() const;
    267   virtual symbol_iterator end_symbols() const;
    268   virtual symbol_iterator begin_dynamic_symbols() const;
    269   virtual symbol_iterator end_dynamic_symbols() const;
    270   virtual library_iterator begin_libraries_needed() const;
    271   virtual library_iterator end_libraries_needed() const;
    272   virtual section_iterator begin_sections() const;
    273   virtual section_iterator end_sections() const;
    274 
    275   const coff_section *getCOFFSection(section_iterator &It) const;
    276   const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
    277   const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
    278 
    279   virtual uint8_t getBytesInAddress() const;
    280   virtual StringRef getFileFormatName() const;
    281   virtual unsigned getArch() const;
    282   virtual StringRef getLoadName() const;
    283 
    284   error_code getHeader(const coff_file_header *&Res) const;
    285   error_code getCOFFHeader(const coff_file_header *&Res) const;
    286   error_code getPE32Header(const pe32_header *&Res) const;
    287   error_code getDataDirectory(uint32_t index, const data_directory *&Res) const;
    288   error_code getSection(int32_t index, const coff_section *&Res) const;
    289   error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
    290   template <typename T>
    291   error_code getAuxSymbol(uint32_t index, const T *&Res) const {
    292     const coff_symbol *s;
    293     error_code ec = getSymbol(index, s);
    294     Res = reinterpret_cast<const T*>(s);
    295     return ec;
    296   }
    297   error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
    298   ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
    299 
    300   error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
    301   error_code getSectionContents(const coff_section *Sec,
    302                                 ArrayRef<uint8_t> &Res) const;
    303 
    304   static inline bool classof(const Binary *v) {
    305     return v->isCOFF();
    306   }
    307 };
    308 
    309 }
    310 }
    311 
    312 #endif
    313