LLVM API Documentation

Object/COFF.h
Go to the documentation of this file.
00001 //===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file declares the COFFObjectFile class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_OBJECT_COFF_H
00015 #define LLVM_OBJECT_COFF_H
00016 
00017 #include "llvm/Object/ObjectFile.h"
00018 #include "llvm/Support/COFF.h"
00019 #include "llvm/Support/Endian.h"
00020 
00021 namespace llvm {
00022   template <typename T>
00023   class ArrayRef;
00024 
00025 namespace object {
00026 
00027 /// The DOS compatible header at the front of all PE/COFF executables.
00028 struct dos_header {
00029   support::ulittle16_t Magic;
00030   support::ulittle16_t UsedBytesInTheLastPage;
00031   support::ulittle16_t FileSizeInPages;
00032   support::ulittle16_t NumberOfRelocationItems;
00033   support::ulittle16_t HeaderSizeInParagraphs;
00034   support::ulittle16_t MinimumExtraParagraphs;
00035   support::ulittle16_t MaximumExtraParagraphs;
00036   support::ulittle16_t InitialRelativeSS;
00037   support::ulittle16_t InitialSP;
00038   support::ulittle16_t Checksum;
00039   support::ulittle16_t InitialIP;
00040   support::ulittle16_t InitialRelativeCS;
00041   support::ulittle16_t AddressOfRelocationTable;
00042   support::ulittle16_t OverlayNumber;
00043   support::ulittle16_t Reserved[4];
00044   support::ulittle16_t OEMid;
00045   support::ulittle16_t OEMinfo;
00046   support::ulittle16_t Reserved2[10];
00047   support::ulittle32_t AddressOfNewExeHeader;
00048 };
00049 
00050 struct coff_file_header {
00051   support::ulittle16_t Machine;
00052   support::ulittle16_t NumberOfSections;
00053   support::ulittle32_t TimeDateStamp;
00054   support::ulittle32_t PointerToSymbolTable;
00055   support::ulittle32_t NumberOfSymbols;
00056   support::ulittle16_t SizeOfOptionalHeader;
00057   support::ulittle16_t Characteristics;
00058 };
00059 
00060 /// The 32-bit PE header that follows the COFF header.
00061 struct pe32_header {
00062   support::ulittle16_t Magic;
00063   uint8_t  MajorLinkerVersion;
00064   uint8_t  MinorLinkerVersion;
00065   support::ulittle32_t SizeOfCode;
00066   support::ulittle32_t SizeOfInitializedData;
00067   support::ulittle32_t SizeOfUninitializedData;
00068   support::ulittle32_t AddressOfEntryPoint;
00069   support::ulittle32_t BaseOfCode;
00070   support::ulittle32_t BaseOfData;
00071   support::ulittle32_t ImageBase;
00072   support::ulittle32_t SectionAlignment;
00073   support::ulittle32_t FileAlignment;
00074   support::ulittle16_t MajorOperatingSystemVersion;
00075   support::ulittle16_t MinorOperatingSystemVersion;
00076   support::ulittle16_t MajorImageVersion;
00077   support::ulittle16_t MinorImageVersion;
00078   support::ulittle16_t MajorSubsystemVersion;
00079   support::ulittle16_t MinorSubsystemVersion;
00080   support::ulittle32_t Win32VersionValue;
00081   support::ulittle32_t SizeOfImage;
00082   support::ulittle32_t SizeOfHeaders;
00083   support::ulittle32_t CheckSum;
00084   support::ulittle16_t Subsystem;
00085   support::ulittle16_t DLLCharacteristics;
00086   support::ulittle32_t SizeOfStackReserve;
00087   support::ulittle32_t SizeOfStackCommit;
00088   support::ulittle32_t SizeOfHeapReserve;
00089   support::ulittle32_t SizeOfHeapCommit;
00090   support::ulittle32_t LoaderFlags;
00091   support::ulittle32_t NumberOfRvaAndSize;
00092 };
00093 
00094 /// The 64-bit PE header that follows the COFF header.
00095 struct pe32plus_header {
00096   support::ulittle16_t Magic;
00097   uint8_t  MajorLinkerVersion;
00098   uint8_t  MinorLinkerVersion;
00099   support::ulittle32_t SizeOfCode;
00100   support::ulittle32_t SizeOfInitializedData;
00101   support::ulittle32_t SizeOfUninitializedData;
00102   support::ulittle32_t AddressOfEntryPoint;
00103   support::ulittle32_t BaseOfCode;
00104   support::ulittle64_t ImageBase;
00105   support::ulittle32_t SectionAlignment;
00106   support::ulittle32_t FileAlignment;
00107   support::ulittle16_t MajorOperatingSystemVersion;
00108   support::ulittle16_t MinorOperatingSystemVersion;
00109   support::ulittle16_t MajorImageVersion;
00110   support::ulittle16_t MinorImageVersion;
00111   support::ulittle16_t MajorSubsystemVersion;
00112   support::ulittle16_t MinorSubsystemVersion;
00113   support::ulittle32_t Win32VersionValue;
00114   support::ulittle32_t SizeOfImage;
00115   support::ulittle32_t SizeOfHeaders;
00116   support::ulittle32_t CheckSum;
00117   support::ulittle16_t Subsystem;
00118   support::ulittle16_t DLLCharacteristics;
00119   support::ulittle64_t SizeOfStackReserve;
00120   support::ulittle64_t SizeOfStackCommit;
00121   support::ulittle64_t SizeOfHeapReserve;
00122   support::ulittle64_t SizeOfHeapCommit;
00123   support::ulittle32_t LoaderFlags;
00124   support::ulittle32_t NumberOfRvaAndSize;
00125 };
00126 
00127 struct data_directory {
00128   support::ulittle32_t RelativeVirtualAddress;
00129   support::ulittle32_t Size;
00130 };
00131 
00132 struct coff_symbol {
00133   struct StringTableOffset {
00134     support::ulittle32_t Zeroes;
00135     support::ulittle32_t Offset;
00136   };
00137 
00138   union {
00139     char ShortName[8];
00140     StringTableOffset Offset;
00141   } Name;
00142 
00143   support::ulittle32_t Value;
00144   support::little16_t SectionNumber;
00145 
00146   support::ulittle16_t Type;
00147 
00148   support::ulittle8_t  StorageClass;
00149   support::ulittle8_t  NumberOfAuxSymbols;
00150 
00151   uint8_t getBaseType() const {
00152     return Type & 0x0F;
00153   }
00154 
00155   uint8_t getComplexType() const {
00156     return (Type & 0xF0) >> 4;
00157   }
00158 };
00159 
00160 struct coff_section {
00161   char Name[8];
00162   support::ulittle32_t VirtualSize;
00163   support::ulittle32_t VirtualAddress;
00164   support::ulittle32_t SizeOfRawData;
00165   support::ulittle32_t PointerToRawData;
00166   support::ulittle32_t PointerToRelocations;
00167   support::ulittle32_t PointerToLinenumbers;
00168   support::ulittle16_t NumberOfRelocations;
00169   support::ulittle16_t NumberOfLinenumbers;
00170   support::ulittle32_t Characteristics;
00171 };
00172 
00173 struct coff_relocation {
00174   support::ulittle32_t VirtualAddress;
00175   support::ulittle32_t SymbolTableIndex;
00176   support::ulittle16_t Type;
00177 };
00178 
00179 struct coff_aux_section_definition {
00180   support::ulittle32_t Length;
00181   support::ulittle16_t NumberOfRelocations;
00182   support::ulittle16_t NumberOfLinenumbers;
00183   support::ulittle32_t CheckSum;
00184   support::ulittle16_t Number;
00185   support::ulittle8_t Selection;
00186   char Unused[3];
00187 };
00188 
00189 class COFFObjectFile : public ObjectFile {
00190 private:
00191   const coff_file_header *COFFHeader;
00192   const pe32_header      *PE32Header;
00193   const coff_section     *SectionTable;
00194   const coff_symbol      *SymbolTable;
00195   const char             *StringTable;
00196         uint32_t          StringTableSize;
00197 
00198         error_code        getString(uint32_t offset, StringRef &Res) const;
00199 
00200   const coff_symbol      *toSymb(DataRefImpl Symb) const;
00201   const coff_section     *toSec(DataRefImpl Sec) const;
00202   const coff_relocation  *toRel(DataRefImpl Rel) const;
00203 
00204 protected:
00205   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
00206   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
00207   virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
00208   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
00209   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
00210   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
00211   virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
00212   virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
00213   virtual error_code getSymbolSection(DataRefImpl Symb,
00214                                       section_iterator &Res) const;
00215   virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
00216 
00217   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
00218   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
00219   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
00220   virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
00221   virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
00222   virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
00223   virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
00224   virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
00225   virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
00226   virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
00227   virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
00228   virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
00229   virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
00230                                                    bool &Res) const;
00231   virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
00232                                            bool &Result) const;
00233   virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
00234   virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
00235 
00236   virtual error_code getRelocationNext(DataRefImpl Rel,
00237                                        RelocationRef &Res) const;
00238   virtual error_code getRelocationAddress(DataRefImpl Rel,
00239                                           uint64_t &Res) const;
00240   virtual error_code getRelocationOffset(DataRefImpl Rel,
00241                                          uint64_t &Res) const;
00242   virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
00243   virtual error_code getRelocationType(DataRefImpl Rel,
00244                                        uint64_t &Res) const;
00245   virtual error_code getRelocationTypeName(DataRefImpl Rel,
00246                                            SmallVectorImpl<char> &Result) const;
00247   virtual error_code getRelocationValueString(DataRefImpl Rel,
00248                                            SmallVectorImpl<char> &Result) const;
00249 
00250   virtual error_code getLibraryNext(DataRefImpl LibData,
00251                                     LibraryRef &Result) const;
00252   virtual error_code getLibraryPath(DataRefImpl LibData,
00253                                     StringRef &Result) const;
00254 
00255 public:
00256   COFFObjectFile(MemoryBuffer *Object, error_code &ec);
00257   virtual symbol_iterator begin_symbols() const;
00258   virtual symbol_iterator end_symbols() const;
00259   virtual symbol_iterator begin_dynamic_symbols() const;
00260   virtual symbol_iterator end_dynamic_symbols() const;
00261   virtual library_iterator begin_libraries_needed() const;
00262   virtual library_iterator end_libraries_needed() const;
00263   virtual section_iterator begin_sections() const;
00264   virtual section_iterator end_sections() const;
00265 
00266   const coff_section *getCOFFSection(section_iterator &It) const;
00267   const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
00268   const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
00269 
00270   virtual uint8_t getBytesInAddress() const;
00271   virtual StringRef getFileFormatName() const;
00272   virtual unsigned getArch() const;
00273   virtual StringRef getLoadName() const;
00274 
00275   error_code getHeader(const coff_file_header *&Res) const;
00276   error_code getCOFFHeader(const coff_file_header *&Res) const;
00277   error_code getPE32Header(const pe32_header *&Res) const;
00278   error_code getSection(int32_t index, const coff_section *&Res) const;
00279   error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
00280   template <typename T>
00281   error_code getAuxSymbol(uint32_t index, const T *&Res) const {
00282     const coff_symbol *s;
00283     error_code ec = getSymbol(index, s);
00284     Res = reinterpret_cast<const T*>(s);
00285     return ec;
00286   }
00287   error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
00288   ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
00289 
00290   error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
00291   error_code getSectionContents(const coff_section *Sec,
00292                                 ArrayRef<uint8_t> &Res) const;
00293 
00294   static inline bool classof(const Binary *v) {
00295     return v->isCOFF();
00296   }
00297 };
00298 
00299 }
00300 }
00301 
00302 #endif