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 #include <tr1/memory> // for std::tr1::shared_ptr
20 
21 #include <libproc.h>
22 #include <mach/mach.h>
23 #include <pthread.h>
24 #include <sys/signal.h>
25 
26 #include "PThreadCondition.h"
27 #include "PThreadMutex.h"
28 #include "MachException.h"
29 #include "DNBArch.h"
30 #include "DNBRegisterInfo.h"
31 
32 class DNBBreakpoint;
33 class MachProcess;
34 class MachThreadList;
35 
36 class MachThread
37 {
38 public:
39 
40                     MachThread (MachProcess *process, thread_t thread = 0);
41                     ~MachThread ();
42 
43     MachProcess *   Process() { return m_process; }
44     const MachProcess *
45                     Process() const { return m_process; }
46     nub_process_t   ProcessID() const;
47     void            Dump(uint32_t index);
48     thread_t        ThreadID() const { return m_tid; }
49     thread_t        InferiorThreadID() const;
50 
51     uint32_t        SequenceID() const { return m_seq_id; }
52     static bool     ThreadIDIsValid(thread_t thread);
53     void            Resume(bool others_stopped);
54     void            Suspend();
55     bool            SetSuspendCountBeforeResume(bool others_stopped);
56     bool            RestoreSuspendCountAfterStop();
57 
58     bool            GetRegisterState(int flavor, bool force);
59     bool            SetRegisterState(int flavor);
60     uint64_t        GetPC(uint64_t failValue = INVALID_NUB_ADDRESS);    // Get program counter
61     bool            SetPC(uint64_t value);                              // Set program counter
62     uint64_t        GetSP(uint64_t failValue = INVALID_NUB_ADDRESS);    // Get stack pointer
63 
64     nub_break_t     CurrentBreakpoint();
65     uint32_t        EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
66     uint32_t        EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
67     bool            DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
68     bool            DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
69 
70     nub_state_t     GetState();
71     void            SetState(nub_state_t state);
72 
73     void            ThreadWillResume (const DNBThreadResumeAction *thread_action, bool others_stopped = false);
74     bool            ShouldStop(bool &step_more);
75     bool            IsStepping();
76     bool            ThreadDidStop();
77     bool            NotifyException(MachException::Data& exc);
78     const MachException::Data& GetStopException() { return m_stop_exception; }
79 
80     uint32_t        GetNumRegistersInSet(int regSet) const;
81     const char *    GetRegisterSetName(int regSet) const;
82     const DNBRegisterInfo *
83                     GetRegisterInfo(int regSet, int regIndex) const;
84     void            DumpRegisterState(int regSet);
85     const DNBRegisterSetInfo *
86                     GetRegisterSetInfo(nub_size_t *num_reg_sets ) const;
87     bool            GetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value );
88     bool            SetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value );
89     nub_size_t      GetRegisterContext (void *buf, nub_size_t buf_len);
90     nub_size_t      SetRegisterContext (const void *buf, nub_size_t buf_len);
91     void            NotifyBreakpointChanged (const DNBBreakpoint *bp)
92                     {
93                     }
94 
95     bool            IsUserReady();
96     struct thread_basic_info *
97                     GetBasicInfo ();
98     const char *    GetBasicInfoAsString () const;
99     const char *    GetName ();
100 
101     DNBArchProtocol*
102     GetArchProtocol()
103     {
104         return m_arch_ap.get();
105     }
106 
107 protected:
108     static bool     GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
109 
110     bool
111     GetIdentifierInfo ();
112 
113 //    const char *
114 //    GetDispatchQueueName();
115 //
116     MachProcess *                   m_process;      // The process that owns this thread
117     thread_t                        m_tid;          // The thread port for this thread
118     uint32_t                        m_seq_id;       // A Sequential ID that increments with each new thread
119     nub_state_t                     m_state;        // The state of our process
120     PThreadMutex                    m_state_mutex;  // Multithreaded protection for m_state
121     nub_break_t                     m_break_id;     // Breakpoint that this thread is (stopped)/was(running) at (NULL for none)
122     struct thread_basic_info        m_basic_info;   // Basic information for a thread used to see if a thread is valid
123     int32_t                         m_suspend_count; // The current suspend count > 0 means we have suspended m_suspendCount times,
124                                                     //                           < 0 means we have resumed it m_suspendCount times.
125     MachException::Data             m_stop_exception; // The best exception that describes why this thread is stopped
126     std::auto_ptr<DNBArchProtocol>  m_arch_ap;      // Arch specific information for register state and more
127     const DNBRegisterSetInfo *      m_reg_sets;      // Register set information for this thread
128     nub_size_t                      m_num_reg_sets;
129 #ifdef THREAD_IDENTIFIER_INFO_COUNT
130     thread_identifier_info_data_t   m_ident_info;
131     struct proc_threadinfo          m_proc_threadinfo;
132     std::string                     m_dispatch_queue_name;
133 #endif
134 
135 private:
136     friend class MachThreadList;
137     void HardwareWatchpointStateChanged(); // Provide a chance to update the global view of the hardware watchpoint state
138 };
139 
140 typedef std::tr1::shared_ptr<MachThread> MachThreadSP;
141 
142 #endif
143