COFFObjectFile.cpp revision 1f6e3f9544c93213111a2f8b314c926c0d0e30e5
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
20a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace llvm;
21a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace object;
22a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
23a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace {
24a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle8_t;
25a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t;
26a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_t;
27a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::little16_t;
28a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
29a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
3025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencernamespace {
3125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if size is greater than the buffer size. And sets ec.
3225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerbool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) {
3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (m->getBufferSize() < size) {
3425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    ec = object_error::unexpected_eof;
3525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return false;
3625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
3725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return true;
3825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
3925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
4025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if any bytes in [addr, addr + size) fall outsize of m.
4125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerbool checkAddr(const MemoryBuffer *m,
4225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer               error_code &ec,
4325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer               uintptr_t addr,
4425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer               uint64_t size) {
4525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (addr + size < addr ||
4625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      addr + size < size ||
4725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      addr + size > uintptr_t(m->getBufferEnd())) {
4825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    ec = object_error::unexpected_eof;
4925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return false;
5025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
5125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return true;
5225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
5325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
5425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
5525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_symbol *COFFObjectFile::toSymb(DataRefImpl Symb) const {
5625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *addr = reinterpret_cast<const coff_symbol*>(Symb.p);
5725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
5825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG
5925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Verify that the symbol points to a valid entry in the symbol table.
6025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  uintptr_t offset = uintptr_t(addr) - uintptr_t(base());
6125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (offset < Header->PointerToSymbolTable
6225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      || offset >= Header->PointerToSymbolTable
6325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer         + (Header->NumberOfSymbols * sizeof(coff_symbol)))
6425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    report_fatal_error("Symbol was outside of symbol table.");
6525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
6625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  assert((offset - Header->PointerToSymbolTable) % sizeof(coff_symbol)
6725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer         == 0 && "Symbol did not point to the beginning of a symbol");
6825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif
6925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
7025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return addr;
7125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
7225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
7325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerconst coff_section *COFFObjectFile::toSec(DataRefImpl Sec) const {
7425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *addr = reinterpret_cast<const coff_section*>(Sec.p);
7525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
7625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG
7725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Verify that the section points to a valid entry in the section table.
7825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (addr < SectionTable
7925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      || addr >= (SectionTable + Header->NumberOfSections))
8025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    report_fatal_error("Section was outside of section table.");
8125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
8225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  uintptr_t offset = uintptr_t(addr) - uintptr_t(SectionTable);
8325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  assert(offset % sizeof(coff_section) == 0 &&
8425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer         "Section did not point to the beginning of a section");
8525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif
8625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
8725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return addr;
8825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
8925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
9025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNext(DataRefImpl Symb,
9125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         SymbolRef &Result) const {
9225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
93a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  symb += 1 + symb->NumberOfAuxSymbols;
9425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Symb.p = reinterpret_cast<uintptr_t>(symb);
9525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SymbolRef(Symb, this);
9625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
97a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
98a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
9925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer error_code COFFObjectFile::getSymbolName(DataRefImpl Symb,
10025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                          StringRef &Result) const {
10125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
1020e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return getSymbolName(symb, Result);
103a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
104a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
105b0436a73054fe676b216a0cf872d1fc433125c62Danil Malysheverror_code COFFObjectFile::getSymbolFileOffset(DataRefImpl Symb,
10625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                            uint64_t &Result) const {
10725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
10864388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer  const coff_section *Section = NULL;
10925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (error_code ec = getSection(symb->SectionNumber, Section))
11025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return ec;
11125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  char Type;
11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (error_code ec = getSymbolNMTypeChar(Symb, Type))
11325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return ec;
114a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  if (Type == 'U' || Type == 'w')
11525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
11625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else if (Section)
117b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev    Result = Section->PointerToRawData + symb->Value;
11825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else
11925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = symb->Value;
12025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
121a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
122a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
123ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb,
124ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                            uint64_t &Result) const {
125ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const coff_symbol *symb = toSymb(Symb);
126ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const coff_section *Section = NULL;
127ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (error_code ec = getSection(symb->SectionNumber, Section))
128ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return ec;
129ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  char Type;
130ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (error_code ec = getSymbolNMTypeChar(Symb, Type))
131ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return ec;
132ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (Type == 'U' || Type == 'w')
133ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
134ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  else if (Section)
135b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev    Result = Section->VirtualAddress + symb->Value;
136ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  else
137b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev    Result = symb->Value;
138ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
139ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
140ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
141ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code COFFObjectFile::getSymbolType(DataRefImpl Symb,
1421130a799ab2fd7042625163a2506518960394884Michael J. Spencer                                         SymbolRef::Type &Result) const {
143ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const coff_symbol *symb = toSymb(Symb);
144ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  Result = SymbolRef::ST_Other;
145ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
146ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
1472c67727046234ad9702ab5acb72700b5ac99a676David Meyer    Result = SymbolRef::ST_Unknown;
148ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  } else {
1495e3a082c797f0214d44858b05a13543872dfd413Michael J. Spencer    if (symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
150ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      Result = SymbolRef::ST_Function;
151ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    } else {
152ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      char Type;
153ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      if (error_code ec = getSymbolNMTypeChar(Symb, Type))
154ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer        return ec;
155ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      if (Type == 'r' || Type == 'R') {
156ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer        Result = SymbolRef::ST_Data;
157ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer      }
158ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    }
159ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
160ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
161ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
162ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
163c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyererror_code COFFObjectFile::getSymbolFlags(DataRefImpl Symb,
164c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer                                          uint32_t &Result) const {
165ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const coff_symbol *symb = toSymb(Symb);
166c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer  Result = SymbolRef::SF_None;
167c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
1682c67727046234ad9702ab5acb72700b5ac99a676David Meyer  // TODO: Correctly set SF_FormatSpecific, SF_ThreadLocal, SF_Common
1692c67727046234ad9702ab5acb72700b5ac99a676David Meyer
1702c67727046234ad9702ab5acb72700b5ac99a676David Meyer  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
1712c67727046234ad9702ab5acb72700b5ac99a676David Meyer      symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
1722c67727046234ad9702ab5acb72700b5ac99a676David Meyer    Result |= SymbolRef::SF_Undefined;
173c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
174c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer  // TODO: This are certainly too restrictive.
175c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
176c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Global;
177c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
178c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
179c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Weak;
180c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
181c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer  if (symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)
182c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Absolute;
183ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
184c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer  return object_error::success;
185c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer}
186c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer
18725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolSize(DataRefImpl Symb,
18825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         uint64_t &Result) const {
189a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  // FIXME: Return the correct size. This requires looking at all the symbols
190a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  //        in the same section as this symbol, and looking for either the next
191a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  //        symbol, or the end of the section.
19225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
19364388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer  const coff_section *Section = NULL;
19425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (error_code ec = getSection(symb->SectionNumber, Section))
19525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return ec;
19625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  char Type;
19725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (error_code ec = getSymbolNMTypeChar(Symb, Type))
19825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return ec;
199a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  if (Type == 'U' || Type == 'w')
20025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
20125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else if (Section)
20225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = Section->SizeOfRawData - symb->Value;
20325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else
20425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = 0;
20525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
206a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
207a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
20825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
20925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                               char &Result) const {
21025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
21125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  StringRef name;
21225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (error_code ec = getSymbolName(Symb, name))
21325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return ec;
21425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  char ret = StringSwitch<char>(name)
215a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    .StartsWith(".debug", 'N')
216a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    .StartsWith(".sxdata", 'N')
217a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    .Default('?');
218a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
21925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (ret != '?') {
22025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = ret;
22125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
22225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
223a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
224a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  uint32_t Characteristics = 0;
22525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (symb->SectionNumber > 0) {
22664388ceee00d5e8fc8750ce7967c07a83af3a5a8Michael J. Spencer    const coff_section *Section = NULL;
22725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error_code ec = getSection(symb->SectionNumber, Section))
22825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      return ec;
229a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    Characteristics = Section->Characteristics;
230a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
231a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
232a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  switch (symb->SectionNumber) {
233a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_SYM_UNDEFINED:
234a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    // Check storage classes.
23525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
23625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      Result = 'w';
23725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      return object_error::success; // Don't do ::toupper.
23811ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer    } else if (symb->Value != 0) // Check for common symbols.
23911ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer      ret = 'c';
24011ba26db13698a4567730be13a154c5690ef5e75Michael J. Spencer    else
241a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 'u';
242a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    break;
243a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_SYM_ABSOLUTE:
244a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    ret = 'a';
245a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    break;
246a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_SYM_DEBUG:
247a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    ret = 'n';
248a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    break;
249a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
250a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    // Check section type.
251a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
252a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 't';
253a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    else if (  Characteristics & COFF::IMAGE_SCN_MEM_READ
254a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer            && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
255a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 'r';
256a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
257a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 'd';
258a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
259a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 'b';
260a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
261a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer      ret = 'i';
262a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
263a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    // Check for section symbol.
264a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    else if (  symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
265a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer            && symb->Value == 0)
266a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer       ret = 's';
267a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
268a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
269a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
270a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    ret = ::toupper(ret);
271a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
27225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = ret;
27325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
274a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
275a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
2769b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencererror_code COFFObjectFile::getSymbolSection(DataRefImpl Symb,
2779b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer                                            section_iterator &Result) const {
2789b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  const coff_symbol *symb = toSymb(Symb);
2799b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  if (symb->SectionNumber <= COFF::IMAGE_SYM_UNDEFINED)
2809b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer    Result = end_sections();
2819b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  else {
282a483fc8e6f9533317f517f2d03f3a41ec0aee663Daniel Dunbar    const coff_section *sec = 0;
2839b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer    if (error_code ec = getSection(symb->SectionNumber, sec)) return ec;
2849b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer    DataRefImpl Sec;
285783d88793afe4b4e42460c139ab742fbd26f39f7Michael J. Spencer    std::memset(&Sec, 0, sizeof(Sec));
2869b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer    Sec.p = reinterpret_cast<uintptr_t>(sec);
2879b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer    Result = section_iterator(SectionRef(Sec, this));
2889b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  }
2899b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  return object_error::success;
2909b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer}
2919b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer
29225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionNext(DataRefImpl Sec,
29325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                          SectionRef &Result) const {
29425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
295a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  sec += 1;
29625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Sec.p = reinterpret_cast<uintptr_t>(sec);
29725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SectionRef(Sec, this);
29825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
299a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
300a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
30125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionName(DataRefImpl Sec,
30225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                          StringRef &Result) const {
30325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
304b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  return getSectionName(sec, Result);
305a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
306a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
30725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionAddress(DataRefImpl Sec,
30825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                             uint64_t &Result) const {
30925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
31025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->VirtualAddress;
31125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
312a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
313a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
31425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionSize(DataRefImpl Sec,
31525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                          uint64_t &Result) const {
31625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
31725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->SizeOfRawData;
31825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
319a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
320a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
32125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSectionContents(DataRefImpl Sec,
32225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                              StringRef &Result) const {
32325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
3241f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  ArrayRef<uint8_t> Res;
3251f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  error_code EC = getSectionContents(sec, Res);
3261f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
3271f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  return EC;
328a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
329a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
330e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencererror_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec,
331e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer                                               uint64_t &Res) const {
332e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  const coff_section *sec = toSec(Sec);
333e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  if (!sec)
334e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer    return object_error::parse_failed;
335e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1);
336e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  return object_error::success;
337e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer}
338e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer
33925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::isSectionText(DataRefImpl Sec,
34025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         bool &Result) const {
34125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const coff_section *sec = toSec(Sec);
34225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
34313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
34413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
34513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
34613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionData(DataRefImpl Sec,
34713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                                         bool &Result) const {
34813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  const coff_section *sec = toSec(Sec);
34913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
35013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
35113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
35213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
35313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code COFFObjectFile::isSectionBSS(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_UNINITIALIZED_DATA;
35725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
358a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
359a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
36007ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramererror_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec,
36107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                 DataRefImpl Symb,
36207ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                 bool &Result) const {
363bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer  const coff_section *sec = toSec(Sec);
364bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer  const coff_symbol *symb = toSymb(Symb);
365a483fc8e6f9533317f517f2d03f3a41ec0aee663Daniel Dunbar  const coff_section *symb_sec = 0;
366bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer  if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec;
367bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer  if (symb_sec == sec)
368bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer    Result = true;
369bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer  else
370bff6f8679a3e4006653157ca11cee9dc58c68f8bMichael J. Spencer    Result = false;
37107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  return object_error::success;
37207ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer}
37307ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer
3744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
3754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const coff_section *sec = toSec(Sec);
3764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl ret;
3774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  std::memset(&ret, 0, sizeof(ret));
3784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec->NumberOfRelocations == 0)
3794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ret.p = 0;
3804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  else
3814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations);
3824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(ret, this));
3844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
3854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
3874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const coff_section *sec = toSec(Sec);
3884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl ret;
3894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  std::memset(&ret, 0, sizeof(ret));
3904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec->NumberOfRelocations == 0)
3914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ret.p = 0;
3924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  else
3934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ret.p = reinterpret_cast<uintptr_t>(
3944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer              reinterpret_cast<const coff_relocation*>(
3954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                base() + sec->PointerToRelocations)
3964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer              + sec->NumberOfRelocations);
3974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(ret, this));
3994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
4004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
401001c9205fca2220480589ec355cb6ec701a37e08Michael J. SpencerCOFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec)
4026f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  : ObjectFile(Binary::ID_COFF, Object, ec)
4037151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  , Header(0)
4047151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  , SectionTable(0)
4057151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  , SymbolTable(0)
4067151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  , StringTable(0)
4077151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  , StringTableSize(0) {
40825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check that we at least have enough room for a header.
40925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (!checkSize(Data, ec, sizeof(coff_file_header))) return;
410539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
41125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // The actual starting location of the COFF header in the file. This can be
41225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // non-zero in PE/COFF files.
41325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  uint64_t HeaderStart = 0;
414539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
41525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check if this is a PE/COFF file.
416001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  if (base()[0] == 0x4d && base()[1] == 0x5a) {
417539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
418539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE signature to find 'normal' COFF header.
41925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (!checkSize(Data, ec, 0x3c + 8)) return;
4207151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    HeaderStart = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
42125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // Check the PE header. ("PE\0\0")
4223209a03dafe1a23fe74c933cebd9f9c92a2a3616Benjamin Kramer    if (std::memcmp(base() + HeaderStart, "PE\0\0", 4) != 0) {
42325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      ec = object_error::parse_failed;
42425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      return;
42525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    }
42625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    HeaderStart += 4; // Skip the PE Header.
427539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  }
428539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
42925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Header = reinterpret_cast<const coff_file_header *>(base() + HeaderStart);
43025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header)))
43125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return;
4320fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
433a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  SectionTable =
434001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    reinterpret_cast<const coff_section *>( base()
43525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                          + HeaderStart
436a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer                                          + sizeof(coff_file_header)
437a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer                                          + Header->SizeOfOptionalHeader);
43825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (!checkAddr(Data, ec, uintptr_t(SectionTable),
43925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                 Header->NumberOfSections * sizeof(coff_section)))
44025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return;
44125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
4427151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer  if (Header->PointerToSymbolTable != 0) {
4437151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    SymbolTable =
4447151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      reinterpret_cast<const coff_symbol *>(base()
4457151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer                                            + Header->PointerToSymbolTable);
4467151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    if (!checkAddr(Data, ec, uintptr_t(SymbolTable),
4477151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer                   Header->NumberOfSymbols * sizeof(coff_symbol)))
4487151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
449a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
4507151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    // Find string table.
4517151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    StringTable = reinterpret_cast<const char *>(base())
4527151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer                  + Header->PointerToSymbolTable
4537151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer                  + Header->NumberOfSymbols * sizeof(coff_symbol);
4547151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    if (!checkAddr(Data, ec, uintptr_t(StringTable), sizeof(ulittle32_t)))
4557151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
45625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
4577151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    StringTableSize = *reinterpret_cast<const ulittle32_t *>(StringTable);
4587151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    if (!checkAddr(Data, ec, uintptr_t(StringTable), StringTableSize))
4597151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
4607151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    // Check that the string table is null terminated if has any in it.
4617151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    if (StringTableSize < 4
4627151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer        || (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)) {
4637151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      ec = object_error::parse_failed;
4647151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
4657151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer    }
46625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
4670fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
46825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  ec = object_error::success;
469a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
470a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
4714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::begin_symbols() const {
4727acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
47325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  std::memset(&ret, 0, sizeof(DataRefImpl));
4747acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(SymbolTable);
4757acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(ret, this));
476a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
477a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
4784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator COFFObjectFile::end_symbols() const {
479a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  // The symbol table ends where the string table begins.
4807acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
48125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  std::memset(&ret, 0, sizeof(DataRefImpl));
4827acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(StringTable);
4837acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(ret, this));
484a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
485a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
486dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator COFFObjectFile::begin_dynamic_symbols() const {
487dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  // TODO: implement
488dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
489dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
490dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
491dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator COFFObjectFile::end_dynamic_symbols() const {
492dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  // TODO: implement
493dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
494dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
495dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
4965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator COFFObjectFile::begin_libraries_needed() const {
4975c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  // TODO: implement
4985c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
4995c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
5005c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
5015c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator COFFObjectFile::end_libraries_needed() const {
5025c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  // TODO: implement
5035c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
5045c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
5055c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
50697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid MeyerStringRef COFFObjectFile::getLoadName() const {
50797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer  // COFF does not have this field.
50897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer  return "";
50997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer}
51097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer
51197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer
5124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::begin_sections() const {
5137acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
51425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  std::memset(&ret, 0, sizeof(DataRefImpl));
5157acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(SectionTable);
5167acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
517a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
518a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
5194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator COFFObjectFile::end_sections() const {
5207acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
52125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  std::memset(&ret, 0, sizeof(DataRefImpl));
5227acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections);
5237acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
524a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
525a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
526a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const {
5277acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return getArch() == Triple::x86_64 ? 8 : 4;
528a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
529a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
530a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const {
531a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  switch(Header->Machine) {
532a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
533a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-i386";
534a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
535a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-x86-64";
536a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
537a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-<unknown arch>";
538a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
539a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
540a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
541a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const {
542a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  switch(Header->Machine) {
543a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
544a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86;
545a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
546a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86_64;
547a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
548a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::UnknownArch;
549a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
550a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
551a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
5520e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getHeader(const coff_file_header *&Res) const {
5530e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  Res = Header;
5540e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return object_error::success;
5550e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
5560e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
55725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getSection(int32_t index,
55825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                      const coff_section *&Result) const {
55925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check for special index values.
56025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (index == COFF::IMAGE_SYM_UNDEFINED ||
56125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      index == COFF::IMAGE_SYM_ABSOLUTE ||
56225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      index == COFF::IMAGE_SYM_DEBUG)
56325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = NULL;
56425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else if (index > 0 && index <= Header->NumberOfSections)
56525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // We already verified the section table data, so no need to check again.
56625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = SectionTable + (index - 1);
56725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else
56825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::parse_failed;
56925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
570a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
571a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
57225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code COFFObjectFile::getString(uint32_t offset,
57325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                     StringRef &Result) const {
57425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (StringTableSize <= 4)
57525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // Tried to get a string from an empty string table.
57625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::parse_failed;
57725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (offset >= StringTableSize)
57825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::unexpected_eof;
57925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = StringRef(StringTable + offset);
58025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
581a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
582a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
5834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getSymbol(uint32_t index,
5844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                     const coff_symbol *&Result) const {
5857c24665390a79ee05a0a562ff689e52d4135063eMichael J. Spencer  if (index < Header->NumberOfSymbols)
5864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    Result = SymbolTable + index;
5874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  else
5884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return object_error::parse_failed;
5894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
5904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
5914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
5920e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencererror_code COFFObjectFile::getSymbolName(const coff_symbol *symbol,
5930e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer                                         StringRef &Res) const {
5940e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  // Check for string table entry. First 4 bytes are 0.
5950e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  if (symbol->Name.Offset.Zeroes == 0) {
5960e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    uint32_t Offset = symbol->Name.Offset.Offset;
5970e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    if (error_code ec = getString(Offset, Res))
5980e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer      return ec;
5990e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    return object_error::success;
6000e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  }
6010e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
6020e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  if (symbol->Name.ShortName[7] == 0)
6030e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
6040e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    Res = StringRef(symbol->Name.ShortName);
6050e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  else
6060e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Not null terminated, use all 8 bytes.
6070e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    Res = StringRef(symbol->Name.ShortName, 8);
6080e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return object_error::success;
6090e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
6100e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
611b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencererror_code COFFObjectFile::getSectionName(const coff_section *Sec,
612b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer                                          StringRef &Res) const {
613b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  StringRef Name;
614b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  if (Sec->Name[7] == 0)
615b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
616b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    Name = Sec->Name;
617b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  else
618b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Not null terminated, use all 8 bytes.
619b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    Name = StringRef(Sec->Name, 8);
620b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
621b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  // Check for string table entry. First byte is '/'.
622b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  if (Name[0] == '/') {
623b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    uint32_t Offset;
624b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    if (Name.substr(1).getAsInteger(10, Offset))
625b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer      return object_error::parse_failed;
626b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    if (error_code ec = getString(Offset, Name))
627b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer      return ec;
628b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  }
629b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
630b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  Res = Name;
631b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  return object_error::success;
632b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer}
633b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
6341f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencererror_code COFFObjectFile::getSectionContents(const coff_section *Sec,
6351f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer                                              ArrayRef<uint8_t> &Res) const {
6361f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // The only thing that we need to verify is that the contents is contained
6371f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // within the file bounds. We don't need to make sure it doesn't cover other
6381f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // data, as there's nothing that says that is not allowed.
6391f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
6401f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  uintptr_t ConEnd = ConStart + Sec->SizeOfRawData;
6411f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  if (ConEnd > uintptr_t(Data->getBufferEnd()))
6421f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer    return object_error::parse_failed;
6431f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart),
6441f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer                          Sec->SizeOfRawData);
6451f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  return object_error::success;
6461f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer}
6471f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer
6480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
6494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return reinterpret_cast<const coff_relocation*>(Rel.p);
6500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
6510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
6520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                             RelocationRef &Res) const {
6534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Rel.p = reinterpret_cast<uintptr_t>(
6544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer            reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
6550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Res = RelocationRef(Rel, this);
6560fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
6570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
6580fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
6590fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                uint64_t &Res) const {
660b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev  Res = toRel(Rel)->VirtualAddress;
661b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev  return object_error::success;
662b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev}
663b0436a73054fe676b216a0cf872d1fc433125c62Danil Malysheverror_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
664b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev                                               uint64_t &Res) const {
6654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Res = toRel(Rel)->VirtualAddress;
6660fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
6670fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
6680fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel,
6690fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                               SymbolRef &Res) const {
6700fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const coff_relocation* R = toRel(Rel);
6710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  DataRefImpl Symb;
672783d88793afe4b4e42460c139ab742fbd26f39f7Michael J. Spencer  std::memset(&Symb, 0, sizeof(Symb));
6730fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
6740fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Res = SymbolRef(Symb, this);
6750fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
6760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
6770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
6789472b8d220fc746498429f430cb4c4dbfbd38f2aOwen Anderson                                             uint64_t &Res) const {
6790fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const coff_relocation* R = toRel(Rel);
6800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Res = R->Type;
6810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
6820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
6834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
6844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \
6854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::enum: res = #enum; break;
6864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
6874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
6884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
6894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const coff_relocation *reloc = toRel(Rel);
6904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef res;
6914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (Header->Machine) {
6924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
6934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (reloc->Type) {
6944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
6954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
6964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
6974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB);
6984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32);
6994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1);
7004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2);
7014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3);
7024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4);
7034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5);
7044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION);
7054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL);
7064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7);
7074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN);
7084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32);
7094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
7104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
7114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
7124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
7134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
7144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
7154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
7164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (reloc->Type) {
7174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
7184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
7194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
7204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32);
7214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB);
7224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12);
7234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION);
7244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL);
7254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN);
7264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
7274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
7284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
7294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
7304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
7314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
7324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
7334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    res = "Unknown";
7344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
7354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result.append(res.begin(), res.end());
7364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
7374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
7384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
7404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
7420fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                       int64_t &Res) const {
7430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Res = 0;
7440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
7450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
7464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
7474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
7484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const coff_relocation *reloc = toRel(Rel);
74948f248ad5f9e435f3aeaa3aa9bca890687085540NAKAMURA Takumi  const coff_symbol *symb = 0;
7504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec;
7514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl sym;
7524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  ::memset(&sym, 0, sizeof(sym));
7534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  sym.p = reinterpret_cast<uintptr_t>(symb);
7544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef symname;
7554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (error_code ec = getSymbolName(sym, symname)) return ec;
7564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result.append(symname.begin(), symname.end());
7574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
758a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling}
759a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling
7605c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
7615c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer                                          LibraryRef &Result) const {
7625c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  report_fatal_error("getLibraryNext not implemented in COFFObjectFile");
7635c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
7645c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
7655c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
7665c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer                                          StringRef &Result) const {
7675c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer  report_fatal_error("getLibraryPath not implemented in COFFObjectFile");
7685c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
7695c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
770a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencernamespace llvm {
771a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
772a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
773001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    error_code ec;
774001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    return new COFFObjectFile(Object, ec);
775a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
776a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
777a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer} // end namespace llvm
778