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