//===- Writer.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Writer.h"
#include "Config.h"
#include "InputChunks.h"
#include "InputEvent.h"
#include "InputGlobal.h"
#include "OutputSections.h"
#include "OutputSegment.h"
#include "Relocations.h"
#include "SymbolTable.h"
#include "SyntheticSections.h"
#include "WriterUtils.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/WasmTraits.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LEB128.h"

#include <cstdarg>
#include <map>

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::wasm;
using namespace lld;
using namespace lld::wasm;

static constexpr int StackAlignment = 16;

namespace {

// The writer writes a SymbolTable result to a file.
class Writer {
public:
  void run();

private:
  void openFile();

  void createApplyRelocationsFunction();
  void createCallCtorsFunction();

  void assignIndexes();
  void populateSymtab();
  void populateProducers();
  void populateTargetFeatures();
  void calculateInitFunctions();
  void calculateImports();
  void calculateExports();
  void calculateCustomSections();
  void calculateTypes();
  void createOutputSegments();
  void layoutMemory();
  void createHeader();

  void addSection(OutputSection *Sec);

  void addSections();
  void addStartStopSymbols(const InputSegment *Seg);

  void createCustomSections();
  void createSyntheticSections();
  void finalizeSections();

  // Custom sections
  void createRelocSections();

  void writeHeader();
  void writeSections();

  uint64_t FileSize = 0;
  uint32_t TableBase = 0;

  std::vector<WasmInitEntry> InitFunctions;
  llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;

  // Elements that are used to construct the final output
  std::string Header;
  std::vector<OutputSection *> OutputSections;

  std::unique_ptr<FileOutputBuffer> Buffer;

  std::vector<OutputSegment *> Segments;
  llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
};

} // anonymous namespace

void Writer::calculateCustomSections() {
  log("calculateCustomSections");
  bool StripDebug = Config->StripDebug || Config->StripAll;
  for (ObjFile *File : Symtab->ObjectFiles) {
    for (InputSection *Section : File->CustomSections) {
      StringRef Name = Section->getName();
      // These custom sections are known the linker and synthesized rather than
      // blindly copied
      if (Name == "linking" || Name == "name" || Name == "producers" ||
          Name == "target_features" || Name.startswith("reloc."))
        continue;
      // .. or it is a debug section
      if (StripDebug && Name.startswith(".debug_"))
        continue;
      CustomSectionMapping[Name].push_back(Section);
    }
  }
}

void Writer::createCustomSections() {
  log("createCustomSections");
  for (auto &Pair : CustomSectionMapping) {
    StringRef Name = Pair.first();
    LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");

    OutputSection *Sec = make<CustomSection>(Name, Pair.second);
    if (Config->Relocatable || Config->EmitRelocs) {
      auto *Sym = make<OutputSectionSymbol>(Sec);
      Out.LinkingSec->addToSymtab(Sym);
      Sec->SectionSym = Sym;
    }
    addSection(Sec);
  }
}

// Create relocations sections in the final output.
// These are only created when relocatable output is requested.
void Writer::createRelocSections() {
  log("createRelocSections");
  // Don't use iterator here since we are adding to OutputSection
  size_t OrigSize = OutputSections.size();
  for (size_t I = 0; I < OrigSize; I++) {
    LLVM_DEBUG(dbgs() << "check section " << I << "\n");
    OutputSection *Sec = OutputSections[I];

    // Count the number of needed sections.
    uint32_t Count = Sec->numRelocations();
    if (!Count)
      continue;

    StringRef Name;
    if (Sec->Type == WASM_SEC_DATA)
      Name = "reloc.DATA";
    else if (Sec->Type == WASM_SEC_CODE)
      Name = "reloc.CODE";
    else if (Sec->Type == WASM_SEC_CUSTOM)
      Name = Saver.save("reloc." + Sec->Name);
    else
      llvm_unreachable(
          "relocations only supported for code, data, or custom sections");

    addSection(make<RelocSection>(Name, Sec));
  }
}

void Writer::populateProducers() {
  for (ObjFile *File : Symtab->ObjectFiles) {
    const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
    Out.ProducersSec->addInfo(Info);
  }
}

void Writer::writeHeader() {
  memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
}

