//===-- MachThread.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 "MachThread.h"
#include "DNB.h"
#include "DNBLog.h"
#include "MachProcess.h"
#include "ThreadInfo.h"
#include <dlfcn.h>
#include <inttypes.h>
#include <mach/thread_policy.h>

static uint32_t GetSequenceID() {
  static uint32_t g_nextID = 0;
  return ++g_nextID;
}

MachThread::MachThread(MachProcess *process, bool is_64_bit,
                       uint64_t unique_thread_id, thread_t mach_port_num)
    : m_process(process), m_unique_id(unique_thread_id),
      m_mach_port_number(mach_port_num), m_seq_id(GetSequenceID()),
      m_state(eStateUnloaded), m_state_mutex(PTHREAD_MUTEX_RECURSIVE),
      m_suspend_count(0), m_stop_exception(),
      m_arch_up(DNBArchProtocol::Create(this)), m_reg_sets(NULL),
      m_num_reg_sets(0), m_ident_info(), m_proc_threadinfo(),
      m_dispatch_queue_name(), m_is_64_bit(is_64_bit),
      m_pthread_qos_class_decode(nullptr) {
  nub_size_t num_reg_sets = 0;
  m_reg_sets = m_arch_up->GetRegisterSetInfo(&num_reg_sets);
  m_num_reg_sets = num_reg_sets;

  m_pthread_qos_class_decode =
      (unsigned int (*)(unsigned long, int *, unsigned long *))dlsym(
          RTLD_DEFAULT, "_pthread_qos_class_decode");

  // Get the thread state so we know if a thread is in a state where we can't
  // muck with it and also so we get the suspend count correct in case it was
  // already suspended
  GetBasicInfo();
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE,
                   "MachThread::MachThread ( process = %p, tid = 0x%8.8" PRIx64
                   ", seq_id = %u )",
                   reinterpret_cast<void *>(&m_process), m_unique_id, m_seq_id);
}

MachThread::~MachThread() {
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE,
                   "MachThread::~MachThread() for tid = 0x%8.8" PRIx64 " (%u)",
                   m_unique_id, m_seq_id);
}

void MachThread::Suspend() {
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
                   __FUNCTION__);
  if (MachPortNumberIsValid(m_mach_port_number)) {
    DNBError err(::thread_suspend(m_mach_port_number), DNBError::MachKernel);
    if (err.Success())
      m_suspend_count++;
    if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
      err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
  }
}

void MachThread::Resume(bool others_stopped) {
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
                   __FUNCTION__);
  if (MachPortNumberIsValid(m_mach_port_number)) {
    SetSuspendCountBeforeResume(others_stopped);
  }
}

bool MachThread::SetSuspendCountBeforeResume(bool others_stopped) {
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
                   __FUNCTION__);
  DNBError err;
  if (!MachPortNumberIsValid(m_mach_port_number))
    return false;

  integer_t times_to_resume;

  if (others_stopped) {
    if (GetBasicInfo()) {
      times_to_resume = m_basic_info.suspend_count;
      m_suspend_count = -(times_to_resume - m_suspend_count);
    } else
      times_to_resume = 0;
  } else {
    times_to_resume = m_suspend_count;
    m_suspend_count = 0;
  }

  if (times_to_resume > 0) {
    while (times_to_resume > 0) {
      err = ::thread_resume(m_mach_port_number);
      if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
        err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
      if (err.Success())
        --times_to_resume;
      else {
        if (GetBasicInfo())
          times_to_resume = m_basic_info.suspend_count;
        else
          times_to_resume = 0;
      }
    }
  }
  return true;
}

bool MachThread::RestoreSuspendCountAfterStop() {
  DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
                   __FUNCTION__);
  DNBError err;
  if (!MachPortNumberIsValid(m_mach_port_number))
    return false;

  if (m_suspend_count > 0) {
    while (m_suspend_count > 0) {
      err = ::thread_resume(m_mach_port_number);
      if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
        err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
      if (err.Success())
        --m_suspend_count;
      else {
        if (GetBasicInfo())
          m_suspend_count = m_basic_info.suspend_count;
        else
          m_suspend_count = 0;
        return false; // ???
      }
    }
  } else if (m_suspend_count < 0) {
    while (m_suspend_count < 0) {
      err = ::thread_suspend(m_mach_port_number);
      if (err.Success())
        ++m_suspend_count;
      if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) {
        err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")",
                        m_mach_port_number);
        return false;
      }
    }
  }
  return true;
}

