//===- SymbolTable.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 "SymbolTable.h"
#include "Config.h"
#include "InputChunks.h"
#include "InputElement.h"
#include "WriterUtils.h"
#include "lld/Common/CommonLinkerContext.h"
#include <optional>

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::wasm;
using namespace llvm::object;

namespace lld::wasm {
SymbolTable *symtab;

void SymbolTable::addFile(InputFile *file, StringRef symName) {
  log("Processing: " + toString(file));

  // Lazy object file
  if (file->lazy) {
    if (auto *f = dyn_cast<BitcodeFile>(file)) {
      ctx.lazyBitcodeFiles.push_back(f);
      f->parseLazy();
    } else {
      cast<ObjFile>(file)->parseLazy();
    }
    return;
  }

  // .so file
  if (auto *f = dyn_cast<SharedFile>(file)) {
    // If we are not reporting undefined symbols that we don't actualy
    // parse the shared library symbol table.
    f->parse();
    ctx.sharedFiles.push_back(f);
    return;
  }

  // stub file
  if (auto *f = dyn_cast<StubFile>(file)) {
    f->parse();
    ctx.stubFiles.push_back(f);
    return;
  }

  if (ctx.arg.trace)
    message(toString(file));

  // LLVM bitcode file
  if (auto *f = dyn_cast<BitcodeFile>(file)) {
    // This order, first adding to `bitcodeFiles` and then parsing is necessary.
    // See https://github.com/llvm/llvm-project/pull/73095
    ctx.bitcodeFiles.push_back(f);
    f->parse(symName);
    return;
  }

  // Regular object file
  auto *f = cast<ObjFile>(file);
  f->parse(false);
  ctx.objectFiles.push_back(f);
}

// This function is where all the optimizations of link-time
// optimization happens. When LTO is in use, some input files are
// not in native object file format but in the LLVM bitcode format.
// This function compiles bitcode files into a few big native files
// using LLVM functions and replaces bitcode symbols with the results.
// Because all bitcode files that the program consists of are passed
// to the compiler at once, it can do whole-program optimization.
void SymbolTable::compileBitcodeFiles() {
  // Prevent further LTO objects being included
  BitcodeFile::doneLTO = true;

  // Compile bitcode files and replace bitcode symbols.
  lto.reset(new BitcodeCompiler);
  for (BitcodeFile *f : ctx.bitcodeFiles)
    lto->add(*f);

  for (StringRef filename : lto->compile()) {
    auto *obj = make<ObjFile>(MemoryBufferRef(filename, "lto.tmp"), "");
    obj->parse(true);
    ctx.objectFiles.push_back(obj);
  }
}

Symbol *SymbolTable::find(StringRef name) {
  auto it = symMap.find(CachedHashStringRef(name));
  if (it == symMap.end() || it->second == -1)
    return nullptr;
  return symVector[it->second];
}

void SymbolTable::replace(StringRef name, Symbol* sym) {
  auto it = symMap.find(CachedHashStringRef(name));
  symVector[it->second] = sym;
}

std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) {
  bool trace = false;
  auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
  int &symIndex = p.first->second;
  bool isNew = p.second;
  if (symIndex == -1) {
    symIndex = symVector.size();
    trace = true;
    isNew = true;
  }

  if (!isNew)
    return {symVector[symIndex], false};

  Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
  sym->isUsedInRegularObj = false;
  sym->canInline = true;
  sym->traced = trace;
  sym->forceExport = false;
  sym->referenced = !ctx.arg.gcSections;
  symVector.emplace_back(sym);
  return {sym, true};
}

std::pair<Symbol *, bool> SymbolTable::insert(StringRef name,
                                              const InputFile *file) {
  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insertName(name);

  if (!file || file->kind() == InputFile::ObjectKind)
    s->isUsedInRegularObj = true;

  return {s, wasInserted};
}

static void reportTypeError(const Symbol *existing, const InputFile *file,
                            llvm::wasm::WasmSymbolType type) {
  error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " +
        toString(existing->getWasmType()) + " in " +
        toString(existing->getFile()) + "\n>>> defined as " + toString(type) +
        " in " + toString(file));
}