void Writer::writeSections() {
  uint8_t *Buf = Buffer->getBufferStart();
  parallelForEach(OutputSections, [Buf](OutputSection *S) {
    assert(S->isNeeded());
    S->writeTo(Buf);
  });
}

// Fix the memory layout of the output binary.  This assigns memory offsets
// to each of the input data sections as well as the explicit stack region.
// The default memory layout is as follows, from low to high.
//
//  - initialized data (starting at Config->GlobalBase)
//  - BSS data (not currently implemented in llvm)
//  - explicit stack (Config->ZStackSize)
//  - heap start / unallocated
//
// The --stack-first option means that stack is placed before any static data.
// This can be useful since it means that stack overflow traps immediately
// rather than overwriting global data, but also increases code size since all
// static data loads and stores requires larger offsets.
void Writer::layoutMemory() {
  uint32_t MemoryPtr = 0;

  auto PlaceStack = [&]() {
    if (Config->Relocatable || Config->Shared)
      return;
    MemoryPtr = alignTo(MemoryPtr, StackAlignment);
    if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
      error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
    log("mem: stack size  = " + Twine(Config->ZStackSize));
    log("mem: stack base  = " + Twine(MemoryPtr));
    MemoryPtr += Config->ZStackSize;
    auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
    SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
    log("mem: stack top   = " + Twine(MemoryPtr));
  };

  if (Config->StackFirst) {
    PlaceStack();
  } else {
    MemoryPtr = Config->GlobalBase;
    log("mem: global base = " + Twine(Config->GlobalBase));
  }

  uint32_t DataStart = MemoryPtr;

  // Arbitrarily set __dso_handle handle to point to the start of the data
  // segments.
  if (WasmSym::DsoHandle)
    WasmSym::DsoHandle->setVirtualAddress(DataStart);

  Out.DylinkSec->MemAlign = 0;
  for (OutputSegment *Seg : Segments) {
    Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment);
    MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
    Seg->StartVA = MemoryPtr;
    log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
                MemoryPtr, Seg->Size, Seg->Alignment));
    MemoryPtr += Seg->Size;
  }

  // TODO: Add .bss space here.
  if (WasmSym::DataEnd)
    WasmSym::DataEnd->setVirtualAddress(MemoryPtr);

  log("mem: static data = " + Twine(MemoryPtr - DataStart));

  if (Config->Shared) {
    Out.DylinkSec->MemSize = MemoryPtr;
    return;
  }

  if (!Config->StackFirst)
    PlaceStack();

  // Set `__heap_base` to directly follow the end of the stack or global data.
  // The fact that this comes last means that a malloc/brk implementation
  // can grow the heap at runtime.
  if (!Config->Relocatable) {
    WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
    log("mem: heap base   = " + Twine(MemoryPtr));
  }

  if (Config->InitialMemory != 0) {
    if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
      error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
    if (MemoryPtr > Config->InitialMemory)
      error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
    else
      MemoryPtr = Config->InitialMemory;
  }
  Out.DylinkSec->MemSize = MemoryPtr;
  Out.MemorySec->NumMemoryPages =
      alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
  log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages));

  // Check max if explicitly supplied or required by shared memory
  if (Config->MaxMemory != 0 || Config->SharedMemory) {
    if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
      error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
    if (MemoryPtr > Config->MaxMemory)
      error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
    Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize;
    log("mem: max pages   = " + Twine(Out.MemorySec->MaxMemoryPages));
  }
}

void Writer::addSection(OutputSection *Sec) {
  if (!Sec->isNeeded())
    return;
  log("addSection: " + toString(*Sec));
  Sec->SectionIndex = OutputSections.size();
  OutputSections.push_back(Sec);
}

// If a section name is valid as a C identifier (which is rare because of
// the leading '.'), linkers are expected to define __start_<secname> and
// __stop_<secname> symbols. They are at beginning and end of the section,
// respectively. This is not requested by the ELF standard, but GNU ld and
// gold provide the feature, and used by many programs.
void Writer::addStartStopSymbols(const InputSegment *Seg) {
  StringRef S = Seg->getName();
  LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n");
  if (!isValidCIdentifier(S))
    return;
  uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset;
  uint32_t Stop = Start + Seg->getSize();
  Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0);
  Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0);
}

