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