//===-- NativeThreadListDarwin.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
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/19/07.
//
//===----------------------------------------------------------------------===//

#include "NativeThreadListDarwin.h"

// C includes
#include <inttypes.h>
#include <mach/vm_map.h>
#include <sys/sysctl.h>

// LLDB includes
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"

#include "NativeProcessDarwin.h"
#include "NativeThreadDarwin.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_darwin;

NativeThreadListDarwin::NativeThreadListDarwin()
    : m_threads(), m_threads_mutex(), m_is_64_bit(false) {}

NativeThreadListDarwin::~NativeThreadListDarwin() {}

// These methods will be accessed directly from NativeThreadDarwin
#if 0
nub_state_t
NativeThreadListDarwin::GetState(nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetState();
    return eStateInvalid;
}

const char *
NativeThreadListDarwin::GetName (nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetName();
    return NULL;
}
#endif

// TODO: figure out if we need to add this to NativeThreadDarwin yet.
#if 0
ThreadInfo::QoS
NativeThreadListDarwin::GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetRequestedQoS(tsd, dti_qos_class_index);
    return ThreadInfo::QoS();
}

nub_addr_t
NativeThreadListDarwin::GetPThreadT (nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetPThreadT();
    return INVALID_NUB_ADDRESS;
}

nub_addr_t
NativeThreadListDarwin::GetDispatchQueueT (nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetDispatchQueueT();
    return INVALID_NUB_ADDRESS;
}

nub_addr_t
NativeThreadListDarwin::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetTSDAddressForThread(plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
    return INVALID_NUB_ADDRESS;
}
#endif

// TODO implement these
#if 0
nub_thread_t
NativeThreadListDarwin::SetCurrentThread(nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
    {
        m_current_thread = thread_sp;
        return tid;
    }
    return INVALID_NUB_THREAD;
}


bool
NativeThreadListDarwin::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetStopException().GetStopInfo(stop_info);
    return false;
}

bool
NativeThreadListDarwin::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
{
    thread_t mach_port_number = GetMachPortNumberByThreadID (tid);

    mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
    return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
}

void
NativeThreadListDarwin::DumpThreadStoppedReason (nub_thread_t tid) const
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        thread_sp->GetStopException().DumpStopReason();
}

const char *
NativeThreadListDarwin::GetThreadInfo (nub_thread_t tid) const
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetBasicInfoAsString();
    return NULL;
}

#endif

NativeThreadDarwinSP
NativeThreadListDarwin::GetThreadByID(lldb::tid_t tid) const {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  for (auto thread_sp : m_threads) {
    if (thread_sp && (thread_sp->GetID() == tid))
      return thread_sp;
  }
  return NativeThreadDarwinSP();
}

NativeThreadDarwinSP NativeThreadListDarwin::GetThreadByMachPortNumber(
    ::thread_t mach_port_number) const {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  for (auto thread_sp : m_threads) {
    if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
      return thread_sp;
  }
  return NativeThreadDarwinSP();
}

lldb::tid_t NativeThreadListDarwin::GetThreadIDByMachPortNumber(
    ::thread_t mach_port_number) const {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  for (auto thread_sp : m_threads) {
    if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
      return thread_sp->GetID();
  }
  return LLDB_INVALID_THREAD_ID;
}

// TODO implement
#if 0
thread_t
NativeThreadListDarwin::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
{
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    MachThreadSP thread_sp;
    const size_t num_threads = m_threads.size();
    for (size_t idx = 0; idx < num_threads; ++idx)
    {
        if (m_threads[idx]->ThreadID() == globally_unique_id)
        {
            return m_threads[idx]->MachPortNumber();
        }
    }
    return 0;
}

bool
NativeThreadListDarwin::GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value ) const
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetRegisterValue(set, reg, reg_value);

    return false;
}

bool
NativeThreadListDarwin::SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value ) const
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->SetRegisterValue(set, reg, reg_value);

    return false;
}

nub_size_t
NativeThreadListDarwin::GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->GetRegisterContext (buf, buf_len);
    return 0;
}

nub_size_t
NativeThreadListDarwin::SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->SetRegisterContext (buf, buf_len);
    return 0;
}