void Writer::addSections() {
  addSection(Out.DylinkSec);
  addSection(Out.TypeSec);
  addSection(Out.ImportSec);
  addSection(Out.FunctionSec);
  addSection(Out.TableSec);
  addSection(Out.MemorySec);
  addSection(Out.GlobalSec);
  addSection(Out.EventSec);
  addSection(Out.ExportSec);
  addSection(Out.ElemSec);
  addSection(Out.DataCountSec);

  addSection(make<CodeSection>(Out.FunctionSec->InputFunctions));
  addSection(make<DataSection>(Segments));

  createCustomSections();

  addSection(Out.LinkingSec);
  if (Config->EmitRelocs || Config->Relocatable) {
    createRelocSections();
  }

  addSection(Out.NameSec);
  addSection(Out.ProducersSec);
  addSection(Out.TargetFeaturesSec);
}

void Writer::finalizeSections() {
  for (OutputSection *S : OutputSections) {
    S->setOffset(FileSize);
    S->finalizeContents();
    FileSize += S->getSize();
  }
}

void Writer::populateTargetFeatures() {
  SmallSet<std::string, 8> Used;
  SmallSet<std::string, 8> Required;
  SmallSet<std::string, 8> Disallowed;

  // Only infer used features if user did not specify features
  bool InferFeatures = !Config->Features.hasValue();

  if (!InferFeatures) {
    for (auto &Feature : Config->Features.getValue())
      Out.TargetFeaturesSec->Features.insert(Feature);
    // No need to read or check features
    if (!Config->CheckFeatures)
      return;
  }

  // Find the sets of used, required, and disallowed features
  for (ObjFile *File : Symtab->ObjectFiles) {
    for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
      switch (Feature.Prefix) {
      case WASM_FEATURE_PREFIX_USED:
        Used.insert(Feature.Name);
        break;
      case WASM_FEATURE_PREFIX_REQUIRED:
        Used.insert(Feature.Name);
        Required.insert(Feature.Name);
        break;
      case WASM_FEATURE_PREFIX_DISALLOWED:
        Disallowed.insert(Feature.Name);
        break;
      default:
        error("Unrecognized feature policy prefix " +
              std::to_string(Feature.Prefix));
      }
    }
  }

  if (InferFeatures)
    Out.TargetFeaturesSec->Features.insert(Used.begin(), Used.end());

  if (Out.TargetFeaturesSec->Features.count("atomics") && !Config->SharedMemory)
    error("'atomics' feature is used, so --shared-memory must be used");

  if (!Config->CheckFeatures)
    return;

  if (Disallowed.count("atomics") && Config->SharedMemory)
    error(
        "'atomics' feature is disallowed, so --shared-memory must not be used");

  // Validate that used features are allowed in output
  if (!InferFeatures) {
    for (auto &Feature : Used) {
      if (!Out.TargetFeaturesSec->Features.count(Feature))
        error(Twine("Target feature '") + Feature + "' is not allowed.");
    }
  }

  // Validate the required and disallowed constraints for each file
  for (ObjFile *File : Symtab->ObjectFiles) {
    SmallSet<std::string, 8> ObjectFeatures;
    for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
      if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
        continue;
      ObjectFeatures.insert(Feature.Name);
      if (Disallowed.count(Feature.Name))
        error(Twine("Target feature '") + Feature.Name +
              "' is disallowed. Use --no-check-features to suppress.");
    }
    for (auto &Feature : Required) {
      if (!ObjectFeatures.count(Feature))
        error(Twine("Missing required target feature '") + Feature +
              "'. Use --no-check-features to suppress.");
    }
  }
}

void Writer::calculateImports() {
  for (Symbol *Sym : Symtab->getSymbols()) {
    if (!Sym->isUndefined())
      continue;
    if (Sym->isWeak() && !Config->Relocatable)
      continue;
    if (!Sym->isLive())
      continue;
    if (!Sym->IsUsedInRegularObj)
      continue;
    // We don't generate imports for data symbols. They however can be imported
    // as GOT entries.
    if (isa<DataSymbol>(Sym))
      continue;

    LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
    Out.ImportSec->addImport(Sym);
  }
}

