130fdc8d8SChris Lattner //===-- MachThread.h --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner // 930fdc8d8SChris Lattner // Created by Greg Clayton on 6/19/07. 1030fdc8d8SChris Lattner // 1130fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 1230fdc8d8SChris Lattner 13*cdc514e4SJonas Devlieghere #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H 14*cdc514e4SJonas Devlieghere #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H 1530fdc8d8SChris Lattner 1630fdc8d8SChris Lattner #include <string> 1730fdc8d8SChris Lattner #include <vector> 1830fdc8d8SChris Lattner 1930fdc8d8SChris Lattner #include <libproc.h> 2030fdc8d8SChris Lattner #include <mach/mach.h> 2130fdc8d8SChris Lattner #include <pthread.h> 2230fdc8d8SChris Lattner #include <sys/signal.h> 2330fdc8d8SChris Lattner 2430fdc8d8SChris Lattner #include "DNBArch.h" 2530fdc8d8SChris Lattner #include "DNBRegisterInfo.h" 26b9c1b51eSKate Stone #include "MachException.h" 27b9c1b51eSKate Stone #include "PThreadCondition.h" 28b9c1b51eSKate Stone #include "PThreadMutex.h" 2930fdc8d8SChris Lattner 30705b1809SJason Molenda #include "ThreadInfo.h" 31705b1809SJason Molenda 3230fdc8d8SChris Lattner class DNBBreakpoint; 3330fdc8d8SChris Lattner class MachProcess; 34a9b68f4dSJohnny Chen class MachThreadList; 3530fdc8d8SChris Lattner 36b9c1b51eSKate Stone class MachThread { 3730fdc8d8SChris Lattner public: 38b9c1b51eSKate Stone MachThread(MachProcess *process, bool is_64_bit, 39b9c1b51eSKate Stone uint64_t unique_thread_id = 0, thread_t mach_port_number = 0); 4030fdc8d8SChris Lattner ~MachThread(); 4130fdc8d8SChris Lattner Process()4230fdc8d8SChris Lattner MachProcess *Process() { return m_process; } Process()43b9c1b51eSKate Stone const MachProcess *Process() const { return m_process; } 4430fdc8d8SChris Lattner nub_process_t ProcessID() const; 4530fdc8d8SChris Lattner void Dump(uint32_t index); ThreadID()461c73911dSJason Molenda uint64_t ThreadID() const { return m_unique_id; } MachPortNumber()471c73911dSJason Molenda thread_t MachPortNumber() const { return m_mach_port_number; } 4830fdc8d8SChris Lattner thread_t InferiorThreadID() const; 4930fdc8d8SChris Lattner SequenceID()5030fdc8d8SChris Lattner uint32_t SequenceID() const { return m_seq_id; } 51b9c1b51eSKate Stone static bool ThreadIDIsValid( 52b9c1b51eSKate Stone uint64_t thread); // The 64-bit system-wide unique thread identifier 53b9c1b51eSKate Stone static bool MachPortNumberIsValid(thread_t thread); // The mach port # for 54b9c1b51eSKate Stone // this thread in 55b9c1b51eSKate Stone // debugserver namespace 569411ddb6SJim Ingham void Resume(bool others_stopped); 579411ddb6SJim Ingham void Suspend(); 589411ddb6SJim Ingham bool SetSuspendCountBeforeResume(bool others_stopped); 599411ddb6SJim Ingham bool RestoreSuspendCountAfterStop(); 60cdc7322bSGreg Clayton 6130fdc8d8SChris Lattner bool GetRegisterState(int flavor, bool force); 6230fdc8d8SChris Lattner bool SetRegisterState(int flavor); 63b9c1b51eSKate Stone uint64_t 64b9c1b51eSKate Stone GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter 6530fdc8d8SChris Lattner bool SetPC(uint64_t value); // Set program counter 6630fdc8d8SChris Lattner uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer 6730fdc8d8SChris Lattner 68d8cf1a11SGreg Clayton DNBBreakpoint *CurrentBreakpoint(); 699902c8e3SJonas Devlieghere uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint, 709902c8e3SJonas Devlieghere bool also_set_on_task); 71b9c1b51eSKate Stone uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 72b9c1b51eSKate Stone bool also_set_on_task); 739902c8e3SJonas Devlieghere bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint, 749902c8e3SJonas Devlieghere bool also_set_on_task); 75b9c1b51eSKate Stone bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint, 76b9c1b51eSKate Stone bool also_set_on_task); 7764637205SJohnny Chen uint32_t NumSupportedHardwareWatchpoints() const; 7884707560SJohnny Chen bool RollbackTransForHWP(); 7984707560SJohnny Chen bool FinishTransForHWP(); 8030fdc8d8SChris Lattner 8130fdc8d8SChris Lattner nub_state_t GetState(); 8230fdc8d8SChris Lattner void SetState(nub_state_t state); 8330fdc8d8SChris Lattner 84b9c1b51eSKate Stone void ThreadWillResume(const DNBThreadResumeAction *thread_action, 85b9c1b51eSKate Stone bool others_stopped = false); 8630fdc8d8SChris Lattner bool ShouldStop(bool &step_more); 8730fdc8d8SChris Lattner bool IsStepping(); 8830fdc8d8SChris Lattner bool ThreadDidStop(); 8930fdc8d8SChris Lattner bool NotifyException(MachException::Data &exc); GetStopException()9030fdc8d8SChris Lattner const MachException::Data &GetStopException() { return m_stop_exception; } 9130fdc8d8SChris Lattner 92a026de05SBruce Mitchener nub_size_t GetNumRegistersInSet(nub_size_t regSet) const; 93a026de05SBruce Mitchener const char *GetRegisterSetName(nub_size_t regSet) const; 94b9c1b51eSKate Stone const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet, 95b9c1b51eSKate Stone nub_size_t regIndex) const; 96a026de05SBruce Mitchener void DumpRegisterState(nub_size_t regSet); 97b9c1b51eSKate Stone const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const; 98b9c1b51eSKate Stone bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 99b9c1b51eSKate Stone DNBRegisterValue *reg_value); 100b9c1b51eSKate Stone bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx, 101b9c1b51eSKate Stone const DNBRegisterValue *reg_value); 10230fdc8d8SChris Lattner nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len); 10330fdc8d8SChris Lattner nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len); 104f74cf86bSGreg Clayton uint32_t SaveRegisterState(); 105f74cf86bSGreg Clayton bool RestoreRegisterState(uint32_t save_id); 106f74cf86bSGreg Clayton NotifyBreakpointChanged(const DNBBreakpoint * bp)107b9c1b51eSKate Stone void NotifyBreakpointChanged(const DNBBreakpoint *bp) {} 1081b946bf6SGreg Clayton 1091b946bf6SGreg Clayton bool IsUserReady(); 110b9c1b51eSKate Stone struct thread_basic_info *GetBasicInfo(); 11130fdc8d8SChris Lattner const char *GetBasicInfoAsString() const; 11230fdc8d8SChris Lattner const char *GetName(); 1133af9ea56SGreg Clayton GetArchProtocol()114d5b44036SJonas Devlieghere DNBArchProtocol *GetArchProtocol() { return m_arch_up.get(); } 1153af9ea56SGreg Clayton 116705b1809SJason Molenda ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index); 117705b1809SJason Molenda nub_addr_t GetPThreadT(); 118705b1809SJason Molenda nub_addr_t GetDispatchQueueT(); 119b9c1b51eSKate Stone nub_addr_t 120b9c1b51eSKate Stone GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset, 121b9c1b51eSKate Stone uint64_t plo_pthread_tsd_base_offset, 122b9c1b51eSKate Stone uint64_t plo_pthread_tsd_entry_size); 123705b1809SJason Molenda 1241c73911dSJason Molenda static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id); 1251c73911dSJason Molenda 12630fdc8d8SChris Lattner protected: 127b9c1b51eSKate Stone static bool GetBasicInfo(thread_t threadID, 128b9c1b51eSKate Stone struct thread_basic_info *basic_info); 12930fdc8d8SChris Lattner 130b9c1b51eSKate Stone bool GetIdentifierInfo(); 13130fdc8d8SChris Lattner 13230fdc8d8SChris Lattner // const char * 13330fdc8d8SChris Lattner // GetDispatchQueueName(); 13430fdc8d8SChris Lattner // 13530fdc8d8SChris Lattner MachProcess *m_process; // The process that owns this thread 1361c73911dSJason Molenda uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t) 137b9c1b51eSKate Stone thread_t m_mach_port_number; // The mach port # for this thread in debugserver 138b9c1b51eSKate Stone // namesp. 13930fdc8d8SChris Lattner uint32_t m_seq_id; // A Sequential ID that increments with each new thread 14030fdc8d8SChris Lattner nub_state_t m_state; // The state of our process 14130fdc8d8SChris Lattner PThreadMutex m_state_mutex; // Multithreaded protection for m_state 142b9c1b51eSKate Stone struct thread_basic_info m_basic_info; // Basic information for a thread used 143b9c1b51eSKate Stone // to see if a thread is valid 144b9c1b51eSKate Stone int32_t m_suspend_count; // The current suspend count > 0 means we have 145b9c1b51eSKate Stone // suspended m_suspendCount times, 146b9c1b51eSKate Stone // < 0 means we have resumed it m_suspendCount 147b9c1b51eSKate Stone // times. 148b9c1b51eSKate Stone MachException::Data m_stop_exception; // The best exception that describes why 149b9c1b51eSKate Stone // this thread is stopped 150b9c1b51eSKate Stone std::unique_ptr<DNBArchProtocol> 151d5b44036SJonas Devlieghere m_arch_up; // Arch specific information for register state and more 152b9c1b51eSKate Stone const DNBRegisterSetInfo 153b9c1b51eSKate Stone *m_reg_sets; // Register set information for this thread 154c235ac76SGreg Clayton nub_size_t m_num_reg_sets; 15530fdc8d8SChris Lattner thread_identifier_info_data_t m_ident_info; 15630fdc8d8SChris Lattner struct proc_threadinfo m_proc_threadinfo; 15730fdc8d8SChris Lattner std::string m_dispatch_queue_name; 158705b1809SJason Molenda bool m_is_64_bit; 159705b1809SJason Molenda 160b9c1b51eSKate Stone // qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *, 161b9c1b51eSKate Stone // unsigned long *); 162b9c1b51eSKate Stone unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *, 163b9c1b51eSKate Stone unsigned long *); 16430fdc8d8SChris Lattner 165a9b68f4dSJohnny Chen private: 166a9b68f4dSJohnny Chen friend class MachThreadList; 16730fdc8d8SChris Lattner }; 16830fdc8d8SChris Lattner 1697b0992d9SGreg Clayton typedef std::shared_ptr<MachThread> MachThreadSP; 17030fdc8d8SChris Lattner 17130fdc8d8SChris Lattner #endif 172