COFFObjectFile.cpp revision 0e752cb4b4eb5676aace4d9f3d7c2e2334c13777
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" 154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#include "llvm/ADT/SmallString.h" 16a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/StringSwitch.h" 17a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/Triple.h" 18a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 19a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace llvm; 20a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace object; 21a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 22a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace { 23a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle8_t; 24a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t; 25a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_t; 26a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::little16_t; 27a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 28a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 2925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencernamespace { 3025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if size is greater than the buffer size. And sets ec. 3125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerbool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) { 3225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (m->getBufferSize() < size) { 3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::unexpected_eof; 3425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return false; 3525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 3625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return true; 3725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 3825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 3925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if any bytes in [addr, addr + size) fall outsize of m. 4025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerbool checkAddr(const MemoryBuffer *m, 4125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer error_code &ec, 4225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t addr, 4325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t size) { 4425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (addr + size < addr || 4525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer addr + size < size || 4625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer addr + size > uintptr_t(m->getBufferEnd())) { 4725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::unexpected_eof; 4825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return false; 4925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 5025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return true; 5125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 5225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 5325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 5425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_symbol *COFFObjectFile::toSymb(DataRefImpl Symb) const { 5525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *addr = reinterpret_cast<const coff_symbol*>(Symb.p); 5625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 5725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 5825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the symbol points to a valid entry in the symbol table. 5925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t offset = uintptr_t(addr) - uintptr_t(base()); 6025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (offset < Header->PointerToSymbolTable 6125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer || offset >= Header->PointerToSymbolTable 6225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer + (Header->NumberOfSymbols * sizeof(coff_symbol))) 6325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Symbol was outside of symbol table."); 6425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 6525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer assert((offset - Header->PointerToSymbolTable) % sizeof(coff_symbol) 6625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer == 0 && "Symbol did not point to the beginning of a symbol"); 6725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 6825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 6925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return addr; 7025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 7125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 7225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_section *COFFObjectFile::toSec(DataRefImpl Sec) const { 7325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *addr = reinterpret_cast<const coff_section*>(Sec.p); 7425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 7525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 7625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the section points to a valid entry in the section table. 7725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (addr < SectionTable 7825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer || addr >= (SectionTable + Header->NumberOfSections)) 7925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Section was outside of section table."); 8025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 8125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t offset = uintptr_t(addr) - uintptr_t(SectionTable); 8225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer assert(offset % sizeof(coff_section) == 0 && 8325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer "Section did not point to the beginning of a section"); 8425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 8525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 8625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return addr; 8725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 8825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 8925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, 9025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer SymbolRef &Result) const { 9125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 92a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer symb += 1 + symb->NumberOfAuxSymbols; 9325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Symb.p = reinterpret_cast<uintptr_t>(symb); 9425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SymbolRef(Symb, this); 9525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 96a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 97a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 9825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer error_code COFFObjectFile::getSymbolName(DataRefImpl Symb, 9925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 10025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 1010e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return getSymbolName(symb, Result); 102a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 103a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 104ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolOffset(DataRefImpl Symb, 10525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 10625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 10764388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 10825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 10925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 11025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char Type; 11125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 113a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Type == 'U' || Type == 'w') 11425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 11525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (Section) 11625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = Section->VirtualAddress + symb->Value; 11725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 11825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = symb->Value; 11925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 120a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 121a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 122ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, 123ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer uint64_t &Result) const { 124ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 125ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_section *Section = NULL; 126ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSection(symb->SectionNumber, Section)) 127ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 128ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer char Type; 129ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 130ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 131ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (Type == 'U' || Type == 'w') 132ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = UnknownAddressOrSize; 133ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else if (Section) 134ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = reinterpret_cast<uintptr_t>(base() + 135ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Section->PointerToRawData + 136ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer symb->Value); 137ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else 138ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = reinterpret_cast<uintptr_t>(base() + symb->Value); 139ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 140ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 141ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 142ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolType(DataRefImpl Symb, 1431130a799ab2fd7042625163a2506518960394884Michael J. Spencer SymbolRef::Type &Result) const { 144ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 145ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Other; 146ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && 147ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 148ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_External; 149ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } else { 150ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (symb->Type.ComplexType == COFF::IMAGE_SYM_DTYPE_FUNCTION) { 151ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Function; 152ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } else { 153ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer char Type; 154ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 155ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 156ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (Type == 'r' || Type == 'R') { 157ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Data; 158ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 159ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 160ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 161ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 162ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 163ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 164ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::isSymbolGlobal(DataRefImpl Symb, 165ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer bool &Result) const { 166ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 167ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL); 168ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 169ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 170ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 17125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, 17225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 173a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // FIXME: Return the correct size. This requires looking at all the symbols 174a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // in the same section as this symbol, and looking for either the next 175a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // symbol, or the end of the section. 17625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 17764388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 17825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 17925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 18025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char Type; 18125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 18225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 183a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Type == 'U' || Type == 'w') 18425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 18525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (Section) 18625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = Section->SizeOfRawData - symb->Value; 18725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 18825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 0; 18925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 190a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 191a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 19225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, 19325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char &Result) const { 19425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 19525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef name; 19625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolName(Symb, name)) 19725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 19825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char ret = StringSwitch<char>(name) 199a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .StartsWith(".debug", 'N') 200a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .StartsWith(".sxdata", 'N') 201a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .Default('?'); 202a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 20325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (ret != '?') { 20425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = ret; 20525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 20625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 207a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 208a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer uint32_t Characteristics = 0; 20925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (symb->SectionNumber > 0) { 21064388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 21125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 21225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 213a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer Characteristics = Section->Characteristics; 214a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 215a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 216a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer switch (symb->SectionNumber) { 217a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_UNDEFINED: 218a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check storage classes. 21925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { 22025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 'w'; 22125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; // Don't do ::toupper. 22225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } else 223a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'u'; 224a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 225a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_ABSOLUTE: 226a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'a'; 227a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 228a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_DEBUG: 229a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'n'; 230a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 231a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 232a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check section type. 233a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 234a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 't'; 235a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ 236a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 237a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'r'; 238a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 239a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'd'; 240a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 241a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'b'; 242a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 243a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'i'; 244a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 245a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check for section symbol. 246a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC 247a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer && symb->Value == 0) 248a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 's'; 249a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 250a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 251a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 252a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = ::toupper(ret); 253a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 25425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = ret; 25525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 256a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 257a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 25825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::isSymbolInternal(DataRefImpl Symb, 25925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool &Result) const { 26025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = false; 26125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 262a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 263a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 26425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionNext(DataRefImpl Sec, 26525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer SectionRef &Result) const { 26625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 267a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer sec += 1; 26825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Sec.p = reinterpret_cast<uintptr_t>(sec); 26925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SectionRef(Sec, this); 27025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 271a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 272a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 27325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionName(DataRefImpl Sec, 27425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 27525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 276a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer StringRef name; 277a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (sec->Name[7] == 0) 278a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Null terminated, let ::strlen figure out the length. 279a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer name = sec->Name; 280a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else 281a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Not null terminated, use all 8 bytes. 282a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer name = StringRef(sec->Name, 8); 283a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 284a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check for string table entry. First byte is '/'. 285a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (name[0] == '/') { 286a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer uint32_t Offset; 287539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher name.substr(1).getAsInteger(10, Offset); 28825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getString(Offset, name)) 28925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 290a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 291a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 29225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = name; 29325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 294a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 295a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 29625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionAddress(DataRefImpl Sec, 29725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 29825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 29925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->VirtualAddress; 30025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 301a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 302a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 30325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionSize(DataRefImpl Sec, 30425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 30525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 30625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->SizeOfRawData; 30725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 308a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 309a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 31025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionContents(DataRefImpl Sec, 31125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 31225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 31325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // The only thing that we need to verify is that the contents is contained 31425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // within the file bounds. We don't need to make sure it doesn't cover other 31525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // data, as there's nothing that says that is not allowed. 31625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t con_start = uintptr_t(base()) + sec->PointerToRawData; 31725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t con_end = con_start + sec->SizeOfRawData; 31825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (con_end >= uintptr_t(Data->getBufferEnd())) 31925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 32025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = StringRef(reinterpret_cast<const char*>(con_start), 32125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer sec->SizeOfRawData); 32225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 323a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 324a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 325e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencererror_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec, 326e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer uint64_t &Res) const { 327e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer const coff_section *sec = toSec(Sec); 328e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer if (!sec) 329e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::parse_failed; 330e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1); 331e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::success; 332e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer} 333e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer 33425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::isSectionText(DataRefImpl Sec, 33525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool &Result) const { 33625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 33725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 33813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 33913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 34013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 34113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionData(DataRefImpl Sec, 34213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 34313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer const coff_section *sec = toSec(Sec); 34413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 34513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 34613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 34713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 34813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionBSS(DataRefImpl Sec, 34913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 35013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer const coff_section *sec = toSec(Sec); 35113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 35225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 353a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 354a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 35507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramererror_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, 35607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer DataRefImpl Symb, 35707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer bool &Result) const { 358bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer const coff_section *sec = toSec(Sec); 359bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer const coff_symbol *symb = toSymb(Symb); 360bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer const coff_section *symb_sec; 361bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec; 362bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer if (symb_sec == sec) 363bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = true; 364bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer else 365bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = false; 36607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer return object_error::success; 36707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer} 36807ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer 3694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const { 3704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_section *sec = toSec(Sec); 3714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl ret; 3724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer std::memset(&ret, 0, sizeof(ret)); 3734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (sec->NumberOfRelocations == 0) 3744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = 0; 3754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 3764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations); 3774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 3784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return relocation_iterator(RelocationRef(ret, this)); 3794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 3804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 3814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const { 3824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_section *sec = toSec(Sec); 3834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl ret; 3844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer std::memset(&ret, 0, sizeof(ret)); 3854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (sec->NumberOfRelocations == 0) 3864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = 0; 3874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 3884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = reinterpret_cast<uintptr_t>( 3894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>( 3904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer base() + sec->PointerToRelocations) 3914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer + sec->NumberOfRelocations); 3924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 3934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return relocation_iterator(RelocationRef(ret, this)); 3944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 3954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 396001c9205fca2220480589ec355cb6ec701a37e08Michael J. SpencerCOFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) 397001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer : ObjectFile(Binary::isCOFF, Object, ec) { 39825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check that we at least have enough room for a header. 39925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkSize(Data, ec, sizeof(coff_file_header))) return; 400539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 40125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // The actual starting location of the COFF header in the file. This can be 40225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // non-zero in PE/COFF files. 40325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t HeaderStart = 0; 404539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 40525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check if this is a PE/COFF file. 406001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (base()[0] == 0x4d && base()[1] == 0x5a) { 407539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 408539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE signature to find 'normal' COFF header. 40925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkSize(Data, ec, 0x3c + 8)) return; 41025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer HeaderStart += *reinterpret_cast<const ulittle32_t *>(base() + 0x3c); 41125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check the PE header. ("PE\0\0") 4123209a03dafe1a23fe74c933cebd9f9c92a2a3616Benjamin Kramer if (std::memcmp(base() + HeaderStart, "PE\0\0", 4) != 0) { 41325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::parse_failed; 41425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 41525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 41625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer HeaderStart += 4; // Skip the PE Header. 417539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher } 418539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 41925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Header = reinterpret_cast<const coff_file_header *>(base() + HeaderStart); 42025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header))) 42125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 4220fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 423a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer SectionTable = 424001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer reinterpret_cast<const coff_section *>( base() 42525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer + HeaderStart 426a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer + sizeof(coff_file_header) 427a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer + Header->SizeOfOptionalHeader); 42825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkAddr(Data, ec, uintptr_t(SectionTable), 42925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Header->NumberOfSections * sizeof(coff_section))) 43025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 43125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 432a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer SymbolTable = 433001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer reinterpret_cast<const coff_symbol *>(base() 43425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer + Header->PointerToSymbolTable); 43525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkAddr(Data, ec, uintptr_t(SymbolTable), 43625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Header->NumberOfSymbols * sizeof(coff_symbol))) 43725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 438a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 439a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Find string table. 440001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer StringTable = reinterpret_cast<const char *>(base()) 44125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer + Header->PointerToSymbolTable 44225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer + Header->NumberOfSymbols * sizeof(coff_symbol); 44325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkAddr(Data, ec, uintptr_t(StringTable), sizeof(ulittle32_t))) 44425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 44525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 44625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringTableSize = *reinterpret_cast<const ulittle32_t *>(StringTable); 44725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkAddr(Data, ec, uintptr_t(StringTable), StringTableSize)) 44825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 44925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check that the string table is null terminated if has any in it. 45025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (StringTableSize < 4 45125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer || (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)) { 45225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::parse_failed; 45325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 45425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 4550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 45625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::success; 457a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 458a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 4594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::begin_symbols() const { 4607acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 46125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer std::memset(&ret, 0, sizeof(DataRefImpl)); 4627acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(SymbolTable); 4637acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 464a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 465a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 4664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::end_symbols() const { 467a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // The symbol table ends where the string table begins. 4687acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 46925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer std::memset(&ret, 0, sizeof(DataRefImpl)); 4707acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(StringTable); 4717acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 472a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 473a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 4744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::begin_sections() const { 4757acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 47625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer std::memset(&ret, 0, sizeof(DataRefImpl)); 4777acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable); 4787acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return section_iterator(SectionRef(ret, this)); 479a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 480a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 4814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::end_sections() const { 4827acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 48325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer std::memset(&ret, 0, sizeof(DataRefImpl)); 4847acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); 4857acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return section_iterator(SectionRef(ret, this)); 486a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 487a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 488a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const { 4897acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 490a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 491a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 492a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const { 493a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer switch(Header->Machine) { 494a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 495a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-i386"; 496a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 497a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-x86-64"; 498a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 499a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-<unknown arch>"; 500a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 501a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 502a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 503a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const { 504a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer switch(Header->Machine) { 505a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 506a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86; 507a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 508a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86_64; 509a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 510a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::UnknownArch; 511a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 512a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 513a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5140e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getHeader(const coff_file_header *&Res) const { 5150e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer Res = Header; 5160e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 5170e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 5180e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 51925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSection(int32_t index, 52025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *&Result) const { 52125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check for special index values. 52225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (index == COFF::IMAGE_SYM_UNDEFINED || 52325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer index == COFF::IMAGE_SYM_ABSOLUTE || 52425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer index == COFF::IMAGE_SYM_DEBUG) 52525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = NULL; 52625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (index > 0 && index <= Header->NumberOfSections) 52725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // We already verified the section table data, so no need to check again. 52825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SectionTable + (index - 1); 52925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 53025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 53125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 532a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 533a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 53425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getString(uint32_t offset, 53525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 53625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (StringTableSize <= 4) 53725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Tried to get a string from an empty string table. 53825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 53925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (offset >= StringTableSize) 54025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::unexpected_eof; 54125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = StringRef(StringTable + offset); 54225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 543a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 544a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getSymbol(uint32_t index, 5464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_symbol *&Result) const { 5470e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (index >= 0 && index < Header->NumberOfSymbols) 5484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result = SymbolTable + index; 5494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 5504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::parse_failed; 5514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 5524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 5534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 5540e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getSymbolName(const coff_symbol *symbol, 5550e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer StringRef &Res) const { 5560e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Check for string table entry. First 4 bytes are 0. 5570e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (symbol->Name.Offset.Zeroes == 0) { 5580e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer uint32_t Offset = symbol->Name.Offset.Offset; 5590e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (error_code ec = getString(Offset, Res)) 5600e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return ec; 5610e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 5620e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer } 5630e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 5640e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (symbol->Name.ShortName[7] == 0) 5650e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Null terminated, let ::strlen figure out the length. 5660e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer Res = StringRef(symbol->Name.ShortName); 5670e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer else 5680e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Not null terminated, use all 8 bytes. 5690e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer Res = StringRef(symbol->Name.ShortName, 8); 5700e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 5710e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 5720e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 5730fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 5744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return reinterpret_cast<const coff_relocation*>(Rel.p); 5750fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 5760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, 5770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer RelocationRef &Res) const { 5784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Rel.p = reinterpret_cast<uintptr_t>( 5794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 5800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = RelocationRef(Rel, this); 5810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 5820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 5830fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 5840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer uint64_t &Res) const { 5854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Res = toRel(Rel)->VirtualAddress; 5860fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 5870fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 5880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, 5890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer SymbolRef &Res) const { 5900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 5910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer DataRefImpl Symb; 5920fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); 5930fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = SymbolRef(Symb, this); 5940fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 5950fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 5960fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 5970fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer uint32_t &Res) const { 5980fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 5990fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = R->Type; 6000fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 6010fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 6024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 6034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \ 6044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::enum: res = #enum; break; 6054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 6064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 6074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 6084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_relocation *reloc = toRel(Rel); 6094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer StringRef res; 6104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer switch (Header->Machine) { 6114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 6124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer switch (reloc->Type) { 6134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 6144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 6154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 6164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 6174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 6184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 6194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 6204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 6214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 6224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 6234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 6244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 6254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 6264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 6274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 6284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 6294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 6304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 6314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 6324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 6334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 6344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 6354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer switch (reloc->Type) { 6364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 6374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 6384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 6394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 6404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 6414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 6424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 6434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 6444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 6454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 6464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 6474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 6484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 6494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 6504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 6514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 6524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 6534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 6544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result.append(res.begin(), res.end()); 6554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 6564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 6574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 6584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 6594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 6600fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, 6610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer int64_t &Res) const { 6620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = 0; 6630fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 6640fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 6654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 6664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 6674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_relocation *reloc = toRel(Rel); 66848f248ad5f9e435f3aeaa3aa9bca890687085540NAKAMURA Takumi const coff_symbol *symb = 0; 6694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec; 6704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl sym; 6714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ::memset(&sym, 0, sizeof(sym)); 6724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer sym.p = reinterpret_cast<uintptr_t>(symb); 6734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer StringRef symname; 6744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (error_code ec = getSymbolName(sym, symname)) return ec; 6754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result.append(symname.begin(), symname.end()); 6764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 677a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling} 678a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling 679a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace llvm { 680a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 681a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { 682001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer error_code ec; 683001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return new COFFObjectFile(Object, ec); 684a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 685a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 686a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} // end namespace llvm 687