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
32class DNBBreakpoint;
33class MachProcess;
34class MachThreadList;
35
36class MachThread {
37public:
38 MachThread(MachProcess *process, bool is_64_bit,
39 uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
40 ~MachThread();
41
42 MachProcess *Process() { return m_process; }
43 const MachProcess *Process() const { return m_process; }
44 nub_process_t ProcessID() const;
45 void Dump(uint32_t index);
46 uint64_t ThreadID() const { return m_unique_id; }
47 thread_t MachPortNumber() const { return m_mach_port_number; }
48 thread_t InferiorThreadID() const;
49
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);
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
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
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
126protected:
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
165private:
166 friend class MachThreadList;
167};
168
169typedef std::shared_ptr<MachThread> MachThreadSP;
170
171#endif
172

source code of lldb/tools/debugserver/source/MacOSX/MachThread.h