uint32_t
NativeThreadListDarwin::SaveRegisterState (nub_thread_t tid)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->SaveRegisterState ();
    return 0;
}

bool
NativeThreadListDarwin::RestoreRegisterState (nub_thread_t tid, uint32_t save_id)
{
    MachThreadSP thread_sp (GetThreadByID (tid));
    if (thread_sp)
        return thread_sp->RestoreRegisterState (save_id);
    return 0;
}
#endif

size_t NativeThreadListDarwin::GetNumberOfThreads() const {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  return static_cast<size_t>(m_threads.size());
}

// TODO implement
#if 0
nub_thread_t
NativeThreadListDarwin::ThreadIDAtIndex (nub_size_t idx) const
{
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    if (idx < m_threads.size())
        return m_threads[idx]->ThreadID();
    return INVALID_NUB_THREAD;
}

nub_thread_t
NativeThreadListDarwin::CurrentThreadID ( )
{
    MachThreadSP thread_sp;
    CurrentThread(thread_sp);
    if (thread_sp.get())
        return thread_sp->ThreadID();
    return INVALID_NUB_THREAD;
}

#endif

bool NativeThreadListDarwin::NotifyException(MachException::Data &exc) {
  auto thread_sp = GetThreadByMachPortNumber(exc.thread_port);
  if (thread_sp) {
    thread_sp->NotifyException(exc);
    return true;
  }
  return false;
}

void NativeThreadListDarwin::Clear() {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  m_threads.clear();
}

uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
                                                  bool update,
                                                  collection *new_threads) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));

  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  LLDB_LOGF(log,
            "NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
            "%u) process stop count = %u",
            __FUNCTION__, process.GetID(), update, process.GetStopID());

  if (process.GetStopID() == 0) {
    // On our first stop, we'll record details like 32/64 bitness and select
    // the proper architecture implementation.
    //
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process.GetID()};

    struct kinfo_proc processInfo;
    size_t bufsize = sizeof(processInfo);
    if ((sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo,
                &bufsize, NULL, 0) == 0) &&
        (bufsize > 0)) {
      if (processInfo.kp_proc.p_flag & P_LP64)
        m_is_64_bit = true;
    }

// TODO implement architecture selection and abstraction.
#if 0
#if defined(__i386__) || defined(__x86_64__)
        if (m_is_64_bit)
            DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
        else
            DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
        if (m_is_64_bit)
            DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
        else
            DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
#endif
#endif
  }

  if (m_threads.empty() || update) {
    thread_array_t thread_list = nullptr;
    mach_msg_type_number_t thread_list_count = 0;
    task_t task = process.GetTask();

    Status error;
    auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
    error.SetError(mach_err, eErrorTypeMachKernel);
    if (error.Fail()) {
      LLDB_LOGF(log,
                "::task_threads(task = 0x%4.4x, thread_list => %p, "
                "thread_list_count => %u) failed: %u (%s)",
                task, thread_list, thread_list_count, error.GetError(),
                error.AsCString());
      return 0;
    }

    if (thread_list_count > 0) {
      collection currThreads;
      size_t idx;
      // Iterator through the current thread list and see which threads we
      // already have in our list (keep them), which ones we don't (add them),
      // and which ones are not around anymore (remove them).
      for (idx = 0; idx < thread_list_count; ++idx) {
        // Get the Mach thread port.
        const ::thread_t mach_port_num = thread_list[idx];

        // Get the unique thread id for the mach port number.
        uint64_t unique_thread_id =
            NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
                mach_port_num);

        // Retrieve the thread if it exists.
        auto thread_sp = GetThreadByID(unique_thread_id);
        if (thread_sp) {
          // We are already tracking it. Keep the existing native thread
          // instance.
          currThreads.push_back(thread_sp);
        } else {
          // We don't have a native thread instance for this thread. Create it
          // now.
          thread_sp.reset(new NativeThreadDarwin(
              &process, m_is_64_bit, unique_thread_id, mach_port_num));

          // Add the new thread regardless of its is user ready state. Make
          // sure the thread is ready to be displayed and shown to users before
          // we add this thread to our list...
          if (thread_sp->IsUserReady()) {
            if (new_threads)
              new_threads->push_back(thread_sp);

            currThreads.push_back(thread_sp);
          }
        }
      }

      m_threads.swap(currThreads);
      m_current_thread.reset();

      // Free the vm memory given to us by ::task_threads()
      vm_size_t thread_list_size =
          (vm_size_t)(thread_list_count * sizeof(::thread_t));
      ::vm_deallocate(::mach_task_self(), (vm_address_t)thread_list,
                      thread_list_size);
    }
  }
  return static_cast<uint32_t>(m_threads.size());
}

