171 lines
6.5 KiB
C++
171 lines
6.5 KiB
C++
//===-- MachThread.h --------------------------------------------*- 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef __MachThread_h__
|
|
#define __MachThread_h__
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <libproc.h>
|
|
#include <mach/mach.h>
|
|
#include <pthread.h>
|
|
#include <sys/signal.h>
|
|
|
|
#include "DNBArch.h"
|
|
#include "DNBRegisterInfo.h"
|
|
#include "MachException.h"
|
|
#include "PThreadCondition.h"
|
|
#include "PThreadMutex.h"
|
|
|
|
#include "ThreadInfo.h"
|
|
|
|
class DNBBreakpoint;
|
|
class MachProcess;
|
|
class MachThreadList;
|
|
|
|
class MachThread {
|
|
public:
|
|
MachThread(MachProcess *process, bool is_64_bit,
|
|
uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
|
|
~MachThread();
|
|
|
|
MachProcess *Process() { return m_process; }
|
|
const MachProcess *Process() const { return m_process; }
|
|
nub_process_t ProcessID() const;
|
|
void Dump(uint32_t index);
|
|
uint64_t ThreadID() const { return m_unique_id; }
|
|
thread_t MachPortNumber() const { return m_mach_port_number; }
|
|
thread_t InferiorThreadID() const;
|
|
|
|
uint32_t SequenceID() const { return m_seq_id; }
|
|
static bool ThreadIDIsValid(
|
|
uint64_t thread); // The 64-bit system-wide unique thread identifier
|
|
static bool MachPortNumberIsValid(thread_t thread); // The mach port # for
|
|
// this thread in
|
|
// debugserver namespace
|
|
void Resume(bool others_stopped);
|
|
void Suspend();
|
|
bool SetSuspendCountBeforeResume(bool others_stopped);
|
|
bool RestoreSuspendCountAfterStop();
|
|
|
|
bool GetRegisterState(int flavor, bool force);
|
|
bool SetRegisterState(int flavor);
|
|
uint64_t
|
|
GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter
|
|
bool SetPC(uint64_t value); // Set program counter
|
|
uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer
|
|
|
|
DNBBreakpoint *CurrentBreakpoint();
|
|
uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
|
|
uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
|
|
bool also_set_on_task);
|
|
bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
|
|
bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
|
|
bool also_set_on_task);
|
|
uint32_t NumSupportedHardwareWatchpoints() const;
|
|
bool RollbackTransForHWP();
|
|
bool FinishTransForHWP();
|
|
|
|
nub_state_t GetState();
|
|
void SetState(nub_state_t state);
|
|
|
|
void ThreadWillResume(const DNBThreadResumeAction *thread_action,
|
|
bool others_stopped = false);
|
|
bool ShouldStop(bool &step_more);
|
|
bool IsStepping();
|
|
bool ThreadDidStop();
|
|
bool NotifyException(MachException::Data &exc);
|
|
const MachException::Data &GetStopException() { return m_stop_exception; }
|
|
|
|
nub_size_t GetNumRegistersInSet(nub_size_t regSet) const;
|
|
const char *GetRegisterSetName(nub_size_t regSet) const;
|
|
const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet,
|
|
nub_size_t regIndex) const;
|
|
void DumpRegisterState(nub_size_t regSet);
|
|
const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
|
|
bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
|
|
DNBRegisterValue *reg_value);
|
|
bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
|
|
const DNBRegisterValue *reg_value);
|
|
nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len);
|
|
nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len);
|
|
uint32_t SaveRegisterState();
|
|
bool RestoreRegisterState(uint32_t save_id);
|
|
|
|
void NotifyBreakpointChanged(const DNBBreakpoint *bp) {}
|
|
|
|
bool IsUserReady();
|
|
struct thread_basic_info *GetBasicInfo();
|
|
const char *GetBasicInfoAsString() const;
|
|
const char *GetName();
|
|
|
|
DNBArchProtocol *GetArchProtocol() { return m_arch_ap.get(); }
|
|
|
|
ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index);
|
|
nub_addr_t GetPThreadT();
|
|
nub_addr_t GetDispatchQueueT();
|
|
nub_addr_t
|
|
GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset,
|
|
uint64_t plo_pthread_tsd_base_offset,
|
|
uint64_t plo_pthread_tsd_entry_size);
|
|
|
|
static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id);
|
|
|
|
protected:
|
|
static bool GetBasicInfo(thread_t threadID,
|
|
struct thread_basic_info *basic_info);
|
|
|
|
bool GetIdentifierInfo();
|
|
|
|
// const char *
|
|
// GetDispatchQueueName();
|
|
//
|
|
MachProcess *m_process; // The process that owns this thread
|
|
uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
|
|
thread_t m_mach_port_number; // The mach port # for this thread in debugserver
|
|
// namesp.
|
|
uint32_t m_seq_id; // A Sequential ID that increments with each new thread
|
|
nub_state_t m_state; // The state of our process
|
|
PThreadMutex m_state_mutex; // Multithreaded protection for m_state
|
|
struct thread_basic_info m_basic_info; // Basic information for a thread used
|
|
// to see if a thread is valid
|
|
int32_t m_suspend_count; // The current suspend count > 0 means we have
|
|
// suspended m_suspendCount times,
|
|
// < 0 means we have resumed it m_suspendCount
|
|
// times.
|
|
MachException::Data m_stop_exception; // The best exception that describes why
|
|
// this thread is stopped
|
|
std::unique_ptr<DNBArchProtocol>
|
|
m_arch_ap; // Arch specific information for register state and more
|
|
const DNBRegisterSetInfo
|
|
*m_reg_sets; // Register set information for this thread
|
|
nub_size_t m_num_reg_sets;
|
|
thread_identifier_info_data_t m_ident_info;
|
|
struct proc_threadinfo m_proc_threadinfo;
|
|
std::string m_dispatch_queue_name;
|
|
bool m_is_64_bit;
|
|
|
|
// qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *,
|
|
// unsigned long *);
|
|
unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *,
|
|
unsigned long *);
|
|
|
|
private:
|
|
friend class MachThreadList;
|
|
};
|
|
|
|
typedef std::shared_ptr<MachThread> MachThreadSP;
|
|
|
|
#endif
|