//===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file handles Wasm-specific object emission, converting LLVM's
/// internal fixups into the appropriate relocations.
///
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/WebAssemblyFixupKinds.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWasmObjectWriter.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

namespace {
class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
public:
  explicit WebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);

private:
  unsigned getRelocType(const MCValue &Target,
                        const MCFixup &Fixup) const override;
};
} // end anonymous namespace

WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit,
                                                         bool IsEmscripten)
    : MCWasmObjectTargetWriter(Is64Bit, IsEmscripten) {}

static const MCSection *getFixupSection(const MCExpr *Expr) {
  if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
    if (SyExp->getSymbol().isInSection())
      return &SyExp->getSymbol().getSection();
    return nullptr;
  }

  if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) {
    auto SectionLHS = getFixupSection(BinOp->getLHS());
    auto SectionRHS = getFixupSection(BinOp->getRHS());
    return SectionLHS == SectionRHS ? nullptr : SectionLHS;
  }

  if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
    return getFixupSection(UnOp->getSubExpr());

  return nullptr;
}

unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
                                                   const MCFixup &Fixup) const {
  const MCSymbolRefExpr *RefA = Target.getSymA();
  assert(RefA);
  auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol());

  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();

  switch (Modifier) {
    case MCSymbolRefExpr::VK_GOT:
      return wasm::R_WASM_GLOBAL_INDEX_LEB;
    case MCSymbolRefExpr::VK_WASM_TBREL:
      assert(SymA.isFunction());
      return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
    case MCSymbolRefExpr::VK_WASM_TLSREL:
      return wasm::R_WASM_MEMORY_ADDR_TLS_SLEB;
    case MCSymbolRefExpr::VK_WASM_MBREL:
      assert(SymA.isData());
      return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_REL_SLEB64
                       : wasm::R_WASM_MEMORY_ADDR_REL_SLEB;
    case MCSymbolRefExpr::VK_WASM_TYPEINDEX:
      return wasm::R_WASM_TYPE_INDEX_LEB;
    default:
      break;
  }

  switch (unsigned(Fixup.getKind())) {
  case WebAssembly::fixup_sleb128_i32:
    if (SymA.isFunction())
      return wasm::R_WASM_TABLE_INDEX_SLEB;
    return wasm::R_WASM_MEMORY_ADDR_SLEB;
  case WebAssembly::fixup_sleb128_i64:
    if (SymA.isFunction())
      return wasm::R_WASM_TABLE_INDEX_SLEB64;
    return wasm::R_WASM_MEMORY_ADDR_SLEB64;
  case WebAssembly::fixup_uleb128_i32:
    if (SymA.isGlobal())
      return wasm::R_WASM_GLOBAL_INDEX_LEB;
    if (SymA.isFunction())
      return wasm::R_WASM_FUNCTION_INDEX_LEB;
    if (SymA.isEvent())
      return wasm::R_WASM_EVENT_INDEX_LEB;
    if (SymA.isTable())
      return wasm::R_WASM_TABLE_NUMBER_LEB;
    return wasm::R_WASM_MEMORY_ADDR_LEB;
  case WebAssembly::fixup_uleb128_i64:
    assert(SymA.isData());
    return wasm::R_WASM_MEMORY_ADDR_LEB64;
  case FK_Data_4:
    if (SymA.isFunction())
      return wasm::R_WASM_TABLE_INDEX_I32;
    if (SymA.isGlobal())
      return wasm::R_WASM_GLOBAL_INDEX_I32;
    if (auto Section = static_cast<const MCSectionWasm *>(
            getFixupSection(Fixup.getValue()))) {
      if (Section->getKind().isText())
        return wasm::R_WASM_FUNCTION_OFFSET_I32;
      else if (!Section->isWasmData())
        return wasm::R_WASM_SECTION_OFFSET_I32;
    }
    return wasm::R_WASM_MEMORY_ADDR_I32;
  case FK_Data_8:
    if (SymA.isFunction())
      return wasm::R_WASM_TABLE_INDEX_I64;
    if (SymA.isGlobal())
      llvm_unreachable("unimplemented R_WASM_GLOBAL_INDEX_I64");
    if (auto Section = static_cast<const MCSectionWasm *>(
            getFixupSection(Fixup.getValue()))) {
      if (Section->getKind().isText())
        return wasm::R_WASM_FUNCTION_OFFSET_I64;
      else if (!Section->isWasmData())
        llvm_unreachable("unimplemented R_WASM_SECTION_OFFSET_I64");
    }
    assert(SymA.isData());
    return wasm::R_WASM_MEMORY_ADDR_I64;
  default:
    llvm_unreachable("unimplemented fixup kind");
  }
}

std::unique_ptr<MCObjectTargetWriter>
llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten) {
  return std::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit, IsEmscripten);
}
