//===- InputFiles.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 "InputFiles.h"
#include "Config.h"
#include "InputChunks.h"
#include "InputElement.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Reproduce.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Wasm.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TarWriter.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>

#define DEBUG_TYPE "lld"

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

namespace lld {

// Returns a string in the format of "foo.o" or "foo.a(bar.o)".
std::string toString(const wasm::InputFile *file) {
  if (!file)
    return "<internal>";

  if (file->archiveName.empty())
    return std::string(file->getName());

  return (file->archiveName + "(" + file->getName() + ")").str();
}

namespace wasm {

std::string replaceThinLTOSuffix(StringRef path) {
  auto [suffix, repl] = ctx.arg.thinLTOObjectSuffixReplace;
  if (path.consume_back(suffix))
    return (path + repl).str();
  return std::string(path);
}

void InputFile::checkArch(Triple::ArchType arch) const {
  bool is64 = arch == Triple::wasm64;
  if (is64 && !ctx.arg.is64) {
    fatal(toString(this) +
          ": must specify -mwasm64 to process wasm64 object files");
  }
  if (ctx.arg.is64.value_or(false) != is64) {
    fatal(toString(this) +
          (is64 ? ": wasm64 object file can't be linked in wasm32 mode"
                : ": wasm32 object file can't be linked in wasm64 mode"));
  }
}

std::unique_ptr<llvm::TarWriter> tar;

std::optional<MemoryBufferRef> readFile(StringRef path) {
  log("Loading: " + path);

  auto mbOrErr = MemoryBuffer::getFile(path);
  if (auto ec = mbOrErr.getError()) {
    error("cannot open " + path + ": " + ec.message());
    return std::nullopt;
  }
  std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
  MemoryBufferRef mbref = mb->getMemBufferRef();
  make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take MB ownership

  if (tar)
    tar->append(relativeToRoot(path), mbref.getBuffer());
  return mbref;
}

InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName,
                            uint64_t offsetInArchive, bool lazy) {
  file_magic magic = identify_magic(mb.getBuffer());
  if (magic == file_magic::wasm_object) {
    std::unique_ptr<Binary> bin =
        CHECK(createBinary(mb), mb.getBufferIdentifier());
    auto *obj = cast<WasmObjectFile>(bin.get());
    if (obj->hasUnmodeledTypes())
      fatal(toString(mb.getBufferIdentifier()) +
            " file has unmodeled reference or GC types");
    if (obj->isSharedObject())
      return make<SharedFile>(mb);
    return make<ObjFile>(mb, archiveName, lazy);
  }

  assert(magic == file_magic::bitcode);
  return make<BitcodeFile>(mb, archiveName, offsetInArchive, lazy);
}

// Relocations contain either symbol or type indices.  This function takes a
// relocation and returns relocated index (i.e. translates from the input
// symbol/type space to the output symbol/type space).
uint32_t ObjFile::calcNewIndex(const WasmRelocation &reloc) const {
  if (reloc.Type == R_WASM_TYPE_INDEX_LEB) {
    assert(typeIsUsed[reloc.Index]);
    return typeMap[reloc.Index];
  }
  const Symbol *sym = symbols[reloc.Index];
  if (auto *ss = dyn_cast<SectionSymbol>(sym))
    sym = ss->getOutputSectionSymbol();
  return sym->getOutputSymbolIndex();
}

// Relocations can contain addend for combined sections. This function takes a
// relocation and returns updated addend by offset in the output section.
int64_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const {
  switch (reloc.Type) {
  case R_WASM_MEMORY_ADDR_LEB:
  case R_WASM_MEMORY_ADDR_LEB64:
  case R_WASM_MEMORY_ADDR_SLEB64:
  case R_WASM_MEMORY_ADDR_SLEB:
  case R_WASM_MEMORY_ADDR_REL_SLEB:
  case R_WASM_MEMORY_ADDR_REL_SLEB64:
  case R_WASM_MEMORY_ADDR_I32:
  case R_WASM_MEMORY_ADDR_I64:
  case R_WASM_MEMORY_ADDR_TLS_SLEB:
  case R_WASM_MEMORY_ADDR_TLS_SLEB64:
  case R_WASM_FUNCTION_OFFSET_I32:
  case R_WASM_FUNCTION_OFFSET_I64:
  case R_WASM_MEMORY_ADDR_LOCREL_I32:
  case R_WASM_MEMORY_ADDR_LOCREL_I64:
    return reloc.Addend;
  case R_WASM_SECTION_OFFSET_I32:
    return getSectionSymbol(reloc.Index)->section->getOffset(reloc.Addend);
  default:
    llvm_unreachable("unexpected relocation type");
  }
}

// Translate from the relocation's index into the final linked output value.
uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
                               const InputChunk *chunk) const {
  const Symbol *sym = nullptr;
  if (reloc.Type != R_WASM_TYPE_INDEX_LEB) {
    sym = symbols[reloc.Index];

    // We can end up with relocations against non-live symbols.  For example
    // in debug sections. We return a tombstone value in debug symbol sections
    // so this will not produce a valid range conflicting with ranges of actual
    // code. In other sections we return reloc.Addend.

    if (!isa<SectionSymbol>(sym) && !sym->isLive())
      return tombstone ? tombstone : reloc.Addend;
  }

  switch (reloc.Type) {
  case R_WASM_TABLE_INDEX_I32:
  case R_WASM_TABLE_INDEX_I64:
  case R_WASM_TABLE_INDEX_SLEB:
  case R_WASM_TABLE_INDEX_SLEB64:
  case R_WASM_TABLE_INDEX_REL_SLEB:
  case R_WASM_TABLE_INDEX_REL_SLEB64: {
    if (!getFunctionSymbol(reloc.Index)->hasTableIndex())
      return 0;
    uint32_t index = getFunctionSymbol(reloc.Index)->getTableIndex();
    if (reloc.Type == R_WASM_TABLE_INDEX_REL_SLEB ||
        reloc.Type == R_WASM_TABLE_INDEX_REL_SLEB64)
      index -= ctx.arg.tableBase;
    return index;
  }
  case R_WASM_MEMORY_ADDR_LEB:
  case R_WASM_MEMORY_ADDR_LEB64:
  case R_WASM_MEMORY_ADDR_SLEB:
  case R_WASM_MEMORY_ADDR_SLEB64:
  case R_WASM_MEMORY_ADDR_REL_SLEB:
  case R_WASM_MEMORY_ADDR_REL_SLEB64:
  case R_WASM_MEMORY_ADDR_I32:
  case R_WASM_MEMORY_ADDR_I64:
  case R_WASM_MEMORY_ADDR_TLS_SLEB:
  case R_WASM_MEMORY_ADDR_TLS_SLEB64:
  case R_WASM_MEMORY_ADDR_LOCREL_I32:
  case R_WASM_MEMORY_ADDR_LOCREL_I64: {
    if (isa<UndefinedData>(sym) || sym->isShared() || sym->isUndefWeak())
      return 0;
    auto D = cast<DefinedData>(sym);
    uint64_t value = D->getVA() + reloc.Addend;
    if (reloc.Type == R_WASM_MEMORY_ADDR_LOCREL_I32 ||
        reloc.Type == R_WASM_MEMORY_ADDR_LOCREL_I64) {
      const auto *segment = cast<InputSegment>(chunk);
      uint64_t p = segment->outputSeg->startVA + segment->outputSegmentOffset +
                   reloc.Offset - segment->getInputSectionOffset();
      value -= p;
    }
    return value;
  }
  case R_WASM_TYPE_INDEX_LEB:
    return typeMap[reloc.Index];
  case R_WASM_FUNCTION_INDEX_LEB:
  case R_WASM_FUNCTION_INDEX_I32:
    return getFunctionSymbol(reloc.Index)->getFunctionIndex();
  case R_WASM_GLOBAL_INDEX_LEB:
  case R_WASM_GLOBAL_INDEX_I32:
    if (auto gs = dyn_cast<GlobalSymbol>(sym))
      return gs->getGlobalIndex();
    return sym->getGOTIndex();
  case R_WASM_TAG_INDEX_LEB:
    return getTagSymbol(reloc.Index)->getTagIndex();
  case R_WASM_FUNCTION_OFFSET_I32:
  case R_WASM_FUNCTION_OFFSET_I64: {
    if (isa<UndefinedFunction>(sym) || sym->isShared()) {
      return tombstone ? tombstone : reloc.Addend;
    }
    auto *f = cast<DefinedFunction>(sym);
    return f->function->getOffset(f->function->getFunctionCodeOffset() +
                                  reloc.Addend);
  }
  case R_WASM_SECTION_OFFSET_I32:
    return getSectionSymbol(reloc.Index)->section->getOffset(reloc.Addend);
  case R_WASM_TABLE_NUMBER_LEB:
    return getTableSymbol(reloc.Index)->getTableNumber();
  default:
    llvm_unreachable("unknown relocation type");
  }
}

