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