//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/Error.h"
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <sstream>
#include <string>
#include <sys/ptrace.h>
#include <unistd.h>
#define DECLARE_REGISTER_INFOS_PPC64_STRUCT
#include "Plugins/Process/Utility/RegisterInfos_ppc64.h"
#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_aix;
using namespace llvm;

static constexpr unsigned k_ptrace_word_size = sizeof(void *);
static_assert(sizeof(long) >= k_ptrace_word_size,
              "Size of long must be larger than ptrace word size");

// Simple helper function to ensure flags are enabled on the given file
// descriptor.
static llvm::Error SetFDFlags(int fd, int flags) {
  int status = fcntl(fd, F_GETFL);
  if (status == -1)
    return errorCodeToError(errnoAsErrorCode());
  if (fcntl(fd, F_SETFL, status | flags) == -1)
    return errorCodeToError(errnoAsErrorCode());
  return Error::success();
}

NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
    : NativeProcessProtocol::Manager(mainloop) {
  Status status;
  m_sigchld_handle = mainloop.RegisterSignal(
      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
  assert(m_sigchld_handle && status.Success());
}

// Public Static Methods

llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
                                  NativeDelegate &native_delegate) {
  Log *log = GetLog(POSIXLog::Process);

  Status status;
  ::pid_t pid = ProcessLauncherPosixFork()
                    .LaunchProcess(launch_info, status)
                    .GetProcessId();
  LLDB_LOG(log, "pid = {0:x}", pid);
  if (status.Fail()) {
    LLDB_LOG(log, "failed to launch process: {0}", status);
    return status.ToError();
  }

  // Wait for the child process to trap on its call to execve.
  int wstatus = 0;
  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
  assert(wpid == pid);
  UNUSED_IF_ASSERT_DISABLED(wpid);
  if (!WIFSTOPPED(wstatus)) {
    LLDB_LOG(log, "Could not sync with inferior process: wstatus={0}",
             WaitStatus::Decode(wstatus));
    return llvm::createStringError("could not sync with inferior process");
  }
  LLDB_LOG(log, "inferior started, now in stopped state");

  ProcessInstanceInfo Info;
  if (!Host::GetProcessInfo(pid, Info)) {
    return llvm::make_error<StringError>("Cannot get process architecture",
                                         llvm::inconvertibleErrorCode());
  }

  // Set the architecture to the exe architecture.
  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
           Info.GetArchitecture().GetArchitectureName());

  return std::unique_ptr<NativeProcessAIX>(new NativeProcessAIX(
      pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
      Info.GetArchitecture(), *this, {pid}));
}

llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessAIX::Manager::Attach(
    lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
  Log *log = GetLog(POSIXLog::Process);
  LLDB_LOG(log, "pid = {0:x}", pid);

  auto tids_or = NativeProcessAIX::Attach(pid);
  if (!tids_or)
    return tids_or.takeError();

  return std::unique_ptr<NativeProcessAIX>(new NativeProcessAIX(
      pid, -1, native_delegate,
      HostInfo::GetArchitecture(HostInfo::eArchKind64), *this, *tids_or));
}

lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
  return LLDB_INVALID_ADDRESS;
}

static std::optional<std::pair<lldb::pid_t, WaitStatus>> WaitPid() {
  Log *log = GetLog(POSIXLog::Process);

  int status;
  ::pid_t wait_pid =
      llvm::sys::RetryAfterSignal(-1, ::waitpid, -1, &status, WNOHANG);

  if (wait_pid == 0)
    return std::nullopt;

  if (wait_pid == -1) {
    Status error(errno, eErrorTypePOSIX);
    LLDB_LOG(log, "waitpid(-1, &status, _) failed: {0}", error);
    return std::nullopt;
  }

  WaitStatus wait_status = WaitStatus::Decode(status);

  LLDB_LOG(log, "waitpid(-1, &status, _) = {0}, status = {1}", wait_pid,
           wait_status);
  return std::make_pair(wait_pid, wait_status);
}

void NativeProcessAIX::Manager::SigchldHandler() {
  while (true) {
    auto wait_result = WaitPid();
    if (!wait_result)
      return;
  }
}

void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}

// Public Instance Methods

NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
                                   NativeDelegate &delegate,
                                   const ArchSpec &arch, Manager &manager,
                                   llvm::ArrayRef<::pid_t> tids)
    : NativeProcessProtocol(pid, terminal_fd, delegate), m_manager(manager),
      m_arch(arch) {
  manager.AddProcess(*this);
  if (m_terminal_fd != -1)
    cantFail(SetFDFlags(m_terminal_fd, O_NONBLOCK));

  // Let our process instance know the thread has stopped.
  SetCurrentThreadID(tids[0]);
  SetState(StateType::eStateStopped, false);
}

llvm::Expected<std::vector<::pid_t>> NativeProcessAIX::Attach(::pid_t pid) {
  Log *log = GetLog(POSIXLog::Process);
  Status status;
  if (llvm::Error err = PtraceWrapper(PT_ATTACH, pid).takeError())
    return err;

  int wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, nullptr, WNOHANG);
  if (wpid <= 0)
    return llvm::errorCodeToError(errnoAsErrorCode());
  LLDB_LOG(log, "adding pid = {0}", pid);

  return std::vector<::pid_t>{pid};
}

bool NativeProcessAIX::SupportHardwareSingleStepping() const { return false; }

Status NativeProcessAIX::Resume(const ResumeActionList &resume_actions) {
  return Status("unsupported");
}

Status NativeProcessAIX::Halt() { return Status("unsupported"); }

Status NativeProcessAIX::Detach() { return Status("unsupported"); }

Status NativeProcessAIX::Signal(int signo) { return Status("unsupported"); }

Status NativeProcessAIX::Interrupt() { return Status("unsupported"); }

Status NativeProcessAIX::Kill() {

  Log *log = GetLog(POSIXLog::Process);
  LLDB_LOG(log, "pid {0}", GetID());

  Status error;

  switch (m_state) {
  case StateType::eStateInvalid:
  case StateType::eStateExited:
  case StateType::eStateCrashed:
  case StateType::eStateDetached:
  case StateType::eStateUnloaded:
    // Nothing to do - the process is already dead.
    LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
             m_state);
    return error;

  case StateType::eStateConnected:
  case StateType::eStateAttaching:
  case StateType::eStateLaunching:
  case StateType::eStateStopped:
  case StateType::eStateRunning:
  case StateType::eStateStepping:
  case StateType::eStateSuspended:
    // We can try to kill a process in these states.
    break;
  }

  llvm::Expected<int> result =
      PtraceWrapper(PT_KILL, GetID(), nullptr, nullptr, 0);
  if (!result) {
    std::string error_string = std::string("Kill failed for process. error: ") +
                               llvm::toString(result.takeError());
    error.FromErrorString(error_string.c_str());
  }
  return error;
}

Status NativeProcessAIX::ReadMemory(const ProcessAddress &process_addr,
                                    void *buf, size_t size,
                                    size_t &bytes_read) {
  return Status("unsupported");
}

Status NativeProcessAIX::DoWriteMemory(lldb::addr_t addr, const void *buf,
                                       size_t size, size_t &bytes_written) {
  return Status("unsupported");
}

size_t NativeProcessAIX::UpdateThreads() {
  // The NativeProcessAIX monitoring threads are always up to date with
  // respect to thread state and they keep the thread list populated properly.
  // All this method needs to do is return the thread count.
  return m_threads.size();
}

Status NativeProcessAIX::GetFileLoadAddress(const llvm::StringRef &file_name,
                                            lldb::addr_t &load_addr) {
  return Status("unsupported");
}

Status NativeProcessAIX::GetLoadedModuleFileSpec(const char *module_path,
                                                 FileSpec &file_spec) {
  return Status("unsupported");
}

Status NativeProcessAIX::SetBreakpoint(lldb::addr_t addr, uint32_t size,
                                       bool hardware) {
  if (hardware)
    return SetHardwareBreakpoint(addr, size);
  return SetSoftwareBreakpoint(addr, size);
}

Status NativeProcessAIX::RemoveBreakpoint(lldb::addr_t addr, bool hardware) {
  if (hardware)
    return RemoveHardwareBreakpoint(addr);
  return NativeProcessProtocol::RemoveBreakpoint(addr);
}

llvm::Error NativeProcessAIX::Detach(lldb::tid_t tid) {
  return PtraceWrapper(PT_DETACH, tid).takeError();
}