void Writer::calculateExports() {
  if (Config->Relocatable)
    return;

  if (!Config->Relocatable && !Config->ImportMemory)
    Out.ExportSec->Exports.push_back(
        WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});

  if (!Config->Relocatable && Config->ExportTable)
    Out.ExportSec->Exports.push_back(
        WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});

  unsigned FakeGlobalIndex =
      Out.ImportSec->numImportedGlobals() + Out.GlobalSec->InputGlobals.size();

  for (Symbol *Sym : Symtab->getSymbols()) {
    if (!Sym->isExported())
      continue;
    if (!Sym->isLive())
      continue;

    StringRef Name = Sym->getName();
    WasmExport Export;
    if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
      Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
    } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
      // TODO(sbc): Remove this check once to mutable global proposal is
      // implement in all major browsers.
      // See: https://github.com/WebAssembly/mutable-global
      if (G->getGlobalType()->Mutable) {
        // Only the __stack_pointer should ever be create as mutable.
        assert(G == WasmSym::StackPointer);
        continue;
      }
      Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
    } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
      Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
    } else {
      auto *D = cast<DefinedData>(Sym);
      Out.GlobalSec->DefinedFakeGlobals.emplace_back(D);
      Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
    }

    LLVM_DEBUG(dbgs() << "Export: " << Name << "\n");
    Out.ExportSec->Exports.push_back(Export);
  }
}

void Writer::populateSymtab() {
  if (!Config->Relocatable && !Config->EmitRelocs)
    return;

  for (Symbol *Sym : Symtab->getSymbols())
    if (Sym->IsUsedInRegularObj && Sym->isLive())
      Out.LinkingSec->addToSymtab(Sym);

  for (ObjFile *File : Symtab->ObjectFiles) {
    LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
    for (Symbol *Sym : File->getSymbols())
      if (Sym->isLocal() && !isa<SectionSymbol>(Sym) && Sym->isLive())
        Out.LinkingSec->addToSymtab(Sym);
  }
}

void Writer::calculateTypes() {
  // The output type section is the union of the following sets:
  // 1. Any signature used in the TYPE relocation
  // 2. The signatures of all imported functions
  // 3. The signatures of all defined functions
  // 4. The signatures of all imported events
  // 5. The signatures of all defined events

  for (ObjFile *File : Symtab->ObjectFiles) {
    ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
    for (uint32_t I = 0; I < Types.size(); I++)
      if (File->TypeIsUsed[I])
        File->TypeMap[I] = Out.TypeSec->registerType(Types[I]);
  }

  for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) {
    if (auto *F = dyn_cast<FunctionSymbol>(Sym))
      Out.TypeSec->registerType(*F->Signature);
    else if (auto *E = dyn_cast<EventSymbol>(Sym))
      Out.TypeSec->registerType(*E->Signature);
  }

  for (const InputFunction *F : Out.FunctionSec->InputFunctions)
    Out.TypeSec->registerType(F->Signature);

  for (const InputEvent *E : Out.EventSec->InputEvents)
    Out.TypeSec->registerType(E->Signature);
}

static void scanRelocations() {
  for (ObjFile *File : Symtab->ObjectFiles) {
    LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n");
    for (InputChunk *Chunk : File->Functions)
      scanRelocations(Chunk);
    for (InputChunk *Chunk : File->Segments)
      scanRelocations(Chunk);
    for (auto &P : File->CustomSections)
      scanRelocations(P);
  }
}

void Writer::assignIndexes() {
  // Seal the import section, since other index spaces such as function and
  // global are effected by the number of imports.
  Out.ImportSec->seal();

  for (InputFunction *Func : Symtab->SyntheticFunctions)
    Out.FunctionSec->addFunction(Func);

  for (ObjFile *File : Symtab->ObjectFiles) {
    LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
    for (InputFunction *Func : File->Functions)
      Out.FunctionSec->addFunction(Func);
  }

  for (InputGlobal *Global : Symtab->SyntheticGlobals)
    Out.GlobalSec->addGlobal(Global);

  for (ObjFile *File : Symtab->ObjectFiles) {
    LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
    for (InputGlobal *Global : File->Globals)
      Out.GlobalSec->addGlobal(Global);
  }

  for (ObjFile *File : Symtab->ObjectFiles) {
    LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
    for (InputEvent *Event : File->Events)
      Out.EventSec->addEvent(Event);
  }
}