// Check the type of new symbol matches that of the symbol is replacing.
// Returns true if the function types match, false is there is a signature
// mismatch.
static bool signatureMatches(FunctionSymbol *existing,
                             const WasmSignature *newSig) {
  const WasmSignature *oldSig = existing->signature;

  // If either function is missing a signature (this happens for bitcode
  // symbols) then assume they match.  Any mismatch will be reported later
  // when the LTO objects are added.
  if (!newSig || !oldSig)
    return true;

  return *newSig == *oldSig;
}

static void checkGlobalType(const Symbol *existing, const InputFile *file,
                            const WasmGlobalType *newType) {
  if (!isa<GlobalSymbol>(existing)) {
    reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL);
    return;
  }

  const WasmGlobalType *oldType = cast<GlobalSymbol>(existing)->getGlobalType();
  if (*newType != *oldType) {
    error("Global type mismatch: " + existing->getName() + "\n>>> defined as " +
          toString(*oldType) + " in " + toString(existing->getFile()) +
          "\n>>> defined as " + toString(*newType) + " in " + toString(file));
  }
}

static void checkTagType(const Symbol *existing, const InputFile *file,
                         const WasmSignature *newSig) {
  const auto *existingTag = dyn_cast<TagSymbol>(existing);
  if (!isa<TagSymbol>(existing)) {
    reportTypeError(existing, file, WASM_SYMBOL_TYPE_TAG);
    return;
  }

  const WasmSignature *oldSig = existingTag->signature;
  if (*newSig != *oldSig)
    warn("Tag signature mismatch: " + existing->getName() +
         "\n>>> defined as " + toString(*oldSig) + " in " +
         toString(existing->getFile()) + "\n>>> defined as " +
         toString(*newSig) + " in " + toString(file));
}

static void checkTableType(const Symbol *existing, const InputFile *file,
                           const WasmTableType *newType) {
  if (!isa<TableSymbol>(existing)) {
    reportTypeError(existing, file, WASM_SYMBOL_TYPE_TABLE);
    return;
  }

  const WasmTableType *oldType = cast<TableSymbol>(existing)->getTableType();
  if (newType->ElemType != oldType->ElemType) {
    error("Table type mismatch: " + existing->getName() + "\n>>> defined as " +
          toString(*oldType) + " in " + toString(existing->getFile()) +
          "\n>>> defined as " + toString(*newType) + " in " + toString(file));
  }
  // FIXME: No assertions currently on the limits.
}

static void checkDataType(const Symbol *existing, const InputFile *file) {
  if (!isa<DataSymbol>(existing))
    reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA);
}

DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name,
                                                   uint32_t flags,
                                                   InputFunction *function) {
  LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << name << "\n");
  assert(!find(name));
  ctx.syntheticFunctions.emplace_back(function);
  return replaceSymbol<DefinedFunction>(insertName(name).first, name,
                                        flags, nullptr, function);
}

// Adds an optional, linker generated, data symbol.  The symbol will only be
// added if there is an undefine reference to it, or if it is explicitly
// exported via the --export flag.  Otherwise we don't add the symbol and return
// nullptr.
DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name,
                                                uint64_t value) {
  Symbol *s = find(name);
  if (!s && (ctx.arg.exportAll || ctx.arg.exportedSymbols.count(name) != 0))
    s = insertName(name).first;
  else if (!s || s->isDefined())
    return nullptr;
  LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << name << "\n");
  auto *rtn = replaceSymbol<DefinedData>(
      s, name, WASM_SYMBOL_VISIBILITY_HIDDEN | WASM_SYMBOL_ABSOLUTE);
  rtn->setVA(value);
  rtn->referenced = true;
  return rtn;
}

DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef name,
                                                 uint32_t flags) {
  LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << name << "\n");
  assert(!find(name));
  return replaceSymbol<DefinedData>(insertName(name).first, name,
                                    flags | WASM_SYMBOL_ABSOLUTE);
}

DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags,
                                               InputGlobal *global) {
  LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << name << " -> " << global
                    << "\n");
  assert(!find(name));
  ctx.syntheticGlobals.emplace_back(global);
  return replaceSymbol<DefinedGlobal>(insertName(name).first, name, flags,
                                      nullptr, global);
}

