1 module mecca.platform.os.darwin.ucontext;
2 
3 version (OSX):
4 version (X86_64):
5 package(mecca):
6 
7 // Implements a platform agnostic interface to `ucontext_t`.
8 struct Ucontext
9 {
10     private ucontext_t context;
11 
12 nothrow:
13 @nogc:
14 
15     Mcontext uc_mcontext()
16     {
17         return Mcontext(context.uc_mcontext);
18     }
19 }
20 
21 struct Mcontext
22 {
23     private mcontext_t* context;
24 
25 nothrow:
26 @nogc:
27 
28     RegisterSet registers()
29     {
30         return RegisterSet(&context.__ss);
31     }
32 }
33 
34 struct RegisterSet
35 {
36     private __darwin_x86_thread_state64* state;
37 
38 nothrow:
39 @nogc:
40 
41     auto rax()
42     {
43         return state.__rax;
44     }
45 
46     auto rbx()
47     {
48         return state.__rbx;
49     }
50 
51     auto rcx()
52     {
53         return state.__rcx;
54     }
55 
56     auto rdx()
57     {
58         return state.__rdx;
59     }
60 
61     auto rdi()
62     {
63         return state.__rdi;
64     }
65 
66     auto rsi()
67     {
68         return state.__rsi;
69     }
70 
71     auto rbp()
72     {
73         return state.__rbp;
74     }
75 
76     auto rsp()
77     {
78         return state.__rsp;
79     }
80 
81     auto r8()
82     {
83         return state.__r8;
84     }
85 
86     auto r9()
87     {
88         return state.__r9;
89     }
90 
91     auto r10()
92     {
93         return state.__r10;
94     }
95 
96     auto r11()
97     {
98         return state.__r11;
99     }
100 
101     auto r12()
102     {
103         return state.__r12;
104     }
105 
106     auto r13()
107     {
108         return state.__r13;
109     }
110 
111     auto r14()
112     {
113         return state.__r14;
114     }
115 
116     auto r15()
117     {
118         return state.__r15;
119     }
120 
121     auto rip()
122     {
123         return state.__rip;
124     }
125 }
126 
127 // bindings
128 struct ucontext_t
129 {
130     int uc_onstack;
131     uint uc_sigmask;
132     stack_t uc_stack;
133     ucontext_t* uc_link;
134     size_t uc_mcsize;
135     mcontext_t* uc_mcontext;
136 }
137 
138 struct stack_t
139 {
140     void* ss_sp;
141     size_t ss_size;
142     int ss_flags;
143 }
144 
145 struct mcontext_t
146 {
147     __darwin_x86_exception_state64 __es;
148     __darwin_x86_thread_state64 __ss;
149     __darwin_x86_float_state64 __fs;
150 }
151 
152 struct __darwin_x86_exception_state64
153 {
154     ushort __trapno;
155     ushort __cpu;
156     uint __err;
157     ulong __faultvaddr;
158 }
159 
160 struct __darwin_x86_thread_state64
161 {
162     ulong __rax;
163     ulong __rbx;
164     ulong __rcx;
165     ulong __rdx;
166     ulong __rdi;
167     ulong __rsi;
168     ulong __rbp;
169     ulong __rsp;
170     ulong __r8;
171     ulong __r9;
172     ulong __r10;
173     ulong __r11;
174     ulong __r12;
175     ulong __r13;
176     ulong __r14;
177     ulong __r15;
178     ulong __rip;
179     ulong __rflags;
180     ulong __cs;
181     ulong __fs;
182     ulong __gs;
183 }
184 
185 struct __darwin_x86_float_state64
186 {
187     int[2] __fpu_reserved;
188     __darwin_fp_control __fpu_fcw; // x87 FPU control word
189     __darwin_fp_status __fpu_fsw; // x87 FPU status word
190     ubyte __fpu_ftw; // x87 FPU tag word
191     ubyte __fpu_rsrv1; // reserved
192     ushort __fpu_fop; // x87 FPU Opcode
193 
194     // x87 FPU Instruction Pointer
195     uint __fpu_ip; // offset
196     ushort __fpu_cs; // selector
197 
198     ushort __fpu_rsrv2; // reserved
199 
200     // x87 FPU Instruction Operand(Data) Pointer
201     uint __fpu_dp; // offset
202     ushort __fpu_ds; // Selector
203 
204     ushort __fpu_rsrv3; // reserved
205     uint __fpu_mxcsr; // MXCSR Register state
206     uint __fpu_mxcsrmask; // MXCSR mask
207     __darwin_mmst_reg __fpu_stmm0; // ST0/MM0
208     __darwin_mmst_reg __fpu_stmm1; // ST1/MM1
209     __darwin_mmst_reg __fpu_stmm2; // ST2/MM2
210     __darwin_mmst_reg __fpu_stmm3; // ST3/MM3
211     __darwin_mmst_reg __fpu_stmm4; // ST4/MM4
212     __darwin_mmst_reg __fpu_stmm5; // ST5/MM5
213     __darwin_mmst_reg __fpu_stmm6; // ST6/MM6
214     __darwin_mmst_reg __fpu_stmm7; // ST7/MM7
215     __darwin_xmm_reg __fpu_xmm0; // XMM 0
216     __darwin_xmm_reg __fpu_xmm1; // XMM 1
217     __darwin_xmm_reg __fpu_xmm2; // XMM 2
218     __darwin_xmm_reg __fpu_xmm3; // XMM 3
219     __darwin_xmm_reg __fpu_xmm4; // XMM 4
220     __darwin_xmm_reg __fpu_xmm5; // XMM 5
221     __darwin_xmm_reg __fpu_xmm6; // XMM 6
222     __darwin_xmm_reg __fpu_xmm7; // XMM 7
223     __darwin_xmm_reg __fpu_xmm8; // XMM 8
224     __darwin_xmm_reg __fpu_xmm9; // XMM 9
225     __darwin_xmm_reg __fpu_xmm10; // XMM 10
226     __darwin_xmm_reg __fpu_xmm11; // XMM 11
227     __darwin_xmm_reg __fpu_xmm12; // XMM 12
228     __darwin_xmm_reg __fpu_xmm13; // XMM 13
229     __darwin_xmm_reg __fpu_xmm14; // XMM 14
230     __darwin_xmm_reg __fpu_xmm15; // XMM 15
231     char[6 * 16] __fpu_rsrv4; // reserved
232     int __fpu_reserved1;
233 }
234 
235 struct __darwin_fp_control
236 {
237     import std.bitmanip : bitfields;
238 
239     mixin(bitfields!(
240         ushort, "__invalid", 1,
241         ushort, "__denorm", 1,
242         ushort, "__zdiv", 1,
243         ushort, "__ovrfl", 1,
244         ushort, "__undfl", 1,
245         ushort, "__precis", 1,
246         ushort, "", 2,
247         ushort, "__pc", 2,
248         ushort, "__rc", 2,
249         ushort, "", 1,
250         ushort, "", 3));
251 }
252 
253 struct __darwin_fp_status
254 {
255     import std.bitmanip : bitfields;
256 
257     mixin(bitfields!(
258         ushort, "__invalid", 1,
259         ushort, "__denorm", 1,
260         ushort, "__zdiv", 1,
261         ushort, "__ovrfl", 1,
262         ushort, "__undfl", 1,
263         ushort, "__precis", 1,
264         ushort, "__stkflt", 1,
265         ushort, "__errsumm", 1,
266         ushort, "__c0", 1,
267         ushort, "__c1", 1,
268         ushort, "__c2", 1,
269         ushort, "__tos", 3,
270         ushort, "__c3", 1,
271         ushort, "__busy", 1));
272 }
273 
274 struct __darwin_mmst_reg
275 {
276     char[10] __mmst_reg;
277     char[6] __mmst_rsrv;
278 }
279 
280 struct __darwin_xmm_reg
281 {
282     char[16] __xmm_reg;
283 }