//===----------------------------------------------------------------------===//
//
// 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/Target/StackFrame.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "llvm/Support/ErrorExtras.h"
#include <cstring>

#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::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().GetTriple().isWasm();
  }

  // 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) {
  if (!GetTarget().GetArchitecture().GetTriple().isWasm())
    return ProcessGDBRemote::CreateThread(tid);

  return std::make_shared<ThreadWasm>(*this, tid);
}

static size_t CopyGlobal(llvm::Expected<lldb::DataBufferSP> global, void *buf,
                         size_t size, Status &error) {
  if (!global) {
    error = Status::FromError(global.takeError());
    return 0;
  }

  // A global comes back whole. Reading more than it holds would have to come
  // from somewhere else, and the next index is not adjacent storage.
  const size_t global_size = (*global)->GetByteSize();
  if (size > global_size) {
    error = Status::FromErrorStringWithFormatv(
        "Wasm global read failed: requested {0} bytes from a {1}-byte global",
        size, global_size);
    return 0;
  }

  std::memcpy(buf, (*global)->GetBytes(), size);
  return size;
}

size_t ProcessWasm::ReadGlobal(uint32_t module_id, uint32_t index, void *buf,
                               size_t size, Status &error) {
  if (CanNameInstance(module_id))
    return CopyGlobal(GetWasmGlobalForModule(module_id, index), buf, size,
                      error);

  // Looking for a frame drives the unwinder, so only pay for it where the
  // instance cannot be named.
  llvm::Expected<uint32_t> frame_index = GetFallbackFrameIndex(module_id);
  if (!frame_index) {
    error = Status::FromError(frame_index.takeError());
    return 0;
  }

  return CopyGlobal(GetWasmGlobalForFrame(*frame_index, index), buf, size,
                    error);
}

llvm::Expected<uint32_t>
ProcessWasm::GetFallbackFrameIndex(uint32_t module_id) {
  if (module_id == kWasmInvalidModuleID)
    return llvm::createStringError(
        "the global belongs to no known module instance");

  ThreadSP thread = GetThreadList().GetSelectedThread();
  StackFrameSP frame =
      thread ? thread->GetSelectedFrame(DoNoSelectMostRelevantFrame) : nullptr;
  if (frame) {
    // A frame can only stand in for the module the stub reports it executing.
    const uint32_t frame_index = frame->GetConcreteFrameIndex();
    ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(*thread);
    if (GetWasmModuleID(wasm_thread.GetConcreteFramePC(frame_index)) ==
        module_id)
      return frame_index;
  }

  return llvm::createStringErrorV(
      "the Wasm stub can only read a global through a frame, and no frame is "
      "executing module {0:x}",
      module_id);
}

size_t ProcessWasm::ReadMemory(const ProcessAddress &process_addr, void *buf,
                               size_t size, Status &error) {
  // A caller may reuse one error across reads, as the overridden
  // Process::ReadMemory allows.
  error.Clear();

  lldb::addr_t vm_addr = process_addr.GetValue();
  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::Global:
    return ReadGlobal(wasm_addr.GetModuleID(), wasm_addr.GetOffset(), buf, size,
                      error);
  case WasmAddressType::Invalid:
    break;
  }

  error = Status::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::SendWasmValueQuery(llvm::StringRef packet) {
  StringExtractorGDBRemote response;
  if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) !=
      GDBRemoteCommunication::PacketResult::Success)
    return llvm::createStringErrorV("failed to send {0}", packet);

  if (!response.IsNormalResponse())
    return llvm::createStringErrorV("failed to get response for {0}", packet);

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

llvm::Expected<lldb::DataBufferSP>
ProcessWasm::GetWasmVariable(WasmVirtualRegisterKinds kind,
                             uint32_t frame_index, uint32_t index) {
  switch (kind) {
  case eWasmTagLocal:
    return SendWasmValueQuery(
        llvm::formatv("qWasmLocal:{0};{1}", frame_index, index).str());
  case eWasmTagOperandStack:
    return SendWasmValueQuery(
        llvm::formatv("qWasmStackValue:{0};{1}", frame_index, index).str());
  case eWasmTagGlobal:
    return llvm::createStringError("a Wasm global does not belong to a frame");
  case eWasmTagNotAWasmLocation:
    return llvm::createStringError("not a Wasm location");
  }
  llvm_unreachable("unhandled Wasm virtual register kind");
}

llvm::Expected<lldb::DataBufferSP>
ProcessWasm::GetWasmGlobalForModule(uint32_t module_id, uint32_t index) {
  return SendWasmValueQuery(
      llvm::formatv("qWasmGlobal:{0};instance:{1};", index, module_id).str());
}

llvm::Expected<lldb::DataBufferSP>
ProcessWasm::GetWasmGlobalForFrame(uint32_t frame_index, uint32_t index) {
  return SendWasmValueQuery(
      llvm::formatv("qWasmGlobal:{0};{1}", frame_index, index).str());
}

bool ProcessWasm::CanNameInstance(uint32_t module_id) {
  return module_id != kWasmInvalidModuleID &&
         m_gdb_comm.GetWasmInstanceSupported();
}
