//===-- WindowsResource.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the .res file class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/WindowsResource.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/MathExtras.h"
#include <ctime>
#include <queue>
#include <sstream>
#include <system_error>

using namespace llvm;
using namespace object;

namespace llvm {
namespace object {

#define RETURN_IF_ERROR(X)                                                     \
  if (auto EC = X)                                                             \
    return EC;

const uint32_t MIN_HEADER_SIZE = 7 * sizeof(uint32_t) + 2 * sizeof(uint16_t);

// COFF files seem to be inconsistent with alignment between sections, just use
// 8-byte because it makes everyone happy.
const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t);

uint32_t WindowsResourceParser::TreeNode::StringCount = 0;
uint32_t WindowsResourceParser::TreeNode::DataCount = 0;

WindowsResource::WindowsResource(MemoryBufferRef Source)
    : Binary(Binary::ID_WinRes, Source) {
  size_t LeadingSize = WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE;
  BBS = BinaryByteStream(Data.getBuffer().drop_front(LeadingSize),
                         support::little);
}

Expected<std::unique_ptr<WindowsResource>>
WindowsResource::createWindowsResource(MemoryBufferRef Source) {
  if (Source.getBufferSize() < WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE)
    return make_error<GenericBinaryError>(
        "File too small to be a resource file",
        object_error::invalid_file_type);
  std::unique_ptr<WindowsResource> Ret(new WindowsResource(Source));
  return std::move(Ret);
}

Expected<ResourceEntryRef> WindowsResource::getHeadEntry() {
  if (BBS.getLength() < sizeof(WinResHeaderPrefix) + sizeof(WinResHeaderSuffix))
    return make_error<EmptyResError>(".res contains no entries",
                                     object_error::unexpected_eof);
  return ResourceEntryRef::create(BinaryStreamRef(BBS), this);
}

ResourceEntryRef::ResourceEntryRef(BinaryStreamRef Ref,
                                   const WindowsResource *Owner)
    : Reader(Ref) {}

Expected<ResourceEntryRef>
ResourceEntryRef::create(BinaryStreamRef BSR, const WindowsResource *Owner) {
  auto Ref = ResourceEntryRef(BSR, Owner);
  if (auto E = Ref.loadNext())
    return std::move(E);
  return Ref;
}

Error ResourceEntryRef::moveNext(bool &End) {
  // Reached end of all the entries.
  if (Reader.bytesRemaining() == 0) {
    End = true;
    return Error::success();
  }
  RETURN_IF_ERROR(loadNext());

  return Error::success();
}

static Error readStringOrId(BinaryStreamReader &Reader, uint16_t &ID,
                            ArrayRef<UTF16> &Str, bool &IsString) {
  uint16_t IDFlag;
  RETURN_IF_ERROR(Reader.readInteger(IDFlag));
  IsString = IDFlag != 0xffff;

  if (IsString) {
    Reader.setOffset(
        Reader.getOffset() -
        sizeof(uint16_t)); // Re-read the bytes which we used to check the flag.
    RETURN_IF_ERROR(Reader.readWideString(Str));
  } else
    RETURN_IF_ERROR(Reader.readInteger(ID));

  return Error::success();
}

Error ResourceEntryRef::loadNext() {
  const WinResHeaderPrefix *Prefix;
  RETURN_IF_ERROR(Reader.readObject(Prefix));

  if (Prefix->HeaderSize < MIN_HEADER_SIZE)
    return make_error<GenericBinaryError>("Header size is too small.",
                                          object_error::parse_failed);

  RETURN_IF_ERROR(readStringOrId(Reader, TypeID, Type, IsStringType));

  RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));

  RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_HEADER_ALIGNMENT));

  RETURN_IF_ERROR(Reader.readObject(Suffix));

  RETURN_IF_ERROR(Reader.readArray(Data, Prefix->DataSize));

  RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_DATA_ALIGNMENT));

  return Error::success();
}

WindowsResourceParser::WindowsResourceParser() : Root(false) {}