template <class T>
static void setRelocs(const std::vector<T *> &chunks,
                      const WasmSection *section) {
  if (!section)
    return;

  ArrayRef<WasmRelocation> relocs = section->Relocations;
  assert(llvm::is_sorted(
      relocs, [](const WasmRelocation &r1, const WasmRelocation &r2) {
        return r1.Offset < r2.Offset;
      }));
  assert(llvm::is_sorted(chunks, [](InputChunk *c1, InputChunk *c2) {
    return c1->getInputSectionOffset() < c2->getInputSectionOffset();
  }));

  auto relocsNext = relocs.begin();
  auto relocsEnd = relocs.end();
  auto relocLess = [](const WasmRelocation &r, uint32_t val) {
    return r.Offset < val;
  };
  for (InputChunk *c : chunks) {
    auto relocsStart = std::lower_bound(relocsNext, relocsEnd,
                                        c->getInputSectionOffset(), relocLess);
    relocsNext = std::lower_bound(
        relocsStart, relocsEnd, c->getInputSectionOffset() + c->getInputSize(),
        relocLess);
    c->setRelocations(ArrayRef<WasmRelocation>(relocsStart, relocsNext));
  }
}

// An object file can have two approaches to tables.  With the
// reference-types feature or call-indirect-overlong feature enabled
// (explicitly, or implied by the reference-types feature), input files that
// define or use tables declare the tables using symbols, and record each use
// with a relocation.  This way when the linker combines inputs, it can collate
// the tables used by the inputs, assigning them distinct table numbers, and
// renumber all the uses as appropriate.  At the same time, the linker has
// special logic to build the indirect function table if it is needed.
//
// However, MVP object files (those that target WebAssembly 1.0, the "minimum
// viable product" version of WebAssembly) neither write table symbols nor
// record relocations.  These files can have at most one table, the indirect
// function table used by call_indirect and which is the address space for
// function pointers.  If this table is present, it is always an import.  If we
// have a file with a table import but no table symbols, it is an MVP object
// file.  synthesizeMVPIndirectFunctionTableSymbolIfNeeded serves as a shim when
// loading these input files, defining the missing symbol to allow the indirect
// function table to be built.
//
// As indirect function table table usage in MVP objects cannot be relocated,
// the linker must ensure that this table gets assigned index zero.
void ObjFile::addLegacyIndirectFunctionTableIfNeeded(
    uint32_t tableSymbolCount) {
  uint32_t tableCount = wasmObj->getNumImportedTables() + tables.size();

  // If there are symbols for all tables, then all is good.
  if (tableCount == tableSymbolCount)
    return;

  // It's possible for an input to define tables and also use the indirect
  // function table, but forget to compile with -mattr=+call-indirect-overlong
  // or -mattr=+reference-types. For these newer files, we require symbols for
  // all tables, and relocations for all of their uses.
  if (tableSymbolCount != 0) {
    error(toString(this) +
          ": expected one symbol table entry for each of the " +
          Twine(tableCount) + " table(s) present, but got " +
          Twine(tableSymbolCount) + " symbol(s) instead.");
    return;
  }

  // An MVP object file can have up to one table import, for the indirect
  // function table, but will have no table definitions.
  if (tables.size()) {
    error(toString(this) +
          ": unexpected table definition(s) without corresponding "
          "symbol-table entries.");
    return;
  }

  // An MVP object file can have only one table import.
  if (tableCount != 1) {
    error(toString(this) +
          ": multiple table imports, but no corresponding symbol-table "
          "entries.");
    return;
  }

  const WasmImport *tableImport = nullptr;
  for (const auto &import : wasmObj->imports()) {
    if (import.Kind == WASM_EXTERNAL_TABLE) {
      assert(!tableImport);
      tableImport = &import;
    }
  }
  assert(tableImport);

  // We can only synthesize a symtab entry for the indirect function table; if
  // it has an unexpected name or type, assume that it's not actually the
  // indirect function table.
  if (tableImport->Field != functionTableName ||
      tableImport->Table.ElemType != ValType::FUNCREF) {
    error(toString(this) + ": table import " + Twine(tableImport->Field) +
          " is missing a symbol table entry.");
    return;
  }

  WasmSymbolInfo info;
  info.Name = tableImport->Field;
  info.Kind = WASM_SYMBOL_TYPE_TABLE;
  info.ImportModule = tableImport->Module;
  info.ImportName = tableImport->Field;
  info.Flags = WASM_SYMBOL_UNDEFINED | WASM_SYMBOL_NO_STRIP;
  info.ElementIndex = 0;
  LLVM_DEBUG(dbgs() << "Synthesizing symbol for table import: " << info.Name
                    << "\n");
  const WasmGlobalType *globalType = nullptr;
  const WasmSignature *signature = nullptr;
  auto *wasmSym =
      make<WasmSymbol>(info, globalType, &tableImport->Table, signature);
  Symbol *sym = createUndefined(*wasmSym, false);
  // We're only sure it's a TableSymbol if the createUndefined succeeded.
  if (errorCount())
    return;
  symbols.push_back(sym);
  // Because there are no TABLE_NUMBER relocs, we can't compute accurate
  // liveness info; instead, just mark the symbol as always live.
  sym->markLive();

  // We assume that this compilation unit has unrelocatable references to
  // this table.
  ctx.legacyFunctionTable = true;
}

