//===- Relocations.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 "Relocations.h"

#include "InputChunks.h"
#include "SyntheticSections.h"

using namespace llvm;
using namespace llvm::wasm;

namespace lld {
namespace wasm {
static bool requiresGOTAccess(const Symbol *sym) {
  return config->isPic && !sym->isHidden() && !sym->isLocal();
}

static bool allowUndefined(const Symbol* sym) {
  // Undefined functions with explicit import name are allowed to be undefined
  // at link time.
  if (auto *F = dyn_cast<UndefinedFunction>(sym))
    if (F->importName)
      return true;
  return (config->allowUndefined ||
          config->allowUndefinedSymbols.count(sym->getName()) != 0);
}

static void reportUndefined(const Symbol* sym) {
  assert(sym->isUndefined());
  assert(!sym->isWeak());
  if (!allowUndefined(sym))
    error(toString(sym->getFile()) + ": undefined symbol: " + toString(*sym));
}

static void addGOTEntry(Symbol *sym) {
  // In PIC mode a GOT entry is an imported global that the dynamic linker
  // will assign.
  // In non-PIC mode (i.e. when code compiled as fPIC is linked into a static
  // binary) we create an internal wasm global with a fixed value that takes the
  // place of th GOT entry and effectivly acts as an i32 const. This can
  // potentially be optimized away at runtime or with a post-link tool.
  // TODO(sbc): Linker relaxation might also be able to optimize this away.
  if (config->isPic)
    out.importSec->addGOTEntry(sym);
  else
    out.globalSec->addStaticGOTEntry(sym);
}

void scanRelocations(InputChunk *chunk) {
  if (!chunk->live)
    return;
  ObjFile *file = chunk->file;
  ArrayRef<WasmSignature> types = file->getWasmObj()->types();
  for (const WasmRelocation &reloc : chunk->getRelocations()) {
    if (reloc.Type == R_WASM_TYPE_INDEX_LEB) {
      // Mark target type as live
      file->typeMap[reloc.Index] =
          out.typeSec->registerType(types[reloc.Index]);
      file->typeIsUsed[reloc.Index] = true;
      continue;
    }

    // Other relocation types all have a corresponding symbol
    Symbol *sym = file->getSymbols()[reloc.Index];

    switch (reloc.Type) {
    case R_WASM_TABLE_INDEX_I32:
    case R_WASM_TABLE_INDEX_SLEB:
    case R_WASM_TABLE_INDEX_REL_SLEB:
      if (requiresGOTAccess(sym))
        break;
      out.elemSec->addEntry(cast<FunctionSymbol>(sym));
      break;
    case R_WASM_GLOBAL_INDEX_LEB:
    case R_WASM_GLOBAL_INDEX_I32:
      if (!isa<GlobalSymbol>(sym))
        addGOTEntry(sym);
      break;
    }

    if (config->isPic) {
      switch (reloc.Type) {
      case R_WASM_TABLE_INDEX_SLEB:
      case R_WASM_MEMORY_ADDR_SLEB:
      case R_WASM_MEMORY_ADDR_LEB:
      case R_WASM_MEMORY_ADDR_SLEB64:
      case R_WASM_MEMORY_ADDR_LEB64:
        // Certain relocation types can't be used when building PIC output,
        // since they would require absolute symbol addresses at link time.
        error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
              " cannot be used against symbol " + toString(*sym) +
              "; recompile with -fPIC");
        break;
      case R_WASM_TABLE_INDEX_I32:
      case R_WASM_MEMORY_ADDR_I32:
      case R_WASM_MEMORY_ADDR_I64:
        // These relocation types are only present in the data section and
        // will be converted into code by `generateRelocationCode`.  This code
        // requires the symbols to have GOT entires.
        if (requiresGOTAccess(sym))
          addGOTEntry(sym);
        break;
      }
    } else {
      // Report undefined symbols
      if (sym->isUndefined() && !config->relocatable && !sym->isWeak())
        reportUndefined(sym);
    }

  }
}

} // namespace wasm
} // namespace lld
