//===-- NativeThreadFreeBSD.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 "NativeThreadFreeBSD.h"
#include "NativeRegisterContextFreeBSD.h"

#include "NativeProcessFreeBSD.h"

#include "Plugins/Process/POSIX/CrashReason.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/State.h"
#include "llvm/Support/Errno.h"

// clang-format off
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/sysctl.h>
#include <sys/user.h>
// clang-format on

#include <sstream>
#include <vector>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_freebsd;

NativeThreadFreeBSD::NativeThreadFreeBSD(NativeProcessFreeBSD &process,
                                         lldb::tid_t tid)
    : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
      m_reg_context_up(
          NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
              process.GetArchitecture(), *this)) {}

Status NativeThreadFreeBSD::Resume() {
  Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
  if (!ret.Success())
    return ret;
  ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID());
  // we can get EINVAL if the architecture in question does not support
  // hardware single-stepping -- that's fine, we have nothing to clear
  // then
  if (ret.GetError() == EINVAL)
    ret.Clear();
  if (ret.Success())
    SetRunning();
  return ret;
}

Status NativeThreadFreeBSD::SingleStep() {
  Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
  if (!ret.Success())
    return ret;
  ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, GetID());
  if (ret.Success())
    SetStepping();
  return ret;
}

Status NativeThreadFreeBSD::Suspend() {
  Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_SUSPEND, GetID());
  if (ret.Success())
    SetStopped();
  return ret;
}

void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo,
                                             const siginfo_t *info) {
  Log *log = GetLog(POSIXLog::Thread);
  LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);

  SetStopped();

  m_stop_info.reason = StopReason::eStopReasonSignal;
  m_stop_info.signo = signo;

  m_stop_description.clear();
  if (info) {
    switch (signo) {
    case SIGSEGV:
    case SIGBUS:
    case SIGFPE:
    case SIGILL:
      m_stop_description = GetCrashReasonString(*info);
      break;
    }
  }
}

void NativeThreadFreeBSD::SetStoppedByBreakpoint() {
  SetStopped();
  m_stop_info.reason = StopReason::eStopReasonBreakpoint;
  m_stop_info.signo = SIGTRAP;
}

void NativeThreadFreeBSD::SetStoppedByTrace() {
  SetStopped();
  m_stop_info.reason = StopReason::eStopReasonTrace;
  m_stop_info.signo = SIGTRAP;
}

void NativeThreadFreeBSD::SetStoppedByExec() {
  SetStopped();
  m_stop_info.reason = StopReason::eStopReasonExec;
  m_stop_info.signo = SIGTRAP;
}

void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
  lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");

  std::ostringstream ostr;
  ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
  ostr << wp_index;

  ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);

  SetStopped();
  m_stop_description = ostr.str();
  m_stop_info.reason = StopReason::eStopReasonWatchpoint;
  m_stop_info.signo = SIGTRAP;
}

void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid,
                                           lldb::tid_t child_tid) {
  SetStopped();

  m_stop_info.reason = StopReason::eStopReasonFork;
  m_stop_info.signo = SIGTRAP;
  m_stop_info.details.fork.child_pid = child_pid;
  m_stop_info.details.fork.child_tid = child_tid;
}

void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid,
                                            lldb::tid_t child_tid) {
  SetStopped();

  m_stop_info.reason = StopReason::eStopReasonVFork;
  m_stop_info.signo = SIGTRAP;
  m_stop_info.details.fork.child_pid = child_pid;
  m_stop_info.details.fork.child_tid = child_tid;
}

void NativeThreadFreeBSD::SetStoppedByVForkDone() {
  SetStopped();

  m_stop_info.reason = StopReason::eStopReasonVForkDone;
  m_stop_info.signo = SIGTRAP;
}

void NativeThreadFreeBSD::SetStoppedWithNoReason() {
  SetStopped();

  m_stop_info.reason = StopReason::eStopReasonNone;
  m_stop_info.signo = 0;
}

void NativeThreadFreeBSD::SetStopped() {
  const StateType new_state = StateType::eStateStopped;
  m_state = new_state;
  m_stop_description.clear();
}

void NativeThreadFreeBSD::SetRunning() {
  m_state = StateType::eStateRunning;
  ClearStopInfo();
}

void NativeThreadFreeBSD::SetStepping() {
  m_state = StateType::eStateStepping;
  ClearStopInfo();
}