static bool shouldMerge(const WasmSection &sec) {
  if (ctx.arg.optimize == 0)
    return false;
  // Sadly we don't have section attributes yet for custom sections, so we
  // currently go by the name alone.
  // TODO(sbc): Add ability for wasm sections to carry flags so we don't
  // need to use names here.
  // For now, keep in sync with uses of wasm::WASM_SEG_FLAG_STRINGS in
  // MCObjectFileInfo::initWasmMCObjectFileInfo which creates these custom
  // sections.
  return sec.Name == ".debug_str" || sec.Name == ".debug_str.dwo" ||
         sec.Name == ".debug_line_str";
}

static bool shouldMerge(const WasmSegment &seg) {
  // As of now we only support merging strings, and only with single byte
  // alignment (2^0).
  if (!(seg.Data.LinkingFlags & WASM_SEG_FLAG_STRINGS) ||
      (seg.Data.Alignment != 0))
    return false;

  // On a regular link we don't merge sections if -O0 (default is -O1). This
  // sometimes makes the linker significantly faster, although the output will
  // be bigger.
  if (ctx.arg.optimize == 0)
    return false;

  // A mergeable section with size 0 is useless because they don't have
  // any data to merge. A mergeable string section with size 0 can be
  // argued as invalid because it doesn't end with a null character.
  // We'll avoid a mess by handling them as if they were non-mergeable.
  if (seg.Data.Content.size() == 0)
    return false;

  return true;
}

