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"
16a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/StringSwitch.h"
17a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer#include "llvm/ADT/Triple.h"
18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/iterator_range.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  }
496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
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);
626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
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
147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarExpected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef Result;
150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::error_code EC = getSymbolName(Symb, Result);
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (EC)
152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return errorCodeToError(EC);
153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Result;
154a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
155a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return getCOFFSymbol(Ref).getValue();
158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1591b6c8d1f6c834d8c3de4f78a4c99f8800f581b73Rafael Espindola
160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarExpected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t Result = getSymbolValue(Ref);
162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  COFFSymbolRef Symb = getCOFFSymbol(Ref);
16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SectionNumber = Symb.getSectionNumber();
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symb.isAnyUndefined() || Symb.isCommon() ||
166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      COFF::isReservedSectionNumber(SectionNumber))
167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Result;
16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const coff_section *Section = nullptr;
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (std::error_code EC = getSection(SectionNumber, Section))
171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return errorCodeToError(EC);
172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Result += Section->VirtualAddress;
173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The section VirtualAddress does not include ImageBase, and we want to
175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // return virtual addresses.
176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Result += getImageBase();
177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Result;
179ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
180ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarExpected<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int32_t SectionNumber = Symb.getSectionNumber();
184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_Function;
187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symb.isAnyUndefined())
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_Unknown;
189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symb.isCommon())
190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_Data;
191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symb.isFileRecord())
192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_File;
193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // TODO: perhaps we need a new symbol type ST_Section.
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (SectionNumber == COFF::IMAGE_SYM_DEBUG || Symb.isSectionDefinition())
196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_Debug;
197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!COFF::isReservedSectionNumber(SectionNumber))
199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return SymbolRef::ST_Data;
200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return SymbolRef::ST_Other;
202ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
203ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Result = SymbolRef::SF_None;
207c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isExternal() || Symb.isWeakExternal())
209c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Global;
210c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isWeakExternal())
212c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Weak;
213c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer
21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE)
215c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    Result |= SymbolRef::SF_Absolute;
216ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isFileRecord())
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_FormatSpecific;
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isSectionDefinition())
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_FormatSpecific;
22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isCommon())
22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_Common;
22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symb.isAnyUndefined())
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result |= SymbolRef::SF_Undefined;
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Result;
230c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer}
231c38c36a8c44bd32bdfc2e48ab3e447f6dc1547bdMichael J. Spencer
232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Symb.getValue();
235a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
236a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarExpected<section_iterator>
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarCOFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  COFFSymbolRef Symb = getCOFFSymbol(Ref);
240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return section_end();
242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const coff_section *Sec = nullptr;
243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return errorCodeToError(EC);
245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DataRefImpl Ret;
246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Ret.p = reinterpret_cast<uintptr_t>(Sec);
247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return section_iterator(SectionRef(Ret, this));
248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  COFFSymbolRef Symb = getCOFFSymbol(Sym.getRawDataRefImpl());
252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Symb.getSectionNumber();
2539b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer}
2549b2b812fea4df160437e7b7d56e38f6335189ad0Michael J. Spencer
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Sec += 1;
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ref.p = reinterpret_cast<uintptr_t>(Sec);
259a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
260a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
261c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                               StringRef &Result) const {
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getSectionName(Sec, Result);
265a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
266a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t Result = Sec->VirtualAddress;
270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The section VirtualAddress does not include ImageBase, and we want to
272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // return virtual addresses.
273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Result += getImageBase();
274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Result;
275a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
276a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return getSectionSize(toSec(Ref));
279a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
280a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
281c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
282c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                   StringRef &Result) const {
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
2841f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  ArrayRef<uint8_t> Res;
285c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC = getSectionContents(Sec, Res);
2861f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
2871f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  return EC;
288a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
289a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return Sec->getAlignment();
293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool COFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return false;
297e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer}
298e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer
29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionText(DataRefImpl Ref) const {
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
30213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
30313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionData(DataRefImpl Ref) const {
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
30713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
30813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
3114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
3124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                            COFF::IMAGE_SCN_MEM_READ |
3134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                            COFF::IMAGE_SCN_MEM_WRITE;
3144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return (Sec->Characteristics & BssFlags) == BssFlags;
315a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
316a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uintptr_t Offset =
319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert((Offset % sizeof(coff_section)) == 0);
321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return (Offset / sizeof(coff_section)) + 1;
322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
3264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // In COFF, a virtual section won't have any in-file
3274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // content, so the file pointer to the content will be zero.
3284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return Sec->PointerToRawData == 0;
329c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd}
330c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint32_t getNumberOfRelocations(const coff_section *Sec,
33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                       MemoryBufferRef M, const uint8_t *base) {
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The field for the number of relocations in COFF section table is only
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // NumberOfRelocations field, and the actual relocation count is stored in the
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // VirtualAddress field in the first relocation entry.
33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Sec->hasExtendedRelocations()) {
33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const coff_relocation *FirstReloc;
33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        base + Sec->PointerToRelocations)))
34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // -1 to exclude this first relocation entry.
343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return FirstReloc->VirtualAddress - 1;
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Sec->NumberOfRelocations;
3464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
3474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const coff_relocation *
34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t NumRelocs = getNumberOfRelocations(Sec, M, Base);
35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!NumRelocs)
35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto begin = reinterpret_cast<const coff_relocation *>(
35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Base + Sec->PointerToRelocations);
35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sec->hasExtendedRelocations()) {
35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Skip the first relocation entry repurposed to store the number of
35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // relocations.
35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    begin++;
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkOffset(M, uintptr_t(begin), sizeof(coff_relocation) * NumRelocs))
36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return begin;
36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_section *Sec = toSec(Ref);
36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *begin = getFirstReloc(Sec, Data, base());
368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (begin && Sec->VirtualAddress != 0)
369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    report_fatal_error("Sections with relocations should have an address of 0");
37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DataRefImpl Ret;
37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(begin);
37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return relocation_iterator(RelocationRef(Ret, this));
37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_section *Sec = toSec(Ref);
37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *I = getFirstReloc(Sec, Data, base());
37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (I)
37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    I += getNumberOfRelocations(Sec, Data, base());
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(I);
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return relocation_iterator(RelocationRef(Ret, this));
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
3844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
385a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Initialize the pointer to the symbol table.
386c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initSymbolTablePtr() {
38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFHeader)
38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getObject(
38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            SymbolTable16, Data, base() + getPointerToSymbolTable(),
39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFBigObjHeader)
39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (std::error_code EC = getObject(
39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            SymbolTable32, Data, base() + getPointerToSymbolTable(),
39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return EC;
398a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
399a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Find string table. The first four byte of the string table contains the
400a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // total size of the string table, including the size field itself. If the
401a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // string table is empty, the value of the first four byte would be 4.
40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t StringTableOffset = getPointerToSymbolTable() +
40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               getNumberOfSymbols() * getSymbolTableEntrySize();
40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const uint8_t *StringTableAddr = base() + StringTableOffset;
405a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const ulittle32_t *StringTableSizePtr;
40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
408a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  StringTableSize = *StringTableSizePtr;
409c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          getObject(StringTable, Data, StringTableAddr, StringTableSize))
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // tools like cvtres write a size of 0 for an empty table instead of 4.
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (StringTableSize < 4)
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringTableSize = 4;
417a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
418a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Check that the string table is null terminated if has any in it.
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
420a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return  object_error::parse_failed;
4216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
422a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
423a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint64_t COFFObjectFile::getImageBase() const {
425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (PE32Header)
426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return PE32Header->ImageBase;
427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  else if (PE32PlusHeader)
428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return PE32PlusHeader->ImageBase;
429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // This actually comes up in practice.
430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return 0;
431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the file offset for the given VA.
434c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t ImageBase = getImageBase();
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Rva = Addr - ImageBase;
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Rva <= UINT32_MAX);
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getRvaPtr((uint32_t)Rva, Res);
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
441a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns the file offset for the given RVA.
442c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &S : sections()) {
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const coff_section *Section = getCOFFSection(S);
445a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    uint32_t SectionStart = Section->VirtualAddress;
446a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SectionStart <= Addr && Addr < SectionEnd) {
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t Offset = Addr - SectionStart;
449a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama      Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return std::error_code();
451a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    }
452a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  }
453a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  return object_error::parse_failed;
454a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
455a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
456de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code
457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarCOFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                     ArrayRef<uint8_t> &Contents) const {
459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (const SectionRef &S : sections()) {
460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const coff_section *Section = getCOFFSection(S);
461de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    uint32_t SectionStart = Section->VirtualAddress;
462de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Check if this RVA is within the section bounds. Be careful about integer
463de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // overflow.
464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    uint32_t OffsetIntoSection = RVA - SectionStart;
465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Size <= Section->VirtualSize - OffsetIntoSection) {
467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      uintptr_t Begin =
468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Contents =
470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return std::error_code();
472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return object_error::parse_failed;
475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
477a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
478a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// table entry.
479c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
480c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                            StringRef &Name) const {
481a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
482c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(Rva, IntPtr))
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
484a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
485a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
486a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
4876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
488a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
489a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
490de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
491de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                const debug_pdb_info *&PDBInfo,
492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                StringRef &PDBFileName) const {
493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ArrayRef<uint8_t> InfoBytes;
494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (std::error_code EC = getRvaAndSizeAsBytes(
495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (InfoBytes.size() < sizeof(debug_pdb_info) + 1)
498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return object_error::parse_failed;
499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PDBInfo = reinterpret_cast<const debug_pdb_info *>(InfoBytes.data());
500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  InfoBytes = InfoBytes.drop_front(sizeof(debug_pdb_info));
501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          InfoBytes.size());
503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Truncate the name at the first null byte. Ignore any padding.
504de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PDBFileName = PDBFileName.split('\0').first;
505de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code COFFObjectFile::getDebugPDBInfo(const debug_pdb_info *&PDBInfo,
509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                StringRef &PDBFileName) const {
510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (const debug_directory &D : debug_directories())
511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If we get here, there is no PDB info to return.
514de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PDBInfo = nullptr;
515de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PDBFileName = StringRef();
516de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
518de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
519a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama// Find the import table.
520c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initImportTablePtr() {
521a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // First, we get the RVA of the import table. If the file lacks a pointer to
522a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // the import table, do nothing.
523a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  const data_directory *DataEntry;
524a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
5256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
526a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
527a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Do nothing if the pointer to import table is NULL.
528a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (DataEntry->RelativeVirtualAddress == 0)
5296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
530a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
531a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
532a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
533a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Find the section that contains the RVA. This is needed because the RVA is
534a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // the import table's memory address which is different from its file offset.
535a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
536c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
540a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  ImportDirectory = reinterpret_cast<
541a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama      const import_directory_table_entry *>(IntPtr);
5426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
544a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initDelayImportTablePtr() {
54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const data_directory *DataEntry;
54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
5496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
5516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA = DataEntry->RelativeVirtualAddress;
55437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  NumberOfDelayImportDirectory = DataEntry->Size /
55537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sizeof(delay_import_directory_table_entry) - 1;
55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
55837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getRvaPtr(RVA, IntPtr))
55937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
56037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DelayImportDirectory = reinterpret_cast<
56137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const delay_import_directory_table_entry *>(IntPtr);
5626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
56337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
56437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Find the export table.
566c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::initExportTablePtr() {
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // First, we get the RVA of the export table. If the file lacks a pointer to
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the export table, do nothing.
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const data_directory *DataEntry;
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
5716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Do nothing if the pointer to export table is NULL.
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
5756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
579c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ExportDirectory =
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      reinterpret_cast<const export_directory_table_entry *>(IntPtr);
5836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
584a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
585a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::initBaseRelocPtr() {
58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const data_directory *DataEntry;
58837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
5896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (DataEntry->RelativeVirtualAddress == 0)
5916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
59537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
59637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
59737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      IntPtr);
59837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      IntPtr + DataEntry->Size);
6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
603de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code COFFObjectFile::initDebugDirectoryPtr() {
604de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Get the RVA of the debug directory. Do nothing if it does not exist.
605de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const data_directory *DataEntry;
606de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
607de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return std::error_code();
608de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
609de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Do nothing if the RVA is NULL.
610de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (DataEntry->RelativeVirtualAddress == 0)
611de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return std::error_code();
612de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
613de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Check that the size is a multiple of the entry size.
614de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (DataEntry->Size % sizeof(debug_directory) != 0)
615de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return object_error::parse_failed;
616de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
617de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uintptr_t IntPtr = 0;
618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (std::error_code EC = getRvaPtr(
622de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          DataEntry->RelativeVirtualAddress + DataEntry->Size, IntPtr))
623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
624de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(IntPtr);
625de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
626de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
63037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
63137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
63237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
633de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ImportDirectory(nullptr),
63437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
635de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
636de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
63725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check that we at least have enough room for a header.
63837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!checkSize(Data, EC, sizeof(coff_file_header)))
639c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
640539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
6414bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // The current location in the file where we are looking at.
6424bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  uint64_t CurPtr = 0;
6434bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
6444bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // PE header is optional and is present only in executables. If it exists,
6454bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  // it is placed right after COFF header.
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool HasPEHeader = false;
647539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
64825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  // Check if this is a PE/COFF file.
64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
650539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
651539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    // PE signature to find 'normal' COFF header.
65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const auto *DH = reinterpret_cast<const dos_header *>(base());
65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr = DH->AddressOfNewExeHeader;
65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check the PE magic bytes. ("PE\0\0")
65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        EC = object_error::parse_failed;
65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return;
65937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
66037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
66137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      HasPEHeader = true;
66225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    }
663539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  }
664539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
66537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
66625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return;
66737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
66837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // It might be a bigobj file, let's check.  Note that COFF bigobj and COFF
66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // import libraries share a common prefix but bigobj is more restrictive.
67037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
67137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader->NumberOfSections == uint16_t(0xffff) &&
67237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
67337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
67537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
67637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Verify that we are dealing with bigobj.
67737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic,
67937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    sizeof(COFF::BigObjMagic)) == 0) {
68037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader = nullptr;
68137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurPtr += sizeof(coff_bigobj_file_header);
68237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
68337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // It's not a bigobj.
68437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFBigObjHeader = nullptr;
68537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
68637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
68737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (COFFHeader) {
68837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // The prior checkSize call may have failed.  This isn't a hard error
68937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // because we were just trying to sniff out bigobj.
6906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    EC = std::error_code();
69137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CurPtr += sizeof(coff_file_header);
69237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
69337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (COFFHeader->isImportLibrary())
69437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
69537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
6960fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (HasPEHeader) {
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const pe32_header *Header;
69937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(Header, Data, base() + CurPtr)))
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const uint8_t *DataDirAddr;
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t DataDirSize;
70437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Header->Magic == COFF::PE32Header::PE32) {
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      PE32Header = Header;
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirAddr = base() + CurPtr + sizeof(pe32_header);
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
70837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // It's neither PE32 nor PE32+.
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EC = object_error::parse_failed;
7154bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama      return;
7162f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama    }
71737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
7194bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama    CurPtr += COFFHeader->SizeOfOptionalHeader;
7204bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  }
7210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
72237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = getObject(SectionTable, Data, base() + CurPtr,
72337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                      (uint64_t)getNumberOfSections() * sizeof(coff_section))))
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
725a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
726a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Initialize the pointer to the symbol table.
72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getPointerToSymbolTable() != 0) {
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if ((EC = initSymbolTablePtr()))
7297151ddd6efb2f3f51297b35f27a30ddfa8a76a7eMichael J. Spencer      return;
73037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
73137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // We had better not have any symbols if we don't have a symbol table.
73237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getNumberOfSymbols() != 0) {
73337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      EC = object_error::parse_failed;
73437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return;
73537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
73637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
7372f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama
738a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  // Initialize the pointer to the beginning of the import table.
73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((EC = initImportTablePtr()))
740a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    return;
74137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = initDelayImportTablePtr()))
74237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
7430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Initialize the pointer to the export table.
74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((EC = initExportTablePtr()))
74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
747a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
74837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Initialize the pointer to the base relocation table.
74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((EC = initBaseRelocPtr()))
75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
75137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Initialize the pointer to the export table.
753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if ((EC = initDebugDirectoryPtr()))
754de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
7566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  EC = std::error_code();
757a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
758a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_begin_impl() const {
76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
76137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Ret.p = getSymbolTable();
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return basic_symbol_iterator(SymbolRef(Ret, this));
763dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
764dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbasic_symbol_iterator COFFObjectFile::symbol_end_impl() const {
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // The symbol table ends where the string table begins.
76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(StringTable);
76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return basic_symbol_iterator(SymbolRef(Ret, this));
770dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer}
771dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
77229552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_begin() const {
773de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ImportDirectory)
774de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return import_directory_end();
775de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (ImportDirectory[0].ImportLookupTableRVA == 0)
776de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return import_directory_end();
77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return import_directory_iterator(
77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ImportDirectoryEntryRef(ImportDirectory, 0, this));
779a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
780a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
78129552222c2e7cbeb37fcd15d247597467f7b8544Rui Ueyamaimport_directory_iterator COFFObjectFile::import_directory_end() const {
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return import_directory_iterator(
783de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ImportDirectoryEntryRef(nullptr, -1, this));
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator
78737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_begin() const {
78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return delay_import_directory_iterator(
78937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectoryEntryRef(DelayImportDirectory, 0, this));
79037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
79137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesdelay_import_directory_iterator
79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directory_end() const {
79437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return delay_import_directory_iterator(
79537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DelayImportDirectoryEntryRef(
79637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          DelayImportDirectory, NumberOfDelayImportDirectory, this));
79737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
79837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_begin() const {
80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return export_directory_iterator(
80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ExportDirectoryEntryRef(ExportDirectory, 0, this));
80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
80436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesexport_directory_iterator COFFObjectFile::export_directory_end() const {
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!ExportDirectory)
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ExportDirectoryEntryRef Ref(ExportDirectory,
80836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              ExportDirectory->AddressTableEntries, this);
80936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return export_directory_iterator(Ref);
810a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
81197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer
81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_begin() const {
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return section_iterator(SectionRef(Ret, this));
816a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
817a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessection_iterator COFFObjectFile::section_end() const {
81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ret;
82037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int NumSections =
82137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();
82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return section_iterator(SectionRef(Ret, this));
824a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
825a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_begin() const {
82737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return base_reloc_iterator(BaseRelocRef(BaseRelocHeader, this));
82837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
82937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
83037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbase_reloc_iterator COFFObjectFile::base_reloc_end() const {
83137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return base_reloc_iterator(BaseRelocRef(BaseRelocEnd, this));
83237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
83337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
834a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spenceruint8_t COFFObjectFile::getBytesInAddress() const {
8357acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return getArch() == Triple::x86_64 ? 8 : 4;
836a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
837a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
838a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. SpencerStringRef COFFObjectFile::getFileFormatName() const {
83937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch(getMachine()) {
840a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
841a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-i386";
842a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
843a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-x86-64";
84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return "COFF-ARM";
846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case COFF::IMAGE_FILE_MACHINE_ARM64:
847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return "COFF-ARM64";
848a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
849a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return "COFF-<unknown arch>";
850a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
851a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
852a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
853a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencerunsigned COFFObjectFile::getArch() const {
85437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (getMachine()) {
855a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
856a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86;
857a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
858a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::x86_64;
85936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Triple::thumb;
861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case COFF::IMAGE_FILE_MACHINE_ARM64:
862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Triple::aarch64;
863a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  default:
864a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer    return Triple::UnknownArch;
865a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
866a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
867a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
86837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<import_directory_iterator>
86937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::import_directories() const {
87037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(import_directory_begin(), import_directory_end());
8714bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama}
8724bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
87337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<delay_import_directory_iterator>
87437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::delay_import_directories() const {
87537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(delay_import_directory_begin(),
87637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    delay_import_directory_end());
87737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
87837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
87937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<export_directory_iterator>
88037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::export_directories() const {
88137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(export_directory_begin(), export_directory_end());
88237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
88337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
88437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
88537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(base_reloc_begin(), base_reloc_end());
8864bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama}
8874bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama
888c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
8894bf771b4e6d37ae1d6ae08ea27c4070a3a09784dRui Ueyama  Res = PE32Header;
8906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
8910e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
8920e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
893c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const {
89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Res = PE32PlusHeader;
8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
899c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
900c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getDataDirectory(uint32_t Index,
901c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                 const data_directory *&Res) const {
9022f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama  // Error if if there's no data directory or the index is out of range.
90337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!DataDirectory) {
90437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = nullptr;
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return object_error::parse_failed;
90637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(PE32Header || PE32PlusHeader);
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               : PE32PlusHeader->NumberOfRvaAndSize;
91037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Index >= NumEnt) {
91137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Res = nullptr;
9122f6c0484d68270f09eecac03b7e56053153203f3Rui Ueyama    return object_error::parse_failed;
91337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Res = &DataDirectory[Index];
9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
9160e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
9170e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
918c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSection(int32_t Index,
919c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                           const coff_section *&Result) const {
92037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = nullptr;
92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (COFF::isReservedSectionNumber(Index))
9226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
92337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
92425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // We already verified the section table data, so no need to check again.
92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = SectionTable + (Index - 1);
9266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
92737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
92837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return object_error::parse_failed;
929a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
930a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
931c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getString(uint32_t Offset,
932c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                          StringRef &Result) const {
93325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (StringTableSize <= 4)
93425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    // Tried to get a string from an empty string table.
93525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::parse_failed;
93636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Offset >= StringTableSize)
93725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::unexpected_eof;
93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(StringTable + Offset);
9396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
940a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer}
941a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
94237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
943c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              StringRef &Res) const {
944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return getSymbolName(Symbol.getGeneric(), Res);
945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstd::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
948f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              StringRef &Res) const {
9490e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  // Check for string table entry. First 4 bytes are 0.
950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symbol->Name.Offset.Zeroes == 0) {
951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
9536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
9540e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  }
9550e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
9570e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Res = StringRef(Symbol->Name.ShortName);
9590e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer  else
9600e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer    // Not null terminated, use all 8 bytes.
961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
9626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
9630e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer}
9640e752cb4b4eb5676aace4d9f3d7c2e2334c13777Michael J. Spencer
96537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesArrayRef<uint8_t>
96637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const {
967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const uint8_t *Aux = nullptr;
968a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
96937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  size_t SymbolSize = getSymbolTableEntrySize();
97037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Symbol.getNumberOfAuxSymbols() > 0) {
97137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // AUX data comes immediately after the symbol in COFF
97237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;
973d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# ifndef NDEBUG
97436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Verify that the Aux symbol points to a valid entry in the symbol table.
97536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
97637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Offset < getPointerToSymbolTable() ||
97737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Offset >=
97837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize))
979d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow      report_fatal_error("Aux Symbol data was outside of symbol table.");
980d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
98137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 &&
98237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           "Aux Symbol data did not point to the beginning of a symbol");
983d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow# endif
98445aad162c68ee58ba1aa8984499064f6b9c8d0f9Marshall Clow  }
98537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);
986d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
987d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
988c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
989c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                               StringRef &Res) const {
990b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  StringRef Name;
99137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sec->Name[COFF::NameSize - 1] == 0)
992b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Null terminated, let ::strlen figure out the length.
993b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    Name = Sec->Name;
994b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  else
995b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    // Not null terminated, use all 8 bytes.
99637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Name = StringRef(Sec->Name, COFF::NameSize);
997b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
998b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  // Check for string table entry. First byte is '/'.
99937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Name.startswith("/")) {
1000b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer    uint32_t Offset;
100137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Name.startswith("//")) {
100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (decodeBase64StringEntry(Name.substr(2), Offset))
100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return object_error::parse_failed;
100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Name.substr(1).getAsInteger(10, Offset))
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return object_error::parse_failed;
100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
1008c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = getString(Offset, Name))
100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
1010b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  }
1011b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
1012b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer  Res = Name;
10136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
1014b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer}
1015b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer
101637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
101737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // SizeOfRawData and VirtualSize change what they represent depending on
101837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // whether or not we have an executable image.
101937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
102037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // For object files, SizeOfRawData contains the size of section's data;
1021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // VirtualSize should be zero but isn't due to buggy COFF writers.
102237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
102337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
102437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // actual section size is in VirtualSize.  It is possible for VirtualSize to
102537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // be greater than SizeOfRawData; the contents past that point should be
102637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // considered to be zero.
1027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (getDOSHeader())
1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
1029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Sec->SizeOfRawData;
103037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
103137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1032c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1033c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCOFFObjectFile::getSectionContents(const coff_section *Sec,
1034c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                   ArrayRef<uint8_t> &Res) const {
1035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // In COFF, a virtual section won't have any in-file
1036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // content, so the file pointer to the content will be zero.
1037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (Sec->PointerToRawData == 0)
1038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return object_error::parse_failed;
10391f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // The only thing that we need to verify is that the contents is contained
10401f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // within the file bounds. We don't need to make sure it doesn't cover other
10411f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  // data, as there's nothing that says that is not allowed.
10421f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer  uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
104337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t SectionSize = getSectionSize(Sec);
104437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (checkOffset(Data, ConStart, SectionSize))
10451f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer    return object_error::parse_failed;
104637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
10476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
10481f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer}
10491f6e3f9544c93213111a2f8b314c926c0d0e30e5Michael J. Spencer
10500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
10514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return reinterpret_cast<const coff_relocation*>(Rel.p);
10520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
10554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Rel.p = reinterpret_cast<uintptr_t>(
10564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer            reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
10570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
105836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
106037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *R = toRel(Rel);
1061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return R->VirtualAddress;
10620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10646c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindolasymbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
106537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const coff_relocation *R = toRel(Rel);
106636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataRefImpl Ref;
106737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (R->SymbolTableIndex >= getNumberOfSymbols())
106837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return symbol_end();
106937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable16)
107037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
107137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (SymbolTable32)
107237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);
107337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
1074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm_unreachable("no symbol table pointer!");
107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return symbol_iterator(SymbolRef(Ref, this));
10760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1078f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel) const {
10790fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const coff_relocation* R = toRel(Rel);
1080f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return R->Type;
10810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
10824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
108336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_section *
108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFSection(const SectionRef &Section) const {
108536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return toSec(Section.getRawDataRefImpl());
1086d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
1087d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
108837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const {
108937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable16)
109037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return toSymb<coff_symbol16>(Ref);
109137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (SymbolTable32)
109237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return toSymb<coff_symbol32>(Ref);
109337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm_unreachable("no symbol table pointer!");
109437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
109537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
109637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCOFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const {
109737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return getCOFFSymbol(Symbol.getRawDataRefImpl());
1098d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow}
1099d4d03e09d3686d317da1166b578ca5ca35593970Marshall Clow
110036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst coff_relocation *
110136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesCOFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
110236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return toRel(Reloc.getRawDataRefImpl());
11039ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow}
11049ac0f1d7255d7941c331b0a62a830a3b033358fdMarshall Clow
1105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainariterator_range<const coff_relocation *>
1106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarCOFFObjectFile::getRelocations(const coff_section *Sec) const {
1107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const coff_relocation *I = getFirstReloc(Sec, Data, base());
1108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const coff_relocation *E = I;
1109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (I)
1110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    E += getNumberOfRelocations(Sec, Data, base());
1111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return make_range(I, E);
1112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
111436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)                           \
111536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case COFF::reloc_type:                                                       \
111636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Res = #reloc_type;                                                         \
111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
11184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid COFFObjectFile::getRelocationTypeName(
1120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const coff_relocation *Reloc = toRel(Rel);
112236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Res;
112337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (getMachine()) {
11244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_AMD64:
112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Reloc->Type) {
11264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
11274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
11284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
11294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB);
11304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32);
11314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1);
11324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2);
11334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3);
11344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4);
11354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5);
11364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION);
11374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL);
11384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7);
11394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN);
11404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32);
11414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
11424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
11434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
114436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Res = "Unknown";
11454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
11464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case COFF::IMAGE_FILE_MACHINE_ARMNT:
1148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Reloc->Type) {
1149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE);
1150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32);
1151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB);
1152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24);
1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11);
1154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN);
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24);
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11);
1157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION);
1158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL);
1159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A);
1160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T);
1161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T);
1162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T);
1163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T);
1164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
1165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Res = "Unknown";
1166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
11684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case COFF::IMAGE_FILE_MACHINE_I386:
116936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Reloc->Type) {
11704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
11714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
11724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
11734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32);
11744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB);
11754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12);
11764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION);
11774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL);
11784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN);
11794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
11804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
11814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
118236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Res = "Unknown";
11834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
11844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
11854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
118636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Res = "Unknown";
11874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
118836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result.append(Res.begin(), Res.end());
11894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
11904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
11914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
11924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
119337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool COFFObjectFile::isRelocatableObject() const {
119437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return !DataDirectory;
11955c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}
11965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer
1197a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamabool ImportDirectoryEntryRef::
1198a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamaoperator==(const ImportDirectoryEntryRef &Other) const {
119936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ImportTable == Other.ImportTable && Index == Other.Index;
1200a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1201a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
120236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ImportDirectoryEntryRef::moveNext() {
120336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ++Index;
1204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (ImportTable[Index].ImportLookupTableRVA == 0) {
1205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Index = -1;
1206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ImportTable = nullptr;
1207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1208a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1209a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
1210c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getImportTableEntry(
1211c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    const import_directory_table_entry *&Result) const {
1212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return getObject(Result, OwningObject->Data, ImportTable + Index);
1213a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1214a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
121537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
121637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesmakeImportedSymbolIterator(const COFFObjectFile *Object,
121737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           uintptr_t Ptr, int Index) {
121837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Object->getBytesInAddress() == 4) {
121937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *P = reinterpret_cast<const import_lookup_table_entry32 *>(Ptr);
122037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
122137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
122237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *P = reinterpret_cast<const import_lookup_table_entry64 *>(Ptr);
122337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return imported_symbol_iterator(ImportedSymbolRef(P, Index, Object));
122437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
122537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
122637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
122737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
122837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
122937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Object->getRvaPtr(RVA, IntPtr);
123037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeImportedSymbolIterator(Object, IntPtr, 0);
123137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
123237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
123337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic imported_symbol_iterator
123437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesimportedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
123537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
123637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Object->getRvaPtr(RVA, IntPtr);
123737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Forward the pointer to the last entry which is null.
123837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int Index = 0;
123937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Object->getBytesInAddress() == 4) {
124037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);
124137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    while (*Entry++)
124237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++Index;
124337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
124437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);
124537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    while (*Entry++)
124637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++Index;
124737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
124837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return makeImportedSymbolIterator(Object, IntPtr, Index);
124937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
125037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
125137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
125237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_begin() const {
125337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolBegin(ImportTable[Index].ImportLookupTableRVA,
125437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             OwningObject);
125537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
125637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
125737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
125837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbol_end() const {
125937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,
126037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           OwningObject);
126137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
126237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
126337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator>
126437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::imported_symbols() const {
126537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(imported_symbol_begin(), imported_symbol_end());
126637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
126737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1268c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
1269a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  uintptr_t IntPtr = 0;
1270c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
127137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
127236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
127336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
12746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
1275a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
1276a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
127737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
127837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t  &Result) const {
127937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = ImportTable[Index].ImportLookupTableRVA;
12806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
128137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
128237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
128337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
128437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
128537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = ImportTable[Index].ImportAddressTableRVA;
12866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
128737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
128837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
128937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool DelayImportDirectoryEntryRef::
129037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const DelayImportDirectoryEntryRef &Other) const {
129137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Table == Other.Table && Index == Other.Index;
129237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
129337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
129437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid DelayImportDirectoryEntryRef::moveNext() {
129537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ++Index;
129637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
129737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
129837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
129937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_begin() const {
130037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolBegin(Table[Index].DelayImportNameTable,
130137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             OwningObject);
130237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
130337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
130437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesimported_symbol_iterator
130537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbol_end() const {
130637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return importedSymbolEnd(Table[Index].DelayImportNameTable,
130737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           OwningObject);
130837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
130937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
131037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesiterator_range<imported_symbol_iterator>
131137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDelayImportDirectoryEntryRef::imported_symbols() const {
131237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return make_range(imported_symbol_begin(), imported_symbol_end());
131337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
131437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
131537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
131637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
131737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
131837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
131937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
13206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
132137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
132237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
132337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::
132437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetDelayImportTable(const delay_import_directory_table_entry *&Result) const {
132537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = Table;
13266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
132737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
132837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
132937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code DelayImportDirectoryEntryRef::
133037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesgetImportAddress(int AddrIndex, uint64_t &Result) const {
133137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA = Table[Index].DelayImportAddressTable +
133237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      AddrIndex * (OwningObject->is64() ? 8 : 4);
133337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
133437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
133537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
133637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (OwningObject->is64())
133737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
133837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
133937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
13406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
134137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
134237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
134336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ExportDirectoryEntryRef::
134436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesoperator==(const ExportDirectoryEntryRef &Other) const {
134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ExportTable == Other.ExportTable && Index == Other.Index;
134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
134836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ExportDirectoryEntryRef::moveNext() {
134936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ++Index;
135036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1351a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
135236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only
135336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result.
1354c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
135536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1356c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1357c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
135836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
13606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the starting ordinal number.
1364c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1365c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
136636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = ExportTable->OrdinalBase;
13676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
136836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
137036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the export ordinal of the current export symbol.
1371c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = ExportTable->OrdinalBase + Index;
13736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
137536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the address of the current export symbol.
1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
137836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1379c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1380c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
138136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const export_address_table_entry *entry =
138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      reinterpret_cast<const export_address_table_entry *>(IntPtr);
138436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = entry[Index].ExportRVA;
13856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
138636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
138736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Returns the name of the current export symbol. If the symbol is exported only
138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// by ordinal, the empty string is set as a result.
1390c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code
1391c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
139236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uintptr_t IntPtr = 0;
1393c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC =
1394c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
139536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
139636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
139736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
139836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t NumEntries = ExportTable->NumberOfNamePointers;
139936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int Offset = 0;
140036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const ulittle16_t *I = Start, *E = Start + NumEntries;
140136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       I < E; ++I, ++Offset) {
140236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (*I != Index)
140336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
1404c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC =
1405c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
140636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
140736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
1408c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
140936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EC;
141036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Result = StringRef(reinterpret_cast<const char *>(IntPtr));
14116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return std::error_code();
1412a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer  }
141336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Result = "";
14146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
141536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1416a1ef8ef66075e28e020e5d2f408e0a9bae9eb9d3Michael J. Spencer
1417de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code ExportDirectoryEntryRef::isForwarder(bool &Result) const {
1418de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const data_directory *DataEntry;
1419de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (auto EC = OwningObject->getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
1420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
1421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t RVA;
1422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (auto EC = getExportRVA(RVA))
1423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
1424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t Begin = DataEntry->RelativeVirtualAddress;
1425de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
1426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Result = (Begin <= RVA && RVA < End);
1427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
1428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
1431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t RVA;
1432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (auto EC = getExportRVA(RVA))
1433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
1434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uintptr_t IntPtr = 0;
1435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
1436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return EC;
1437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Result = StringRef(reinterpret_cast<const char *>(IntPtr));
1438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
1439de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
144137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool ImportedSymbolRef::
144237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesoperator==(const ImportedSymbolRef &Other) const {
144337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Entry32 == Other.Entry32 && Entry64 == Other.Entry64
144437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && Index == Other.Index;
144537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
144637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
144737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid ImportedSymbolRef::moveNext() {
144837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ++Index;
144937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
145037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
145137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code
145237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesImportedSymbolRef::getSymbolName(StringRef &Result) const {
145337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA;
145437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Entry32) {
145537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If a symbol is imported only by ordinal, it has no name.
145637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry32[Index].isOrdinal())
14576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return std::error_code();
145837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry32[Index].getHintNameRVA();
145937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
146037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry64[Index].isOrdinal())
14616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return std::error_code();
146237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry64[Index].getHintNameRVA();
146337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
146437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
146537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
146637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
146737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // +2 because the first two bytes is hint.
146837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
14696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
147037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
147137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
1473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (Entry32)
1474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Result = Entry32[Index].isOrdinal();
1475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
1476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Result = Entry64[Index].isOrdinal();
1477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
1478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstd::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
1481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (Entry32)
1482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Result = Entry32[Index].getHintNameRVA();
1483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
1484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Result = Entry64[Index].getHintNameRVA();
1485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return std::error_code();
1486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
148837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
148937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RVA;
149037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Entry32) {
149137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry32[Index].isOrdinal()) {
149237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = Entry32[Index].getOrdinal();
14936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return std::error_code();
149437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
149537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry32[Index].getHintNameRVA();
149637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
149737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry64[Index].isOrdinal()) {
149837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = Entry64[Index].getOrdinal();
14996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return std::error_code();
150037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
150137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RVA = Entry64[Index].getHintNameRVA();
150237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
150337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uintptr_t IntPtr = 0;
150437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
150537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return EC;
150637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
15076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
150837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
150937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
151037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesErrorOr<std::unique_ptr<COFFObjectFile>>
151137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
1512c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC;
151337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
151436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (EC)
151536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EC;
151637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return std::move(Ret);
151737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
151837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
151937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
152037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Header == Other.Header && Index == Other.Index;
152137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
152237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
152337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid BaseRelocRef::moveNext() {
152437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Header->BlockSize is the size of the current block, including the
152537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // size of the header itself.
152637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Size = sizeof(*Header) +
152737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sizeof(coff_base_reloc_block_entry) * (Index + 1);
152837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Size == Header->BlockSize) {
152937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // .reloc contains a list of base relocation blocks. Each block
153037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // consists of the header followed by entries. The header contains
153137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // how many entories will follow. When we reach the end of the
153237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // current block, proceed to the next block.
153337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Header = reinterpret_cast<const coff_base_reloc_block_header *>(
153437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reinterpret_cast<const uint8_t *>(Header) + Size);
153537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Index = 0;
153637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
153737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ++Index;
153837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
153937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
154037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
154137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getType(uint8_t &Type) const {
154237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
154337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Type = Entry[Index].getType();
15446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
154537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
154637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
154737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
154837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
154937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = Header->PageRVA + Entry[Index].getOffset();
15506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return std::error_code();
155136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1552