const char *MachThread::GetBasicInfoAsString() const {
  static char g_basic_info_string[1024];
  struct thread_basic_info basicInfo;

  if (GetBasicInfo(m_mach_port_number, &basicInfo)) {

    //        char run_state_str[32];
    //        size_t run_state_str_size = sizeof(run_state_str);
    //        switch (basicInfo.run_state)
    //        {
    //        case TH_STATE_RUNNING:          strlcpy(run_state_str, "running",
    //        run_state_str_size); break;
    //        case TH_STATE_STOPPED:          strlcpy(run_state_str, "stopped",
    //        run_state_str_size); break;
    //        case TH_STATE_WAITING:          strlcpy(run_state_str, "waiting",
    //        run_state_str_size); break;
    //        case TH_STATE_UNINTERRUPTIBLE:  strlcpy(run_state_str,
    //        "uninterruptible", run_state_str_size); break;
    //        case TH_STATE_HALTED:           strlcpy(run_state_str, "halted",
    //        run_state_str_size); break;
    //        default:                        snprintf(run_state_str,
    //        run_state_str_size, "%d", basicInfo.run_state); break;    // ???
    //        }
    float user = (float)basicInfo.user_time.seconds +
                 (float)basicInfo.user_time.microseconds / 1000000.0f;
    float system = (float)basicInfo.user_time.seconds +
                   (float)basicInfo.user_time.microseconds / 1000000.0f;
    snprintf(g_basic_info_string, sizeof(g_basic_info_string),
             "Thread 0x%8.8" PRIx64 ": user=%f system=%f cpu=%d sleep_time=%d",
             m_unique_id, user, system, basicInfo.cpu_usage,
             basicInfo.sleep_time);

    return g_basic_info_string;
  }
  return NULL;
}

// Finds the Mach port number for a given thread in the inferior process' port
// namespace.
thread_t MachThread::InferiorThreadID() const {
  mach_msg_type_number_t i;
  mach_port_name_array_t names;
  mach_port_type_array_t types;
  mach_msg_type_number_t ncount, tcount;
  thread_t inferior_tid = INVALID_NUB_THREAD;
  task_t my_task = ::mach_task_self();
  task_t task = m_process->Task().TaskPort();

  kern_return_t kret =
      ::mach_port_names(task, &names, &ncount, &types, &tcount);
  if (kret == KERN_SUCCESS) {

    for (i = 0; i < ncount; i++) {
      mach_port_t my_name;
      mach_msg_type_name_t my_type;

      kret = ::mach_port_extract_right(task, names[i], MACH_MSG_TYPE_COPY_SEND,
                                       &my_name, &my_type);
      if (kret == KERN_SUCCESS) {
        ::mach_port_deallocate(my_task, my_name);
        if (my_name == m_mach_port_number) {
          inferior_tid = names[i];
          break;
        }
      }
    }
    // Free up the names and types
    ::vm_deallocate(my_task, (vm_address_t)names,
                    ncount * sizeof(mach_port_name_t));
    ::vm_deallocate(my_task, (vm_address_t)types,
                    tcount * sizeof(mach_port_type_t));
  }
  return inferior_tid;
}

bool MachThread::IsUserReady() {
  if (m_basic_info.run_state == 0)
    GetBasicInfo();

  switch (m_basic_info.run_state) {
  default:
  case TH_STATE_UNINTERRUPTIBLE:
    break;

  case TH_STATE_RUNNING:
  case TH_STATE_STOPPED:
  case TH_STATE_WAITING:
  case TH_STATE_HALTED:
    return true;
  }
  return false;
}

struct thread_basic_info *MachThread::GetBasicInfo() {
  if (MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info))
    return &m_basic_info;
  return NULL;
}

bool MachThread::GetBasicInfo(thread_t thread,
                              struct thread_basic_info *basicInfoPtr) {
  if (MachPortNumberIsValid(thread)) {
    unsigned int info_count = THREAD_BASIC_INFO_COUNT;
    kern_return_t err = ::thread_info(thread, THREAD_BASIC_INFO,
                                      (thread_info_t)basicInfoPtr, &info_count);
    if (err == KERN_SUCCESS)
      return true;
  }
  ::memset(basicInfoPtr, 0, sizeof(struct thread_basic_info));
  return false;
}

