LLVM API Documentation
00001 //===- COFFObjectFile.cpp - 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 #include "llvm/Object/COFF.h" 00015 #include "llvm/ADT/ArrayRef.h" 00016 #include "llvm/ADT/SmallString.h" 00017 #include "llvm/ADT/StringSwitch.h" 00018 #include "llvm/ADT/Triple.h" 00019 #include "llvm/Support/COFF.h" 00020 #include "llvm/Support/Debug.h" 00021 #include "llvm/Support/raw_ostream.h" 00022 #include <cctype> 00023 #include <limits> 00024 00025 using namespace llvm; 00026 using namespace object; 00027 00028 using support::ulittle16_t; 00029 using support::ulittle32_t; 00030 using support::little16_t; 00031 00032 // Returns false if size is greater than the buffer size. And sets ec. 00033 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) { 00034 if (M.getBufferSize() < Size) { 00035 EC = object_error::unexpected_eof; 00036 return false; 00037 } 00038 return true; 00039 } 00040 00041 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 00042 // Returns unexpected_eof if error. 00043 template <typename T> 00044 static std::error_code getObject(const T *&Obj, MemoryBufferRef M, 00045 const uint8_t *Ptr, 00046 const size_t Size = sizeof(T)) { 00047 uintptr_t Addr = uintptr_t(Ptr); 00048 if (Addr + Size < Addr || Addr + Size < Size || 00049 Addr + Size > uintptr_t(M.getBufferEnd())) { 00050 return object_error::unexpected_eof; 00051 } 00052 Obj = reinterpret_cast<const T *>(Addr); 00053 return object_error::success; 00054 } 00055 00056 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 00057 // prefixed slashes. 00058 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 00059 assert(Str.size() <= 6 && "String too long, possible overflow."); 00060 if (Str.size() > 6) 00061 return true; 00062 00063 uint64_t Value = 0; 00064 while (!Str.empty()) { 00065 unsigned CharVal; 00066 if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25 00067 CharVal = Str[0] - 'A'; 00068 else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51 00069 CharVal = Str[0] - 'a' + 26; 00070 else if (Str[0] >= '0' && Str[0] <= '9') // 52..61 00071 CharVal = Str[0] - '0' + 52; 00072 else if (Str[0] == '+') // 62 00073 CharVal = 62; 00074 else if (Str[0] == '/') // 63 00075 CharVal = 63; 00076 else 00077 return true; 00078 00079 Value = (Value * 64) + CharVal; 00080 Str = Str.substr(1); 00081 } 00082 00083 if (Value > std::numeric_limits<uint32_t>::max()) 00084 return true; 00085 00086 Result = static_cast<uint32_t>(Value); 00087 return false; 00088 } 00089 00090 template <typename coff_symbol_type> 00091 const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const { 00092 const coff_symbol_type *Addr = 00093 reinterpret_cast<const coff_symbol_type *>(Ref.p); 00094 00095 #ifndef NDEBUG 00096 // Verify that the symbol points to a valid entry in the symbol table. 00097 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 00098 if (Offset < getPointerToSymbolTable() || 00099 Offset >= getPointerToSymbolTable() + 00100 (getNumberOfSymbols() * sizeof(coff_symbol_type))) 00101 report_fatal_error("Symbol was outside of symbol table."); 00102 00103 assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 && 00104 "Symbol did not point to the beginning of a symbol"); 00105 #endif 00106 00107 return Addr; 00108 } 00109 00110 const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 00111 const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 00112 00113 # ifndef NDEBUG 00114 // Verify that the section points to a valid entry in the section table. 00115 if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections())) 00116 report_fatal_error("Section was outside of section table."); 00117 00118 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 00119 assert(Offset % sizeof(coff_section) == 0 && 00120 "Section did not point to the beginning of a section"); 00121 # endif 00122 00123 return Addr; 00124 } 00125 00126 void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 00127 if (SymbolTable16) { 00128 const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref); 00129 Symb += 1 + Symb->NumberOfAuxSymbols; 00130 Ref.p = reinterpret_cast<uintptr_t>(Symb); 00131 } else if (SymbolTable32) { 00132 const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref); 00133 Symb += 1 + Symb->NumberOfAuxSymbols; 00134 Ref.p = reinterpret_cast<uintptr_t>(Symb); 00135 } else { 00136 llvm_unreachable("no symbol table pointer!"); 00137 } 00138 } 00139 00140 std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 00141 StringRef &Result) const { 00142 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00143 return getSymbolName(Symb, Result); 00144 } 00145 00146 std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 00147 uint64_t &Result) const { 00148 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00149 const coff_section *Section = nullptr; 00150 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 00151 return EC; 00152 00153 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) 00154 Result = UnknownAddressOrSize; 00155 else if (Section) 00156 Result = Section->VirtualAddress + Symb.getValue(); 00157 else 00158 Result = Symb.getValue(); 00159 return object_error::success; 00160 } 00161 00162 std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 00163 SymbolRef::Type &Result) const { 00164 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00165 Result = SymbolRef::ST_Other; 00166 00167 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && 00168 Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { 00169 Result = SymbolRef::ST_Unknown; 00170 } else if (Symb.isFunctionDefinition()) { 00171 Result = SymbolRef::ST_Function; 00172 } else { 00173 uint32_t Characteristics = 0; 00174 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 00175 const coff_section *Section = nullptr; 00176 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 00177 return EC; 00178 Characteristics = Section->Characteristics; 00179 } 00180 if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 00181 ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 00182 Result = SymbolRef::ST_Data; 00183 } 00184 return object_error::success; 00185 } 00186 00187 uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 00188 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00189 uint32_t Result = SymbolRef::SF_None; 00190 00191 // TODO: Correctly set SF_FormatSpecific, SF_Common 00192 00193 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { 00194 if (Symb.getValue() == 0) 00195 Result |= SymbolRef::SF_Undefined; 00196 else 00197 Result |= SymbolRef::SF_Common; 00198 } 00199 00200 00201 // TODO: This are certainly too restrictive. 00202 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL) 00203 Result |= SymbolRef::SF_Global; 00204 00205 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 00206 Result |= SymbolRef::SF_Weak; 00207 00208 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) 00209 Result |= SymbolRef::SF_Absolute; 00210 00211 return Result; 00212 } 00213 00214 std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 00215 uint64_t &Result) const { 00216 // FIXME: Return the correct size. This requires looking at all the symbols 00217 // in the same section as this symbol, and looking for either the next 00218 // symbol, or the end of the section. 00219 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00220 const coff_section *Section = nullptr; 00221 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 00222 return EC; 00223 00224 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) 00225 Result = UnknownAddressOrSize; 00226 else if (Section) 00227 Result = Section->SizeOfRawData - Symb.getValue(); 00228 else 00229 Result = 0; 00230 return object_error::success; 00231 } 00232 00233 std::error_code 00234 COFFObjectFile::getSymbolSection(DataRefImpl Ref, 00235 section_iterator &Result) const { 00236 COFFSymbolRef Symb = getCOFFSymbol(Ref); 00237 if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 00238 Result = section_end(); 00239 } else { 00240 const coff_section *Sec = nullptr; 00241 if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) 00242 return EC; 00243 DataRefImpl Ref; 00244 Ref.p = reinterpret_cast<uintptr_t>(Sec); 00245 Result = section_iterator(SectionRef(Ref, this)); 00246 } 00247 return object_error::success; 00248 } 00249 00250 void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 00251 const coff_section *Sec = toSec(Ref); 00252 Sec += 1; 00253 Ref.p = reinterpret_cast<uintptr_t>(Sec); 00254 } 00255 00256 std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref, 00257 StringRef &Result) const { 00258 const coff_section *Sec = toSec(Ref); 00259 return getSectionName(Sec, Result); 00260 } 00261 00262 std::error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref, 00263 uint64_t &Result) const { 00264 const coff_section *Sec = toSec(Ref); 00265 Result = Sec->VirtualAddress; 00266 return object_error::success; 00267 } 00268 00269 std::error_code COFFObjectFile::getSectionSize(DataRefImpl Ref, 00270 uint64_t &Result) const { 00271 const coff_section *Sec = toSec(Ref); 00272 Result = Sec->SizeOfRawData; 00273 return object_error::success; 00274 } 00275 00276 std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 00277 StringRef &Result) const { 00278 const coff_section *Sec = toSec(Ref); 00279 ArrayRef<uint8_t> Res; 00280 std::error_code EC = getSectionContents(Sec, Res); 00281 Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 00282 return EC; 00283 } 00284 00285 std::error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref, 00286 uint64_t &Res) const { 00287 const coff_section *Sec = toSec(Ref); 00288 if (!Sec) 00289 return object_error::parse_failed; 00290 Res = uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 00291 return object_error::success; 00292 } 00293 00294 std::error_code COFFObjectFile::isSectionText(DataRefImpl Ref, 00295 bool &Result) const { 00296 const coff_section *Sec = toSec(Ref); 00297 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 00298 return object_error::success; 00299 } 00300 00301 std::error_code COFFObjectFile::isSectionData(DataRefImpl Ref, 00302 bool &Result) const { 00303 const coff_section *Sec = toSec(Ref); 00304 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 00305 return object_error::success; 00306 } 00307 00308 std::error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref, 00309 bool &Result) const { 00310 const coff_section *Sec = toSec(Ref); 00311 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 00312 return object_error::success; 00313 } 00314 00315 std::error_code 00316 COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref, 00317 bool &Result) const { 00318 // FIXME: Unimplemented 00319 Result = true; 00320 return object_error::success; 00321 } 00322 00323 std::error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref, 00324 bool &Result) const { 00325 const coff_section *Sec = toSec(Ref); 00326 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 00327 return object_error::success; 00328 } 00329 00330 std::error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref, 00331 bool &Result) const { 00332 // FIXME: Unimplemented. 00333 Result = false; 00334 return object_error::success; 00335 } 00336 00337 std::error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref, 00338 bool &Result) const { 00339 // FIXME: Unimplemented. 00340 Result = false; 00341 return object_error::success; 00342 } 00343 00344 std::error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 00345 DataRefImpl SymbRef, 00346 bool &Result) const { 00347 const coff_section *Sec = toSec(SecRef); 00348 COFFSymbolRef Symb = getCOFFSymbol(SymbRef); 00349 const coff_section *SymbSec = nullptr; 00350 if (std::error_code EC = getSection(Symb.getSectionNumber(), SymbSec)) 00351 return EC; 00352 if (SymbSec == Sec) 00353 Result = true; 00354 else 00355 Result = false; 00356 return object_error::success; 00357 } 00358 00359 relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 00360 const coff_section *Sec = toSec(Ref); 00361 DataRefImpl Ret; 00362 if (Sec->NumberOfRelocations == 0) { 00363 Ret.p = 0; 00364 } else { 00365 auto begin = reinterpret_cast<const coff_relocation*>( 00366 base() + Sec->PointerToRelocations); 00367 if (Sec->hasExtendedRelocations()) { 00368 // Skip the first relocation entry repurposed to store the number of 00369 // relocations. 00370 begin++; 00371 } 00372 Ret.p = reinterpret_cast<uintptr_t>(begin); 00373 } 00374 return relocation_iterator(RelocationRef(Ret, this)); 00375 } 00376 00377 static uint32_t getNumberOfRelocations(const coff_section *Sec, 00378 const uint8_t *base) { 00379 // The field for the number of relocations in COFF section table is only 00380 // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 00381 // NumberOfRelocations field, and the actual relocation count is stored in the 00382 // VirtualAddress field in the first relocation entry. 00383 if (Sec->hasExtendedRelocations()) { 00384 auto *FirstReloc = reinterpret_cast<const coff_relocation*>( 00385 base + Sec->PointerToRelocations); 00386 return FirstReloc->VirtualAddress; 00387 } 00388 return Sec->NumberOfRelocations; 00389 } 00390 00391 relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 00392 const coff_section *Sec = toSec(Ref); 00393 DataRefImpl Ret; 00394 if (Sec->NumberOfRelocations == 0) { 00395 Ret.p = 0; 00396 } else { 00397 auto begin = reinterpret_cast<const coff_relocation*>( 00398 base() + Sec->PointerToRelocations); 00399 uint32_t NumReloc = getNumberOfRelocations(Sec, base()); 00400 Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc); 00401 } 00402 return relocation_iterator(RelocationRef(Ret, this)); 00403 } 00404 00405 // Initialize the pointer to the symbol table. 00406 std::error_code COFFObjectFile::initSymbolTablePtr() { 00407 if (COFFHeader) 00408 if (std::error_code EC = 00409 getObject(SymbolTable16, Data, base() + getPointerToSymbolTable(), 00410 getNumberOfSymbols() * getSymbolTableEntrySize())) 00411 return EC; 00412 00413 if (COFFBigObjHeader) 00414 if (std::error_code EC = 00415 getObject(SymbolTable32, Data, base() + getPointerToSymbolTable(), 00416 getNumberOfSymbols() * getSymbolTableEntrySize())) 00417 return EC; 00418 00419 // Find string table. The first four byte of the string table contains the 00420 // total size of the string table, including the size field itself. If the 00421 // string table is empty, the value of the first four byte would be 4. 00422 const uint8_t *StringTableAddr = 00423 base() + getPointerToSymbolTable() + 00424 getNumberOfSymbols() * getSymbolTableEntrySize(); 00425 const ulittle32_t *StringTableSizePtr; 00426 if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 00427 return EC; 00428 StringTableSize = *StringTableSizePtr; 00429 if (std::error_code EC = 00430 getObject(StringTable, Data, StringTableAddr, StringTableSize)) 00431 return EC; 00432 00433 // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 00434 // tools like cvtres write a size of 0 for an empty table instead of 4. 00435 if (StringTableSize < 4) 00436 StringTableSize = 4; 00437 00438 // Check that the string table is null terminated if has any in it. 00439 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 00440 return object_error::parse_failed; 00441 return object_error::success; 00442 } 00443 00444 // Returns the file offset for the given VA. 00445 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 00446 uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 00447 : (uint64_t)PE32PlusHeader->ImageBase; 00448 uint64_t Rva = Addr - ImageBase; 00449 assert(Rva <= UINT32_MAX); 00450 return getRvaPtr((uint32_t)Rva, Res); 00451 } 00452 00453 // Returns the file offset for the given RVA. 00454 std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 00455 for (const SectionRef &S : sections()) { 00456 const coff_section *Section = getCOFFSection(S); 00457 uint32_t SectionStart = Section->VirtualAddress; 00458 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 00459 if (SectionStart <= Addr && Addr < SectionEnd) { 00460 uint32_t Offset = Addr - SectionStart; 00461 Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 00462 return object_error::success; 00463 } 00464 } 00465 return object_error::parse_failed; 00466 } 00467 00468 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 00469 // table entry. 00470 std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint, 00471 StringRef &Name) const { 00472 uintptr_t IntPtr = 0; 00473 if (std::error_code EC = getRvaPtr(Rva, IntPtr)) 00474 return EC; 00475 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 00476 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 00477 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 00478 return object_error::success; 00479 } 00480 00481 // Find the import table. 00482 std::error_code COFFObjectFile::initImportTablePtr() { 00483 // First, we get the RVA of the import table. If the file lacks a pointer to 00484 // the import table, do nothing. 00485 const data_directory *DataEntry; 00486 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 00487 return object_error::success; 00488 00489 // Do nothing if the pointer to import table is NULL. 00490 if (DataEntry->RelativeVirtualAddress == 0) 00491 return object_error::success; 00492 00493 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 00494 NumberOfImportDirectory = DataEntry->Size / 00495 sizeof(import_directory_table_entry); 00496 00497 // Find the section that contains the RVA. This is needed because the RVA is 00498 // the import table's memory address which is different from its file offset. 00499 uintptr_t IntPtr = 0; 00500 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 00501 return EC; 00502 ImportDirectory = reinterpret_cast< 00503 const import_directory_table_entry *>(IntPtr); 00504 return object_error::success; 00505 } 00506 00507 // Find the export table. 00508 std::error_code COFFObjectFile::initExportTablePtr() { 00509 // First, we get the RVA of the export table. If the file lacks a pointer to 00510 // the export table, do nothing. 00511 const data_directory *DataEntry; 00512 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 00513 return object_error::success; 00514 00515 // Do nothing if the pointer to export table is NULL. 00516 if (DataEntry->RelativeVirtualAddress == 0) 00517 return object_error::success; 00518 00519 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 00520 uintptr_t IntPtr = 0; 00521 if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 00522 return EC; 00523 ExportDirectory = 00524 reinterpret_cast<const export_directory_table_entry *>(IntPtr); 00525 return object_error::success; 00526 } 00527 00528 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 00529 : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), 00530 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), 00531 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr), 00532 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0), 00533 ImportDirectory(nullptr), NumberOfImportDirectory(0), 00534 ExportDirectory(nullptr) { 00535 // Check that we at least have enough room for a header. 00536 if (!checkSize(Data, EC, sizeof(coff_file_header))) 00537 return; 00538 00539 // The current location in the file where we are looking at. 00540 uint64_t CurPtr = 0; 00541 00542 // PE header is optional and is present only in executables. If it exists, 00543 // it is placed right after COFF header. 00544 bool HasPEHeader = false; 00545 00546 // Check if this is a PE/COFF file. 00547 if (base()[0] == 0x4d && base()[1] == 0x5a) { 00548 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 00549 // PE signature to find 'normal' COFF header. 00550 if (!checkSize(Data, EC, 0x3c + 8)) 00551 return; 00552 CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); 00553 // Check the PE magic bytes. ("PE\0\0") 00554 if (std::memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 00555 0) { 00556 EC = object_error::parse_failed; 00557 return; 00558 } 00559 CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes. 00560 HasPEHeader = true; 00561 } 00562 00563 if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 00564 return; 00565 00566 // It might be a bigobj file, let's check. Note that COFF bigobj and COFF 00567 // import libraries share a common prefix but bigobj is more restrictive. 00568 if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN && 00569 COFFHeader->NumberOfSections == uint16_t(0xffff) && 00570 checkSize(Data, EC, sizeof(coff_bigobj_file_header))) { 00571 if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr))) 00572 return; 00573 00574 // Verify that we are dealing with bigobj. 00575 if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion && 00576 std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic, 00577 sizeof(COFF::BigObjMagic)) == 0) { 00578 COFFHeader = nullptr; 00579 CurPtr += sizeof(coff_bigobj_file_header); 00580 } else { 00581 // It's not a bigobj. 00582 COFFBigObjHeader = nullptr; 00583 } 00584 } 00585 if (COFFHeader) { 00586 // The prior checkSize call may have failed. This isn't a hard error 00587 // because we were just trying to sniff out bigobj. 00588 EC = object_error::success; 00589 CurPtr += sizeof(coff_file_header); 00590 00591 if (COFFHeader->isImportLibrary()) 00592 return; 00593 } 00594 00595 if (HasPEHeader) { 00596 const pe32_header *Header; 00597 if ((EC = getObject(Header, Data, base() + CurPtr))) 00598 return; 00599 00600 const uint8_t *DataDirAddr; 00601 uint64_t DataDirSize; 00602 if (Header->Magic == 0x10b) { 00603 PE32Header = Header; 00604 DataDirAddr = base() + CurPtr + sizeof(pe32_header); 00605 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 00606 } else if (Header->Magic == 0x20b) { 00607 PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 00608 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 00609 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 00610 } else { 00611 // It's neither PE32 nor PE32+. 00612 EC = object_error::parse_failed; 00613 return; 00614 } 00615 if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 00616 return; 00617 CurPtr += COFFHeader->SizeOfOptionalHeader; 00618 } 00619 00620 if ((EC = getObject(SectionTable, Data, base() + CurPtr, 00621 getNumberOfSections() * sizeof(coff_section)))) 00622 return; 00623 00624 // Initialize the pointer to the symbol table. 00625 if (getPointerToSymbolTable() != 0) 00626 if ((EC = initSymbolTablePtr())) 00627 return; 00628 00629 // Initialize the pointer to the beginning of the import table. 00630 if ((EC = initImportTablePtr())) 00631 return; 00632 00633 // Initialize the pointer to the export table. 00634 if ((EC = initExportTablePtr())) 00635 return; 00636 00637 EC = object_error::success; 00638 } 00639 00640 basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 00641 DataRefImpl Ret; 00642 Ret.p = getSymbolTable(); 00643 return basic_symbol_iterator(SymbolRef(Ret, this)); 00644 } 00645 00646 basic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 00647 // The symbol table ends where the string table begins. 00648 DataRefImpl Ret; 00649 Ret.p = reinterpret_cast<uintptr_t>(StringTable); 00650 return basic_symbol_iterator(SymbolRef(Ret, this)); 00651 } 00652 00653 import_directory_iterator COFFObjectFile::import_directory_begin() const { 00654 return import_directory_iterator( 00655 ImportDirectoryEntryRef(ImportDirectory, 0, this)); 00656 } 00657 00658 import_directory_iterator COFFObjectFile::import_directory_end() const { 00659 return import_directory_iterator( 00660 ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 00661 } 00662 00663 export_directory_iterator COFFObjectFile::export_directory_begin() const { 00664 return export_directory_iterator( 00665 ExportDirectoryEntryRef(ExportDirectory, 0, this)); 00666 } 00667 00668 export_directory_iterator COFFObjectFile::export_directory_end() const { 00669 if (!ExportDirectory) 00670 return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this)); 00671 ExportDirectoryEntryRef Ref(ExportDirectory, 00672 ExportDirectory->AddressTableEntries, this); 00673 return export_directory_iterator(Ref); 00674 } 00675 00676 section_iterator COFFObjectFile::section_begin() const { 00677 DataRefImpl Ret; 00678 Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 00679 return section_iterator(SectionRef(Ret, this)); 00680 } 00681 00682 section_iterator COFFObjectFile::section_end() const { 00683 DataRefImpl Ret; 00684 int NumSections = 00685 COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections(); 00686 Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 00687 return section_iterator(SectionRef(Ret, this)); 00688 } 00689 00690 uint8_t COFFObjectFile::getBytesInAddress() const { 00691 return getArch() == Triple::x86_64 ? 8 : 4; 00692 } 00693 00694 StringRef COFFObjectFile::getFileFormatName() const { 00695 switch(getMachine()) { 00696 case COFF::IMAGE_FILE_MACHINE_I386: 00697 return "COFF-i386"; 00698 case COFF::IMAGE_FILE_MACHINE_AMD64: 00699 return "COFF-x86-64"; 00700 case COFF::IMAGE_FILE_MACHINE_ARMNT: 00701 return "COFF-ARM"; 00702 default: 00703 return "COFF-<unknown arch>"; 00704 } 00705 } 00706 00707 unsigned COFFObjectFile::getArch() const { 00708 switch (getMachine()) { 00709 case COFF::IMAGE_FILE_MACHINE_I386: 00710 return Triple::x86; 00711 case COFF::IMAGE_FILE_MACHINE_AMD64: 00712 return Triple::x86_64; 00713 case COFF::IMAGE_FILE_MACHINE_ARMNT: 00714 return Triple::thumb; 00715 default: 00716 return Triple::UnknownArch; 00717 } 00718 } 00719 00720 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 00721 Res = PE32Header; 00722 return object_error::success; 00723 } 00724 00725 std::error_code 00726 COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 00727 Res = PE32PlusHeader; 00728 return object_error::success; 00729 } 00730 00731 std::error_code 00732 COFFObjectFile::getDataDirectory(uint32_t Index, 00733 const data_directory *&Res) const { 00734 // Error if if there's no data directory or the index is out of range. 00735 if (!DataDirectory) 00736 return object_error::parse_failed; 00737 assert(PE32Header || PE32PlusHeader); 00738 uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 00739 : PE32PlusHeader->NumberOfRvaAndSize; 00740 if (Index > NumEnt) 00741 return object_error::parse_failed; 00742 Res = &DataDirectory[Index]; 00743 return object_error::success; 00744 } 00745 00746 std::error_code COFFObjectFile::getSection(int32_t Index, 00747 const coff_section *&Result) const { 00748 // Check for special index values. 00749 if (COFF::isReservedSectionNumber(Index)) 00750 Result = nullptr; 00751 else if (Index > 0 && static_cast<uint32_t>(Index) <= getNumberOfSections()) 00752 // We already verified the section table data, so no need to check again. 00753 Result = SectionTable + (Index - 1); 00754 else 00755 return object_error::parse_failed; 00756 return object_error::success; 00757 } 00758 00759 std::error_code COFFObjectFile::getString(uint32_t Offset, 00760 StringRef &Result) const { 00761 if (StringTableSize <= 4) 00762 // Tried to get a string from an empty string table. 00763 return object_error::parse_failed; 00764 if (Offset >= StringTableSize) 00765 return object_error::unexpected_eof; 00766 Result = StringRef(StringTable + Offset); 00767 return object_error::success; 00768 } 00769 00770 std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, 00771 StringRef &Res) const { 00772 // Check for string table entry. First 4 bytes are 0. 00773 if (Symbol.getStringTableOffset().Zeroes == 0) { 00774 uint32_t Offset = Symbol.getStringTableOffset().Offset; 00775 if (std::error_code EC = getString(Offset, Res)) 00776 return EC; 00777 return object_error::success; 00778 } 00779 00780 if (Symbol.getShortName()[COFF::NameSize - 1] == 0) 00781 // Null terminated, let ::strlen figure out the length. 00782 Res = StringRef(Symbol.getShortName()); 00783 else 00784 // Not null terminated, use all 8 bytes. 00785 Res = StringRef(Symbol.getShortName(), COFF::NameSize); 00786 return object_error::success; 00787 } 00788 00789 ArrayRef<uint8_t> 00790 COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { 00791 const uint8_t *Aux = nullptr; 00792 00793 size_t SymbolSize = getSymbolTableEntrySize(); 00794 if (Symbol.getNumberOfAuxSymbols() > 0) { 00795 // AUX data comes immediately after the symbol in COFF 00796 Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize; 00797 # ifndef NDEBUG 00798 // Verify that the Aux symbol points to a valid entry in the symbol table. 00799 uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 00800 if (Offset < getPointerToSymbolTable() || 00801 Offset >= 00802 getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize)) 00803 report_fatal_error("Aux Symbol data was outside of symbol table."); 00804 00805 assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 && 00806 "Aux Symbol data did not point to the beginning of a symbol"); 00807 # endif 00808 } 00809 return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize); 00810 } 00811 00812 std::error_code COFFObjectFile::getSectionName(const coff_section *Sec, 00813 StringRef &Res) const { 00814 StringRef Name; 00815 if (Sec->Name[COFF::NameSize - 1] == 0) 00816 // Null terminated, let ::strlen figure out the length. 00817 Name = Sec->Name; 00818 else 00819 // Not null terminated, use all 8 bytes. 00820 Name = StringRef(Sec->Name, COFF::NameSize); 00821 00822 // Check for string table entry. First byte is '/'. 00823 if (Name[0] == '/') { 00824 uint32_t Offset; 00825 if (Name[1] == '/') { 00826 if (decodeBase64StringEntry(Name.substr(2), Offset)) 00827 return object_error::parse_failed; 00828 } else { 00829 if (Name.substr(1).getAsInteger(10, Offset)) 00830 return object_error::parse_failed; 00831 } 00832 if (std::error_code EC = getString(Offset, Name)) 00833 return EC; 00834 } 00835 00836 Res = Name; 00837 return object_error::success; 00838 } 00839 00840 std::error_code 00841 COFFObjectFile::getSectionContents(const coff_section *Sec, 00842 ArrayRef<uint8_t> &Res) const { 00843 // The only thing that we need to verify is that the contents is contained 00844 // within the file bounds. We don't need to make sure it doesn't cover other 00845 // data, as there's nothing that says that is not allowed. 00846 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 00847 uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; 00848 if (ConEnd > uintptr_t(Data.getBufferEnd())) 00849 return object_error::parse_failed; 00850 Res = makeArrayRef(reinterpret_cast<const uint8_t*>(ConStart), 00851 Sec->SizeOfRawData); 00852 return object_error::success; 00853 } 00854 00855 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 00856 return reinterpret_cast<const coff_relocation*>(Rel.p); 00857 } 00858 00859 void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 00860 Rel.p = reinterpret_cast<uintptr_t>( 00861 reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 00862 } 00863 00864 std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 00865 uint64_t &Res) const { 00866 report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 00867 } 00868 00869 std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 00870 uint64_t &Res) const { 00871 Res = toRel(Rel)->VirtualAddress; 00872 return object_error::success; 00873 } 00874 00875 symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 00876 const coff_relocation *R = toRel(Rel); 00877 DataRefImpl Ref; 00878 if (SymbolTable16) 00879 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex); 00880 else if (SymbolTable32) 00881 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex); 00882 else 00883 llvm_unreachable("no symbol table pointer!"); 00884 return symbol_iterator(SymbolRef(Ref, this)); 00885 } 00886 00887 std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 00888 uint64_t &Res) const { 00889 const coff_relocation* R = toRel(Rel); 00890 Res = R->Type; 00891 return object_error::success; 00892 } 00893 00894 const coff_section * 00895 COFFObjectFile::getCOFFSection(const SectionRef &Section) const { 00896 return toSec(Section.getRawDataRefImpl()); 00897 } 00898 00899 COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const { 00900 if (SymbolTable16) 00901 return toSymb<coff_symbol16>(Ref); 00902 if (SymbolTable32) 00903 return toSymb<coff_symbol32>(Ref); 00904 llvm_unreachable("no symbol table pointer!"); 00905 } 00906 00907 COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 00908 return getCOFFSymbol(Symbol.getRawDataRefImpl()); 00909 } 00910 00911 const coff_relocation * 00912 COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 00913 return toRel(Reloc.getRawDataRefImpl()); 00914 } 00915 00916 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 00917 case COFF::reloc_type: \ 00918 Res = #reloc_type; \ 00919 break; 00920 00921 std::error_code 00922 COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 00923 SmallVectorImpl<char> &Result) const { 00924 const coff_relocation *Reloc = toRel(Rel); 00925 StringRef Res; 00926 switch (getMachine()) { 00927 case COFF::IMAGE_FILE_MACHINE_AMD64: 00928 switch (Reloc->Type) { 00929 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 00930 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 00931 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 00932 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 00933 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 00934 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 00935 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 00936 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 00937 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 00938 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 00939 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 00940 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 00941 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 00942 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 00943 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 00944 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 00945 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 00946 default: 00947 Res = "Unknown"; 00948 } 00949 break; 00950 case COFF::IMAGE_FILE_MACHINE_ARMNT: 00951 switch (Reloc->Type) { 00952 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE); 00953 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32); 00954 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB); 00955 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24); 00956 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11); 00957 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN); 00958 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24); 00959 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11); 00960 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION); 00961 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL); 00962 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A); 00963 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T); 00964 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T); 00965 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T); 00966 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T); 00967 default: 00968 Res = "Unknown"; 00969 } 00970 break; 00971 case COFF::IMAGE_FILE_MACHINE_I386: 00972 switch (Reloc->Type) { 00973 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 00974 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 00975 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 00976 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 00977 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 00978 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 00979 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 00980 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 00981 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 00982 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 00983 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 00984 default: 00985 Res = "Unknown"; 00986 } 00987 break; 00988 default: 00989 Res = "Unknown"; 00990 } 00991 Result.append(Res.begin(), Res.end()); 00992 return object_error::success; 00993 } 00994 00995 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 00996 00997 std::error_code 00998 COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 00999 SmallVectorImpl<char> &Result) const { 01000 const coff_relocation *Reloc = toRel(Rel); 01001 DataRefImpl Sym; 01002 ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex); 01003 if (std::error_code EC = Symb.getError()) 01004 return EC; 01005 Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr()); 01006 StringRef SymName; 01007 if (std::error_code EC = getSymbolName(Sym, SymName)) 01008 return EC; 01009 Result.append(SymName.begin(), SymName.end()); 01010 return object_error::success; 01011 } 01012 01013 bool COFFObjectFile::isRelocatableObject() const { 01014 return !DataDirectory; 01015 } 01016 01017 bool ImportDirectoryEntryRef:: 01018 operator==(const ImportDirectoryEntryRef &Other) const { 01019 return ImportTable == Other.ImportTable && Index == Other.Index; 01020 } 01021 01022 void ImportDirectoryEntryRef::moveNext() { 01023 ++Index; 01024 } 01025 01026 std::error_code ImportDirectoryEntryRef::getImportTableEntry( 01027 const import_directory_table_entry *&Result) const { 01028 Result = ImportTable; 01029 return object_error::success; 01030 } 01031 01032 std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 01033 uintptr_t IntPtr = 0; 01034 if (std::error_code EC = 01035 OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr)) 01036 return EC; 01037 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 01038 return object_error::success; 01039 } 01040 01041 std::error_code ImportDirectoryEntryRef::getImportLookupEntry( 01042 const import_lookup_table_entry32 *&Result) const { 01043 uintptr_t IntPtr = 0; 01044 if (std::error_code EC = 01045 OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr)) 01046 return EC; 01047 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 01048 return object_error::success; 01049 } 01050 01051 bool ExportDirectoryEntryRef:: 01052 operator==(const ExportDirectoryEntryRef &Other) const { 01053 return ExportTable == Other.ExportTable && Index == Other.Index; 01054 } 01055 01056 void ExportDirectoryEntryRef::moveNext() { 01057 ++Index; 01058 } 01059 01060 // Returns the name of the current export symbol. If the symbol is exported only 01061 // by ordinal, the empty string is set as a result. 01062 std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 01063 uintptr_t IntPtr = 0; 01064 if (std::error_code EC = 01065 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 01066 return EC; 01067 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 01068 return object_error::success; 01069 } 01070 01071 // Returns the starting ordinal number. 01072 std::error_code 01073 ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 01074 Result = ExportTable->OrdinalBase; 01075 return object_error::success; 01076 } 01077 01078 // Returns the export ordinal of the current export symbol. 01079 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 01080 Result = ExportTable->OrdinalBase + Index; 01081 return object_error::success; 01082 } 01083 01084 // Returns the address of the current export symbol. 01085 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 01086 uintptr_t IntPtr = 0; 01087 if (std::error_code EC = 01088 OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr)) 01089 return EC; 01090 const export_address_table_entry *entry = 01091 reinterpret_cast<const export_address_table_entry *>(IntPtr); 01092 Result = entry[Index].ExportRVA; 01093 return object_error::success; 01094 } 01095 01096 // Returns the name of the current export symbol. If the symbol is exported only 01097 // by ordinal, the empty string is set as a result. 01098 std::error_code 01099 ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 01100 uintptr_t IntPtr = 0; 01101 if (std::error_code EC = 01102 OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr)) 01103 return EC; 01104 const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 01105 01106 uint32_t NumEntries = ExportTable->NumberOfNamePointers; 01107 int Offset = 0; 01108 for (const ulittle16_t *I = Start, *E = Start + NumEntries; 01109 I < E; ++I, ++Offset) { 01110 if (*I != Index) 01111 continue; 01112 if (std::error_code EC = 01113 OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr)) 01114 return EC; 01115 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 01116 if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 01117 return EC; 01118 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 01119 return object_error::success; 01120 } 01121 Result = ""; 01122 return object_error::success; 01123 } 01124 01125 ErrorOr<std::unique_ptr<COFFObjectFile>> 01126 ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { 01127 std::error_code EC; 01128 std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC)); 01129 if (EC) 01130 return EC; 01131 return std::move(Ret); 01132 }