1 //===-- MachThread.h --------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Created by Greg Clayton on 6/19/07. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef __MachThread_h__ 15 #define __MachThread_h__ 16 17 #include <string> 18 #include <vector> 19 20 #include <libproc.h> 21 #include <mach/mach.h> 22 #include <pthread.h> 23 #include <sys/signal.h> 24 25 #include "DNBArch.h" 26 #include "DNBRegisterInfo.h" 27 #include "MachException.h" 28 #include "PThreadCondition.h" 29 #include "PThreadMutex.h" 30 31 #include "ThreadInfo.h" 32 33 class DNBBreakpoint; 34 class MachProcess; 35 class MachThreadList; 36 37 class MachThread { 38 public: 39 MachThread(MachProcess *process, bool is_64_bit, 40 uint64_t unique_thread_id = 0, thread_t mach_port_number = 0); 41 ~MachThread(); 42 43 MachProcess *Process() { return m_process; } 44 const MachProcess *Process() const { return m_process; } 45 nub_process_t ProcessID() const; 46 void Dump(uint32_t index); 47 uint64_t ThreadID() const { return m_unique_id; } 48 thread_t MachPortNumber() const { return m_mach_port_number; } 49 thread_t InferiorThreadID() const; 50 51 uint32_t SequenceID() const { return m_seq_id; } 52 static bool ThreadIDIsValid( 53 uint64_t thread); // The 64-bit system-wide unique thread identifier 54 static bool MachPortNumberIsValid(thread_t thread); // The mach port # for 55 // this thread in 56 // debugserver namespace 57 void Resume(bool others_stopped); 58 void Suspend(); 59 bool SetSuspendCountBeforeResume(bool others_stopped); 60 bool RestoreSuspendCountAfterStop(); 61 62 bool GetRegisterState(int flavor, bool force); 63 bool SetRegisterState(int flavor); 64 uint64_t 65 GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter 66 bool SetPC(uint64_t value); // Set program counter 67 uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer 68 69 DNBBreakpoint *CurrentBreakpoint(); 70 uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint); 71 uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 72 bool also_set_on_task); 73 bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint); 74 bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 75 bool also_set_on_task); 76 uint32_t NumSupportedHardwareWatchpoints() const; 77 bool RollbackTransForHWP(); 78 bool FinishTransForHWP(); 79 80 nub_state_t GetState(); 81 void SetState(nub_state_t state); 82 83 void ThreadWillResume(const DNBThreadResumeAction *thread_action, 84 bool others_stopped = false); 85 bool ShouldStop(bool &step_more); 86 bool IsStepping(); 87 bool ThreadDidStop(); 88 bool NotifyException(MachException::Data &exc); 89 const MachException::Data &GetStopException() { return m_stop_exception; } 90 91 nub_size_t GetNumRegistersInSet(nub_size_t regSet) const; 92 const char *GetRegisterSetName(nub_size_t regSet) const; 93 const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet, 94 nub_size_t regIndex) const; 95 void DumpRegisterState(nub_size_t regSet); 96 const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const; 97 bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 98 DNBRegisterValue *reg_value); 99 bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 100 const DNBRegisterValue *reg_value); 101 nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len); 102 nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len); 103 uint32_t SaveRegisterState(); 104 bool RestoreRegisterState(uint32_t save_id); 105 106 void NotifyBreakpointChanged(const DNBBreakpoint *bp) {} 107 108 bool IsUserReady(); 109 struct thread_basic_info *GetBasicInfo(); 110 const char *GetBasicInfoAsString() const; 111 const char *GetName(); 112 113 DNBArchProtocol *GetArchProtocol() { return m_arch_ap.get(); } 114 115 ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index); 116 nub_addr_t GetPThreadT(); 117 nub_addr_t GetDispatchQueueT(); 118 nub_addr_t 119 GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset, 120 uint64_t plo_pthread_tsd_base_offset, 121 uint64_t plo_pthread_tsd_entry_size); 122 123 static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id); 124 125 protected: 126 static bool GetBasicInfo(thread_t threadID, 127 struct thread_basic_info *basic_info); 128 129 bool GetIdentifierInfo(); 130 131 // const char * 132 // GetDispatchQueueName(); 133 // 134 MachProcess *m_process; // The process that owns this thread 135 uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t) 136 thread_t m_mach_port_number; // The mach port # for this thread in debugserver 137 // namesp. 138 uint32_t m_seq_id; // A Sequential ID that increments with each new thread 139 nub_state_t m_state; // The state of our process 140 PThreadMutex m_state_mutex; // Multithreaded protection for m_state 141 struct thread_basic_info m_basic_info; // Basic information for a thread used 142 // to see if a thread is valid 143 int32_t m_suspend_count; // The current suspend count > 0 means we have 144 // suspended m_suspendCount times, 145 // < 0 means we have resumed it m_suspendCount 146 // times. 147 MachException::Data m_stop_exception; // The best exception that describes why 148 // this thread is stopped 149 std::unique_ptr<DNBArchProtocol> 150 m_arch_ap; // Arch specific information for register state and more 151 const DNBRegisterSetInfo 152 *m_reg_sets; // Register set information for this thread 153 nub_size_t m_num_reg_sets; 154 thread_identifier_info_data_t m_ident_info; 155 struct proc_threadinfo m_proc_threadinfo; 156 std::string m_dispatch_queue_name; 157 bool m_is_64_bit; 158 159 // qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *, 160 // unsigned long *); 161 unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *, 162 unsigned long *); 163 164 private: 165 friend class MachThreadList; 166 }; 167 168 typedef std::shared_ptr<MachThread> MachThreadSP; 169 170 #endif 171