DefinedGlobal *SymbolTable::addOptionalGlobalSymbol(StringRef name,
                                                    InputGlobal *global) {
  Symbol *s = find(name);
  if (!s || s->isDefined())
    return nullptr;
  LLVM_DEBUG(dbgs() << "addOptionalGlobalSymbol: " << name << " -> " << global
                    << "\n");
  ctx.syntheticGlobals.emplace_back(global);
  return replaceSymbol<DefinedGlobal>(s, name, WASM_SYMBOL_VISIBILITY_HIDDEN,
                                      nullptr, global);
}

DefinedTable *SymbolTable::addSyntheticTable(StringRef name, uint32_t flags,
                                             InputTable *table) {
  LLVM_DEBUG(dbgs() << "addSyntheticTable: " << name << " -> " << table
                    << "\n");
  Symbol *s = find(name);
  assert(!s || s->isUndefined());
  if (!s)
    s = insertName(name).first;
  ctx.syntheticTables.emplace_back(table);
  return replaceSymbol<DefinedTable>(s, name, flags, nullptr, table);
}

static bool shouldReplace(const Symbol *existing, InputFile *newFile,
                          uint32_t newFlags) {
  // If existing symbol is undefined, replace it.
  if (!existing->isDefined()) {
    LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
                      << existing->getName() << "\n");
    return true;
  }

  // Now we have two defined symbols. If the new one is weak, we can ignore it.
  if ((newFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
    LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
    return false;
  }

  // If the existing symbol is weak, we should replace it.
  if (existing->isWeak()) {
    LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
    return true;
  }

  // Similarly with shared symbols
  if (existing->isShared()) {
    LLVM_DEBUG(dbgs() << "replacing existing shared symbol\n");
    return true;
  }

  // Neither symbol is week. They conflict.
  if (ctx.arg.allowMultipleDefinition)
    return false;

  errorOrWarn("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
              toString(existing->getFile()) + "\n>>> defined in " +
              toString(newFile));
  return true;
}

static void reportFunctionSignatureMismatch(StringRef symName,
                                            FunctionSymbol *sym,
                                            const WasmSignature *signature,
                                            InputFile *file,
                                            bool isError = true) {
  std::string msg =
      ("function signature mismatch: " + symName + "\n>>> defined as " +
       toString(*sym->signature) + " in " + toString(sym->getFile()) +
       "\n>>> defined as " + toString(*signature) + " in " + toString(file))
          .str();
  if (isError)
    error(msg);
  else
    warn(msg);
}

static void reportFunctionSignatureMismatch(StringRef symName,
                                            FunctionSymbol *a,
                                            FunctionSymbol *b,
                                            bool isError = true) {
  reportFunctionSignatureMismatch(symName, a, b->signature, b->getFile(),
                                  isError);
}

Symbol *SymbolTable::addSharedFunction(StringRef name, uint32_t flags,
                                       InputFile *file,
                                       const WasmSignature *sig) {
  LLVM_DEBUG(dbgs() << "addSharedFunction: " << name << " [" << toString(*sig)
                    << "]\n");
  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&](Symbol *sym) {
    replaceSymbol<SharedFunctionSymbol>(sym, name, flags, file, sig);
  };

  if (wasInserted || s->isLazy()) {
    replaceSym(s);
    return s;
  }

  auto existingFunction = dyn_cast<FunctionSymbol>(s);
  if (!existingFunction) {
    reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
    return s;
  }

  // Shared symbols should never replace locally-defined ones
  if (s->isDefined()) {
    return s;
  }

  LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " << s->getName()
                    << "\n");

  bool checkSig = true;
  if (auto ud = dyn_cast<UndefinedFunction>(existingFunction))
    checkSig = ud->isCalledDirectly;

  if (checkSig && !signatureMatches(existingFunction, sig)) {
    if (ctx.arg.shlibSigCheck) {
      reportFunctionSignatureMismatch(name, existingFunction, sig, file);
    } else {
      // With --no-shlib-sigcheck we ignore the signature of the function as
      // defined by the shared library and instead use the signature as
      // expected by the program being linked.
      sig = existingFunction->signature;
    }
  }

  replaceSym(s);
  return s;
}

