COFFObjectFile.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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::ulittle8_t; 29a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t; 30a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_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. 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool checkSize(const MemoryBuffer *M, error_code &EC, uint64_t Size) { 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen 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 422f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 432f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Returns unexpected_eof if error. 442f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyamatemplate<typename T> 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic error_code getObject(const T *&Obj, const MemoryBuffer *M, 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint8_t *Ptr, const size_t Size = sizeof(T)) { 472f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama uintptr_t Addr = uintptr_t(Ptr); 482f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if (Addr + Size < Addr || 492f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama Addr + Size < Size || 502f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama Addr + Size > uintptr_t(M->getBufferEnd())) { 512f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::unexpected_eof; 5225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 532f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama Obj = reinterpret_cast<const T *>(Addr); 542f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::success; 5525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// prefixed slashes. 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Str.size() <= 6 && "String too long, possible overflow."); 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Str.size() > 6) 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Value = 0; 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (!Str.empty()) { 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CharVal; 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - 'A'; 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - 'a' + 26; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] >= '0' && Str[0] <= '9') // 52..61 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = Str[0] - '0' + 52; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] == '+') // 62 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = 62; 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Str[0] == '/') // 63 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CharVal = 63; 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value = (Value * 64) + CharVal; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Str = Str.substr(1); 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Value > std::numeric_limits<uint32_t>::max()) 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = static_cast<uint32_t>(Value); 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 8925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 9025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_symbol *COFFObjectFile::toSymb(DataRefImpl Ref) const { 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Addr = reinterpret_cast<const coff_symbol*>(Ref.p); 9325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 9425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 9525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the symbol points to a valid entry in the symbol table. 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset < COFFHeader->PointerToSymbolTable 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || Offset >= COFFHeader->PointerToSymbolTable 994bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 10025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Symbol was outside of symbol table."); 10125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 10325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer == 0 && "Symbol did not point to the beginning of a symbol"); 10425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 10525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Addr; 10725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 10825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p); 11125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 11325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the section points to a valid entry in the section table. 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Addr < SectionTable 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || Addr >= (SectionTable + COFFHeader->NumberOfSections)) 11625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Section was outside of section table."); 11725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Offset % sizeof(coff_section) == 0 && 12025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer "Section did not point to the beginning of a section"); 12125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 12225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Addr; 124a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 125a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Symb += 1 + Symb->NumberOfAuxSymbols; 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(Symb); 130a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 131a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolName(DataRefImpl Ref, 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef &Result) const { 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSymbolName(Symb, Result); 136a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 137a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, 139ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer uint64_t &Result) const { 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 141ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_section *Section = NULL; 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSection(Symb->SectionNumber, Section)) 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 1441b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) 146ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = UnknownAddressOrSize; 147ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else if (Section) 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Section->VirtualAddress + Symb->Value; 149ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Symb->Value; 151ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 152ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 153ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolType(DataRefImpl Ref, 1551130a799ab2fd7042625163a2506518960394884Michael J. Spencer SymbolRef::Type &Result) const { 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 157ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Other; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 1602c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result = SymbolRef::ST_Unknown; 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Symb->isFunctionDefinition()) { 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SymbolRef::ST_Function; 163ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } else { 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Characteristics = 0; 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Section = NULL; 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSection(Symb->SectionNumber, Section)) 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Characteristics = Section->Characteristics; 170ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SymbolRef::ST_Data; 174ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 175ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 176ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 177ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Result = SymbolRef::SF_None; 181c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // TODO: Correctly set SF_FormatSpecific, SF_Common 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->Value == 0) 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result |= SymbolRef::SF_Undefined; 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result |= SymbolRef::SF_Common; 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1902c67727046234ad9702ab5acb72700b5ac99a676David Meyer 191c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 192c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer // TODO: This are certainly too restrictive. 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 194c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Global; 195c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 197c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Weak; 198c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE) 200c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Absolute; 201ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Result; 203c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer} 204c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, 20625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 207a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // FIXME: Return the correct size. This requires looking at all the symbols 208a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // in the same section as this symbol, and looking for either the next 209a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // symbol, or the end of the section. 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 21164388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSection(Symb->SectionNumber, Section)) 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 2141b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) 21625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 21725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (Section) 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Section->SizeOfRawData - Symb->Value; 21925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 22025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 0; 22125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 222a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 223a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolSection(DataRefImpl Ref, 2259b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer section_iterator &Result) const { 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(Ref); 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (COFF::isReservedSectionNumber(Symb->SectionNumber)) { 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = section_end(); 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = 0; 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSection(Symb->SectionNumber, Sec)) return EC; 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ref; 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(Sec); 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = section_iterator(SectionRef(Ref, this)); 2359b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer } 2369b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer return object_error::success; 2379b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer} 2389b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const { 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Sec += 1; 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(Sec); 243a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 244a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSectionName(DataRefImpl Ref, 24625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSectionName(Sec, Result); 249a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 250a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSectionAddress(DataRefImpl Ref, 25225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->VirtualAddress; 25525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 256a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 257a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSectionSize(DataRefImpl Ref, 25925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->SizeOfRawData; 26225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 263a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 264a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSectionContents(DataRefImpl Ref, 26625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 2681f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer ArrayRef<uint8_t> Res; 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error_code EC = getSectionContents(Sec, Res); 2701f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 2711f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return EC; 272a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 273a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref, 275e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer uint64_t &Res) const { 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Sec) 278e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::parse_failed; 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1); 280e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::success; 281e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer} 282e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionText(DataRefImpl Ref, 28425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool &Result) const { 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 28713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 28813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 28913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionData(DataRefImpl Ref, 29113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 29413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 29513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 29613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionBSS(DataRefImpl Ref, 29813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 30125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 302a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 303a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref, 305c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 306c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // FIXME: Unimplemented 307c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = true; 308c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 309c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 310c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref, 312c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 315c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 316c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 317c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref, 319c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 32030b20ebdd3a41e103c6aa35849a33ed299332bc9Andrew Kaylor // FIXME: Unimplemented. 321c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = false; 322c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 323c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 324c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref, 3263a129c85920404e7ccdb7e655c89fa60a0309cfdAndrew Kaylor bool &Result) const { 3273a129c85920404e7ccdb7e655c89fa60a0309cfdAndrew Kaylor // FIXME: Unimplemented. 328c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = false; 329c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 330c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 331c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl SymbRef, 33407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer bool &Result) const { 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(SecRef); 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = toSymb(SymbRef); 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *SymbSec = 0; 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSection(Symb->SectionNumber, SymbSec)) return EC; 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymbSec == Sec) 340bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = true; 341bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer else 342bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = false; 34307ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer return object_error::success; 34407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer} 34507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec->NumberOfRelocations == 0) { 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = 0; 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto begin = reinterpret_cast<const coff_relocation*>( 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines base() + Sec->PointerToRelocations); 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec->hasExtendedRelocations()) { 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip the first relocation entry repurposed to store the number of 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // relocations. 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines begin++; 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(begin); 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return relocation_iterator(RelocationRef(Ret, this)); 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint32_t getNumberOfRelocations(const coff_section *Sec, 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint8_t *base) { 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The field for the number of relocations in COFF section table is only 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // NumberOfRelocations field, and the actual relocation count is stored in the 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // VirtualAddress field in the first relocation entry. 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec->hasExtendedRelocations()) { 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *FirstReloc = reinterpret_cast<const coff_relocation*>( 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines base + Sec->PointerToRelocations); 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return FirstReloc->VirtualAddress; 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Sec->NumberOfRelocations; 3764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 3774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec->NumberOfRelocations == 0) { 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = 0; 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto begin = reinterpret_cast<const coff_relocation*>( 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines base() + Sec->PointerToRelocations); 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t NumReloc = getNumberOfRelocations(Sec, base()); 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc); 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return relocation_iterator(RelocationRef(Ret, this)); 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 3914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool COFFObjectFile::section_rel_empty(DataRefImpl Ref) const { 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Sec = toSec(Ref); 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Sec->NumberOfRelocations == 0; 3954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 3964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 397a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Initialize the pointer to the symbol table. 398a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code COFFObjectFile::initSymbolTablePtr() { 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getObject( 400a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable, 401a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 403a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 404a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Find string table. The first four byte of the string table contains the 405a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // total size of the string table, including the size field itself. If the 406a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // string table is empty, the value of the first four byte would be 4. 407a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const uint8_t *StringTableAddr = 408a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama base() + COFFHeader->PointerToSymbolTable + 409a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama COFFHeader->NumberOfSymbols * sizeof(coff_symbol); 410a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const ulittle32_t *StringTableSizePtr; 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 413a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama StringTableSize = *StringTableSizePtr; 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = 415a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama getObject(StringTable, Data, StringTableAddr, StringTableSize)) 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // tools like cvtres write a size of 0 for an empty table instead of 4. 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StringTableSize < 4) 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringTableSize = 4; 422a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 423a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Check that the string table is null terminated if has any in it. 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0) 425a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::parse_failed; 426a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 427a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 428a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the file offset for the given VA. 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : (uint64_t)PE32PlusHeader->ImageBase; 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Rva = Addr - ImageBase; 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Rva <= UINT32_MAX); 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getRvaPtr((uint32_t)Rva, Res); 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 438a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns the file offset for the given RVA. 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const { 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &S : sections()) { 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Section = getCOFFSection(S); 442a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t SectionStart = Section->VirtualAddress; 443a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize; 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SectionStart <= Addr && Addr < SectionEnd) { 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Offset = Addr - SectionStart; 446a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Res = uintptr_t(base()) + Section->PointerToRawData + Offset; 447a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 448a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } 449a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } 450a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::parse_failed; 451a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 452a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 453a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name 454a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// table entry. 455a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code COFFObjectFile:: 456a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui UeyamagetHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const { 457a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getRvaPtr(Rva, IntPtr)) 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 460a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr); 461a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Hint = *reinterpret_cast<const ulittle16_t *>(Ptr); 462a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Name = StringRef(reinterpret_cast<const char *>(Ptr + 2)); 463a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 464a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 465a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 466a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Find the import table. 467a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code COFFObjectFile::initImportTablePtr() { 468a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // First, we get the RVA of the import table. If the file lacks a pointer to 469a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // the import table, do nothing. 470a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const data_directory *DataEntry; 471a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry)) 472a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 473a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 474a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Do nothing if the pointer to import table is NULL. 475a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (DataEntry->RelativeVirtualAddress == 0) 476a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 477a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 478a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress; 479a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama NumberOfImportDirectory = DataEntry->Size / 480a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama sizeof(import_directory_table_entry); 481a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 482a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Find the section that contains the RVA. This is needed because the RVA is 483a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // the import table's memory address which is different from its file offset. 484a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getRvaPtr(ImportTableRva, IntPtr)) 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 487a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama ImportDirectory = reinterpret_cast< 488a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const import_directory_table_entry *>(IntPtr); 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 491a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Find the export table. 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::initExportTablePtr() { 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // First, we get the RVA of the export table. If the file lacks a pointer to 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the export table, do nothing. 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const data_directory *DataEntry; 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry)) 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Do nothing if the pointer to export table is NULL. 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DataEntry->RelativeVirtualAddress == 0) 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress; 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getRvaPtr(ExportTableRva, IntPtr)) 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectory = 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const export_directory_table_entry *>(IntPtr); 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 511a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 512a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC, 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool BufferOwned) 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(0), 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PE32Header(0), PE32PlusHeader(0), DataDirectory(0), SectionTable(0), 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolTable(0), StringTable(0), StringTableSize(0), ImportDirectory(0), 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumberOfImportDirectory(0), ExportDirectory(0) { 51925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check that we at least have enough room for a header. 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!checkSize(Data, EC, sizeof(coff_file_header))) return; 521539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 5224bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // The current location in the file where we are looking at. 5234bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama uint64_t CurPtr = 0; 5244bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 5254bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // PE header is optional and is present only in executables. If it exists, 5264bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // it is placed right after COFF header. 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool HasPEHeader = false; 528539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 52925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check if this is a PE/COFF file. 530001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (base()[0] == 0x4d && base()[1] == 0x5a) { 531539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 532539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE signature to find 'normal' COFF header. 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!checkSize(Data, EC, 0x3c + 8)) return; 5344bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); 5354bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // Check the PE magic bytes. ("PE\0\0") 5364bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) { 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::parse_failed; 53825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 53925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 5404bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += 4; // Skip the PE magic bytes. 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines HasPEHeader = true; 542539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher } 543539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) 54525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 5464bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += sizeof(coff_file_header); 5470fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (HasPEHeader) { 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const pe32_header *Header; 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = getObject(Header, Data, base() + CurPtr))) 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint8_t *DataDirAddr; 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t DataDirSize; 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Header->Magic == 0x10b) { 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PE32Header = Header; 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirAddr = base() + CurPtr + sizeof(pe32_header); 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Header->Magic == 0x20b) { 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header); 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirAddr = base() + CurPtr + sizeof(pe32plus_header); 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize; 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It's neither PE32 nor PE32+. 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::parse_failed; 5664bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return; 5672f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama } 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 5704bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += COFFHeader->SizeOfOptionalHeader; 5714bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama } 5720fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (COFFHeader->isImportLibrary()) 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = getObject(SectionTable, Data, base() + CurPtr, 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines COFFHeader->NumberOfSections * sizeof(coff_section)))) 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 579a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 580a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Initialize the pointer to the symbol table. 581a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (COFFHeader->PointerToSymbolTable != 0) 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initSymbolTablePtr())) 5837151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 5842f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama 585a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama // Initialize the pointer to the beginning of the import table. 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initImportTablePtr())) 587a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return; 5880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Initialize the pointer to the export table. 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((EC = initExportTablePtr())) 59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 592a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EC = object_error::success; 594a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 595a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { 59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(SymbolTable); 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return basic_symbol_iterator(SymbolRef(Ret, this)); 600dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 601dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_end_impl() const { 60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The symbol table ends where the string table begins. 60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(StringTable); 60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return basic_symbol_iterator(SymbolRef(Ret, this)); 607dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 608dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineslibrary_iterator COFFObjectFile::needed_library_begin() const { 6105c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: implement 6115c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 6125c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 6135c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineslibrary_iterator COFFObjectFile::needed_library_end() const { 6155c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: implement 6165c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 6175c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 6185c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 61997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid MeyerStringRef COFFObjectFile::getLoadName() const { 62097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer // COFF does not have this field. 62197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer return ""; 62297f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer} 62397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 62429552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_begin() const { 62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return import_directory_iterator( 62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ImportDirectoryEntryRef(ImportDirectory, 0, this)); 627a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 628a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 62929552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_end() const { 63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return import_directory_iterator( 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this)); 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_begin() const { 63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return export_directory_iterator( 63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectoryEntryRef(ExportDirectory, 0, this)); 63736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 63836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_end() const { 64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ExportDirectory == 0) 64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return export_directory_iterator(ExportDirectoryEntryRef(0, 0, this)); 64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectoryEntryRef Ref(ExportDirectory, 64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportDirectory->AddressTableEntries, this); 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return export_directory_iterator(Ref); 645a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 64697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_begin() const { 64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(SectionTable); 65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return section_iterator(SectionRef(Ret, this)); 651a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 652a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_end() const { 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ret; 65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int NumSections = COFFHeader->isImportLibrary() 6563a226015a0ca52936763a079da582656164c2908Rui Ueyama ? 0 : COFFHeader->NumberOfSections; 65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections); 65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return section_iterator(SectionRef(Ret, this)); 659a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 660a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 661a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const { 6627acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 663a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 664a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 665a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const { 6664bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch(COFFHeader->Machine) { 667a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 668a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-i386"; 669a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 670a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-x86-64"; 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::IMAGE_FILE_MACHINE_ARMNT: 67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "COFF-ARM"; 673a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 674a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-<unknown arch>"; 675a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 676a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 677a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 678a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const { 6794bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch(COFFHeader->Machine) { 680a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 681a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86; 682a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 683a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86_64; 68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::IMAGE_FILE_MACHINE_ARMNT: 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Triple::thumb; 686a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 687a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::UnknownArch; 688a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 689a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 690a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 6914bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama// This method is kept here because lld uses this. As soon as we make 6924bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama// lld to use getCOFFHeader, this method will be removed. 6930e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getHeader(const coff_file_header *&Res) const { 6944bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return getCOFFHeader(Res); 6954bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 6964bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 6974bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyamaerror_code COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const { 6984bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama Res = COFFHeader; 6994bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return object_error::success; 7004bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 7014bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 7024bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyamaerror_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 7034bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama Res = PE32Header; 7040e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 7050e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 7060e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const { 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = PE32PlusHeader; 71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getDataDirectory(uint32_t Index, 7142f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama const data_directory *&Res) const { 7152f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // Error if if there's no data directory or the index is out of range. 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!DataDirectory) 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(PE32Header || PE32PlusHeader); 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : PE32PlusHeader->NumberOfRvaAndSize; 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index > NumEnt) 7222f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::parse_failed; 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = &DataDirectory[Index]; 7240e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 7250e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 7260e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSection(int32_t Index, 72825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *&Result) const { 72925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check for special index values. 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (COFF::isReservedSectionNumber(Index)) 73125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = NULL; 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Index > 0 && Index <= COFFHeader->NumberOfSections) 73325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // We already verified the section table data, so no need to check again. 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SectionTable + (Index - 1); 73525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 73625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 73725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 738a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 739a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getString(uint32_t Offset, 74125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 74225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (StringTableSize <= 4) 74325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Tried to get a string from an empty string table. 74425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset >= StringTableSize) 74625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::unexpected_eof; 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(StringTable + Offset); 74825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 749a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 750a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbol(uint32_t Index, 7524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_symbol *&Result) const { 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index < COFFHeader->NumberOfSymbols) 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = SymbolTable + Index; 7554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 7564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::parse_failed; 7574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 7584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 7594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol, 7610e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer StringRef &Res) const { 7620e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Check for string table entry. First 4 bytes are 0. 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symbol->Name.Offset.Zeroes == 0) { 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Offset = Symbol->Name.Offset.Offset; 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getString(Offset, Res)) 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 7670e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 7680e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer } 7690e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symbol->Name.ShortName[7] == 0) 7710e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Null terminated, let ::strlen figure out the length. 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = StringRef(Symbol->Name.ShortName); 7730e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer else 7740e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Not null terminated, use all 8 bytes. 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = StringRef(Symbol->Name.ShortName, 8); 7760e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 7770e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 7780e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 779d4d03e09d3686d317da1166b578ca5ca35593970Marshall ClowArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData( 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symbol) const { 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const uint8_t *Aux = NULL; 782a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symbol->NumberOfAuxSymbols > 0) { 784d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow // AUX data comes immediately after the symbol in COFF 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Aux = reinterpret_cast<const uint8_t *>(Symbol + 1); 786d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# ifndef NDEBUG 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Verify that the Aux symbol points to a valid entry in the symbol table. 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); 78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset < COFFHeader->PointerToSymbolTable 79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || Offset >= COFFHeader->PointerToSymbolTable 7914bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 792d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow report_fatal_error("Aux Symbol data was outside of symbol table."); 793d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 79436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 795d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow == 0 && "Aux Symbol data did not point to the beginning of a symbol"); 796d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# endif 79745aad162c68ee58ba1aa8984499064f6b9c8d0f9Marshall Clow } 79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ArrayRef<uint8_t>(Aux, 79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Symbol->NumberOfAuxSymbols * sizeof(coff_symbol)); 800d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 801d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 802b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencererror_code COFFObjectFile::getSectionName(const coff_section *Sec, 803b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer StringRef &Res) const { 804b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer StringRef Name; 805b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (Sec->Name[7] == 0) 806b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Null terminated, let ::strlen figure out the length. 807b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Name = Sec->Name; 808b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer else 809b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Not null terminated, use all 8 bytes. 810b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Name = StringRef(Sec->Name, 8); 811b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 812b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Check for string table entry. First byte is '/'. 813b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (Name[0] == '/') { 814b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer uint32_t Offset; 81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Name[1] == '/') { 81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (decodeBase64StringEntry(Name.substr(2), Offset)) 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Name.substr(1).getAsInteger(10, Offset)) 82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::parse_failed; 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getString(Offset, Name)) 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 824b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer } 825b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 826b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Res = Name; 827b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return object_error::success; 828b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer} 829b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 8301f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencererror_code COFFObjectFile::getSectionContents(const coff_section *Sec, 8311f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer ArrayRef<uint8_t> &Res) const { 8321f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // The only thing that we need to verify is that the contents is contained 8331f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // within the file bounds. We don't need to make sure it doesn't cover other 8341f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // data, as there's nothing that says that is not allowed. 8351f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 8361f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; 8371f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer if (ConEnd > uintptr_t(Data->getBufferEnd())) 8381f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::parse_failed; 8391f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart), 8401f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Sec->SizeOfRawData); 8411f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::success; 8421f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer} 8431f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer 8440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 8454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return reinterpret_cast<const coff_relocation*>(Rel.p); 8460fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 8494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Rel.p = reinterpret_cast<uintptr_t>( 8504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 8510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8530fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 8540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer uint64_t &Res) const { 855956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 856b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev} 85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 858b0436a73054fe676b216a0cf872d1fc433125c62Danil Malysheverror_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 859b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev uint64_t &Res) const { 8604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Res = toRel(Rel)->VirtualAddress; 8610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 8620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8646c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindolasymbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 8650fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Ref; 86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ref.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); 86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return symbol_iterator(SymbolRef(Ref, this)); 8690fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 8729472b8d220fc746498429f430cb4c4dbfbd38f2aOwen Anderson uint64_t &Res) const { 8730fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 8740fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = R->Type; 8750fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 8760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 8774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section * 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFSection(const SectionRef &Section) const { 88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return toSec(Section.getRawDataRefImpl()); 881d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 882d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_symbol * 88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { 88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return toSymb(Symbol.getRawDataRefImpl()); 886d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 887d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_relocation * 88936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const { 89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return toRel(Reloc.getRawDataRefImpl()); 8919ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow} 8929ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow 89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \ 89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case COFF::reloc_type: \ 89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = #reloc_type; \ 89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 8974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 8984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 8994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_relocation *Reloc = toRel(Rel); 90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Res; 9024bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch (COFFHeader->Machine) { 9034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Reloc->Type) { 9054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 9064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 9074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 9084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 9094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 9104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 9114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 9124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 9134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 9144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 9154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 9164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 9174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 9184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 9194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 9204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 9214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 9224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 9244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 9254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 9264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Reloc->Type) { 9284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 9294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 9304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 9314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 9324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 9334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 9344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 9354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 9364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 9374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 9384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 9394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 9414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 9424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 9434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 94436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = "Unknown"; 9454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 94636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.append(Res.begin(), Res.end()); 9474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 9484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 9494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 9504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 9514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 9524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 9534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 95436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_relocation *Reloc = toRel(Rel); 95536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = 0; 95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) return EC; 95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Sym; 95836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Sym.p = reinterpret_cast<uintptr_t>(Symb); 95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SymName; 96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = getSymbolName(Sym, SymName)) return EC; 96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.append(SymName.begin(), SymName.end()); 9624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 963a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling} 964a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling 9655c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryNext(DataRefImpl LibData, 9665c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer LibraryRef &Result) const { 9675c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("getLibraryNext not implemented in COFFObjectFile"); 9685c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 9695c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 9705c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryPath(DataRefImpl LibData, 9715c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer StringRef &Result) const { 9725c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("getLibraryPath not implemented in COFFObjectFile"); 9735c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 9745c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 975a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamabool ImportDirectoryEntryRef:: 976a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaoperator==(const ImportDirectoryEntryRef &Other) const { 97736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ImportTable == Other.ImportTable && Index == Other.Index; 978a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 979a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 98036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ImportDirectoryEntryRef::moveNext() { 98136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Index; 982a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 983a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 984a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code ImportDirectoryEntryRef:: 985a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui UeyamagetImportTableEntry(const import_directory_table_entry *&Result) const { 98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ImportTable; 987a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 988a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 989a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 990a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code ImportDirectoryEntryRef::getName(StringRef &Result) const { 991a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr)) 99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 995a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 996a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 997a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 998a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaerror_code ImportDirectoryEntryRef::getImportLookupEntry( 999a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama const import_lookup_table_entry32 *&Result) const { 1000a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama uintptr_t IntPtr = 0; 100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = 100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr)) 100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 1004a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr); 1005a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama return object_error::success; 1006a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 1007a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ExportDirectoryEntryRef:: 100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesoperator==(const ExportDirectoryEntryRef &Other) const { 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ExportTable == Other.ExportTable && Index == Other.Index; 101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ExportDirectoryEntryRef::moveNext() { 101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Index; 101536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1016a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 101736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only 101836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result. 101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const { 102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr)) 102236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 102736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the starting ordinal number. 102836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const { 102936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ExportTable->OrdinalBase; 103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the export ordinal of the current export symbol. 103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const { 103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ExportTable->OrdinalBase + Index; 103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 103736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the address of the current export symbol. 104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const { 104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 104236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr( 104336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportTable->ExportAddressTableRVA, IntPtr)) 104436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 104536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const export_address_table_entry *entry = 104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const export_address_table_entry *>(IntPtr); 104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = entry[Index].ExportRVA; 104836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 104936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 105036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 105136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only 105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result. 105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineserror_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { 105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t IntPtr = 0; 105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr( 105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportTable->OrdinalTableRVA, IntPtr)) 105736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 105836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr); 105936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 106036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t NumEntries = ExportTable->NumberOfNamePointers; 106136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int Offset = 0; 106236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const ulittle16_t *I = Start, *E = Start + NumEntries; 106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I < E; ++I, ++Offset) { 106436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (*I != Index) 106536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 106636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr( 106736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExportTable->NamePointerRVA, IntPtr)) 106836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 106936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr); 107036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr)) 107136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 107236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = StringRef(reinterpret_cast<const char *>(IntPtr)); 107336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 1074a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result = ""; 107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return object_error::success; 107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1078a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 107936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object, 108036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool BufferOwned) { 108136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error_code EC; 108236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<COFFObjectFile> Ret( 108336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new COFFObjectFile(Object, EC, BufferOwned)); 108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC) 108536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 108636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Ret.release(); 108736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 1088