LLVM API Documentation
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/ADT/PointerUnion.h" 00018 #include "llvm/Object/ObjectFile.h" 00019 #include "llvm/Support/COFF.h" 00020 #include "llvm/Support/Endian.h" 00021 #include "llvm/Support/ErrorOr.h" 00022 00023 namespace llvm { 00024 template <typename T> class ArrayRef; 00025 00026 namespace object { 00027 class ImportDirectoryEntryRef; 00028 class ExportDirectoryEntryRef; 00029 typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator; 00030 typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator; 00031 00032 /// The DOS compatible header at the front of all PE/COFF executables. 00033 struct dos_header { 00034 support::ulittle16_t Magic; 00035 support::ulittle16_t UsedBytesInTheLastPage; 00036 support::ulittle16_t FileSizeInPages; 00037 support::ulittle16_t NumberOfRelocationItems; 00038 support::ulittle16_t HeaderSizeInParagraphs; 00039 support::ulittle16_t MinimumExtraParagraphs; 00040 support::ulittle16_t MaximumExtraParagraphs; 00041 support::ulittle16_t InitialRelativeSS; 00042 support::ulittle16_t InitialSP; 00043 support::ulittle16_t Checksum; 00044 support::ulittle16_t InitialIP; 00045 support::ulittle16_t InitialRelativeCS; 00046 support::ulittle16_t AddressOfRelocationTable; 00047 support::ulittle16_t OverlayNumber; 00048 support::ulittle16_t Reserved[4]; 00049 support::ulittle16_t OEMid; 00050 support::ulittle16_t OEMinfo; 00051 support::ulittle16_t Reserved2[10]; 00052 support::ulittle32_t AddressOfNewExeHeader; 00053 }; 00054 00055 struct coff_file_header { 00056 support::ulittle16_t Machine; 00057 support::ulittle16_t NumberOfSections; 00058 support::ulittle32_t TimeDateStamp; 00059 support::ulittle32_t PointerToSymbolTable; 00060 support::ulittle32_t NumberOfSymbols; 00061 support::ulittle16_t SizeOfOptionalHeader; 00062 support::ulittle16_t Characteristics; 00063 00064 bool isImportLibrary() const { return NumberOfSections == 0xffff; } 00065 }; 00066 00067 struct coff_bigobj_file_header { 00068 support::ulittle16_t Sig1; 00069 support::ulittle16_t Sig2; 00070 support::ulittle16_t Version; 00071 support::ulittle16_t Machine; 00072 support::ulittle32_t TimeDateStamp; 00073 uint8_t UUID[16]; 00074 support::ulittle32_t unused1; 00075 support::ulittle32_t unused2; 00076 support::ulittle32_t unused3; 00077 support::ulittle32_t unused4; 00078 support::ulittle32_t NumberOfSections; 00079 support::ulittle32_t PointerToSymbolTable; 00080 support::ulittle32_t NumberOfSymbols; 00081 }; 00082 00083 /// The 32-bit PE header that follows the COFF header. 00084 struct pe32_header { 00085 support::ulittle16_t Magic; 00086 uint8_t MajorLinkerVersion; 00087 uint8_t MinorLinkerVersion; 00088 support::ulittle32_t SizeOfCode; 00089 support::ulittle32_t SizeOfInitializedData; 00090 support::ulittle32_t SizeOfUninitializedData; 00091 support::ulittle32_t AddressOfEntryPoint; 00092 support::ulittle32_t BaseOfCode; 00093 support::ulittle32_t BaseOfData; 00094 support::ulittle32_t ImageBase; 00095 support::ulittle32_t SectionAlignment; 00096 support::ulittle32_t FileAlignment; 00097 support::ulittle16_t MajorOperatingSystemVersion; 00098 support::ulittle16_t MinorOperatingSystemVersion; 00099 support::ulittle16_t MajorImageVersion; 00100 support::ulittle16_t MinorImageVersion; 00101 support::ulittle16_t MajorSubsystemVersion; 00102 support::ulittle16_t MinorSubsystemVersion; 00103 support::ulittle32_t Win32VersionValue; 00104 support::ulittle32_t SizeOfImage; 00105 support::ulittle32_t SizeOfHeaders; 00106 support::ulittle32_t CheckSum; 00107 support::ulittle16_t Subsystem; 00108 support::ulittle16_t DLLCharacteristics; 00109 support::ulittle32_t SizeOfStackReserve; 00110 support::ulittle32_t SizeOfStackCommit; 00111 support::ulittle32_t SizeOfHeapReserve; 00112 support::ulittle32_t SizeOfHeapCommit; 00113 support::ulittle32_t LoaderFlags; 00114 support::ulittle32_t NumberOfRvaAndSize; 00115 }; 00116 00117 /// The 64-bit PE header that follows the COFF header. 00118 struct pe32plus_header { 00119 support::ulittle16_t Magic; 00120 uint8_t MajorLinkerVersion; 00121 uint8_t MinorLinkerVersion; 00122 support::ulittle32_t SizeOfCode; 00123 support::ulittle32_t SizeOfInitializedData; 00124 support::ulittle32_t SizeOfUninitializedData; 00125 support::ulittle32_t AddressOfEntryPoint; 00126 support::ulittle32_t BaseOfCode; 00127 support::ulittle64_t ImageBase; 00128 support::ulittle32_t SectionAlignment; 00129 support::ulittle32_t FileAlignment; 00130 support::ulittle16_t MajorOperatingSystemVersion; 00131 support::ulittle16_t MinorOperatingSystemVersion; 00132 support::ulittle16_t MajorImageVersion; 00133 support::ulittle16_t MinorImageVersion; 00134 support::ulittle16_t MajorSubsystemVersion; 00135 support::ulittle16_t MinorSubsystemVersion; 00136 support::ulittle32_t Win32VersionValue; 00137 support::ulittle32_t SizeOfImage; 00138 support::ulittle32_t SizeOfHeaders; 00139 support::ulittle32_t CheckSum; 00140 support::ulittle16_t Subsystem; 00141 support::ulittle16_t DLLCharacteristics; 00142 support::ulittle64_t SizeOfStackReserve; 00143 support::ulittle64_t SizeOfStackCommit; 00144 support::ulittle64_t SizeOfHeapReserve; 00145 support::ulittle64_t SizeOfHeapCommit; 00146 support::ulittle32_t LoaderFlags; 00147 support::ulittle32_t NumberOfRvaAndSize; 00148 }; 00149 00150 struct data_directory { 00151 support::ulittle32_t RelativeVirtualAddress; 00152 support::ulittle32_t Size; 00153 }; 00154 00155 struct import_directory_table_entry { 00156 support::ulittle32_t ImportLookupTableRVA; 00157 support::ulittle32_t TimeDateStamp; 00158 support::ulittle32_t ForwarderChain; 00159 support::ulittle32_t NameRVA; 00160 support::ulittle32_t ImportAddressTableRVA; 00161 }; 00162 00163 struct import_lookup_table_entry32 { 00164 support::ulittle32_t data; 00165 00166 bool isOrdinal() const { return data & 0x80000000; } 00167 00168 uint16_t getOrdinal() const { 00169 assert(isOrdinal() && "ILT entry is not an ordinal!"); 00170 return data & 0xFFFF; 00171 } 00172 00173 uint32_t getHintNameRVA() const { 00174 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); 00175 return data; 00176 } 00177 }; 00178 00179 struct export_directory_table_entry { 00180 support::ulittle32_t ExportFlags; 00181 support::ulittle32_t TimeDateStamp; 00182 support::ulittle16_t MajorVersion; 00183 support::ulittle16_t MinorVersion; 00184 support::ulittle32_t NameRVA; 00185 support::ulittle32_t OrdinalBase; 00186 support::ulittle32_t AddressTableEntries; 00187 support::ulittle32_t NumberOfNamePointers; 00188 support::ulittle32_t ExportAddressTableRVA; 00189 support::ulittle32_t NamePointerRVA; 00190 support::ulittle32_t OrdinalTableRVA; 00191 }; 00192 00193 union export_address_table_entry { 00194 support::ulittle32_t ExportRVA; 00195 support::ulittle32_t ForwarderRVA; 00196 }; 00197 00198 typedef support::ulittle32_t export_name_pointer_table_entry; 00199 typedef support::ulittle16_t export_ordinal_table_entry; 00200 00201 struct StringTableOffset { 00202 support::ulittle32_t Zeroes; 00203 support::ulittle32_t Offset; 00204 }; 00205 00206 template <typename SectionNumberType> 00207 struct coff_symbol { 00208 union { 00209 char ShortName[COFF::NameSize]; 00210 StringTableOffset Offset; 00211 } Name; 00212 00213 support::ulittle32_t Value; 00214 SectionNumberType SectionNumber; 00215 00216 support::ulittle16_t Type; 00217 00218 uint8_t StorageClass; 00219 uint8_t NumberOfAuxSymbols; 00220 }; 00221 00222 typedef coff_symbol<support::ulittle16_t> coff_symbol16; 00223 typedef coff_symbol<support::ulittle32_t> coff_symbol32; 00224 00225 class COFFSymbolRef { 00226 public: 00227 COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {} 00228 COFFSymbolRef(const coff_symbol32 *CS) : CS16(nullptr), CS32(CS) {} 00229 COFFSymbolRef() : CS16(nullptr), CS32(nullptr) {} 00230 00231 const void *getRawPtr() const { 00232 return CS16 ? static_cast<const void *>(CS16) : CS32; 00233 } 00234 00235 friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) { 00236 return A.getRawPtr() < B.getRawPtr(); 00237 } 00238 00239 bool isBigObj() const { 00240 if (CS16) 00241 return false; 00242 if (CS32) 00243 return true; 00244 llvm_unreachable("COFFSymbolRef points to nothing!"); 00245 } 00246 00247 const char *getShortName() const { 00248 return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName; 00249 } 00250 00251 const StringTableOffset &getStringTableOffset() const { 00252 return CS16 ? CS16->Name.Offset : CS32->Name.Offset; 00253 } 00254 00255 uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; } 00256 00257 int32_t getSectionNumber() const { 00258 if (CS16) { 00259 // Reserved sections are returned as negative numbers. 00260 if (CS16->SectionNumber <= COFF::MaxNumberOfSections16) 00261 return CS16->SectionNumber; 00262 return static_cast<int16_t>(CS16->SectionNumber); 00263 } 00264 return static_cast<int32_t>(CS32->SectionNumber); 00265 } 00266 00267 uint16_t getType() const { return CS16 ? CS16->Type : CS32->Type; } 00268 00269 uint8_t getStorageClass() const { 00270 return CS16 ? CS16->StorageClass : CS32->StorageClass; 00271 } 00272 00273 uint8_t getNumberOfAuxSymbols() const { 00274 return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols; 00275 } 00276 00277 uint8_t getBaseType() const { return getType() & 0x0F; } 00278 00279 uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; } 00280 00281 bool isFunctionDefinition() const { 00282 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && 00283 getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && 00284 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION && 00285 !COFF::isReservedSectionNumber(getSectionNumber()); 00286 } 00287 00288 bool isFunctionLineInfo() const { 00289 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION; 00290 } 00291 00292 bool isWeakExternal() const { 00293 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || 00294 (getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && 00295 getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && getValue() == 0); 00296 } 00297 00298 bool isFileRecord() const { 00299 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE; 00300 } 00301 00302 bool isSectionDefinition() const { 00303 // C++/CLI creates external ABS symbols for non-const appdomain globals. 00304 // These are also followed by an auxiliary section definition. 00305 bool isAppdomainGlobal = 00306 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && 00307 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE; 00308 bool isOrdinarySection = 00309 getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC && getValue() == 0; 00310 return isAppdomainGlobal || isOrdinarySection; 00311 } 00312 00313 bool isCLRToken() const { 00314 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN; 00315 } 00316 00317 private: 00318 const coff_symbol16 *CS16; 00319 const coff_symbol32 *CS32; 00320 }; 00321 00322 struct coff_section { 00323 char Name[COFF::NameSize]; 00324 support::ulittle32_t VirtualSize; 00325 support::ulittle32_t VirtualAddress; 00326 support::ulittle32_t SizeOfRawData; 00327 support::ulittle32_t PointerToRawData; 00328 support::ulittle32_t PointerToRelocations; 00329 support::ulittle32_t PointerToLinenumbers; 00330 support::ulittle16_t NumberOfRelocations; 00331 support::ulittle16_t NumberOfLinenumbers; 00332 support::ulittle32_t Characteristics; 00333 00334 // Returns true if the actual number of relocations is stored in 00335 // VirtualAddress field of the first relocation table entry. 00336 bool hasExtendedRelocations() const { 00337 return Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL && 00338 NumberOfRelocations == UINT16_MAX; 00339 }; 00340 }; 00341 00342 struct coff_relocation { 00343 support::ulittle32_t VirtualAddress; 00344 support::ulittle32_t SymbolTableIndex; 00345 support::ulittle16_t Type; 00346 }; 00347 00348 struct coff_aux_function_definition { 00349 support::ulittle32_t TagIndex; 00350 support::ulittle32_t TotalSize; 00351 support::ulittle32_t PointerToLinenumber; 00352 support::ulittle32_t PointerToNextFunction; 00353 }; 00354 00355 struct coff_aux_bf_and_ef_symbol { 00356 char Unused1[4]; 00357 support::ulittle16_t Linenumber; 00358 char Unused2[6]; 00359 support::ulittle32_t PointerToNextFunction; 00360 }; 00361 00362 struct coff_aux_weak_external { 00363 support::ulittle32_t TagIndex; 00364 support::ulittle32_t Characteristics; 00365 }; 00366 00367 struct coff_aux_section_definition { 00368 support::ulittle32_t Length; 00369 support::ulittle16_t NumberOfRelocations; 00370 support::ulittle16_t NumberOfLinenumbers; 00371 support::ulittle32_t CheckSum; 00372 support::ulittle16_t NumberLowPart; 00373 uint8_t Selection; 00374 uint8_t Unused; 00375 support::ulittle16_t NumberHighPart; 00376 int32_t getNumber(bool IsBigObj) const { 00377 uint32_t Number = static_cast<uint32_t>(NumberLowPart); 00378 if (IsBigObj) 00379 Number |= static_cast<uint32_t>(NumberHighPart) << 16; 00380 return static_cast<int32_t>(Number); 00381 } 00382 }; 00383 00384 struct coff_aux_clr_token { 00385 uint8_t AuxType; 00386 uint8_t Reserved; 00387 support::ulittle32_t SymbolTableIndex; 00388 }; 00389 00390 struct coff_load_configuration32 { 00391 support::ulittle32_t Characteristics; 00392 support::ulittle32_t TimeDateStamp; 00393 support::ulittle16_t MajorVersion; 00394 support::ulittle16_t MinorVersion; 00395 support::ulittle32_t GlobalFlagsClear; 00396 support::ulittle32_t GlobalFlagsSet; 00397 support::ulittle32_t CriticalSectionDefaultTimeout; 00398 support::ulittle32_t DeCommitFreeBlockThreshold; 00399 support::ulittle32_t DeCommitTotalFreeThreshold; 00400 support::ulittle32_t LockPrefixTable; 00401 support::ulittle32_t MaximumAllocationSize; 00402 support::ulittle32_t VirtualMemoryThreshold; 00403 support::ulittle32_t ProcessAffinityMask; 00404 support::ulittle32_t ProcessHeapFlags; 00405 support::ulittle16_t CSDVersion; 00406 support::ulittle16_t Reserved; 00407 support::ulittle32_t EditList; 00408 support::ulittle32_t SecurityCookie; 00409 support::ulittle32_t SEHandlerTable; 00410 support::ulittle32_t SEHandlerCount; 00411 }; 00412 00413 struct coff_runtime_function_x64 { 00414 support::ulittle32_t BeginAddress; 00415 support::ulittle32_t EndAddress; 00416 support::ulittle32_t UnwindInformation; 00417 }; 00418 00419 class COFFObjectFile : public ObjectFile { 00420 private: 00421 friend class ImportDirectoryEntryRef; 00422 friend class ExportDirectoryEntryRef; 00423 const coff_file_header *COFFHeader; 00424 const coff_bigobj_file_header *COFFBigObjHeader; 00425 const pe32_header *PE32Header; 00426 const pe32plus_header *PE32PlusHeader; 00427 const data_directory *DataDirectory; 00428 const coff_section *SectionTable; 00429 const coff_symbol16 *SymbolTable16; 00430 const coff_symbol32 *SymbolTable32; 00431 const char *StringTable; 00432 uint32_t StringTableSize; 00433 const import_directory_table_entry *ImportDirectory; 00434 uint32_t NumberOfImportDirectory; 00435 const export_directory_table_entry *ExportDirectory; 00436 00437 std::error_code getString(uint32_t offset, StringRef &Res) const; 00438 00439 template <typename coff_symbol_type> 00440 const coff_symbol_type *toSymb(DataRefImpl Symb) const; 00441 const coff_section *toSec(DataRefImpl Sec) const; 00442 const coff_relocation *toRel(DataRefImpl Rel) const; 00443 00444 std::error_code initSymbolTablePtr(); 00445 std::error_code initImportTablePtr(); 00446 std::error_code initExportTablePtr(); 00447 00448 public: 00449 uintptr_t getSymbolTable() const { 00450 if (SymbolTable16) 00451 return reinterpret_cast<uintptr_t>(SymbolTable16); 00452 if (SymbolTable32) 00453 return reinterpret_cast<uintptr_t>(SymbolTable32); 00454 return uintptr_t(0); 00455 } 00456 uint16_t getMachine() const { 00457 if (COFFHeader) 00458 return COFFHeader->Machine; 00459 if (COFFBigObjHeader) 00460 return COFFBigObjHeader->Machine; 00461 llvm_unreachable("no COFF header!"); 00462 } 00463 uint16_t getSizeOfOptionalHeader() const { 00464 if (COFFHeader) 00465 return COFFHeader->SizeOfOptionalHeader; 00466 // bigobj doesn't have this field. 00467 if (COFFBigObjHeader) 00468 return 0; 00469 llvm_unreachable("no COFF header!"); 00470 } 00471 uint16_t getCharacteristics() const { 00472 if (COFFHeader) 00473 return COFFHeader->Characteristics; 00474 // bigobj doesn't have characteristics to speak of, 00475 // editbin will silently lie to you if you attempt to set any. 00476 if (COFFBigObjHeader) 00477 return 0; 00478 llvm_unreachable("no COFF header!"); 00479 } 00480 uint32_t getTimeDateStamp() const { 00481 if (COFFHeader) 00482 return COFFHeader->TimeDateStamp; 00483 if (COFFBigObjHeader) 00484 return COFFBigObjHeader->TimeDateStamp; 00485 llvm_unreachable("no COFF header!"); 00486 } 00487 uint32_t getNumberOfSections() const { 00488 if (COFFHeader) 00489 return COFFHeader->NumberOfSections; 00490 if (COFFBigObjHeader) 00491 return COFFBigObjHeader->NumberOfSections; 00492 llvm_unreachable("no COFF header!"); 00493 } 00494 uint32_t getPointerToSymbolTable() const { 00495 if (COFFHeader) 00496 return COFFHeader->PointerToSymbolTable; 00497 if (COFFBigObjHeader) 00498 return COFFBigObjHeader->PointerToSymbolTable; 00499 llvm_unreachable("no COFF header!"); 00500 } 00501 uint32_t getNumberOfSymbols() const { 00502 if (COFFHeader) 00503 return COFFHeader->NumberOfSymbols; 00504 if (COFFBigObjHeader) 00505 return COFFBigObjHeader->NumberOfSymbols; 00506 llvm_unreachable("no COFF header!"); 00507 } 00508 protected: 00509 void moveSymbolNext(DataRefImpl &Symb) const override; 00510 std::error_code getSymbolName(DataRefImpl Symb, 00511 StringRef &Res) const override; 00512 std::error_code getSymbolAddress(DataRefImpl Symb, 00513 uint64_t &Res) const override; 00514 std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; 00515 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 00516 std::error_code getSymbolType(DataRefImpl Symb, 00517 SymbolRef::Type &Res) const override; 00518 std::error_code getSymbolSection(DataRefImpl Symb, 00519 section_iterator &Res) const override; 00520 void moveSectionNext(DataRefImpl &Sec) const override; 00521 std::error_code getSectionName(DataRefImpl Sec, 00522 StringRef &Res) const override; 00523 std::error_code getSectionAddress(DataRefImpl Sec, 00524 uint64_t &Res) const override; 00525 std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; 00526 std::error_code getSectionContents(DataRefImpl Sec, 00527 StringRef &Res) const override; 00528 std::error_code getSectionAlignment(DataRefImpl Sec, 00529 uint64_t &Res) const override; 00530 std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; 00531 std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; 00532 std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; 00533 std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; 00534 std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; 00535 std::error_code isSectionReadOnlyData(DataRefImpl Sec, 00536 bool &Res) const override; 00537 std::error_code isSectionRequiredForExecution(DataRefImpl Sec, 00538 bool &Res) const override; 00539 std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 00540 bool &Result) const override; 00541 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 00542 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 00543 00544 void moveRelocationNext(DataRefImpl &Rel) const override; 00545 std::error_code getRelocationAddress(DataRefImpl Rel, 00546 uint64_t &Res) const override; 00547 std::error_code getRelocationOffset(DataRefImpl Rel, 00548 uint64_t &Res) const override; 00549 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 00550 std::error_code getRelocationType(DataRefImpl Rel, 00551 uint64_t &Res) const override; 00552 std::error_code 00553 getRelocationTypeName(DataRefImpl Rel, 00554 SmallVectorImpl<char> &Result) const override; 00555 std::error_code 00556 getRelocationValueString(DataRefImpl Rel, 00557 SmallVectorImpl<char> &Result) const override; 00558 00559 public: 00560 COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); 00561 basic_symbol_iterator symbol_begin_impl() const override; 00562 basic_symbol_iterator symbol_end_impl() const override; 00563 section_iterator section_begin() const override; 00564 section_iterator section_end() const override; 00565 00566 const coff_section *getCOFFSection(const SectionRef &Section) const; 00567 COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const; 00568 COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const; 00569 const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const; 00570 00571 uint8_t getBytesInAddress() const override; 00572 StringRef getFileFormatName() const override; 00573 unsigned getArch() const override; 00574 00575 import_directory_iterator import_directory_begin() const; 00576 import_directory_iterator import_directory_end() const; 00577 export_directory_iterator export_directory_begin() const; 00578 export_directory_iterator export_directory_end() const; 00579 00580 std::error_code getPE32Header(const pe32_header *&Res) const; 00581 std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const; 00582 std::error_code getDataDirectory(uint32_t index, 00583 const data_directory *&Res) const; 00584 std::error_code getSection(int32_t index, const coff_section *&Res) const; 00585 template <typename coff_symbol_type> 00586 std::error_code getSymbol(uint32_t Index, 00587 const coff_symbol_type *&Res) const { 00588 if (Index >= getNumberOfSymbols()) 00589 return object_error::parse_failed; 00590 00591 Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index; 00592 return object_error::success; 00593 } 00594 ErrorOr<COFFSymbolRef> getSymbol(uint32_t index) const { 00595 if (SymbolTable16) { 00596 const coff_symbol16 *Symb = nullptr; 00597 if (std::error_code EC = getSymbol(index, Symb)) 00598 return EC; 00599 return COFFSymbolRef(Symb); 00600 } 00601 if (SymbolTable32) { 00602 const coff_symbol32 *Symb = nullptr; 00603 if (std::error_code EC = getSymbol(index, Symb)) 00604 return EC; 00605 return COFFSymbolRef(Symb); 00606 } 00607 llvm_unreachable("no symbol table pointer!"); 00608 } 00609 template <typename T> 00610 std::error_code getAuxSymbol(uint32_t index, const T *&Res) const { 00611 ErrorOr<COFFSymbolRef> s = getSymbol(index); 00612 if (std::error_code EC = s.getError()) 00613 return EC; 00614 Res = reinterpret_cast<const T *>(s->getRawPtr()); 00615 return object_error::success; 00616 } 00617 std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; 00618 00619 ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const; 00620 00621 size_t getSymbolTableEntrySize() const { 00622 if (COFFHeader) 00623 return sizeof(coff_symbol16); 00624 if (COFFBigObjHeader) 00625 return sizeof(coff_symbol32); 00626 llvm_unreachable("null symbol table pointer!"); 00627 } 00628 00629 std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const; 00630 std::error_code getSectionContents(const coff_section *Sec, 00631 ArrayRef<uint8_t> &Res) const; 00632 00633 std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const; 00634 std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const; 00635 std::error_code getHintName(uint32_t Rva, uint16_t &Hint, 00636 StringRef &Name) const; 00637 00638 bool isRelocatableObject() const override; 00639 00640 static inline bool classof(const Binary *v) { return v->isCOFF(); } 00641 }; 00642 00643 // The iterator for the import directory table. 00644 class ImportDirectoryEntryRef { 00645 public: 00646 ImportDirectoryEntryRef() : OwningObject(nullptr) {} 00647 ImportDirectoryEntryRef(const import_directory_table_entry *Table, uint32_t I, 00648 const COFFObjectFile *Owner) 00649 : ImportTable(Table), Index(I), OwningObject(Owner) {} 00650 00651 bool operator==(const ImportDirectoryEntryRef &Other) const; 00652 void moveNext(); 00653 std::error_code getName(StringRef &Result) const; 00654 00655 std::error_code 00656 getImportTableEntry(const import_directory_table_entry *&Result) const; 00657 00658 std::error_code 00659 getImportLookupEntry(const import_lookup_table_entry32 *&Result) const; 00660 00661 private: 00662 const import_directory_table_entry *ImportTable; 00663 uint32_t Index; 00664 const COFFObjectFile *OwningObject; 00665 }; 00666 00667 // The iterator for the export directory table entry. 00668 class ExportDirectoryEntryRef { 00669 public: 00670 ExportDirectoryEntryRef() : OwningObject(nullptr) {} 00671 ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I, 00672 const COFFObjectFile *Owner) 00673 : ExportTable(Table), Index(I), OwningObject(Owner) {} 00674 00675 bool operator==(const ExportDirectoryEntryRef &Other) const; 00676 void moveNext(); 00677 00678 std::error_code getDllName(StringRef &Result) const; 00679 std::error_code getOrdinalBase(uint32_t &Result) const; 00680 std::error_code getOrdinal(uint32_t &Result) const; 00681 std::error_code getExportRVA(uint32_t &Result) const; 00682 std::error_code getSymbolName(StringRef &Result) const; 00683 00684 private: 00685 const export_directory_table_entry *ExportTable; 00686 uint32_t Index; 00687 const COFFObjectFile *OwningObject; 00688 }; 00689 } // end namespace object 00690 } // end namespace llvm 00691 00692 #endif