//===-- MachThread.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  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_ap(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_ap->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 )",
                   &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) == false)
    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) == false)
    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:          strncpy(run_state_str, "running",
    //        run_state_str_size); break;
    //        case TH_STATE_STOPPED:          strncpy(run_state_str, "stopped",
    //        run_state_str_size); break;
    //        case TH_STATE_WAITING:          strncpy(run_state_str, "waiting",
    //        run_state_str_size); break;
    //        case TH_STATE_UNINTERRUPTIBLE:  strncpy(run_state_str,
    //        "uninterruptible", run_state_str_size); break;
    //        case TH_STATE_HALTED:           strncpy(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_ap->GetRegisterState(flavor, force) == KERN_SUCCESS;
}

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

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

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

uint64_t MachThread::GetSP(uint64_t failValue) {
  // Get stack pointer
  return m_arch_ap->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_ap->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_ap->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_ap->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_ap->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_ap->RegisterSetStateIsValid((int)regSet)) {
      const size_t numRegisters = GetNumRegistersInSet(regSet);
      uint32_t regIndex = 0;
      DNBRegisterValueClass reg;
      for (regIndex = 0; regIndex < numRegisters; ++regIndex) {
        if (m_arch_ap->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_ap->GetRegisterValue(set, reg, value);
}

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

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

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

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

uint32_t MachThread::EnableHardwareBreakpoint(const DNBBreakpoint *bp) {
  if (bp != NULL && bp->IsBreakpoint())
    return m_arch_ap->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_ap->EnableHardwareWatchpoint(
        wp->Address(), wp->ByteSize(), wp->WatchpointRead(),
        wp->WatchpointWrite(), also_set_on_task);
  return INVALID_NUB_HW_INDEX;
}

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

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

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

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

uint32_t MachThread::NumSupportedHardwareWatchpoints() const {
  return m_arch_ap->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;
}
