1 /**
2  * D header file for Darwin.
3  *
4  * Copyright: Copyright Sean Kelly 2008 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly
7  */
8 
9 /*          Copyright Sean Kelly 2008 - 2009.
10  * Distributed under the Boost Software License, Version 1.0.
11  *    (See accompanying file LICENSE or copy at
12  *          http://www.boost.org/LICENSE_1_0.txt)
13  */
14 module core.sys.darwin.mach.thread_act;
15 
16 version (OSX)
17     version = Darwin;
18 else version (iOS)
19     version = Darwin;
20 else version (TVOS)
21     version = Darwin;
22 else version (WatchOS)
23     version = Darwin;
24 
25 version (Darwin):
26 extern (C):
27 nothrow:
28 @nogc:
29 
30 public import core.sys.darwin.mach.kern_return;
31 public import core.sys.darwin.mach.port;
32 
33 version (X86)
34     version = i386;
35 version (X86_64)
36     version = i386;
37 version (AArch64)
38     version = AnyARM;
39 version (ARM)
40     version = AnyARM;
41 version (PPC)
42     version = AnyPPC;
43 version (PPC64)
44     version = AnyPPC;
45 
46 version (i386)
47 {
48     alias mach_port_t thread_act_t;
49     alias void        thread_state_t;
50     alias int         thread_state_flavor_t;
51     alias natural_t   mach_msg_type_number_t;
52 
53     enum
54     {
55         x86_THREAD_STATE32      = 1,
56         x86_FLOAT_STATE32       = 2,
57         x86_EXCEPTION_STATE32   = 3,
58         x86_THREAD_STATE64      = 4,
59         x86_FLOAT_STATE64       = 5,
60         x86_EXCEPTION_STATE64   = 6,
61         x86_THREAD_STATE        = 7,
62         x86_FLOAT_STATE         = 8,
63         x86_EXCEPTION_STATE     = 9,
64         x86_DEBUG_STATE32       = 10,
65         x86_DEBUG_STATE64       = 11,
66         x86_DEBUG_STATE         = 12,
67         THREAD_STATE_NONE       = 13,
68     }
69 
70     struct x86_thread_state32_t
71     {
72         uint    eax;
73         uint    ebx;
74         uint    ecx;
75         uint    edx;
76         uint    edi;
77         uint    esi;
78         uint    ebp;
79         uint    esp;
80         uint    ss;
81         uint    eflags;
82         uint    eip;
83         uint    cs;
84         uint    ds;
85         uint    es;
86         uint    fs;
87         uint    gs;
88     }
89 
90     struct x86_thread_state64_t
91     {
92         ulong   rax;
93         ulong   rbx;
94         ulong   rcx;
95         ulong   rdx;
96         ulong   rdi;
97         ulong   rsi;
98         ulong   rbp;
99         ulong   rsp;
100         ulong   r8;
101         ulong   r9;
102         ulong   r10;
103         ulong   r11;
104         ulong   r12;
105         ulong   r13;
106         ulong   r14;
107         ulong   r15;
108         ulong   rip;
109         ulong   rflags;
110         ulong   cs;
111         ulong   fs;
112         ulong   gs;
113     }
114 
115     struct x86_state_hdr_t
116     {
117         int     flavor;
118         int     count;
119     }
120 
121     struct x86_thread_state_t
122     {
123         x86_state_hdr_t             tsh;
124         union _uts
125         {
126             x86_thread_state32_t    ts32;
127             x86_thread_state64_t    ts64;
128         }
129         _uts                        uts;
130     }
131 
132     enum : mach_msg_type_number_t
133     {
134         x86_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t)( x86_thread_state32_t.sizeof / int.sizeof ),
135         x86_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t)( x86_thread_state64_t.sizeof / int.sizeof ),
136         x86_THREAD_STATE_COUNT   = cast(mach_msg_type_number_t)( x86_thread_state_t.sizeof / int.sizeof ),
137     }
138 
139     alias x86_THREAD_STATE          MACHINE_THREAD_STATE;
140     alias x86_THREAD_STATE_COUNT    MACHINE_THREAD_STATE_COUNT;
141 
142     mach_port_t   mach_thread_self();
143     kern_return_t thread_suspend(thread_act_t);
144     kern_return_t thread_resume(thread_act_t);
145     kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
146 }
147 // https://github.com/apple/darwin-xnu/blob/master/osfmk/mach/arm/_structs.h
148 // https://github.com/apple/darwin-xnu/blob/master/osfmk/mach/arm/thread_status.h
149 else version (AnyARM)
150 {
151     alias thread_act_t = mach_port_t;
152     alias thread_state_t = void;
153     alias thread_state_flavor_t = int;
154     alias mach_msg_type_number_t = natural_t;
155 
156     enum
157     {
158         ARM_THREAD_STATE = 1,
159         ARM_UNIFIED_THREAD_STATE = ARM_THREAD_STATE,
160         ARM_VFP_STATE = 2,
161         ARM_EXCEPTION_STATE = 3,
162         ARM_DEBUG_STATE = 4, /* pre-armv8 */
163         THREAD_STATE_NONE = 5,
164         ARM_THREAD_STATE64 = 6,
165         ARM_EXCEPTION_STATE64 = 7,
166         // ARM_THREAD_STATE_LAST = 8, /* legacy */
167         ARM_THREAD_STATE32 = 9
168     }
169 
170     enum
171     {
172         ARM_DEBUG_STATE32 = 14,
173         ARM_DEBUG_STATE64 = 15,
174         ARM_NEON_STATE = 16,
175         ARM_NEON_STATE64 = 17,
176         ARM_CPMU_STATE64 = 18
177     }
178 
179     enum
180     {
181         ARM_AMX_STATE = 24,
182         ARM_AMX_STATE_V1 = 25
183     }
184 
185     struct arm_thread_state_t
186     {
187         uint[13] r; /// General purpose register r0-r12
188         uint sp;    /// Stack pointer r13
189         uint lr;    /// Link register r14
190         uint pc;    /// Program counter r15
191         uint cpsr;  /// Current program status register
192     }
193 
194     alias arm_thread_state32_t = arm_thread_state_t;
195 
196     struct arm_thread_state64_t
197     {
198         ulong[29] x; /// General purpose registers x0-x28
199         ulong fp; /// Frame pointer x29
200         ulong lr; /// Link register x30
201         ulong sp; /// Stack pointer x31
202         ulong pc; /// Program counter
203         ulong cpsr; /// Current program status register
204         ulong pad; /// Same size for 32-bit or 64-bit clients
205     }
206 
207     struct arm_state_hdr_t
208     {
209         uint flavor;
210         uint count;
211     }
212 
213     struct arm_unified_thread_state_t
214     {
215         arm_state_hdr_t ash;
216 
217         union _uts
218         {
219             arm_thread_state32_t ts_32;
220             arm_thread_state64_t ts_64;
221         }
222 
223         _uts uts;
224     }
225 
226     enum : mach_msg_type_number_t
227     {
228         ARM_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (arm_thread_state_t.sizeof / uint.sizeof),
229         ARM_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (arm_thread_state32_t.sizeof / uint.sizeof),
230         ARM_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (arm_thread_state64_t.sizeof / uint.sizeof),
231         ARM_UNIFIED_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (arm_unified_thread_state_t.sizeof / uint.sizeof)
232     }
233 
234     alias MACHINE_THREAD_STATE = ARM_THREAD_STATE;
235     alias MACHINE_THREAD_STATE_COUNT = ARM_UNIFIED_THREAD_STATE_COUNT;
236 
237     mach_port_t   mach_thread_self();
238     kern_return_t thread_suspend(thread_act_t);
239     kern_return_t thread_resume(thread_act_t);
240     kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
241 }
242 else version (AnyPPC)
243 {
244     alias thread_act_t = mach_port_t;
245     alias thread_state_t = void;
246     alias thread_state_flavor_t = int;
247     alias mach_msg_type_number_t = natural_t;
248 
249     enum
250     {
251         PPC_THREAD_STATE = 1,
252         PPC_FLOAT_STATE = 2,
253         PPC_EXCEPTION_STATE = 3,
254         PPC_VECTOR_STATE = 4,
255         PPC_THREAD_STATE64 = 5,
256         PPC_EXCEPTION_STATE64 = 6,
257         THREAD_STATE_NONE = 7
258     }
259 
260     struct ppc_thread_state_t
261     {
262         uint srr0;   /// Instruction address register (PC)
263         uint srr1;   /// Machine state register (supervisor)
264         uint[32] r;  /// General purpose register r0-r31
265         uint cr;     /// Condition register
266         uint xer;    /// User's integer exception register
267         uint lr;     /// Link register
268         uint ctr;    /// Count register
269         uint mq;     /// MQ register (601 only)
270         uint vrsave; /// Vector save register
271     }
272 
273     alias ppc_thread_state32_t = ppc_thread_state_t;
274 
275     struct ppc_thread_state64_t
276     {
277         ulong srr0;   /// Instruction address register (PC)
278         ulong srr1;   /// Machine state register (supervisor)
279         ulong[32] r;  /// General purpose register r0-r31
280         uint cr;      /// Condition register
281         uint pad0;
282         ulong xer;    /// User's integer exception register
283         ulong lr;     /// Link register
284         ulong ctr;    /// Count register
285         uint vrsave;  /// Vector save register
286         uint pad1;
287     }
288 
289     enum : mach_msg_type_number_t
290     {
291         PPC_THREAD_STATE_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state_t.sizeof / uint.sizeof),
292         PPC_THREAD_STATE32_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state32_t.sizeof / uint.sizeof),
293         PPC_THREAD_STATE64_COUNT = cast(mach_msg_type_number_t) (ppc_thread_state64_t.sizeof / uint.sizeof),
294     }
295 
296     alias MACHINE_THREAD_STATE = PPC_THREAD_STATE;
297     alias MACHINE_THREAD_STATE_COUNT = PPC_THREAD_STATE_COUNT;
298 
299     mach_port_t   mach_thread_self();
300     kern_return_t thread_suspend(thread_act_t);
301     kern_return_t thread_resume(thread_act_t);
302     kern_return_t thread_get_state(thread_act_t, thread_state_flavor_t, thread_state_t*, mach_msg_type_number_t*);
303 }