//===-- FreeBSDThread.cpp ---------------------------------------*- C++ -*-===//
//
// 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 <errno.h>
#include <pthread.h>
#include <pthread_np.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/user.h>

#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/State.h"

#include "FreeBSDThread.h"
#include "POSIXStopInfo.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
#include "Plugins/Process/Utility/UnwindLLDB.h"
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
#include "RegisterContextPOSIXProcessMonitor_arm.h"
#include "RegisterContextPOSIXProcessMonitor_arm64.h"
#include "RegisterContextPOSIXProcessMonitor_mips64.h"
#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
#include "RegisterContextPOSIXProcessMonitor_x86.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
#include "lldb/Utility/State.h"
#include "llvm/ADT/SmallString.h"

using namespace lldb;
using namespace lldb_private;

FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
    : Thread(process, tid), m_frame_up(), m_breakpoint(),
      m_thread_name_valid(false), m_thread_name(), m_posix_thread(nullptr) {
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
  LLDB_LOGV(log, "tid = {0}", tid);

  // Set the current watchpoints for this thread.
  Target &target = GetProcess()->GetTarget();
  const WatchpointList &wp_list = target.GetWatchpointList();
  size_t wp_size = wp_list.GetSize();

  for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
    lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
    if (wp.get() && wp->IsEnabled()) {
      // This watchpoint as been enabled; obviously this "new" thread has been
      // created since that watchpoint was enabled.  Since the
      // POSIXBreakpointProtocol has yet to be initialized, its
      // m_watchpoints_initialized member will be FALSE.  Attempting to read
      // the debug status register to determine if a watchpoint has been hit
      // would result in the zeroing of that register. Since the active debug
      // registers would have been cloned when this thread was created, simply
      // force the m_watchpoints_initized member to TRUE and avoid resetting
      // dr6 and dr7.
      GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
    }
  }
}

FreeBSDThread::~FreeBSDThread() { DestroyThread(); }

ProcessMonitor &FreeBSDThread::GetMonitor() {
  ProcessSP base = GetProcess();
  ProcessFreeBSD &process = static_cast<ProcessFreeBSD &>(*base);
  return process.GetMonitor();
}

void FreeBSDThread::RefreshStateAfterStop() {
  // Invalidate all registers in our register context. We don't set "force" to
  // true because the stop reply packet might have had some register values
  // that were expedited and these will already be copied into the register
  // context by the time this function gets called. The KDPRegisterContext
  // class has been made smart enough to detect when it needs to invalidate
  // which registers are valid by putting hooks in the register read and
  // register supply functions where they check the process stop ID and do the
  // right thing. if (StateIsStoppedState(GetState())
  {
    const bool force = false;
    GetRegisterContext()->InvalidateIfNeeded(force);
  }
}

const char *FreeBSDThread::GetInfo() { return nullptr; }

void FreeBSDThread::SetName(const char *name) {
  m_thread_name_valid = (name && name[0]);
  if (m_thread_name_valid)
    m_thread_name.assign(name);
  else
    m_thread_name.clear();
}

const char *FreeBSDThread::GetName() {
  if (!m_thread_name_valid) {
    m_thread_name.clear();
    int pid = GetProcess()->GetID();

    struct kinfo_proc *kp = nullptr, *nkp;
    size_t len = 0;
    int error;
    int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
                  pid};

    while (1) {
      error = sysctl(ctl, 4, kp, &len, nullptr, 0);
      if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
        // Add extra space in case threads are added before next call.
        len += sizeof(*kp) + len / 10;
        nkp = (struct kinfo_proc *)realloc(kp, len);
        if (nkp == nullptr) {
          free(kp);
          return nullptr;
        }
        kp = nkp;
        continue;
      }
      if (error != 0)
        len = 0;
      break;
    }

    for (size_t i = 0; i < len / sizeof(*kp); i++) {
      if (kp[i].ki_tid == (lwpid_t)GetID()) {
        m_thread_name.append(kp[i].ki_tdname,
                             kp[i].ki_tdname + strlen(kp[i].ki_tdname));
        break;
      }
    }
    free(kp);
    m_thread_name_valid = true;
  }

  if (m_thread_name.empty())
    return nullptr;
  return m_thread_name.c_str();
}

lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
  if (!m_reg_context_sp) {
    m_posix_thread = nullptr;

    RegisterInfoInterface *reg_interface = nullptr;
    const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();

    assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
    switch (target_arch.GetMachine()) {
    case llvm::Triple::aarch64:
      reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
      break;
    case llvm::Triple::arm:
      reg_interface = new RegisterInfoPOSIX_arm(target_arch);
      break;
    case llvm::Triple::ppc:
#ifndef __powerpc64__
      reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
      break;
#endif
    case llvm::Triple::ppc64:
      reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
      break;
    case llvm::Triple::mips64:
      reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
      break;
    case llvm::Triple::x86:
      reg_interface = new RegisterContextFreeBSD_i386(target_arch);
      break;
    case llvm::Triple::x86_64:
      reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
      break;
    default:
      llvm_unreachable("CPU not supported");
    }

    switch (target_arch.GetMachine()) {
    case llvm::Triple::aarch64: {
      RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
          new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
      m_posix_thread = reg_ctx;
      m_reg_context_sp.reset(reg_ctx);
      break;
    }
    case llvm::Triple::arm: {
      RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
          new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
      m_posix_thread = reg_ctx;
      m_reg_context_sp.reset(reg_ctx);
      break;
    }
    case llvm::Triple::mips64: {
      RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
          new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
                                                        reg_interface);
      m_posix_thread = reg_ctx;
      m_reg_context_sp.reset(reg_ctx);
      break;
    }
    case llvm::Triple::ppc:
    case llvm::Triple::ppc64: {
      RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
          new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
                                                         reg_interface);
      m_posix_thread = reg_ctx;
      m_reg_context_sp.reset(reg_ctx);
      break;
    }
    case llvm::Triple::x86:
    case llvm::Triple::x86_64: {
      RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
          new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
                                                        reg_interface);
      m_posix_thread = reg_ctx;
      m_reg_context_sp.reset(reg_ctx);
      break;
    }
    default:
      break;
    }
  }
  return m_reg_context_sp;
}

lldb::RegisterContextSP
FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
  lldb::RegisterContextSP reg_ctx_sp;
  uint32_t concrete_frame_idx = 0;

  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
  LLDB_LOGV(log, "called");

  if (frame)
    concrete_frame_idx = frame->GetConcreteFrameIndex();

  if (concrete_frame_idx == 0)
    reg_ctx_sp = GetRegisterContext();
  else {
    assert(GetUnwinder());
    reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
  }

  return reg_ctx_sp;
}

lldb::addr_t FreeBSDThread::GetThreadPointer() {
  ProcessMonitor &monitor = GetMonitor();
  addr_t addr;
  if (monitor.ReadThreadPointer(GetID(), addr))
    return addr;
  else
    return LLDB_INVALID_ADDRESS;
}

bool FreeBSDThread::CalculateStopInfo() {
  SetStopInfo(m_stop_info_sp);
  return true;
}

Unwind *FreeBSDThread::GetUnwinder() {
  if (!m_unwinder_up)
    m_unwinder_up.reset(new UnwindLLDB(*this));

  return m_unwinder_up.get();
}

void FreeBSDThread::DidStop() {
  // Don't set the thread state to stopped unless we really stopped.
}

void FreeBSDThread::WillResume(lldb::StateType resume_state) {
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
  LLDB_LOGF(log, "tid %lu resume_state = %s", GetID(),
            lldb_private::StateAsCString(resume_state));
  ProcessSP process_sp(GetProcess());
  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
  int signo = GetResumeSignal();
  bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);

  switch (resume_state) {
  case eStateSuspended:
  case eStateStopped:
    process->m_suspend_tids.push_back(GetID());
    break;
  case eStateRunning:
    process->m_run_tids.push_back(GetID());
    if (signo_valid)
      process->m_resume_signo = signo;
    break;
  case eStateStepping:
    process->m_step_tids.push_back(GetID());
    if (signo_valid)
      process->m_resume_signo = signo;
    break;
  default:
    break;
  }
}