void ObjFile::parseLazy() {
  LLVM_DEBUG(dbgs() << "ObjFile::parseLazy: " << toString(this) << " "
                    << wasmObj.get() << "\n");
  for (const SymbolRef &sym : wasmObj->symbols()) {
    const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
    if (wasmSym.isUndefined() || wasmSym.isBindingLocal())
      continue;
    symtab->addLazy(wasmSym.Info.Name, this);
    // addLazy() may trigger this->extract() if an existing symbol is an
    // undefined symbol. If that happens, this function has served its purpose,
    // and we can exit from the loop early.
    if (!lazy)
      break;
  }
}

ObjFile::ObjFile(MemoryBufferRef m, StringRef archiveName, bool lazy)
    : WasmFileBase(ObjectKind, m) {
  this->lazy = lazy;
  this->archiveName = std::string(archiveName);

  // Unless we are processing this as a lazy object file (e.g. part of an
  // archive file or within `--start-lib`/`--end-lib`, it's eagerly linked, so
  // mark it live.
  if (!lazy)
    markLive();
}

void SharedFile::parse() {
  assert(wasmObj->isSharedObject());

  for (const SymbolRef &sym : wasmObj->symbols()) {
    const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
    if (wasmSym.isDefined()) {
      StringRef name = wasmSym.Info.Name;
      // Certain shared library exports are known to be DSO-local so we
      // don't want to add them to the symbol table.
      // TODO(sbc): Instead of hardcoding these here perhaps we could add
      // this as extra metadata in the `dylink` section.
      if (name == "__wasm_apply_data_relocs" || name == "__wasm_call_ctors" ||
          name.starts_with("__start_") || name.starts_with("__stop_"))
        continue;
      uint32_t flags = wasmSym.Info.Flags;
      Symbol *s;
      LLVM_DEBUG(dbgs() << "shared symbol: " << name << "\n");
      switch (wasmSym.Info.Kind) {
      case WASM_SYMBOL_TYPE_FUNCTION:
        s = symtab->addSharedFunction(name, flags, this, wasmSym.Signature);
        break;
      case WASM_SYMBOL_TYPE_DATA:
        s = symtab->addSharedData(name, flags, this);
        break;
      case WASM_SYMBOL_TYPE_TAG:
        s = symtab->addSharedTag(name, flags, this, wasmSym.Signature);
        break;
      default:
        continue;
      }
      symbols.push_back(s);
    }
  }
}

