xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.h (revision dda2819751e49c83612958492e38917049128b41)
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