bool MachThread::ThreadIDIsValid(uint64_t thread) { return thread != 0; }

bool MachThread::MachPortNumberIsValid(thread_t thread) {
  return thread != THREAD_NULL;
}

bool MachThread::GetRegisterState(int flavor, bool force) {
  return m_arch_up->GetRegisterState(flavor, force) == KERN_SUCCESS;
}

bool MachThread::SetRegisterState(int flavor) {
  return m_arch_up->SetRegisterState(flavor) == KERN_SUCCESS;
}

uint64_t MachThread::GetPC(uint64_t failValue) {
  // Get program counter
  return m_arch_up->GetPC(failValue);
}

bool MachThread::SetPC(uint64_t value) {
  // Set program counter
  return m_arch_up->SetPC(value);
}

uint64_t MachThread::GetSP(uint64_t failValue) {
  // Get stack pointer
  return m_arch_up->GetSP(failValue);
}

nub_process_t MachThread::ProcessID() const {
  if (m_process)
    return m_process->ProcessID();
  return INVALID_NUB_PROCESS;
}

void MachThread::Dump(uint32_t index) {
  const char *thread_run_state = NULL;

  switch (m_basic_info.run_state) {
  case TH_STATE_RUNNING:
    thread_run_state = "running";
    break; // 1 thread is running normally
  case TH_STATE_STOPPED:
    thread_run_state = "stopped";
    break; // 2 thread is stopped
  case TH_STATE_WAITING:
    thread_run_state = "waiting";
    break; // 3 thread is waiting normally
  case TH_STATE_UNINTERRUPTIBLE:
    thread_run_state = "uninter";
    break; // 4 thread is in an uninterruptible wait
  case TH_STATE_HALTED:
    thread_run_state = "halted ";
    break; // 5 thread is halted at a
  default:
    thread_run_state = "???";
    break;
  }

  DNBLogThreaded(
      "[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64
      ", sp: 0x%16.16" PRIx64
      ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: "
      "%2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
      index, m_seq_id, m_unique_id, GetPC(INVALID_NUB_ADDRESS),
      GetSP(INVALID_NUB_ADDRESS), m_basic_info.user_time.seconds,
      m_basic_info.user_time.microseconds, m_basic_info.system_time.seconds,
      m_basic_info.system_time.microseconds, m_basic_info.cpu_usage,
      m_basic_info.policy, m_basic_info.run_state, thread_run_state,
      m_basic_info.flags, m_basic_info.suspend_count, m_suspend_count,
      m_basic_info.sleep_time);
  // DumpRegisterState(0);
}

void MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action,
                                  bool others_stopped) {
  if (thread_action->addr != INVALID_NUB_ADDRESS)
    SetPC(thread_action->addr);

  SetState(thread_action->state);
  switch (thread_action->state) {
  case eStateStopped:
  case eStateSuspended:
    assert(others_stopped == false);
    Suspend();
    break;

  case eStateRunning:
  case eStateStepping:
    Resume(others_stopped);
    break;
  default:
    break;
  }
  m_arch_up->ThreadWillResume();
  m_stop_exception.Clear();
}

DNBBreakpoint *MachThread::CurrentBreakpoint() {
  return m_process->Breakpoints().FindByAddress(GetPC());
}

bool MachThread::ShouldStop(bool &step_more) {
  // See if this thread is at a breakpoint?
  DNBBreakpoint *bp = CurrentBreakpoint();

  if (bp) {
    // This thread is sitting at a breakpoint, ask the breakpoint
    // if we should be stopping here.
    return true;
  } else {
    if (m_arch_up->StepNotComplete()) {
      step_more = true;
      return false;
    }
    // The thread state is used to let us know what the thread was
    // trying to do. MachThread::ThreadWillResume() will set the
    // thread state to various values depending if the thread was
    // the current thread and if it was to be single stepped, or
    // resumed.
    if (GetState() == eStateRunning) {
      // If our state is running, then we should continue as we are in
      // the process of stepping over a breakpoint.
      return false;
    } else {
      // Stop if we have any kind of valid exception for this
      // thread.
      if (GetStopException().IsValid())
        return true;
    }
  }
  return false;
}
bool MachThread::IsStepping() { return GetState() == eStateStepping; }

