//===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Synthetic sections represent chunks of linker-created data. If you
// need to create a chunk of data that to be included in some section
// in the result, you probably want to create that as a synthetic section.
//
//===----------------------------------------------------------------------===//

#ifndef LLD_WASM_SYNTHETIC_SECTIONS_H
#define LLD_WASM_SYNTHETIC_SECTIONS_H

#include "OutputSections.h"

#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/WasmTraits.h"

#define DEBUG_TYPE "lld"

namespace lld {
namespace wasm {

// An init entry to be written to either the synthetic init func or the
// linking metadata.
struct WasmInitEntry {
  const FunctionSymbol *sym;
  uint32_t priority;
};

class SyntheticSection : public OutputSection {
public:
  SyntheticSection(uint32_t type, std::string name = "")
      : OutputSection(type, name), bodyOutputStream(body) {
    if (!name.empty())
      writeStr(bodyOutputStream, name, "section name");
  }

  void writeTo(uint8_t *buf) override {
    assert(offset);
    log("writing " + toString(*this));
    memcpy(buf + offset, header.data(), header.size());
    memcpy(buf + offset + header.size(), body.data(), body.size());
  }

  size_t getSize() const override { return header.size() + body.size(); }

  virtual void writeBody() {}

  virtual void assignIndexes() {}

  void finalizeContents() override {
    writeBody();
    bodyOutputStream.flush();
    createHeader(body.size());
  }

  raw_ostream &getStream() { return bodyOutputStream; }

  std::string body;

protected:
  llvm::raw_string_ostream bodyOutputStream;
};

// Create the custom "dylink" section containing information for the dynamic
// linker.
// See
// https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
class DylinkSection : public SyntheticSection {
public:
  DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink.0") {}
  bool isNeeded() const override { return config->isPic; }
  void writeBody() override;

  uint32_t memAlign = 0;
  uint32_t memSize = 0;
};

class TypeSection : public SyntheticSection {
public:
  TypeSection() : SyntheticSection(llvm::wasm::WASM_SEC_TYPE) {}

  bool isNeeded() const override { return types.size() > 0; };
  void writeBody() override;
  uint32_t registerType(const WasmSignature &sig);
  uint32_t lookupType(const WasmSignature &sig);

protected:
  std::vector<const WasmSignature *> types;
  llvm::DenseMap<WasmSignature, int32_t> typeIndices;
};

/**
 * A key for some kind of imported entity of type `T`.
 *
 * Used when de-duplicating imports.
 */
template <typename T> struct ImportKey {
public:
  enum class State { Plain, Empty, Tombstone };

public:
  T type;
  llvm::Optional<StringRef> importModule;
  llvm::Optional<StringRef> importName;
  State state;

public:
  ImportKey(T type) : type(type), state(State::Plain) {}
  ImportKey(T type, State state) : type(type), state(state) {}
  ImportKey(T type, llvm::Optional<StringRef> importModule,
            llvm::Optional<StringRef> importName)
      : type(type), importModule(importModule), importName(importName),
        state(State::Plain) {}
};

template <typename T>
inline bool operator==(const ImportKey<T> &lhs, const ImportKey<T> &rhs) {
  return lhs.state == rhs.state && lhs.importModule == rhs.importModule &&
         lhs.importName == rhs.importName && lhs.type == rhs.type;
}

} // namespace wasm
} // namespace lld

// `ImportKey<T>` can be used as a key in a `DenseMap` if `T` can be used as a
// key in a `DenseMap`.
namespace llvm {
template <typename T> struct DenseMapInfo<lld::wasm::ImportKey<T>> {
  static lld::wasm::ImportKey<T> getEmptyKey() {
    typename lld::wasm::ImportKey<T> key(llvm::DenseMapInfo<T>::getEmptyKey());
    key.state = lld::wasm::ImportKey<T>::State::Empty;
    return key;
  }
  static lld::wasm::ImportKey<T> getTombstoneKey() {
    typename lld::wasm::ImportKey<T> key(llvm::DenseMapInfo<T>::getEmptyKey());
    key.state = lld::wasm::ImportKey<T>::State::Tombstone;
    return key;
  }
  static unsigned getHashValue(const lld::wasm::ImportKey<T> &key) {
    uintptr_t hash = hash_value(key.importModule);
    hash = hash_combine(hash, key.importName);
    hash = hash_combine(hash, llvm::DenseMapInfo<T>::getHashValue(key.type));
    hash = hash_combine(hash, key.state);
    return hash;
  }
  static bool isEqual(const lld::wasm::ImportKey<T> &lhs,
                      const lld::wasm::ImportKey<T> &rhs) {
    return lhs == rhs;
  }
};
} // end namespace llvm

