COFFObjectFile.cpp revision 280031
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::ulittle16_t; 29using support::ulittle32_t; 30using support::ulittle64_t; 31using support::little16_t; 32 33// Returns false if size is greater than the buffer size. And sets ec. 34static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) { 35 if (M.getBufferSize() < Size) { 36 EC = object_error::unexpected_eof; 37 return false; 38 } 39 return true; 40} 41 42static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, 43 const uint64_t Size) { 44 if (Addr + Size < Addr || Addr + Size < Size || 45 Addr + Size > uintptr_t(M.getBufferEnd()) || 46 Addr < uintptr_t(M.getBufferStart())) { 47 return object_error::unexpected_eof; 48 } 49 return object_error::success; 50} 51 52// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 53// Returns unexpected_eof if error. 54template <typename T> 55static std::error_code getObject(const T *&Obj, MemoryBufferRef M, 56 const void *Ptr, 57 const uint64_t Size = sizeof(T)) { 58 uintptr_t Addr = uintptr_t(Ptr); 59 if (std::error_code EC = checkOffset(M, Addr, Size)) 60 return EC; 61 Obj = reinterpret_cast<const T *>(Addr); 62 return object_error::success; 63} 64 65// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 66// prefixed slashes. 67static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 68 assert(Str.size() <= 6 && "String too long, possible overflow."); 69 if (Str.size() > 6) 70 return true; 71 72 uint64_t Value = 0; 73 while (!Str.empty()) { 74 unsigned CharVal; 75 if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25 76 CharVal = Str[0] - 'A'; 77 else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51 78 CharVal = Str[0] - 'a' + 26; 79 else if (Str[0] >= '0' && Str[0] <= '9') // 52..61 80 CharVal = Str[0] - '0' + 52; 81 else if (Str[0] == '+') // 62 82 CharVal = 62; 83 else if (Str[0] == '/') // 63 84 CharVal = 63; 85 else 86 return true; 87 88 Value = (Value * 64) + CharVal; 89 Str = Str.substr(1); 90 } 91 92 if (Value > std::numeric_limits<uint32_t>::max()) 93 return true; 94 95 Result = static_cast<uint32_t>(Value); 96 return false; 97} 98 99template <typename coff_symbol_type> 100const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const { 101 const coff_symbol_type *Addr = 102 reinterpret_cast<const coff_symbol_type *>(Ref.p); 103 104 assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr))); 105#ifndef NDEBUG 106 // Verify that the symbol points to a valid entry in the symbol table. 107 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 108 109 assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 && 110 "Symbol did not point to the beginning of a symbol"); 111#endif 112 113 return Addr; 114} 115 116const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 117 const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 118 119# ifndef NDEBUG 120 // Verify that the section points to a valid entry in the section table. 121 if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections())) 122 report_fatal_error("Section was outside of section table."); 123 124 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 125 assert(Offset % sizeof(coff_section) == 0 && 126 "Section did not point to the beginning of a section"); 127# endif 128 129 return Addr; 130} 131 132void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 133 auto End = reinterpret_cast<uintptr_t>(StringTable); 134 if (SymbolTable16) { 135 const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref); 136 Symb += 1 + Symb->NumberOfAuxSymbols; 137 Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End); 138 } else if (SymbolTable32) { 139 const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref); 140 Symb += 1 + Symb->NumberOfAuxSymbols; 141 Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End); 142 } else { 143 llvm_unreachable("no symbol table pointer!"); 144 } 145} 146 147std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 148 StringRef &Result) const { 149 COFFSymbolRef Symb = getCOFFSymbol(Ref); 150 return getSymbolName(Symb, Result); 151} 152 153std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 154 uint64_t &Result) const { 155 COFFSymbolRef Symb = getCOFFSymbol(Ref); 156 157 if (Symb.isAnyUndefined()) { 158 Result = UnknownAddressOrSize; 159 return object_error::success; 160 } 161 if (Symb.isCommon()) { 162 Result = UnknownAddressOrSize; 163 return object_error::success; 164 } 165 int32_t SectionNumber = Symb.getSectionNumber(); 166 if (!COFF::isReservedSectionNumber(SectionNumber)) { 167 const coff_section *Section = nullptr; 168 if (std::error_code EC = getSection(SectionNumber, Section)) 169 return EC; 170 171 Result = Section->VirtualAddress + Symb.getValue(); 172 return object_error::success; 173 } 174 175 Result = Symb.getValue(); 176 return object_error::success; 177} 178 179std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 180 SymbolRef::Type &Result) const { 181 COFFSymbolRef Symb = getCOFFSymbol(Ref); 182 int32_t SectionNumber = Symb.getSectionNumber(); 183 Result = SymbolRef::ST_Other; 184 185 if (Symb.isAnyUndefined()) { 186 Result = SymbolRef::ST_Unknown; 187 } else if (Symb.isFunctionDefinition()) { 188 Result = SymbolRef::ST_Function; 189 } else if (Symb.isCommon()) { 190 Result = SymbolRef::ST_Data; 191 } else if (Symb.isFileRecord()) { 192 Result = SymbolRef::ST_File; 193 } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG) { 194 Result = SymbolRef::ST_Debug; 195 } else if (!COFF::isReservedSectionNumber(SectionNumber)) { 196 const coff_section *Section = nullptr; 197 if (std::error_code EC = getSection(SectionNumber, Section)) 198 return EC; 199 uint32_t Characteristics = Section->Characteristics; 200 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 201 Result = SymbolRef::ST_Function; 202 else if (Characteristics & (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 203 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) 204 Result = SymbolRef::ST_Data; 205 } 206 return object_error::success; 207} 208 209uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 210 COFFSymbolRef Symb = getCOFFSymbol(Ref); 211 uint32_t Result = SymbolRef::SF_None; 212 213 if (Symb.isExternal() || Symb.isWeakExternal()) 214 Result |= SymbolRef::SF_Global; 215 216 if (Symb.isWeakExternal()) 217 Result |= SymbolRef::SF_Weak; 218 219 if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) 220 Result |= SymbolRef::SF_Absolute; 221 222 if (Symb.isFileRecord()) 223 Result |= SymbolRef::SF_FormatSpecific; 224 225 if (Symb.isSectionDefinition()) 226 Result |= SymbolRef::SF_FormatSpecific; 227 228 if (Symb.isCommon()) 229 Result |= SymbolRef::SF_Common; 230 231 if (Symb.isAnyUndefined()) 232 Result |= SymbolRef::SF_Undefined; 233 234 return Result; 235} 236 237std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 238 uint64_t &Result) const { 239 COFFSymbolRef Symb = getCOFFSymbol(Ref); 240 241 if (Symb.isAnyUndefined()) { 242 Result = UnknownAddressOrSize; 243 return object_error::success; 244 } 245 if (Symb.isCommon()) { 246 Result = Symb.getValue(); 247 return object_error::success; 248 } 249 250 // Let's attempt to get the size of the symbol by looking at the address of 251 // the symbol after the symbol in question. 252 uint64_t SymbAddr; 253 if (std::error_code EC = getSymbolAddress(Ref, SymbAddr)) 254 return EC; 255 int32_t SectionNumber = Symb.getSectionNumber(); 256 if (COFF::isReservedSectionNumber(SectionNumber)) { 257 // Absolute and debug symbols aren't sorted in any interesting way. 258 Result = 0; 259 return object_error::success; 260 } 261 const section_iterator SecEnd = section_end(); 262 uint64_t AfterAddr = UnknownAddressOrSize; 263 for (const symbol_iterator &SymbI : symbols()) { 264 section_iterator SecI = SecEnd; 265 if (std::error_code EC = SymbI->getSection(SecI)) 266 return EC; 267 // Check the symbol's section, skip it if it's in the wrong section. 268 // First, make sure it is in any section. 269 if (SecI == SecEnd) 270 continue; 271 // Second, make sure it is in the same section as the symbol in question. 272 if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref)) 273 continue; 274 uint64_t Addr; 275 if (std::error_code EC = SymbI->getAddress(Addr)) 276 return EC; 277 // We want to compare our symbol in question with the closest possible 278 // symbol that comes after. 279 if (AfterAddr > Addr && Addr > SymbAddr) 280 AfterAddr = Addr; 281 } 282 if (AfterAddr == UnknownAddressOrSize) { 283 // No symbol comes after this one, assume that everything after our symbol 284 // is part of it. 285 const coff_section *Section = nullptr; 286 if (std::error_code EC = getSection(SectionNumber, Section)) 287 return EC; 288 Result = Section->SizeOfRawData - Symb.getValue(); 289 } else { 290 // Take the difference between our symbol and the symbol that comes after 291 // our symbol. 292 Result = AfterAddr - SymbAddr; 293 } 294 295 return object_error::success; 296} 297 298std::error_code 299COFFObjectFile::getSymbolSection(DataRefImpl Ref, 300 section_iterator &Result) const { 301 COFFSymbolRef Symb = getCOFFSymbol(Ref); 302 if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 303 Result = section_end(); 304 } else { 305 const coff_section *Sec = nullptr; 306 if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) 307 return EC; 308 DataRefImpl Ref; 309 Ref.p = reinterpret_cast<uintptr_t>(Sec); 310 Result = section_iterator(SectionRef(Ref, this)); 311 } 312 return object_error::success; 313} 314 315void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 316 const coff_section *Sec = toSec(Ref); 317 Sec += 1; 318 Ref.p = reinterpret_cast<uintptr_t>(Sec); 319} 320 321std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref, 322 StringRef &Result) const { 323 const coff_section *Sec = toSec(Ref); 324 return getSectionName(Sec, Result); 325} 326 327uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const { 328 const coff_section *Sec = toSec(Ref); 329 return Sec->VirtualAddress; 330} 331 332uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { 333 return getSectionSize(toSec(Ref)); 334} 335 336std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 337 StringRef &Result) const { 338 const coff_section *Sec = toSec(Ref); 339 ArrayRef<uint8_t> Res; 340 std::error_code EC = getSectionContents(Sec, Res); 341 Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 342 return EC; 343} 344 345uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const { 346 const coff_section *Sec = toSec(Ref); 347 return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 348} 349 350bool COFFObjectFile::isSectionText(DataRefImpl Ref) const { 351 const coff_section *Sec = toSec(Ref); 352 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 353} 354 355bool COFFObjectFile::isSectionData(DataRefImpl Ref) const { 356 const coff_section *Sec = toSec(Ref); 357 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 358} 359 360bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const { 361 const coff_section *Sec = toSec(Ref); 362 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 363} 364 365bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const { 366 const coff_section *Sec = toSec(Ref); 367 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 368} 369 370bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 371 DataRefImpl SymbRef) const { 372 const coff_section *Sec = toSec(SecRef); 373 COFFSymbolRef Symb = getCOFFSymbol(SymbRef); 374 int32_t SecNumber = (Sec - SectionTable) + 1; 375 return SecNumber == Symb.getSectionNumber(); 376} 377 378static uint32_t getNumberOfRelocations(const coff_section *Sec, 379 MemoryBufferRef M, const uint8_t *base) { 380 // The field for the number of relocations in COFF section table is only 381 // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 382 // NumberOfRelocations field, and the actual relocation count is stored in the 383 // VirtualAddress field in the first relocation entry. 384 if (Sec->hasExtendedRelocations()) { 385 const coff_relocation *FirstReloc; 386 if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>( 387 base + Sec->PointerToRelocations))) 388 return 0; 389 // -1 to exclude this first relocation entry. 390 return FirstReloc->VirtualAddress - 1; 391 } 392 return Sec->NumberOfRelocations; 393} 394 395static const coff_relocation * 396getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) { 397 uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base); 398 if (!NumRelocs) 399 return nullptr; 400 auto begin = reinterpret_cast<const coff_relocation *>( 401 Base + Sec->PointerToRelocations); 402 if (Sec->hasExtendedRelocations()) { 403 // Skip the first relocation entry repurposed to store the number of 404 // relocations. 405 begin++; 406 } 407 if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs)) 408 return nullptr; 409 return begin; 410} 411 412relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 413 const coff_section *Sec = toSec(Ref); 414 const coff_relocation *begin = getFirstReloc(Sec, Data, base()); 415 DataRefImpl Ret; 416 Ret.p = reinterpret_cast<uintptr_t>(begin); 417 return relocation_iterator(RelocationRef(Ret, this)); 418} 419 420relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 421 const coff_section *Sec = toSec(Ref); 422 const coff_relocation *I = getFirstReloc(Sec, Data, base()); 423 if (I) 424 I += getNumberOfRelocations(Sec, Data, base()); 425 DataRefImpl Ret; 426 Ret.p = reinterpret_cast<uintptr_t>(I); 427 return relocation_iterator(RelocationRef(Ret, this)); 428} 429 430// Initialize the pointer to the symbol table. 431std::error_code COFFObjectFile::initSymbolTablePtr() { 432 if (COFFHeader) 433 if (std::error_code EC = getObject( 434 SymbolTable16, Data, base() + getPointerToSymbolTable(), 435 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize())) 436 return EC; 437 438 if (COFFBigObjHeader) 439 if (std::error_code EC = getObject( 440 SymbolTable32, Data, base() + getPointerToSymbolTable(), 441 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize())) 442 return EC; 443 444 // Find string table. The first four byte of the string table contains the 445 // total size of the string table, including the size field itself. If the 446 // string table is empty, the value of the first four byte would be 4. 447 uint32_t StringTableOffset = getPointerToSymbolTable() + 448 getNumberOfSymbols() * getSymbolTableEntrySize(); 449 const uint8_t *StringTableAddr = base() + StringTableOffset; 450 const ulittle32_t *StringTableSizePtr; 451 if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 452 return EC; 453 StringTableSize = *StringTableSizePtr; 454 if (std::error_code EC = 455 getObject(StringTable, Data, StringTableAddr, StringTableSize)) 456 return EC; 457 458 // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 459 // tools like cvtres write a size of 0 for an empty table instead of 4. 460 if (StringTableSize < 4) 461 StringTableSize = 4; 462 463 // Check that the string table is null terminated if has any in it. 464 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 465 return object_error::parse_failed; 466 return object_error::success; 467} 468 469// Returns the file offset for the given VA. 470std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 471 uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 472 : (uint64_t)PE32PlusHeader->ImageBase; 473 uint64_t Rva = Addr - ImageBase; 474 assert(Rva <= UINT32_MAX); 475 return getRvaPtr((uint32_t)Rva, Res); 476} 477 478// Returns the file offset for the given RVA. 479std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 480 for (const SectionRef &S : sections()) { 481 const coff_section *Section = getCOFFSection(S); 482 uint32_t SectionStart = Section->VirtualAddress; 483 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 484 if (SectionStart <= Addr && Addr < SectionEnd) { 485 uint32_t Offset = Addr - SectionStart; 486 Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 487 return object_error::success; 488 } 489 } 490 return object_error::parse_failed; 491} 492 493// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 494// table entry. 495std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint, 496 StringRef &Name) const { 497 uintptr_t IntPtr = 0; 498 if (std::error_code EC = getRvaPtr(Rva, IntPtr)) 499 return EC; 500 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 501 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 502 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 503 return object_error::success; 504} 505 506// Find the import table. 507std::error_code COFFObjectFile::initImportTablePtr() { 508 // First, we get the RVA of the import table. If the file lacks a pointer to 509 // the import table, do nothing. 510 const data_directory *DataEntry; 511 if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 512 return object_error::success; 513 514 // Do nothing if the pointer to import table is NULL. 515 if (DataEntry->RelativeVirtualAddress == 0) 516 return object_error::success; 517 518 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 519 // -1 because the last entry is the null entry. 520 NumberOfImportDirectory = DataEntry->Size / 521 sizeof(import_directory_table_entry) - 1; 522 523 // Find the section that contains the RVA. This is needed because the RVA is 524 // the import table's memory address which is different from its file offset. 525 uintptr_t IntPtr = 0; 526 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 527 return EC; 528 ImportDirectory = reinterpret_cast< 529 const import_directory_table_entry *>(IntPtr); 530 return object_error::success; 531} 532 533// Initializes DelayImportDirectory and NumberOfDelayImportDirectory. 534std::error_code COFFObjectFile::initDelayImportTablePtr() { 535 const data_directory *DataEntry; 536 if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry)) 537 return object_error::success; 538 if (DataEntry->RelativeVirtualAddress == 0) 539 return object_error::success; 540 541 uint32_t RVA = DataEntry->RelativeVirtualAddress; 542 NumberOfDelayImportDirectory = DataEntry->Size / 543 sizeof(delay_import_directory_table_entry) - 1; 544 545 uintptr_t IntPtr = 0; 546 if (std::error_code EC = getRvaPtr(RVA, IntPtr)) 547 return EC; 548 DelayImportDirectory = reinterpret_cast< 549 const delay_import_directory_table_entry *>(IntPtr); 550 return object_error::success; 551} 552 553// Find the export table. 554std::error_code COFFObjectFile::initExportTablePtr() { 555 // First, we get the RVA of the export table. If the file lacks a pointer to 556 // the export table, do nothing. 557 const data_directory *DataEntry; 558 if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 559 return object_error::success; 560 561 // Do nothing if the pointer to export table is NULL. 562 if (DataEntry->RelativeVirtualAddress == 0) 563 return object_error::success; 564 565 uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 566 uintptr_t IntPtr = 0; 567 if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 568 return EC; 569 ExportDirectory = 570 reinterpret_cast<const export_directory_table_entry *>(IntPtr); 571 return object_error::success; 572} 573 574std::error_code COFFObjectFile::initBaseRelocPtr() { 575 const data_directory *DataEntry; 576 if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry)) 577 return object_error::success; 578 if (DataEntry->RelativeVirtualAddress == 0) 579 return object_error::success; 580 581 uintptr_t IntPtr = 0; 582 if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr)) 583 return EC; 584 BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>( 585 IntPtr); 586 BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>( 587 IntPtr + DataEntry->Size); 588 return object_error::success; 589} 590 591COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 592 : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), 593 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), 594 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr), 595 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0), 596 ImportDirectory(nullptr), NumberOfImportDirectory(0), 597 DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0), 598 ExportDirectory(nullptr), BaseRelocHeader(nullptr), 599 BaseRelocEnd(nullptr) { 600 // Check that we at least have enough room for a header. 601 if (!checkSize(Data, EC, sizeof(coff_file_header))) 602 return; 603 604 // The current location in the file where we are looking at. 605 uint64_t CurPtr = 0; 606 607 // PE header is optional and is present only in executables. If it exists, 608 // it is placed right after COFF header. 609 bool HasPEHeader = false; 610 611 // Check if this is a PE/COFF file. 612 if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) { 613 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 614 // PE signature to find 'normal' COFF header. 615 const auto *DH = reinterpret_cast<const dos_header *>(base()); 616 if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') { 617 CurPtr = DH->AddressOfNewExeHeader; 618 // Check the PE magic bytes. ("PE\0\0") 619 if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) { 620 EC = object_error::parse_failed; 621 return; 622 } 623 CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes. 624 HasPEHeader = true; 625 } 626 } 627 628 if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 629 return; 630 631 // It might be a bigobj file, let's check. Note that COFF bigobj and COFF 632 // import libraries share a common prefix but bigobj is more restrictive. 633 if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN && 634 COFFHeader->NumberOfSections == uint16_t(0xffff) && 635 checkSize(Data, EC, sizeof(coff_bigobj_file_header))) { 636 if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr))) 637 return; 638 639 // Verify that we are dealing with bigobj. 640 if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion && 641 std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic, 642 sizeof(COFF::BigObjMagic)) == 0) { 643 COFFHeader = nullptr; 644 CurPtr += sizeof(coff_bigobj_file_header); 645 } else { 646 // It's not a bigobj. 647 COFFBigObjHeader = nullptr; 648 } 649 } 650 if (COFFHeader) { 651 // The prior checkSize call may have failed. This isn't a hard error 652 // because we were just trying to sniff out bigobj. 653 EC = object_error::success; 654 CurPtr += sizeof(coff_file_header); 655 656 if (COFFHeader->isImportLibrary()) 657 return; 658 } 659 660 if (HasPEHeader) { 661 const pe32_header *Header; 662 if ((EC = getObject(Header, Data, base() + CurPtr))) 663 return; 664 665 const uint8_t *DataDirAddr; 666 uint64_t DataDirSize; 667 if (Header->Magic == COFF::PE32Header::PE32) { 668 PE32Header = Header; 669 DataDirAddr = base() + CurPtr + sizeof(pe32_header); 670 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 671 } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) { 672 PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 673 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 674 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 675 } else { 676 // It's neither PE32 nor PE32+. 677 EC = object_error::parse_failed; 678 return; 679 } 680 if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 681 return; 682 CurPtr += COFFHeader->SizeOfOptionalHeader; 683 } 684 685 if ((EC = getObject(SectionTable, Data, base() + CurPtr, 686 (uint64_t)getNumberOfSections() * sizeof(coff_section)))) 687 return; 688 689 // Initialize the pointer to the symbol table. 690 if (getPointerToSymbolTable() != 0) { 691 if ((EC = initSymbolTablePtr())) 692 return; 693 } else { 694 // We had better not have any symbols if we don't have a symbol table. 695 if (getNumberOfSymbols() != 0) { 696 EC = object_error::parse_failed; 697 return; 698 } 699 } 700 701 // Initialize the pointer to the beginning of the import table. 702 if ((EC = initImportTablePtr())) 703 return; 704 if ((EC = initDelayImportTablePtr())) 705 return; 706 707 // Initialize the pointer to the export table. 708 if ((EC = initExportTablePtr())) 709 return; 710 711 // Initialize the pointer to the base relocation table. 712 if ((EC = initBaseRelocPtr())) 713 return; 714 715 EC = object_error::success; 716} 717 718basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 719 DataRefImpl Ret; 720 Ret.p = getSymbolTable(); 721 return basic_symbol_iterator(SymbolRef(Ret, this)); 722} 723 724basic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 725 // The symbol table ends where the string table begins. 726 DataRefImpl Ret; 727 Ret.p = reinterpret_cast<uintptr_t>(StringTable); 728 return basic_symbol_iterator(SymbolRef(Ret, this)); 729} 730 731import_directory_iterator COFFObjectFile::import_directory_begin() const { 732 return import_directory_iterator( 733 ImportDirectoryEntryRef(ImportDirectory, 0, this)); 734} 735 736import_directory_iterator COFFObjectFile::import_directory_end() const { 737 return import_directory_iterator( 738 ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 739} 740 741delay_import_directory_iterator 742COFFObjectFile::delay_import_directory_begin() const { 743 return delay_import_directory_iterator( 744 DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this)); 745} 746 747delay_import_directory_iterator 748COFFObjectFile::delay_import_directory_end() const { 749 return delay_import_directory_iterator( 750 DelayImportDirectoryEntryRef( 751 DelayImportDirectory, NumberOfDelayImportDirectory, this)); 752} 753 754export_directory_iterator COFFObjectFile::export_directory_begin() const { 755 return export_directory_iterator( 756 ExportDirectoryEntryRef(ExportDirectory, 0, this)); 757} 758 759export_directory_iterator COFFObjectFile::export_directory_end() const { 760 if (!ExportDirectory) 761 return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this)); 762 ExportDirectoryEntryRef Ref(ExportDirectory, 763 ExportDirectory->AddressTableEntries, this); 764 return export_directory_iterator(Ref); 765} 766 767section_iterator COFFObjectFile::section_begin() const { 768 DataRefImpl Ret; 769 Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 770 return section_iterator(SectionRef(Ret, this)); 771} 772 773section_iterator COFFObjectFile::section_end() const { 774 DataRefImpl Ret; 775 int NumSections = 776 COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections(); 777 Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 778 return section_iterator(SectionRef(Ret, this)); 779} 780 781base_reloc_iterator COFFObjectFile::base_reloc_begin() const { 782 return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this)); 783} 784 785base_reloc_iterator COFFObjectFile::base_reloc_end() const { 786 return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this)); 787} 788 789uint8_t COFFObjectFile::getBytesInAddress() const { 790 return getArch() == Triple::x86_64 ? 8 : 4; 791} 792 793StringRef COFFObjectFile::getFileFormatName() const { 794 switch(getMachine()) { 795 case COFF::IMAGE_FILE_MACHINE_I386: 796 return "COFF-i386"; 797 case COFF::IMAGE_FILE_MACHINE_AMD64: 798 return "COFF-x86-64"; 799 case COFF::IMAGE_FILE_MACHINE_ARMNT: 800 return "COFF-ARM"; 801 default: 802 return "COFF-<unknown arch>"; 803 } 804} 805 806unsigned COFFObjectFile::getArch() const { 807 switch (getMachine()) { 808 case COFF::IMAGE_FILE_MACHINE_I386: 809 return Triple::x86; 810 case COFF::IMAGE_FILE_MACHINE_AMD64: 811 return Triple::x86_64; 812 case COFF::IMAGE_FILE_MACHINE_ARMNT: 813 return Triple::thumb; 814 default: 815 return Triple::UnknownArch; 816 } 817} 818 819iterator_range<import_directory_iterator> 820COFFObjectFile::import_directories() const { 821 return make_range(import_directory_begin(), import_directory_end()); 822} 823 824iterator_range<delay_import_directory_iterator> 825COFFObjectFile::delay_import_directories() const { 826 return make_range(delay_import_directory_begin(), 827 delay_import_directory_end()); 828} 829 830iterator_range<export_directory_iterator> 831COFFObjectFile::export_directories() const { 832 return make_range(export_directory_begin(), export_directory_end()); 833} 834 835iterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const { 836 return make_range(base_reloc_begin(), base_reloc_end()); 837} 838 839std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 840 Res = PE32Header; 841 return object_error::success; 842} 843 844std::error_code 845COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 846 Res = PE32PlusHeader; 847 return object_error::success; 848} 849 850std::error_code 851COFFObjectFile::getDataDirectory(uint32_t Index, 852 const data_directory *&Res) const { 853 // Error if if there's no data directory or the index is out of range. 854 if (!DataDirectory) { 855 Res = nullptr; 856 return object_error::parse_failed; 857 } 858 assert(PE32Header || PE32PlusHeader); 859 uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 860 : PE32PlusHeader->NumberOfRvaAndSize; 861 if (Index >= NumEnt) { 862 Res = nullptr; 863 return object_error::parse_failed; 864 } 865 Res = &DataDirectory[Index]; 866 return object_error::success; 867} 868 869std::error_code COFFObjectFile::getSection(int32_t Index, 870 const coff_section *&Result) const { 871 Result = nullptr; 872 if (COFF::isReservedSectionNumber(Index)) 873 return object_error::success; 874 if (static_cast<uint32_t>(Index) <= getNumberOfSections()) { 875 // We already verified the section table data, so no need to check again. 876 Result = SectionTable + (Index - 1); 877 return object_error::success; 878 } 879 return object_error::parse_failed; 880} 881 882std::error_code COFFObjectFile::getString(uint32_t Offset, 883 StringRef &Result) const { 884 if (StringTableSize <= 4) 885 // Tried to get a string from an empty string table. 886 return object_error::parse_failed; 887 if (Offset >= StringTableSize) 888 return object_error::unexpected_eof; 889 Result = StringRef(StringTable + Offset); 890 return object_error::success; 891} 892 893std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, 894 StringRef &Res) const { 895 // Check for string table entry. First 4 bytes are 0. 896 if (Symbol.getStringTableOffset().Zeroes == 0) { 897 uint32_t Offset = Symbol.getStringTableOffset().Offset; 898 if (std::error_code EC = getString(Offset, Res)) 899 return EC; 900 return object_error::success; 901 } 902 903 if (Symbol.getShortName()[COFF::NameSize - 1] == 0) 904 // Null terminated, let ::strlen figure out the length. 905 Res = StringRef(Symbol.getShortName()); 906 else 907 // Not null terminated, use all 8 bytes. 908 Res = StringRef(Symbol.getShortName(), COFF::NameSize); 909 return object_error::success; 910} 911 912ArrayRef<uint8_t> 913COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { 914 const uint8_t *Aux = nullptr; 915 916 size_t SymbolSize = getSymbolTableEntrySize(); 917 if (Symbol.getNumberOfAuxSymbols() > 0) { 918 // AUX data comes immediately after the symbol in COFF 919 Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize; 920# ifndef NDEBUG 921 // Verify that the Aux symbol points to a valid entry in the symbol table. 922 uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 923 if (Offset < getPointerToSymbolTable() || 924 Offset >= 925 getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize)) 926 report_fatal_error("Aux Symbol data was outside of symbol table."); 927 928 assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 && 929 "Aux Symbol data did not point to the beginning of a symbol"); 930# endif 931 } 932 return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize); 933} 934 935std::error_code COFFObjectFile::getSectionName(const coff_section *Sec, 936 StringRef &Res) const { 937 StringRef Name; 938 if (Sec->Name[COFF::NameSize - 1] == 0) 939 // Null terminated, let ::strlen figure out the length. 940 Name = Sec->Name; 941 else 942 // Not null terminated, use all 8 bytes. 943 Name = StringRef(Sec->Name, COFF::NameSize); 944 945 // Check for string table entry. First byte is '/'. 946 if (Name.startswith("/")) { 947 uint32_t Offset; 948 if (Name.startswith("//")) { 949 if (decodeBase64StringEntry(Name.substr(2), Offset)) 950 return object_error::parse_failed; 951 } else { 952 if (Name.substr(1).getAsInteger(10, Offset)) 953 return object_error::parse_failed; 954 } 955 if (std::error_code EC = getString(Offset, Name)) 956 return EC; 957 } 958 959 Res = Name; 960 return object_error::success; 961} 962 963uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const { 964 // SizeOfRawData and VirtualSize change what they represent depending on 965 // whether or not we have an executable image. 966 // 967 // For object files, SizeOfRawData contains the size of section's data; 968 // VirtualSize is always zero. 969 // 970 // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the 971 // actual section size is in VirtualSize. It is possible for VirtualSize to 972 // be greater than SizeOfRawData; the contents past that point should be 973 // considered to be zero. 974 uint32_t SectionSize; 975 if (Sec->VirtualSize) 976 SectionSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData); 977 else 978 SectionSize = Sec->SizeOfRawData; 979 980 return SectionSize; 981} 982 983std::error_code 984COFFObjectFile::getSectionContents(const coff_section *Sec, 985 ArrayRef<uint8_t> &Res) const { 986 // PointerToRawData and SizeOfRawData won't make sense for BSS sections, 987 // don't do anything interesting for them. 988 assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 && 989 "BSS sections don't have contents!"); 990 // The only thing that we need to verify is that the contents is contained 991 // within the file bounds. We don't need to make sure it doesn't cover other 992 // data, as there's nothing that says that is not allowed. 993 uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 994 uint32_t SectionSize = getSectionSize(Sec); 995 if (checkOffset(Data, ConStart, SectionSize)) 996 return object_error::parse_failed; 997 Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize); 998 return object_error::success; 999} 1000 1001const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 1002 return reinterpret_cast<const coff_relocation*>(Rel.p); 1003} 1004 1005void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 1006 Rel.p = reinterpret_cast<uintptr_t>( 1007 reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 1008} 1009 1010std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 1011 uint64_t &Res) const { 1012 report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 1013} 1014 1015std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 1016 uint64_t &Res) const { 1017 const coff_relocation *R = toRel(Rel); 1018 const support::ulittle32_t *VirtualAddressPtr; 1019 if (std::error_code EC = 1020 getObject(VirtualAddressPtr, Data, &R->VirtualAddress)) 1021 return EC; 1022 Res = *VirtualAddressPtr; 1023 return object_error::success; 1024} 1025 1026symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 1027 const coff_relocation *R = toRel(Rel); 1028 DataRefImpl Ref; 1029 if (R->SymbolTableIndex >= getNumberOfSymbols()) 1030 return symbol_end(); 1031 if (SymbolTable16) 1032 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex); 1033 else if (SymbolTable32) 1034 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex); 1035 else 1036 llvm_unreachable("no symbol table pointer!"); 1037 return symbol_iterator(SymbolRef(Ref, this)); 1038} 1039 1040std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 1041 uint64_t &Res) const { 1042 const coff_relocation* R = toRel(Rel); 1043 Res = R->Type; 1044 return object_error::success; 1045} 1046 1047const coff_section * 1048COFFObjectFile::getCOFFSection(const SectionRef &Section) const { 1049 return toSec(Section.getRawDataRefImpl()); 1050} 1051 1052COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const { 1053 if (SymbolTable16) 1054 return toSymb<coff_symbol16>(Ref); 1055 if (SymbolTable32) 1056 return toSymb<coff_symbol32>(Ref); 1057 llvm_unreachable("no symbol table pointer!"); 1058} 1059 1060COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 1061 return getCOFFSymbol(Symbol.getRawDataRefImpl()); 1062} 1063 1064const coff_relocation * 1065COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 1066 return toRel(Reloc.getRawDataRefImpl()); 1067} 1068 1069#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 1070 case COFF::reloc_type: \ 1071 Res = #reloc_type; \ 1072 break; 1073 1074std::error_code 1075COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 1076 SmallVectorImpl<char> &Result) const { 1077 const coff_relocation *Reloc = toRel(Rel); 1078 StringRef Res; 1079 switch (getMachine()) { 1080 case COFF::IMAGE_FILE_MACHINE_AMD64: 1081 switch (Reloc->Type) { 1082 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 1083 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 1084 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 1085 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 1086 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 1087 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 1088 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 1089 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 1090 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 1091 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 1092 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 1093 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 1094 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 1095 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 1096 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 1097 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 1098 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 1099 default: 1100 Res = "Unknown"; 1101 } 1102 break; 1103 case COFF::IMAGE_FILE_MACHINE_ARMNT: 1104 switch (Reloc->Type) { 1105 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE); 1106 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32); 1107 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB); 1108 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24); 1109 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11); 1110 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN); 1111 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24); 1112 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11); 1113 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION); 1114 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL); 1115 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A); 1116 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T); 1117 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T); 1118 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T); 1119 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T); 1120 default: 1121 Res = "Unknown"; 1122 } 1123 break; 1124 case COFF::IMAGE_FILE_MACHINE_I386: 1125 switch (Reloc->Type) { 1126 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 1127 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 1128 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 1129 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 1130 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 1131 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 1132 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 1133 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 1134 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 1135 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 1136 LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 1137 default: 1138 Res = "Unknown"; 1139 } 1140 break; 1141 default: 1142 Res = "Unknown"; 1143 } 1144 Result.append(Res.begin(), Res.end()); 1145 return object_error::success; 1146} 1147 1148#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 1149 1150std::error_code 1151COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 1152 SmallVectorImpl<char> &Result) const { 1153 const coff_relocation *Reloc = toRel(Rel); 1154 DataRefImpl Sym; 1155 ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex); 1156 if (std::error_code EC = Symb.getError()) 1157 return EC; 1158 Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr()); 1159 StringRef SymName; 1160 if (std::error_code EC = getSymbolName(Sym, SymName)) 1161 return EC; 1162 Result.append(SymName.begin(), SymName.end()); 1163 return object_error::success; 1164} 1165 1166bool COFFObjectFile::isRelocatableObject() const { 1167 return !DataDirectory; 1168} 1169 1170bool ImportDirectoryEntryRef:: 1171operator==(const ImportDirectoryEntryRef &Other) const { 1172 return ImportTable == Other.ImportTable && Index == Other.Index; 1173} 1174 1175void ImportDirectoryEntryRef::moveNext() { 1176 ++Index; 1177} 1178 1179std::error_code ImportDirectoryEntryRef::getImportTableEntry( 1180 const import_directory_table_entry *&Result) const { 1181 Result = ImportTable + Index; 1182 return object_error::success; 1183} 1184 1185static imported_symbol_iterator 1186makeImportedSymbolIterator(const COFFObjectFile *Object, 1187 uintptr_t Ptr, int Index) { 1188 if (Object->getBytesInAddress() == 4) { 1189 auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr); 1190 return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 1191 } 1192 auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr); 1193 return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 1194} 1195 1196static imported_symbol_iterator 1197importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) { 1198 uintptr_t IntPtr = 0; 1199 Object->getRvaPtr(RVA, IntPtr); 1200 return makeImportedSymbolIterator(Object, IntPtr, 0); 1201} 1202 1203static imported_symbol_iterator 1204importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) { 1205 uintptr_t IntPtr = 0; 1206 Object->getRvaPtr(RVA, IntPtr); 1207 // Forward the pointer to the last entry which is null. 1208 int Index = 0; 1209 if (Object->getBytesInAddress() == 4) { 1210 auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr); 1211 while (*Entry++) 1212 ++Index; 1213 } else { 1214 auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr); 1215 while (*Entry++) 1216 ++Index; 1217 } 1218 return makeImportedSymbolIterator(Object, IntPtr, Index); 1219} 1220 1221imported_symbol_iterator 1222ImportDirectoryEntryRef::imported_symbol_begin() const { 1223 return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA, 1224 OwningObject); 1225} 1226 1227imported_symbol_iterator 1228ImportDirectoryEntryRef::imported_symbol_end() const { 1229 return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA, 1230 OwningObject); 1231} 1232 1233iterator_range<imported_symbol_iterator> 1234ImportDirectoryEntryRef::imported_symbols() const { 1235 return make_range(imported_symbol_begin(), imported_symbol_end()); 1236} 1237 1238std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 1239 uintptr_t IntPtr = 0; 1240 if (std::error_code EC = 1241 OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr)) 1242 return EC; 1243 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1244 return object_error::success; 1245} 1246 1247std::error_code 1248ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const { 1249 Result = ImportTable[Index].ImportLookupTableRVA; 1250 return object_error::success; 1251} 1252 1253std::error_code 1254ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const { 1255 Result = ImportTable[Index].ImportAddressTableRVA; 1256 return object_error::success; 1257} 1258 1259std::error_code ImportDirectoryEntryRef::getImportLookupEntry( 1260 const import_lookup_table_entry32 *&Result) const { 1261 uintptr_t IntPtr = 0; 1262 uint32_t RVA = ImportTable[Index].ImportLookupTableRVA; 1263 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1264 return EC; 1265 Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1266 return object_error::success; 1267} 1268 1269bool DelayImportDirectoryEntryRef:: 1270operator==(const DelayImportDirectoryEntryRef &Other) const { 1271 return Table == Other.Table && Index == Other.Index; 1272} 1273 1274void DelayImportDirectoryEntryRef::moveNext() { 1275 ++Index; 1276} 1277 1278imported_symbol_iterator 1279DelayImportDirectoryEntryRef::imported_symbol_begin() const { 1280 return importedSymbolBegin(Table[Index].DelayImportNameTable, 1281 OwningObject); 1282} 1283 1284imported_symbol_iterator 1285DelayImportDirectoryEntryRef::imported_symbol_end() const { 1286 return importedSymbolEnd(Table[Index].DelayImportNameTable, 1287 OwningObject); 1288} 1289 1290iterator_range<imported_symbol_iterator> 1291DelayImportDirectoryEntryRef::imported_symbols() const { 1292 return make_range(imported_symbol_begin(), imported_symbol_end()); 1293} 1294 1295std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const { 1296 uintptr_t IntPtr = 0; 1297 if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr)) 1298 return EC; 1299 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1300 return object_error::success; 1301} 1302 1303std::error_code DelayImportDirectoryEntryRef:: 1304getDelayImportTable(const delay_import_directory_table_entry *&Result) const { 1305 Result = Table; 1306 return object_error::success; 1307} 1308 1309std::error_code DelayImportDirectoryEntryRef:: 1310getImportAddress(int AddrIndex, uint64_t &Result) const { 1311 uint32_t RVA = Table[Index].DelayImportAddressTable + 1312 AddrIndex * (OwningObject->is64() ? 8 : 4); 1313 uintptr_t IntPtr = 0; 1314 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1315 return EC; 1316 if (OwningObject->is64()) 1317 Result = *reinterpret_cast<const ulittle64_t *>(IntPtr); 1318 else 1319 Result = *reinterpret_cast<const ulittle32_t *>(IntPtr); 1320 return object_error::success; 1321} 1322 1323bool ExportDirectoryEntryRef:: 1324operator==(const ExportDirectoryEntryRef &Other) const { 1325 return ExportTable == Other.ExportTable && Index == Other.Index; 1326} 1327 1328void ExportDirectoryEntryRef::moveNext() { 1329 ++Index; 1330} 1331 1332// Returns the name of the current export symbol. If the symbol is exported only 1333// by ordinal, the empty string is set as a result. 1334std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 1335 uintptr_t IntPtr = 0; 1336 if (std::error_code EC = 1337 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 1338 return EC; 1339 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1340 return object_error::success; 1341} 1342 1343// Returns the starting ordinal number. 1344std::error_code 1345ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 1346 Result = ExportTable->OrdinalBase; 1347 return object_error::success; 1348} 1349 1350// Returns the export ordinal of the current export symbol. 1351std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 1352 Result = ExportTable->OrdinalBase + Index; 1353 return object_error::success; 1354} 1355 1356// Returns the address of the current export symbol. 1357std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 1358 uintptr_t IntPtr = 0; 1359 if (std::error_code EC = 1360 OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr)) 1361 return EC; 1362 const export_address_table_entry *entry = 1363 reinterpret_cast<const export_address_table_entry *>(IntPtr); 1364 Result = entry[Index].ExportRVA; 1365 return object_error::success; 1366} 1367 1368// Returns the name of the current export symbol. If the symbol is exported only 1369// by ordinal, the empty string is set as a result. 1370std::error_code 1371ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 1372 uintptr_t IntPtr = 0; 1373 if (std::error_code EC = 1374 OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr)) 1375 return EC; 1376 const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 1377 1378 uint32_t NumEntries = ExportTable->NumberOfNamePointers; 1379 int Offset = 0; 1380 for (const ulittle16_t *I = Start, *E = Start + NumEntries; 1381 I < E; ++I, ++Offset) { 1382 if (*I != Index) 1383 continue; 1384 if (std::error_code EC = 1385 OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr)) 1386 return EC; 1387 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 1388 if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 1389 return EC; 1390 Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1391 return object_error::success; 1392 } 1393 Result = ""; 1394 return object_error::success; 1395} 1396 1397bool ImportedSymbolRef:: 1398operator==(const ImportedSymbolRef &Other) const { 1399 return Entry32 == Other.Entry32 && Entry64 == Other.Entry64 1400 && Index == Other.Index; 1401} 1402 1403void ImportedSymbolRef::moveNext() { 1404 ++Index; 1405} 1406 1407std::error_code 1408ImportedSymbolRef::getSymbolName(StringRef &Result) const { 1409 uint32_t RVA; 1410 if (Entry32) { 1411 // If a symbol is imported only by ordinal, it has no name. 1412 if (Entry32[Index].isOrdinal()) 1413 return object_error::success; 1414 RVA = Entry32[Index].getHintNameRVA(); 1415 } else { 1416 if (Entry64[Index].isOrdinal()) 1417 return object_error::success; 1418 RVA = Entry64[Index].getHintNameRVA(); 1419 } 1420 uintptr_t IntPtr = 0; 1421 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1422 return EC; 1423 // +2 because the first two bytes is hint. 1424 Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2)); 1425 return object_error::success; 1426} 1427 1428std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const { 1429 uint32_t RVA; 1430 if (Entry32) { 1431 if (Entry32[Index].isOrdinal()) { 1432 Result = Entry32[Index].getOrdinal(); 1433 return object_error::success; 1434 } 1435 RVA = Entry32[Index].getHintNameRVA(); 1436 } else { 1437 if (Entry64[Index].isOrdinal()) { 1438 Result = Entry64[Index].getOrdinal(); 1439 return object_error::success; 1440 } 1441 RVA = Entry64[Index].getHintNameRVA(); 1442 } 1443 uintptr_t IntPtr = 0; 1444 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 1445 return EC; 1446 Result = *reinterpret_cast<const ulittle16_t *>(IntPtr); 1447 return object_error::success; 1448} 1449 1450ErrorOr<std::unique_ptr<COFFObjectFile>> 1451ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { 1452 std::error_code EC; 1453 std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC)); 1454 if (EC) 1455 return EC; 1456 return std::move(Ret); 1457} 1458 1459bool BaseRelocRef::operator==(const BaseRelocRef &Other) const { 1460 return Header == Other.Header && Index == Other.Index; 1461} 1462 1463void BaseRelocRef::moveNext() { 1464 // Header->BlockSize is the size of the current block, including the 1465 // size of the header itself. 1466 uint32_t Size = sizeof(*Header) + 1467 sizeof(coff_base_reloc_block_entry) * (Index + 1); 1468 if (Size == Header->BlockSize) { 1469 // .reloc contains a list of base relocation blocks. Each block 1470 // consists of the header followed by entries. The header contains 1471 // how many entories will follow. When we reach the end of the 1472 // current block, proceed to the next block. 1473 Header = reinterpret_cast<const coff_base_reloc_block_header *>( 1474 reinterpret_cast<const uint8_t *>(Header) + Size); 1475 Index = 0; 1476 } else { 1477 ++Index; 1478 } 1479} 1480 1481std::error_code BaseRelocRef::getType(uint8_t &Type) const { 1482 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 1483 Type = Entry[Index].getType(); 1484 return object_error::success; 1485} 1486 1487std::error_code BaseRelocRef::getRVA(uint32_t &Result) const { 1488 auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 1489 Result = Header->PageRVA + Entry[Index].getOffset(); 1490 return object_error::success; 1491} 1492