COFFObjectFile.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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 25using namespace llvm; 26using namespace object; 27 28using support::ulittle8_t; 29using support::ulittle16_t; 30using support::ulittle32_t; 31using support::little16_t; 32 33// Returns false if size is greater than the buffer size. And sets ec. 34static bool checkSize(const MemoryBuffer *M, 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. 44template<typename T> 45static error_code getObject(const T *&Obj, const MemoryBuffer *M, 46 const uint8_t *Ptr, const size_t Size = sizeof(T)) { 47 uintptr_t Addr = uintptr_t(Ptr); 48 if (Addr + Size < Addr || 49 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. 59static 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 91const coff_symbol *COFFObjectFile::toSymb(DataRefImpl Ref) const { 92 const coff_symbol *Addr = reinterpret_cast<const coff_symbol*>(Ref.p); 93 94# ifndef NDEBUG 95 // Verify that the symbol points to a valid entry in the symbol table. 96 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 97 if (Offset < COFFHeader->PointerToSymbolTable 98 || Offset >= COFFHeader->PointerToSymbolTable 99 + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 100 report_fatal_error("Symbol was outside of symbol table."); 101 102 assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 103 == 0 && "Symbol did not point to the beginning of a symbol"); 104# endif 105 106 return Addr; 107} 108 109const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 110 const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 111 112# ifndef NDEBUG 113 // Verify that the section points to a valid entry in the section table. 114 if (Addr < SectionTable 115 || Addr >= (SectionTable + COFFHeader->NumberOfSections)) 116 report_fatal_error("Section was outside of section table."); 117 118 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 119 assert(Offset % sizeof(coff_section) == 0 && 120 "Section did not point to the beginning of a section"); 121# endif 122 123 return Addr; 124} 125 126void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 127 const coff_symbol *Symb = toSymb(Ref); 128 Symb += 1 + Symb->NumberOfAuxSymbols; 129 Ref.p = reinterpret_cast<uintptr_t>(Symb); 130} 131 132error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 133 StringRef &Result) const { 134 const coff_symbol *Symb = toSymb(Ref); 135 return getSymbolName(Symb, Result); 136} 137 138error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 139 uint64_t &Result) const { 140 const coff_symbol *Symb = toSymb(Ref); 141 const coff_section *Section = nullptr; 142 if (error_code EC = getSection(Symb->SectionNumber, Section)) 143 return EC; 144 145 if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) 146 Result = UnknownAddressOrSize; 147 else if (Section) 148 Result = Section->VirtualAddress + Symb->Value; 149 else 150 Result = Symb->Value; 151 return object_error::success; 152} 153 154error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 155 SymbolRef::Type &Result) const { 156 const coff_symbol *Symb = toSymb(Ref); 157 Result = SymbolRef::ST_Other; 158 if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && 159 Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 160 Result = SymbolRef::ST_Unknown; 161 } else if (Symb->isFunctionDefinition()) { 162 Result = SymbolRef::ST_Function; 163 } else { 164 uint32_t Characteristics = 0; 165 if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { 166 const coff_section *Section = nullptr; 167 if (error_code EC = getSection(Symb->SectionNumber, Section)) 168 return EC; 169 Characteristics = Section->Characteristics; 170 } 171 if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 172 ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 173 Result = SymbolRef::ST_Data; 174 } 175 return object_error::success; 176} 177 178uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 179 const coff_symbol *Symb = toSymb(Ref); 180 uint32_t Result = SymbolRef::SF_None; 181 182 // TODO: Correctly set SF_FormatSpecific, SF_Common 183 184 if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 185 if (Symb->Value == 0) 186 Result |= SymbolRef::SF_Undefined; 187 else 188 Result |= SymbolRef::SF_Common; 189 } 190 191 192 // TODO: This are certainly too restrictive. 193 if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 194 Result |= SymbolRef::SF_Global; 195 196 if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 197 Result |= SymbolRef::SF_Weak; 198 199 if (Symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE) 200 Result |= SymbolRef::SF_Absolute; 201 202 return Result; 203} 204 205error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 206 uint64_t &Result) const { 207 // FIXME: Return the correct size. This requires looking at all the symbols 208 // in the same section as this symbol, and looking for either the next 209 // symbol, or the end of the section. 210 const coff_symbol *Symb = toSymb(Ref); 211 const coff_section *Section = nullptr; 212 if (error_code EC = getSection(Symb->SectionNumber, Section)) 213 return EC; 214 215 if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) 216 Result = UnknownAddressOrSize; 217 else if (Section) 218 Result = Section->SizeOfRawData - Symb->Value; 219 else 220 Result = 0; 221 return object_error::success; 222} 223 224error_code COFFObjectFile::getSymbolSection(DataRefImpl Ref, 225 section_iterator &Result) const { 226 const coff_symbol *Symb = toSymb(Ref); 227 if (COFF::isReservedSectionNumber(Symb->SectionNumber)) { 228 Result = section_end(); 229 } else { 230 const coff_section *Sec = nullptr; 231 if (error_code EC = getSection(Symb->SectionNumber, Sec)) return EC; 232 DataRefImpl Ref; 233 Ref.p = reinterpret_cast<uintptr_t>(Sec); 234 Result = section_iterator(SectionRef(Ref, this)); 235 } 236 return object_error::success; 237} 238 239void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 240 const coff_section *Sec = toSec(Ref); 241 Sec += 1; 242 Ref.p = reinterpret_cast<uintptr_t>(Sec); 243} 244 245error_code COFFObjectFile::getSectionName(DataRefImpl Ref, 246 StringRef &Result) const { 247 const coff_section *Sec = toSec(Ref); 248 return getSectionName(Sec, Result); 249} 250 251error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref, 252 uint64_t &Result) const { 253 const coff_section *Sec = toSec(Ref); 254 Result = Sec->VirtualAddress; 255 return object_error::success; 256} 257 258error_code COFFObjectFile::getSectionSize(DataRefImpl Ref, 259 uint64_t &Result) const { 260 const coff_section *Sec = toSec(Ref); 261 Result = Sec->SizeOfRawData; 262 return object_error::success; 263} 264 265error_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 266 StringRef &Result) const { 267 const coff_section *Sec = toSec(Ref); 268 ArrayRef<uint8_t> Res; 269 error_code EC = getSectionContents(Sec, Res); 270 Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 271 return EC; 272} 273 274error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref, 275 uint64_t &Res) const { 276 const coff_section *Sec = toSec(Ref); 277 if (!Sec) 278 return object_error::parse_failed; 279 Res = uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 280 return object_error::success; 281} 282 283error_code COFFObjectFile::isSectionText(DataRefImpl Ref, 284 bool &Result) const { 285 const coff_section *Sec = toSec(Ref); 286 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 287 return object_error::success; 288} 289 290error_code COFFObjectFile::isSectionData(DataRefImpl Ref, 291 bool &Result) const { 292 const coff_section *Sec = toSec(Ref); 293 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 294 return object_error::success; 295} 296 297error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref, 298 bool &Result) const { 299 const coff_section *Sec = toSec(Ref); 300 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 301 return object_error::success; 302} 303 304error_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref, 305 bool &Result) const { 306 // FIXME: Unimplemented 307 Result = true; 308 return object_error::success; 309} 310 311error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref, 312 bool &Result) const { 313 const coff_section *Sec = toSec(Ref); 314 Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 315 return object_error::success; 316} 317 318error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref, 319 bool &Result) const { 320 // FIXME: Unimplemented. 321 Result = false; 322 return object_error::success; 323} 324 325error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref, 326 bool &Result) const { 327 // FIXME: Unimplemented. 328 Result = false; 329 return object_error::success; 330} 331 332error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 333 DataRefImpl SymbRef, 334 bool &Result) const { 335 const coff_section *Sec = toSec(SecRef); 336 const coff_symbol *Symb = toSymb(SymbRef); 337 const coff_section *SymbSec = nullptr; 338 if (error_code EC = getSection(Symb->SectionNumber, SymbSec)) return EC; 339 if (SymbSec == Sec) 340 Result = true; 341 else 342 Result = false; 343 return object_error::success; 344} 345 346relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 347 const coff_section *Sec = toSec(Ref); 348 DataRefImpl Ret; 349 if (Sec->NumberOfRelocations == 0) { 350 Ret.p = 0; 351 } else { 352 auto begin = reinterpret_cast<const coff_relocation*>( 353 base() + Sec->PointerToRelocations); 354 if (Sec->hasExtendedRelocations()) { 355 // Skip the first relocation entry repurposed to store the number of 356 // relocations. 357 begin++; 358 } 359 Ret.p = reinterpret_cast<uintptr_t>(begin); 360 } 361 return relocation_iterator(RelocationRef(Ret, this)); 362} 363 364static uint32_t getNumberOfRelocations(const coff_section *Sec, 365 const uint8_t *base) { 366 // The field for the number of relocations in COFF section table is only 367 // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 368 // NumberOfRelocations field, and the actual relocation count is stored in the 369 // VirtualAddress field in the first relocation entry. 370 if (Sec->hasExtendedRelocations()) { 371 auto *FirstReloc = reinterpret_cast<const coff_relocation*>( 372 base + Sec->PointerToRelocations); 373 return FirstReloc->VirtualAddress; 374 } 375 return Sec->NumberOfRelocations; 376} 377 378relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 379 const coff_section *Sec = toSec(Ref); 380 DataRefImpl Ret; 381 if (Sec->NumberOfRelocations == 0) { 382 Ret.p = 0; 383 } else { 384 auto begin = reinterpret_cast<const coff_relocation*>( 385 base() + Sec->PointerToRelocations); 386 uint32_t NumReloc = getNumberOfRelocations(Sec, base()); 387 Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc); 388 } 389 return relocation_iterator(RelocationRef(Ret, this)); 390} 391 392// Initialize the pointer to the symbol table. 393error_code COFFObjectFile::initSymbolTablePtr() { 394 if (error_code EC = getObject( 395 SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable, 396 COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 397 return EC; 398 399 // Find string table. The first four byte of the string table contains the 400 // total size of the string table, including the size field itself. If the 401 // string table is empty, the value of the first four byte would be 4. 402 const uint8_t *StringTableAddr = 403 base() + COFFHeader->PointerToSymbolTable + 404 COFFHeader->NumberOfSymbols * sizeof(coff_symbol); 405 const ulittle32_t *StringTableSizePtr; 406 if (error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 407 return EC; 408 StringTableSize = *StringTableSizePtr; 409 if (error_code EC = 410 getObject(StringTable, Data, StringTableAddr, StringTableSize)) 411 return EC; 412 413 // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 414 // tools like cvtres write a size of 0 for an empty table instead of 4. 415 if (StringTableSize < 4) 416 StringTableSize = 4; 417 418 // Check that the string table is null terminated if has any in it. 419 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 420 return object_error::parse_failed; 421 return object_error::success; 422} 423 424// Returns the file offset for the given VA. 425error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 426 uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 427 : (uint64_t)PE32PlusHeader->ImageBase; 428 uint64_t Rva = Addr - ImageBase; 429 assert(Rva <= UINT32_MAX); 430 return getRvaPtr((uint32_t)Rva, Res); 431} 432 433// Returns the file offset for the given RVA. 434error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 435 for (const SectionRef &S : sections()) { 436 const coff_section *Section = getCOFFSection(S); 437 uint32_t SectionStart = Section->VirtualAddress; 438 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 439 if (SectionStart <= Addr && Addr < SectionEnd) { 440 uint32_t Offset = Addr - SectionStart; 441 Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 442 return object_error::success; 443 } 444 } 445 return object_error::parse_failed; 446} 447 448// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 449// table entry. 450error_code COFFObjectFile:: 451getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const { 452 uintptr_t IntPtr = 0; 453 if (error_code EC = getRvaPtr(Rva, IntPtr)) 454 return EC; 455 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 456 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 457 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 458 return object_error::success; 459} 460 461// Find the import table. 462error_code COFFObjectFile::initImportTablePtr() { 463 // First, we get the RVA of the import table. If the file lacks a pointer to 464 // the import table, do nothing. 465 const data_directory *DataEntry; 466 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 467 return object_error::success; 468 469 // Do nothing if the pointer to import table is NULL. 470 if (DataEntry->RelativeVirtualAddress == 0) 471 return object_error::success; 472 473 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 474 NumberOfImportDirectory = DataEntry->Size / 475 sizeof(import_directory_table_entry); 476 477 // Find the section that contains the RVA. This is needed because the RVA is 478 // the import table's memory address which is different from its file offset. 479 uintptr_t IntPtr = 0; 480 if (error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 481 return EC; 482 ImportDirectory = reinterpret_cast< 483 const import_directory_table_entry *>(IntPtr); 484 return object_error::success; 485} 486 487// Find the export table. 488error_code COFFObjectFile::initExportTablePtr() { 489 // First, we get the RVA of the export table. If the file lacks a pointer to 490 // the export table, do nothing. 491 const data_directory *DataEntry; 492 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 493 return object_error::success; 494 495 // Do nothing if the pointer to export table is NULL. 496 if (DataEntry->RelativeVirtualAddress == 0) 497 return object_error::success; 498 499 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 500 uintptr_t IntPtr = 0; 501 if (error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 502 return EC; 503 ExportDirectory = 504 reinterpret_cast<const export_directory_table_entry *>(IntPtr); 505 return object_error::success; 506} 507 508COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC, 509 bool BufferOwned) 510 : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(nullptr), 511 PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr), 512 SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr), 513 StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0), 514 ExportDirectory(nullptr) { 515 // Check that we at least have enough room for a header. 516 if (!checkSize(Data, EC, sizeof(coff_file_header))) return; 517 518 // The current location in the file where we are looking at. 519 uint64_t CurPtr = 0; 520 521 // PE header is optional and is present only in executables. If it exists, 522 // it is placed right after COFF header. 523 bool HasPEHeader = false; 524 525 // Check if this is a PE/COFF file. 526 if (base()[0] == 0x4d && base()[1] == 0x5a) { 527 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 528 // PE signature to find 'normal' COFF header. 529 if (!checkSize(Data, EC, 0x3c + 8)) return; 530 CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); 531 // Check the PE magic bytes. ("PE\0\0") 532 if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) { 533 EC = object_error::parse_failed; 534 return; 535 } 536 CurPtr += 4; // Skip the PE magic bytes. 537 HasPEHeader = true; 538 } 539 540 if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 541 return; 542 CurPtr += sizeof(coff_file_header); 543 544 if (HasPEHeader) { 545 const pe32_header *Header; 546 if ((EC = getObject(Header, Data, base() + CurPtr))) 547 return; 548 549 const uint8_t *DataDirAddr; 550 uint64_t DataDirSize; 551 if (Header->Magic == 0x10b) { 552 PE32Header = Header; 553 DataDirAddr = base() + CurPtr + sizeof(pe32_header); 554 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 555 } else if (Header->Magic == 0x20b) { 556 PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 557 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 558 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 559 } else { 560 // It's neither PE32 nor PE32+. 561 EC = object_error::parse_failed; 562 return; 563 } 564 if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 565 return; 566 CurPtr += COFFHeader->SizeOfOptionalHeader; 567 } 568 569 if (COFFHeader->isImportLibrary()) 570 return; 571 572 if ((EC = getObject(SectionTable, Data, base() + CurPtr, 573 COFFHeader->NumberOfSections * sizeof(coff_section)))) 574 return; 575 576 // Initialize the pointer to the symbol table. 577 if (COFFHeader->PointerToSymbolTable != 0) 578 if ((EC = initSymbolTablePtr())) 579 return; 580 581 // Initialize the pointer to the beginning of the import table. 582 if ((EC = initImportTablePtr())) 583 return; 584 585 // Initialize the pointer to the export table. 586 if ((EC = initExportTablePtr())) 587 return; 588 589 EC = object_error::success; 590} 591 592basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 593 DataRefImpl Ret; 594 Ret.p = reinterpret_cast<uintptr_t>(SymbolTable); 595 return basic_symbol_iterator(SymbolRef(Ret, this)); 596} 597 598basic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 599 // The symbol table ends where the string table begins. 600 DataRefImpl Ret; 601 Ret.p = reinterpret_cast<uintptr_t>(StringTable); 602 return basic_symbol_iterator(SymbolRef(Ret, this)); 603} 604 605library_iterator COFFObjectFile::needed_library_begin() const { 606 // TODO: implement 607 report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 608} 609 610library_iterator COFFObjectFile::needed_library_end() const { 611 // TODO: implement 612 report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 613} 614 615StringRef COFFObjectFile::getLoadName() const { 616 // COFF does not have this field. 617 return ""; 618} 619 620import_directory_iterator COFFObjectFile::import_directory_begin() const { 621 return import_directory_iterator( 622 ImportDirectoryEntryRef(ImportDirectory, 0, this)); 623} 624 625import_directory_iterator COFFObjectFile::import_directory_end() const { 626 return import_directory_iterator( 627 ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 628} 629 630export_directory_iterator COFFObjectFile::export_directory_begin() const { 631 return export_directory_iterator( 632 ExportDirectoryEntryRef(ExportDirectory, 0, this)); 633} 634 635export_directory_iterator COFFObjectFile::export_directory_end() const { 636 if (!ExportDirectory) 637 return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this)); 638 ExportDirectoryEntryRef Ref(ExportDirectory, 639 ExportDirectory->AddressTableEntries, this); 640 return export_directory_iterator(Ref); 641} 642 643section_iterator COFFObjectFile::section_begin() const { 644 DataRefImpl Ret; 645 Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 646 return section_iterator(SectionRef(Ret, this)); 647} 648 649section_iterator COFFObjectFile::section_end() const { 650 DataRefImpl Ret; 651 int NumSections = COFFHeader->isImportLibrary() 652 ? 0 : COFFHeader->NumberOfSections; 653 Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 654 return section_iterator(SectionRef(Ret, this)); 655} 656 657uint8_t COFFObjectFile::getBytesInAddress() const { 658 return getArch() == Triple::x86_64 ? 8 : 4; 659} 660 661StringRef COFFObjectFile::getFileFormatName() const { 662 switch(COFFHeader->Machine) { 663 case COFF::IMAGE_FILE_MACHINE_I386: 664 return "COFF-i386"; 665 case COFF::IMAGE_FILE_MACHINE_AMD64: 666 return "COFF-x86-64"; 667 case COFF::IMAGE_FILE_MACHINE_ARMNT: 668 return "COFF-ARM"; 669 default: 670 return "COFF-<unknown arch>"; 671 } 672} 673 674unsigned COFFObjectFile::getArch() const { 675 switch(COFFHeader->Machine) { 676 case COFF::IMAGE_FILE_MACHINE_I386: 677 return Triple::x86; 678 case COFF::IMAGE_FILE_MACHINE_AMD64: 679 return Triple::x86_64; 680 case COFF::IMAGE_FILE_MACHINE_ARMNT: 681 return Triple::thumb; 682 default: 683 return Triple::UnknownArch; 684 } 685} 686 687// This method is kept here because lld uses this. As soon as we make 688// lld to use getCOFFHeader, this method will be removed. 689error_code COFFObjectFile::getHeader(const coff_file_header *&Res) const { 690 return getCOFFHeader(Res); 691} 692 693error_code COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const { 694 Res = COFFHeader; 695 return object_error::success; 696} 697 698error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 699 Res = PE32Header; 700 return object_error::success; 701} 702 703error_code 704COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 705 Res = PE32PlusHeader; 706 return object_error::success; 707} 708 709error_code COFFObjectFile::getDataDirectory(uint32_t Index, 710 const data_directory *&Res) const { 711 // Error if if there's no data directory or the index is out of range. 712 if (!DataDirectory) 713 return object_error::parse_failed; 714 assert(PE32Header || PE32PlusHeader); 715 uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 716 : PE32PlusHeader->NumberOfRvaAndSize; 717 if (Index > NumEnt) 718 return object_error::parse_failed; 719 Res = &DataDirectory[Index]; 720 return object_error::success; 721} 722 723error_code COFFObjectFile::getSection(int32_t Index, 724 const coff_section *&Result) const { 725 // Check for special index values. 726 if (COFF::isReservedSectionNumber(Index)) 727 Result = nullptr; 728 else if (Index > 0 && Index <= COFFHeader->NumberOfSections) 729 // We already verified the section table data, so no need to check again. 730 Result = SectionTable + (Index - 1); 731 else 732 return object_error::parse_failed; 733 return object_error::success; 734} 735 736error_code COFFObjectFile::getString(uint32_t Offset, 737 StringRef &Result) const { 738 if (StringTableSize <= 4) 739 // Tried to get a string from an empty string table. 740 return object_error::parse_failed; 741 if (Offset >= StringTableSize) 742 return object_error::unexpected_eof; 743 Result = StringRef(StringTable + Offset); 744 return object_error::success; 745} 746 747error_code COFFObjectFile::getSymbol(uint32_t Index, 748 const coff_symbol *&Result) const { 749 if (Index < COFFHeader->NumberOfSymbols) 750 Result = SymbolTable + Index; 751 else 752 return object_error::parse_failed; 753 return object_error::success; 754} 755 756error_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol, 757 StringRef &Res) const { 758 // Check for string table entry. First 4 bytes are 0. 759 if (Symbol->Name.Offset.Zeroes == 0) { 760 uint32_t Offset = Symbol->Name.Offset.Offset; 761 if (error_code EC = getString(Offset, Res)) 762 return EC; 763 return object_error::success; 764 } 765 766 if (Symbol->Name.ShortName[7] == 0) 767 // Null terminated, let ::strlen figure out the length. 768 Res = StringRef(Symbol->Name.ShortName); 769 else 770 // Not null terminated, use all 8 bytes. 771 Res = StringRef(Symbol->Name.ShortName, 8); 772 return object_error::success; 773} 774 775ArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData( 776 const coff_symbol *Symbol) const { 777 const uint8_t *Aux = nullptr; 778 779 if (Symbol->NumberOfAuxSymbols > 0) { 780 // AUX data comes immediately after the symbol in COFF 781 Aux = reinterpret_cast<const uint8_t *>(Symbol + 1); 782# ifndef NDEBUG 783 // Verify that the Aux symbol points to a valid entry in the symbol table. 784 uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 785 if (Offset < COFFHeader->PointerToSymbolTable 786 || Offset >= COFFHeader->PointerToSymbolTable 787 + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 788 report_fatal_error("Aux Symbol data was outside of symbol table."); 789 790 assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 791 == 0 && "Aux Symbol data did not point to the beginning of a symbol"); 792# endif 793 } 794 return ArrayRef<uint8_t>(Aux, 795 Symbol->NumberOfAuxSymbols * sizeof(coff_symbol)); 796} 797 798error_code COFFObjectFile::getSectionName(const coff_section *Sec, 799 StringRef &Res) const { 800 StringRef Name; 801 if (Sec->Name[7] == 0) 802 // Null terminated, let ::strlen figure out the length. 803 Name = Sec->Name; 804 else 805 // Not null terminated, use all 8 bytes. 806 Name = StringRef(Sec->Name, 8); 807 808 // Check for string table entry. First byte is '/'. 809 if (Name[0] == '/') { 810 uint32_t Offset; 811 if (Name[1] == '/') { 812 if (decodeBase64StringEntry(Name.substr(2), Offset)) 813 return object_error::parse_failed; 814 } else { 815 if (Name.substr(1).getAsInteger(10, Offset)) 816 return object_error::parse_failed; 817 } 818 if (error_code EC = getString(Offset, Name)) 819 return EC; 820 } 821 822 Res = Name; 823 return object_error::success; 824} 825 826error_code COFFObjectFile::getSectionContents(const coff_section *Sec, 827 ArrayRef<uint8_t> &Res) const { 828 // The only thing that we need to verify is that the contents is contained 829 // within the file bounds. We don't need to make sure it doesn't cover other 830 // data, as there's nothing that says that is not allowed. 831 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 832 uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; 833 if (ConEnd > uintptr_t(Data->getBufferEnd())) 834 return object_error::parse_failed; 835 Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart), 836 Sec->SizeOfRawData); 837 return object_error::success; 838} 839 840const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 841 return reinterpret_cast<const coff_relocation*>(Rel.p); 842} 843 844void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 845 Rel.p = reinterpret_cast<uintptr_t>( 846 reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 847} 848 849error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 850 uint64_t &Res) const { 851 report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 852} 853 854error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 855 uint64_t &Res) const { 856 Res = toRel(Rel)->VirtualAddress; 857 return object_error::success; 858} 859 860symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 861 const coff_relocation* R = toRel(Rel); 862 DataRefImpl Ref; 863 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); 864 return symbol_iterator(SymbolRef(Ref, this)); 865} 866 867error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 868 uint64_t &Res) const { 869 const coff_relocation* R = toRel(Rel); 870 Res = R->Type; 871 return object_error::success; 872} 873 874const coff_section * 875COFFObjectFile::getCOFFSection(const SectionRef &Section) const { 876 return toSec(Section.getRawDataRefImpl()); 877} 878 879const coff_symbol * 880COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 881 return toSymb(Symbol.getRawDataRefImpl()); 882} 883 884const coff_relocation * 885COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 886 return toRel(Reloc.getRawDataRefImpl()); 887} 888 889#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 890 case COFF::reloc_type: \ 891 Res = #reloc_type; \ 892 break; 893 894error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 895 SmallVectorImpl<char> &Result) const { 896 const coff_relocation *Reloc = toRel(Rel); 897 StringRef Res; 898 switch (COFFHeader->Machine) { 899 case COFF::IMAGE_FILE_MACHINE_AMD64: 900 switch (Reloc->Type) { 901 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 902 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 903 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 904 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 905 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 906 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 907 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 908 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 909 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 910 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 911 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 912 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 913 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 914 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 915 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 916 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 917 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 918 default: 919 Res = "Unknown"; 920 } 921 break; 922 case COFF::IMAGE_FILE_MACHINE_ARMNT: 923 switch (Reloc->Type) { 924 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE); 925 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32); 926 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB); 927 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24); 928 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11); 929 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN); 930 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24); 931 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11); 932 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION); 933 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL); 934 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A); 935 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T); 936 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T); 937 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T); 938 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T); 939 default: 940 Res = "Unknown"; 941 } 942 break; 943 case COFF::IMAGE_FILE_MACHINE_I386: 944 switch (Reloc->Type) { 945 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 946 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 947 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 948 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 949 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 950 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 951 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 952 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 953 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 954 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 955 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 956 default: 957 Res = "Unknown"; 958 } 959 break; 960 default: 961 Res = "Unknown"; 962 } 963 Result.append(Res.begin(), Res.end()); 964 return object_error::success; 965} 966 967#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 968 969error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 970 SmallVectorImpl<char> &Result) const { 971 const coff_relocation *Reloc = toRel(Rel); 972 const coff_symbol *Symb = nullptr; 973 if (error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) return EC; 974 DataRefImpl Sym; 975 Sym.p = reinterpret_cast<uintptr_t>(Symb); 976 StringRef SymName; 977 if (error_code EC = getSymbolName(Sym, SymName)) return EC; 978 Result.append(SymName.begin(), SymName.end()); 979 return object_error::success; 980} 981 982error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData, 983 LibraryRef &Result) const { 984 report_fatal_error("getLibraryNext not implemented in COFFObjectFile"); 985} 986 987error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData, 988 StringRef &Result) const { 989 report_fatal_error("getLibraryPath not implemented in COFFObjectFile"); 990} 991 992bool ImportDirectoryEntryRef:: 993operator==(const ImportDirectoryEntryRef &Other) const { 994 return ImportTable == Other.ImportTable && Index == Other.Index; 995} 996 997void ImportDirectoryEntryRef::moveNext() { 998 ++Index; 999} 1000 1001error_code ImportDirectoryEntryRef:: 1002getImportTableEntry(const import_directory_table_entry *&Result) const { 1003 Result = ImportTable; 1004 return object_error::success; 1005} 1006 1007error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 1008 uintptr_t IntPtr = 0; 1009 if (error_code EC = OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr)) 1010 return EC; 1011 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1012 return object_error::success; 1013} 1014 1015error_code ImportDirectoryEntryRef::getImportLookupEntry( 1016 const import_lookup_table_entry32 *&Result) const { 1017 uintptr_t IntPtr = 0; 1018 if (error_code EC = 1019 OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr)) 1020 return EC; 1021 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1022 return object_error::success; 1023} 1024 1025bool ExportDirectoryEntryRef:: 1026operator==(const ExportDirectoryEntryRef &Other) const { 1027 return ExportTable == Other.ExportTable && Index == Other.Index; 1028} 1029 1030void ExportDirectoryEntryRef::moveNext() { 1031 ++Index; 1032} 1033 1034// Returns the name of the current export symbol. If the symbol is exported only 1035// by ordinal, the empty string is set as a result. 1036error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 1037 uintptr_t IntPtr = 0; 1038 if (error_code EC = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 1039 return EC; 1040 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1041 return object_error::success; 1042} 1043 1044// Returns the starting ordinal number. 1045error_code ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 1046 Result = ExportTable->OrdinalBase; 1047 return object_error::success; 1048} 1049 1050// Returns the export ordinal of the current export symbol. 1051error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 1052 Result = ExportTable->OrdinalBase + Index; 1053 return object_error::success; 1054} 1055 1056// Returns the address of the current export symbol. 1057error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 1058 uintptr_t IntPtr = 0; 1059 if (error_code EC = OwningObject->getRvaPtr( 1060 ExportTable->ExportAddressTableRVA, IntPtr)) 1061 return EC; 1062 const export_address_table_entry *entry = 1063 reinterpret_cast<const export_address_table_entry *>(IntPtr); 1064 Result = entry[Index].ExportRVA; 1065 return object_error::success; 1066} 1067 1068// Returns the name of the current export symbol. If the symbol is exported only 1069// by ordinal, the empty string is set as a result. 1070error_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 1071 uintptr_t IntPtr = 0; 1072 if (error_code EC = OwningObject->getRvaPtr( 1073 ExportTable->OrdinalTableRVA, IntPtr)) 1074 return EC; 1075 const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 1076 1077 uint32_t NumEntries = ExportTable->NumberOfNamePointers; 1078 int Offset = 0; 1079 for (const ulittle16_t *I = Start, *E = Start + NumEntries; 1080 I < E; ++I, ++Offset) { 1081 if (*I != Index) 1082 continue; 1083 if (error_code EC = OwningObject->getRvaPtr( 1084 ExportTable->NamePointerRVA, IntPtr)) 1085 return EC; 1086 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 1087 if (error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 1088 return EC; 1089 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1090 return object_error::success; 1091 } 1092 Result = ""; 1093 return object_error::success; 1094} 1095 1096ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object, 1097 bool BufferOwned) { 1098 error_code EC; 1099 std::unique_ptr<COFFObjectFile> Ret( 1100 new COFFObjectFile(Object, EC, BufferOwned)); 1101 if (EC) 1102 return EC; 1103 return Ret.release(); 1104} 1105