template <typename GPR_T, typename PTSPRS_T>
int GetSPRs(int req, lldb::tid_t tid, GPR_T *gpr) {
  PTSPRS_T sprs;

  int ret = ptrace64(req, tid, reinterpret_cast<long long>(&sprs), 0, 0);

  if (ret != -1) {
    gpr->cr = sprs.pt_cr;
    gpr->msr = sprs.pt_msr;
    gpr->xer = sprs.pt_xer;
    gpr->lr = sprs.pt_lr;
    gpr->ctr = sprs.pt_ctr;
    gpr->pc = sprs.pt_iar;
  }
  return ret;
}

template <typename GPR_T, typename PTSPRS_T>
int SetSPRs(int req, lldb::tid_t tid, GPR_T *gpr) {
  PTSPRS_T sprs;

  sprs.pt_cr = gpr->cr;
  sprs.pt_msr = gpr->msr;
  sprs.pt_xer = gpr->xer;
  sprs.pt_lr = gpr->lr;
  sprs.pt_ctr = gpr->ctr;
  sprs.pt_iar = gpr->pc;

  return ptrace64(req, tid, reinterpret_cast<long long>(&sprs), 0, 0);
}

llvm::Expected<int> NativeProcessAIX::PtraceWrapper(int req, lldb::pid_t pid,
                                                    void *addr, void *data,
                                                    size_t data_size) {
  int ret = 0;
  Log *log = GetLog(POSIXLog::Ptrace);
  // PTT_* requests require a thread ID (TID).
  // Each entry under /proc/<pid>/lwp/ represents a thread,
  // and the directory name corresponds to its thread ID (TID).
  // A process may contain multiple threads.
  // TODO: With multi-threading support, iterate over all entries to enumerate
  // available TIDs and retrieve the target debugging thread ID.
  llvm::SmallString<128> proc_lwp_dir;
  llvm::sys::path::append(proc_lwp_dir, "/proc/", std::to_string(pid), "/lwp/");

  lldb::tid_t tid = 0;
  std::error_code ec;
  bool result;
  if (!llvm::sys::fs::is_directory(proc_lwp_dir, result) && result) {
    for (sys::fs::directory_iterator it(proc_lwp_dir, ec), end;
         it != end && !ec; it.increment(ec)) {
      llvm::StringRef name = llvm::sys::path::filename(it->path());

      if (name == "." || name == "..")
        continue;

      if (!name.getAsInteger(10, tid)) {
        break;
      }
    }
  }

  switch (req) {
  // On AIX, ptrace exposes differently. GPRs and SPRs are handled via separate
  // requests: PTT_READ_GPRS reads only GPRs & PTT_READ_SPRS is required to
  // fetch SPRs. Similarly, writes are also split across:
  // PTT_WRITE_GPRS & PTT_WRITE_SPRS.
  case PTT_READ_GPRS:
    if (data_size == sizeof(GPR_PPC)) // 32bit SPRs read
      ret = GetSPRs<GPR_PPC, ptsprs>(PTT_READ_SPRS, tid,
                                     static_cast<GPR_PPC *>(data));
    else if (data_size == sizeof(GPR_PPC64)) // 64bit SPRs read
      ret = GetSPRs<GPR_PPC64, ptxsprs>(PTT_READ_SPRS, tid,
                                        static_cast<GPR_PPC64 *>(data));

    if (ret != -1)
      ret = ptrace64(req, tid, reinterpret_cast<long long>(data), 0,
                     0); // read GPRs
    break;

  case PTT_WRITE_GPRS:
    if (data_size == sizeof(GPR_PPC)) // 32bit SPRs write
      ret = SetSPRs<GPR_PPC, ptsprs>(PTT_WRITE_SPRS, tid,
                                     static_cast<GPR_PPC *>(data));
    else if (data_size == sizeof(GPR_PPC64)) // 64bit SPRS write
      ret = SetSPRs<GPR_PPC64, ptxsprs>(PTT_WRITE_SPRS, tid,
                                        static_cast<GPR_PPC64 *>(data));

    if (ret != -1)
      ret = ptrace64(req, tid, reinterpret_cast<long long>(data), 0,
                     0); // write GPRs
    break;
  case PT_ATTACH:
  case PT_DETACH:
  case PT_KILL:
    ret = ptrace64(req, pid, 0, 0, nullptr);
    break;
  default:
    llvm_unreachable("PT_ request not supported yet.");
  }

  LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
           data_size, ret);

  if (ret == -1) {
    LLDB_LOG(log, "ptrace() failed");
    return llvm::errorCodeToError(errnoAsErrorCode());
  }
  return ret;
}