bool FreeBSDThread::Resume() {
  lldb::StateType resume_state = GetResumeState();
  ProcessMonitor &monitor = GetMonitor();
  bool status;

  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
  LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
            StateAsCString(resume_state));

  switch (resume_state) {
  default:
    assert(false && "Unexpected state for resume!");
    status = false;
    break;

  case lldb::eStateRunning:
    SetState(resume_state);
    status = monitor.Resume(GetID(), GetResumeSignal());
    break;

  case lldb::eStateStepping:
    SetState(resume_state);
    status = monitor.SingleStep(GetID(), GetResumeSignal());
    break;
  case lldb::eStateStopped:
  case lldb::eStateSuspended:
    status = true;
    break;
  }

  return status;
}

void FreeBSDThread::Notify(const ProcessMessage &message) {
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
  LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
            __FUNCTION__, message.PrintKind(), GetID());

  switch (message.GetKind()) {
  default:
    assert(false && "Unexpected message kind!");
    break;

  case ProcessMessage::eExitMessage:
    // Nothing to be done.
    break;

  case ProcessMessage::eLimboMessage:
    LimboNotify(message);
    break;

  case ProcessMessage::eCrashMessage:
  case ProcessMessage::eSignalMessage:
    SignalNotify(message);
    break;

  case ProcessMessage::eSignalDeliveredMessage:
    SignalDeliveredNotify(message);
    break;

  case ProcessMessage::eTraceMessage:
    TraceNotify(message);
    break;

  case ProcessMessage::eBreakpointMessage:
    BreakNotify(message);
    break;

  case ProcessMessage::eWatchpointMessage:
    WatchNotify(message);
    break;

  case ProcessMessage::eExecMessage:
    ExecNotify(message);
    break;
  }
}

bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
  bool wp_set = false;
  if (wp) {
    addr_t wp_addr = wp->GetLoadAddress();
    size_t wp_size = wp->GetByteSize();
    bool wp_read = wp->WatchpointRead();
    bool wp_write = wp->WatchpointWrite();
    uint32_t wp_hw_index = wp->GetHardwareIndex();
    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
    if (reg_ctx)
      wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
          wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
  }
  return wp_set;
}

bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
  bool result = false;
  if (wp) {
    lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
    if (reg_ctx_sp.get())
      result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
  }
  return result;
}

uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
  lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
  if (reg_ctx_sp.get())
    return reg_ctx_sp->NumSupportedHardwareWatchpoints();
  return 0;
}

uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
  uint32_t hw_index = LLDB_INVALID_INDEX32;
  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
  uint32_t wp_idx;
  POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
  if (reg_ctx) {
    for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
      if (reg_ctx->IsWatchpointVacant(wp_idx)) {
        hw_index = wp_idx;
        break;
      }
    }
  }
  return hw_index;
}

void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
  bool status;
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));

  assert(GetRegisterContext());
  status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
  assert(status && "Breakpoint update failed!");

  // With our register state restored, resolve the breakpoint object
  // corresponding to our current PC.
  assert(GetRegisterContext());
  lldb::addr_t pc = GetRegisterContext()->GetPC();
  LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
  lldb::BreakpointSiteSP bp_site(
      GetProcess()->GetBreakpointSiteList().FindByAddress(pc));

  // If the breakpoint is for this thread, then we'll report the hit, but if it
  // is for another thread, we create a stop reason with should_stop=false.  If
  // there is no breakpoint location, then report an invalid stop reason. We
  // don't need to worry about stepping over the breakpoint here, that will be
  // taken care of when the thread resumes and notices that there's a
  // breakpoint under the pc.
  if (bp_site) {
    lldb::break_id_t bp_id = bp_site->GetID();
    // If we have an operating system plug-in, we might have set a thread
    // specific breakpoint using the operating system thread ID, so we can't
    // make any assumptions about the thread ID so we must always report the
    // breakpoint regardless of the thread.
    if (bp_site->ValidForThisThread(this) ||
        GetProcess()->GetOperatingSystem() != nullptr)
      SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
    else {
      const bool should_stop = false;
      SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
                                                                 should_stop));
    }
  } else
    SetStopInfo(StopInfoSP());
}

