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