Symbol *SymbolTable::addSharedData(StringRef name, uint32_t flags,
                                   InputFile *file) {
  LLVM_DEBUG(dbgs() << "addSharedData: " << name << "\n");
  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  if (wasInserted || s->isLazy()) {
    replaceSymbol<SharedData>(s, name, flags, file);
    return s;
  }

  // Shared symbols should never replace locally-defined ones
  if (s->isDefined()) {
    return s;
  }

  checkDataType(s, file);
  replaceSymbol<SharedData>(s, name, flags, file);
  return s;
}

Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags,
                                        InputFile *file,
                                        InputFunction *function) {
  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << name << " ["
                    << (function ? toString(function->signature) : "none")
                    << "]\n");
  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&](Symbol *sym) {
    // If the new defined function doesn't have signature (i.e. bitcode
    // functions) but the old symbol does, then preserve the old signature
    const WasmSignature *oldSig = s->getSignature();
    auto* newSym = replaceSymbol<DefinedFunction>(sym, name, flags, file, function);
    if (!newSym->signature)
      newSym->signature = oldSig;
  };

  if (wasInserted || s->isLazy()) {
    replaceSym(s);
    return s;
  }

  auto existingFunction = dyn_cast<FunctionSymbol>(s);
  if (!existingFunction) {
    reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
    return s;
  }

  bool checkSig = true;
  if (auto ud = dyn_cast<UndefinedFunction>(existingFunction))
    checkSig = ud->isCalledDirectly;

  if (checkSig && function && !signatureMatches(existingFunction, &function->signature)) {
    Symbol* variant;
    if (getFunctionVariant(s, &function->signature, file, &variant))
      // New variant, always replace
      replaceSym(variant);
    else if (shouldReplace(s, file, flags))
      // Variant already exists, replace it after checking shouldReplace
      replaceSym(variant);

    // This variant we found take the place in the symbol table as the primary
    // variant.
    replace(name, variant);
    return variant;
  }

  // Existing function with matching signature.
  if (shouldReplace(s, file, flags))
    replaceSym(s);

  return s;
}

Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags,
                                    InputFile *file, InputChunk *segment,
                                    uint64_t address, uint64_t size) {
  LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address
                    << "\n");
  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&]() {
    replaceSymbol<DefinedData>(s, name, flags, file, segment, address, size);
  };

  if (wasInserted || s->isLazy()) {
    replaceSym();
    return s;
  }

  checkDataType(s, file);

  if (shouldReplace(s, file, flags))
    replaceSym();
  return s;
}

Symbol *SymbolTable::addDefinedGlobal(StringRef name, uint32_t flags,
                                      InputFile *file, InputGlobal *global) {
  LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << name << "\n");

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&]() {
    replaceSymbol<DefinedGlobal>(s, name, flags, file, global);
  };

  if (wasInserted || s->isLazy()) {
    replaceSym();
    return s;
  }

  checkGlobalType(s, file, &global->getType());

  if (shouldReplace(s, file, flags))
    replaceSym();
  return s;
}

Symbol *SymbolTable::addDefinedTag(StringRef name, uint32_t flags,
                                   InputFile *file, InputTag *tag) {
  LLVM_DEBUG(dbgs() << "addDefinedTag:" << name << "\n");

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&]() {
    replaceSymbol<DefinedTag>(s, name, flags, file, tag);
  };

  if (wasInserted || s->isLazy()) {
    replaceSym();
    return s;
  }

  checkTagType(s, file, &tag->signature);

  if (shouldReplace(s, file, flags))
    replaceSym();
  return s;
}

Symbol *SymbolTable::addDefinedTable(StringRef name, uint32_t flags,
                                     InputFile *file, InputTable *table) {
  LLVM_DEBUG(dbgs() << "addDefinedTable:" << name << "\n");

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);

  auto replaceSym = [&]() {
    replaceSymbol<DefinedTable>(s, name, flags, file, table);
  };

  if (wasInserted || s->isLazy()) {
    replaceSym();
    return s;
  }

  checkTableType(s, file, &table->getType());

  if (shouldReplace(s, file, flags))
    replaceSym();
  return s;
}