// Returns the alignment for a custom section. This is used to concatenate
// custom sections with the same name into a single custom section.
static uint32_t getCustomSectionAlignment(const WasmSection &sec) {
  // TODO: Add a section attribute for alignment in the linking spec.
  if (sec.Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm) ||
      sec.Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm)) {
    // llvm-cov assumes that coverage metadata sections are 8-byte aligned.
    return 8;
  }
  return 1;
}

WasmFileBase::WasmFileBase(Kind k, MemoryBufferRef m) : InputFile(k, m) {
  // Parse a memory buffer as a wasm file.
  LLVM_DEBUG(dbgs() << "Reading object: " << toString(this) << "\n");
  std::unique_ptr<Binary> bin = CHECK(createBinary(mb), toString(this));

  auto *obj = dyn_cast<WasmObjectFile>(bin.get());
  if (!obj)
    fatal(toString(this) + ": not a wasm file");

  bin.release();
  wasmObj.reset(obj);

  checkArch(wasmObj->getArch());
}

void ObjFile::parse(bool ignoreComdats) {
  // Parse a memory buffer as a wasm file.
  LLVM_DEBUG(dbgs() << "ObjFile::parse: " << toString(this) << "\n");

  if (!wasmObj->isRelocatableObject())
    fatal(toString(this) + ": not a relocatable wasm file");

  // Build up a map of function indices to table indices for use when
  // verifying the existing table index relocations
  uint32_t totalFunctions =
      wasmObj->getNumImportedFunctions() + wasmObj->functions().size();
  tableEntriesRel.resize(totalFunctions);
  tableEntries.resize(totalFunctions);
  for (const WasmElemSegment &seg : wasmObj->elements()) {
    int64_t offset;
    if (seg.Offset.Extended)
      fatal(toString(this) + ": extended init exprs not supported");
    else if (seg.Offset.Inst.Opcode == WASM_OPCODE_I32_CONST)
      offset = seg.Offset.Inst.Value.Int32;
    else if (seg.Offset.Inst.Opcode == WASM_OPCODE_I64_CONST)
      offset = seg.Offset.Inst.Value.Int64;
    else
      fatal(toString(this) + ": invalid table elements");
    for (size_t index = 0; index < seg.Functions.size(); index++) {
      auto functionIndex = seg.Functions[index];
      tableEntriesRel[functionIndex] = index;
      tableEntries[functionIndex] = offset + index;
    }
  }

  ArrayRef<StringRef> comdats = wasmObj->linkingData().Comdats;
  for (StringRef comdat : comdats) {
    bool isNew = ignoreComdats || symtab->addComdat(comdat);
    keptComdats.push_back(isNew);
  }

  uint32_t sectionIndex = 0;

  // Bool for each symbol, true if called directly.  This allows us to implement
  // a weaker form of signature checking where undefined functions that are not
  // called directly (i.e. only address taken) don't have to match the defined
  // function's signature.  We cannot do this for directly called functions
  // because those signatures are checked at validation times.
  // See https://github.com/llvm/llvm-project/issues/39758
  std::vector<bool> isCalledDirectly(wasmObj->getNumberOfSymbols(), false);
  for (const SectionRef &sec : wasmObj->sections()) {
    const WasmSection &section = wasmObj->getWasmSection(sec);
    // Wasm objects can have at most one code and one data section.
    if (section.Type == WASM_SEC_CODE) {
      assert(!codeSection);
      codeSection = &section;
    } else if (section.Type == WASM_SEC_DATA) {
      assert(!dataSection);
      dataSection = &section;
    } else if (section.Type == WASM_SEC_CUSTOM) {
      InputChunk *customSec;
      uint32_t alignment = getCustomSectionAlignment(section);
      if (shouldMerge(section))
        customSec = make<MergeInputChunk>(section, this, alignment);
      else
        customSec = make<InputSection>(section, this, alignment);
      customSec->discarded = isExcludedByComdat(customSec);
      customSections.emplace_back(customSec);
      customSections.back()->setRelocations(section.Relocations);
      customSectionsByIndex[sectionIndex] = customSections.back();
    }
    sectionIndex++;
    // Scans relocations to determine if a function symbol is called directly.
    for (const WasmRelocation &reloc : section.Relocations)
      if (reloc.Type == R_WASM_FUNCTION_INDEX_LEB)
        isCalledDirectly[reloc.Index] = true;
  }

  typeMap.resize(getWasmObj()->types().size());
  typeIsUsed.resize(getWasmObj()->types().size(), false);

  // Populate `Segments`.
  for (const WasmSegment &s : wasmObj->dataSegments()) {
    InputChunk *seg;
    if (shouldMerge(s))
      seg = make<MergeInputChunk>(s, this);
    else
      seg = make<InputSegment>(s, this);
    seg->discarded = isExcludedByComdat(seg);
    // Older object files did not include WASM_SEG_FLAG_TLS and instead
    // relied on the naming convention.  To maintain compat with such objects
    // we still imply the TLS flag based on the name of the segment.
    if (!seg->isTLS() &&
        (seg->name.starts_with(".tdata") || seg->name.starts_with(".tbss")))
      seg->flags |= WASM_SEG_FLAG_TLS;
    segments.emplace_back(seg);
  }
  setRelocs(segments, dataSection);

  // Populate `Functions`.
  ArrayRef<WasmFunction> funcs = wasmObj->functions();
  ArrayRef<WasmSignature> types = wasmObj->types();
  functions.reserve(funcs.size());

  for (auto &f : funcs) {
    auto *func = make<InputFunction>(types[f.SigIndex], &f, this);
    func->discarded = isExcludedByComdat(func);
    functions.emplace_back(func);
  }
  setRelocs(functions, codeSection);

  // Populate `Tables`.
  for (const WasmTable &t : wasmObj->tables())
    tables.emplace_back(make<InputTable>(t, this));

  // Populate `Globals`.
  for (const WasmGlobal &g : wasmObj->globals())
    globals.emplace_back(make<InputGlobal>(g, this));

  // Populate `Tags`.
  for (const WasmTag &t : wasmObj->tags())
    tags.emplace_back(make<InputTag>(types[t.SigIndex], t, this));

  // Populate `Symbols` based on the symbols in the object.
  symbols.reserve(wasmObj->getNumberOfSymbols());
  uint32_t tableSymbolCount = 0;
  for (const SymbolRef &sym : wasmObj->symbols()) {
    const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
    if (wasmSym.isTypeTable())
      tableSymbolCount++;
    if (wasmSym.isDefined()) {
      // createDefined may fail if the symbol is comdat excluded in which case
      // we fall back to creating an undefined symbol
      if (Symbol *d = createDefined(wasmSym)) {
        symbols.push_back(d);
        continue;
      }
    }
    size_t idx = symbols.size();
    symbols.push_back(createUndefined(wasmSym, isCalledDirectly[idx]));
  }

  addLegacyIndirectFunctionTableIfNeeded(tableSymbolCount);
}