bool MachThread::ThreadDidStop() {
  // This thread has existed prior to resuming under debug nub control,
  // and has just been stopped. Do any cleanup that needs to be done
  // after running.

  // The thread state and breakpoint will still have the same values
  // as they had prior to resuming the thread, so it makes it easy to check
  // if we were trying to step a thread, or we tried to resume while being
  // at a breakpoint.

  // When this method gets called, the process state is still in the
  // state it was in while running so we can act accordingly.
  m_arch_up->ThreadDidStop();

  // We may have suspended this thread so the primary thread could step
  // without worrying about race conditions, so lets restore our suspend
  // count.
  RestoreSuspendCountAfterStop();

  // Update the basic information for a thread
  MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);

  if (m_basic_info.suspend_count > 0)
    SetState(eStateSuspended);
  else
    SetState(eStateStopped);
  return true;
}

bool MachThread::NotifyException(MachException::Data &exc) {
  // Allow the arch specific protocol to process (MachException::Data &)exc
  // first before possible reassignment of m_stop_exception with exc.
  // See also MachThread::GetStopException().
  bool handled = m_arch_up->NotifyException(exc);

  if (m_stop_exception.IsValid()) {
    // We may have more than one exception for a thread, but we need to
    // only remember the one that we will say is the reason we stopped.
    // We may have been single stepping and also gotten a signal exception,
    // so just remember the most pertinent one.
    if (m_stop_exception.IsBreakpoint())
      m_stop_exception = exc;
  } else {
    m_stop_exception = exc;
  }

  return handled;
}

nub_state_t MachThread::GetState() {
  // If any other threads access this we will need a mutex for it
  PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
  return m_state;
}

void MachThread::SetState(nub_state_t state) {
  PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
  m_state = state;
  DNBLogThreadedIf(LOG_THREAD,
                   "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "",
                   DNBStateAsString(state), m_unique_id);
}

nub_size_t MachThread::GetNumRegistersInSet(nub_size_t regSet) const {
  if (regSet < m_num_reg_sets)
    return m_reg_sets[regSet].num_registers;
  return 0;
}

const char *MachThread::GetRegisterSetName(nub_size_t regSet) const {
  if (regSet < m_num_reg_sets)
    return m_reg_sets[regSet].name;
  return NULL;
}

const DNBRegisterInfo *MachThread::GetRegisterInfo(nub_size_t regSet,
                                                   nub_size_t regIndex) const {
  if (regSet < m_num_reg_sets)
    if (regIndex < m_reg_sets[regSet].num_registers)
      return &m_reg_sets[regSet].registers[regIndex];
  return NULL;
}
void MachThread::DumpRegisterState(nub_size_t regSet) {
  if (regSet == REGISTER_SET_ALL) {
    for (regSet = 1; regSet < m_num_reg_sets; regSet++)
      DumpRegisterState(regSet);
  } else {
    if (m_arch_up->RegisterSetStateIsValid((int)regSet)) {
      const size_t numRegisters = GetNumRegistersInSet(regSet);
      uint32_t regIndex = 0;
      DNBRegisterValueClass reg;
      for (regIndex = 0; regIndex < numRegisters; ++regIndex) {
        if (m_arch_up->GetRegisterValue((uint32_t)regSet, regIndex, &reg)) {
          reg.Dump(NULL, NULL);
        }
      }
    } else {
      DNBLog("%s: registers are not currently valid.",
             GetRegisterSetName(regSet));
    }
  }
}

const DNBRegisterSetInfo *
MachThread::GetRegisterSetInfo(nub_size_t *num_reg_sets) const {
  *num_reg_sets = m_num_reg_sets;
  return &m_reg_sets[0];
}

bool MachThread::GetRegisterValue(uint32_t set, uint32_t reg,
                                  DNBRegisterValue *value) {
  return m_arch_up->GetRegisterValue(set, reg, value);
}

bool MachThread::SetRegisterValue(uint32_t set, uint32_t reg,
                                  const DNBRegisterValue *value) {
  return m_arch_up->SetRegisterValue(set, reg, value);
}

nub_size_t MachThread::GetRegisterContext(void *buf, nub_size_t buf_len) {
  return m_arch_up->GetRegisterContext(buf, buf_len);
}

nub_size_t MachThread::SetRegisterContext(const void *buf, nub_size_t buf_len) {
  return m_arch_up->SetRegisterContext(buf, buf_len);
}

