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