bool ObjFile::isExcludedByComdat(const InputChunk *chunk) const {
  uint32_t c = chunk->getComdat();
  if (c == UINT32_MAX)
    return false;
  return !keptComdats[c];
}

FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t index) const {
  return cast<FunctionSymbol>(symbols[index]);
}

GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t index) const {
  return cast<GlobalSymbol>(symbols[index]);
}

TagSymbol *ObjFile::getTagSymbol(uint32_t index) const {
  return cast<TagSymbol>(symbols[index]);
}

TableSymbol *ObjFile::getTableSymbol(uint32_t index) const {
  return cast<TableSymbol>(symbols[index]);
}

SectionSymbol *ObjFile::getSectionSymbol(uint32_t index) const {
  return cast<SectionSymbol>(symbols[index]);
}

DataSymbol *ObjFile::getDataSymbol(uint32_t index) const {
  return cast<DataSymbol>(symbols[index]);
}

Symbol *ObjFile::createDefined(const WasmSymbol &sym) {
  StringRef name = sym.Info.Name;
  uint32_t flags = sym.Info.Flags;

  switch (sym.Info.Kind) {
  case WASM_SYMBOL_TYPE_FUNCTION: {
    InputFunction *func =
        functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()];
    if (sym.isBindingLocal())
      return make<DefinedFunction>(name, flags, this, func);
    if (func->discarded)
      return nullptr;
    return symtab->addDefinedFunction(name, flags, this, func);
  }
  case WASM_SYMBOL_TYPE_DATA: {
    if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_COMMON) {
      assert(!sym.isBindingLocal());
      auto size = sym.Info.CommonRef.Size;
      auto alignment = sym.Info.CommonRef.Alignment;
      return symtab->addCommon(name, flags, this, size, alignment);
    }
    InputChunk *seg = segments[sym.Info.DataRef.Segment];
    auto offset = sym.Info.DataRef.Offset;
    auto size = sym.Info.DataRef.Size;
    // Support older (e.g. llvm 13) object files that pre-date the per-symbol
    // TLS flag, and symbols were assumed to be TLS by being defined in a TLS
    // segment.
    if (!(flags & WASM_SYMBOL_TLS) && seg->isTLS())
      flags |= WASM_SYMBOL_TLS;
    if (sym.isBindingLocal())
      return make<DefinedData>(name, flags, this, seg, offset, size);
    if (seg->discarded)
      return nullptr;
    return symtab->addDefinedData(name, flags, this, seg, offset, size);
  }
  case WASM_SYMBOL_TYPE_GLOBAL: {
    InputGlobal *global =
        globals[sym.Info.ElementIndex - wasmObj->getNumImportedGlobals()];
    if (sym.isBindingLocal())
      return make<DefinedGlobal>(name, flags, this, global);
    return symtab->addDefinedGlobal(name, flags, this, global);
  }
  case WASM_SYMBOL_TYPE_SECTION: {
    InputChunk *section = customSectionsByIndex[sym.Info.ElementIndex];
    assert(sym.isBindingLocal());
    // Need to return null if discarded here? data and func only do that when
    // binding is not local.
    if (section->discarded)
      return nullptr;
    return make<SectionSymbol>(flags, section, this);
  }
  case WASM_SYMBOL_TYPE_TAG: {
    InputTag *tag = tags[sym.Info.ElementIndex - wasmObj->getNumImportedTags()];
    if (sym.isBindingLocal())
      return make<DefinedTag>(name, flags, this, tag);
    return symtab->addDefinedTag(name, flags, this, tag);
  }
  case WASM_SYMBOL_TYPE_TABLE: {
    InputTable *table =
        tables[sym.Info.ElementIndex - wasmObj->getNumImportedTables()];
    if (sym.isBindingLocal())
      return make<DefinedTable>(name, flags, this, table);
    return symtab->addDefinedTable(name, flags, this, table);
  }
  }
  llvm_unreachable("unknown symbol kind");
}

Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) {
  StringRef name = sym.Info.Name;
  uint32_t flags = sym.Info.Flags | WASM_SYMBOL_UNDEFINED;

  switch (sym.Info.Kind) {
  case WASM_SYMBOL_TYPE_FUNCTION:
    if (sym.isBindingLocal())
      return make<UndefinedFunction>(name, sym.Info.ImportName,
                                     sym.Info.ImportModule, flags, this,
                                     sym.Signature, isCalledDirectly);
    return symtab->addUndefinedFunction(name, sym.Info.ImportName,
                                        sym.Info.ImportModule, flags, this,
                                        sym.Signature, isCalledDirectly);
  case WASM_SYMBOL_TYPE_DATA:
    if (sym.isBindingLocal())
      return make<UndefinedData>(name, flags, this);
    return symtab->addUndefinedData(name, flags, this);
  case WASM_SYMBOL_TYPE_GLOBAL:
    if (sym.isBindingLocal())
      return make<UndefinedGlobal>(name, sym.Info.ImportName,
                                   sym.Info.ImportModule, flags, this,
                                   sym.GlobalType);
    return symtab->addUndefinedGlobal(name, sym.Info.ImportName,
                                      sym.Info.ImportModule, flags, this,
                                      sym.GlobalType);
  case WASM_SYMBOL_TYPE_TABLE:
    if (sym.isBindingLocal())
      return make<UndefinedTable>(name, sym.Info.ImportName,
                                  sym.Info.ImportModule, flags, this,
                                  sym.TableType);
    return symtab->addUndefinedTable(name, sym.Info.ImportName,
                                     sym.Info.ImportModule, flags, this,
                                     sym.TableType);
  case WASM_SYMBOL_TYPE_TAG:
    if (sym.isBindingLocal())
      return make<UndefinedTag>(name, sym.Info.ImportName,
                                sym.Info.ImportModule, flags, this,
                                sym.Signature);
    return symtab->addUndefinedTag(name, sym.Info.ImportName,
                                   sym.Info.ImportModule, flags, this,
                                   sym.Signature);
  case WASM_SYMBOL_TYPE_SECTION:
    llvm_unreachable("section symbols cannot be undefined");
  }
  llvm_unreachable("unknown symbol kind");
}

