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