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" 19a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 20ca8b2c655eb4d283187cbbb4f0f3acd34f60fa1cLogan Chien#include <ctype.h> 21ca8b2c655eb4d283187cbbb4f0f3acd34f60fa1cLogan Chien 22a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace llvm; 23a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace object; 24a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 25a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace { 26a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle8_t; 27a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t; 28a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_t; 29a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::little16_t; 30a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 31a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 3225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencernamespace { 3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if size is greater than the buffer size. And sets ec. 3425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerbool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) { 3525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (m->getBufferSize() < size) { 3625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 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> 452f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyamaerror_code getObject(const T *&Obj, const MemoryBuffer *M, const uint8_t *Ptr, 462f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama 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} 5625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 5725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 5825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_symbol *COFFObjectFile::toSymb(DataRefImpl Symb) const { 5925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *addr = reinterpret_cast<const coff_symbol*>(Symb.p); 6025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 6125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 6225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the symbol points to a valid entry in the symbol table. 6325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t offset = uintptr_t(addr) - uintptr_t(base()); 644bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (offset < COFFHeader->PointerToSymbolTable 654bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama || offset >= COFFHeader->PointerToSymbolTable 664bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 6725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Symbol was outside of symbol table."); 6825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 694bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama assert((offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 7025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer == 0 && "Symbol did not point to the beginning of a symbol"); 7125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 7225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 7325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return addr; 7425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 7525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 7625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_section *COFFObjectFile::toSec(DataRefImpl Sec) const { 7725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *addr = reinterpret_cast<const coff_section*>(Sec.p); 7825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 7925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG 8025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Verify that the section points to a valid entry in the section table. 8125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (addr < SectionTable 824bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama || addr >= (SectionTable + COFFHeader->NumberOfSections)) 8325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer report_fatal_error("Section was outside of section table."); 8425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 8525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uintptr_t offset = uintptr_t(addr) - uintptr_t(SectionTable); 8625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer assert(offset % sizeof(coff_section) == 0 && 8725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer "Section did not point to the beginning of a section"); 8825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif 8925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 9025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return addr; 9125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer} 9225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 9325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, 9425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer SymbolRef &Result) const { 9525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 96a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer symb += 1 + symb->NumberOfAuxSymbols; 9725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Symb.p = reinterpret_cast<uintptr_t>(symb); 9825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SymbolRef(Symb, this); 9925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 100a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 101a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 10225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer error_code COFFObjectFile::getSymbolName(DataRefImpl Symb, 10325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 10425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 1050e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return getSymbolName(symb, Result); 106a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 107a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 108b0436a73054fe676b216a0cf872d1fc433125c62Danil Malysheverror_code COFFObjectFile::getSymbolFileOffset(DataRefImpl Symb, 10925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 11025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 11164388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 11325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 11425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char Type; 11525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 11625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 117a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Type == 'U' || Type == 'w') 11825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 11925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (Section) 120b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev Result = Section->PointerToRawData + symb->Value; 12125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 12225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = symb->Value; 12325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 124a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 125a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 126ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, 127ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer uint64_t &Result) const { 128ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 129ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_section *Section = NULL; 130ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSection(symb->SectionNumber, Section)) 131ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 132ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer char Type; 133ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 134ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 135ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (Type == 'U' || Type == 'w') 136ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = UnknownAddressOrSize; 137ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else if (Section) 138b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev Result = Section->VirtualAddress + symb->Value; 139ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer else 140b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev Result = symb->Value; 141ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 142ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 143ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 144ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolType(DataRefImpl Symb, 1451130a799ab2fd7042625163a2506518960394884Michael J. Spencer SymbolRef::Type &Result) const { 146ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 147ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Other; 148ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && 149ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { 1502c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result = SymbolRef::ST_Unknown; 151ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } else { 1525e3a082c797f0214d44858b05a13543872dfd413Michael J. Spencer if (symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) { 153ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Function; 154ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } else { 155ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer char Type; 156ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 157ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return ec; 158ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer if (Type == 'r' || Type == 'R') { 159ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer Result = SymbolRef::ST_Data; 160ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 161ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 162ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer } 163ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer return object_error::success; 164ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer} 165ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 166c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyererror_code COFFObjectFile::getSymbolFlags(DataRefImpl Symb, 167c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer uint32_t &Result) const { 168ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer const coff_symbol *symb = toSymb(Symb); 169c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result = SymbolRef::SF_None; 170c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 1712c67727046234ad9702ab5acb72700b5ac99a676David Meyer // TODO: Correctly set SF_FormatSpecific, SF_ThreadLocal, SF_Common 1722c67727046234ad9702ab5acb72700b5ac99a676David Meyer 1732c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && 1742c67727046234ad9702ab5acb72700b5ac99a676David Meyer symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) 1752c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_Undefined; 176c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 177c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer // TODO: This are certainly too restrictive. 178c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 179c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Global; 180c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 181c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 182c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Weak; 183c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 184c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE) 185c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Absolute; 186ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer 187c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer return object_error::success; 188c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer} 189c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer 19025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, 19125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 192a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // FIXME: Return the correct size. This requires looking at all the symbols 193a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // in the same section as this symbol, and looking for either the next 194a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // symbol, or the end of the section. 19525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 19664388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 19725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 19825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 19925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char Type; 20025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolNMTypeChar(Symb, Type)) 20125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 202a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Type == 'U' || Type == 'w') 20325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = UnknownAddressOrSize; 20425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if (Section) 20525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = Section->SizeOfRawData - symb->Value; 20625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 20725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 0; 20825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 209a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 210a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 21125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, 21225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char &Result) const { 21325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 21425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef name; 21525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSymbolName(Symb, name)) 21625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 21725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char ret = StringSwitch<char>(name) 218a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .StartsWith(".debug", 'N') 219a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .StartsWith(".sxdata", 'N') 220a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer .Default('?'); 221a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 22225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (ret != '?') { 22325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = ret; 22425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 22525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 226a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 227a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer uint32_t Characteristics = 0; 22825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (symb->SectionNumber > 0) { 22964388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer const coff_section *Section = NULL; 23025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, Section)) 23125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return ec; 232a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer Characteristics = Section->Characteristics; 233a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 234a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 235a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer switch (symb->SectionNumber) { 236a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_UNDEFINED: 237a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check storage classes. 23825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { 23925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = 'w'; 24025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; // Don't do ::toupper. 24111ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer } else if (symb->Value != 0) // Check for common symbols. 24211ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer ret = 'c'; 24311ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer else 244a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'u'; 245a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 246a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_ABSOLUTE: 247a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'a'; 248a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 249a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_SYM_DEBUG: 250a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'n'; 251a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer break; 252a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 253a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check section type. 254a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 255a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 't'; 256a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ 257a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 258a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'r'; 259a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 260a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'd'; 261a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 262a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'b'; 263a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 264a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 'i'; 265a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 266a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // Check for section symbol. 267a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC 268a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer && symb->Value == 0) 269a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ret = 's'; 270a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 271a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 272a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 27387d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei ret = ::toupper(static_cast<unsigned char>(ret)); 274a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 27525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = ret; 27625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 277a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 278a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 2799b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencererror_code COFFObjectFile::getSymbolSection(DataRefImpl Symb, 2809b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer section_iterator &Result) const { 2819b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer const coff_symbol *symb = toSymb(Symb); 2829b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer if (symb->SectionNumber <= COFF::IMAGE_SYM_UNDEFINED) 2839b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer Result = end_sections(); 2849b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer else { 285a483fc8e6f9533317f517f2d03f3a41ec0aee663Daniel Dunbar const coff_section *sec = 0; 2869b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer if (error_code ec = getSection(symb->SectionNumber, sec)) return ec; 2879b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer DataRefImpl Sec; 2889b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer Sec.p = reinterpret_cast<uintptr_t>(sec); 2899b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer Result = section_iterator(SectionRef(Sec, this)); 2909b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer } 2919b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer return object_error::success; 2929b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer} 2939b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer 294a41dce3c642e50775352cce49e3a3d0cd004d393Tim Northovererror_code COFFObjectFile::getSymbolValue(DataRefImpl Symb, 295a41dce3c642e50775352cce49e3a3d0cd004d393Tim Northover uint64_t &Val) const { 296a41dce3c642e50775352cce49e3a3d0cd004d393Tim Northover report_fatal_error("getSymbolValue unimplemented in COFFObjectFile"); 297a41dce3c642e50775352cce49e3a3d0cd004d393Tim Northover} 298a41dce3c642e50775352cce49e3a3d0cd004d393Tim Northover 29925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionNext(DataRefImpl Sec, 30025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer SectionRef &Result) const { 30125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 302a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer sec += 1; 30325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Sec.p = reinterpret_cast<uintptr_t>(sec); 30425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SectionRef(Sec, this); 30525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 306a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 307a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 30825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionName(DataRefImpl Sec, 30925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 31025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 311b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return getSectionName(sec, Result); 312a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 313a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 31425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionAddress(DataRefImpl Sec, 31525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 31625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 31725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->VirtualAddress; 31825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 319a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 320a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 32125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionSize(DataRefImpl Sec, 32225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer uint64_t &Result) const { 32325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 32425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->SizeOfRawData; 32525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 326a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 327a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 32825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionContents(DataRefImpl Sec, 32925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 33025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 3311f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer ArrayRef<uint8_t> Res; 3321f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer error_code EC = getSectionContents(sec, Res); 3331f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size()); 3341f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return EC; 335a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 336a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 337e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencererror_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec, 338e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer uint64_t &Res) const { 339e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer const coff_section *sec = toSec(Sec); 340e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer if (!sec) 341e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::parse_failed; 342e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1); 343e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer return object_error::success; 344e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer} 345e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer 34625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::isSectionText(DataRefImpl Sec, 34725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool &Result) const { 34825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *sec = toSec(Sec); 34925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 35013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 35113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 35213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 35313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionData(DataRefImpl Sec, 35413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 35513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer const coff_section *sec = toSec(Sec); 35613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 35713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer return object_error::success; 35813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer} 35913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer 36013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionBSS(DataRefImpl Sec, 36113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer bool &Result) const { 36213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer const coff_section *sec = toSec(Sec); 36313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 36425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 365a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 366a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 367c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurderror_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, 368c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 369c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // FIXME: Unimplemented 370c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = true; 371c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 372c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 373c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 374c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurderror_code COFFObjectFile::isSectionVirtual(DataRefImpl Sec, 375c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 376c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd const coff_section *sec = toSec(Sec); 377c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 378c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 379c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 380c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 381c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurderror_code COFFObjectFile::isSectionZeroInit(DataRefImpl Sec, 382c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool &Result) const { 38330b20ebdd3a41e103c6aa35849a33ed299332bc9Andrew Kaylor // FIXME: Unimplemented. 384c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = false; 385c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 386c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 387c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 3883a129c85920404e7ccdb7e655c89fa60a0309cfdAndrew Kaylorerror_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Sec, 3893a129c85920404e7ccdb7e655c89fa60a0309cfdAndrew Kaylor bool &Result) const { 3903a129c85920404e7ccdb7e655c89fa60a0309cfdAndrew Kaylor // FIXME: Unimplemented. 391c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Result = false; 392c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd return object_error::success; 393c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 394c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 39507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramererror_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, 39607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer DataRefImpl Symb, 39707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer bool &Result) const { 398bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer const coff_section *sec = toSec(Sec); 399bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer const coff_symbol *symb = toSymb(Symb); 400a483fc8e6f9533317f517f2d03f3a41ec0aee663Daniel Dunbar const coff_section *symb_sec = 0; 401bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec; 402bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer if (symb_sec == sec) 403bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = true; 404bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer else 405bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer Result = false; 40607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer return object_error::success; 40707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer} 40807ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer 4094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const { 4104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_section *sec = toSec(Sec); 4114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl ret; 4124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (sec->NumberOfRelocations == 0) 4134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = 0; 4144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 4154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations); 4164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 4174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return relocation_iterator(RelocationRef(ret, this)); 4184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 4194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 4204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const { 4214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_section *sec = toSec(Sec); 4224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl ret; 4234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (sec->NumberOfRelocations == 0) 4244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = 0; 4254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 4264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer ret.p = reinterpret_cast<uintptr_t>( 4274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>( 4284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer base() + sec->PointerToRelocations) 4294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer + sec->NumberOfRelocations); 4304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 4314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return relocation_iterator(RelocationRef(ret, this)); 4324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 4334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 434001c9205fca2220480589ec355cb6ec701a37e08Michael J. SpencerCOFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) 4352c6f997290f589b80da903e33718175666557dd7Rafael Espindola : ObjectFile(Binary::ID_COFF, Object) 4364bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama , COFFHeader(0) 4374bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama , PE32Header(0) 4382f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama , DataDirectory(0) 4397151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer , SectionTable(0) 4407151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer , SymbolTable(0) 4417151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer , StringTable(0) 4427151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer , StringTableSize(0) { 44325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check that we at least have enough room for a header. 44425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkSize(Data, ec, sizeof(coff_file_header))) return; 445539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 4464bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // The current location in the file where we are looking at. 4474bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama uint64_t CurPtr = 0; 4484bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 4494bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // PE header is optional and is present only in executables. If it exists, 4504bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // it is placed right after COFF header. 4514bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama bool hasPEHeader = false; 452539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 45325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check if this is a PE/COFF file. 454001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (base()[0] == 0x4d && base()[1] == 0x5a) { 455539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 456539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher // PE signature to find 'normal' COFF header. 45725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!checkSize(Data, ec, 0x3c + 8)) return; 4584bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); 4594bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama // Check the PE magic bytes. ("PE\0\0") 4604bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) { 46125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::parse_failed; 46225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 46325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 4644bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += 4; // Skip the PE magic bytes. 4654bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama hasPEHeader = true; 466539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher } 467539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher 4682f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(COFFHeader, Data, base() + CurPtr))) 46925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 4704bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += sizeof(coff_file_header); 4710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 4724bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (hasPEHeader) { 4732f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(PE32Header, Data, base() + CurPtr))) 4744bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return; 4752f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if (PE32Header->Magic != 0x10b) { 4762f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // We only support PE32. If this is PE32 (not PE32+), the magic byte 4772f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // should be 0x10b. If this is not PE32, continue as if there's no PE 4782f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // header in this file. 4794bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama PE32Header = 0; 4802f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama } else if (PE32Header->NumberOfRvaAndSize > 0) { 4812f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama const uint8_t *addr = base() + CurPtr + sizeof(pe32_header); 4822f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama uint64_t size = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize; 4832f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(DataDirectory, Data, addr, size))) 4842f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return; 4852f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama } 4864bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama CurPtr += COFFHeader->SizeOfOptionalHeader; 4874bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama } 4880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 4892f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(SectionTable, Data, base() + CurPtr, 4902f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama COFFHeader->NumberOfSections * sizeof(coff_section)))) 49125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return; 49225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 4934bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (COFFHeader->PointerToSymbolTable != 0) { 4942f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(SymbolTable, Data, 4952f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama base() + COFFHeader->PointerToSymbolTable, 4962f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))) 4977151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 498a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 4992f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // Find string table. The first four byte of the string table contains the 5002f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // total size of the string table, including the size field itself. If the 5012f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // string table is empty, the value of the first four byte would be 4. 5022f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama const uint8_t *StringTableAddr = base() + COFFHeader->PointerToSymbolTable 5032f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama + COFFHeader->NumberOfSymbols * sizeof(coff_symbol); 5042f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama const ulittle32_t *StringTableSizePtr; 5052f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(StringTableSizePtr, Data, StringTableAddr))) 5067151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 5072f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama StringTableSize = *StringTableSizePtr; 5082f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if ((ec = getObject(StringTable, Data, StringTableAddr, StringTableSize))) 5097151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 5102f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama 5117151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer // Check that the string table is null terminated if has any in it. 5127151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer if (StringTableSize < 4 5137151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer || (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)) { 5147151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer ec = object_error::parse_failed; 5157151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer return; 5167151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer } 51725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 5180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 51925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer ec = object_error::success; 520a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 521a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::begin_symbols() const { 5237acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 5247acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(SymbolTable); 5257acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 526a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 527a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::end_symbols() const { 529a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer // The symbol table ends where the string table begins. 5307acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 5317acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(StringTable); 5327acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 533a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 534a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 535dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator COFFObjectFile::begin_dynamic_symbols() const { 536dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // TODO: implement 537dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile"); 538dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 539dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 540dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator COFFObjectFile::end_dynamic_symbols() const { 541dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // TODO: implement 542dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile"); 543dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 544dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 5455c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator COFFObjectFile::begin_libraries_needed() const { 5465c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: implement 5475c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 5485c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 5495c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 5505c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator COFFObjectFile::end_libraries_needed() const { 5515c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: implement 5525c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Libraries needed unimplemented in COFFObjectFile"); 5535c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 5545c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 55597f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid MeyerStringRef COFFObjectFile::getLoadName() const { 55697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer // COFF does not have this field. 55797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer return ""; 55897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer} 55997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 56097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 5614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::begin_sections() const { 5627acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 5637acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable); 5647acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return section_iterator(SectionRef(ret, this)); 565a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 566a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::end_sections() const { 5687acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer DataRefImpl ret; 5694bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama ret.p = reinterpret_cast<intptr_t>(SectionTable + COFFHeader->NumberOfSections); 5707acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return section_iterator(SectionRef(ret, this)); 571a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 572a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 573a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const { 5747acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 575a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 576a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 577a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const { 5784bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch(COFFHeader->Machine) { 579a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 580a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-i386"; 581a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 582a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-x86-64"; 583a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 584a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return "COFF-<unknown arch>"; 585a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 586a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 587a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 588a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const { 5894bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch(COFFHeader->Machine) { 590a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 591a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86; 592a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 593a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::x86_64; 594a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer default: 595a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer return Triple::UnknownArch; 596a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 597a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 598a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 5994bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama// This method is kept here because lld uses this. As soon as we make 6004bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama// lld to use getCOFFHeader, this method will be removed. 6010e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getHeader(const coff_file_header *&Res) const { 6024bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return getCOFFHeader(Res); 6034bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 6044bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 6054bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyamaerror_code COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const { 6064bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama Res = COFFHeader; 6074bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama return object_error::success; 6084bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama} 6094bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama 6104bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyamaerror_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { 6114bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama Res = PE32Header; 6120e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 6130e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 6140e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 6152f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyamaerror_code COFFObjectFile::getDataDirectory(uint32_t index, 6162f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama const data_directory *&Res) const { 6172f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama // Error if if there's no data directory or the index is out of range. 6182f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama if (!DataDirectory || index > PE32Header->NumberOfRvaAndSize) 6192f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama return object_error::parse_failed; 6202f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama Res = &DataDirectory[index]; 6210e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 6220e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 6230e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 62425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSection(int32_t index, 62525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer const coff_section *&Result) const { 62625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Check for special index values. 62725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (index == COFF::IMAGE_SYM_UNDEFINED || 62825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer index == COFF::IMAGE_SYM_ABSOLUTE || 62925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer index == COFF::IMAGE_SYM_DEBUG) 63025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = NULL; 6314bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama else if (index > 0 && index <= COFFHeader->NumberOfSections) 63225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // We already verified the section table data, so no need to check again. 63325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = SectionTable + (index - 1); 63425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else 63525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 63625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 637a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 638a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 63925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getString(uint32_t offset, 64025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef &Result) const { 64125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (StringTableSize <= 4) 64225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer // Tried to get a string from an empty string table. 64325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::parse_failed; 64425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (offset >= StringTableSize) 64525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::unexpected_eof; 64625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer Result = StringRef(StringTable + offset); 64725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return object_error::success; 648a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} 649a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 6504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getSymbol(uint32_t index, 6514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_symbol *&Result) const { 6524bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (index < COFFHeader->NumberOfSymbols) 6534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result = SymbolTable + index; 6544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer else 6554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::parse_failed; 6564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 6574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 6584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 6590e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getSymbolName(const coff_symbol *symbol, 6600e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer StringRef &Res) const { 6610e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Check for string table entry. First 4 bytes are 0. 6620e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (symbol->Name.Offset.Zeroes == 0) { 6630e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer uint32_t Offset = symbol->Name.Offset.Offset; 6640e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (error_code ec = getString(Offset, Res)) 6650e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return ec; 6660e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 6670e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer } 6680e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 6690e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer if (symbol->Name.ShortName[7] == 0) 6700e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Null terminated, let ::strlen figure out the length. 6710e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer Res = StringRef(symbol->Name.ShortName); 6720e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer else 6730e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer // Not null terminated, use all 8 bytes. 6740e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer Res = StringRef(symbol->Name.ShortName, 8); 6750e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer return object_error::success; 6760e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer} 6770e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer 678d4d03e09d3686d317da1166b578ca5ca35593970Marshall ClowArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData( 679d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow const coff_symbol *symbol) const { 680d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow const uint8_t *aux = NULL; 681d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 682d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow if ( symbol->NumberOfAuxSymbols > 0 ) { 683d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow // AUX data comes immediately after the symbol in COFF 684d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow aux = reinterpret_cast<const uint8_t *>(symbol + 1); 685d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# ifndef NDEBUG 686d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow // Verify that the aux symbol points to a valid entry in the symbol table. 687d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow uintptr_t offset = uintptr_t(aux) - uintptr_t(base()); 6884bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama if (offset < COFFHeader->PointerToSymbolTable 6894bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama || offset >= COFFHeader->PointerToSymbolTable 6904bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) 691d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow report_fatal_error("Aux Symbol data was outside of symbol table."); 692d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 6934bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama assert((offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) 694d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow == 0 && "Aux Symbol data did not point to the beginning of a symbol"); 695d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# endif 69645aad162c68ee58ba1aa8984499064f6b9c8d0f9Marshall Clow } 697d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow return ArrayRef<uint8_t>(aux, symbol->NumberOfAuxSymbols * sizeof(coff_symbol)); 698d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 699d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 700b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencererror_code COFFObjectFile::getSectionName(const coff_section *Sec, 701b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer StringRef &Res) const { 702b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer StringRef Name; 703b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (Sec->Name[7] == 0) 704b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Null terminated, let ::strlen figure out the length. 705b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Name = Sec->Name; 706b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer else 707b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Not null terminated, use all 8 bytes. 708b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Name = StringRef(Sec->Name, 8); 709b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 710b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer // Check for string table entry. First byte is '/'. 711b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (Name[0] == '/') { 712b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer uint32_t Offset; 713b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (Name.substr(1).getAsInteger(10, Offset)) 714b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return object_error::parse_failed; 715b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer if (error_code ec = getString(Offset, Name)) 716b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return ec; 717b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer } 718b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 719b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer Res = Name; 720b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer return object_error::success; 721b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer} 722b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer 7231f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencererror_code COFFObjectFile::getSectionContents(const coff_section *Sec, 7241f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer ArrayRef<uint8_t> &Res) const { 7251f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // The only thing that we need to verify is that the contents is contained 7261f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // within the file bounds. We don't need to make sure it doesn't cover other 7271f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer // data, as there's nothing that says that is not allowed. 7281f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; 7291f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; 7301f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer if (ConEnd > uintptr_t(Data->getBufferEnd())) 7311f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::parse_failed; 7321f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart), 7331f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer Sec->SizeOfRawData); 7341f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer return object_error::success; 7351f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer} 7361f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer 7370fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { 7384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return reinterpret_cast<const coff_relocation*>(Rel.p); 7390fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 7400fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, 7410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer RelocationRef &Res) const { 7424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Rel.p = reinterpret_cast<uintptr_t>( 7434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer reinterpret_cast<const coff_relocation*>(Rel.p) + 1); 7440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = RelocationRef(Rel, this); 7450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 7460fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 7470fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, 7480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer uint64_t &Res) const { 749956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); 750b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev} 751b0436a73054fe676b216a0cf872d1fc433125c62Danil Malysheverror_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, 752b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev uint64_t &Res) const { 7534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Res = toRel(Rel)->VirtualAddress; 7540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 7550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 7566c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindolasymbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 7570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 7580fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer DataRefImpl Symb; 7590fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); 7606c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola return symbol_iterator(SymbolRef(Symb, this)); 7610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 7620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationType(DataRefImpl Rel, 7639472b8d220fc746498429f430cb4c4dbfbd38f2aOwen Anderson uint64_t &Res) const { 7640fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer const coff_relocation* R = toRel(Rel); 7650fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer Res = R->Type; 7660fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer return object_error::success; 7670fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 7684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 769d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clowconst coff_section *COFFObjectFile::getCOFFSection(section_iterator &It) const { 770d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow return toSec(It->getRawDataRefImpl()); 771d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 772d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 773d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clowconst coff_symbol *COFFObjectFile::getCOFFSymbol(symbol_iterator &It) const { 774d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow return toSymb(It->getRawDataRefImpl()); 775d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow} 776d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 7779ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clowconst coff_relocation *COFFObjectFile::getCOFFRelocation( 7789ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow relocation_iterator &It) const { 7799ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow return toRel(It->getRawDataRefImpl()); 7809ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow} 7819ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow 782d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow 7834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \ 7844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::enum: res = #enum; break; 7854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 7864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, 7874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 7884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_relocation *reloc = toRel(Rel); 7894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer StringRef res; 7904bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama switch (COFFHeader->Machine) { 7914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 7924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer switch (reloc->Type) { 7934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); 7944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); 7954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); 7964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); 7974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); 7984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); 7994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); 8004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); 8014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); 8024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); 8034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); 8044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); 8054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); 8064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); 8074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); 8084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); 8094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); 8104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 8114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 8124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 8134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 8144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 8154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer switch (reloc->Type) { 8164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); 8174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); 8184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); 8194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); 8204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); 8214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); 8224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); 8234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); 8244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); 8254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); 8264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); 8274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 8284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 8294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 8304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer break; 8314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer default: 8324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer res = "Unknown"; 8334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer } 8344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result.append(res.begin(), res.end()); 8354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 8364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer} 8374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 8384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME 8394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 8404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, 8414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer SmallVectorImpl<char> &Result) const { 8424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer const coff_relocation *reloc = toRel(Rel); 84348f248ad5f9e435f3aeaa3aa9bca890687085540NAKAMURA Takumi const coff_symbol *symb = 0; 8444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec; 8454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer DataRefImpl sym; 8464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer sym.p = reinterpret_cast<uintptr_t>(symb); 8474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer StringRef symname; 8484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer if (error_code ec = getSymbolName(sym, symname)) return ec; 8494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer Result.append(symname.begin(), symname.end()); 8504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer return object_error::success; 851a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling} 852a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling 8535c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryNext(DataRefImpl LibData, 8545c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer LibraryRef &Result) const { 8555c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("getLibraryNext not implemented in COFFObjectFile"); 8565c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 8575c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 8585c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryPath(DataRefImpl LibData, 8595c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer StringRef &Result) const { 8605c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("getLibraryPath not implemented in COFFObjectFile"); 8615c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 8625c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 863a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace llvm { 864a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 865a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { 866001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer error_code ec; 867001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return new COFFObjectFile(Object, ec); 868a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer } 869a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer 870a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} // end namespace llvm 871