1 //===- COFFObjectFile.cpp - 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 #include "llvm/Object/COFF.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Support/COFF.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <cctype> 23 #include <limits> 24 25 using namespace llvm; 26 using namespace object; 27 28 using support::ulittle16_t; 29 using support::ulittle32_t; 30 using support::ulittle64_t; 31 using support::little16_t; 32 33 // Returns false if size is greater than the buffer size. And sets ec. 34 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) { 35 if (M.getBufferSize() < Size) { 36 EC = object_error::unexpected_eof; 37 return false; 38 } 39 return true; 40 } 41 42 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 43 // Returns unexpected_eof if error. 44 template <typename T> 45 static std::error_code getObject(const T *&Obj, MemoryBufferRef M, 46 const uint8_t *Ptr, 47 const size_t Size = sizeof(T)) { 48 uintptr_t Addr = uintptr_t(Ptr); 49 if (Addr + Size < Addr || Addr + Size < Size || 50 Addr + Size > uintptr_t(M.getBufferEnd())) { 51 return object_error::unexpected_eof; 52 } 53 Obj = reinterpret_cast<const T *>(Addr); 54 return object_error::success; 55 } 56 57 // Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 58 // prefixed slashes. 59 static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 60 assert(Str.size() <= 6 && "String too long, possible overflow."); 61 if (Str.size() > 6) 62 return true; 63 64 uint64_t Value = 0; 65 while (!Str.empty()) { 66 unsigned CharVal; 67 if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25 68 CharVal = Str[0] - 'A'; 69 else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51 70 CharVal = Str[0] - 'a' + 26; 71 else if (Str[0] >= '0' && Str[0] <= '9') // 52..61 72 CharVal = Str[0] - '0' + 52; 73 else if (Str[0] == '+') // 62 74 CharVal = 62; 75 else if (Str[0] == '/') // 63 76 CharVal = 63; 77 else 78 return true; 79 80 Value = (Value * 64) + CharVal; 81 Str = Str.substr(1); 82 } 83 84 if (Value > std::numeric_limits<uint32_t>::max()) 85 return true; 86 87 Result = static_cast<uint32_t>(Value); 88 return false; 89 } 90 91 template <typename coff_symbol_type> 92 const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const { 93 const coff_symbol_type *Addr = 94 reinterpret_cast<const coff_symbol_type *>(Ref.p); 95 96 #ifndef NDEBUG 97 // Verify that the symbol points to a valid entry in the symbol table. 98 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 99 if (Offset < getPointerToSymbolTable() || 100 Offset >= getPointerToSymbolTable() + 101 (getNumberOfSymbols() * sizeof(coff_symbol_type))) 102 report_fatal_error("Symbol was outside of symbol table."); 103 104 assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 && 105 "Symbol did not point to the beginning of a symbol"); 106 #endif 107 108 return Addr; 109 } 110 111 const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 112 const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 113 114 # ifndef NDEBUG 115 // Verify that the section points to a valid entry in the section table. 116 if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections())) 117 report_fatal_error("Section was outside of section table."); 118 119 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 120 assert(Offset % sizeof(coff_section) == 0 && 121 "Section did not point to the beginning of a section"); 122 # endif 123 124 return Addr; 125 } 126 127 void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 128 if (SymbolTable16) { 129 const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref); 130 Symb += 1 + Symb->NumberOfAuxSymbols; 131 Ref.p = reinterpret_cast<uintptr_t>(Symb); 132 } else if (SymbolTable32) { 133 const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref); 134 Symb += 1 + Symb->NumberOfAuxSymbols; 135 Ref.p = reinterpret_cast<uintptr_t>(Symb); 136 } else { 137 llvm_unreachable("no symbol table pointer!"); 138 } 139 } 140 141 std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 142 StringRef &Result) const { 143 COFFSymbolRef Symb = getCOFFSymbol(Ref); 144 return getSymbolName(Symb, Result); 145 } 146 147 std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 148 uint64_t &Result) const { 149 COFFSymbolRef Symb = getCOFFSymbol(Ref); 150 const coff_section *Section = nullptr; 151 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 152 return EC; 153 154 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) 155 Result = UnknownAddressOrSize; 156 else if (Section) 157 Result = Section->VirtualAddress + Symb.getValue(); 158 else 159 Result = Symb.getValue(); 160 return object_error::success; 161 } 162 163 std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 164 SymbolRef::Type &Result) const { 165 COFFSymbolRef Symb = getCOFFSymbol(Ref); 166 Result = SymbolRef::ST_Other; 167 168 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && 169 Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { 170 Result = SymbolRef::ST_Unknown; 171 } else if (Symb.isFunctionDefinition()) { 172 Result = SymbolRef::ST_Function; 173 } else { 174 uint32_t Characteristics = 0; 175 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 176 const coff_section *Section = nullptr; 177 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 178 return EC; 179 Characteristics = Section->Characteristics; 180 } 181 if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 182 ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 183 Result = SymbolRef::ST_Data; 184 } 185 return object_error::success; 186 } 187 188 uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 189 COFFSymbolRef Symb = getCOFFSymbol(Ref); 190 uint32_t Result = SymbolRef::SF_None; 191 192 // TODO: Correctly set SF_FormatSpecific, SF_Common 193 194 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { 195 if (Symb.getValue() == 0) 196 Result |= SymbolRef::SF_Undefined; 197 else 198 Result |= SymbolRef::SF_Common; 199 } 200 201 202 // TODO: This are certainly too restrictive. 203 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL) 204 Result |= SymbolRef::SF_Global; 205 206 if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 207 Result |= SymbolRef::SF_Weak; 208 209 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) 210 Result |= SymbolRef::SF_Absolute; 211 212 return Result; 213 } 214 215 std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 216 uint64_t &Result) const { 217 // FIXME: Return the correct size. This requires looking at all the symbols 218 // in the same section as this symbol, and looking for either the next 219 // symbol, or the end of the section. 220 COFFSymbolRef Symb = getCOFFSymbol(Ref); 221 const coff_section *Section = nullptr; 222 if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) 223 return EC; 224 225 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) 226 Result = UnknownAddressOrSize; 227 else if (Section) 228 Result = Section->SizeOfRawData - Symb.getValue(); 229 else 230 Result = 0; 231 return object_error::success; 232 } 233 234 std::error_code 235 COFFObjectFile::getSymbolSection(DataRefImpl Ref, 236 section_iterator &Result) const { 237 COFFSymbolRef Symb = getCOFFSymbol(Ref); 238 if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 239 Result = section_end(); 240 } else { 241 const coff_section *Sec = nullptr; 242 if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) 243 return EC; 244 DataRefImpl Ref; 245 Ref.p = reinterpret_cast<uintptr_t>(Sec); 246 Result = section_iterator(SectionRef(Ref, this)); 247 } 248 return object_error::success; 249 } 250 251 void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 252 const coff_section *Sec = toSec(Ref); 253 Sec += 1; 254 Ref.p = reinterpret_cast<uintptr_t>(Sec); 255 } 256 257 std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref, 258 StringRef &Result) const { 259 const coff_section *Sec = toSec(Ref); 260 return getSectionName(Sec, Result); 261 } 262 263 std::error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref, 264 uint64_t &Result) const { 265 const coff_section *Sec = toSec(Ref); 266 Result = Sec->VirtualAddress; 267 return object_error::success; 268 } 269 270 std::error_code COFFObjectFile::getSectionSize(DataRefImpl Ref, 271 uint64_t &Result) const { 272 const coff_section *Sec = toSec(Ref); 273 Result = Sec->SizeOfRawData; 274 return object_error::success; 275 } 276 277 std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 278 StringRef &Result) const { 279 const coff_section *Sec = toSec(Ref); 280 ArrayRef<uint8_t> Res; 281 std::error_code EC = getSectionContents(Sec, Res); 282 Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 283 return EC; 284 } 285 286 std::error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref, 287 uint64_t &Res) const { 288 const coff_section *Sec = toSec(Ref); 289 Res = uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 290 return object_error::success; 291 } 292 293 std::error_code COFFObjectFile::isSectionText(DataRefImpl Ref, 294 bool &Result) const { 295 const coff_section *Sec = toSec(Ref); 296 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 297 return object_error::success; 298 } 299 300 std::error_code COFFObjectFile::isSectionData(DataRefImpl Ref, 301 bool &Result) const { 302 const coff_section *Sec = toSec(Ref); 303 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 304 return object_error::success; 305 } 306 307 std::error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref, 308 bool &Result) const { 309 const coff_section *Sec = toSec(Ref); 310 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 311 return object_error::success; 312 } 313 314 std::error_code 315 COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref, 316 bool &Result) const { 317 // FIXME: Unimplemented 318 Result = true; 319 return object_error::success; 320 } 321 322 std::error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref, 323 bool &Result) const { 324 const coff_section *Sec = toSec(Ref); 325 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 326 return object_error::success; 327 } 328 329 std::error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref, 330 bool &Result) const { 331 // FIXME: Unimplemented. 332 Result = false; 333 return object_error::success; 334 } 335 336 std::error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref, 337 bool &Result) const { 338 // FIXME: Unimplemented. 339 Result = false; 340 return object_error::success; 341 } 342 343 std::error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 344 DataRefImpl SymbRef, 345 bool &Result) const { 346 const coff_section *Sec = toSec(SecRef); 347 COFFSymbolRef Symb = getCOFFSymbol(SymbRef); 348 int32_t SecNumber = (Sec - SectionTable) + 1; 349 Result = SecNumber == Symb.getSectionNumber(); 350 return object_error::success; 351 } 352 353 relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 354 const coff_section *Sec = toSec(Ref); 355 DataRefImpl Ret; 356 if (Sec->NumberOfRelocations == 0) { 357 Ret.p = 0; 358 } else { 359 auto begin = reinterpret_cast<const coff_relocation*>( 360 base() + Sec->PointerToRelocations); 361 if (Sec->hasExtendedRelocations()) { 362 // Skip the first relocation entry repurposed to store the number of 363 // relocations. 364 begin++; 365 } 366 Ret.p = reinterpret_cast<uintptr_t>(begin); 367 } 368 return relocation_iterator(RelocationRef(Ret, this)); 369 } 370 371 static uint32_t getNumberOfRelocations(const coff_section *Sec, 372 const uint8_t *base) { 373 // The field for the number of relocations in COFF section table is only 374 // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 375 // NumberOfRelocations field, and the actual relocation count is stored in the 376 // VirtualAddress field in the first relocation entry. 377 if (Sec->hasExtendedRelocations()) { 378 auto *FirstReloc = reinterpret_cast<const coff_relocation*>( 379 base + Sec->PointerToRelocations); 380 return FirstReloc->VirtualAddress; 381 } 382 return Sec->NumberOfRelocations; 383 } 384 385 relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 386 const coff_section *Sec = toSec(Ref); 387 DataRefImpl Ret; 388 if (Sec->NumberOfRelocations == 0) { 389 Ret.p = 0; 390 } else { 391 auto begin = reinterpret_cast<const coff_relocation*>( 392 base() + Sec->PointerToRelocations); 393 uint32_t NumReloc = getNumberOfRelocations(Sec, base()); 394 Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc); 395 } 396 return relocation_iterator(RelocationRef(Ret, this)); 397 } 398 399 // Initialize the pointer to the symbol table. 400 std::error_code COFFObjectFile::initSymbolTablePtr() { 401 if (COFFHeader) 402 if (std::error_code EC = 403 getObject(SymbolTable16, Data, base() + getPointerToSymbolTable(), 404 getNumberOfSymbols() * getSymbolTableEntrySize())) 405 return EC; 406 407 if (COFFBigObjHeader) 408 if (std::error_code EC = 409 getObject(SymbolTable32, Data, base() + getPointerToSymbolTable(), 410 getNumberOfSymbols() * getSymbolTableEntrySize())) 411 return EC; 412 413 // Find string table. The first four byte of the string table contains the 414 // total size of the string table, including the size field itself. If the 415 // string table is empty, the value of the first four byte would be 4. 416 const uint8_t *StringTableAddr = 417 base() + getPointerToSymbolTable() + 418 getNumberOfSymbols() * getSymbolTableEntrySize(); 419 const ulittle32_t *StringTableSizePtr; 420 if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 421 return EC; 422 StringTableSize = *StringTableSizePtr; 423 if (std::error_code EC = 424 getObject(StringTable, Data, StringTableAddr, StringTableSize)) 425 return EC; 426 427 // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 428 // tools like cvtres write a size of 0 for an empty table instead of 4. 429 if (StringTableSize < 4) 430 StringTableSize = 4; 431 432 // Check that the string table is null terminated if has any in it. 433 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 434 return object_error::parse_failed; 435 return object_error::success; 436 } 437 438 // Returns the file offset for the given VA. 439 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 440 uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 441 : (uint64_t)PE32PlusHeader->ImageBase; 442 uint64_t Rva = Addr - ImageBase; 443 assert(Rva <= UINT32_MAX); 444 return getRvaPtr((uint32_t)Rva, Res); 445 } 446 447 // Returns the file offset for the given RVA. 448 std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 449 for (const SectionRef &S : sections()) { 450 const coff_section *Section = getCOFFSection(S); 451 uint32_t SectionStart = Section->VirtualAddress; 452 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 453 if (SectionStart <= Addr && Addr < SectionEnd) { 454 uint32_t Offset = Addr - SectionStart; 455 Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 456 return object_error::success; 457 } 458 } 459 return object_error::parse_failed; 460 } 461 462 // Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 463 // table entry. 464 std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint, 465 StringRef &Name) const { 466 uintptr_t IntPtr = 0; 467 if (std::error_code EC = getRvaPtr(Rva, IntPtr)) 468 return EC; 469 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 470 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 471 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 472 return object_error::success; 473 } 474 475 // Find the import table. 476 std::error_code COFFObjectFile::initImportTablePtr() { 477 // First, we get the RVA of the import table. If the file lacks a pointer to 478 // the import table, do nothing. 479 const data_directory *DataEntry; 480 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 481 return object_error::success; 482 483 // Do nothing if the pointer to import table is NULL. 484 if (DataEntry->RelativeVirtualAddress == 0) 485 return object_error::success; 486 487 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 488 // -1 because the last entry is the null entry. 489 NumberOfImportDirectory = DataEntry->Size / 490 sizeof(import_directory_table_entry) - 1; 491 492 // Find the section that contains the RVA. This is needed because the RVA is 493 // the import table's memory address which is different from its file offset. 494 uintptr_t IntPtr = 0; 495 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 496 return EC; 497 ImportDirectory = reinterpret_cast< 498 const import_directory_table_entry *>(IntPtr); 499 return object_error::success; 500 } 501 502 // Initializes DelayImportDirectory and NumberOfDelayImportDirectory. 503 std::error_code COFFObjectFile::initDelayImportTablePtr() { 504 const data_directory *DataEntry; 505 if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry)) 506 return object_error::success; 507 if (DataEntry->RelativeVirtualAddress == 0) 508 return object_error::success; 509 510 uint32_t RVA = DataEntry->RelativeVirtualAddress; 511 NumberOfDelayImportDirectory = DataEntry->Size / 512 sizeof(delay_import_directory_table_entry) - 1; 513 514 uintptr_t IntPtr = 0; 515 if (std::error_code EC = getRvaPtr(RVA, IntPtr)) 516 return EC; 517 DelayImportDirectory = reinterpret_cast< 518 const delay_import_directory_table_entry *>(IntPtr); 519 return object_error::success; 520 } 521 522 // Find the export table. 523 std::error_code COFFObjectFile::initExportTablePtr() { 524 // First, we get the RVA of the export table. If the file lacks a pointer to 525 // the export table, do nothing. 526 const data_directory *DataEntry; 527 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 528 return object_error::success; 529 530 // Do nothing if the pointer to export table is NULL. 531 if (DataEntry->RelativeVirtualAddress == 0) 532 return object_error::success; 533 534 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 535 uintptr_t IntPtr = 0; 536 if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 537 return EC; 538 ExportDirectory = 539 reinterpret_cast<const export_directory_table_entry *>(IntPtr); 540 return object_error::success; 541 } 542 543 COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 544 : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), 545 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), 546 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr), 547 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0), 548 ImportDirectory(nullptr), NumberOfImportDirectory(0), 549 DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0), 550 ExportDirectory(nullptr) { 551 // Check that we at least have enough room for a header. 552 if (!checkSize(Data, EC, sizeof(coff_file_header))) 553 return; 554 555 // The current location in the file where we are looking at. 556 uint64_t CurPtr = 0; 557 558 // PE header is optional and is present only in executables. If it exists, 559 // it is placed right after COFF header. 560 bool HasPEHeader = false; 561 562 // Check if this is a PE/COFF file. 563 if (base()[0] == 0x4d && base()[1] == 0x5a) { 564 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 565 // PE signature to find 'normal' COFF header. 566 if (!checkSize(Data, EC, 0x3c + 8)) 567 return; 568 CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); 569 // Check the PE magic bytes. ("PE\0\0") 570 if (std::memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 571 0) { 572 EC = object_error::parse_failed; 573 return; 574 } 575 CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes. 576 HasPEHeader = true; 577 } 578 579 if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 580 return; 581 582 // It might be a bigobj file, let's check. Note that COFF bigobj and COFF 583 // import libraries share a common prefix but bigobj is more restrictive. 584 if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN && 585 COFFHeader->NumberOfSections == uint16_t(0xffff) && 586 checkSize(Data, EC, sizeof(coff_bigobj_file_header))) { 587 if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr))) 588 return; 589 590 // Verify that we are dealing with bigobj. 591 if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion && 592 std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic, 593 sizeof(COFF::BigObjMagic)) == 0) { 594 COFFHeader = nullptr; 595 CurPtr += sizeof(coff_bigobj_file_header); 596 } else { 597 // It's not a bigobj. 598 COFFBigObjHeader = nullptr; 599 } 600 } 601 if (COFFHeader) { 602 // The prior checkSize call may have failed. This isn't a hard error 603 // because we were just trying to sniff out bigobj. 604 EC = object_error::success; 605 CurPtr += sizeof(coff_file_header); 606 607 if (COFFHeader->isImportLibrary()) 608 return; 609 } 610 611 if (HasPEHeader) { 612 const pe32_header *Header; 613 if ((EC = getObject(Header, Data, base() + CurPtr))) 614 return; 615 616 const uint8_t *DataDirAddr; 617 uint64_t DataDirSize; 618 if (Header->Magic == 0x10b) { 619 PE32Header = Header; 620 DataDirAddr = base() + CurPtr + sizeof(pe32_header); 621 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 622 } else if (Header->Magic == 0x20b) { 623 PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 624 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 625 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 626 } else { 627 // It's neither PE32 nor PE32+. 628 EC = object_error::parse_failed; 629 return; 630 } 631 if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 632 return; 633 CurPtr += COFFHeader->SizeOfOptionalHeader; 634 } 635 636 if ((EC = getObject(SectionTable, Data, base() + CurPtr, 637 getNumberOfSections() * sizeof(coff_section)))) 638 return; 639 640 // Initialize the pointer to the symbol table. 641 if (getPointerToSymbolTable() != 0) 642 if ((EC = initSymbolTablePtr())) 643 return; 644 645 // Initialize the pointer to the beginning of the import table. 646 if ((EC = initImportTablePtr())) 647 return; 648 if ((EC = initDelayImportTablePtr())) 649 return; 650 651 // Initialize the pointer to the export table. 652 if ((EC = initExportTablePtr())) 653 return; 654 655 EC = object_error::success; 656 } 657 658 basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 659 DataRefImpl Ret; 660 Ret.p = getSymbolTable(); 661 return basic_symbol_iterator(SymbolRef(Ret, this)); 662 } 663 664 basic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 665 // The symbol table ends where the string table begins. 666 DataRefImpl Ret; 667 Ret.p = reinterpret_cast<uintptr_t>(StringTable); 668 return basic_symbol_iterator(SymbolRef(Ret, this)); 669 } 670 671 import_directory_iterator COFFObjectFile::import_directory_begin() const { 672 return import_directory_iterator( 673 ImportDirectoryEntryRef(ImportDirectory, 0, this)); 674 } 675 676 import_directory_iterator COFFObjectFile::import_directory_end() const { 677 return import_directory_iterator( 678 ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 679 } 680 681 delay_import_directory_iterator 682 COFFObjectFile::delay_import_directory_begin() const { 683 return delay_import_directory_iterator( 684 DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this)); 685 } 686 687 delay_import_directory_iterator 688 COFFObjectFile::delay_import_directory_end() const { 689 return delay_import_directory_iterator( 690 DelayImportDirectoryEntryRef( 691 DelayImportDirectory, NumberOfDelayImportDirectory, this)); 692 } 693 694 export_directory_iterator COFFObjectFile::export_directory_begin() const { 695 return export_directory_iterator( 696 ExportDirectoryEntryRef(ExportDirectory, 0, this)); 697 } 698 699 export_directory_iterator COFFObjectFile::export_directory_end() const { 700 if (!ExportDirectory) 701 return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this)); 702 ExportDirectoryEntryRef Ref(ExportDirectory, 703 ExportDirectory->AddressTableEntries, this); 704 return export_directory_iterator(Ref); 705 } 706 707 section_iterator COFFObjectFile::section_begin() const { 708 DataRefImpl Ret; 709 Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 710 return section_iterator(SectionRef(Ret, this)); 711 } 712 713 section_iterator COFFObjectFile::section_end() const { 714 DataRefImpl Ret; 715 int NumSections = 716 COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections(); 717 Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 718 return section_iterator(SectionRef(Ret, this)); 719 } 720 721 uint8_t COFFObjectFile::getBytesInAddress() const { 722 return getArch() == Triple::x86_64 ? 8 : 4; 723 } 724 725 StringRef COFFObjectFile::getFileFormatName() const { 726 switch(getMachine()) { 727 case COFF::IMAGE_FILE_MACHINE_I386: 728 return "COFF-i386"; 729 case COFF::IMAGE_FILE_MACHINE_AMD64: 730 return "COFF-x86-64"; 731 case COFF::IMAGE_FILE_MACHINE_ARMNT: 732 return "COFF-ARM"; 733 default: 734 return "COFF-<unknown arch>"; 735 } 736 } 737 738 unsigned COFFObjectFile::getArch() const { 739 switch (getMachine()) { 740 case COFF::IMAGE_FILE_MACHINE_I386: 741 return Triple::x86; 742 case COFF::IMAGE_FILE_MACHINE_AMD64: 743 return Triple::x86_64; 744 case COFF::IMAGE_FILE_MACHINE_ARMNT: 745 return Triple::thumb; 746 default: 747 return Triple::UnknownArch; 748 } 749 } 750 751 std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 752 Res = PE32Header; 753 return object_error::success; 754 } 755 756 std::error_code 757 COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 758 Res = PE32PlusHeader; 759 return object_error::success; 760 } 761 762 std::error_code 763 COFFObjectFile::getDataDirectory(uint32_t Index, 764 const data_directory *&Res) const { 765 // Error if if there's no data directory or the index is out of range. 766 if (!DataDirectory) 767 return object_error::parse_failed; 768 assert(PE32Header || PE32PlusHeader); 769 uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 770 : PE32PlusHeader->NumberOfRvaAndSize; 771 if (Index > NumEnt) 772 return object_error::parse_failed; 773 Res = &DataDirectory[Index]; 774 return object_error::success; 775 } 776 777 std::error_code COFFObjectFile::getSection(int32_t Index, 778 const coff_section *&Result) const { 779 // Check for special index values. 780 if (COFF::isReservedSectionNumber(Index)) 781 Result = nullptr; 782 else if (Index > 0 && static_cast<uint32_t>(Index) <= getNumberOfSections()) 783 // We already verified the section table data, so no need to check again. 784 Result = SectionTable + (Index - 1); 785 else 786 return object_error::parse_failed; 787 return object_error::success; 788 } 789 790 std::error_code COFFObjectFile::getString(uint32_t Offset, 791 StringRef &Result) const { 792 if (StringTableSize <= 4) 793 // Tried to get a string from an empty string table. 794 return object_error::parse_failed; 795 if (Offset >= StringTableSize) 796 return object_error::unexpected_eof; 797 Result = StringRef(StringTable + Offset); 798 return object_error::success; 799 } 800 801 std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, 802 StringRef &Res) const { 803 // Check for string table entry. First 4 bytes are 0. 804 if (Symbol.getStringTableOffset().Zeroes == 0) { 805 uint32_t Offset = Symbol.getStringTableOffset().Offset; 806 if (std::error_code EC = getString(Offset, Res)) 807 return EC; 808 return object_error::success; 809 } 810 811 if (Symbol.getShortName()[COFF::NameSize - 1] == 0) 812 // Null terminated, let ::strlen figure out the length. 813 Res = StringRef(Symbol.getShortName()); 814 else 815 // Not null terminated, use all 8 bytes. 816 Res = StringRef(Symbol.getShortName(), COFF::NameSize); 817 return object_error::success; 818 } 819 820 ArrayRef<uint8_t> 821 COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { 822 const uint8_t *Aux = nullptr; 823 824 size_t SymbolSize = getSymbolTableEntrySize(); 825 if (Symbol.getNumberOfAuxSymbols() > 0) { 826 // AUX data comes immediately after the symbol in COFF 827 Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize; 828 # ifndef NDEBUG 829 // Verify that the Aux symbol points to a valid entry in the symbol table. 830 uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 831 if (Offset < getPointerToSymbolTable() || 832 Offset >= 833 getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize)) 834 report_fatal_error("Aux Symbol data was outside of symbol table."); 835 836 assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 && 837 "Aux Symbol data did not point to the beginning of a symbol"); 838 # endif 839 } 840 return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize); 841 } 842 843 std::error_code COFFObjectFile::getSectionName(const coff_section *Sec, 844 StringRef &Res) const { 845 StringRef Name; 846 if (Sec->Name[COFF::NameSize - 1] == 0) 847 // Null terminated, let ::strlen figure out the length. 848 Name = Sec->Name; 849 else 850 // Not null terminated, use all 8 bytes. 851 Name = StringRef(Sec->Name, COFF::NameSize); 852 853 // Check for string table entry. First byte is '/'. 854 if (Name[0] == '/') { 855 uint32_t Offset; 856 if (Name[1] == '/') { 857 if (decodeBase64StringEntry(Name.substr(2), Offset)) 858 return object_error::parse_failed; 859 } else { 860 if (Name.substr(1).getAsInteger(10, Offset)) 861 return object_error::parse_failed; 862 } 863 if (std::error_code EC = getString(Offset, Name)) 864 return EC; 865 } 866 867 Res = Name; 868 return object_error::success; 869 } 870 871 std::error_code 872 COFFObjectFile::getSectionContents(const coff_section *Sec, 873 ArrayRef<uint8_t> &Res) const { 874 // PointerToRawData and SizeOfRawData won't make sense for BSS sections, don't 875 // do anything interesting for them. 876 assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 && 877 "BSS sections don't have contents!"); 878 // The only thing that we need to verify is that the contents is contained 879 // within the file bounds. We don't need to make sure it doesn't cover other 880 // data, as there's nothing that says that is not allowed. 881 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 882 uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; 883 if (ConEnd > uintptr_t(Data.getBufferEnd())) 884 return object_error::parse_failed; 885 Res = makeArrayRef(reinterpret_cast<const uint8_t*>(ConStart), 886 Sec->SizeOfRawData); 887 return object_error::success; 888 } 889 890 const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 891 return reinterpret_cast<const coff_relocation*>(Rel.p); 892 } 893 894 void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 895 Rel.p = reinterpret_cast<uintptr_t>( 896 reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 897 } 898 899 std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 900 uint64_t &Res) const { 901 report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 902 } 903 904 std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 905 uint64_t &Res) const { 906 Res = toRel(Rel)->VirtualAddress; 907 return object_error::success; 908 } 909 910 symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 911 const coff_relocation *R = toRel(Rel); 912 DataRefImpl Ref; 913 if (SymbolTable16) 914 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex); 915 else if (SymbolTable32) 916 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex); 917 else 918 llvm_unreachable("no symbol table pointer!"); 919 return symbol_iterator(SymbolRef(Ref, this)); 920 } 921 922 std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 923 uint64_t &Res) const { 924 const coff_relocation* R = toRel(Rel); 925 Res = R->Type; 926 return object_error::success; 927 } 928 929 const coff_section * 930 COFFObjectFile::getCOFFSection(const SectionRef &Section) const { 931 return toSec(Section.getRawDataRefImpl()); 932 } 933 934 COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const { 935 if (SymbolTable16) 936 return toSymb<coff_symbol16>(Ref); 937 if (SymbolTable32) 938 return toSymb<coff_symbol32>(Ref); 939 llvm_unreachable("no symbol table pointer!"); 940 } 941 942 COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 943 return getCOFFSymbol(Symbol.getRawDataRefImpl()); 944 } 945 946 const coff_relocation * 947 COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 948 return toRel(Reloc.getRawDataRefImpl()); 949 } 950 951 #define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 952 case COFF::reloc_type: \ 953 Res = #reloc_type; \ 954 break; 955 956 std::error_code 957 COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 958 SmallVectorImpl<char> &Result) const { 959 const coff_relocation *Reloc = toRel(Rel); 960 StringRef Res; 961 switch (getMachine()) { 962 case COFF::IMAGE_FILE_MACHINE_AMD64: 963 switch (Reloc->Type) { 964 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 965 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 966 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 967 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 968 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 969 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 970 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 971 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 972 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 973 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 974 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 975 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 976 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 977 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 978 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 979 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 980 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 981 default: 982 Res = "Unknown"; 983 } 984 break; 985 case COFF::IMAGE_FILE_MACHINE_ARMNT: 986 switch (Reloc->Type) { 987 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE); 988 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32); 989 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB); 990 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24); 991 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11); 992 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN); 993 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24); 994 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11); 995 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION); 996 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL); 997 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A); 998 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T); 999 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T); 1000 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T); 1001 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T); 1002 default: 1003 Res = "Unknown"; 1004 } 1005 break; 1006 case COFF::IMAGE_FILE_MACHINE_I386: 1007 switch (Reloc->Type) { 1008 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 1009 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 1010 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 1011 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 1012 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 1013 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 1014 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 1015 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 1016 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 1017 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 1018 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 1019 default: 1020 Res = "Unknown"; 1021 } 1022 break; 1023 default: 1024 Res = "Unknown"; 1025 } 1026 Result.append(Res.begin(), Res.end()); 1027 return object_error::success; 1028 } 1029 1030 #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 1031 1032 std::error_code 1033 COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 1034 SmallVectorImpl<char> &Result) const { 1035 const coff_relocation *Reloc = toRel(Rel); 1036 DataRefImpl Sym; 1037 ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex); 1038 if (std::error_code EC = Symb.getError()) 1039 return EC; 1040 Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr()); 1041 StringRef SymName; 1042 if (std::error_code EC = getSymbolName(Sym, SymName)) 1043 return EC; 1044 Result.append(SymName.begin(), SymName.end()); 1045 return object_error::success; 1046 } 1047 1048 bool COFFObjectFile::isRelocatableObject() const { 1049 return !DataDirectory; 1050 } 1051 1052 bool ImportDirectoryEntryRef:: 1053 operator==(const ImportDirectoryEntryRef &Other) const { 1054 return ImportTable == Other.ImportTable && Index == Other.Index; 1055 } 1056 1057 void ImportDirectoryEntryRef::moveNext() { 1058 ++Index; 1059 } 1060 1061 std::error_code ImportDirectoryEntryRef::getImportTableEntry( 1062 const import_directory_table_entry *&Result) const { 1063 Result = ImportTable + Index; 1064 return object_error::success; 1065 } 1066 1067 static imported_symbol_iterator 1068 makeImportedSymbolIterator(const COFFObjectFile *Object, 1069 uintptr_t Ptr, int Index) { 1070 if (Object->getBytesInAddress() == 4) { 1071 auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr); 1072 return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 1073 } 1074 auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr); 1075 return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 1076 } 1077 1078 static imported_symbol_iterator 1079 importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) { 1080 uintptr_t IntPtr = 0; 1081 Object->getRvaPtr(RVA, IntPtr); 1082 return makeImportedSymbolIterator(Object, IntPtr, 0); 1083 } 1084 1085 static imported_symbol_iterator 1086 importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) { 1087 uintptr_t IntPtr = 0; 1088 Object->getRvaPtr(RVA, IntPtr); 1089 // Forward the pointer to the last entry which is null. 1090 int Index = 0; 1091 if (Object->getBytesInAddress() == 4) { 1092 auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr); 1093 while (*Entry++) 1094 ++Index; 1095 } else { 1096 auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr); 1097 while (*Entry++) 1098 ++Index; 1099 } 1100 return makeImportedSymbolIterator(Object, IntPtr, Index); 1101 } 1102 1103 imported_symbol_iterator 1104 ImportDirectoryEntryRef::imported_symbol_begin() const { 1105 return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA, 1106 OwningObject); 1107 } 1108 1109 imported_symbol_iterator 1110 ImportDirectoryEntryRef::imported_symbol_end() const { 1111 return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA, 1112 OwningObject); 1113 } 1114 1115 std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 1116 uintptr_t IntPtr = 0; 1117 if (std::error_code EC = 1118 OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr)) 1119 return EC; 1120 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1121 return object_error::success; 1122 } 1123 1124 std::error_code 1125 ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const { 1126 Result = ImportTable[Index].ImportLookupTableRVA; 1127 return object_error::success; 1128 } 1129 1130 std::error_code 1131 ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const { 1132 Result = ImportTable[Index].ImportAddressTableRVA; 1133 return object_error::success; 1134 } 1135 1136 std::error_code ImportDirectoryEntryRef::getImportLookupEntry( 1137 const import_lookup_table_entry32 *&Result) const { 1138 uintptr_t IntPtr = 0; 1139 uint32_t RVA = ImportTable[Index].ImportLookupTableRVA; 1140 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1141 return EC; 1142 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1143 return object_error::success; 1144 } 1145 1146 bool DelayImportDirectoryEntryRef:: 1147 operator==(const DelayImportDirectoryEntryRef &Other) const { 1148 return Table == Other.Table && Index == Other.Index; 1149 } 1150 1151 void DelayImportDirectoryEntryRef::moveNext() { 1152 ++Index; 1153 } 1154 1155 imported_symbol_iterator 1156 DelayImportDirectoryEntryRef::imported_symbol_begin() const { 1157 return importedSymbolBegin(Table[Index].DelayImportNameTable, 1158 OwningObject); 1159 } 1160 1161 imported_symbol_iterator 1162 DelayImportDirectoryEntryRef::imported_symbol_end() const { 1163 return importedSymbolEnd(Table[Index].DelayImportNameTable, 1164 OwningObject); 1165 } 1166 1167 std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const { 1168 uintptr_t IntPtr = 0; 1169 if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr)) 1170 return EC; 1171 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1172 return object_error::success; 1173 } 1174 1175 std::error_code DelayImportDirectoryEntryRef:: 1176 getDelayImportTable(const delay_import_directory_table_entry *&Result) const { 1177 Result = Table; 1178 return object_error::success; 1179 } 1180 1181 bool ExportDirectoryEntryRef:: 1182 operator==(const ExportDirectoryEntryRef &Other) const { 1183 return ExportTable == Other.ExportTable && Index == Other.Index; 1184 } 1185 1186 void ExportDirectoryEntryRef::moveNext() { 1187 ++Index; 1188 } 1189 1190 // Returns the name of the current export symbol. If the symbol is exported only 1191 // by ordinal, the empty string is set as a result. 1192 std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 1193 uintptr_t IntPtr = 0; 1194 if (std::error_code EC = 1195 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 1196 return EC; 1197 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1198 return object_error::success; 1199 } 1200 1201 // Returns the starting ordinal number. 1202 std::error_code 1203 ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 1204 Result = ExportTable->OrdinalBase; 1205 return object_error::success; 1206 } 1207 1208 // Returns the export ordinal of the current export symbol. 1209 std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 1210 Result = ExportTable->OrdinalBase + Index; 1211 return object_error::success; 1212 } 1213 1214 // Returns the address of the current export symbol. 1215 std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 1216 uintptr_t IntPtr = 0; 1217 if (std::error_code EC = 1218 OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr)) 1219 return EC; 1220 const export_address_table_entry *entry = 1221 reinterpret_cast<const export_address_table_entry *>(IntPtr); 1222 Result = entry[Index].ExportRVA; 1223 return object_error::success; 1224 } 1225 1226 // Returns the name of the current export symbol. If the symbol is exported only 1227 // by ordinal, the empty string is set as a result. 1228 std::error_code 1229 ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 1230 uintptr_t IntPtr = 0; 1231 if (std::error_code EC = 1232 OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr)) 1233 return EC; 1234 const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 1235 1236 uint32_t NumEntries = ExportTable->NumberOfNamePointers; 1237 int Offset = 0; 1238 for (const ulittle16_t *I = Start, *E = Start + NumEntries; 1239 I < E; ++I, ++Offset) { 1240 if (*I != Index) 1241 continue; 1242 if (std::error_code EC = 1243 OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr)) 1244 return EC; 1245 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 1246 if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 1247 return EC; 1248 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1249 return object_error::success; 1250 } 1251 Result = ""; 1252 return object_error::success; 1253 } 1254 1255 bool ImportedSymbolRef:: 1256 operator==(const ImportedSymbolRef &Other) const { 1257 return Entry32 == Other.Entry32 && Entry64 == Other.Entry64 1258 && Index == Other.Index; 1259 } 1260 1261 void ImportedSymbolRef::moveNext() { 1262 ++Index; 1263 } 1264 1265 std::error_code 1266 ImportedSymbolRef::getSymbolName(StringRef &Result) const { 1267 uint32_t RVA; 1268 if (Entry32) { 1269 // If a symbol is imported only by ordinal, it has no name. 1270 if (Entry32[Index].isOrdinal()) 1271 return object_error::success; 1272 RVA = Entry32[Index].getHintNameRVA(); 1273 } else { 1274 if (Entry64[Index].isOrdinal()) 1275 return object_error::success; 1276 RVA = Entry64[Index].getHintNameRVA(); 1277 } 1278 uintptr_t IntPtr = 0; 1279 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1280 return EC; 1281 // +2 because the first two bytes is hint. 1282 Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2)); 1283 return object_error::success; 1284 } 1285 1286 std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const { 1287 uint32_t RVA; 1288 if (Entry32) { 1289 if (Entry32[Index].isOrdinal()) { 1290 Result = Entry32[Index].getOrdinal(); 1291 return object_error::success; 1292 } 1293 RVA = Entry32[Index].getHintNameRVA(); 1294 } else { 1295 if (Entry64[Index].isOrdinal()) { 1296 Result = Entry64[Index].getOrdinal(); 1297 return object_error::success; 1298 } 1299 RVA = Entry64[Index].getHintNameRVA(); 1300 } 1301 uintptr_t IntPtr = 0; 1302 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1303 return EC; 1304 Result = *reinterpret_cast<const ulittle16_t *>(IntPtr); 1305 return object_error::success; 1306 } 1307 1308 ErrorOr<std::unique_ptr<COFFObjectFile>> 1309 ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { 1310 std::error_code EC; 1311 std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC)); 1312 if (EC) 1313 return EC; 1314 return std::move(Ret); 1315 } 1316