1a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===- COFFObjectFile.cpp - COFF object file implementation -----*- C++ -*-===//
2a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//
3a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//                     The LLVM Compiler Infrastructure
4a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//
5a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// License. See LICENSE.TXT for details.
7a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//
8a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===----------------------------------------------------------------------===//
9a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//
10a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer// This file declares the COFFObjectFile class.
11a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//
12a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer//===----------------------------------------------------------------------===//
13a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
14001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer#include "llvm/Object/COFF.h"
151f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer#include "llvm/ADT/ArrayRef.h"
164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#include "llvm/ADT/SmallString.h"
17a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/StringSwitch.h"
18a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/Triple.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/COFF.h"
20a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama#include "llvm/Support/Debug.h"
21a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama#include "llvm/Support/raw_ostream.h"
22e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype>
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <limits>
24ca8b2c655eb4d283187cbbb4f0f3acd34f60fa1cLogan Chien
25a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace llvm;
26a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing namespace object;
27a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
28a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle16_t;
29a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::ulittle32_t;
3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing support::ulittle64_t;
31a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerusing support::little16_t;
32a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer// Returns false if size is greater than the buffer size. And sets ec.
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (M.getBufferSize() < Size) {
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EC = object_error::unexpected_eof;
3725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return false;
3825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
3925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return true;
4025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
4125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                   const uint64_t Size) {
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Addr + Size < Addr || Addr + Size < Size ||
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addr + Size > uintptr_t(M.getBufferEnd()) ||
4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addr < uintptr_t(M.getBufferStart())) {
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::unexpected_eof;
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
522f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
532f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama// Returns unexpected_eof if error.
54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <typename T>
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::error_code getObject(const T *&Obj, MemoryBufferRef M,
5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 const void *Ptr,
5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 const uint64_t Size = sizeof(T)) {
582f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama  uintptr_t Addr = uintptr_t(Ptr);
5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = checkOffset(M, Addr, Size))
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
612f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama  Obj = reinterpret_cast<const T *>(Addr);
622f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama  return object_error::success;
6325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// prefixed slashes.
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Str.size() <= 6 && "String too long, possible overflow.");
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Str.size() > 6)
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Value = 0;
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (!Str.empty()) {
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned CharVal;
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CharVal = Str[0] - 'A';
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CharVal = Str[0] - 'a' + 26;
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CharVal = Str[0] - '0' + 52;
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Str[0] == '+') // 62
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CharVal = 62;
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Str[0] == '/') // 63
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CharVal = 63;
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value = (Value * 64) + CharVal;
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Str = Str.substr(1);
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Value > std::numeric_limits<uint32_t>::max())
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = static_cast<uint32_t>(Value);
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
9725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
9825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <typename coff_symbol_type>
10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_symbol_type *Addr =
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reinterpret_cast<const coff_symbol_type *>(Ref.p);
10325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef NDEBUG
10625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Verify that the symbol points to a valid entry in the symbol table.
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
10825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "Symbol did not point to the beginning of a symbol");
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
11225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Addr;
11425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}
11525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
11825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
11925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# ifndef NDEBUG
12025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Verify that the section points to a valid entry in the section table.
12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
12225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    report_fatal_error("Section was outside of section table.");
12325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Offset % sizeof(coff_section) == 0 &&
12625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer         "Section did not point to the beginning of a section");
12725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer# endif
12825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Addr;
130a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
131a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto End = reinterpret_cast<uintptr_t>(StringTable);
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable16) {
13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Symb += 1 + Symb->NumberOfAuxSymbols;
13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (SymbolTable32) {
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Symb += 1 + Symb->NumberOfAuxSymbols;
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    llvm_unreachable("no symbol table pointer!");
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
145a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
146a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              StringRef &Result) const {
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getSymbolName(Symb, Result);
151a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
152a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                 uint64_t &Result) const {
15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
1561b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola
15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isAnyUndefined()) {
158ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isCommon()) {
16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = UnknownAddressOrSize;
16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SectionNumber = Symb.getSectionNumber();
16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!COFF::isReservedSectionNumber(SectionNumber)) {
16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_section *Section = nullptr;
16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getSection(SectionNumber, Section))
16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = Section->VirtualAddress + Symb.getValue();
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = Symb.getValue();
176ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
177ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
178ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              SymbolRef::Type &Result) const {
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SectionNumber = Symb.getSectionNumber();
183ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  Result = SymbolRef::ST_Other;
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isAnyUndefined()) {
1862c67727046234ad9702ab5acb72700b5ac99a676David Meyer    Result = SymbolRef::ST_Unknown;
18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Symb.isFunctionDefinition()) {
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = SymbolRef::ST_Function;
18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Symb.isCommon()) {
19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = SymbolRef::ST_Data;
19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Symb.isFileRecord()) {
19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = SymbolRef::ST_File;
1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG ||
1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar             Symb.isSectionDefinition()) {
1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    // TODO: perhaps we need a new symbol type ST_Section.
19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = SymbolRef::ST_Debug;
19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (!COFF::isReservedSectionNumber(SectionNumber)) {
19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_section *Section = nullptr;
19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getSection(SectionNumber, Section))
20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Characteristics = Section->Characteristics;
20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = SymbolRef::ST_Function;
20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (Characteristics & (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA))
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result = SymbolRef::ST_Data;
207ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
208ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
209ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
210ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Result = SymbolRef::SF_None;
214c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isExternal() || Symb.isWeakExternal())
216c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Global;
217c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isWeakExternal())
219c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Weak;
220c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE)
222c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Absolute;
223ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isFileRecord())
22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_FormatSpecific;
22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isSectionDefinition())
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_FormatSpecific;
22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isCommon())
23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_Common;
23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isAnyUndefined())
23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_Undefined;
23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Result;
237c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer}
238c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer
239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              uint64_t &Result) const {
24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
2421b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola
24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isAnyUndefined()) {
24425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isCommon()) {
24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = Symb.getValue();
24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Let's attempt to get the size of the symbol by looking at the address of
25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // the symbol after the symbol in question.
25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t SymbAddr;
25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getSymbolAddress(Ref, SymbAddr))
25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SectionNumber = Symb.getSectionNumber();
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFF::isReservedSectionNumber(SectionNumber)) {
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Absolute and debug symbols aren't sorted in any interesting way.
26025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = 0;
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const section_iterator SecEnd = section_end();
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t AfterAddr = UnknownAddressOrSize;
2652c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  for (const symbol_iterator SymbI : symbols()) {
26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    section_iterator SecI = SecEnd;
26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = SymbI->getSection(SecI))
26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Check the symbol's section, skip it if it's in the wrong section.
27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // First, make sure it is in any section.
27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SecI == SecEnd)
27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Second, make sure it is in the same section as the symbol in question.
27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref))
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Addr;
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = SymbI->getAddress(Addr))
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // We want to compare our symbol in question with the closest possible
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // symbol that comes after.
28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (AfterAddr > Addr && Addr > SymbAddr)
28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      AfterAddr = Addr;
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (AfterAddr == UnknownAddressOrSize) {
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // No symbol comes after this one, assume that everything after our symbol
28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // is part of it.
28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_section *Section = nullptr;
28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getSection(SectionNumber, Section))
28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = Section->SizeOfRawData - Symb.getValue();
29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Take the difference between our symbol and the symbol that comes after
29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // our symbol.
29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = AfterAddr - SymbAddr;
29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
29725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
298a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
299a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
300c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
301c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getSymbolSection(DataRefImpl Ref,
302c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                 section_iterator &Result) const {
30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = section_end();
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const coff_section *Sec = nullptr;
30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return EC;
31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataRefImpl Ref;
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Ref.p = reinterpret_cast<uintptr_t>(Sec);
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = section_iterator(SectionRef(Ref, this));
3139b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  }
3149b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer  return object_error::success;
3159b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer}
3169b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Sec += 1;
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ref.p = reinterpret_cast<uintptr_t>(Sec);
321a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
322a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
323c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
324c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                               StringRef &Result) const {
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getSectionName(Sec, Result);
327a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
328a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Sec->VirtualAddress;
332a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
333a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return getSectionSize(toSec(Ref));
336a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
337a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
338c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
339c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                   StringRef &Result) const {
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
3411f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  ArrayRef<uint8_t> Res;
342c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC = getSectionContents(Sec, Res);
3431f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
3441f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  return EC;
345a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
346a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1);
350e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer}
351e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer
35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionText(DataRefImpl Ref) const {
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
35513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
35613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionData(DataRefImpl Ref) const {
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
36013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
36113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
3644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
3654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                            COFF::IMAGE_SCN_MEM_READ |
3664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                            COFF::IMAGE_SCN_MEM_WRITE;
3674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return (Sec->Characteristics & BssFlags) == BssFlags;
368a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
369a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
3724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // In COFF, a virtual section won't have any in-file
3734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // content, so the file pointer to the content will be zero.
3744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return Sec->PointerToRawData == 0;
375c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd}
376c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd
37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                           DataRefImpl SymbRef) const {
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(SecRef);
38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(SymbRef);
38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SecNumber = (Sec - SectionTable) + 1;
38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SecNumber == Symb.getSectionNumber();
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint32_t getNumberOfRelocations(const coff_section *Sec,
38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                       MemoryBufferRef M, const uint8_t *base) {
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The field for the number of relocations in COFF section table is only
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // NumberOfRelocations field, and the actual relocation count is stored in the
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // VirtualAddress field in the first relocation entry.
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Sec->hasExtendedRelocations()) {
39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_relocation *FirstReloc;
39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        base + Sec->PointerToRelocations)))
39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // -1 to exclude this first relocation entry.
397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return FirstReloc->VirtualAddress - 1;
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Sec->NumberOfRelocations;
4004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
4014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const coff_relocation *
40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!NumRelocs)
40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto begin = reinterpret_cast<const coff_relocation *>(
40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Base + Sec->PointerToRelocations);
40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sec->hasExtendedRelocations()) {
41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Skip the first relocation entry repurposed to store the number of
41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // relocations.
41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    begin++;
41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
41437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs))
41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return begin;
41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_section *Sec = toSec(Ref);
42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DataRefImpl Ret;
42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(begin);
42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return relocation_iterator(RelocationRef(Ret, this));
42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *I = getFirstReloc(Sec, Data, base());
43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (I)
43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    I += getNumberOfRelocations(Sec, Data, base());
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(I);
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return relocation_iterator(RelocationRef(Ret, this));
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
4364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
437a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Initialize the pointer to the symbol table.
438c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initSymbolTablePtr() {
43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFHeader)
44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getObject(
44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            SymbolTable16, Data, base() + getPointerToSymbolTable(),
44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFBigObjHeader)
44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getObject(
44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            SymbolTable32, Data, base() + getPointerToSymbolTable(),
44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
450a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
451a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Find string table. The first four byte of the string table contains the
452a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // total size of the string table, including the size field itself. If the
453a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // string table is empty, the value of the first four byte would be 4.
45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t StringTableOffset = getPointerToSymbolTable() +
45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               getNumberOfSymbols() * getSymbolTableEntrySize();
45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const uint8_t *StringTableAddr = base() + StringTableOffset;
457a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const ulittle32_t *StringTableSizePtr;
45837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
460a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  StringTableSize = *StringTableSizePtr;
461c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          getObject(StringTable, Data, StringTableAddr, StringTableSize))
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // tools like cvtres write a size of 0 for an empty table instead of 4.
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (StringTableSize < 4)
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringTableSize = 4;
469a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
470a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Check that the string table is null terminated if has any in it.
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
472a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return  object_error::parse_failed;
473a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::success;
474a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
475a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the file offset for the given VA.
477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  : (uint64_t)PE32PlusHeader->ImageBase;
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Rva = Addr - ImageBase;
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Rva <= UINT32_MAX);
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getRvaPtr((uint32_t)Rva, Res);
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
485a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns the file offset for the given RVA.
486c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &S : sections()) {
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const coff_section *Section = getCOFFSection(S);
489a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    uint32_t SectionStart = Section->VirtualAddress;
490a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SectionStart <= Addr && Addr < SectionEnd) {
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t Offset = Addr - SectionStart;
493a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama      Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
494a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama      return object_error::success;
495a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    }
496a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  }
497a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::parse_failed;
498a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
499a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
500a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
501a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// table entry.
502c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
503c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                            StringRef &Name) const {
504a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
505c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(Rva, IntPtr))
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
507a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
508a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
509a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
510a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::success;
511a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
512a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
513a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Find the import table.
514c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initImportTablePtr() {
515a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // First, we get the RVA of the import table. If the file lacks a pointer to
516a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // the import table, do nothing.
517a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const data_directory *DataEntry;
518a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
519a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return object_error::success;
520a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
521a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Do nothing if the pointer to import table is NULL.
522a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (DataEntry->RelativeVirtualAddress == 0)
523a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return object_error::success;
524a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
525a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // -1 because the last entry is the null entry.
527a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  NumberOfImportDirectory = DataEntry->Size /
52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sizeof(import_directory_table_entry) - 1;
529a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
530a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Find the section that contains the RVA. This is needed because the RVA is
531a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // the import table's memory address which is different from its file offset.
532a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
533c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
535a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  ImportDirectory = reinterpret_cast<
536a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama      const import_directory_table_entry *>(IntPtr);
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
539a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initDelayImportTablePtr() {
54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const data_directory *DataEntry;
54337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
54437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA = DataEntry->RelativeVirtualAddress;
54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  NumberOfDelayImportDirectory = DataEntry->Size /
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sizeof(delay_import_directory_table_entry) - 1;
55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getRvaPtr(RVA, IntPtr))
55437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
55537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DelayImportDirectory = reinterpret_cast<
55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const delay_import_directory_table_entry *>(IntPtr);
55737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
55837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
55937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Find the export table.
561c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initExportTablePtr() {
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // First, we get the RVA of the export table. If the file lacks a pointer to
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the export table, do nothing.
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const data_directory *DataEntry;
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return object_error::success;
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Do nothing if the pointer to export table is NULL.
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return object_error::success;
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
574c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ExportDirectory =
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      reinterpret_cast<const export_directory_table_entry *>(IntPtr);
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
579a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
580a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
58137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initBaseRelocPtr() {
58237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const data_directory *DataEntry;
58337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
58437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
58837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
58937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      IntPtr);
59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      IntPtr + DataEntry->Size);
59537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
59637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
59737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
59837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
60037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ImportDirectory(nullptr), NumberOfImportDirectory(0),
60437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ExportDirectory(nullptr), BaseRelocHeader(nullptr),
60637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      BaseRelocEnd(nullptr) {
60725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check that we at least have enough room for a header.
60837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!checkSize(Data, EC, sizeof(coff_file_header)))
609c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
610539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
6114bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // The current location in the file where we are looking at.
6124bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  uint64_t CurPtr = 0;
6134bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
6144bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // PE header is optional and is present only in executables. If it exists,
6154bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // it is placed right after COFF header.
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool HasPEHeader = false;
617539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
61825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check if this is a PE/COFF file.
61937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
620539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
621539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE signature to find 'normal' COFF header.
62237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const auto *DH = reinterpret_cast<const dos_header *>(base());
62337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
62437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr = DH->AddressOfNewExeHeader;
62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check the PE magic bytes. ("PE\0\0")
62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        EC = object_error::parse_failed;
62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return;
62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
63037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
63137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      HasPEHeader = true;
63225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    }
633539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  }
634539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
63537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
63625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return;
63737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
63837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // It might be a bigobj file, let's check.  Note that COFF bigobj and COFF
63937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // import libraries share a common prefix but bigobj is more restrictive.
64037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
64137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader->NumberOfSections == uint16_t(0xffff) &&
64237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
64337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
64537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
64637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Verify that we are dealing with bigobj.
64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
64837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    sizeof(COFF::BigObjMagic)) == 0) {
65037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader = nullptr;
65137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr += sizeof(coff_bigobj_file_header);
65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // It's not a bigobj.
65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFBigObjHeader = nullptr;
65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFHeader) {
65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // The prior checkSize call may have failed.  This isn't a hard error
65937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // because we were just trying to sniff out bigobj.
66037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    EC = object_error::success;
66137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CurPtr += sizeof(coff_file_header);
66237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
66337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (COFFHeader->isImportLibrary())
66437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
66537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
6660fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (HasPEHeader) {
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const pe32_header *Header;
66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(Header, Data, base() + CurPtr)))
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const uint8_t *DataDirAddr;
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t DataDirSize;
67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Header->Magic == COFF::PE32Header::PE32) {
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      PE32Header = Header;
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirAddr = base() + CurPtr + sizeof(pe32_header);
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // It's neither PE32 nor PE32+.
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EC = object_error::parse_failed;
6854bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama      return;
6862f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama    }
68737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
6894bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama    CurPtr += COFFHeader->SizeOfOptionalHeader;
6904bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  }
6910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
69237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = getObject(SectionTable, Data, base() + CurPtr,
69337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                      (uint64_t)getNumberOfSections() * sizeof(coff_section))))
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
695a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
696a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Initialize the pointer to the symbol table.
69737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getPointerToSymbolTable() != 0) {
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if ((EC = initSymbolTablePtr()))
6997151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
70037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
70137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // We had better not have any symbols if we don't have a symbol table.
70237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getNumberOfSymbols() != 0) {
70337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      EC = object_error::parse_failed;
70437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
70537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
7072f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama
708a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Initialize the pointer to the beginning of the import table.
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((EC = initImportTablePtr()))
710a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return;
71137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = initDelayImportTablePtr()))
71237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
7130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Initialize the pointer to the export table.
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((EC = initExportTablePtr()))
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
717a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
71837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Initialize the pointer to the base relocation table.
71937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = initBaseRelocPtr()))
72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EC = object_error::success;
723a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
724a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_begin_impl() const {
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = getSymbolTable();
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return basic_symbol_iterator(SymbolRef(Ret, this));
729dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
730dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_end_impl() const {
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The symbol table ends where the string table begins.
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return basic_symbol_iterator(SymbolRef(Ret, this));
736dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
737dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
73829552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_begin() const {
73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return import_directory_iterator(
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ImportDirectoryEntryRef(ImportDirectory, 0, this));
741a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
742a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
74329552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_end() const {
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return import_directory_iterator(
74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
74837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator
74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_begin() const {
75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return delay_import_directory_iterator(
75137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
75237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
75337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
75437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator
75537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_end() const {
75637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return delay_import_directory_iterator(
75737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectoryEntryRef(
75837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          DelayImportDirectory, NumberOfDelayImportDirectory, this));
75937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
76037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_begin() const {
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return export_directory_iterator(
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ExportDirectoryEntryRef(ExportDirectory, 0, this));
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_end() const {
767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!ExportDirectory)
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ExportDirectoryEntryRef Ref(ExportDirectory,
77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              ExportDirectory->AddressTableEntries, this);
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return export_directory_iterator(Ref);
772a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
77397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_begin() const {
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return section_iterator(SectionRef(Ret, this));
778a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
779a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_end() const {
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
78237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int NumSections =
78337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return section_iterator(SectionRef(Ret, this));
786a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
787a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_begin() const {
78937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
79037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
79137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_end() const {
79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
79437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
79537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
796a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const {
7977acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return getArch() == Triple::x86_64 ? 8 : 4;
798a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
799a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
800a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const {
80137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch(getMachine()) {
802a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
803a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-i386";
804a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
805a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-x86-64";
80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return "COFF-ARM";
808a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
809a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-<unknown arch>";
810a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
811a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
812a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
813a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const {
81437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (getMachine()) {
815a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
816a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86;
817a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
818a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86_64;
81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Triple::thumb;
821a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
822a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::UnknownArch;
823a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
824a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
825a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<import_directory_iterator>
82737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::import_directories() const {
82837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(import_directory_begin(), import_directory_end());
8294bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama}
8304bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
83137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<delay_import_directory_iterator>
83237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directories() const {
83337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(delay_import_directory_begin(),
83437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    delay_import_directory_end());
83537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
83637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
83737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<export_directory_iterator>
83837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::export_directories() const {
83937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(export_directory_begin(), export_directory_end());
84037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
84137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
84237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
84337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(base_reloc_begin(), base_reloc_end());
8444bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama}
8454bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
846c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
8474bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  Res = PE32Header;
8480e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return object_error::success;
8490e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
8500e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
851c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const {
85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Res = PE32PlusHeader;
85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
857c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
858c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getDataDirectory(uint32_t Index,
859c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                 const data_directory *&Res) const {
8602f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama  // Error if if there's no data directory or the index is out of range.
86137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!DataDirectory) {
86237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = nullptr;
86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return object_error::parse_failed;
86437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(PE32Header || PE32PlusHeader);
86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               : PE32PlusHeader->NumberOfRvaAndSize;
86837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Index >= NumEnt) {
86937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = nullptr;
8702f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama    return object_error::parse_failed;
87137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Res = &DataDirectory[Index];
8730e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return object_error::success;
8740e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
8750e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
876c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSection(int32_t Index,
877c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                           const coff_section *&Result) const {
87837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = nullptr;
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (COFF::isReservedSectionNumber(Index))
88037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
88137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
88225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // We already verified the section table data, so no need to check again.
88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = SectionTable + (Index - 1);
88437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return object_error::success;
88537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
88637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::parse_failed;
887a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
888a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
889c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getString(uint32_t Offset,
890c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                          StringRef &Result) const {
89125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (StringTableSize <= 4)
89225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // Tried to get a string from an empty string table.
89325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::parse_failed;
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Offset >= StringTableSize)
89525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::unexpected_eof;
89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(StringTable + Offset);
89725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
898a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
899a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
90037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
901c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              StringRef &Res) const {
9020e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  // Check for string table entry. First 4 bytes are 0.
90337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symbol.getStringTableOffset().Zeroes == 0) {
90437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Offset = Symbol.getStringTableOffset().Offset;
905c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = getString(Offset, Res))
90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
9070e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    return object_error::success;
9080e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  }
9090e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
91037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symbol.getShortName()[COFF::NameSize - 1] == 0)
9110e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
91237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = StringRef(Symbol.getShortName());
9130e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  else
9140e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Not null terminated, use all 8 bytes.
91537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = StringRef(Symbol.getShortName(), COFF::NameSize);
9160e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  return object_error::success;
9170e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
9180e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
91937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesArrayRef<uint8_t>
92037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const {
921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const uint8_t *Aux = nullptr;
922a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
92337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t SymbolSize = getSymbolTableEntrySize();
92437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symbol.getNumberOfAuxSymbols() > 0) {
92537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // AUX data comes immediately after the symbol in COFF
92637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
927d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# ifndef NDEBUG
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Verify that the Aux symbol points to a valid entry in the symbol table.
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
93037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Offset < getPointerToSymbolTable() ||
93137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Offset >=
93237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
933d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow      report_fatal_error("Aux Symbol data was outside of symbol table.");
934d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
93537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
93637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           "Aux Symbol data did not point to the beginning of a symbol");
937d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# endif
93845aad162c68ee58ba1aa8984499064f6b9c8d0f9Marshall Clow  }
93937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
940d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
941d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
942c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
943c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                               StringRef &Res) const {
944b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  StringRef Name;
94537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sec->Name[COFF::NameSize - 1] == 0)
946b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
947b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    Name = Sec->Name;
948b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  else
949b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Not null terminated, use all 8 bytes.
95037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Name = StringRef(Sec->Name, COFF::NameSize);
951b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
952b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  // Check for string table entry. First byte is '/'.
95337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Name.startswith("/")) {
954b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    uint32_t Offset;
95537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Name.startswith("//")) {
95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (decodeBase64StringEntry(Name.substr(2), Offset))
95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return object_error::parse_failed;
95836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Name.substr(1).getAsInteger(10, Offset))
96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return object_error::parse_failed;
96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
962c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = getString(Offset, Name))
96336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
964b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  }
965b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
966b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  Res = Name;
967b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  return object_error::success;
968b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer}
969b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
97037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
97137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // SizeOfRawData and VirtualSize change what they represent depending on
97237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // whether or not we have an executable image.
97337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
97437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // For object files, SizeOfRawData contains the size of section's data;
97537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // VirtualSize is always zero.
97637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
97737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
97837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // actual section size is in VirtualSize.  It is possible for VirtualSize to
97937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // be greater than SizeOfRawData; the contents past that point should be
98037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // considered to be zero.
98137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t SectionSize;
98237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sec->VirtualSize)
98337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SectionSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData);
98437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
98537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SectionSize = Sec->SizeOfRawData;
98637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
98737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SectionSize;
98837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
98937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
990c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
991c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getSectionContents(const coff_section *Sec,
992c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                   ArrayRef<uint8_t> &Res) const {
99337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // PointerToRawData and SizeOfRawData won't make sense for BSS sections,
99437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // don't do anything interesting for them.
99537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 &&
99637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "BSS sections don't have contents!");
9971f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // The only thing that we need to verify is that the contents is contained
9981f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // within the file bounds. We don't need to make sure it doesn't cover other
9991f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // data, as there's nothing that says that is not allowed.
10001f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
100137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t SectionSize = getSectionSize(Sec);
100237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkOffset(Data, ConStart, SectionSize))
10031f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer    return object_error::parse_failed;
100437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
10051f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  return object_error::success;
10061f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer}
10071f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer
10080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
10094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return reinterpret_cast<const coff_relocation*>(Rel.p);
10100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
10134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Rel.p = reinterpret_cast<uintptr_t>(
10144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer            reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
10150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1017c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
1018c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                     uint64_t &Res) const {
1019956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola  report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
1020b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev}
102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1022c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
1023c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                    uint64_t &Res) const {
102437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *R = toRel(Rel);
102537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const support::ulittle32_t *VirtualAddressPtr;
102637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC =
102737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          getObject(VirtualAddressPtr, Data, &R->VirtualAddress))
102837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
102937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Res = *VirtualAddressPtr;
10300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
10310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10336c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindolasymbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
103437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *R = toRel(Rel);
103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ref;
103637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (R->SymbolTableIndex >= getNumberOfSymbols())
103737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return symbol_end();
103837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable16)
103937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
104037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (SymbolTable32)
104137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
104237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
1043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm_unreachable("no symbol table pointer!");
104436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return symbol_iterator(SymbolRef(Ref, this));
10450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1047c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
1048c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                  uint64_t &Res) const {
10490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const coff_relocation* R = toRel(Rel);
10500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Res = R->Type;
10510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
10520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
10534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section *
105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFSection(const SectionRef &Section) const {
105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return toSec(Section.getRawDataRefImpl());
1057d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
1058d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
105937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const {
106037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable16)
106137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return toSymb<coff_symbol16>(Ref);
106237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable32)
106337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return toSymb<coff_symbol32>(Ref);
106437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm_unreachable("no symbol table pointer!");
106537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
106637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
106737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const {
106837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1069d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
1070d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
107136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_relocation *
107236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
107336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return toRel(Reloc.getRawDataRefImpl());
10749ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow}
10759ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow
107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)                           \
107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::reloc_type:                                                       \
107836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Res = #reloc_type;                                                         \
107936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
10804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1081c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1082c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
1083c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                      SmallVectorImpl<char> &Result) const {
108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_relocation *Reloc = toRel(Rel);
108536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Res;
108637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (getMachine()) {
10874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
108836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Reloc->Type) {
10894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
10904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
10914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
10924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB);
10934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32);
10944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1);
10954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2);
10964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3);
10974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4);
10984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5);
10994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION);
11004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL);
11014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7);
11024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN);
11034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32);
11044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
11054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
11064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
110736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Res = "Unknown";
11084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
11094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
1110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
1111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Reloc->Type) {
1112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE);
1113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32);
1114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB);
1115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24);
1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11);
1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN);
1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24);
1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11);
1120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION);
1121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL);
1122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A);
1123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T);
1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T);
1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T);
1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T);
1127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
1128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Res = "Unknown";
1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
11314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
113236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Reloc->Type) {
11334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
11344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
11354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
11364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32);
11374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB);
11384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12);
11394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION);
11404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL);
11414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN);
11424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
11434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
11444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
114536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Res = "Unknown";
11464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
11474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
11484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
114936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Res = "Unknown";
11504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
115136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result.append(Res.begin(), Res.end());
11524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
11534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
11544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
11554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
11564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getRelocationValueString(DataRefImpl Rel,
1159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                         SmallVectorImpl<char> &Result) const {
116036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_relocation *Reloc = toRel(Rel);
116136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Sym;
116237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex);
116337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = Symb.getError())
116437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
116537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr());
116636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef SymName;
1167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getSymbolName(Sym, SymName))
1168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return EC;
116936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result.append(SymName.begin(), SymName.end());
11704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
1171a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling}
1172a48ad1333999e2fb483d23096349138af5a51ec6Bill Wendling
117337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isRelocatableObject() const {
117437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !DataDirectory;
11755c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
11765c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
1177a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamabool ImportDirectoryEntryRef::
1178a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaoperator==(const ImportDirectoryEntryRef &Other) const {
117936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ImportTable == Other.ImportTable && Index == Other.Index;
1180a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1181a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
118236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ImportDirectoryEntryRef::moveNext() {
118336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ++Index;
1184a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1185a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
1186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getImportTableEntry(
1187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    const import_directory_table_entry *&Result) const {
118837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = ImportTable + Index;
1189a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::success;
1190a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1191a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
119237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
119337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesmakeImportedSymbolIterator(const COFFObjectFile *Object,
119437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           uintptr_t Ptr, int Index) {
119537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Object->getBytesInAddress() == 4) {
119637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
119737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
119837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
119937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
120037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
120137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
120237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
120337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
120437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
120537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
120637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Object->getRvaPtr(RVA, IntPtr);
120737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeImportedSymbolIterator(Object, IntPtr, 0);
120837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
120937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
121037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
121137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
121237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
121337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Object->getRvaPtr(RVA, IntPtr);
121437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Forward the pointer to the last entry which is null.
121537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int Index = 0;
121637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Object->getBytesInAddress() == 4) {
121737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
121837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    while (*Entry++)
121937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++Index;
122037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
122137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
122237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    while (*Entry++)
122337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++Index;
122437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
122537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeImportedSymbolIterator(Object, IntPtr, Index);
122637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
122737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
122837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
122937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_begin() const {
123037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
123137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             OwningObject);
123237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
123337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
123437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
123537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_end() const {
123637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
123737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           OwningObject);
123837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
123937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
124037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator>
124137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbols() const {
124237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(imported_symbol_begin(), imported_symbol_end());
124337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
124437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1245c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
1246a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
1247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
124837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
124936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
125036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1251a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::success;
1252a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1253a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
125437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
125537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t  &Result) const {
125637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = ImportTable[Index].ImportLookupTableRVA;
125737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
125837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
125937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
126037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
126137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
126237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = ImportTable[Index].ImportAddressTableRVA;
126337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
126437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
126537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1266c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getImportLookupEntry(
1267a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    const import_lookup_table_entry32 *&Result) const {
1268a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
126937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
127037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
127136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
1272a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
1273a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::success;
1274a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1275a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
127637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool DelayImportDirectoryEntryRef::
127737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const DelayImportDirectoryEntryRef &Other) const {
127837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Table == Other.Table && Index == Other.Index;
127937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
128037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
128137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DelayImportDirectoryEntryRef::moveNext() {
128237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ++Index;
128337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
128437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
128537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
128637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_begin() const {
128737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolBegin(Table[Index].DelayImportNameTable,
128837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             OwningObject);
128937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
129037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
129137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
129237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_end() const {
129337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolEnd(Table[Index].DelayImportNameTable,
129437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           OwningObject);
129537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
129637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
129737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator>
129837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbols() const {
129937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(imported_symbol_begin(), imported_symbol_end());
130037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
130137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
130237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
130337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
130437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
130537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
130637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
130737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
130837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
130937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
131037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::
131137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetDelayImportTable(const delay_import_directory_table_entry *&Result) const {
131237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = Table;
131337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
131437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
131537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
131637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::
131737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetImportAddress(int AddrIndex, uint64_t &Result) const {
131837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA = Table[Index].DelayImportAddressTable +
131937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      AddrIndex * (OwningObject->is64() ? 8 : 4);
132037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
132137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
132237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
132337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (OwningObject->is64())
132437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
132537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
132637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
132737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
132837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
132937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
133036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ExportDirectoryEntryRef::
133136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesoperator==(const ExportDirectoryEntryRef &Other) const {
133236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ExportTable == Other.ExportTable && Index == Other.Index;
133336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
133436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
133536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ExportDirectoryEntryRef::moveNext() {
133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ++Index;
133736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1338a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
133936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only
134036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result.
1341c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
134236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1343c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1344c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
134836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
134936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
135036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the starting ordinal number.
1351c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1352c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
135336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = ExportTable->OrdinalBase;
135436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
135536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
135636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
135736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the export ordinal of the current export symbol.
1358c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = ExportTable->OrdinalBase + Index;
136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the address of the current export symbol.
1364c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
136536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1366c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1367c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
136836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const export_address_table_entry *entry =
137036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      reinterpret_cast<const export_address_table_entry *>(IntPtr);
137136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = entry[Index].ExportRVA;
137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
137336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
137536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only
137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result.
1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1378c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
137936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1380c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1381c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
138436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
138636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int Offset = 0;
138736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       I < E; ++I, ++Offset) {
138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (*I != Index)
139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
1391c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC =
1392c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
139336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
139436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1395c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
139636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
139736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = StringRef(reinterpret_cast<const char *>(IntPtr));
139836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return object_error::success;
1399a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
140036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = "";
140136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return object_error::success;
140236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1403a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
140437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool ImportedSymbolRef::
140537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const ImportedSymbolRef &Other) const {
140637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
140737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && Index == Other.Index;
140837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
140937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
141037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid ImportedSymbolRef::moveNext() {
141137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ++Index;
141237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
141337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
141437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
141537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportedSymbolRef::getSymbolName(StringRef &Result) const {
141637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA;
141737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Entry32) {
141837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If a symbol is imported only by ordinal, it has no name.
141937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry32[Index].isOrdinal())
142037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return object_error::success;
142137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry32[Index].getHintNameRVA();
142237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
142337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry64[Index].isOrdinal())
142437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return object_error::success;
142537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry64[Index].getHintNameRVA();
142637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
142737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
142837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
142937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
143037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // +2 because the first two bytes is hint.
143137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
143237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
143337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
143437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
143537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
143637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA;
143737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Entry32) {
143837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry32[Index].isOrdinal()) {
143937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = Entry32[Index].getOrdinal();
144037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return object_error::success;
144137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
144237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry32[Index].getHintNameRVA();
144337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
144437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry64[Index].isOrdinal()) {
144537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = Entry64[Index].getOrdinal();
144637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return object_error::success;
144737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
144837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry64[Index].getHintNameRVA();
144937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
145037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
145137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
145237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
145337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
145437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
145537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
145637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
145737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesErrorOr<std::unique_ptr<COFFObjectFile>>
145837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
1459c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC;
146037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
146136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (EC)
146236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
146337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return std::move(Ret);
146437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
146537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
146637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
146737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Header == Other.Header && Index == Other.Index;
146837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
146937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
147037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid BaseRelocRef::moveNext() {
147137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Header->BlockSize is the size of the current block, including the
147237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // size of the header itself.
147337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Size = sizeof(*Header) +
147437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sizeof(coff_base_reloc_block_entry) * (Index + 1);
147537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Size == Header->BlockSize) {
147637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // .reloc contains a list of base relocation blocks. Each block
147737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // consists of the header followed by entries. The header contains
147837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // how many entories will follow. When we reach the end of the
147937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // current block, proceed to the next block.
148037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Header = reinterpret_cast<const coff_base_reloc_block_header *>(
148137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reinterpret_cast<const uint8_t *>(Header) + Size);
148237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Index = 0;
148337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
148437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ++Index;
148537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
148637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
148737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
148837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getType(uint8_t &Type) const {
148937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
149037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Type = Entry[Index].getType();
149137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
149237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
149337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
149437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
149537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
149637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = Header->PageRVA + Entry[Index].getOffset();
149737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::success;
149836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1499