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