//===----------------------------------------------------------------------===//
//
// 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 "ProcessWasm.h"
#include "ThreadWasm.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Utility/DataBufferHeap.h"

#include "lldb/Target/UnixSignals.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace lldb_private::wasm;

LLDB_PLUGIN_DEFINE(ProcessWasm)

ProcessWasm::ProcessWasm(lldb::TargetSP target_sp, ListenerSP listener_sp)
    : ProcessGDBRemote(target_sp, listener_sp) {
  assert(target_sp);
  // Wasm doesn't have any Unix-like signals as a platform concept, but pretend
  // like it does to appease LLDB.
  m_unix_signals_sp = UnixSignals::Create(target_sp->GetArchitecture());
  // FIXME: LLVM's RuntimeDyld doesn't support the Wasm object format, so we
  // can't JIT expressions for this target.
  SetCanJIT(false);
}

void ProcessWasm::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance,
                                DebuggerInitialize);
}

void ProcessWasm::DebuggerInitialize(Debugger &debugger) {
  ProcessGDBRemote::DebuggerInitialize(debugger);
}

llvm::StringRef ProcessWasm::GetPluginName() { return GetPluginNameStatic(); }

llvm::StringRef ProcessWasm::GetPluginNameStatic() { return "wasm"; }

llvm::StringRef ProcessWasm::GetPluginDescriptionStatic() {
  return "GDB Remote protocol based WebAssembly debugging plug-in.";
}

void ProcessWasm::Terminate() {
  PluginManager::UnregisterPlugin(ProcessWasm::CreateInstance);
}

lldb::ProcessSP ProcessWasm::CreateInstance(lldb::TargetSP target_sp,
                                            ListenerSP listener_sp,
                                            const FileSpec *crash_file_path,
                                            bool can_connect) {
  if (crash_file_path == nullptr)
    return std::make_shared<ProcessWasm>(target_sp, listener_sp);
  return {};
}

bool ProcessWasm::CanDebug(lldb::TargetSP target_sp,
                           bool plugin_specified_by_name) {
  if (plugin_specified_by_name)
    return true;

  if (Module *exe_module = target_sp->GetExecutableModulePointer()) {
    if (ObjectFile *exe_objfile = exe_module->GetObjectFile())
      return exe_objfile->GetArchitecture().GetMachine() ==
             llvm::Triple::wasm32;
  }

  // However, if there is no wasm module, we return false, otherwise,
  // we might use ProcessWasm to attach gdb remote.
  return false;
}

std::shared_ptr<ThreadGDBRemote> ProcessWasm::CreateThread(lldb::tid_t tid) {
  return std::make_shared<ThreadWasm>(*this, tid);
}

size_t ProcessWasm::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
                               Status &error) {
  wasm_addr_t wasm_addr(vm_addr);

  switch (wasm_addr.GetType()) {
  case WasmAddressType::Memory:
  case WasmAddressType::Object:
    return ProcessGDBRemote::ReadMemory(vm_addr, buf, size, error);
  case WasmAddressType::Invalid:
    break;
  }

  error.FromErrorStringWithFormatv(
      "Wasm read failed for invalid address {0:x} (type = {1:x}, module = "
      "{2:x}, offset = {3:x})",
      vm_addr, wasm_addr.GetType(), wasm_addr.GetModuleID(),
      wasm_addr.GetOffset());
  return 0;
}

llvm::Expected<std::vector<lldb::addr_t>>
ProcessWasm::GetWasmCallStack(lldb::tid_t tid) {
  StreamString packet;
  packet.Printf("qWasmCallStack:");
  packet.Printf("%" PRIx64, tid);

  StringExtractorGDBRemote response;
  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
      GDBRemoteCommunication::PacketResult::Success)
    return llvm::createStringError("failed to send qWasmCallStack");

  if (!response.IsNormalResponse())
    return llvm::createStringError("failed to get response for qWasmCallStack");

  WritableDataBufferSP data_buffer_sp =
      std::make_shared<DataBufferHeap>(response.GetStringRef().size() / 2, 0);
  const size_t bytes = response.GetHexBytes(data_buffer_sp->GetData(), '\xcc');
  if (bytes == 0 || bytes % sizeof(uint64_t) != 0)
    return llvm::createStringError("invalid response for qWasmCallStack");

  // To match the Wasm specification, the addresses are encoded in little endian
  // byte order.
  DataExtractor data(data_buffer_sp, lldb::eByteOrderLittle,
                     GetAddressByteSize());
  lldb::offset_t offset = 0;
  std::vector<lldb::addr_t> call_stack_pcs;
  while (offset < bytes)
    call_stack_pcs.push_back(data.GetU64(&offset));

  return call_stack_pcs;
}

llvm::Expected<lldb::DataBufferSP>
ProcessWasm::GetWasmVariable(WasmVirtualRegisterKinds kind, int frame_index,
                             int index) {
  StreamString packet;
  switch (kind) {
  case eWasmTagLocal:
    packet.Printf("qWasmLocal:");
    break;
  case eWasmTagGlobal:
    packet.Printf("qWasmGlobal:");
    break;
  case eWasmTagOperandStack:
    packet.PutCString("qWasmStackValue:");
    break;
  case eWasmTagNotAWasmLocation:
    return llvm::createStringError("not a Wasm location");
  }
  packet.Printf("%d;%d", frame_index, index);

  StringExtractorGDBRemote response;
  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
      GDBRemoteCommunication::PacketResult::Success)
    return llvm::createStringError("failed to send Wasm variable");

  if (!response.IsNormalResponse())
    return llvm::createStringError("failed to get response for Wasm variable");

  WritableDataBufferSP buffer_sp(
      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  return buffer_sp;
}