static StringRef getOutputDataSegmentName(StringRef Name) {
  // With PIC code we currently only support a single data segment since
  // we only have a single __memory_base to use as our base address.
  if (Config->Pic)
    return "data";
  if (!Config->MergeDataSegments)
    return Name;
  if (Name.startswith(".text."))
    return ".text";
  if (Name.startswith(".data."))
    return ".data";
  if (Name.startswith(".bss."))
    return ".bss";
  if (Name.startswith(".rodata."))
    return ".rodata";
  return Name;
}

void Writer::createOutputSegments() {
  for (ObjFile *File : Symtab->ObjectFiles) {
    for (InputSegment *Segment : File->Segments) {
      if (!Segment->Live)
        continue;
      StringRef Name = getOutputDataSegmentName(Segment->getName());
      OutputSegment *&S = SegmentMap[Name];
      if (S == nullptr) {
        LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
        S = make<OutputSegment>(Name, Segments.size());
        Segments.push_back(S);
      }
      S->addInputSegment(Segment);
      LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
    }
  }
}

// For -shared (PIC) output, we create create a synthetic function which will
// apply any relocations to the data segments on startup.  This function is
// called __wasm_apply_relocs and is added at the very beginning of
// __wasm_call_ctors before any of the constructors run.
void Writer::createApplyRelocationsFunction() {
  LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n");
  // First write the body's contents to a string.
  std::string BodyContent;
  {
    raw_string_ostream OS(BodyContent);
    writeUleb128(OS, 0, "num locals");
    for (const OutputSegment *Seg : Segments)
      for (const InputSegment *InSeg : Seg->InputSegments)
        InSeg->generateRelocationCode(OS);
    writeU8(OS, WASM_OPCODE_END, "END");
  }

  // Once we know the size of the body we can create the final function body
  std::string FunctionBody;
  {
    raw_string_ostream OS(FunctionBody);
    writeUleb128(OS, BodyContent.size(), "function size");
    OS << BodyContent;
  }

  ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
  cast<SyntheticFunction>(WasmSym::ApplyRelocs->Function)->setBody(Body);
}

// Create synthetic "__wasm_call_ctors" function based on ctor functions
// in input object.
void Writer::createCallCtorsFunction() {
  if (!WasmSym::CallCtors->isLive())
    return;

  // First write the body's contents to a string.
  std::string BodyContent;
  {
    raw_string_ostream OS(BodyContent);
    writeUleb128(OS, 0, "num locals");
    if (Config->Pic) {
      writeU8(OS, WASM_OPCODE_CALL, "CALL");
      writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(),
                   "function index");
    }
    for (const WasmInitEntry &F : InitFunctions) {
      writeU8(OS, WASM_OPCODE_CALL, "CALL");
      writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
    }
    writeU8(OS, WASM_OPCODE_END, "END");
  }

  // Once we know the size of the body we can create the final function body
  std::string FunctionBody;
  {
    raw_string_ostream OS(FunctionBody);
    writeUleb128(OS, BodyContent.size(), "function size");
    OS << BodyContent;
  }

  ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
  cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
}

// Populate InitFunctions vector with init functions from all input objects.
// This is then used either when creating the output linking section or to
// synthesize the "__wasm_call_ctors" function.
void Writer::calculateInitFunctions() {
  if (!Config->Relocatable && !WasmSym::CallCtors->isLive())
    return;

  for (ObjFile *File : Symtab->ObjectFiles) {
    const WasmLinkingData &L = File->getWasmObj()->linkingData();
    for (const WasmInitFunc &F : L.InitFunctions) {
      FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
      assert(Sym->isLive());
      if (*Sym->Signature != WasmSignature{{}, {}})
        error("invalid signature for init func: " + toString(*Sym));
      InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
    }
  }

  // Sort in order of priority (lowest first) so that they are called
  // in the correct order.
  llvm::stable_sort(InitFunctions,
                    [](const WasmInitEntry &L, const WasmInitEntry &R) {
                      return L.Priority < R.Priority;
                    });
}

