The OpenD Programming Language

1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 
10 /*          Copyright Sean Kelly 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module core.sys.posix.ucontext;
16 
17 import core.sys.posix.config;
18 public import core.sys.posix.signal; // for sigset_t, stack_t
19 import core.stdc.stdint : uintptr_t;
20 
21 version (Posix):
22 extern (C):
23 nothrow:
24 @nogc:
25 
26 version (OSX)
27     version = Darwin;
28 else version (iOS)
29     version = Darwin;
30 else version (TVOS)
31     version = Darwin;
32 else version (WatchOS)
33     version = Darwin;
34 
35 version (ARM)     version = ARM_Any;
36 version (AArch64) version = ARM_Any;
37 version (MIPS32)  version = MIPS_Any;
38 version (MIPS64)  version = MIPS_Any;
39 version (PPC)     version = PPC_Any;
40 version (PPC64)   version = PPC_Any;
41 version (RISCV32) version = RISCV_Any;
42 version (RISCV64) version = RISCV_Any;
43 version (S390)    version = IBMZ_Any;
44 version (SPARC)   version = SPARC_Any;
45 version (SPARC64) version = SPARC_Any;
46 version (SystemZ) version = IBMZ_Any;
47 version (X86)     version = X86_Any;
48 version (X86_64)  version = X86_Any;
49 
50 version (WebAssembly)  version = X86_Any; // FIXME?
51 
52 //
53 // XOpen (XSI)
54 //
55 /*
56 mcontext_t
57 
58 struct ucontext_t
59 {
60     ucontext_t* uc_link;
61     sigset_t    uc_sigmask;
62     stack_t     uc_stack;
63     mcontext_t  uc_mcontext;
64 }
65 */
66 
67 version (linux)
68 {
69     version (X86_64)
70     {
71         enum
72         {
73             REG_R8 = 0,
74             REG_R9,
75             REG_R10,
76             REG_R11,
77             REG_R12,
78             REG_R13,
79             REG_R14,
80             REG_R15,
81             REG_RDI,
82             REG_RSI,
83             REG_RBP,
84             REG_RBX,
85             REG_RDX,
86             REG_RAX,
87             REG_RCX,
88             REG_RSP,
89             REG_RIP,
90             REG_EFL,
91             REG_CSGSFS,     /* Actually short cs, gs, fs, __pad0.  */
92             REG_ERR,
93             REG_TRAPNO,
94             REG_OLDMASK,
95             REG_CR2
96         }
97 
98         private
99         {
100             struct _libc_fpxreg
101             {
102                 ushort[4] significand;
103                 ushort    exponent;
104                 ushort[3] padding;
105             }
106 
107             struct _libc_xmmreg
108             {
109                 uint[4] element;
110             }
111 
112             struct _libc_fpstate
113             {
114                 ushort           cwd;
115                 ushort           swd;
116                 ushort           ftw;
117                 ushort           fop;
118                 ulong            rip;
119                 ulong            rdp;
120                 uint             mxcsr;
121                 uint             mxcr_mask;
122                 _libc_fpxreg[8]  _st;
123                 _libc_xmmreg[16] _xmm;
124                 uint[24]         padding;
125             }
126 
127             enum NGREG = 23;
128 
129             alias long              greg_t;
130             alias greg_t[NGREG]     gregset_t;
131             alias _libc_fpstate*    fpregset_t;
132         }
133 
134         struct mcontext_t
135         {
136             gregset_t   gregs;
137             fpregset_t  fpregs;
138             ulong[8]    __reserved1;
139         }
140 
141         struct ucontext_t
142         {
143             c_ulong         uc_flags;
144             ucontext_t*     uc_link;
145             stack_t         uc_stack;
146             mcontext_t      uc_mcontext;
147             sigset_t        uc_sigmask;
148             _libc_fpstate   __fpregs_mem;
149             version (CRuntime_Glibc)
150                 ulong[4]    __ssp;
151         }
152     }
153     else version (X86)
154     {
155         enum
156         {
157             REG_GS = 0,
158             REG_FS,
159             REG_ES,
160             REG_DS,
161             REG_EDI,
162             REG_ESI,
163             REG_EBP,
164             REG_ESP,
165             REG_EBX,
166             REG_EDX,
167             REG_ECX,
168             REG_EAX,
169             REG_TRAPNO,
170             REG_ERR,
171             REG_EIP,
172             REG_CS,
173             REG_EFL,
174             REG_UESP,
175             REG_SS
176         }
177 
178         private
179         {
180             struct _libc_fpreg
181             {
182               ushort[4] significand;
183               ushort    exponent;
184             }
185 
186             struct _libc_fpstate
187             {
188               c_ulong           cw;
189               c_ulong           sw;
190               c_ulong           tag;
191               c_ulong           ipoff;
192               c_ulong           cssel;
193               c_ulong           dataoff;
194               c_ulong           datasel;
195               _libc_fpreg[8]    _st;
196               c_ulong           status;
197             }
198 
199             enum NGREG = 19;
200 
201             alias int               greg_t;
202             alias greg_t[NGREG]     gregset_t;
203             alias _libc_fpstate*    fpregset_t;
204         }
205 
206         struct mcontext_t
207         {
208             gregset_t   gregs;
209             fpregset_t  fpregs;
210             c_ulong     oldmask;
211             c_ulong     cr2;
212         }
213 
214         struct ucontext_t
215         {
216             c_ulong         uc_flags;
217             ucontext_t*     uc_link;
218             stack_t         uc_stack;
219             mcontext_t      uc_mcontext;
220             sigset_t        uc_sigmask;
221             _libc_fpstate   __fpregs_mem;
222             version (CRuntime_Glibc)
223                 c_ulong[4]  __ssp;
224         }
225     }
226     else version (HPPA)
227     {
228         private
229         {
230             enum NGREG  = 80;
231             enum NFPREG = 32;
232 
233             alias c_ulong greg_t;
234 
235             struct gregset_t
236             {
237                 greg_t[32] g_regs;
238                 greg_t[8] sr_regs;
239                 greg_t[24] cr_regs;
240                 greg_t[16] g_pad;
241             }
242 
243             struct fpregset_t
244             {
245                 double[32] fpregs;
246             }
247         }
248 
249         struct mcontext_t
250         {
251             greg_t sc_flags;
252             greg_t[32] sc_gr;
253             fpregset_t sc_fr;
254             greg_t[2] sc_iasq;
255             greg_t[2] sc_iaoq;
256             greg_t sc_sar;
257         }
258 
259         struct ucontext_t
260         {
261             c_ulong uc_flags;
262             ucontext_t* uc_link;
263             stack_t uc_stack;
264             mcontext_t uc_mcontext;
265             sigset_t uc_sigmask;
266         }
267     }
268     else version (MIPS32)
269     {
270         private
271         {
272             enum NGREG  = 32;
273             enum NFPREG = 32;
274 
275             alias ulong         greg_t;
276             alias greg_t[NGREG] gregset_t;
277 
278             struct fpregset_t
279             {
280                 union fp_r_t
281                 {
282                     double[NFPREG]  fp_dregs;
283                     static struct fp_fregs_t
284                     {
285                         float   _fp_fregs;
286                         uint    _fp_pad;
287                     } fp_fregs_t[NFPREG] fp_fregs;
288                 } fp_r_t fp_r;
289             }
290         }
291 
292         version (MIPS_O32)
293         {
294             struct mcontext_t
295             {
296                 uint regmask;
297                 uint status;
298                 greg_t pc;
299                 gregset_t gregs;
300                 fpregset_t fpregs;
301                 uint fp_owned;
302                 uint fpc_csr;
303                 uint fpc_eir;
304                 uint used_math;
305                 uint dsp;
306                 greg_t mdhi;
307                 greg_t mdlo;
308                 c_ulong hi1;
309                 c_ulong lo1;
310                 c_ulong hi2;
311                 c_ulong lo2;
312                 c_ulong hi3;
313                 c_ulong lo3;
314             }
315         }
316         else
317         {
318             struct mcontext_t
319             {
320                 gregset_t gregs;
321                 fpregset_t fpregs;
322                 greg_t mdhi;
323                 greg_t hi1;
324                 greg_t hi2;
325                 greg_t hi3;
326                 greg_t mdlo;
327                 greg_t lo1;
328                 greg_t lo2;
329                 greg_t lo3;
330                 greg_t pc;
331                 uint fpc_csr;
332                 uint used_math;
333                 uint dsp;
334                 uint reserved;
335             }
336         }
337 
338         struct ucontext_t
339         {
340             c_ulong     uc_flags;
341             ucontext_t* uc_link;
342             stack_t     uc_stack;
343             mcontext_t  uc_mcontext;
344             sigset_t    uc_sigmask;
345         }
346     }
347     else version (MIPS64)
348     {
349         private
350         {
351             enum NGREG  = 32;
352             enum NFPREG = 32;
353 
354             alias ulong         greg_t;
355             alias greg_t[NGREG] gregset_t;
356 
357             struct fpregset_t
358             {
359                 union fp_r_t
360                 {
361                     double[NFPREG]  fp_dregs;
362                     static struct fp_fregs_t
363                     {
364                         float   _fp_fregs;
365                         uint    _fp_pad;
366                     } fp_fregs_t[NFPREG] fp_fregs;
367                 } fp_r_t fp_r;
368             }
369         }
370 
371         struct mcontext_t
372         {
373             gregset_t gregs;
374             fpregset_t fpregs;
375             greg_t mdhi;
376             greg_t hi1;
377             greg_t hi2;
378             greg_t hi3;
379             greg_t mdlo;
380             greg_t lo1;
381             greg_t lo2;
382             greg_t lo3;
383             greg_t pc;
384             uint fpc_csr;
385             uint used_math;
386             uint dsp;
387             uint reserved;
388         }
389 
390         struct ucontext_t
391         {
392             c_ulong     uc_flags;
393             ucontext_t* uc_link;
394             stack_t     uc_stack;
395             mcontext_t  uc_mcontext;
396             sigset_t    uc_sigmask;
397         }
398     }
399     else version (PPC)
400     {
401         private
402         {
403             enum NGREG  = 48;
404 
405             alias c_ulong        greg_t;
406             alias greg_t[NGREG]  gregset_t;
407 
408             struct fpregset_t
409             {
410                 double[32] fpregs;
411                 double fpscr;
412                 uint[2] _pad;
413             }
414 
415             struct vrregset_t
416             {
417                 uint[32][4] vrregs;
418                 uint        vrsave;
419                 uint[2]     __pad;
420                 uint vscr;
421             }
422 
423             struct pt_regs
424             {
425                 c_ulong[32] gpr;
426                 c_ulong     nip;
427                 c_ulong     msr;
428                 c_ulong     orig_gpr3;
429                 c_ulong     ctr;
430                 c_ulong     link;
431                 c_ulong     xer;
432                 c_ulong     ccr;
433                 c_ulong     mq;
434                 c_ulong     trap;
435                 c_ulong     dar;
436                 c_ulong     dsisr;
437                 c_ulong     result;
438             }
439         }
440 
441         struct mcontext_t
442         {
443             gregset_t gregs;
444             fpregset_t fpregs;
445             align(16) vrregset_t vrregs;
446         }
447 
448         struct ucontext_t
449         {
450             c_ulong     uc_flags;
451             ucontext_t* uc_link;
452             stack_t     uc_stack;
453             int[7]      uc_pad;
454             union uc_mcontext
455             {
456                 pt_regs*     regs;
457                 mcontext_t*  uc_regs;
458             }
459             sigset_t    uc_sigmask;
460             char[mcontext_t.sizeof + 12] uc_reg_space = 0;
461         }
462     }
463     else version (PPC64)
464     {
465         private
466         {
467             enum NGREG  = 48;
468             enum NFPREG = 33;
469             enum NVRREG = 34;
470 
471             alias c_ulong        greg_t;
472             alias greg_t[NGREG]  gregset_t;
473             alias double[NFPREG] fpregset_t;
474 
475             struct vscr_t
476             {
477                 uint[3] __pad;
478                 uint    vscr_word;
479             }
480 
481             struct vrregset_t
482             {
483                 uint[32][4] vrregs;
484                 vscr_t      vscr;
485                 uint        vrsave;
486                 uint[3]     __pad;
487             }
488 
489             struct pt_regs
490             {
491                 c_ulong[32] gpr;
492                 c_ulong     nip;
493                 c_ulong     msr;
494                 c_ulong     orig_gpr3;
495                 c_ulong     ctr;
496                 c_ulong     link;
497                 c_ulong     xer;
498                 c_ulong     ccr;
499                 c_ulong     softe;
500                 c_ulong     trap;
501                 c_ulong     dar;
502                 c_ulong     dsisr;
503                 c_ulong     result;
504             }
505         }
506 
507         struct mcontext_t
508         {
509             c_ulong[4] __unused;
510             int signal;
511             int __pad0;
512             c_ulong handler;
513             c_ulong oldmask;
514             pt_regs* regs;
515             gregset_t gp_regs;
516             fpregset_t fp_regs;
517             vrregset_t *v_regs;
518             c_long[NVRREG+NVRREG+1] vmx_reserve;
519         }
520 
521         struct ucontext_t
522         {
523             c_ulong     uc_flags;
524             ucontext_t* uc_link;
525             stack_t     uc_stack;
526             sigset_t    uc_sigmask;
527             mcontext_t  uc_mcontext;
528         }
529     }
530     else version (ARM)
531     {
532         enum
533         {
534             R0 = 0,
535             R1 = 1,
536             R2 = 2,
537             R3 = 3,
538             R4 = 4,
539             R5 = 5,
540             R6 = 6,
541             R7 = 7,
542             R8 = 8,
543             R9 = 9,
544             R10 = 10,
545             R11 = 11,
546             R12 = 12,
547             R13 = 13,
548             R14 = 14,
549             R15 = 15
550         }
551 
552         struct sigcontext
553         {
554             c_ulong trap_no;
555             c_ulong error_code;
556             c_ulong oldmask;
557             c_ulong arm_r0;
558             c_ulong arm_r1;
559             c_ulong arm_r2;
560             c_ulong arm_r3;
561             c_ulong arm_r4;
562             c_ulong arm_r5;
563             c_ulong arm_r6;
564             c_ulong arm_r7;
565             c_ulong arm_r8;
566             c_ulong arm_r9;
567             c_ulong arm_r10;
568             c_ulong arm_fp;
569             c_ulong arm_ip;
570             c_ulong arm_sp;
571             c_ulong arm_lr;
572             c_ulong arm_pc;
573             c_ulong arm_cpsr;
574             c_ulong fault_address;
575         }
576 
577         //alias elf_fpregset_t fpregset_t;
578         alias sigcontext mcontext_t;
579 
580         struct ucontext_t
581         {
582             c_ulong uc_flags;
583             ucontext_t* uc_link;
584             stack_t uc_stack;
585             mcontext_t uc_mcontext;
586             sigset_t uc_sigmask;
587             align(8) c_ulong[128] uc_regspace;
588         }
589     }
590     else version (AArch64)
591     {
592         alias int greg_t;
593 
594         struct sigcontext {
595             ulong           fault_address;
596             /* AArch64 registers */
597             ulong[31]       regs;
598             ulong           sp;
599             ulong           pc;
600             ulong           pstate;
601             /* 4K reserved for FP/SIMD state and future expansion */
602             align(16) ubyte[4096] __reserved;
603         }
604 
605         alias sigcontext mcontext_t;
606 
607         struct ucontext_t
608         {
609             c_ulong     uc_flags;
610             ucontext_t* uc_link;
611             stack_t     uc_stack;
612             sigset_t    uc_sigmask;
613             mcontext_t  uc_mcontext;
614         }
615     }
616     else version (RISCV_Any)
617     {
618         private
619         {
620             alias c_ulong[32] __riscv_mc_gp_state;
621 
622             struct __riscv_mc_f_ext_state
623             {
624                 uint[32] __f;
625                 uint __fcsr;
626             }
627 
628             struct __riscv_mc_d_ext_state
629             {
630                 ulong[32] __f;
631                 uint __fcsr;
632             }
633 
634             struct __riscv_mc_q_ext_state
635             {
636                 align(16) ulong[64] __f;
637                 uint __fcsr;
638                 uint[3] __reserved;
639             }
640 
641             union __riscv_mc_fp_state
642             {
643                 __riscv_mc_f_ext_state __f;
644                 __riscv_mc_d_ext_state __d;
645                 __riscv_mc_q_ext_state __q;
646             }
647         }
648 
649         struct mcontext_t
650         {
651             __riscv_mc_gp_state __gregs;
652             __riscv_mc_fp_state __fpregs;
653         }
654 
655         struct ucontext_t
656         {
657             c_ulong     __uc_flags;
658             ucontext_t* uc_link;
659             stack_t     uc_stack;
660             sigset_t    uc_sigmask;
661             char[1024 / 8 - sigset_t.sizeof] __reserved = 0;
662             mcontext_t  uc_mcontext;
663         }
664     }
665     else version (SPARC_Any)
666     {
667         enum MC_NGREG = 19;
668         alias mc_greg_t = c_ulong;
669         alias mc_gregset_t = mc_greg_t[MC_NGREG];
670 
671         struct mc_fq
672         {
673             c_ulong* mcfq_addr;
674             uint     mcfq_insn;
675         }
676 
677         struct mc_fpu_t
678         {
679             union mcfpu_fregs_t
680             {
681                 uint[32]    sregs;
682                 c_ulong[32] dregs;
683                 real[16]    qregs;
684             }
685             mcfpu_fregs_t mcfpu_fregs;
686             c_ulong       mcfpu_fsr;
687             c_ulong       mcfpu_fprs;
688             c_ulong       mcfpu_gsr;
689             mc_fq*        mcfpu_fq;
690             ubyte         mcfpu_qcnt;
691             ubyte         mcfpu_qentsz;
692             ubyte         mcfpu_enab;
693         }
694 
695         struct mcontext_t
696         {
697             mc_gregset_t mc_gregs;
698             mc_greg_t    mc_fp;
699             mc_greg_t    mc_i7;
700             mc_fpu_t     mc_fpregs;
701         }
702 
703         struct ucontext_t
704         {
705             ucontext_t* uc_link;
706             c_ulong     uc_flags;
707             c_ulong     __uc_sigmask;
708             mcontext_t  uc_mcontext;
709             stack_t     uc_stack;
710             sigset_t    uc_sigmask;
711         }
712 
713         /* Location of the users' stored registers relative to R0.
714          * Usage is as an index into a gregset_t array. */
715         enum
716         {
717             REG_PSR = 0,
718             REG_PC  = 1,
719             REG_nPC = 2,
720             REG_Y   = 3,
721             REG_G1  = 4,
722             REG_G2  = 5,
723             REG_G3  = 6,
724             REG_G4  = 7,
725             REG_G5  = 8,
726             REG_G6  = 9,
727             REG_G7  = 10,
728             REG_O0  = 11,
729             REG_O1  = 12,
730             REG_O2  = 13,
731             REG_O3  = 14,
732             REG_O4  = 15,
733             REG_O5  = 16,
734             REG_O6  = 17,
735             REG_O7  = 18,
736             REG_ASI = 19,
737             REG_FPRS = 20,
738         }
739 
740         enum NGREG = 21;
741         alias greg_t = c_ulong;
742         alias gregset_t = greg_t[NGREG];
743     }
744     else version (IBMZ_Any)
745     {
746         public import core.sys.posix.signal : sigset_t;
747 
748         enum NGREG = 27;
749 
750         alias greg_t = c_ulong;
751         alias gregset_t = align(8) greg_t[NGREG];
752 
753         align(8) struct __psw_t
754         {
755             c_ulong mask;
756             c_ulong addr;
757         }
758 
759         union fpreg_t
760         {
761             double d;
762             float  f;
763         }
764 
765         struct fpregset_t
766         {
767             uint        fpc;
768             fpreg_t[16] fprs;
769         }
770 
771         struct  mcontext_t
772         {
773             __psw_t     psw;
774             c_ulong[16] gregs;
775             uint[16]    aregs;
776             fpregset_t  fpregs;
777         }
778 
779         struct ucontext
780         {
781             c_ulong    uc_flags;
782             ucontext*  uc_link;
783             stack_t    uc_stack;
784             mcontext_t uc_mcontext;
785             sigset_t   uc_sigmask;
786         }
787 
788         alias ucontext_t = ucontext;
789     }
790     else version (LoongArch64)
791     {
792         private
793         {
794             enum LARCH_NGREG  = 32;
795 
796             alias ulong         greg_t;
797             alias greg_t[LARCH_NGREG] gregset_t;
798         }
799 
800         struct mcontext_t
801         {
802             c_ulong __pc;
803             c_ulong[32] __gregs;
804             int __flags;
805             align(16) c_ulong[0] __extcontext;
806         }
807 
808         struct ucontext_t
809         {
810             c_ulong     __uc_flags;
811             ucontext_t* uc_link;
812             stack_t     uc_stack;
813             sigset_t    uc_sigmask;
814             mcontext_t  uc_mcontext;
815         }
816     }
817     else version (WebAssembly)
818     {
819 		// FIXME?
820     }
821     else
822         static assert(0, "unimplemented");
823 }
824 else version (Darwin)
825 {
826     private
827     {
828         version (X86_64)
829         {
830             struct __darwin_mcontext
831             {
832                 ulong[89] __opaque;
833             }
834             static assert(__darwin_mcontext.sizeof == 712);
835         }
836         else version (X86)
837         {
838             struct __darwin_mcontext
839             {
840                 uint[150] __opaque;
841             }
842             static assert(__darwin_mcontext.sizeof == 600);
843         }
844         else version (AArch64)
845         {
846             struct __darwin_mcontext
847             {
848                 align(16) ulong[102] __opaque;
849             }
850             static assert(__darwin_mcontext.sizeof == 816);
851         }
852         else version (ARM)
853         {
854             struct __darwin_mcontext
855             {
856                 uint[85] __opaque;
857             }
858             static assert(__darwin_mcontext.sizeof == 340);
859         }
860         else version (PPC_Any)
861         {
862             struct __darwin_mcontext
863             {
864                 version (PPC64)
865                     ulong[129] __opaque;
866                 else
867                     uint[258] __opaque;
868             }
869             static assert(__darwin_mcontext.sizeof == 1032);
870         }
871         else
872             static assert(false, "mcontext_t unimplemented for this platform.");
873     }
874 
875     alias mcontext_t = __darwin_mcontext*;
876 
877     struct ucontext
878     {
879         int                uc_onstack;
880         sigset_t           uc_sigmask;
881         stack_t            uc_stack;
882         ucontext*          uc_link;
883         size_t             uc_mcsize;
884         __darwin_mcontext* uc_mcontext;
885         __darwin_mcontext  __mcontext_data;
886     }
887 
888     alias ucontext_t = ucontext;
889 }
890 else version (FreeBSD)
891 {
892     // <machine/ucontext.h>
893     version (X86_64)
894     {
895       alias long __register_t;
896       alias uint __uint32_t;
897       alias ushort __uint16_t;
898 
899       struct mcontext_t {
900        __register_t    mc_onstack;
901        __register_t    mc_rdi;
902        __register_t    mc_rsi;
903        __register_t    mc_rdx;
904        __register_t    mc_rcx;
905        __register_t    mc_r8;
906        __register_t    mc_r9;
907        __register_t    mc_rax;
908        __register_t    mc_rbx;
909        __register_t    mc_rbp;
910        __register_t    mc_r10;
911        __register_t    mc_r11;
912        __register_t    mc_r12;
913        __register_t    mc_r13;
914        __register_t    mc_r14;
915        __register_t    mc_r15;
916        __uint32_t      mc_trapno;
917        __uint16_t      mc_fs;
918        __uint16_t      mc_gs;
919        __register_t    mc_addr;
920        __uint32_t      mc_flags;
921        __uint16_t      mc_es;
922        __uint16_t      mc_ds;
923        __register_t    mc_err;
924        __register_t    mc_rip;
925        __register_t    mc_cs;
926        __register_t    mc_rflags;
927        __register_t    mc_rsp;
928        __register_t    mc_ss;
929 
930        long    mc_len;                 /* sizeof(mcontext_t) */
931 
932        long    mc_fpformat;
933        long    mc_ownedfp;
934 
935        align(16)
936        long[64]    mc_fpstate;
937 
938        __register_t    mc_fsbase;
939        __register_t    mc_gsbase;
940 
941        long[6]    mc_spare;
942       }
943     }
944     else version (X86)
945     {
946         alias int __register_t;
947 
948         struct mcontext_t
949         {
950             __register_t    mc_onstack;
951             __register_t    mc_gs;
952             __register_t    mc_fs;
953             __register_t    mc_es;
954             __register_t    mc_ds;
955             __register_t    mc_edi;
956             __register_t    mc_esi;
957             __register_t    mc_ebp;
958             __register_t    mc_isp;
959             __register_t    mc_ebx;
960             __register_t    mc_edx;
961             __register_t    mc_ecx;
962             __register_t    mc_eax;
963             __register_t    mc_trapno;
964             __register_t    mc_err;
965             __register_t    mc_eip;
966             __register_t    mc_cs;
967             __register_t    mc_eflags;
968             __register_t    mc_esp;
969             __register_t    mc_ss;
970 
971             int             mc_len;
972             int             mc_fpformat;
973             int             mc_ownedfp;
974             int[1]          mc_spare1;
975 
976             align(16)
977             int[128]        mc_fpstate;
978 
979             __register_t    mc_fsbase;
980             __register_t    mc_gsbase;
981 
982             int[6]          mc_spare2;
983         }
984     }
985     else version (AArch64)
986     {
987         alias __register_t = long;
988 
989         struct gpregs
990         {
991             __register_t[30] gp_x;
992             __register_t     gp_lr;
993             __register_t     gp_sp;
994             __register_t     gp_elr;
995             uint             gp_spsr;
996             int              gp_pad;
997         }
998 
999         struct fpregs
1000         {
1001             ulong[2][32]    fp_q; // __uint128_t
1002             uint            fp_sr;
1003             uint            fp_cr;
1004             int             fp_flags;
1005             int             fp_pad;
1006         }
1007 
1008         struct mcontext_t
1009         {
1010             gpregs          mc_gpregs;
1011             fpregs          mc_fpregs;
1012             int             mc_flags;
1013             int             mc_pad;
1014             ulong[8]        mc_spare;
1015         }
1016     }
1017     else version (PPC_Any)
1018     {
1019         alias size_t __register_t;
1020         alias uint   __uint32_t;
1021         alias ulong  __uint64_t;
1022 
1023         struct mcontext_t {
1024             int     mc_vers;
1025             int     mc_flags;
1026             enum _MC_FP_VALID = 0x01;
1027             enum _MC_AV_VALID = 0x02;
1028             int     mc_onstack;
1029             int     mc_len;
1030             __uint64_t[32 * 2]  mc_avec;
1031             __uint32_t[2]       mc_av;
1032             __register_t[42]    mc_frame;
1033             __uint64_t[33]      mc_fpreg;
1034             __uint64_t[32]      mc_vsxfpreg;
1035         }
1036     }
1037 
1038     // <ucontext.h>
1039     enum UCF_SWAPPED = 0x00000001;
1040 
1041     struct ucontext_t
1042     {
1043         sigset_t        uc_sigmask;
1044         mcontext_t      uc_mcontext;
1045 
1046         ucontext_t*     uc_link;
1047         stack_t         uc_stack;
1048         int             uc_flags;
1049         int[4]          __spare__;
1050     }
1051 }
1052 else version (NetBSD)
1053 {
1054     version (X86_64)
1055     {
1056         private
1057         {
1058             enum _NGREG = 26;
1059             alias __greg_t = c_ulong;
1060             alias __gregset_t = __greg_t[_NGREG];
1061             alias __fpregset_t = align(8) ubyte[512];
1062         }
1063 
1064         struct mcontext_t
1065         {
1066             __gregset_t  __gregs;
1067             __greg_t     _mc_tlsbase;
1068             __fpregset_t __fpregs;
1069         }
1070     }
1071     else version (X86)
1072     {
1073         private
1074         {
1075             enum _NGREG = 19;
1076             alias __greg_t = int;
1077             alias __gregset_t = __greg_t[_NGREG];
1078             struct __fpregset_t
1079             {
1080                 union fp_reg_set_t
1081                 {
1082                     struct fpchip_state_t
1083                     {
1084                         int[27] __fp_state;
1085                     }
1086                     struct fp_xmm_state_t
1087                     {
1088                         ubyte[512]    __fp_xmm;
1089                     }
1090                     fpchip_state_t __fpchip_state;
1091                     fp_xmm_state_t __fp_xmm_state;
1092                     int[128]     __fp_fpregs;
1093                 }
1094                 fp_reg_set_t __fp_reg_set;
1095                 int[33]     __fp_pad;
1096             }
1097         }
1098 
1099         struct mcontext_t
1100         {
1101             __gregset_t     __gregs;
1102             __fpregset_t    __fpregs;
1103             __greg_t        _mc_tlsbase;
1104         }
1105     }
1106 
1107     struct ucontext_t
1108     {
1109         uint    uc_flags;       /* properties */
1110         ucontext_t *    uc_link;        /* context to resume */
1111         sigset_t        uc_sigmask;     /* signals blocked in this context */
1112         stack_t         uc_stack;       /* the stack used by this context */
1113         mcontext_t      uc_mcontext;    /* machine state */
1114         /+ todo #if defined(_UC_MACHINE_PAD)
1115                 long            __uc_pad[_UC_MACHINE_PAD];
1116         #endif
1117         +/
1118     }
1119 }
1120 else version (OpenBSD)
1121 {
1122     version (Alpha)
1123     {
1124         struct sigcontext
1125         {
1126             c_long      sc_cookie;
1127             c_long      sc_mask;
1128             c_long      sc_pc;
1129             c_long      sc_ps;
1130             c_ulong[32] sc_regs;
1131             c_long      sc_ownedfp;
1132             c_ulong[32] sc_fpregs;
1133             c_ulong     sc_fpcr;
1134             c_ulong     sc_fp_control;
1135             c_long[2]   sc_reserved;
1136             c_long[8]   sc_xxx;
1137         }
1138     }
1139     else version (X86_64)
1140     {
1141         struct sigcontext
1142         {
1143             c_long  sc_rdi;
1144             c_long  sc_rsi;
1145             c_long  sc_rdx;
1146             c_long  sc_rcx;
1147             c_long  sc_r8;
1148             c_long  sc_r9;
1149             c_long  sc_r10;
1150             c_long  sc_r11;
1151             c_long  sc_r12;
1152             c_long  sc_r13;
1153             c_long  sc_r14;
1154             c_long  sc_r15;
1155             c_long  sc_rbp;
1156             c_long  sc_rbx;
1157             c_long  sc_rax;
1158             c_long  sc_gs;
1159             c_long  sc_fs;
1160             c_long  sc_es;
1161             c_long  sc_ds;
1162             c_long  sc_trapno;
1163             c_long  sc_err;
1164             c_long  sc_rip;
1165             c_long  sc_cs;
1166             c_long  sc_rflags;
1167             c_long  sc_rsp;
1168             c_long  sc_ss;
1169             void*   sc_fpstate;  // struct fxsave64*
1170             int   __sc_unused;
1171             int     sc_mask;
1172             c_long  sc_cookie;
1173         }
1174     }
1175     else version (AArch64)
1176     {
1177         struct sigcontext
1178         {
1179             int       __sc_unused;
1180             int         sc_mask;
1181             c_ulong     sc_sp;
1182             c_ulong     sc_lr;
1183             c_ulong     sc_elr;
1184             c_ulong     sc_spsr;
1185             c_ulong[30] sc_x;
1186             c_long      sc_cookie;
1187         }
1188     }
1189     else version (ARM)
1190     {
1191         struct sigcontext
1192         {
1193             c_long    sc_cookie;
1194             int       sc_mask;
1195             uint      sc_spsr;
1196             uint      sc_r0;
1197             uint      sc_r1;
1198             uint      sc_r2;
1199             uint      sc_r3;
1200             uint      sc_r4;
1201             uint      sc_r5;
1202             uint      sc_r6;
1203             uint      sc_r7;
1204             uint      sc_r8;
1205             uint      sc_r9;
1206             uint      sc_r10;
1207             uint      sc_r11;
1208             uint      sc_r12;
1209             uint      sc_usr_sp;
1210             uint      sc_usr_lr;
1211             uint      sc_svc_lr;
1212             uint      sc_pc;
1213             uint      sc_fpused;
1214             uint      sc_fpscr;
1215             ulong[32] sc_fpreg;
1216         }
1217     }
1218     else version (HPPA)
1219     {
1220         struct sigcontext
1221         {
1222             c_ulong   __sc_unused;
1223             c_long      sc_mask;
1224             c_ulong     sc_ps;
1225             c_ulong     sc_fp;
1226             c_ulong     sc_pcoqh;
1227             c_ulong     sc_pcoqt;
1228             c_ulong[2]  sc_resv;
1229             c_ulong[32] sc_regs;
1230             c_ulong[64] sc_fpregs;
1231             c_long      sc_cookie;
1232         }
1233     }
1234     else version (X86)
1235     {
1236         struct sigcontext
1237         {
1238             int     sc_gs;
1239             int     sc_fs;
1240             int     sc_es;
1241             int     sc_ds;
1242             int     sc_edi;
1243             int     sc_esi;
1244             int     sc_ebp;
1245             int     sc_ebx;
1246             int     sc_edx;
1247             int     sc_ecx;
1248             int     sc_eax;
1249             int     sc_eip;
1250             int     sc_cs;
1251             int     sc_eflags;
1252             int     sc_esp;
1253             int     sc_ss;
1254             c_long  sc_cookie;
1255             int     sc_mask;
1256             int     sc_trapno;
1257             int     sc_err;
1258             void*   sc_fpstate; // union savefpu*
1259         }
1260     }
1261     else version (PPC)
1262     {
1263         private struct trapframe
1264         {
1265             c_long[32] fixreg;
1266             c_long lr;
1267             c_long cr;
1268             c_long xer;
1269             c_long ctr;
1270             int srr0;
1271             int srr1;
1272             int dar;
1273             int dsisr;
1274             c_long exc;
1275         }
1276 
1277         struct sigcontext
1278         {
1279             c_long    sc_cookie;
1280             int       sc_mask;
1281             trapframe sc_frame;
1282         }
1283     }
1284     else version (SPARC64)
1285     {
1286         struct sigcontext
1287         {
1288             c_long sc_cookie;
1289             c_long sc_sp;
1290             c_long sc_pc;
1291             c_long sc_npc;
1292             c_long sc_tstate;
1293             c_long sc_g1;
1294             c_long sc_o0;
1295             int    sc_mask;
1296         }
1297     }
1298     else
1299         static assert(false, "Architecture not supported.");
1300 
1301     alias ucontext_t = sigcontext;
1302 }
1303 else version (DragonFlyBSD)
1304 {
1305     // <machine/ucontext.h>
1306     version (X86_64)
1307     {
1308       alias long __register_t;
1309       alias uint __uint32_t;
1310       alias ushort __uint16_t;
1311 
1312       struct mcontext_t {
1313         __register_t    mc_onstack;
1314         __register_t    mc_rdi;
1315         __register_t    mc_rsi;
1316         __register_t    mc_rdx;
1317         __register_t    mc_rcx;
1318         __register_t    mc_r8;
1319         __register_t    mc_r9;
1320         __register_t    mc_rax;
1321         __register_t    mc_rbx;
1322         __register_t    mc_rbp;
1323         __register_t    mc_r10;
1324         __register_t    mc_r11;
1325         __register_t    mc_r12;
1326         __register_t    mc_r13;
1327         __register_t    mc_r14;
1328         __register_t    mc_r15;
1329         __register_t    mc_xflags;
1330         __register_t    mc_trapno;
1331         __register_t    mc_addr;
1332         __register_t    mc_flags;
1333         __register_t    mc_err;
1334         __register_t    mc_rip;
1335         __register_t    mc_cs;
1336         __register_t    mc_rflags;
1337         __register_t    mc_rsp;
1338         __register_t    mc_ss;
1339 
1340         uint            mc_len;
1341         uint            mc_fpformat;
1342         uint            mc_ownedfp;
1343         uint            mc_reserved;
1344         uint[8]         mc_unused;
1345         int[256]        mc_fpregs;
1346       }  // __attribute__((aligned(64)));
1347     }
1348     else
1349     {
1350         static assert(0, "Only X86_64 support on DragonFlyBSD");
1351     }
1352 
1353     // <ucontext.h>
1354     enum UCF_SWAPPED = 0x00000001;
1355 
1356     struct ucontext_t
1357     {
1358         sigset_t        uc_sigmask;
1359         mcontext_t      uc_mcontext;
1360 
1361         ucontext_t*     uc_link;
1362         stack_t         uc_stack;
1363         void            function(ucontext_t *, void *) uc_cofunc;
1364         void*           uc_arg;
1365         int[4]          __spare__;
1366     }
1367 }
1368 else version (Solaris)
1369 {
1370     import core.stdc.stdint;
1371 
1372     alias uint[4] upad128_t;
1373 
1374     version (SPARC64)
1375     {
1376         enum _NGREG = 21;
1377         alias long greg_t;
1378     }
1379     else version (SPARC)
1380     {
1381         enum _NGREG = 19;
1382         alias int greg_t;
1383     }
1384     else version (X86_64)
1385     {
1386         enum _NGREG = 28;
1387         alias long greg_t;
1388     }
1389     else version (X86)
1390     {
1391         enum _NGREG = 19;
1392         alias int greg_t;
1393     }
1394     else
1395         static assert(0, "unimplemented");
1396 
1397     alias greg_t[_NGREG] gregset_t;
1398 
1399     version (SPARC64)
1400     {
1401         private
1402         {
1403             struct _fpq
1404             {
1405                 uint *fpq_addr;
1406                 uint fpq_instr;
1407             }
1408 
1409             struct fq
1410             {
1411                 union
1412                 {
1413                     double whole;
1414                     _fpq fpq;
1415                 }
1416             }
1417         }
1418 
1419         struct fpregset_t
1420         {
1421             union
1422             {
1423                 uint[32]   fpu_regs;
1424                 double[32] fpu_dregs;
1425                 real[16]   fpu_qregs;
1426             }
1427             fq    *fpu_q;
1428             ulong fpu_fsr;
1429             ubyte fpu_qcnt;
1430             ubyte fpu_q_entrysize;
1431             ubyte fpu_en;
1432         }
1433     }
1434     else version (SPARC)
1435     {
1436         private
1437         {
1438             struct _fpq
1439             {
1440                 uint *fpq_addr;
1441                 uint fpq_instr;
1442             }
1443 
1444             struct fq
1445             {
1446                 union
1447                 {
1448                     double whole;
1449                     _fpq fpq;
1450                 }
1451             }
1452         }
1453 
1454         struct fpregset_t
1455         {
1456             union
1457             {
1458                 uint[32]   fpu_regs;
1459                 double[16] fpu_dregs;
1460             }
1461             fq    *fpu_q;
1462             uint  fpu_fsr;
1463             ubyte fpu_qcnt;
1464             ubyte fpu_q_entrysize;
1465             ubyte fpu_en;
1466         }
1467     }
1468     else version (X86_64)
1469     {
1470         private
1471         {
1472             union _u_st
1473             {
1474                 ushort[5]   fpr_16;
1475                 upad128_t   __fpr_pad;
1476             }
1477         }
1478 
1479         struct fpregset_t
1480         {
1481             union fp_reg_set
1482             {
1483                 struct fpchip_state
1484                 {
1485                     ushort          cw;
1486                     ushort          sw;
1487                     ubyte           fctw;
1488                     ubyte           __fx_rsvd;
1489                     ushort          fop;
1490                     ulong           rip;
1491                     ulong           rdp;
1492                     uint            mxcsr;
1493                     uint            mxcsr_mask;
1494                     _u_st[8]        st;
1495                     upad128_t[16]   xmm;
1496                     upad128_t[6]    __fx_ign2;
1497                     uint            status;
1498                     uint            xstatus;
1499                 }
1500                 uint[130]   f_fpregs;
1501             }
1502         }
1503     }
1504     else version (X86)
1505     {
1506         struct fpregset_t
1507         {
1508             union u_fp_reg_set
1509             {
1510                 struct s_fpchip_state
1511                 {
1512                     uint[27]        state;
1513                     uint            status;
1514                     uint            mxcsr;
1515                     uint            xstatus;
1516                     uint[2]         __pad;
1517                     upad128_t[8]    xmm;
1518                 }
1519                 s_fpchip_state    fpchip_state;
1520 
1521                 struct s_fp_emul_space
1522                 {
1523                     ubyte[246]  fp_emul;
1524                     ubyte[2]    fp_epad;
1525                 }
1526                 s_fp_emul_space   fp_emul_space;
1527                 uint[95]        f_fpregs;
1528             }
1529         u_fp_reg_set fp_reg_set;
1530         }
1531     }
1532     else
1533         static assert(0, "unimplemented");
1534 
1535     version (SPARC_Any)
1536     {
1537         private
1538         {
1539             struct rwindow
1540             {
1541                 greg_t[8]     rw_local;
1542                 greg_t[8]     rw_in;
1543             }
1544 
1545             struct gwindows_t
1546             {
1547                 int         wbcnt;
1548                 greg_t[31] *spbuf;
1549                 rwindow[31] wbuf;
1550             }
1551 
1552             struct xrs_t
1553             {
1554                 uint         xrs_id;
1555                 caddr_t      xrs_ptr;
1556             }
1557 
1558             struct cxrs_t
1559             {
1560                 uint         cxrs_id;
1561                 caddr_t      cxrs_ptr;
1562             }
1563 
1564             alias int64_t[16] asrset_t;
1565         }
1566 
1567         struct mcontext_t
1568         {
1569             gregset_t    gregs;
1570             gwindows_t   *gwins;
1571             fpregset_t   fpregs;
1572             xrs_t        xrs;
1573             version (SPARC64)
1574             {
1575                 asrset_t asrs;
1576                 cxrs_t   cxrs;
1577                 c_long[2] filler;
1578             }
1579             else version (SPARC)
1580             {
1581                 cxrs_t   cxrs;
1582                 c_long[17] filler;
1583             }
1584         }
1585     }
1586     else version (X86_Any)
1587     {
1588         private
1589         {
1590             struct xrs_t
1591             {
1592                 uint         xrs_id;
1593                 caddr_t      xrs_ptr;
1594             }
1595         }
1596 
1597         struct mcontext_t
1598         {
1599             gregset_t   gregs;
1600             fpregset_t  fpregs;
1601         }
1602     }
1603 
1604     struct ucontext_t
1605     {
1606         version (SPARC_Any)
1607             uint    uc_flags;
1608         else version (X86_Any)
1609             c_ulong uc_flags;
1610         ucontext_t  *uc_link;
1611         sigset_t    uc_sigmask;
1612         stack_t     uc_stack;
1613         mcontext_t  uc_mcontext;
1614         version (SPARC64)
1615             c_long[4]  uc_filler;
1616         else version (SPARC)
1617             c_long[23] uc_filler;
1618         else version (X86_Any)
1619         {
1620             xrs_t      uc_xrs;
1621             c_long[3]  uc_filler;
1622         }
1623     }
1624 }
1625 
1626 //
1627 // Obsolescent (OB)
1628 //
1629 /*
1630 int  getcontext(ucontext_t*);
1631 void makecontext(ucontext_t*, void function(), int, ...);
1632 int  setcontext(const scope ucontext_t*);
1633 int  swapcontext(ucontext_t*, const scope ucontext_t*);
1634 */
1635 
1636 static if ( is( ucontext_t ) )
1637 {
1638     int  getcontext(ucontext_t*);
1639 
1640     version (Solaris)
1641     {
1642         version (SPARC_Any)
1643         {
1644             void __makecontext_v2(ucontext_t*, void function(), int, ...);
1645             alias makecontext = __makecontext_v2;
1646         }
1647         else
1648             void makecontext(ucontext_t*, void function(), int, ...);
1649     }
1650     else
1651         void makecontext(ucontext_t*, void function(), int, ...);
1652 
1653     int  setcontext(const scope ucontext_t*);
1654     int  swapcontext(ucontext_t*, const scope ucontext_t*);
1655 }
1656 
1657 version (Solaris)
1658 {
1659     int walkcontext(const scope ucontext_t*, int function(uintptr_t, int, void*), void*);
1660     int addrtosymstr(uintptr_t, char*, int);
1661     int printstack(int);
1662 }