void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));

  lldb::addr_t halt_addr = message.GetHWAddress();
  LLDB_LOGF(log,
            "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
            __FUNCTION__, halt_addr);

  POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
  if (reg_ctx) {
    uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
    uint32_t wp_idx;
    for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
      if (reg_ctx->IsWatchpointHit(wp_idx)) {
        // Clear the watchpoint hit here
        reg_ctx->ClearWatchpointHits();
        break;
      }
    }

    if (wp_idx == num_hw_wps)
      return;

    Target &target = GetProcess()->GetTarget();
    lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
    const WatchpointList &wp_list = target.GetWatchpointList();
    lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);

    assert(wp_sp.get() && "No watchpoint found");
    SetStopInfo(
        StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
  }
}

void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));

  // Try to resolve the breakpoint object corresponding to the current PC.
  assert(GetRegisterContext());
  lldb::addr_t pc = GetRegisterContext()->GetPC();
  LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
  lldb::BreakpointSiteSP bp_site(
      GetProcess()->GetBreakpointSiteList().FindByAddress(pc));

  // If the current pc is a breakpoint site then set the StopInfo to
  // Breakpoint. Otherwise, set the StopInfo to Watchpoint or Trace. If we have
  // an operating system plug-in, we might have set a thread specific
  // breakpoint using the operating system thread ID, so we can't make any
  // assumptions about the thread ID so we must always report the breakpoint
  // regardless of the thread.
  if (bp_site && (bp_site->ValidForThisThread(this) ||
                  GetProcess()->GetOperatingSystem() != nullptr))
    SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
        *this, bp_site->GetID()));
  else {
    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
    if (reg_ctx) {
      uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
      uint32_t wp_idx;
      for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
        if (reg_ctx->IsWatchpointHit(wp_idx)) {
          WatchNotify(message);
          return;
        }
      }
    }
    SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
  }
}

void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
  SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
}

void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
  int signo = message.GetSignal();
  if (message.GetKind() == ProcessMessage::eCrashMessage) {
    std::string stop_description = GetCrashReasonString(
        message.GetCrashReason(), message.GetFaultAddress());
    SetStopInfo(StopInfo::CreateStopReasonWithSignal(
        *this, signo, stop_description.c_str()));
  } else {
    SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
  }
}

void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
  int signo = message.GetSignal();
  SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}

unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
  unsigned reg = LLDB_INVALID_REGNUM;
  ArchSpec arch = HostInfo::GetArchitecture();

  switch (arch.GetMachine()) {
  default:
    llvm_unreachable("CPU type not supported!");
    break;

  case llvm::Triple::aarch64:
  case llvm::Triple::arm:
  case llvm::Triple::mips64:
  case llvm::Triple::ppc:
  case llvm::Triple::ppc64:
  case llvm::Triple::x86:
  case llvm::Triple::x86_64: {
    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
    reg = reg_ctx->GetRegisterIndexFromOffset(offset);
  } break;
  }
  return reg;
}

void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
  SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
}

const char *FreeBSDThread::GetRegisterName(unsigned reg) {
  const char *name = nullptr;
  ArchSpec arch = HostInfo::GetArchitecture();

  switch (arch.GetMachine()) {
  default:
    assert(false && "CPU type not supported!");
    break;

  case llvm::Triple::aarch64:
  case llvm::Triple::arm:
  case llvm::Triple::mips64:
  case llvm::Triple::ppc:
  case llvm::Triple::ppc64:
  case llvm::Triple::x86:
  case llvm::Triple::x86_64:
    name = GetRegisterContext()->GetRegisterName(reg);
    break;
  }
  return name;
}

const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
  return GetRegisterName(GetRegisterIndexFromOffset(offset));
}