void Writer::createSyntheticSections() {
  Out.DylinkSec = make<DylinkSection>();
  Out.TypeSec = make<TypeSection>();
  Out.ImportSec = make<ImportSection>();
  Out.FunctionSec = make<FunctionSection>();
  Out.TableSec = make<TableSection>();
  Out.MemorySec = make<MemorySection>();
  Out.GlobalSec = make<GlobalSection>();
  Out.EventSec = make<EventSection>();
  Out.ExportSec = make<ExportSection>();
  Out.ElemSec = make<ElemSection>(TableBase);
  Out.DataCountSec = make<DataCountSection>(Segments.size());
  Out.LinkingSec = make<LinkingSection>(InitFunctions, Segments);
  Out.NameSec = make<NameSection>();
  Out.ProducersSec = make<ProducersSection>();
  Out.TargetFeaturesSec = make<TargetFeaturesSection>();
}

void Writer::run() {
  if (Config->Relocatable || Config->Pic)
    Config->GlobalBase = 0;

  // For PIC code the table base is assigned dynamically by the loader.
  // For non-PIC, we start at 1 so that accessing table index 0 always traps.
  if (!Config->Pic)
    TableBase = 1;

  log("-- createOutputSegments");
  createOutputSegments();
  log("-- createSyntheticSections");
  createSyntheticSections();
  log("-- populateProducers");
  populateProducers();
  log("-- populateTargetFeatures");
  populateTargetFeatures();
  log("-- calculateImports");
  calculateImports();
  log("-- layoutMemory");
  layoutMemory();

  if (!Config->Relocatable) {
    // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
    // This has to be done after memory layout is performed.
    for (const OutputSegment *Seg : Segments)
      for (const InputSegment *S : Seg->InputSegments)
        addStartStopSymbols(S);
  }

  log("-- scanRelocations");
  scanRelocations();
  log("-- assignIndexes");
  assignIndexes();
  log("-- calculateInitFunctions");
  calculateInitFunctions();

  if (!Config->Relocatable) {
    // Create linker synthesized functions
    if (Config->Pic)
      createApplyRelocationsFunction();
    createCallCtorsFunction();

    // Make sure we have resolved all symbols.
    if (!Config->AllowUndefined)
      Symtab->reportRemainingUndefines();

    if (errorCount())
      return;
  }

  log("-- calculateTypes");
  calculateTypes();
  log("-- calculateExports");
  calculateExports();
  log("-- calculateCustomSections");
  calculateCustomSections();
  log("-- populateSymtab");
  populateSymtab();
  log("-- addSections");
  addSections();

  if (errorHandler().Verbose) {
    log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size()));
    log("Defined Globals  : " + Twine(Out.GlobalSec->InputGlobals.size()));
    log("Defined Events   : " + Twine(Out.EventSec->InputEvents.size()));
    log("Function Imports : " + Twine(Out.ImportSec->numImportedFunctions()));
    log("Global Imports   : " + Twine(Out.ImportSec->numImportedGlobals()));
    log("Event Imports    : " + Twine(Out.ImportSec->numImportedEvents()));
    for (ObjFile *File : Symtab->ObjectFiles)
      File->dumpInfo();
  }

  createHeader();
  log("-- finalizeSections");
  finalizeSections();

  log("-- openFile");
  openFile();
  if (errorCount())
    return;

  writeHeader();

  log("-- writeSections");
  writeSections();
  if (errorCount())
    return;

  if (Error E = Buffer->commit())
    fatal("failed to write the output file: " + toString(std::move(E)));
}

// Open a result file.
void Writer::openFile() {
  log("writing: " + Config->OutputFile);

  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(Config->OutputFile, FileSize,
                               FileOutputBuffer::F_executable);

  if (!BufferOrErr)
    error("failed to open " + Config->OutputFile + ": " +
          toString(BufferOrErr.takeError()));
  else
    Buffer = std::move(*BufferOrErr);
}

void Writer::createHeader() {
  raw_string_ostream OS(Header);
  writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
  writeU32(OS, WasmVersion, "wasm version");
  OS.flush();
  FileSize += Header.size();
}

void lld::wasm::writeResult() { Writer().run(); }
