| //===-- 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 |