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 version (LoongArch64)
789     {
790         private
791         {
792             enum LARCH_NGREG  = 32;
793 
794             alias ulong         greg_t;
795             alias greg_t[LARCH_NGREG] gregset_t;
796         }
797 
798         struct mcontext_t
799         {
800             c_ulong __pc;
801             c_ulong[32] __gregs;
802             int __flags;
803             align(16) c_ulong[0] __extcontext;
804         }
805 
806         struct ucontext_t
807         {
808             c_ulong     __uc_flags;
809             ucontext_t* uc_link;
810             stack_t     uc_stack;
811             sigset_t    uc_sigmask;
812             mcontext_t  uc_mcontext;
813         }
814     }
815     else
816         static assert(0, "unimplemented");
817 }
818 else version (Darwin)
819 {
820     private
821     {
822         version (X86_64)
823         {
824             struct __darwin_mcontext
825             {
826                 ulong[89] __opaque;
827             }
828             static assert(__darwin_mcontext.sizeof == 712);
829         }
830         else version (X86)
831         {
832             struct __darwin_mcontext
833             {
834                 uint[150] __opaque;
835             }
836             static assert(__darwin_mcontext.sizeof == 600);
837         }
838         else version (AArch64)
839         {
840             struct __darwin_mcontext
841             {
842                 align(16) ulong[102] __opaque;
843             }
844             static assert(__darwin_mcontext.sizeof == 816);
845         }
846         else version (ARM)
847         {
848             struct __darwin_mcontext
849             {
850                 uint[85] __opaque;
851             }
852             static assert(__darwin_mcontext.sizeof == 340);
853         }
854         else version (PPC_Any)
855         {
856             struct __darwin_mcontext
857             {
858                 version (PPC64)
859                     ulong[129] __opaque;
860                 else
861                     uint[258] __opaque;
862             }
863             static assert(__darwin_mcontext.sizeof == 1032);
864         }
865         else
866             static assert(false, "mcontext_t unimplemented for this platform.");
867     }
868 
869     alias mcontext_t = __darwin_mcontext*;
870 
871     struct ucontext
872     {
873         int                uc_onstack;
874         sigset_t           uc_sigmask;
875         stack_t            uc_stack;
876         ucontext*          uc_link;
877         size_t             uc_mcsize;
878         __darwin_mcontext* uc_mcontext;
879         __darwin_mcontext  __mcontext_data;
880     }
881 
882     alias ucontext_t = ucontext;
883 }
884 else version (FreeBSD)
885 {
886     // <machine/ucontext.h>
887     version (X86_64)
888     {
889       alias long __register_t;
890       alias uint __uint32_t;
891       alias ushort __uint16_t;
892 
893       struct mcontext_t {
894        __register_t    mc_onstack;
895        __register_t    mc_rdi;
896        __register_t    mc_rsi;
897        __register_t    mc_rdx;
898        __register_t    mc_rcx;
899        __register_t    mc_r8;
900        __register_t    mc_r9;
901        __register_t    mc_rax;
902        __register_t    mc_rbx;
903        __register_t    mc_rbp;
904        __register_t    mc_r10;
905        __register_t    mc_r11;
906        __register_t    mc_r12;
907        __register_t    mc_r13;
908        __register_t    mc_r14;
909        __register_t    mc_r15;
910        __uint32_t      mc_trapno;
911        __uint16_t      mc_fs;
912        __uint16_t      mc_gs;
913        __register_t    mc_addr;
914        __uint32_t      mc_flags;
915        __uint16_t      mc_es;
916        __uint16_t      mc_ds;
917        __register_t    mc_err;
918        __register_t    mc_rip;
919        __register_t    mc_cs;
920        __register_t    mc_rflags;
921        __register_t    mc_rsp;
922        __register_t    mc_ss;
923 
924        long    mc_len;                 /* sizeof(mcontext_t) */
925 
926        long    mc_fpformat;
927        long    mc_ownedfp;
928 
929        align(16)
930        long[64]    mc_fpstate;
931 
932        __register_t    mc_fsbase;
933        __register_t    mc_gsbase;
934 
935        long[6]    mc_spare;
936       }
937     }
938     else version (X86)
939     {
940         alias int __register_t;
941 
942         struct mcontext_t
943         {
944             __register_t    mc_onstack;
945             __register_t    mc_gs;
946             __register_t    mc_fs;
947             __register_t    mc_es;
948             __register_t    mc_ds;
949             __register_t    mc_edi;
950             __register_t    mc_esi;
951             __register_t    mc_ebp;
952             __register_t    mc_isp;
953             __register_t    mc_ebx;
954             __register_t    mc_edx;
955             __register_t    mc_ecx;
956             __register_t    mc_eax;
957             __register_t    mc_trapno;
958             __register_t    mc_err;
959             __register_t    mc_eip;
960             __register_t    mc_cs;
961             __register_t    mc_eflags;
962             __register_t    mc_esp;
963             __register_t    mc_ss;
964 
965             int             mc_len;
966             int             mc_fpformat;
967             int             mc_ownedfp;
968             int[1]          mc_spare1;
969 
970             align(16)
971             int[128]        mc_fpstate;
972 
973             __register_t    mc_fsbase;
974             __register_t    mc_gsbase;
975 
976             int[6]          mc_spare2;
977         }
978     }
979     else version (AArch64)
980     {
981         alias __register_t = long;
982 
983         struct gpregs
984         {
985             __register_t[30] gp_x;
986             __register_t     gp_lr;
987             __register_t     gp_sp;
988             __register_t     gp_elr;
989             uint             gp_spsr;
990             int              gp_pad;
991         }
992 
993         struct fpregs
994         {
995             ulong[2][32]    fp_q; // __uint128_t
996             uint            fp_sr;
997             uint            fp_cr;
998             int             fp_flags;
999             int             fp_pad;
1000         }
1001 
1002         struct mcontext_t
1003         {
1004             gpregs          mc_gpregs;
1005             fpregs          mc_fpregs;
1006             int             mc_flags;
1007             int             mc_pad;
1008             ulong[8]        mc_spare;
1009         }
1010     }
1011     else version (PPC_Any)
1012     {
1013         alias size_t __register_t;
1014         alias uint   __uint32_t;
1015         alias ulong  __uint64_t;
1016 
1017         struct mcontext_t {
1018             int     mc_vers;
1019             int     mc_flags;
1020             enum _MC_FP_VALID = 0x01;
1021             enum _MC_AV_VALID = 0x02;
1022             int     mc_onstack;
1023             int     mc_len;
1024             __uint64_t[32 * 2]  mc_avec;
1025             __uint32_t[2]       mc_av;
1026             __register_t[42]    mc_frame;
1027             __uint64_t[33]      mc_fpreg;
1028             __uint64_t[32]      mc_vsxfpreg;
1029         }
1030     }
1031 
1032     // <ucontext.h>
1033     enum UCF_SWAPPED = 0x00000001;
1034 
1035     struct ucontext_t
1036     {
1037         sigset_t        uc_sigmask;
1038         mcontext_t      uc_mcontext;
1039 
1040         ucontext_t*     uc_link;
1041         stack_t         uc_stack;
1042         int             uc_flags;
1043         int[4]          __spare__;
1044     }
1045 }
1046 else version (NetBSD)
1047 {
1048     version (X86_64)
1049     {
1050         private
1051         {
1052             enum _NGREG = 26;
1053             alias __greg_t = c_ulong;
1054             alias __gregset_t = __greg_t[_NGREG];
1055             alias __fpregset_t = align(8) ubyte[512];
1056         }
1057 
1058         struct mcontext_t
1059         {
1060             __gregset_t  __gregs;
1061             __greg_t     _mc_tlsbase;
1062             __fpregset_t __fpregs;
1063         }
1064     }
1065     else version (X86)
1066     {
1067         private
1068         {
1069             enum _NGREG = 19;
1070             alias __greg_t = int;
1071             alias __gregset_t = __greg_t[_NGREG];
1072             struct __fpregset_t
1073             {
1074                 union fp_reg_set_t
1075                 {
1076                     struct fpchip_state_t
1077                     {
1078                         int[27] __fp_state;
1079                     }
1080                     struct fp_xmm_state_t
1081                     {
1082                         ubyte[512]    __fp_xmm;
1083                     }
1084                     fpchip_state_t __fpchip_state;
1085                     fp_xmm_state_t __fp_xmm_state;
1086                     int[128]     __fp_fpregs;
1087                 }
1088                 fp_reg_set_t __fp_reg_set;
1089                 int[33]     __fp_pad;
1090             }
1091         }
1092 
1093         struct mcontext_t
1094         {
1095             __gregset_t     __gregs;
1096             __fpregset_t    __fpregs;
1097             __greg_t        _mc_tlsbase;
1098         }
1099     }
1100 
1101     struct ucontext_t
1102     {
1103         uint    uc_flags;       /* properties */
1104         ucontext_t *    uc_link;        /* context to resume */
1105         sigset_t        uc_sigmask;     /* signals blocked in this context */
1106         stack_t         uc_stack;       /* the stack used by this context */
1107         mcontext_t      uc_mcontext;    /* machine state */
1108         /+ todo #if defined(_UC_MACHINE_PAD)
1109                 long            __uc_pad[_UC_MACHINE_PAD];
1110         #endif
1111         +/
1112     }
1113 }
1114 else version (OpenBSD)
1115 {
1116     version (Alpha)
1117     {
1118         struct sigcontext
1119         {
1120             c_long      sc_cookie;
1121             c_long      sc_mask;
1122             c_long      sc_pc;
1123             c_long      sc_ps;
1124             c_ulong[32] sc_regs;
1125             c_long      sc_ownedfp;
1126             c_ulong[32] sc_fpregs;
1127             c_ulong     sc_fpcr;
1128             c_ulong     sc_fp_control;
1129             c_long[2]   sc_reserved;
1130             c_long[8]   sc_xxx;
1131         }
1132     }
1133     else version (X86_64)
1134     {
1135         struct sigcontext
1136         {
1137             c_long  sc_rdi;
1138             c_long  sc_rsi;
1139             c_long  sc_rdx;
1140             c_long  sc_rcx;
1141             c_long  sc_r8;
1142             c_long  sc_r9;
1143             c_long  sc_r10;
1144             c_long  sc_r11;
1145             c_long  sc_r12;
1146             c_long  sc_r13;
1147             c_long  sc_r14;
1148             c_long  sc_r15;
1149             c_long  sc_rbp;
1150             c_long  sc_rbx;
1151             c_long  sc_rax;
1152             c_long  sc_gs;
1153             c_long  sc_fs;
1154             c_long  sc_es;
1155             c_long  sc_ds;
1156             c_long  sc_trapno;
1157             c_long  sc_err;
1158             c_long  sc_rip;
1159             c_long  sc_cs;
1160             c_long  sc_rflags;
1161             c_long  sc_rsp;
1162             c_long  sc_ss;
1163             void*   sc_fpstate;  // struct fxsave64*
1164             int   __sc_unused;
1165             int     sc_mask;
1166             c_long  sc_cookie;
1167         }
1168     }
1169     else version (AArch64)
1170     {
1171         struct sigcontext
1172         {
1173             int       __sc_unused;
1174             int         sc_mask;
1175             c_ulong     sc_sp;
1176             c_ulong     sc_lr;
1177             c_ulong     sc_elr;
1178             c_ulong     sc_spsr;
1179             c_ulong[30] sc_x;
1180             c_long      sc_cookie;
1181         }
1182     }
1183     else version (ARM)
1184     {
1185         struct sigcontext
1186         {
1187             c_long    sc_cookie;
1188             int       sc_mask;
1189             uint      sc_spsr;
1190             uint      sc_r0;
1191             uint      sc_r1;
1192             uint      sc_r2;
1193             uint      sc_r3;
1194             uint      sc_r4;
1195             uint      sc_r5;
1196             uint      sc_r6;
1197             uint      sc_r7;
1198             uint      sc_r8;
1199             uint      sc_r9;
1200             uint      sc_r10;
1201             uint      sc_r11;
1202             uint      sc_r12;
1203             uint      sc_usr_sp;
1204             uint      sc_usr_lr;
1205             uint      sc_svc_lr;
1206             uint      sc_pc;
1207             uint      sc_fpused;
1208             uint      sc_fpscr;
1209             ulong[32] sc_fpreg;
1210         }
1211     }
1212     else version (HPPA)
1213     {
1214         struct sigcontext
1215         {
1216             c_ulong   __sc_unused;
1217             c_long      sc_mask;
1218             c_ulong     sc_ps;
1219             c_ulong     sc_fp;
1220             c_ulong     sc_pcoqh;
1221             c_ulong     sc_pcoqt;
1222             c_ulong[2]  sc_resv;
1223             c_ulong[32] sc_regs;
1224             c_ulong[64] sc_fpregs;
1225             c_long      sc_cookie;
1226         }
1227     }
1228     else version (X86)
1229     {
1230         struct sigcontext
1231         {
1232             int     sc_gs;
1233             int     sc_fs;
1234             int     sc_es;
1235             int     sc_ds;
1236             int     sc_edi;
1237             int     sc_esi;
1238             int     sc_ebp;
1239             int     sc_ebx;
1240             int     sc_edx;
1241             int     sc_ecx;
1242             int     sc_eax;
1243             int     sc_eip;
1244             int     sc_cs;
1245             int     sc_eflags;
1246             int     sc_esp;
1247             int     sc_ss;
1248             c_long  sc_cookie;
1249             int     sc_mask;
1250             int     sc_trapno;
1251             int     sc_err;
1252             void*   sc_fpstate; // union savefpu*
1253         }
1254     }
1255     else version (PPC)
1256     {
1257         private struct trapframe
1258         {
1259             c_long[32] fixreg;
1260             c_long lr;
1261             c_long cr;
1262             c_long xer;
1263             c_long ctr;
1264             int srr0;
1265             int srr1;
1266             int dar;
1267             int dsisr;
1268             c_long exc;
1269         }
1270 
1271         struct sigcontext
1272         {
1273             c_long    sc_cookie;
1274             int       sc_mask;
1275             trapframe sc_frame;
1276         }
1277     }
1278     else version (SPARC64)
1279     {
1280         struct sigcontext
1281         {
1282             c_long sc_cookie;
1283             c_long sc_sp;
1284             c_long sc_pc;
1285             c_long sc_npc;
1286             c_long sc_tstate;
1287             c_long sc_g1;
1288             c_long sc_o0;
1289             int    sc_mask;
1290         }
1291     }
1292     else
1293         static assert(false, "Architecture not supported.");
1294 
1295     alias ucontext_t = sigcontext;
1296 }
1297 else version (DragonFlyBSD)
1298 {
1299     // <machine/ucontext.h>
1300     version (X86_64)
1301     {
1302       alias long __register_t;
1303       alias uint __uint32_t;
1304       alias ushort __uint16_t;
1305 
1306       struct mcontext_t {
1307         __register_t    mc_onstack;
1308         __register_t    mc_rdi;
1309         __register_t    mc_rsi;
1310         __register_t    mc_rdx;
1311         __register_t    mc_rcx;
1312         __register_t    mc_r8;
1313         __register_t    mc_r9;
1314         __register_t    mc_rax;
1315         __register_t    mc_rbx;
1316         __register_t    mc_rbp;
1317         __register_t    mc_r10;
1318         __register_t    mc_r11;
1319         __register_t    mc_r12;
1320         __register_t    mc_r13;
1321         __register_t    mc_r14;
1322         __register_t    mc_r15;
1323         __register_t    mc_xflags;
1324         __register_t    mc_trapno;
1325         __register_t    mc_addr;
1326         __register_t    mc_flags;
1327         __register_t    mc_err;
1328         __register_t    mc_rip;
1329         __register_t    mc_cs;
1330         __register_t    mc_rflags;
1331         __register_t    mc_rsp;
1332         __register_t    mc_ss;
1333 
1334         uint            mc_len;
1335         uint            mc_fpformat;
1336         uint            mc_ownedfp;
1337         uint            mc_reserved;
1338         uint[8]         mc_unused;
1339         int[256]        mc_fpregs;
1340       }  // __attribute__((aligned(64)));
1341     }
1342     else
1343     {
1344         static assert(0, "Only X86_64 support on DragonFlyBSD");
1345     }
1346 
1347     // <ucontext.h>
1348     enum UCF_SWAPPED = 0x00000001;
1349 
1350     struct ucontext_t
1351     {
1352         sigset_t        uc_sigmask;
1353         mcontext_t      uc_mcontext;
1354 
1355         ucontext_t*     uc_link;
1356         stack_t         uc_stack;
1357         void            function(ucontext_t *, void *) uc_cofunc;
1358         void*           uc_arg;
1359         int[4]          __spare__;
1360     }
1361 }
1362 else version (Solaris)
1363 {
1364     import core.stdc.stdint;
1365 
1366     alias uint[4] upad128_t;
1367 
1368     version (SPARC64)
1369     {
1370         enum _NGREG = 21;
1371         alias long greg_t;
1372     }
1373     else version (SPARC)
1374     {
1375         enum _NGREG = 19;
1376         alias int greg_t;
1377     }
1378     else version (X86_64)
1379     {
1380         enum _NGREG = 28;
1381         alias long greg_t;
1382     }
1383     else version (X86)
1384     {
1385         enum _NGREG = 19;
1386         alias int greg_t;
1387     }
1388     else
1389         static assert(0, "unimplemented");
1390 
1391     alias greg_t[_NGREG] gregset_t;
1392 
1393     version (SPARC64)
1394     {
1395         private
1396         {
1397             struct _fpq
1398             {
1399                 uint *fpq_addr;
1400                 uint fpq_instr;
1401             }
1402 
1403             struct fq
1404             {
1405                 union
1406                 {
1407                     double whole;
1408                     _fpq fpq;
1409                 }
1410             }
1411         }
1412 
1413         struct fpregset_t
1414         {
1415             union
1416             {
1417                 uint[32]   fpu_regs;
1418                 double[32] fpu_dregs;
1419                 real[16]   fpu_qregs;
1420             }
1421             fq    *fpu_q;
1422             ulong fpu_fsr;
1423             ubyte fpu_qcnt;
1424             ubyte fpu_q_entrysize;
1425             ubyte fpu_en;
1426         }
1427     }
1428     else version (SPARC)
1429     {
1430         private
1431         {
1432             struct _fpq
1433             {
1434                 uint *fpq_addr;
1435                 uint fpq_instr;
1436             }
1437 
1438             struct fq
1439             {
1440                 union
1441                 {
1442                     double whole;
1443                     _fpq fpq;
1444                 }
1445             }
1446         }
1447 
1448         struct fpregset_t
1449         {
1450             union
1451             {
1452                 uint[32]   fpu_regs;
1453                 double[16] fpu_dregs;
1454             }
1455             fq    *fpu_q;
1456             uint  fpu_fsr;
1457             ubyte fpu_qcnt;
1458             ubyte fpu_q_entrysize;
1459             ubyte fpu_en;
1460         }
1461     }
1462     else version (X86_64)
1463     {
1464         private
1465         {
1466             union _u_st
1467             {
1468                 ushort[5]   fpr_16;
1469                 upad128_t   __fpr_pad;
1470             }
1471         }
1472 
1473         struct fpregset_t
1474         {
1475             union fp_reg_set
1476             {
1477                 struct fpchip_state
1478                 {
1479                     ushort          cw;
1480                     ushort          sw;
1481                     ubyte           fctw;
1482                     ubyte           __fx_rsvd;
1483                     ushort          fop;
1484                     ulong           rip;
1485                     ulong           rdp;
1486                     uint            mxcsr;
1487                     uint            mxcsr_mask;
1488                     _u_st[8]        st;
1489                     upad128_t[16]   xmm;
1490                     upad128_t[6]    __fx_ign2;
1491                     uint            status;
1492                     uint            xstatus;
1493                 }
1494                 uint[130]   f_fpregs;
1495             }
1496         }
1497     }
1498     else version (X86)
1499     {
1500         struct fpregset_t
1501         {
1502             union u_fp_reg_set
1503             {
1504                 struct s_fpchip_state
1505                 {
1506                     uint[27]        state;
1507                     uint            status;
1508                     uint            mxcsr;
1509                     uint            xstatus;
1510                     uint[2]         __pad;
1511                     upad128_t[8]    xmm;
1512                 }
1513                 s_fpchip_state    fpchip_state;
1514 
1515                 struct s_fp_emul_space
1516                 {
1517                     ubyte[246]  fp_emul;
1518                     ubyte[2]    fp_epad;
1519                 }
1520                 s_fp_emul_space   fp_emul_space;
1521                 uint[95]        f_fpregs;
1522             }
1523         u_fp_reg_set fp_reg_set;
1524         }
1525     }
1526     else
1527         static assert(0, "unimplemented");
1528 
1529     version (SPARC_Any)
1530     {
1531         private
1532         {
1533             struct rwindow
1534             {
1535                 greg_t[8]     rw_local;
1536                 greg_t[8]     rw_in;
1537             }
1538 
1539             struct gwindows_t
1540             {
1541                 int         wbcnt;
1542                 greg_t[31] *spbuf;
1543                 rwindow[31] wbuf;
1544             }
1545 
1546             struct xrs_t
1547             {
1548                 uint         xrs_id;
1549                 caddr_t      xrs_ptr;
1550             }
1551 
1552             struct cxrs_t
1553             {
1554                 uint         cxrs_id;
1555                 caddr_t      cxrs_ptr;
1556             }
1557 
1558             alias int64_t[16] asrset_t;
1559         }
1560 
1561         struct mcontext_t
1562         {
1563             gregset_t    gregs;
1564             gwindows_t   *gwins;
1565             fpregset_t   fpregs;
1566             xrs_t        xrs;
1567             version (SPARC64)
1568             {
1569                 asrset_t asrs;
1570                 cxrs_t   cxrs;
1571                 c_long[2] filler;
1572             }
1573             else version (SPARC)
1574             {
1575                 cxrs_t   cxrs;
1576                 c_long[17] filler;
1577             }
1578         }
1579     }
1580     else version (X86_Any)
1581     {
1582         private
1583         {
1584             struct xrs_t
1585             {
1586                 uint         xrs_id;
1587                 caddr_t      xrs_ptr;
1588             }
1589         }
1590 
1591         struct mcontext_t
1592         {
1593             gregset_t   gregs;
1594             fpregset_t  fpregs;
1595         }
1596     }
1597 
1598     struct ucontext_t
1599     {
1600         version (SPARC_Any)
1601             uint    uc_flags;
1602         else version (X86_Any)
1603             c_ulong uc_flags;
1604         ucontext_t  *uc_link;
1605         sigset_t    uc_sigmask;
1606         stack_t     uc_stack;
1607         mcontext_t  uc_mcontext;
1608         version (SPARC64)
1609             c_long[4]  uc_filler;
1610         else version (SPARC)
1611             c_long[23] uc_filler;
1612         else version (X86_Any)
1613         {
1614             xrs_t      uc_xrs;
1615             c_long[3]  uc_filler;
1616         }
1617     }
1618 }
1619 
1620 //
1621 // Obsolescent (OB)
1622 //
1623 /*
1624 int  getcontext(ucontext_t*);
1625 void makecontext(ucontext_t*, void function(), int, ...);
1626 int  setcontext(const scope ucontext_t*);
1627 int  swapcontext(ucontext_t*, const scope ucontext_t*);
1628 */
1629 
1630 static if ( is( ucontext_t ) )
1631 {
1632     int  getcontext(ucontext_t*);
1633 
1634     version (Solaris)
1635     {
1636         version (SPARC_Any)
1637         {
1638             void __makecontext_v2(ucontext_t*, void function(), int, ...);
1639             alias makecontext = __makecontext_v2;
1640         }
1641         else
1642             void makecontext(ucontext_t*, void function(), int, ...);
1643     }
1644     else
1645         void makecontext(ucontext_t*, void function(), int, ...);
1646 
1647     int  setcontext(const scope ucontext_t*);
1648     int  swapcontext(ucontext_t*, const scope ucontext_t*);
1649 }
1650 
1651 version (Solaris)
1652 {
1653     int walkcontext(const scope ucontext_t*, int function(uintptr_t, int, void*), void*);
1654     int addrtosymstr(uintptr_t, char*, int);
1655     int printstack(int);
1656 }