// TODO implement
#if 0

void
NativeThreadListDarwin::CurrentThread (MachThreadSP& thread_sp)
{
    // locker will keep a mutex locked until it goes out of scope
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    if (m_current_thread.get() == NULL)
    {
        // Figure out which thread is going to be our current thread. This is
        // currently done by finding the first thread in the list that has a
        // valid exception.
        const size_t num_threads = m_threads.size();
        for (uint32_t idx = 0; idx < num_threads; ++idx)
        {
            if (m_threads[idx]->GetStopException().IsValid())
            {
                m_current_thread = m_threads[idx];
                break;
            }
        }
    }
    thread_sp = m_current_thread;
}

#endif

void NativeThreadListDarwin::Dump(Stream &stream) const {
  bool first = true;

  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  for (auto thread_sp : m_threads) {
    if (thread_sp) {
      // Handle newlines between thread entries.
      if (first)
        first = false;
      else
        stream.PutChar('\n');
      thread_sp->Dump(stream);
    }
  }
}

void NativeThreadListDarwin::ProcessWillResume(
    NativeProcessDarwin &process, const ResumeActionList &thread_actions) {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);

  // Update our thread list, because sometimes libdispatch or the kernel will
  // spawn threads while a task is suspended.
  NativeThreadListDarwin::collection new_threads;

// TODO implement this.
#if 0
    // First figure out if we were planning on running only one thread, and if
    // so, force that thread to resume.
    bool run_one_thread;
    thread_t solo_thread = THREAD_NULL;
    if ((thread_actions.GetSize() > 0) &&
        (thread_actions.NumActionsWithState(eStateStepping) +
         thread_actions.NumActionsWithState (eStateRunning) == 1))
    {
        run_one_thread = true;
        const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
        size_t num_actions = thread_actions.GetSize();
        for (size_t i = 0; i < num_actions; i++, action_ptr++)
        {
            if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning)
            {
                solo_thread = action_ptr->tid;
                break;
            }
        }
    }
    else
        run_one_thread = false;
#endif

  UpdateThreadList(process, true, &new_threads);

#if 0
    DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS };
    // If we are planning to run only one thread, any new threads should be
    // suspended.
    if (run_one_thread)
        resume_new_threads.state = eStateSuspended;

    const size_t num_new_threads = new_threads.size();
    const size_t num_threads = m_threads.size();
    for (uint32_t idx = 0; idx < num_threads; ++idx)
    {
        MachThread *thread = m_threads[idx].get();
        bool handled = false;
        for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx)
        {
            if (thread == new_threads[new_idx].get())
            {
                thread->ThreadWillResume(&resume_new_threads);
                handled = true;
                break;
            }
        }

        if (!handled)
        {
            const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true);
            // There must always be a thread action for every thread.
            assert (thread_action);
            bool others_stopped = false;
            if (solo_thread == thread->ThreadID())
                others_stopped = true;
            thread->ThreadWillResume (thread_action, others_stopped);
        }
    }
    
    if (new_threads.size())
    {
        for (uint32_t idx = 0; idx < num_new_threads; ++idx)
        {
            DNBLogThreadedIf (LOG_THREAD, "NativeThreadListDarwin::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
                              process->ProcessID(), 
                              process->StopCount(), 
                              new_threads[idx]->ThreadID(),
                              new_threads[idx]->IsUserReady());
        }
    }
#endif
}

uint32_t NativeThreadListDarwin::ProcessDidStop(NativeProcessDarwin &process) {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);

  // Update our thread list.
  UpdateThreadList(process, true);

  for (auto thread_sp : m_threads) {
    if (thread_sp)
      thread_sp->ThreadDidStop();
  }
  return (uint32_t)m_threads.size();
}

