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