Error WindowsResourceParser::parse(WindowsResource *WR) {
  auto EntryOrErr = WR->getHeadEntry();
  if (!EntryOrErr) {
    auto E = EntryOrErr.takeError();
    if (E.isA<EmptyResError>()) {
      // Check if the .res file contains no entries.  In this case we don't have
      // to throw an error but can rather just return without parsing anything.
      // This applies for files which have a valid PE header magic and the
      // mandatory empty null resource entry.  Files which do not fit this
      // criteria would have already been filtered out by
      // WindowsResource::createWindowsResource().
      consumeError(std::move(E));
      return Error::success();
    }
    return E;
  }

  ResourceEntryRef Entry = EntryOrErr.get();
  bool End = false;
  while (!End) {
    Data.push_back(Entry.getData());

    bool IsNewTypeString = false;
    bool IsNewNameString = false;

    Root.addEntry(Entry, IsNewTypeString, IsNewNameString);

    if (IsNewTypeString)
      StringTable.push_back(Entry.getTypeString());

    if (IsNewNameString)
      StringTable.push_back(Entry.getNameString());

    RETURN_IF_ERROR(Entry.moveNext(End));
  }

  return Error::success();
}

void WindowsResourceParser::printTree(raw_ostream &OS) const {
  ScopedPrinter Writer(OS);
  Root.print(Writer, "Resource Tree");
}

void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry,
                                               bool &IsNewTypeString,
                                               bool &IsNewNameString) {
  TreeNode &TypeNode = addTypeNode(Entry, IsNewTypeString);
  TreeNode &NameNode = TypeNode.addNameNode(Entry, IsNewNameString);
  NameNode.addLanguageNode(Entry);
}

WindowsResourceParser::TreeNode::TreeNode(bool IsStringNode) {
  if (IsStringNode)
    StringIndex = StringCount++;
}

WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion,
                                          uint16_t MinorVersion,
                                          uint32_t Characteristics)
    : IsDataNode(true), MajorVersion(MajorVersion), MinorVersion(MinorVersion),
      Characteristics(Characteristics) {
    DataIndex = DataCount++;
}

std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createStringNode() {
  return std::unique_ptr<TreeNode>(new TreeNode(true));
}

std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createIDNode() {
  return std::unique_ptr<TreeNode>(new TreeNode(false));
}

std::unique_ptr<WindowsResourceParser::TreeNode>
WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion,
                                                uint16_t MinorVersion,
                                                uint32_t Characteristics) {
  return std::unique_ptr<TreeNode>(
      new TreeNode(MajorVersion, MinorVersion, Characteristics));
}

WindowsResourceParser::TreeNode &
WindowsResourceParser::TreeNode::addTypeNode(const ResourceEntryRef &Entry,
                                             bool &IsNewTypeString) {
  if (Entry.checkTypeString())
    return addChild(Entry.getTypeString(), IsNewTypeString);
  else
    return addChild(Entry.getTypeID());
}

WindowsResourceParser::TreeNode &
WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry,
                                             bool &IsNewNameString) {
  if (Entry.checkNameString())
    return addChild(Entry.getNameString(), IsNewNameString);
  else
    return addChild(Entry.getNameID());
}

WindowsResourceParser::TreeNode &
WindowsResourceParser::TreeNode::addLanguageNode(
    const ResourceEntryRef &Entry) {
  return addChild(Entry.getLanguage(), true, Entry.getMajorVersion(),
                  Entry.getMinorVersion(), Entry.getCharacteristics());
}

WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addChild(
    uint32_t ID, bool IsDataNode, uint16_t MajorVersion, uint16_t MinorVersion,
    uint32_t Characteristics) {
  auto Child = IDChildren.find(ID);
  if (Child == IDChildren.end()) {
    auto NewChild =
        IsDataNode ? createDataNode(MajorVersion, MinorVersion, Characteristics)
                   : createIDNode();
    WindowsResourceParser::TreeNode &Node = *NewChild;
    IDChildren.emplace(ID, std::move(NewChild));
    return Node;
  } else
    return *(Child->second);
}