static StringRef strip(StringRef s) { return s.trim(' '); }

void StubFile::parse() {
  bool first = true;

  SmallVector<StringRef> lines;
  mb.getBuffer().split(lines, '\n');
  for (StringRef line : lines) {
    line = line.trim();

    // File must begin with #STUB
    if (first) {
      assert(line == "#STUB");
      first = false;
    }

    // Lines starting with # are considered comments
    if (line.starts_with("#") || !line.size())
      continue;

    StringRef sym;
    StringRef rest;
    std::tie(sym, rest) = line.split(':');
    sym = strip(sym);
    rest = strip(rest);

    symbolDependencies[sym] = {};

    while (rest.size()) {
      StringRef dep;
      std::tie(dep, rest) = rest.split(',');
      dep = strip(dep);
      symbolDependencies[sym].push_back(dep);
    }
  }
}

static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
  switch (gvVisibility) {
  case GlobalValue::DefaultVisibility:
    return WASM_SYMBOL_VISIBILITY_DEFAULT;
  case GlobalValue::HiddenVisibility:
  case GlobalValue::ProtectedVisibility:
    return WASM_SYMBOL_VISIBILITY_HIDDEN;
  }
  llvm_unreachable("unknown visibility");
}

static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
                                   const lto::InputFile::Symbol &objSym,
                                   BitcodeFile &f) {
  StringRef name = saver().save(objSym.getName());

  uint32_t flags = objSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0;
  flags |= mapVisibility(objSym.getVisibility());

  int c = objSym.getComdatIndex();
  bool excludedByComdat = c != -1 && !keptComdats[c];

  if (objSym.isUndefined() || excludedByComdat) {
    flags |= WASM_SYMBOL_UNDEFINED;
    if (objSym.isExecutable())
      return symtab->addUndefinedFunction(name, std::nullopt, std::nullopt,
                                          flags, &f, nullptr, true);
    return symtab->addUndefinedData(name, flags, &f);
  }

  if (objSym.isExecutable())
    return symtab->addDefinedFunction(name, flags, &f, nullptr);
  return symtab->addDefinedData(name, flags, &f, nullptr, 0, 0);
}

