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