namespace lld {
namespace wasm {

class ImportSection : public SyntheticSection {
public:
  ImportSection() : SyntheticSection(llvm::wasm::WASM_SEC_IMPORT) {}
  bool isNeeded() const override { return getNumImports() > 0; }
  void writeBody() override;
  void addImport(Symbol *sym);
  void addGOTEntry(Symbol *sym);
  void seal() { isSealed = true; }
  uint32_t getNumImports() const;
  uint32_t getNumImportedGlobals() const {
    assert(isSealed);
    return numImportedGlobals;
  }
  uint32_t getNumImportedFunctions() const {
    assert(isSealed);
    return numImportedFunctions;
  }
  uint32_t getNumImportedTags() const {
    assert(isSealed);
    return numImportedTags;
  }
  uint32_t getNumImportedTables() const {
    assert(isSealed);
    return numImportedTables;
  }

  std::vector<const Symbol *> importedSymbols;
  std::vector<const Symbol *> gotSymbols;

protected:
  bool isSealed = false;
  unsigned numImportedGlobals = 0;
  unsigned numImportedFunctions = 0;
  unsigned numImportedTags = 0;
  unsigned numImportedTables = 0;
  llvm::DenseMap<ImportKey<WasmGlobalType>, uint32_t> importedGlobals;
  llvm::DenseMap<ImportKey<WasmSignature>, uint32_t> importedFunctions;
  llvm::DenseMap<ImportKey<WasmTableType>, uint32_t> importedTables;
  llvm::DenseMap<ImportKey<WasmSignature>, uint32_t> importedTags;
};

class FunctionSection : public SyntheticSection {
public:
  FunctionSection() : SyntheticSection(llvm::wasm::WASM_SEC_FUNCTION) {}

  bool isNeeded() const override { return inputFunctions.size() > 0; };
  void writeBody() override;
  void addFunction(InputFunction *func);

  std::vector<InputFunction *> inputFunctions;

protected:
};

class TableSection : public SyntheticSection {
public:
  TableSection() : SyntheticSection(llvm::wasm::WASM_SEC_TABLE) {}

  bool isNeeded() const override { return inputTables.size() > 0; };
  void assignIndexes() override;
  void writeBody() override;
  void addTable(InputTable *table);

  std::vector<InputTable *> inputTables;
};

class MemorySection : public SyntheticSection {
public:
  MemorySection() : SyntheticSection(llvm::wasm::WASM_SEC_MEMORY) {}

  bool isNeeded() const override { return !config->importMemory; }
  void writeBody() override;

  uint64_t numMemoryPages = 0;
  uint64_t maxMemoryPages = 0;
};

// The tag section contains a list of declared wasm tags associated with the
// module. Currently the only supported tag kind is exceptions. All C++
// exceptions are represented by a single tag. A tag entry in this section
// contains information on what kind of tag it is (e.g. exception) and the type
// of values associated with the tag. (In Wasm, a tag can contain multiple
// values of primitive types. But for C++ exceptions, we just throw a pointer
// which is an i32 value (for wasm32 architecture), so the signature of C++
// exception is (i32)->(void), because all exception tag types are assumed to
// have void return type to share WasmSignature with functions.)
class TagSection : public SyntheticSection {
public:
  TagSection() : SyntheticSection(llvm::wasm::WASM_SEC_TAG) {}
  void writeBody() override;
  bool isNeeded() const override { return inputTags.size() > 0; }
  void addTag(InputTag *tag);

  std::vector<InputTag *> inputTags;
};

class GlobalSection : public SyntheticSection {
public:
  GlobalSection() : SyntheticSection(llvm::wasm::WASM_SEC_GLOBAL) {}

  static bool classof(const OutputSection *sec) {
    return sec->type == llvm::wasm::WASM_SEC_GLOBAL;
  }

  uint32_t numGlobals() const {
    assert(isSealed);
    return inputGlobals.size() + dataAddressGlobals.size() +
           internalGotSymbols.size();
  }
  bool isNeeded() const override { return numGlobals() > 0; }
  void assignIndexes() override;
  void writeBody() override;
  void addGlobal(InputGlobal *global);

  // Add an internal GOT entry global that corresponds to the given symbol.
  // Normally GOT entries are imported and assigned by the external dynamic
  // linker.  However, when linking PIC code statically or when linking with
  // -Bsymbolic we can internalize GOT entries by declaring globals the hold
  // symbol addresses.
  //
  // For the static linking case these internal globals can be completely
  // eliminated by a post-link optimizer such as wasm-opt.
  //
  // TODO(sbc): Another approach to optimizing these away could be to use
  // specific relocation types combined with linker relaxation which could
  // transform a `global.get` to an `i32.const`.
  void addInternalGOTEntry(Symbol *sym);
  bool needsRelocations() {
    return llvm::find_if(internalGotSymbols, [=](Symbol *sym) {
             return !sym->isTLS();
           }) != internalGotSymbols.end();
  }
  bool needsTLSRelocations() {
    return llvm::find_if(internalGotSymbols, [=](Symbol *sym) {
             return sym->isTLS();
           }) != internalGotSymbols.end();
  }
  void generateRelocationCode(raw_ostream &os, bool TLS) const;

