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