// This function get called when an undefined symbol is added, and there is
// already an existing one in the symbols table.  In this case we check that
// custom 'import-module' and 'import-field' symbol attributes agree.
// With LTO these attributes are not available when the bitcode is read and only
// become available when the LTO object is read.  In this case we silently
// replace the empty attributes with the valid ones.
template <typename T>
static void setImportAttributes(T *existing,
                                std::optional<StringRef> importName,
                                std::optional<StringRef> importModule,
                                uint32_t flags, InputFile *file) {
  if (importName) {
    if (!existing->importName)
      existing->importName = importName;
    if (existing->importName != importName)
      error("import name mismatch for symbol: " + toString(*existing) +
            "\n>>> defined as " + *existing->importName + " in " +
            toString(existing->getFile()) + "\n>>> defined as " + *importName +
            " in " + toString(file));
  }

  if (importModule) {
    if (!existing->importModule)
      existing->importModule = importModule;
    if (existing->importModule != importModule)
      error("import module mismatch for symbol: " + toString(*existing) +
            "\n>>> defined as " + *existing->importModule + " in " +
            toString(existing->getFile()) + "\n>>> defined as " +
            *importModule + " in " + toString(file));
  }

  // Update symbol binding, if the existing symbol is weak
  uint32_t binding = flags & WASM_SYMBOL_BINDING_MASK;
  if (existing->isWeak() && binding != WASM_SYMBOL_BINDING_WEAK) {
    existing->flags = (existing->flags & ~WASM_SYMBOL_BINDING_MASK) | binding;
  }
}

Symbol *SymbolTable::addUndefinedFunction(StringRef name,
                                          std::optional<StringRef> importName,
                                          std::optional<StringRef> importModule,
                                          uint32_t flags, InputFile *file,
                                          const WasmSignature *sig,
                                          bool isCalledDirectly) {
  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " ["
                    << (sig ? toString(*sig) : "none")
                    << "] IsCalledDirectly:" << isCalledDirectly << " flags=0x"
                    << utohexstr(flags) << "\n");
  assert(flags & WASM_SYMBOL_UNDEFINED);

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);
  if (s->traced)
    printTraceSymbolUndefined(name, file);

  auto replaceSym = [&]() {
    replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags,
                                     file, sig, isCalledDirectly);
  };

  if (wasInserted) {
    replaceSym();
  } else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
    if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
      lazy->setWeak();
      lazy->signature = sig;
    } else {
      lazy->extract();
      if (!ctx.arg.whyExtract.empty())
        ctx.whyExtractRecords.emplace_back(toString(file), s->getFile(), *s);
    }
  } else {
    auto existingFunction = dyn_cast<FunctionSymbol>(s);
    if (!existingFunction) {
      reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
      return s;
    }
    if (!existingFunction->signature && sig)
      existingFunction->signature = sig;
    auto *existingUndefined = dyn_cast<UndefinedFunction>(existingFunction);
    if (isCalledDirectly && !signatureMatches(existingFunction, sig)) {
      if (existingFunction->isShared()) {
        // Special handling for when the existing function is a shared symbol
        if (ctx.arg.shlibSigCheck) {
          reportFunctionSignatureMismatch(name, existingFunction, sig, file);
        } else {
          existingFunction->signature = sig;
        }
      }
      // If the existing undefined functions is not called directly then let
      // this one take precedence.  Otherwise the existing function is either
      // directly called or defined, in which case we need a function variant.
      else if (existingUndefined && !existingUndefined->isCalledDirectly)
        replaceSym();
      else if (getFunctionVariant(s, sig, file, &s))
        replaceSym();
    }
    if (existingUndefined) {
      setImportAttributes(existingUndefined, importName, importModule, flags,
                          file);
      if (isCalledDirectly)
        existingUndefined->isCalledDirectly = true;
      if (s->isWeak())
        s->flags = flags;
    }
  }

  return s;
}

Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
                                      InputFile *file) {
  LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n");
  assert(flags & WASM_SYMBOL_UNDEFINED);

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);
  if (s->traced)
    printTraceSymbolUndefined(name, file);

  if (wasInserted) {
    replaceSymbol<UndefinedData>(s, name, flags, file);
  } else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
    if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK)
      lazy->setWeak();
    else
      lazy->extract();
  } else if (s->isDefined()) {
    checkDataType(s, file);
  } else if (s->isWeak()) {
    s->flags = flags;
  }
  return s;
}

Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
                                        std::optional<StringRef> importName,
                                        std::optional<StringRef> importModule,
                                        uint32_t flags, InputFile *file,
                                        const WasmGlobalType *type) {
  LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n");
  assert(flags & WASM_SYMBOL_UNDEFINED);

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);
  if (s->traced)
    printTraceSymbolUndefined(name, file);

  if (wasInserted)
    replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags,
                                   file, type);
  else if (auto *lazy = dyn_cast<LazySymbol>(s))
    lazy->extract();
  else if (s->isDefined())
    checkGlobalType(s, file, type);
  else if (s->isWeak())
    s->flags = flags;
  return s;
}