WindowsResourceParser::TreeNode &
WindowsResourceParser::TreeNode::addChild(ArrayRef<UTF16> NameRef,
                                          bool &IsNewString) {
  std::string NameString;
  ArrayRef<UTF16> CorrectedName;
  std::vector<UTF16> EndianCorrectedName;
  if (sys::IsBigEndianHost) {
    EndianCorrectedName.resize(NameRef.size() + 1);
    std::copy(NameRef.begin(), NameRef.end(), EndianCorrectedName.begin() + 1);
    EndianCorrectedName[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
    CorrectedName = makeArrayRef(EndianCorrectedName);
  } else
    CorrectedName = NameRef;
  convertUTF16ToUTF8String(CorrectedName, NameString);

  auto Child = StringChildren.find(NameString);
  if (Child == StringChildren.end()) {
    auto NewChild = createStringNode();
    IsNewString = true;
    WindowsResourceParser::TreeNode &Node = *NewChild;
    StringChildren.emplace(NameString, std::move(NewChild));
    return Node;
  } else
    return *(Child->second);
}

void WindowsResourceParser::TreeNode::print(ScopedPrinter &Writer,
                                            StringRef Name) const {
  ListScope NodeScope(Writer, Name);
  for (auto const &Child : StringChildren) {
    Child.second->print(Writer, Child.first);
  }
  for (auto const &Child : IDChildren) {
    Child.second->print(Writer, to_string(Child.first));
  }
}

// This function returns the size of the entire resource tree, including
// directory tables, directory entries, and data entries.  It does not include
// the directory strings or the relocations of the .rsrc section.
uint32_t WindowsResourceParser::TreeNode::getTreeSize() const {
  uint32_t Size = (IDChildren.size() + StringChildren.size()) *
                  sizeof(coff_resource_dir_entry);

  // Reached a node pointing to a data entry.
  if (IsDataNode) {
    Size += sizeof(coff_resource_data_entry);
    return Size;
  }

  // If the node does not point to data, it must have a directory table pointing
  // to other nodes.
  Size += sizeof(coff_resource_dir_table);

  for (auto const &Child : StringChildren) {
    Size += Child.second->getTreeSize();
  }
  for (auto const &Child : IDChildren) {
    Size += Child.second->getTreeSize();
  }
  return Size;
}

class WindowsResourceCOFFWriter {
public:
  WindowsResourceCOFFWriter(COFF::MachineTypes MachineType,
                            const WindowsResourceParser &Parser, Error &E);
  std::unique_ptr<MemoryBuffer> write();

private:
  void performFileLayout();
  void performSectionOneLayout();
  void performSectionTwoLayout();
  void writeCOFFHeader();
  void writeFirstSectionHeader();
  void writeSecondSectionHeader();
  void writeFirstSection();
  void writeSecondSection();
  void writeSymbolTable();
  void writeStringTable();
  void writeDirectoryTree();
  void writeDirectoryStringTable();
  void writeFirstSectionRelocations();
  std::unique_ptr<MemoryBuffer> OutputBuffer;
  char *BufferStart;
  uint64_t CurrentOffset = 0;
  COFF::MachineTypes MachineType;
  const WindowsResourceParser::TreeNode &Resources;
  const ArrayRef<std::vector<uint8_t>> Data;
  uint64_t FileSize;
  uint32_t SymbolTableOffset;
  uint32_t SectionOneSize;
  uint32_t SectionOneOffset;
  uint32_t SectionOneRelocations;
  uint32_t SectionTwoSize;
  uint32_t SectionTwoOffset;
  const ArrayRef<std::vector<UTF16>> StringTable;
  std::vector<uint32_t> StringTableOffsets;
  std::vector<uint32_t> DataOffsets;
  std::vector<uint32_t> RelocationAddresses;
};

WindowsResourceCOFFWriter::WindowsResourceCOFFWriter(
    COFF::MachineTypes MachineType, const WindowsResourceParser &Parser,
    Error &E)
    : MachineType(MachineType), Resources(Parser.getTree()),
      Data(Parser.getData()), StringTable(Parser.getStringTable()) {
  performFileLayout();

  OutputBuffer = MemoryBuffer::getNewMemBuffer(FileSize);
}

void WindowsResourceCOFFWriter::performFileLayout() {
  // Add size of COFF header.
  FileSize = COFF::Header16Size;

  // one .rsrc section header for directory tree, another for resource data.
  FileSize += 2 * COFF::SectionSize;

  performSectionOneLayout();
  performSectionTwoLayout();

  // We have reached the address of the symbol table.
  SymbolTableOffset = FileSize;

  FileSize += COFF::Symbol16Size;     // size of the @feat.00 symbol.
  FileSize += 4 * COFF::Symbol16Size; // symbol + aux for each section.
  FileSize += Data.size() * COFF::Symbol16Size; // 1 symbol per resource.
  FileSize += 4; // four null bytes for the string table.
}

void WindowsResourceCOFFWriter::performSectionOneLayout() {
  SectionOneOffset = FileSize;

  SectionOneSize = Resources.getTreeSize();
  uint32_t CurrentStringOffset = SectionOneSize;
  uint32_t TotalStringTableSize = 0;
  for (auto const &String : StringTable) {
    StringTableOffsets.push_back(CurrentStringOffset);
    uint32_t StringSize = String.size() * sizeof(UTF16) + sizeof(uint16_t);
    CurrentStringOffset += StringSize;
    TotalStringTableSize += StringSize;
  }
  SectionOneSize += alignTo(TotalStringTableSize, sizeof(uint32_t));

  // account for the relocations of section one.
  SectionOneRelocations = FileSize + SectionOneSize;
  FileSize += SectionOneSize;
  FileSize +=
      Data.size() * COFF::RelocationSize; // one relocation for each resource.
  FileSize = alignTo(FileSize, SECTION_ALIGNMENT);
}

void WindowsResourceCOFFWriter::performSectionTwoLayout() {
  // add size of .rsrc$2 section, which contains all resource data on 8-byte
  // alignment.
  SectionTwoOffset = FileSize;
  SectionTwoSize = 0;
  for (auto const &Entry : Data) {
    DataOffsets.push_back(SectionTwoSize);
    SectionTwoSize += alignTo(Entry.size(), sizeof(uint64_t));
  }
  FileSize += SectionTwoSize;
  FileSize = alignTo(FileSize, SECTION_ALIGNMENT);
}

static std::time_t getTime() {
  std::time_t Now = time(nullptr);
  if (Now < 0 || !isUInt<32>(Now))
    return UINT32_MAX;
  return Now;
}

std::unique_ptr<MemoryBuffer> WindowsResourceCOFFWriter::write() {
  BufferStart = const_cast<char *>(OutputBuffer->getBufferStart());

  writeCOFFHeader();
  writeFirstSectionHeader();
  writeSecondSectionHeader();
  writeFirstSection();
  writeSecondSection();
  writeSymbolTable();
  writeStringTable();

  return std::move(OutputBuffer);
}

void WindowsResourceCOFFWriter::writeCOFFHeader() {
  // Write the COFF header.
  auto *Header = reinterpret_cast<coff_file_header *>(BufferStart);
  switch (MachineType) {
  case COFF::IMAGE_FILE_MACHINE_ARMNT:
    Header->Machine = COFF::IMAGE_FILE_MACHINE_ARMNT;
    break;
  case COFF::IMAGE_FILE_MACHINE_AMD64:
    Header->Machine = COFF::IMAGE_FILE_MACHINE_AMD64;
    break;
  case COFF::IMAGE_FILE_MACHINE_I386:
    Header->Machine = COFF::IMAGE_FILE_MACHINE_I386;
    break;
  default:
    Header->Machine = COFF::IMAGE_FILE_MACHINE_UNKNOWN;
  }
  Header->NumberOfSections = 2;
  Header->TimeDateStamp = getTime();
  Header->PointerToSymbolTable = SymbolTableOffset;
  // One symbol for every resource plus 2 for each section and @feat.00
  Header->NumberOfSymbols = Data.size() + 5;
  Header->SizeOfOptionalHeader = 0;
  Header->Characteristics = COFF::IMAGE_FILE_32BIT_MACHINE;
}

void WindowsResourceCOFFWriter::writeFirstSectionHeader() {
  // Write the first section header.
  CurrentOffset += sizeof(coff_file_header);
  auto *SectionOneHeader =
      reinterpret_cast<coff_section *>(BufferStart + CurrentOffset);
  strncpy(SectionOneHeader->Name, ".rsrc$01", (size_t)COFF::NameSize);
  SectionOneHeader->VirtualSize = 0;
  SectionOneHeader->VirtualAddress = 0;
  SectionOneHeader->SizeOfRawData = SectionOneSize;
  SectionOneHeader->PointerToRawData = SectionOneOffset;
  SectionOneHeader->PointerToRelocations = SectionOneRelocations;
  SectionOneHeader->PointerToLinenumbers = 0;
  SectionOneHeader->NumberOfRelocations = Data.size();
  SectionOneHeader->NumberOfLinenumbers = 0;
  SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
  SectionOneHeader->Characteristics += COFF::IMAGE_SCN_MEM_READ;
}

void WindowsResourceCOFFWriter::writeSecondSectionHeader() {
  // Write the second section header.
  CurrentOffset += sizeof(coff_section);
  auto *SectionTwoHeader =
      reinterpret_cast<coff_section *>(BufferStart + CurrentOffset);
  strncpy(SectionTwoHeader->Name, ".rsrc$02", (size_t)COFF::NameSize);
  SectionTwoHeader->VirtualSize = 0;
  SectionTwoHeader->VirtualAddress = 0;
  SectionTwoHeader->SizeOfRawData = SectionTwoSize;
  SectionTwoHeader->PointerToRawData = SectionTwoOffset;
  SectionTwoHeader->PointerToRelocations = 0;
  SectionTwoHeader->PointerToLinenumbers = 0;
  SectionTwoHeader->NumberOfRelocations = 0;
  SectionTwoHeader->NumberOfLinenumbers = 0;
  SectionTwoHeader->Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
  SectionTwoHeader->Characteristics += COFF::IMAGE_SCN_MEM_READ;
}

void WindowsResourceCOFFWriter::writeFirstSection() {
  // Write section one.
  CurrentOffset += sizeof(coff_section);

  writeDirectoryTree();
  writeDirectoryStringTable();
  writeFirstSectionRelocations();

  CurrentOffset = alignTo(CurrentOffset, SECTION_ALIGNMENT);
}

void WindowsResourceCOFFWriter::writeSecondSection() {
  // Now write the .rsrc$02 section.
  for (auto const &RawDataEntry : Data) {
    std::copy(RawDataEntry.begin(), RawDataEntry.end(),
              BufferStart + CurrentOffset);
    CurrentOffset += alignTo(RawDataEntry.size(), sizeof(uint64_t));
  }

  CurrentOffset = alignTo(CurrentOffset, SECTION_ALIGNMENT);
}

void WindowsResourceCOFFWriter::writeSymbolTable() {
  // Now write the symbol table.
  // First, the feat symbol.
  auto *Symbol = reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
  strncpy(Symbol->Name.ShortName, "@feat.00", (size_t)COFF::NameSize);
  Symbol->Value = 0x11;
  Symbol->SectionNumber = 0xffff;
  Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL;
  Symbol->StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
  Symbol->NumberOfAuxSymbols = 0;
  CurrentOffset += sizeof(coff_symbol16);

  // Now write the .rsrc1 symbol + aux.
  Symbol = reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
  strncpy(Symbol->Name.ShortName, ".rsrc$01", (size_t)COFF::NameSize);
  Symbol->Value = 0;
  Symbol->SectionNumber = 1;
  Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL;
  Symbol->StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
  Symbol->NumberOfAuxSymbols = 1;
  CurrentOffset += sizeof(coff_symbol16);
  auto *Aux = reinterpret_cast<coff_aux_section_definition *>(BufferStart +
                                                              CurrentOffset);
  Aux->Length = SectionOneSize;
  Aux->NumberOfRelocations = Data.size();
  Aux->NumberOfLinenumbers = 0;
  Aux->CheckSum = 0;
  Aux->NumberLowPart = 0;
  Aux->Selection = 0;
  CurrentOffset += sizeof(coff_aux_section_definition);

  // Now write the .rsrc2 symbol + aux.
  Symbol = reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
  strncpy(Symbol->Name.ShortName, ".rsrc$02", (size_t)COFF::NameSize);
  Symbol->Value = 0;
  Symbol->SectionNumber = 2;
  Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL;
  Symbol->StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
  Symbol->NumberOfAuxSymbols = 1;
  CurrentOffset += sizeof(coff_symbol16);
  Aux = reinterpret_cast<coff_aux_section_definition *>(BufferStart +
                                                        CurrentOffset);
  Aux->Length = SectionTwoSize;
  Aux->NumberOfRelocations = 0;
  Aux->NumberOfLinenumbers = 0;
  Aux->CheckSum = 0;
  Aux->NumberLowPart = 0;
  Aux->Selection = 0;
  CurrentOffset += sizeof(coff_aux_section_definition);

  // Now write a symbol for each relocation.
  for (unsigned i = 0; i < Data.size(); i++) {
    char RelocationName[9];
    sprintf(RelocationName, "$R%06X", DataOffsets[i]);
    Symbol = reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
    strncpy(Symbol->Name.ShortName, RelocationName, (size_t)COFF::NameSize);
    Symbol->Value = DataOffsets[i];
    Symbol->SectionNumber = 2;
    Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL;
    Symbol->StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
    Symbol->NumberOfAuxSymbols = 0;
    CurrentOffset += sizeof(coff_symbol16);
  }
}

void WindowsResourceCOFFWriter::writeStringTable() {
  // Just 4 null bytes for the string table.
  auto COFFStringTable = reinterpret_cast<void *>(BufferStart + CurrentOffset);
  memset(COFFStringTable, 0, 4);
}

void WindowsResourceCOFFWriter::writeDirectoryTree() {
  // Traverse parsed resource tree breadth-first and write the corresponding
  // COFF objects.
  std::queue<const WindowsResourceParser::TreeNode *> Queue;
  Queue.push(&Resources);
  uint32_t NextLevelOffset =
      sizeof(coff_resource_dir_table) + (Resources.getStringChildren().size() +
                                         Resources.getIDChildren().size()) *
                                            sizeof(coff_resource_dir_entry);
  std::vector<const WindowsResourceParser::TreeNode *> DataEntriesTreeOrder;
  uint32_t CurrentRelativeOffset = 0;

  while (!Queue.empty()) {
    auto CurrentNode = Queue.front();
    Queue.pop();
    auto *Table = reinterpret_cast<coff_resource_dir_table *>(BufferStart +
                                                              CurrentOffset);
    Table->Characteristics = CurrentNode->getCharacteristics();
    Table->TimeDateStamp = 0;
    Table->MajorVersion = CurrentNode->getMajorVersion();
    Table->MinorVersion = CurrentNode->getMinorVersion();
    auto &IDChildren = CurrentNode->getIDChildren();
    auto &StringChildren = CurrentNode->getStringChildren();
    Table->NumberOfNameEntries = StringChildren.size();
    Table->NumberOfIDEntries = IDChildren.size();
    CurrentOffset += sizeof(coff_resource_dir_table);
    CurrentRelativeOffset += sizeof(coff_resource_dir_table);

    // Write the directory entries immediately following each directory table.
    for (auto const &Child : StringChildren) {
      auto *Entry = reinterpret_cast<coff_resource_dir_entry *>(BufferStart +
                                                                CurrentOffset);
      Entry->Identifier.setNameOffset(
          StringTableOffsets[Child.second->getStringIndex()]);
      if (Child.second->checkIsDataNode()) {
        Entry->Offset.DataEntryOffset = NextLevelOffset;
        NextLevelOffset += sizeof(coff_resource_data_entry);
        DataEntriesTreeOrder.push_back(Child.second.get());
      } else {
        Entry->Offset.SubdirOffset = NextLevelOffset + (1 << 31);
        NextLevelOffset += sizeof(coff_resource_dir_table) +
                           (Child.second->getStringChildren().size() +
                            Child.second->getIDChildren().size()) *
                               sizeof(coff_resource_dir_entry);
        Queue.push(Child.second.get());
      }
      CurrentOffset += sizeof(coff_resource_dir_entry);
      CurrentRelativeOffset += sizeof(coff_resource_dir_entry);
    }
    for (auto const &Child : IDChildren) {
      auto *Entry = reinterpret_cast<coff_resource_dir_entry *>(BufferStart +
                                                                CurrentOffset);
      Entry->Identifier.ID = Child.first;
      if (Child.second->checkIsDataNode()) {
        Entry->Offset.DataEntryOffset = NextLevelOffset;
        NextLevelOffset += sizeof(coff_resource_data_entry);
        DataEntriesTreeOrder.push_back(Child.second.get());
      } else {
        Entry->Offset.SubdirOffset = NextLevelOffset + (1 << 31);
        NextLevelOffset += sizeof(coff_resource_dir_table) +
                           (Child.second->getStringChildren().size() +
                            Child.second->getIDChildren().size()) *
                               sizeof(coff_resource_dir_entry);
        Queue.push(Child.second.get());
      }
      CurrentOffset += sizeof(coff_resource_dir_entry);
      CurrentRelativeOffset += sizeof(coff_resource_dir_entry);
    }
  }

  RelocationAddresses.resize(Data.size());
  // Now write all the resource data entries.
  for (auto DataNodes : DataEntriesTreeOrder) {
    auto *Entry = reinterpret_cast<coff_resource_data_entry *>(BufferStart +
                                                               CurrentOffset);
    RelocationAddresses[DataNodes->getDataIndex()] = CurrentRelativeOffset;
    Entry->DataRVA = 0; // Set to zero because it is a relocation.
    Entry->DataSize = Data[DataNodes->getDataIndex()].size();
    Entry->Codepage = 0;
    Entry->Reserved = 0;
    CurrentOffset += sizeof(coff_resource_data_entry);
    CurrentRelativeOffset += sizeof(coff_resource_data_entry);
  }
}

void WindowsResourceCOFFWriter::writeDirectoryStringTable() {
  // Now write the directory string table for .rsrc$01
  uint32_t TotalStringTableSize = 0;
  for (auto &String : StringTable) {
    uint16_t Length = String.size();
    support::endian::write16le(BufferStart + CurrentOffset, Length);
    CurrentOffset += sizeof(uint16_t);
    auto *Start = reinterpret_cast<UTF16 *>(BufferStart + CurrentOffset);
    std::copy(String.begin(), String.end(), Start);
    CurrentOffset += Length * sizeof(UTF16);
    TotalStringTableSize += Length * sizeof(UTF16) + sizeof(uint16_t);
  }
  CurrentOffset +=
      alignTo(TotalStringTableSize, sizeof(uint32_t)) - TotalStringTableSize;
}

void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {

  // Now write the relocations for .rsrc$01
  // Five symbols already in table before we start, @feat.00 and 2 for each
  // .rsrc section.
  uint32_t NextSymbolIndex = 5;
  for (unsigned i = 0; i < Data.size(); i++) {
    auto *Reloc =
        reinterpret_cast<coff_relocation *>(BufferStart + CurrentOffset);
    Reloc->VirtualAddress = RelocationAddresses[i];
    Reloc->SymbolTableIndex = NextSymbolIndex++;
    switch (MachineType) {
    case COFF::IMAGE_FILE_MACHINE_ARMNT:
      Reloc->Type = COFF::IMAGE_REL_ARM_ADDR32NB;
      break;
    case COFF::IMAGE_FILE_MACHINE_AMD64:
      Reloc->Type = COFF::IMAGE_REL_AMD64_ADDR32NB;
      break;
    case COFF::IMAGE_FILE_MACHINE_I386:
      Reloc->Type = COFF::IMAGE_REL_I386_DIR32NB;
      break;
    default:
      Reloc->Type = 0;
    }
    CurrentOffset += sizeof(coff_relocation);
  }
}

Expected<std::unique_ptr<MemoryBuffer>>
writeWindowsResourceCOFF(COFF::MachineTypes MachineType,
                         const WindowsResourceParser &Parser) {
  Error E = Error::success();
  WindowsResourceCOFFWriter Writer(MachineType, Parser, E);
  if (E)
    return std::move(E);
  return Writer.write();
}

} // namespace object
} // namespace llvm
