//===-- 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_MBREL:
      assert(SymA.isData());
      return 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:
    llvm_unreachable("fixup_sleb128_i64 not implemented yet");
  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;
    return wasm::R_WASM_MEMORY_ADDR_LEB;
  case FK_Data_4:
    if (SymA.isFunction())
      return wasm::R_WASM_TABLE_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;
  default:
    llvm_unreachable("unimplemented fixup kind");
  }
}

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