Symbol *SymbolTable::addUndefinedTable(StringRef name,
                                       std::optional<StringRef> importName,
                                       std::optional<StringRef> importModule,
                                       uint32_t flags, InputFile *file,
                                       const WasmTableType *type) {
  LLVM_DEBUG(dbgs() << "addUndefinedTable: " << name << "\n");
  assert(flags & WASM_SYMBOL_UNDEFINED);

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);
  if (s->traced)
    printTraceSymbolUndefined(name, file);

  if (wasInserted)
    replaceSymbol<UndefinedTable>(s, name, importName, importModule, flags,
                                  file, type);
  else if (auto *lazy = dyn_cast<LazySymbol>(s))
    lazy->extract();
  else if (s->isDefined())
    checkTableType(s, file, type);
  else if (s->isWeak())
    s->flags = flags;
  return s;
}

Symbol *SymbolTable::addUndefinedTag(StringRef name,
                                     std::optional<StringRef> importName,
                                     std::optional<StringRef> importModule,
                                     uint32_t flags, InputFile *file,
                                     const WasmSignature *sig) {
  LLVM_DEBUG(dbgs() << "addUndefinedTag: " << name << "\n");
  assert(flags & WASM_SYMBOL_UNDEFINED);

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insert(name, file);
  if (s->traced)
    printTraceSymbolUndefined(name, file);

  if (wasInserted)
    replaceSymbol<UndefinedTag>(s, name, importName, importModule, flags, file,
                                sig);
  else if (auto *lazy = dyn_cast<LazySymbol>(s))
    lazy->extract();
  else if (s->isDefined())
    checkTagType(s, file, sig);
  else if (s->isWeak())
    s->flags = flags;
  return s;
}

TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
  WasmLimits limits{0, 0, 0}; // Set by the writer.
  WasmTableType *type = make<WasmTableType>();
  type->ElemType = ValType::FUNCREF;
  type->Limits = limits;
  uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
  flags |= WASM_SYMBOL_UNDEFINED;
  Symbol *sym =
      addUndefinedTable(name, name, defaultModule, flags, nullptr, type);
  sym->markLive();
  sym->forceExport = ctx.arg.exportTable;
  return cast<TableSymbol>(sym);
}

TableSymbol *SymbolTable::createDefinedIndirectFunctionTable(StringRef name) {
  const uint32_t invalidIndex = -1;
  WasmLimits limits{0, 0, 0}; // Set by the writer.
  WasmTableType type{ValType::FUNCREF, limits};
  WasmTable desc{invalidIndex, type, name};
  InputTable *table = make<InputTable>(desc, nullptr);
  uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
  TableSymbol *sym = addSyntheticTable(name, flags, table);
  sym->markLive();
  sym->forceExport = ctx.arg.exportTable;
  return sym;
}

// Whether or not we need an indirect function table is usually a function of
// whether an input declares a need for it.  However sometimes it's possible for
// no input to need the indirect function table, but then a late
// addInternalGOTEntry causes a function to be allocated an address.  In that
// case address we synthesize a definition at the last minute.
TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
  Symbol *existing = find(functionTableName);
  if (existing) {
    if (!isa<TableSymbol>(existing)) {
      error(Twine("reserved symbol must be of type table: `") +
            functionTableName + "`");
      return nullptr;
    }
    if (existing->isDefined()) {
      error(Twine("reserved symbol must not be defined in input files: `") +
            functionTableName + "`");
      return nullptr;
    }
  }

  if (ctx.arg.importTable) {
    if (existing) {
      existing->importModule = defaultModule;
      existing->importName = functionTableName;
      return cast<TableSymbol>(existing);
    }
    if (required)
      return createUndefinedIndirectFunctionTable(functionTableName);
  } else if ((existing && existing->isLive()) || ctx.arg.exportTable ||
             required) {
    // A defined table is required.  Either because the user request an exported
    // table or because the table symbol is already live.  The existing table is
    // guaranteed to be undefined due to the check above.
    return createDefinedIndirectFunctionTable(functionTableName);
  }

  // An indirect function table will only be present in the symbol table if
  // needed by a reloc; if we get here, we don't need one.
  return nullptr;
}