uint32_t MachThread::SaveRegisterState() {
  return m_arch_up->SaveRegisterState();
}
bool MachThread::RestoreRegisterState(uint32_t save_id) {
  return m_arch_up->RestoreRegisterState(save_id);
}

uint32_t MachThread::EnableHardwareBreakpoint(const DNBBreakpoint *bp) {
  if (bp != NULL && bp->IsBreakpoint())
    return m_arch_up->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize());
  return INVALID_NUB_HW_INDEX;
}

uint32_t MachThread::EnableHardwareWatchpoint(const DNBBreakpoint *wp,
                                              bool also_set_on_task) {
  if (wp != NULL && wp->IsWatchpoint())
    return m_arch_up->EnableHardwareWatchpoint(
        wp->Address(), wp->ByteSize(), wp->WatchpointRead(),
        wp->WatchpointWrite(), also_set_on_task);
  return INVALID_NUB_HW_INDEX;
}

bool MachThread::RollbackTransForHWP() {
  return m_arch_up->RollbackTransForHWP();
}

bool MachThread::FinishTransForHWP() { return m_arch_up->FinishTransForHWP(); }

bool MachThread::DisableHardwareBreakpoint(const DNBBreakpoint *bp) {
  if (bp != NULL && bp->IsHardware())
    return m_arch_up->DisableHardwareBreakpoint(bp->GetHardwareIndex());
  return false;
}

bool MachThread::DisableHardwareWatchpoint(const DNBBreakpoint *wp,
                                           bool also_set_on_task) {
  if (wp != NULL && wp->IsHardware())
    return m_arch_up->DisableHardwareWatchpoint(wp->GetHardwareIndex(),
                                                also_set_on_task);
  return false;
}

uint32_t MachThread::NumSupportedHardwareWatchpoints() const {
  return m_arch_up->NumSupportedHardwareWatchpoints();
}

bool MachThread::GetIdentifierInfo() {
  // Don't try to get the thread info once and cache it for the life of the
  // thread.  It changes over time, for instance
  // if the thread name changes, then the thread_handle also changes...  So you
  // have to refetch it every time.
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kret = ::thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
                                     (thread_info_t)&m_ident_info, &count);
  return kret == KERN_SUCCESS;

  return false;
}

const char *MachThread::GetName() {
  if (GetIdentifierInfo()) {
    int len = ::proc_pidinfo(m_process->ProcessID(), PROC_PIDTHREADINFO,
                             m_ident_info.thread_handle, &m_proc_threadinfo,
                             sizeof(m_proc_threadinfo));

    if (len && m_proc_threadinfo.pth_name[0])
      return m_proc_threadinfo.pth_name;
  }
  return NULL;
}

uint64_t
MachThread::GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id) {
  kern_return_t kr;
  thread_identifier_info_data_t tident;
  mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
  kr = thread_info(mach_port_id, THREAD_IDENTIFIER_INFO, (thread_info_t)&tident,
                   &tident_count);
  if (kr != KERN_SUCCESS) {
    return mach_port_id;
  }
  return tident.thread_id;
}

nub_addr_t MachThread::GetPThreadT() {
  nub_addr_t pthread_t_value = INVALID_NUB_ADDRESS;
  if (MachPortNumberIsValid(m_mach_port_number)) {
    kern_return_t kr;
    thread_identifier_info_data_t tident;
    mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
    kr = thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
                     (thread_info_t)&tident, &tident_count);
    if (kr == KERN_SUCCESS) {
      // Dereference thread_handle to get the pthread_t value for this thread.
      if (m_is_64_bit) {
        uint64_t addr;
        if (m_process->ReadMemory(tident.thread_handle, 8, &addr) == 8) {
          if (addr != 0) {
            pthread_t_value = addr;
          }
        }
      } else {
        uint32_t addr;
        if (m_process->ReadMemory(tident.thread_handle, 4, &addr) == 4) {
          if (addr != 0) {
            pthread_t_value = addr;
          }
        }
      }
    }
  }
  return pthread_t_value;
}

// Return this thread's TSD (Thread Specific Data) address.
// This is computed based on this thread's pthread_t value.
//
// We compute the TSD from the pthread_t by one of two methods.
//
// If plo_pthread_tsd_base_offset is non-zero, this is a simple offset that we
// add to
// the pthread_t to get the TSD base address.
//
// Else we read a pointer from memory at pthread_t +
// plo_pthread_tsd_base_address_offset and
// that gives us the TSD address.
//
// These plo_pthread_tsd_base values must be read out of libpthread by lldb &
// provided to debugserver.

