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