1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Public Domain
5  * License:   Public Domain
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 module tango.stdc.posix.ucontext;
10 
11 private import tango.stdc.posix.config;
12 public import tango.stdc.posix.signal; // for sigset_t, stack_t
13 
14 extern (C):
15 
16 //
17 // XOpen (XSI)
18 //
19 /*
20 mcontext_t
21 
22 struct ucontext_t
23 {
24     ucontext_t* uc_link;
25     sigset_t    uc_sigmask;
26     stack_t     uc_stack;
27     mcontext_t  uc_mcontext;
28 }
29 */
30 
31 version( linux )
32 {
33 
34     version( X86_64 )
35     {
36         private
37         {
38             struct _libc_fpxreg
39             {
40                 ushort[4] significand;
41                 ushort    exponent;
42                 ushort[3] padding;
43             }
44 
45             struct _libc_xmmreg
46             {
47                 uint[4] element;
48             }
49 
50             struct _libc_fpstate
51             {
52                 ushort           cwd;
53                 ushort           swd;
54                 ushort           ftw;
55                 ushort           fop;
56                 ulong            rip;
57                 ulong            rdp;
58                 uint             mxcsr;
59                 uint             mxcr_mask;
60                 _libc_fpxreg[8]  _st;
61                 _libc_xmmreg[16] _xmm;
62                 uint[24]         padding;
63             }
64 
65             const NGREG = 23;
66 
67             alias c_long            greg_t;
68             alias greg_t[NGREG]     gregset_t;
69             alias _libc_fpstate*    fpregset_t;
70         }
71 
72         struct mcontext_t
73         {
74             gregset_t   gregs;
75             fpregset_t  fpregs;
76             c_ulong[8]  __reserved1;
77         }
78 
79         struct ucontext_t
80         {
81             c_ulong         uc_flags;
82             ucontext_t*     uc_link;
83             stack_t         uc_stack;
84             mcontext_t      uc_mcontext;
85             sigset_t        uc_sigmask;
86             _libc_fpstate   __fpregs_mem;
87         }
88     }
89     else version( X86 )
90     {
91         private
92         {
93             struct _libc_fpreg
94             {
95               ushort[4] significand;
96               ushort    exponent;
97             }
98 
99             struct _libc_fpstate
100             {
101               c_ulong           cw;
102               c_ulong           sw;
103               c_ulong           tag;
104               c_ulong           ipoff;
105               c_ulong           cssel;
106               c_ulong           dataoff;
107               c_ulong           datasel;
108               _libc_fpreg[8]    _st;
109               c_ulong           status;
110             }
111 
112             const NGREG = 19;
113 
114             alias int               greg_t;
115             alias greg_t[NGREG]     gregset_t;
116             alias _libc_fpstate*    fpregset_t;
117         }
118 
119         struct mcontext_t
120         {
121             gregset_t   gregs;
122             fpregset_t  fpregs;
123             c_ulong     oldmask;
124             c_ulong     cr2;
125         }
126 
127         struct ucontext_t
128         {
129             c_ulong         uc_flags;
130             ucontext_t*     uc_link;
131             stack_t         uc_stack;
132             mcontext_t      uc_mcontext;
133             sigset_t        uc_sigmask;
134             _libc_fpstate   __fpregs_mem;
135         }
136     }
137 }
138 
139 version(OSX){
140     struct mcontext_t{
141         int undefined; /// this is architecture dependent, if you need it, then define it from the header files
142     }
143     
144     struct stack_t{
145      void *ss_sp;
146      size_t ss_size;
147      int ss_flags;
148     }
149     
150     alias uint sigset_t;
151     struct ucontext_t
152     {
153         int uc_onstack;
154         sigset_t uc_sigmask;
155         stack_t uc_stack;
156         ucontext_t* uc_link;
157         size_t uc_mcsize;
158         mcontext_t*uc_mcontext;
159     }
160 }
161 
162 version( FreeBSD ) {
163     alias int	__register_t;
164     alias int	c_int;
165     struct mcontext_t { /* from /usr/include/machine/ucontext.h */
166         __register_t    mc_onstack;     /* XXX - sigcontext compat. */
167         __register_t    mc_gs;          /* machine state (struct trapframe) */
168         __register_t    mc_fs;
169         __register_t    mc_es;
170         __register_t    mc_ds;
171         __register_t    mc_edi;
172         __register_t    mc_esi;
173         __register_t    mc_ebp;
174         __register_t    mc_isp;
175         __register_t    mc_ebx;
176         __register_t    mc_edx;
177         __register_t    mc_ecx;
178         __register_t    mc_eax;
179         __register_t    mc_trapno;
180         __register_t    mc_err;
181         __register_t    mc_eip;
182         __register_t    mc_cs;
183         __register_t    mc_eflags;
184         __register_t    mc_esp;
185         __register_t    mc_ss;
186 
187         c_int     	mc_len;                 /* sizeof(mcontext_t) */
188         c_int    	mc_fpformat;
189         c_int    	mc_ownedfp;
190         c_int[1]     mc_spare1;           /* align next field to 16 bytes */
191         c_int[128]  mc_fpstate ; // __aligned(16)
192         c_int[8]     mc_spare2;
193     }
194 
195     enum {
196         _MC_FPFMT_NODEV        = 0x10000, /* device not present or configured */
197         _MC_FPFMT_387           = 0x10001,
198         _MC_FPFMT_XMM           = 0x10002,
199 
200         _MC_FPOWNED_NONE        = 0x20000, /* FP state not used */
201         _MC_FPOWNED_FPU         = 0x20001, /* FP state came from FPU */
202         _MC_FPOWNED_PCB         = 0x20002,  /* FP state came from PCB */
203     }
204 
205     alias uint sigset_t;
206     struct ucontext_t { /* from /usr/include/ucontext.h */
207         sigset_t 		uc_sigmask;
208         mcontext_t		uc_mcontext;
209         ucontext_t*		uc_link;
210         stack_t		uc_stack;
211         c_int			uc_flags;
212         c_int[4]		__spare__;
213     }
214 }
215 
216 version(solaris)
217 {
218     alias uint[4] upad128_t;
219 
220     version( X86 )
221     {
222         const  NGREG = 19;
223         alias int greg_t;
224         
225         /*
226         * This definition of the floating point structure is binary
227         * compatible with the Intel386 psABI definition, and source
228         * compatible with that specification for x87-style floating point.
229         * It also allows SSE/SSE2 state to be accessed on machines that
230         * possess such hardware capabilities.
231         */
232         struct fpregset_t {
233             union fp_reg_set_ {
234                 struct fpchip_state_ {
235                     uint[27] state;	/* 287/387 saved state */
236                     uint status;	/* saved at exception */
237                     uint mxcsr;		/* SSE control and status */
238                     uint xstatus;	/* SSE mxcsr at exception */
239                     uint[2] __pad;	/* align to 128-bits */
240                     upad128_t[8] xmm;	/* %xmm0-%xmm7 */
241                 };
242                 fpchip_state_ fpchip_state;
243                 struct fp_emul_space_ {		/* for emulator(s) */
244                     ubyte[246]	fp_emul;
245                     ubyte[2]	fp_epad;
246                 };
247                 fp_emul_space_ fp_emul_space;
248                 uint[95]	f_fpregs;	/* union of the above */
249             };
250             fp_reg_set_ fp_reg_set;
251         };
252     }
253     else version( X86_64 )
254     {
255         const NGREG = 28;
256         alias c_long greg_t;
257 
258         struct fpregset_t {
259             union fp_reg_set_ {
260                 struct fpchip_state_ {
261                     ushort cw;
262                     ushort sw;
263                     ubyte  fctw;
264                     ubyte  __fx_rsvd;
265                     ushort fop;
266                     ulong rip;
267                     ulong rdp;
268                     uint mxcsr;
269                     uint mxcsr_mask;
270                     union st_ {
271                         ushort[5] fpr_16;
272                         upad128_t __fpr_pad;
273                     };
274                     st_[8] st;
275                     upad128_t[16] xmm;
276                     upad128_t[6] __fx_ign2;
277                     uint status;	/* sw at exception */
278                     uint xstatus;	/* mxcsr at exception */
279                 } 
280                 fpchip_state_   fpchip_state;
281                 uint[130] f_fpregs;
282             };
283             fp_reg_set_ fp_reg_set;
284         };
285     }
286     
287     alias greg_t[NGREG] gregset_t;
288 
289     struct mcontext_t
290     {
291         gregset_t	gregs;		/* general register set */
292         fpregset_t	fpregs;		/* floating point register set */
293     }
294 
295     struct stack_t
296     {
297         void* ss_sp;
298         size_t ss_size;
299         int ss_flags;
300     }
301     
302     struct ucontext_t /* from /usr/include/sys/ucontext.h*/
303     {
304         c_ulong uc_flags;
305         ucontext_t *uc_link;
306         sigset_t uc_sigmask;
307         stack_t uc_stack;
308         mcontext_t 	uc_mcontext;
309         c_long[5] uc_filler;	/* see ABI spec for Intel386 */
310     }
311 }
312 
313 //
314 // Obsolescent (OB)
315 //
316 /*
317 int  getcontext(ucontext_t*);
318 void makecontext(ucontext_t*, void function(), int, ...);
319 int  setcontext(in ucontext_t*);
320 int  swapcontext(ucontext_t*, in ucontext_t*);
321 */
322 
323 static if( is( ucontext_t ) )
324 {
325     int  getcontext(ucontext_t*);
326     void makecontext(ucontext_t*, void function(), int, ...);
327     int  setcontext(in ucontext_t*);
328     int  swapcontext(ucontext_t*, in ucontext_t*);
329 }