nub_addr_t
MachThread::GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset,
                                   uint64_t plo_pthread_tsd_base_offset,
                                   uint64_t plo_pthread_tsd_entry_size) {
  nub_addr_t tsd_addr = INVALID_NUB_ADDRESS;
  nub_addr_t pthread_t_value = GetPThreadT();
  if (plo_pthread_tsd_base_offset != 0 &&
      plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS) {
    tsd_addr = pthread_t_value + plo_pthread_tsd_base_offset;
  } else {
    if (plo_pthread_tsd_entry_size == 4) {
      uint32_t addr = 0;
      if (m_process->ReadMemory(pthread_t_value +
                                    plo_pthread_tsd_base_address_offset,
                                4, &addr) == 4) {
        if (addr != 0) {
          tsd_addr = addr;
        }
      }
    }
    if (plo_pthread_tsd_entry_size == 4) {
      uint64_t addr = 0;
      if (m_process->ReadMemory(pthread_t_value +
                                    plo_pthread_tsd_base_address_offset,
                                8, &addr) == 8) {
        if (addr != 0) {
          tsd_addr = addr;
        }
      }
    }
  }
  return tsd_addr;
}

nub_addr_t MachThread::GetDispatchQueueT() {
  nub_addr_t dispatch_queue_t_value = INVALID_NUB_ADDRESS;
  if (MachPortNumberIsValid(m_mach_port_number)) {
    kern_return_t kr;
    thread_identifier_info_data_t tident;
    mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
    kr = thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
                     (thread_info_t)&tident, &tident_count);
    if (kr == KERN_SUCCESS && tident.dispatch_qaddr != 0 &&
        tident.dispatch_qaddr != INVALID_NUB_ADDRESS) {
      // Dereference dispatch_qaddr to get the dispatch_queue_t value for this
      // thread's queue, if any.
      if (m_is_64_bit) {
        uint64_t addr;
        if (m_process->ReadMemory(tident.dispatch_qaddr, 8, &addr) == 8) {
          if (addr != 0)
            dispatch_queue_t_value = addr;
        }
      } else {
        uint32_t addr;
        if (m_process->ReadMemory(tident.dispatch_qaddr, 4, &addr) == 4) {
          if (addr != 0)
            dispatch_queue_t_value = addr;
        }
      }
    }
  }
  return dispatch_queue_t_value;
}

ThreadInfo::QoS MachThread::GetRequestedQoS(nub_addr_t tsd,
                                            uint64_t dti_qos_class_index) {
  ThreadInfo::QoS qos_value;
  if (MachPortNumberIsValid(m_mach_port_number) &&
      m_pthread_qos_class_decode != nullptr) {
    uint64_t pthread_priority_value = 0;
    if (m_is_64_bit) {
      uint64_t pri;
      if (m_process->ReadMemory(tsd + (dti_qos_class_index * 8), 8, &pri) ==
          8) {
        pthread_priority_value = pri;
      }
    } else {
      uint32_t pri;
      if (m_process->ReadMemory(tsd + (dti_qos_class_index * 4), 4, &pri) ==
          4) {
        pthread_priority_value = pri;
      }
    }

    uint32_t requested_qos =
        m_pthread_qos_class_decode(pthread_priority_value, NULL, NULL);

    switch (requested_qos) {
    // These constants from <pthread/qos.h>
    case 0x21:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_USER_INTERACTIVE";
      qos_value.printable_name = "User Interactive";
      break;
    case 0x19:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_USER_INITIATED";
      qos_value.printable_name = "User Initiated";
      break;
    case 0x15:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_DEFAULT";
      qos_value.printable_name = "Default";
      break;
    case 0x11:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_UTILITY";
      qos_value.printable_name = "Utility";
      break;
    case 0x09:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_BACKGROUND";
      qos_value.printable_name = "Background";
      break;
    case 0x00:
      qos_value.enum_value = requested_qos;
      qos_value.constant_name = "QOS_CLASS_UNSPECIFIED";
      qos_value.printable_name = "Unspecified";
      break;
    }
  }
  return qos_value;
}
