1061da546Spatrick //===-- MachThread.h --------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick // 9061da546Spatrick // Created by Greg Clayton on 6/19/07. 10061da546Spatrick // 11061da546Spatrick //===----------------------------------------------------------------------===// 12061da546Spatrick 13*dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H 14*dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H 15061da546Spatrick 16061da546Spatrick #include <string> 17061da546Spatrick #include <vector> 18061da546Spatrick 19061da546Spatrick #include <libproc.h> 20061da546Spatrick #include <mach/mach.h> 21061da546Spatrick #include <pthread.h> 22061da546Spatrick #include <sys/signal.h> 23061da546Spatrick 24061da546Spatrick #include "DNBArch.h" 25061da546Spatrick #include "DNBRegisterInfo.h" 26061da546Spatrick #include "MachException.h" 27061da546Spatrick #include "PThreadCondition.h" 28061da546Spatrick #include "PThreadMutex.h" 29061da546Spatrick 30061da546Spatrick #include "ThreadInfo.h" 31061da546Spatrick 32061da546Spatrick class DNBBreakpoint; 33061da546Spatrick class MachProcess; 34061da546Spatrick class MachThreadList; 35061da546Spatrick 36061da546Spatrick class MachThread { 37061da546Spatrick public: 38061da546Spatrick MachThread(MachProcess *process, bool is_64_bit, 39061da546Spatrick uint64_t unique_thread_id = 0, thread_t mach_port_number = 0); 40061da546Spatrick ~MachThread(); 41061da546Spatrick Process()42061da546Spatrick MachProcess *Process() { return m_process; } Process()43061da546Spatrick const MachProcess *Process() const { return m_process; } 44061da546Spatrick nub_process_t ProcessID() const; 45061da546Spatrick void Dump(uint32_t index); ThreadID()46061da546Spatrick uint64_t ThreadID() const { return m_unique_id; } MachPortNumber()47061da546Spatrick thread_t MachPortNumber() const { return m_mach_port_number; } 48061da546Spatrick thread_t InferiorThreadID() const; 49061da546Spatrick SequenceID()50061da546Spatrick uint32_t SequenceID() const { return m_seq_id; } 51061da546Spatrick static bool ThreadIDIsValid( 52061da546Spatrick uint64_t thread); // The 64-bit system-wide unique thread identifier 53061da546Spatrick static bool MachPortNumberIsValid(thread_t thread); // The mach port # for 54061da546Spatrick // this thread in 55061da546Spatrick // debugserver namespace 56061da546Spatrick void Resume(bool others_stopped); 57061da546Spatrick void Suspend(); 58061da546Spatrick bool SetSuspendCountBeforeResume(bool others_stopped); 59061da546Spatrick bool RestoreSuspendCountAfterStop(); 60061da546Spatrick 61061da546Spatrick bool GetRegisterState(int flavor, bool force); 62061da546Spatrick bool SetRegisterState(int flavor); 63061da546Spatrick uint64_t 64061da546Spatrick GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter 65061da546Spatrick bool SetPC(uint64_t value); // Set program counter 66061da546Spatrick uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer 67061da546Spatrick 68061da546Spatrick DNBBreakpoint *CurrentBreakpoint(); 69*dda28197Spatrick uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint, 70*dda28197Spatrick bool also_set_on_task); 71061da546Spatrick uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 72061da546Spatrick bool also_set_on_task); 73*dda28197Spatrick bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint, 74*dda28197Spatrick bool also_set_on_task); 75061da546Spatrick bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 76061da546Spatrick bool also_set_on_task); 77061da546Spatrick uint32_t NumSupportedHardwareWatchpoints() const; 78061da546Spatrick bool RollbackTransForHWP(); 79061da546Spatrick bool FinishTransForHWP(); 80061da546Spatrick 81061da546Spatrick nub_state_t GetState(); 82061da546Spatrick void SetState(nub_state_t state); 83061da546Spatrick 84061da546Spatrick void ThreadWillResume(const DNBThreadResumeAction *thread_action, 85061da546Spatrick bool others_stopped = false); 86061da546Spatrick bool ShouldStop(bool &step_more); 87061da546Spatrick bool IsStepping(); 88061da546Spatrick bool ThreadDidStop(); 89061da546Spatrick bool NotifyException(MachException::Data &exc); GetStopException()90061da546Spatrick const MachException::Data &GetStopException() { return m_stop_exception; } 91061da546Spatrick 92061da546Spatrick nub_size_t GetNumRegistersInSet(nub_size_t regSet) const; 93061da546Spatrick const char *GetRegisterSetName(nub_size_t regSet) const; 94061da546Spatrick const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet, 95061da546Spatrick nub_size_t regIndex) const; 96061da546Spatrick void DumpRegisterState(nub_size_t regSet); 97061da546Spatrick const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const; 98061da546Spatrick bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 99061da546Spatrick DNBRegisterValue *reg_value); 100061da546Spatrick bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 101061da546Spatrick const DNBRegisterValue *reg_value); 102061da546Spatrick nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len); 103061da546Spatrick nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len); 104061da546Spatrick uint32_t SaveRegisterState(); 105061da546Spatrick bool RestoreRegisterState(uint32_t save_id); 106061da546Spatrick NotifyBreakpointChanged(const DNBBreakpoint * bp)107061da546Spatrick void NotifyBreakpointChanged(const DNBBreakpoint *bp) {} 108061da546Spatrick 109061da546Spatrick bool IsUserReady(); 110061da546Spatrick struct thread_basic_info *GetBasicInfo(); 111061da546Spatrick const char *GetBasicInfoAsString() const; 112061da546Spatrick const char *GetName(); 113061da546Spatrick GetArchProtocol()114061da546Spatrick DNBArchProtocol *GetArchProtocol() { return m_arch_up.get(); } 115061da546Spatrick 116061da546Spatrick ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index); 117061da546Spatrick nub_addr_t GetPThreadT(); 118061da546Spatrick nub_addr_t GetDispatchQueueT(); 119061da546Spatrick nub_addr_t 120061da546Spatrick GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset, 121061da546Spatrick uint64_t plo_pthread_tsd_base_offset, 122061da546Spatrick uint64_t plo_pthread_tsd_entry_size); 123061da546Spatrick 124061da546Spatrick static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id); 125061da546Spatrick 126061da546Spatrick protected: 127061da546Spatrick static bool GetBasicInfo(thread_t threadID, 128061da546Spatrick struct thread_basic_info *basic_info); 129061da546Spatrick 130061da546Spatrick bool GetIdentifierInfo(); 131061da546Spatrick 132061da546Spatrick // const char * 133061da546Spatrick // GetDispatchQueueName(); 134061da546Spatrick // 135061da546Spatrick MachProcess *m_process; // The process that owns this thread 136061da546Spatrick uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t) 137061da546Spatrick thread_t m_mach_port_number; // The mach port # for this thread in debugserver 138061da546Spatrick // namesp. 139061da546Spatrick uint32_t m_seq_id; // A Sequential ID that increments with each new thread 140061da546Spatrick nub_state_t m_state; // The state of our process 141061da546Spatrick PThreadMutex m_state_mutex; // Multithreaded protection for m_state 142061da546Spatrick struct thread_basic_info m_basic_info; // Basic information for a thread used 143061da546Spatrick // to see if a thread is valid 144061da546Spatrick int32_t m_suspend_count; // The current suspend count > 0 means we have 145061da546Spatrick // suspended m_suspendCount times, 146061da546Spatrick // < 0 means we have resumed it m_suspendCount 147061da546Spatrick // times. 148061da546Spatrick MachException::Data m_stop_exception; // The best exception that describes why 149061da546Spatrick // this thread is stopped 150061da546Spatrick std::unique_ptr<DNBArchProtocol> 151061da546Spatrick m_arch_up; // Arch specific information for register state and more 152061da546Spatrick const DNBRegisterSetInfo 153061da546Spatrick *m_reg_sets; // Register set information for this thread 154061da546Spatrick nub_size_t m_num_reg_sets; 155061da546Spatrick thread_identifier_info_data_t m_ident_info; 156061da546Spatrick struct proc_threadinfo m_proc_threadinfo; 157061da546Spatrick std::string m_dispatch_queue_name; 158061da546Spatrick bool m_is_64_bit; 159061da546Spatrick 160061da546Spatrick // qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *, 161061da546Spatrick // unsigned long *); 162061da546Spatrick unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *, 163061da546Spatrick unsigned long *); 164061da546Spatrick 165061da546Spatrick private: 166061da546Spatrick friend class MachThreadList; 167061da546Spatrick }; 168061da546Spatrick 169061da546Spatrick typedef std::shared_ptr<MachThread> MachThreadSP; 170061da546Spatrick 171061da546Spatrick #endif 172