std::string NativeThreadFreeBSD::GetName() {
  Log *log = GetLog(POSIXLog::Thread);

  std::vector<struct kinfo_proc> kp;
  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
                static_cast<int>(GetProcess().GetID())};

  while (1) {
    size_t len = kp.size() * sizeof(struct kinfo_proc);
    void *ptr = len == 0 ? nullptr : kp.data();
    int error = ::sysctl(mib, 4, ptr, &len, nullptr, 0);
    if (ptr == nullptr || (error != 0 && errno == ENOMEM)) {
      kp.resize(len / sizeof(struct kinfo_proc));
      continue;
    }
    if (error != 0) {
      len = 0;
      LLDB_LOG(log, "tid = {0} in state {1} failed to get thread name: {2}",
               GetID(), m_state, strerror(errno));
    }
    kp.resize(len / sizeof(struct kinfo_proc));
    break;
  }

  for (auto &procinfo : kp) {
    if (procinfo.ki_tid == static_cast<lwpid_t>(GetID()))
      return procinfo.ki_tdname;
  }

  return "";
}

lldb::StateType NativeThreadFreeBSD::GetState() { return m_state; }

bool NativeThreadFreeBSD::GetStopReason(ThreadStopInfo &stop_info,
                                        std::string &description) {
  Log *log = GetLog(POSIXLog::Thread);
  description.clear();

  switch (m_state) {
  case eStateStopped:
  case eStateCrashed:
  case eStateExited:
  case eStateSuspended:
  case eStateUnloaded:
    stop_info = m_stop_info;
    description = m_stop_description;

    return true;

  case eStateInvalid:
  case eStateConnected:
  case eStateAttaching:
  case eStateLaunching:
  case eStateRunning:
  case eStateStepping:
  case eStateDetached:
    LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(),
             StateAsCString(m_state));
    return false;
  }
  llvm_unreachable("unhandled StateType!");
}

NativeRegisterContextFreeBSD &NativeThreadFreeBSD::GetRegisterContext() {
  assert(m_reg_context_up);
  return *m_reg_context_up;
}

Status NativeThreadFreeBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
                                          uint32_t watch_flags, bool hardware) {
  assert(m_state == eStateStopped);
  if (!hardware)
    return Status::FromErrorString("not implemented");
  Status error = RemoveWatchpoint(addr);
  if (error.Fail())
    return error;
  uint32_t wp_index =
      GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
  if (wp_index == LLDB_INVALID_INDEX32)
    return Status::FromErrorString("Setting hardware watchpoint failed.");
  m_watchpoint_index_map.insert({addr, wp_index});
  return Status();
}

Status NativeThreadFreeBSD::RemoveWatchpoint(lldb::addr_t addr) {
  auto wp = m_watchpoint_index_map.find(addr);
  if (wp == m_watchpoint_index_map.end())
    return Status();
  uint32_t wp_index = wp->second;
  m_watchpoint_index_map.erase(wp);
  if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
    return Status();
  return Status::FromErrorString("Clearing hardware watchpoint failed.");
}

Status NativeThreadFreeBSD::SetHardwareBreakpoint(lldb::addr_t addr,
                                                  size_t size) {
  assert(m_state == eStateStopped);
  Status error = RemoveHardwareBreakpoint(addr);
  if (error.Fail())
    return error;

  uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);

  if (bp_index == LLDB_INVALID_INDEX32)
    return Status::FromErrorString("Setting hardware breakpoint failed.");

  m_hw_break_index_map.insert({addr, bp_index});
  return Status();
}

Status NativeThreadFreeBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
  auto bp = m_hw_break_index_map.find(addr);
  if (bp == m_hw_break_index_map.end())
    return Status();

  uint32_t bp_index = bp->second;
  if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
    m_hw_break_index_map.erase(bp);
    return Status();
  }

  return Status::FromErrorString("Clearing hardware breakpoint failed.");
}

llvm::Error
NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) {
  llvm::Error s = GetRegisterContext().CopyHardwareWatchpointsFrom(
      source.GetRegisterContext());
  if (!s) {
    m_watchpoint_index_map = source.m_watchpoint_index_map;
    m_hw_break_index_map = source.m_hw_break_index_map;
  }
  return s;
}

NativeProcessFreeBSD &NativeThreadFreeBSD::GetProcess() {
  return static_cast<NativeProcessFreeBSD &>(m_process);
}

llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
NativeThreadFreeBSD::GetSiginfo() const {
  Log *log = GetLog(POSIXLog::Process);

  struct ptrace_lwpinfo info;
  const auto siginfo_err = NativeProcessFreeBSD::PtraceWrapper(
      PT_LWPINFO, GetID(), &info, sizeof(info));
  if (siginfo_err.Fail()) {
    LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
    return siginfo_err.ToError();
  }

  if (info.pl_event != PL_EVENT_SIGNAL)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Thread not signaled");
  if (!(info.pl_flags & PL_FLAG_SI))
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "No siginfo for thread");

  return llvm::MemoryBuffer::getMemBufferCopy(
      llvm::StringRef(reinterpret_cast<const char *>(&info.pl_siginfo),
                      sizeof(info.pl_siginfo)));
}
