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