BitcodeFile::BitcodeFile(MemoryBufferRef m, StringRef archiveName,
                         uint64_t offsetInArchive, bool lazy)
    : InputFile(BitcodeKind, m) {
  this->lazy = lazy;
  this->archiveName = std::string(archiveName);

  std::string path = mb.getBufferIdentifier().str();
  if (ctx.arg.thinLTOIndexOnly)
    path = replaceThinLTOSuffix(mb.getBufferIdentifier());

  // ThinLTO assumes that all MemoryBufferRefs given to it have a unique
  // name. If two archives define two members with the same name, this
  // causes a collision which result in only one of the objects being taken
  // into consideration at LTO time (which very likely causes undefined
  // symbols later in the link stage). So we append file offset to make
  // filename unique.
  StringRef name = archiveName.empty()
                       ? saver().save(path)
                       : saver().save(archiveName + "(" + path::filename(path) +
                                      " at " + utostr(offsetInArchive) + ")");
  MemoryBufferRef mbref(mb.getBuffer(), name);

  obj = check(lto::InputFile::create(mbref));

  // If this isn't part of an archive, it's eagerly linked, so mark it live.
  if (archiveName.empty())
    markLive();
}

bool BitcodeFile::doneLTO = false;

void BitcodeFile::parseLazy() {
  for (auto [i, irSym] : llvm::enumerate(obj->symbols())) {
    if (irSym.isUndefined())
      continue;
    StringRef name = saver().save(irSym.getName());
    symtab->addLazy(name, this);
    // addLazy() may trigger this->extract() if an existing symbol is an
    // undefined symbol. If that happens, this function has served its purpose,
    // and we can exit from the loop early.
    if (!lazy)
      break;
  }
}

void BitcodeFile::parse(StringRef symName) {
  if (doneLTO) {
    error(toString(this) + ": attempt to add bitcode file after LTO (" +
          symName + ")");
    return;
  }

  Triple t(obj->getTargetTriple());
  if (!t.isWasm()) {
    error(toString(this) + ": machine type must be wasm32 or wasm64");
    return;
  }
  checkArch(t.getArch());
  std::vector<bool> keptComdats;
  // TODO Support nodeduplicate
  // https://github.com/llvm/llvm-project/issues/49875
  for (std::pair<StringRef, Comdat::SelectionKind> s : obj->getComdatTable())
    keptComdats.push_back(symtab->addComdat(s.first));

  for (const lto::InputFile::Symbol &objSym : obj->symbols())
    symbols.push_back(createBitcodeSymbol(keptComdats, objSym, *this));
}

} // namespace wasm
} // namespace lld