void SymbolTable::addLazy(StringRef name, InputFile *file) {
  LLVM_DEBUG(dbgs() << "addLazy: " << name << "\n");

  Symbol *s;
  bool wasInserted;
  std::tie(s, wasInserted) = insertName(name);

  if (wasInserted) {
    replaceSymbol<LazySymbol>(s, name, 0, file);
    return;
  }

  if (!s->isUndefined())
    return;

  // The existing symbol is undefined, load a new one from the archive,
  // unless the existing symbol is weak in which case replace the undefined
  // symbols with a LazySymbol.
  if (s->isWeak()) {
    const WasmSignature *oldSig = nullptr;
    // In the case of an UndefinedFunction we need to preserve the expected
    // signature.
    if (auto *f = dyn_cast<UndefinedFunction>(s))
      oldSig = f->signature;
    LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
    auto newSym =
        replaceSymbol<LazySymbol>(s, name, WASM_SYMBOL_BINDING_WEAK, file);
    newSym->signature = oldSig;
    return;
  }

  LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
  const InputFile *oldFile = s->getFile();
  LazySymbol(name, 0, file).extract();
  if (!ctx.arg.whyExtract.empty())
    ctx.whyExtractRecords.emplace_back(toString(oldFile), s->getFile(), *s);
}

bool SymbolTable::addComdat(StringRef name) {
  return comdatGroups.insert(CachedHashStringRef(name)).second;
}

// The new signature doesn't match.  Create a variant to the symbol with the
// signature encoded in the name and return that instead.  These symbols are
// then unified later in handleSymbolVariants.
bool SymbolTable::getFunctionVariant(Symbol* sym, const WasmSignature *sig,
                                     const InputFile *file, Symbol **out) {
  LLVM_DEBUG(dbgs() << "getFunctionVariant: " << sym->getName() << " -> "
                    << " " << toString(*sig) << "\n");
  Symbol *variant = nullptr;

  // Linear search through symbol variants.  Should never be more than two
  // or three entries here.
  auto &variants = symVariants[CachedHashStringRef(sym->getName())];
  if (variants.empty())
    variants.push_back(sym);

  for (Symbol* v : variants) {
    if (*v->getSignature() == *sig) {
      variant = v;
      break;
    }
  }

  bool wasAdded = !variant;
  if (wasAdded) {
    // Create a new variant;
    LLVM_DEBUG(dbgs() << "added new variant\n");
    variant = reinterpret_cast<Symbol *>(make<SymbolUnion>());
    variant->isUsedInRegularObj =
        !file || file->kind() == InputFile::ObjectKind;
    variant->canInline = true;
    variant->traced = false;
    variant->forceExport = false;
    variants.push_back(variant);
  } else {
    LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n");
    assert(*variant->getSignature() == *sig);
  }

  *out = variant;
  return wasAdded;
}

// Set a flag for --trace-symbol so that we can print out a log message
// if a new symbol with the same name is inserted into the symbol table.
void SymbolTable::trace(StringRef name) {
  symMap.insert({CachedHashStringRef(name), -1});
}

void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
  // Swap symbols as instructed by -wrap.
  int &origIdx = symMap[CachedHashStringRef(sym->getName())];
  int &realIdx= symMap[CachedHashStringRef(real->getName())];
  int &wrapIdx = symMap[CachedHashStringRef(wrap->getName())];
  LLVM_DEBUG(dbgs() << "wrap: " << sym->getName() << "\n");

  // Anyone looking up __real symbols should get the original
  realIdx = origIdx;
  // Anyone looking up the original should get the __wrap symbol
  origIdx = wrapIdx;
}

static const uint8_t unreachableFn[] = {
    0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
    0x00 /* opcode unreachable */, 0x0b /* opcode end */
};