  std::vector<DefinedData *> dataAddressGlobals;
  std::vector<InputGlobal *> inputGlobals;
  std::vector<Symbol *> internalGotSymbols;

protected:
  bool isSealed = false;
};

class ExportSection : public SyntheticSection {
public:
  ExportSection() : SyntheticSection(llvm::wasm::WASM_SEC_EXPORT) {}
  bool isNeeded() const override { return exports.size() > 0; }
  void writeBody() override;

  std::vector<llvm::wasm::WasmExport> exports;
  std::vector<const Symbol *> exportedSymbols;
};

class StartSection : public SyntheticSection {
public:
  StartSection() : SyntheticSection(llvm::wasm::WASM_SEC_START) {}
  bool isNeeded() const override;
  void writeBody() override;
};

class ElemSection : public SyntheticSection {
public:
  ElemSection()
      : SyntheticSection(llvm::wasm::WASM_SEC_ELEM) {}
  bool isNeeded() const override { return indirectFunctions.size() > 0; };
  void writeBody() override;
  void addEntry(FunctionSymbol *sym);
  uint32_t numEntries() const { return indirectFunctions.size(); }

protected:
  std::vector<const FunctionSymbol *> indirectFunctions;
};

class DataCountSection : public SyntheticSection {
public:
  DataCountSection(ArrayRef<OutputSegment *> segments);
  bool isNeeded() const override;
  void writeBody() override;

protected:
  uint32_t numSegments;
};

// Create the custom "linking" section containing linker metadata.
// This is only created when relocatable output is requested.
class LinkingSection : public SyntheticSection {
public:
  LinkingSection(const std::vector<WasmInitEntry> &initFunctions,
                 const std::vector<OutputSegment *> &dataSegments)
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"),
        initFunctions(initFunctions), dataSegments(dataSegments) {}
  bool isNeeded() const override {
    return config->relocatable || config->emitRelocs;
  }
  void writeBody() override;
  void addToSymtab(Symbol *sym);

protected:
  std::vector<const Symbol *> symtabEntries;
  llvm::StringMap<uint32_t> sectionSymbolIndices;
  const std::vector<WasmInitEntry> &initFunctions;
  const std::vector<OutputSegment *> &dataSegments;
};

// Create the custom "name" section containing debug symbol names.
class NameSection : public SyntheticSection {
public:
  NameSection(ArrayRef<OutputSegment *> segments)
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name"),
        segments(segments) {}
  bool isNeeded() const override { return !config->stripAll && numNames() > 0; }
  void writeBody() override;
  unsigned numNames() const { return numNamedGlobals() + numNamedFunctions(); }
  unsigned numNamedGlobals() const;
  unsigned numNamedFunctions() const;
  unsigned numNamedDataSegments() const;

protected:
  ArrayRef<OutputSegment *> segments;
};

class ProducersSection : public SyntheticSection {
public:
  ProducersSection()
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "producers") {}
  bool isNeeded() const override {
    return !config->stripAll && fieldCount() > 0;
  }
  void writeBody() override;
  void addInfo(const llvm::wasm::WasmProducerInfo &info);

protected:
  int fieldCount() const {
    return int(!languages.empty()) + int(!tools.empty()) + int(!sDKs.empty());
  }
  SmallVector<std::pair<std::string, std::string>, 8> languages;
  SmallVector<std::pair<std::string, std::string>, 8> tools;
  SmallVector<std::pair<std::string, std::string>, 8> sDKs;
};

class TargetFeaturesSection : public SyntheticSection {
public:
  TargetFeaturesSection()
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "target_features") {}
  bool isNeeded() const override {
    return !config->stripAll && features.size() > 0;
  }
  void writeBody() override;

  llvm::SmallSet<std::string, 8> features;
};

class RelocSection : public SyntheticSection {
public:
  RelocSection(StringRef name, OutputSection *sec)
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, std::string(name)),
        sec(sec) {}
  void writeBody() override;
  bool isNeeded() const override { return sec->getNumRelocations() > 0; };

protected:
  OutputSection *sec;
};

// Linker generated output sections
struct OutStruct {
  DylinkSection *dylinkSec;
  TypeSection *typeSec;
  FunctionSection *functionSec;
  ImportSection *importSec;
  TableSection *tableSec;
  MemorySection *memorySec;
  GlobalSection *globalSec;
  TagSection *tagSec;
  ExportSection *exportSec;
  StartSection *startSec;
  ElemSection *elemSec;
  DataCountSection *dataCountSec;
  LinkingSection *linkingSec;
  NameSection *nameSec;
  ProducersSection *producersSec;
  TargetFeaturesSection *targetFeaturesSec;
};

extern OutStruct out;

} // namespace wasm
} // namespace lld

#endif
