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