// Replace the given symbol body with an unreachable function.
// This is used by handleWeakUndefines in order to generate a callable
// equivalent of an undefined function and also handleSymbolVariants for
// undefined functions that don't match the signature of the definition.
InputFunction *SymbolTable::replaceWithUnreachable(Symbol *sym,
                                                   const WasmSignature &sig,
                                                   StringRef debugName) {
  auto *func = make<SyntheticFunction>(sig, sym->getName(), debugName);
  func->setBody(unreachableFn);
  ctx.syntheticFunctions.emplace_back(func);
  // Mark new symbols as local. For relocatable output we don't want them
  // to be exported outside the object file.
  replaceSymbol<DefinedFunction>(sym, debugName, WASM_SYMBOL_BINDING_LOCAL,
                                 nullptr, func);
  // Ensure the stub function doesn't get a table entry.  Its address
  // should always compare equal to the null pointer.
  sym->isStub = true;
  return func;
}

void SymbolTable::replaceWithUndefined(Symbol *sym) {
  // Add a synthetic dummy for weak undefined functions.  These dummies will
  // be GC'd if not used as the target of any "call" instructions.
  StringRef debugName = saver().save("undefined_weak:" + toString(*sym));
  replaceWithUnreachable(sym, *sym->getSignature(), debugName);
  // Hide our dummy to prevent export.
  sym->setHidden(true);
}

// For weak undefined functions, there may be "call" instructions that reference
// the symbol. In this case, we need to synthesise a dummy/stub function that
// will abort at runtime, so that relocations can still provided an operand to
// the call instruction that passes Wasm validation.
void SymbolTable::handleWeakUndefines() {
  for (Symbol *sym : symbols()) {
    if (sym->isUndefWeak() && sym->isUsedInRegularObj) {
      if (sym->getSignature()) {
        replaceWithUndefined(sym);
      } else {
        // It is possible for undefined functions not to have a signature (eg.
        // if added via "--undefined"), but weak undefined ones do have a
        // signature.  Lazy symbols may not be functions and therefore Sig can
        // still be null in some circumstance.
        assert(!isa<FunctionSymbol>(sym));
      }
    }
  }
}

DefinedFunction *SymbolTable::createUndefinedStub(const WasmSignature &sig) {
  if (auto it = stubFunctions.find(sig); it != stubFunctions.end())
    return it->second;
  LLVM_DEBUG(dbgs() << "createUndefinedStub: " << toString(sig) << "\n");
  auto *sym = reinterpret_cast<DefinedFunction *>(make<SymbolUnion>());
  sym->isUsedInRegularObj = true;
  sym->canInline = true;
  sym->traced = false;
  sym->forceExport = false;
  sym->signature = &sig;
  replaceSymbol<DefinedFunction>(
      sym, "undefined_stub", WASM_SYMBOL_VISIBILITY_HIDDEN, nullptr, nullptr);
  replaceWithUnreachable(sym, sig, "undefined_stub");
  stubFunctions[sig] = sym;
  return sym;
}

// Remove any variant symbols that were created due to function signature
// mismatches.
void SymbolTable::handleSymbolVariants() {
  for (auto pair : symVariants) {
    // Push the initial symbol onto the list of variants.
    StringRef symName = pair.first.val();
    std::vector<Symbol *> &variants = pair.second;

#ifndef NDEBUG
    LLVM_DEBUG(dbgs() << "symbol with (" << variants.size()
                      << ") variants: " << symName << "\n");
    for (auto *s: variants) {
      auto *f = cast<FunctionSymbol>(s);
      LLVM_DEBUG(dbgs() << " variant: " + f->getName() << " "
                        << toString(*f->signature) << "\n");
    }
#endif

    // Find the one definition.
    DefinedFunction *defined = nullptr;
    for (auto *symbol : variants) {
      if (auto f = dyn_cast<DefinedFunction>(symbol)) {
        defined = f;
        break;
      }
    }

    // If there are no definitions, and the undefined symbols disagree on
    // the signature, there is not we can do since we don't know which one
    // to use as the signature on the import.
    if (!defined) {
      reportFunctionSignatureMismatch(symName,
                                      cast<FunctionSymbol>(variants[0]),
                                      cast<FunctionSymbol>(variants[1]));
      return;
    }

    for (auto *symbol : variants) {
      if (symbol != defined) {
        auto *f = cast<FunctionSymbol>(symbol);
        reportFunctionSignatureMismatch(symName, f, defined, false);
        StringRef debugName =
            saver().save("signature_mismatch:" + toString(*f));
        replaceWithUnreachable(f, *f->signature, debugName);
      }
    }
  }
}

} // namespace wasm::lld