// Check each thread in our thread list to see if we should notify our client
// of the current halt in execution.
//
// Breakpoints can have callback functions associated with them than can return
// true to stop, or false to continue executing the inferior.
//
// RETURNS
//    true if we should stop and notify our clients
//    false if we should resume our child process and skip notification
bool NativeThreadListDarwin::ShouldStop(bool &step_more) {
  std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
  for (auto thread_sp : m_threads) {
    if (thread_sp && thread_sp->ShouldStop(step_more))
      return true;
  }
  return false;
}

// Implement.
#if 0

void
NativeThreadListDarwin::NotifyBreakpointChanged (const DNBBreakpoint *bp)
{
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    const size_t num_threads = m_threads.size();
    for (uint32_t idx = 0; idx < num_threads; ++idx)
    {
        m_threads[idx]->NotifyBreakpointChanged(bp);
    }
}


uint32_t
NativeThreadListDarwin::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const
{
    if (bp != NULL)
    {
        const size_t num_threads = m_threads.size();
        for (uint32_t idx = 0; idx < num_threads; ++idx)
            m_threads[idx]->EnableHardwareBreakpoint(bp);
    }
    return INVALID_NUB_HW_INDEX;
}

bool
NativeThreadListDarwin::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const
{
    if (bp != NULL)
    {
        const size_t num_threads = m_threads.size();
        for (uint32_t idx = 0; idx < num_threads; ++idx)
            m_threads[idx]->DisableHardwareBreakpoint(bp);
    }
    return false;
}

// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
// MachProcess::EnableWatchpoint() ->
// NativeThreadListDarwin::EnableHardwareWatchpoint().
uint32_t
NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
{
    uint32_t hw_index = INVALID_NUB_HW_INDEX;
    if (wp != NULL)
    {
        PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
        const size_t num_threads = m_threads.size();
        // On Mac OS X we have to prime the control registers for new threads.
        // We do this using the control register data for the first thread, for
        // lack of a better way of choosing.
        bool also_set_on_task = true;
        for (uint32_t idx = 0; idx < num_threads; ++idx)
        {                
            if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX)
            {
                // We know that idx failed for some reason.  Let's rollback the
                // transaction for [0, idx).
                for (uint32_t i = 0; i < idx; ++i)
                    m_threads[i]->RollbackTransForHWP();
                return INVALID_NUB_HW_INDEX;
            }
            also_set_on_task = false;
        }
        // Notify each thread to commit the pending transaction.
        for (uint32_t idx = 0; idx < num_threads; ++idx)
            m_threads[idx]->FinishTransForHWP();

    }
    return hw_index;
}

bool
NativeThreadListDarwin::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const
{
    if (wp != NULL)
    {
        PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
        const size_t num_threads = m_threads.size();
        
        // On Mac OS X we have to prime the control registers for new threads.
        // We do this using the control register data for the first thread, for
        // lack of a better way of choosing.
        bool also_set_on_task = true;
        for (uint32_t idx = 0; idx < num_threads; ++idx)
        {
            if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task))
            {
                // We know that idx failed for some reason.  Let's rollback the
                // transaction for [0, idx).
                for (uint32_t i = 0; i < idx; ++i)
                    m_threads[i]->RollbackTransForHWP();
                return false;
            }
            also_set_on_task = false;
        }
        // Notify each thread to commit the pending transaction.
        for (uint32_t idx = 0; idx < num_threads; ++idx)
            m_threads[idx]->FinishTransForHWP();

        return true;
    }
    return false;
}

uint32_t
NativeThreadListDarwin::NumSupportedHardwareWatchpoints () const
{
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    const size_t num_threads = m_threads.size();
    // Use an arbitrary thread to retrieve the number of supported hardware
    // watchpoints.
    if (num_threads)
        return m_threads[0]->NumSupportedHardwareWatchpoints();
    return 0;
}

uint32_t
NativeThreadListDarwin::GetThreadIndexForThreadStoppedWithSignal (const int signo) const
{
    PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
    uint32_t should_stop = false;
    const size_t num_threads = m_threads.size();
    for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx)
    {
        if (m_threads[idx]->GetStopException().SoftSignal () == signo)
            return idx;
    }
    return UINT32_MAX;
}

#endif
