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