1a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===- COFFObjectFile.cpp - COFF object file implementation -----*- C++ -*-===// 2a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// 3a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// The LLVM Compiler Infrastructure 4a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// 5a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// This file is distributed under the University of Illinois Open Source 6a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// License. See LICENSE.TXT for details. 7a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// 8a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===----------------------------------------------------------------------===// 9a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// 10a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// This file declares the COFFObjectFile class. 11a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// 12a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===----------------------------------------------------------------------===// 13a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 14001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer#include "llvm/Object/COFF.h" 151f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer#include "llvm/ADT/ArrayRef.h" 164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#include "llvm/ADT/SmallString.h" 17a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/StringSwitch.h" 18a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/Triple.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/COFF.h" 20a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama#include "llvm/Support/Debug.h" 21a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama#include "llvm/Support/raw_ostream.h" 22e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <limits> 24ca8b2c655eb4d283187cbbb4f0f3acd34f60fa1cLogan Chien 25a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace llvm; 26a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace object; 27a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 28a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t; 29a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_t; 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing support::ulittle64_t; 31a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::little16_t; 32a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if size is greater than the buffer size. And sets ec. 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) { 35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (M.getBufferSize() < Size) { 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::unexpected_eof; 3725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return false; 3825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 3925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return true; 4025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 4125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const uint64_t Size) { 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Addr + Size < Addr || Addr + Size < Size || 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addr + Size > uintptr_t(M.getBufferEnd()) || 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addr < uintptr_t(M.getBufferStart())) { 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::unexpected_eof; 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 522f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 532f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Returns unexpected_eof if error. 54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <typename T> 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::error_code getObject(const T *&Obj, MemoryBufferRef M, 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const void *Ptr, 5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const uint64_t Size = sizeof(T)) { 582f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama uintptr_t Addr = uintptr_t(Ptr); 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = checkOffset(M, Addr, Size)) 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 612f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama Obj = reinterpret_cast<const T *>(Addr); 622f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::success; 6325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// prefixed slashes. 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Str.size() <= 6 && "String too long, possible overflow."); 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Str.size() > 6) 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Value = 0; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (!Str.empty()) { 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CharVal; 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - 'A'; 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - 'a' + 26; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] >= '0' && Str[0] <= '9') // 52..61 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - '0' + 52; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] == '+') // 62 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = 62; 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] == '/') // 63 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = 63; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value = (Value * 64) + CharVal; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Str = Str.substr(1); 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Value > std::numeric_limits<uint32_t>::max()) 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = static_cast<uint32_t>(Value); 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 9725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 9825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <typename coff_symbol_type> 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const { 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_symbol_type *Addr = 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines reinterpret_cast<const coff_symbol_type *>(Ref.p); 10325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr))); 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef NDEBUG 10625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the symbol points to a valid entry in the symbol table. 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 10825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 && 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Symbol did not point to the beginning of a symbol"); 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif 11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Addr; 11425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 11525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 11825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 11925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 12025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the section points to a valid entry in the section table. 12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections())) 12225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Section was outside of section table."); 12325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Offset % sizeof(coff_section) == 0 && 12625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer "Section did not point to the beginning of a section"); 12725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 12825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Addr; 130a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 131a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto End = reinterpret_cast<uintptr_t>(StringTable); 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SymbolTable16) { 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref); 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Symb += 1 + Symb->NumberOfAuxSymbols; 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End); 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (SymbolTable32) { 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref); 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Symb += 1 + Symb->NumberOfAuxSymbols; 14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End); 14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("no symbol table pointer!"); 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 145a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 146a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Result) const { 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSymbolName(Symb, Result); 151a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 152a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t &Result) const { 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 1561b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isAnyUndefined()) { 158ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = UnknownAddressOrSize; 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isCommon()) { 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = UnknownAddressOrSize; 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int32_t SectionNumber = Symb.getSectionNumber(); 16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!COFF::isReservedSectionNumber(SectionNumber)) { 16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_section *Section = nullptr; 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getSection(SectionNumber, Section)) 16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Section->VirtualAddress + Symb.getValue(); 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Symb.getValue(); 176ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 177ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 178ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines SymbolRef::Type &Result) const { 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int32_t SectionNumber = Symb.getSectionNumber(); 183ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Other; 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isAnyUndefined()) { 1862c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result = SymbolRef::ST_Unknown; 18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (Symb.isFunctionDefinition()) { 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SymbolRef::ST_Function; 18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (Symb.isCommon()) { 19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = SymbolRef::ST_Data; 19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (Symb.isFileRecord()) { 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = SymbolRef::ST_File; 1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG || 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Symb.isSectionDefinition()) { 1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // TODO: perhaps we need a new symbol type ST_Section. 19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = SymbolRef::ST_Debug; 19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (!COFF::isReservedSectionNumber(SectionNumber)) { 19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_section *Section = nullptr; 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getSection(SectionNumber, Section)) 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Characteristics = Section->Characteristics; 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = SymbolRef::ST_Function; 20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (Characteristics & (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SymbolRef::ST_Data; 207ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 208ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 209ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 210ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Result = SymbolRef::SF_None; 214c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isExternal() || Symb.isWeakExternal()) 216c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Global; 217c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isWeakExternal()) 219c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Weak; 220c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) 222c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Absolute; 223ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isFileRecord()) 22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result |= SymbolRef::SF_FormatSpecific; 22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isSectionDefinition()) 22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result |= SymbolRef::SF_FormatSpecific; 22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isCommon()) 23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result |= SymbolRef::SF_Common; 23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isAnyUndefined()) 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result |= SymbolRef::SF_Undefined; 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Result; 237c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer} 238c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer 239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t &Result) const { 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 2421b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isAnyUndefined()) { 24425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symb.isCommon()) { 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Symb.getValue(); 24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Let's attempt to get the size of the symbol by looking at the address of 25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // the symbol after the symbol in question. 25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t SymbAddr; 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getSymbolAddress(Ref, SymbAddr)) 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int32_t SectionNumber = Symb.getSectionNumber(); 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFF::isReservedSectionNumber(SectionNumber)) { 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Absolute and debug symbols aren't sorted in any interesting way. 26025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 0; 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const section_iterator SecEnd = section_end(); 26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t AfterAddr = UnknownAddressOrSize; 2652c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar for (const symbol_iterator SymbI : symbols()) { 26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines section_iterator SecI = SecEnd; 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = SymbI->getSection(SecI)) 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check the symbol's section, skip it if it's in the wrong section. 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // First, make sure it is in any section. 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SecI == SecEnd) 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Second, make sure it is in the same section as the symbol in question. 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref)) 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t Addr; 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = SymbI->getAddress(Addr)) 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We want to compare our symbol in question with the closest possible 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // symbol that comes after. 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (AfterAddr > Addr && Addr > SymbAddr) 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AfterAddr = Addr; 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (AfterAddr == UnknownAddressOrSize) { 28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // No symbol comes after this one, assume that everything after our symbol 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // is part of it. 28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_section *Section = nullptr; 28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getSection(SectionNumber, Section)) 28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Section->SizeOfRawData - Symb.getValue(); 29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Take the difference between our symbol and the symbol that comes after 29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // our symbol. 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = AfterAddr - SymbAddr; 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 29725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 298a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 299a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 300c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 301c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getSymbolSection(DataRefImpl Ref, 302c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines section_iterator &Result) const { 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(Ref); 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = section_end(); 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const coff_section *Sec = nullptr; 30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) 309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return EC; 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ref; 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(Sec); 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = section_iterator(SectionRef(Ref, this)); 3139b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer } 3149b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer return object_error::success; 3159b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer} 3169b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Sec += 1; 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(Sec); 321a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 322a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 323c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(DataRefImpl Ref, 324c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Result) const { 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSectionName(Sec, Result); 327a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 328a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const { 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Sec->VirtualAddress; 332a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 333a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { 33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return getSectionSize(toSec(Ref)); 336a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 337a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 338c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 339c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Result) const { 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 3411f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer ArrayRef<uint8_t> Res; 342c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code EC = getSectionContents(Sec, Res); 3431f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 3441f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return EC; 345a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 346a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const { 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 350e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer} 351e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer 35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionText(DataRefImpl Ref) const { 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 35513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 35613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionData(DataRefImpl Ref) const { 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 36013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 36113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const { 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 3644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 3654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar COFF::IMAGE_SCN_MEM_READ | 3664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar COFF::IMAGE_SCN_MEM_WRITE; 3674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return (Sec->Characteristics & BssFlags) == BssFlags; 368a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 369a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const { 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 3724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // In COFF, a virtual section won't have any in-file 3734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // content, so the file pointer to the content will be zero. 3744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Sec->PointerToRawData == 0; 375c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 376c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DataRefImpl SymbRef) const { 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(SecRef); 38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFSymbolRef Symb = getCOFFSymbol(SymbRef); 38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int32_t SecNumber = (Sec - SectionTable) + 1; 38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return SecNumber == Symb.getSectionNumber(); 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint32_t getNumberOfRelocations(const coff_section *Sec, 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MemoryBufferRef M, const uint8_t *base) { 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The field for the number of relocations in COFF section table is only 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // NumberOfRelocations field, and the actual relocation count is stored in the 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // VirtualAddress field in the first relocation entry. 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec->hasExtendedRelocations()) { 39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_relocation *FirstReloc; 39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>( 39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines base + Sec->PointerToRelocations))) 39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -1 to exclude this first relocation entry. 397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return FirstReloc->VirtualAddress - 1; 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Sec->NumberOfRelocations; 4004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 4014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const coff_relocation * 40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) { 40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base); 40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!NumRelocs) 40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto begin = reinterpret_cast<const coff_relocation *>( 40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Base + Sec->PointerToRelocations); 40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Sec->hasExtendedRelocations()) { 41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Skip the first relocation entry repurposed to store the number of 41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // relocations. 41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines begin++; 41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 41437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs)) 41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return begin; 41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_section *Sec = toSec(Ref); 42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_relocation *begin = getFirstReloc(Sec, Data, base()); 42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DataRefImpl Ret; 42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(begin); 42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return relocation_iterator(RelocationRef(Ret, this)); 42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_relocation *I = getFirstReloc(Sec, Data, base()); 43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (I) 43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines I += getNumberOfRelocations(Sec, Data, base()); 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(I); 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return relocation_iterator(RelocationRef(Ret, this)); 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 4364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 437a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Initialize the pointer to the symbol table. 438c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initSymbolTablePtr() { 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFFHeader) 44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getObject( 44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SymbolTable16, Data, base() + getPointerToSymbolTable(), 44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize())) 44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFFBigObjHeader) 44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getObject( 44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SymbolTable32, Data, base() + getPointerToSymbolTable(), 44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize())) 44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 450a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 451a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Find string table. The first four byte of the string table contains the 452a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // total size of the string table, including the size field itself. If the 453a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // string table is empty, the value of the first four byte would be 4. 45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t StringTableOffset = getPointerToSymbolTable() + 45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getNumberOfSymbols() * getSymbolTableEntrySize(); 45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const uint8_t *StringTableAddr = base() + StringTableOffset; 457a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const ulittle32_t *StringTableSizePtr; 45837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 460a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama StringTableSize = *StringTableSizePtr; 461c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getObject(StringTable, Data, StringTableAddr, StringTableSize)) 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // tools like cvtres write a size of 0 for an empty table instead of 4. 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StringTableSize < 4) 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringTableSize = 4; 469a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 470a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Check that the string table is null terminated if has any in it. 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 472a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::parse_failed; 473a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 474a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 475a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the file offset for the given VA. 477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : (uint64_t)PE32PlusHeader->ImageBase; 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Rva = Addr - ImageBase; 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Rva <= UINT32_MAX); 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getRvaPtr((uint32_t)Rva, Res); 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 485a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns the file offset for the given RVA. 486c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &S : sections()) { 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Section = getCOFFSection(S); 489a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t SectionStart = Section->VirtualAddress; 490a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SectionStart <= Addr && Addr < SectionEnd) { 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Offset = Addr - SectionStart; 493a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 494a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 495a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } 496a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } 497a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::parse_failed; 498a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 499a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 500a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 501a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// table entry. 502c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint, 503c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Name) const { 504a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 505c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getRvaPtr(Rva, IntPtr)) 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 507a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 508a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 509a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 510a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 511a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 512a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 513a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Find the import table. 514c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initImportTablePtr() { 515a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // First, we get the RVA of the import table. If the file lacks a pointer to 516a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // the import table, do nothing. 517a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const data_directory *DataEntry; 518a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 519a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 520a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 521a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Do nothing if the pointer to import table is NULL. 522a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (DataEntry->RelativeVirtualAddress == 0) 523a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 524a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 525a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // -1 because the last entry is the null entry. 527a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama NumberOfImportDirectory = DataEntry->Size / 52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sizeof(import_directory_table_entry) - 1; 529a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 530a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Find the section that contains the RVA. This is needed because the RVA is 531a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // the import table's memory address which is different from its file offset. 532a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 533c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 535a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama ImportDirectory = reinterpret_cast< 536a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const import_directory_table_entry *>(IntPtr); 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 539a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Initializes DelayImportDirectory and NumberOfDelayImportDirectory. 54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initDelayImportTablePtr() { 54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const data_directory *DataEntry; 54337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry)) 54437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (DataEntry->RelativeVirtualAddress == 0) 54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RVA = DataEntry->RelativeVirtualAddress; 54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines NumberOfDelayImportDirectory = DataEntry->Size / 55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sizeof(delay_import_directory_table_entry) - 1; 55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getRvaPtr(RVA, IntPtr)) 55437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 55537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DelayImportDirectory = reinterpret_cast< 55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const delay_import_directory_table_entry *>(IntPtr); 55737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 55837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 55937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Find the export table. 561c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initExportTablePtr() { 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // First, we get the RVA of the export table. If the file lacks a pointer to 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the export table, do nothing. 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const data_directory *DataEntry; 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Do nothing if the pointer to export table is NULL. 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DataEntry->RelativeVirtualAddress == 0) 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 574c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectory = 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const export_directory_table_entry *>(IntPtr); 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 579a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 580a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 58137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initBaseRelocPtr() { 58237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const data_directory *DataEntry; 58337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry)) 58437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (DataEntry->RelativeVirtualAddress == 0) 58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 58837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 58937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr)) 59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>( 59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntPtr); 59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>( 59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntPtr + DataEntry->Size); 59537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 59637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 59737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 59837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), 60037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), 60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr), 60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0), 60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ImportDirectory(nullptr), NumberOfImportDirectory(0), 60437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0), 60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExportDirectory(nullptr), BaseRelocHeader(nullptr), 60637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BaseRelocEnd(nullptr) { 60725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check that we at least have enough room for a header. 60837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!checkSize(Data, EC, sizeof(coff_file_header))) 609c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 610539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 6114bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // The current location in the file where we are looking at. 6124bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama uint64_t CurPtr = 0; 6134bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 6144bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // PE header is optional and is present only in executables. If it exists, 6154bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // it is placed right after COFF header. 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool HasPEHeader = false; 617539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 61825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check if this is a PE/COFF file. 61937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) { 620539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 621539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE signature to find 'normal' COFF header. 62237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const auto *DH = reinterpret_cast<const dos_header *>(base()); 62337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') { 62437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CurPtr = DH->AddressOfNewExeHeader; 62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check the PE magic bytes. ("PE\0\0") 62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) { 62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC = object_error::parse_failed; 62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 63037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes. 63137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines HasPEHeader = true; 63225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 633539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher } 634539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 63537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 63625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 63737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 63837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // It might be a bigobj file, let's check. Note that COFF bigobj and COFF 63937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // import libraries share a common prefix but bigobj is more restrictive. 64037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN && 64137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFHeader->NumberOfSections == uint16_t(0xffff) && 64237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines checkSize(Data, EC, sizeof(coff_bigobj_file_header))) { 64337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr))) 64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 64537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 64637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that we are dealing with bigobj. 64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion && 64837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic, 64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sizeof(COFF::BigObjMagic)) == 0) { 65037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFHeader = nullptr; 65137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CurPtr += sizeof(coff_bigobj_file_header); 65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // It's not a bigobj. 65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFBigObjHeader = nullptr; 65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFFHeader) { 65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // The prior checkSize call may have failed. This isn't a hard error 65937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // because we were just trying to sniff out bigobj. 66037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC = object_error::success; 66137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CurPtr += sizeof(coff_file_header); 66237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 66337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (COFFHeader->isImportLibrary()) 66437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 66537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 6660fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (HasPEHeader) { 66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const pe32_header *Header; 66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = getObject(Header, Data, base() + CurPtr))) 67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint8_t *DataDirAddr; 67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t DataDirSize; 67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Header->Magic == COFF::PE32Header::PE32) { 67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PE32Header = Header; 67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirAddr = base() + CurPtr + sizeof(pe32_header); 67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) { 67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It's neither PE32 nor PE32+. 68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::parse_failed; 6854bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return; 6862f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama } 68737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 6894bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += COFFHeader->SizeOfOptionalHeader; 6904bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama } 6910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 69237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = getObject(SectionTable, Data, base() + CurPtr, 69337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (uint64_t)getNumberOfSections() * sizeof(coff_section)))) 69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 695a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 696a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Initialize the pointer to the symbol table. 69737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (getPointerToSymbolTable() != 0) { 69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initSymbolTablePtr())) 6997151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 70037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 70137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We had better not have any symbols if we don't have a symbol table. 70237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (getNumberOfSymbols() != 0) { 70337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC = object_error::parse_failed; 70437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 70537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 7072f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama 708a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Initialize the pointer to the beginning of the import table. 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initImportTablePtr())) 710a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return; 71137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = initDelayImportTablePtr())) 71237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 7130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Initialize the pointer to the export table. 71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initExportTablePtr())) 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 717a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 71837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Initialize the pointer to the base relocation table. 71937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((EC = initBaseRelocPtr())) 72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::success; 723a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 724a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ret.p = getSymbolTable(); 72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return basic_symbol_iterator(SymbolRef(Ret, this)); 729dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 730dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The symbol table ends where the string table begins. 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(StringTable); 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return basic_symbol_iterator(SymbolRef(Ret, this)); 736dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 737dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 73829552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_begin() const { 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return import_directory_iterator( 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ImportDirectoryEntryRef(ImportDirectory, 0, this)); 741a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 742a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 74329552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_end() const { 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return import_directory_iterator( 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 74837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator 74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_begin() const { 75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return delay_import_directory_iterator( 75137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this)); 75237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 75337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 75437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator 75537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_end() const { 75637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return delay_import_directory_iterator( 75737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DelayImportDirectoryEntryRef( 75837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DelayImportDirectory, NumberOfDelayImportDirectory, this)); 75937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 76037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_begin() const { 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return export_directory_iterator( 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectoryEntryRef(ExportDirectory, 0, this)); 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_end() const { 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ExportDirectory) 768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this)); 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectoryEntryRef Ref(ExportDirectory, 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectory->AddressTableEntries, this); 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return export_directory_iterator(Ref); 772a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 77397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_begin() const { 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return section_iterator(SectionRef(Ret, this)); 778a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 779a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_end() const { 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 78237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int NumSections = 78337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections(); 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return section_iterator(SectionRef(Ret, this)); 786a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 787a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_begin() const { 78937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this)); 79037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 79137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_end() const { 79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this)); 79437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 79537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 796a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const { 7977acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 798a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 799a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 800a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const { 80137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch(getMachine()) { 802a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 803a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-i386"; 804a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 805a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-x86-64"; 80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::IMAGE_FILE_MACHINE_ARMNT: 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "COFF-ARM"; 808a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 809a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-<unknown arch>"; 810a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 811a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 812a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 813a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const { 81437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (getMachine()) { 815a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 816a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86; 817a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 818a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86_64; 81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::IMAGE_FILE_MACHINE_ARMNT: 82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Triple::thumb; 821a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 822a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::UnknownArch; 823a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 824a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 825a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<import_directory_iterator> 82737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::import_directories() const { 82837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(import_directory_begin(), import_directory_end()); 8294bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 8304bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 83137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<delay_import_directory_iterator> 83237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directories() const { 83337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(delay_import_directory_begin(), 83437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines delay_import_directory_end()); 83537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 83637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 83737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<export_directory_iterator> 83837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::export_directories() const { 83937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(export_directory_begin(), export_directory_end()); 84037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 84137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 84237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const { 84337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(base_reloc_begin(), base_reloc_end()); 8444bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 8454bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 846c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 8474bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama Res = PE32Header; 8480e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 8490e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 8500e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 851c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = PE32PlusHeader; 85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 857c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 858c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getDataDirectory(uint32_t Index, 859c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const data_directory *&Res) const { 8602f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // Error if if there's no data directory or the index is out of range. 86137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!DataDirectory) { 86237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = nullptr; 86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 86437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(PE32Header || PE32PlusHeader); 86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : PE32PlusHeader->NumberOfRvaAndSize; 86837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Index >= NumEnt) { 86937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = nullptr; 8702f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::parse_failed; 87137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = &DataDirectory[Index]; 8730e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 8740e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 8750e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 876c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSection(int32_t Index, 877c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const coff_section *&Result) const { 87837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = nullptr; 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (COFF::isReservedSectionNumber(Index)) 88037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 88137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (static_cast<uint32_t>(Index) <= getNumberOfSections()) { 88225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // We already verified the section table data, so no need to check again. 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SectionTable + (Index - 1); 88437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 88537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 88637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::parse_failed; 887a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 888a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 889c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getString(uint32_t Offset, 890c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Result) const { 89125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (StringTableSize <= 4) 89225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Tried to get a string from an empty string table. 89325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset >= StringTableSize) 89525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::unexpected_eof; 89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(StringTable + Offset); 89725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 898a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 899a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 90037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, 901c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Res) const { 9020e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Check for string table entry. First 4 bytes are 0. 90337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symbol.getStringTableOffset().Zeroes == 0) { 90437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Offset = Symbol.getStringTableOffset().Offset; 905c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getString(Offset, Res)) 90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 9070e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 9080e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer } 9090e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 91037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symbol.getShortName()[COFF::NameSize - 1] == 0) 9110e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Null terminated, let ::strlen figure out the length. 91237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = StringRef(Symbol.getShortName()); 9130e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer else 9140e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Not null terminated, use all 8 bytes. 91537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = StringRef(Symbol.getShortName(), COFF::NameSize); 9160e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 9170e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 9180e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 91937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesArrayRef<uint8_t> 92037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { 921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const uint8_t *Aux = nullptr; 922a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 92337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines size_t SymbolSize = getSymbolTableEntrySize(); 92437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symbol.getNumberOfAuxSymbols() > 0) { 92537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // AUX data comes immediately after the symbol in COFF 92637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize; 927d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# ifndef NDEBUG 92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Verify that the Aux symbol points to a valid entry in the symbol table. 92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 93037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Offset < getPointerToSymbolTable() || 93137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Offset >= 93237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize)) 933d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow report_fatal_error("Aux Symbol data was outside of symbol table."); 934d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 93537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 && 93637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Aux Symbol data did not point to the beginning of a symbol"); 937d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# endif 93845aad162c68ee58ba1aa8984499064f6b9c8d0f9Marshall Clow } 93937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize); 940d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 941d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 942c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(const coff_section *Sec, 943c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef &Res) const { 944b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer StringRef Name; 94537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Sec->Name[COFF::NameSize - 1] == 0) 946b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Null terminated, let ::strlen figure out the length. 947b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Name = Sec->Name; 948b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer else 949b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Not null terminated, use all 8 bytes. 95037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Name = StringRef(Sec->Name, COFF::NameSize); 951b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 952b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Check for string table entry. First byte is '/'. 95337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Name.startswith("/")) { 954b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer uint32_t Offset; 95537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Name.startswith("//")) { 95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (decodeBase64StringEntry(Name.substr(2), Offset)) 95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 95836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Name.substr(1).getAsInteger(10, Offset)) 96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 962c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getString(Offset, Name)) 96336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 964b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer } 965b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 966b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Res = Name; 967b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return object_error::success; 968b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer} 969b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 97037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const { 97137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // SizeOfRawData and VirtualSize change what they represent depending on 97237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // whether or not we have an executable image. 97337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // 97437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // For object files, SizeOfRawData contains the size of section's data; 97537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // VirtualSize is always zero. 97637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // 97737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the 97837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // actual section size is in VirtualSize. It is possible for VirtualSize to 97937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // be greater than SizeOfRawData; the contents past that point should be 98037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // considered to be zero. 98137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t SectionSize; 98237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Sec->VirtualSize) 98337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SectionSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData); 98437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 98537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SectionSize = Sec->SizeOfRawData; 98637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 98737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return SectionSize; 98837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 98937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 990c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 991c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getSectionContents(const coff_section *Sec, 992c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ArrayRef<uint8_t> &Res) const { 99337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // PointerToRawData and SizeOfRawData won't make sense for BSS sections, 99437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // don't do anything interesting for them. 99537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 && 99637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "BSS sections don't have contents!"); 9971f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // The only thing that we need to verify is that the contents is contained 9981f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // within the file bounds. We don't need to make sure it doesn't cover other 9991f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // data, as there's nothing that says that is not allowed. 10001f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 100137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t SectionSize = getSectionSize(Sec); 100237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (checkOffset(Data, ConStart, SectionSize)) 10031f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::parse_failed; 100437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize); 10051f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::success; 10061f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer} 10071f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer 10080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 10094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return reinterpret_cast<const coff_relocation*>(Rel.p); 10100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 10134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Rel.p = reinterpret_cast<uintptr_t>( 10144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 10150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1017c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 1018c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t &Res) const { 1019956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 1020b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev} 102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1022c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 1023c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t &Res) const { 102437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_relocation *R = toRel(Rel); 102537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const support::ulittle32_t *VirtualAddressPtr; 102637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = 102737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines getObject(VirtualAddressPtr, Data, &R->VirtualAddress)) 102837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 102937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Res = *VirtualAddressPtr; 10300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 10310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10336c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindolasymbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 103437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const coff_relocation *R = toRel(Rel); 103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ref; 103637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (R->SymbolTableIndex >= getNumberOfSymbols()) 103737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return symbol_end(); 103837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SymbolTable16) 103937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex); 104037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (SymbolTable32) 104137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex); 104237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 1043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines llvm_unreachable("no symbol table pointer!"); 104436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return symbol_iterator(SymbolRef(Ref, this)); 10450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1047c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 1048c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t &Res) const { 10490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 10500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = R->Type; 10510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 10520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 10534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section * 105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFSection(const SectionRef &Section) const { 105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return toSec(Section.getRawDataRefImpl()); 1057d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 1058d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 105937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const { 106037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SymbolTable16) 106137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return toSymb<coff_symbol16>(Ref); 106237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SymbolTable32) 106337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return toSymb<coff_symbol32>(Ref); 106437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("no symbol table pointer!"); 106537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 106637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 106737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 106837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return getCOFFSymbol(Symbol.getRawDataRefImpl()); 1069d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 1070d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 107136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_relocation * 107236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 107336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return toRel(Reloc.getRawDataRefImpl()); 10749ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow} 10759ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow 107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::reloc_type: \ 107836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = #reloc_type; \ 107936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 10804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 1081c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 1082c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 1083c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines SmallVectorImpl<char> &Result) const { 108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_relocation *Reloc = toRel(Rel); 108536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Res; 108637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (getMachine()) { 10874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 108836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Reloc->Type) { 10894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 10904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 10914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 10924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 10934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 10944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 10954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 10964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 10974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 10984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 10994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 11004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 11014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 11024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 11034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 11044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 11054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 11064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 110736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 11084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 11094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 1110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case COFF::IMAGE_FILE_MACHINE_ARMNT: 1111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (Reloc->Type) { 1112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE); 1113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32); 1114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB); 1115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24); 1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11); 1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN); 1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24); 1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11); 1120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION); 1121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL); 1122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A); 1123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T); 1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T); 1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T); 1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T); 1127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 1128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Res = "Unknown"; 1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 11314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 113236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Reloc->Type) { 11334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 11344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 11354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 11364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 11374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 11384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 11394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 11404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 11414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 11424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 11434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 11444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 114536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 11464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 11474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 11484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 114936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 11504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 115136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.append(Res.begin(), Res.end()); 11524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 11534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 11544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 11554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 11564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 1157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 1158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getRelocationValueString(DataRefImpl Rel, 1159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines SmallVectorImpl<char> &Result) const { 116036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_relocation *Reloc = toRel(Rel); 116136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Sym; 116237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex); 116337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = Symb.getError()) 116437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 116537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr()); 116636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SymName; 1167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = getSymbolName(Sym, SymName)) 1168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return EC; 116936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.append(SymName.begin(), SymName.end()); 11704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 1171a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling} 1172a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling 117337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isRelocatableObject() const { 117437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return !DataDirectory; 11755c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 11765c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 1177a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamabool ImportDirectoryEntryRef:: 1178a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaoperator==(const ImportDirectoryEntryRef &Other) const { 117936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ImportTable == Other.ImportTable && Index == Other.Index; 1180a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1181a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 118236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ImportDirectoryEntryRef::moveNext() { 118336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Index; 1184a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1185a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 1186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getImportTableEntry( 1187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const import_directory_table_entry *&Result) const { 118837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = ImportTable + Index; 1189a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 1190a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1191a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 119237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator 119337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesmakeImportedSymbolIterator(const COFFObjectFile *Object, 119437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t Ptr, int Index) { 119537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Object->getBytesInAddress() == 4) { 119637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr); 119737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 119837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 119937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr); 120037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object)); 120137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 120237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 120337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator 120437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) { 120537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 120637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Object->getRvaPtr(RVA, IntPtr); 120737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return makeImportedSymbolIterator(Object, IntPtr, 0); 120837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 120937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 121037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator 121137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) { 121237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 121337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Object->getRvaPtr(RVA, IntPtr); 121437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Forward the pointer to the last entry which is null. 121537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int Index = 0; 121637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Object->getBytesInAddress() == 4) { 121737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr); 121837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (*Entry++) 121937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Index; 122037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 122137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr); 122237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (*Entry++) 122337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Index; 122437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 122537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return makeImportedSymbolIterator(Object, IntPtr, Index); 122637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 122737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 122837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator 122937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_begin() const { 123037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA, 123137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OwningObject); 123237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 123337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 123437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator 123537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_end() const { 123637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA, 123737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OwningObject); 123837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 123937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 124037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator> 124137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbols() const { 124237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(imported_symbol_begin(), imported_symbol_end()); 124337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 124437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1245c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 1246a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 1247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 124837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr)) 124936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 125036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 1251a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 1252a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1253a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 125437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code 125537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const { 125637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = ImportTable[Index].ImportLookupTableRVA; 125737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 125837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 125937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 126037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code 126137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const { 126237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = ImportTable[Index].ImportAddressTableRVA; 126337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 126437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 126537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1266c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getImportLookupEntry( 1267a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const import_lookup_table_entry32 *&Result) const { 1268a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 126937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RVA = ImportTable[Index].ImportLookupTableRVA; 127037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 127136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 1272a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1273a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 1274a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1275a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 127637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool DelayImportDirectoryEntryRef:: 127737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const DelayImportDirectoryEntryRef &Other) const { 127837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Table == Other.Table && Index == Other.Index; 127937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 128037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 128137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DelayImportDirectoryEntryRef::moveNext() { 128237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Index; 128337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 128437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 128537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator 128637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_begin() const { 128737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return importedSymbolBegin(Table[Index].DelayImportNameTable, 128837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OwningObject); 128937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 129037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 129137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator 129237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_end() const { 129337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return importedSymbolEnd(Table[Index].DelayImportNameTable, 129437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OwningObject); 129537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 129637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 129737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator> 129837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbols() const { 129937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return make_range(imported_symbol_begin(), imported_symbol_end()); 130037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 130137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 130237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const { 130337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 130437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr)) 130537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 130637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 130737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 130837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 130937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 131037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef:: 131137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetDelayImportTable(const delay_import_directory_table_entry *&Result) const { 131237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Table; 131337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 131437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 131537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 131637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef:: 131737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetImportAddress(int AddrIndex, uint64_t &Result) const { 131837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RVA = Table[Index].DelayImportAddressTable + 131937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AddrIndex * (OwningObject->is64() ? 8 : 4); 132037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 132137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 132237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 132337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (OwningObject->is64()) 132437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = *reinterpret_cast<const ulittle64_t *>(IntPtr); 132537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 132637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = *reinterpret_cast<const ulittle32_t *>(IntPtr); 132737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 132837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 132937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 133036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ExportDirectoryEntryRef:: 133136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesoperator==(const ExportDirectoryEntryRef &Other) const { 133236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ExportTable == Other.ExportTable && Index == Other.Index; 133336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 133436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 133536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ExportDirectoryEntryRef::moveNext() { 133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Index; 133736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1338a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 133936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only 134036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result. 1341c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 134236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 1343c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 1344c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 134836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 134936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 135036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the starting ordinal number. 1351c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 1352c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 135336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ExportTable->OrdinalBase; 135436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 135536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 135636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 135736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the export ordinal of the current export symbol. 1358c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ExportTable->OrdinalBase + Index; 136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the address of the current export symbol. 1364c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 136536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 1366c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 1367c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr)) 136836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const export_address_table_entry *entry = 137036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const export_address_table_entry *>(IntPtr); 137136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = entry[Index].ExportRVA; 137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 137336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 137536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only 137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result. 1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code 1378c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 137936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 1380c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 1381c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr)) 138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 138436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 138536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t NumEntries = ExportTable->NumberOfNamePointers; 138636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int Offset = 0; 138736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const ulittle16_t *I = Start, *E = Start + NumEntries; 138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I < E; ++I, ++Offset) { 138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*I != Index) 139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1391c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = 1392c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr)) 139336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 139436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 1395c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 139636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 139736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 139836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 1399a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 140036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ""; 140136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 140236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1403a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 140437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool ImportedSymbolRef:: 140537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const ImportedSymbolRef &Other) const { 140637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Entry32 == Other.Entry32 && Entry64 == Other.Entry64 140737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines && Index == Other.Index; 140837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 140937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 141037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid ImportedSymbolRef::moveNext() { 141137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Index; 141237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 141337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 141437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code 141537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportedSymbolRef::getSymbolName(StringRef &Result) const { 141637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RVA; 141737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry32) { 141837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // If a symbol is imported only by ordinal, it has no name. 141937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry32[Index].isOrdinal()) 142037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 142137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RVA = Entry32[Index].getHintNameRVA(); 142237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 142337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry64[Index].isOrdinal()) 142437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 142537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RVA = Entry64[Index].getHintNameRVA(); 142637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 142737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 142837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 142937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 143037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // +2 because the first two bytes is hint. 143137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2)); 143237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 143337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 143437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 143537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const { 143637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t RVA; 143737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry32) { 143837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry32[Index].isOrdinal()) { 143937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Entry32[Index].getOrdinal(); 144037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 144137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 144237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RVA = Entry32[Index].getHintNameRVA(); 144337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 144437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Entry64[Index].isOrdinal()) { 144537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Entry64[Index].getOrdinal(); 144637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 144737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 144837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RVA = Entry64[Index].getHintNameRVA(); 144937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 145037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t IntPtr = 0; 145137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr)) 145237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 145337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = *reinterpret_cast<const ulittle16_t *>(IntPtr); 145437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 145537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 145637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 145737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesErrorOr<std::unique_ptr<COFFObjectFile>> 145837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { 1459c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::error_code EC; 146037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC)); 146136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC) 146236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 146337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return std::move(Ret); 146437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 146537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 146637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool BaseRelocRef::operator==(const BaseRelocRef &Other) const { 146737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Header == Other.Header && Index == Other.Index; 146837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 146937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 147037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid BaseRelocRef::moveNext() { 147137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Header->BlockSize is the size of the current block, including the 147237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // size of the header itself. 147337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Size = sizeof(*Header) + 147437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sizeof(coff_base_reloc_block_entry) * (Index + 1); 147537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Size == Header->BlockSize) { 147637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // .reloc contains a list of base relocation blocks. Each block 147737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // consists of the header followed by entries. The header contains 147837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // how many entories will follow. When we reach the end of the 147937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // current block, proceed to the next block. 148037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Header = reinterpret_cast<const coff_base_reloc_block_header *>( 148137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines reinterpret_cast<const uint8_t *>(Header) + Size); 148237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Index = 0; 148337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 148437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Index; 148537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 148637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 148737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 148837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getType(uint8_t &Type) const { 148937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 149037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Type = Entry[Index].getType(); 149137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 149237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 149337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 149437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getRVA(uint32_t &Result) const { 149537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1); 149637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Result = Header->PageRVA + Entry[Index].getOffset(); 149737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return object_error::success; 149836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1499