475 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			475 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
| /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
 | |
| │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
 | |
| ╞══════════════════════════════════════════════════════════════════════════════╡
 | |
| │ Copyright 2020 Justine Alexandra Roberts Tunney                              │
 | |
| │                                                                              │
 | |
| │ Permission to use, copy, modify, and/or distribute this software for         │
 | |
| │ any purpose with or without fee is hereby granted, provided that the         │
 | |
| │ above copyright notice and this permission notice appear in all copies.      │
 | |
| │                                                                              │
 | |
| │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
 | |
| │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
 | |
| │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
 | |
| │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
 | |
| │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
 | |
| │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
 | |
| │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 | |
| │ PERFORMANCE OF THIS SOFTWARE.                                                │
 | |
| ╚─────────────────────────────────────────────────────────────────────────────*/
 | |
| #include "libc/calls/calls.h"
 | |
| #include "libc/calls/internal.h"
 | |
| #include "libc/calls/struct/siginfo.h"
 | |
| #include "libc/calls/ucontext.h"
 | |
| #include "libc/str/str.h"
 | |
| 
 | |
| /**
 | |
|  * @fileoverview XNU kernel callback normalization.
 | |
|  */
 | |
| 
 | |
| union __darwin_sigval {
 | |
|   int32_t sival_int;
 | |
|   void *sival_ptr;
 | |
| };
 | |
| 
 | |
| struct __darwin_siginfo {
 | |
|   int32_t si_signo;
 | |
|   int32_t si_errno;
 | |
|   int32_t si_code;
 | |
|   int32_t si_pid;
 | |
|   uint32_t si_uid;
 | |
|   int32_t si_status;
 | |
|   void *si_addr;
 | |
|   union __darwin_sigval si_value;
 | |
|   int64_t si_band;
 | |
|   uint64_t __pad[7];
 | |
| };
 | |
| 
 | |
| struct __darwin_sigaltstack {
 | |
|   void *ss_sp;
 | |
|   uint64_t ss_size;
 | |
|   int32_t ss_flags;
 | |
| };
 | |
| 
 | |
| struct __darwin_fp_control {
 | |
|   uint16_t __invalid : 1, __denorm : 1, __zdiv : 1, __ovrfl : 1, __undfl : 1,
 | |
|       __precis : 1, : 2, __pc : 2, __rc : 2, : 1, : 3;
 | |
| };
 | |
| 
 | |
| struct __darwin_fp_status {
 | |
|   uint16_t __invalid : 1, __denorm : 1, __zdiv : 1, __ovrfl : 1, __undfl : 1,
 | |
|       __precis : 1, __stkflt : 1, __errsumm : 1, __c0 : 1, __c1 : 1, __c2 : 1,
 | |
|       __tos : 3, __c3 : 1, __busy : 1;
 | |
| };
 | |
| 
 | |
| struct __darwin_mmst_reg {
 | |
|   char __mmst_reg[10];
 | |
|   char __mmst_rsrv[6];
 | |
| };
 | |
| 
 | |
| struct __darwin_xmm_reg {
 | |
|   char __xmm_reg[16];
 | |
| };
 | |
| 
 | |
| struct __darwin_ymm_reg {
 | |
|   char __ymm_reg[32];
 | |
| };
 | |
| 
 | |
| struct __darwin_zmm_reg {
 | |
|   char __zmm_reg[64];
 | |
| };
 | |
| 
 | |
| struct __darwin_opmask_reg {
 | |
|   char __opmask_reg[8];
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_thread_state64 {
 | |
|   uint64_t __rax;
 | |
|   uint64_t __rbx;
 | |
|   uint64_t __rcx;
 | |
|   uint64_t __rdx;
 | |
|   uint64_t __rdi;
 | |
|   uint64_t __rsi;
 | |
|   uint64_t __rbp;
 | |
|   uint64_t __rsp;
 | |
|   uint64_t __r8;
 | |
|   uint64_t __r9;
 | |
|   uint64_t __r10;
 | |
|   uint64_t __r11;
 | |
|   uint64_t __r12;
 | |
|   uint64_t __r13;
 | |
|   uint64_t __r14;
 | |
|   uint64_t __r15;
 | |
|   uint64_t __rip;
 | |
|   uint64_t __rflags;
 | |
|   uint64_t __cs;
 | |
|   uint64_t __fs;
 | |
|   uint64_t __gs;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_thread_full_state64 {
 | |
|   struct __darwin_x86_thread_state64 ss64;
 | |
|   uint64_t __ds;
 | |
|   uint64_t __es;
 | |
|   uint64_t __ss;
 | |
|   uint64_t __gsbase;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_float_state64 {
 | |
|   int32_t __fpu_reserved[2];
 | |
|   struct __darwin_fp_control __fpu_fcw;
 | |
|   struct __darwin_fp_status __fpu_fsw;
 | |
|   uint8_t __fpu_ftw;
 | |
|   uint8_t __fpu_rsrv1;
 | |
|   uint16_t __fpu_fop;
 | |
|   uint32_t __fpu_ip;
 | |
|   uint16_t __fpu_cs;
 | |
|   uint16_t __fpu_rsrv2;
 | |
|   uint32_t __fpu_dp;
 | |
|   uint16_t __fpu_ds;
 | |
|   uint16_t __fpu_rsrv3;
 | |
|   uint32_t __fpu_mxcsr;
 | |
|   uint32_t __fpu_mxcsrmask;
 | |
|   struct __darwin_mmst_reg __fpu_stmm0;
 | |
|   struct __darwin_mmst_reg __fpu_stmm1;
 | |
|   struct __darwin_mmst_reg __fpu_stmm2;
 | |
|   struct __darwin_mmst_reg __fpu_stmm3;
 | |
|   struct __darwin_mmst_reg __fpu_stmm4;
 | |
|   struct __darwin_mmst_reg __fpu_stmm5;
 | |
|   struct __darwin_mmst_reg __fpu_stmm6;
 | |
|   struct __darwin_mmst_reg __fpu_stmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm0;
 | |
|   struct __darwin_xmm_reg __fpu_xmm1;
 | |
|   struct __darwin_xmm_reg __fpu_xmm2;
 | |
|   struct __darwin_xmm_reg __fpu_xmm3;
 | |
|   struct __darwin_xmm_reg __fpu_xmm4;
 | |
|   struct __darwin_xmm_reg __fpu_xmm5;
 | |
|   struct __darwin_xmm_reg __fpu_xmm6;
 | |
|   struct __darwin_xmm_reg __fpu_xmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm8;
 | |
|   struct __darwin_xmm_reg __fpu_xmm9;
 | |
|   struct __darwin_xmm_reg __fpu_xmm10;
 | |
|   struct __darwin_xmm_reg __fpu_xmm11;
 | |
|   struct __darwin_xmm_reg __fpu_xmm12;
 | |
|   struct __darwin_xmm_reg __fpu_xmm13;
 | |
|   struct __darwin_xmm_reg __fpu_xmm14;
 | |
|   struct __darwin_xmm_reg __fpu_xmm15;
 | |
|   char __fpu_rsrv4[6 * 16];
 | |
|   int32_t __fpu_reserved1;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_avx_state64 {
 | |
|   int32_t __fpu_reserved[2];
 | |
|   struct __darwin_fp_control __fpu_fcw;
 | |
|   struct __darwin_fp_status __fpu_fsw;
 | |
|   uint8_t __fpu_ftw;
 | |
|   uint8_t __fpu_rsrv1;
 | |
|   uint16_t __fpu_fop;
 | |
|   uint32_t __fpu_ip;
 | |
|   uint16_t __fpu_cs;
 | |
|   uint16_t __fpu_rsrv2;
 | |
|   uint32_t __fpu_dp;
 | |
|   uint16_t __fpu_ds;
 | |
|   uint16_t __fpu_rsrv3;
 | |
|   uint32_t __fpu_mxcsr;
 | |
|   uint32_t __fpu_mxcsrmask;
 | |
|   struct __darwin_mmst_reg __fpu_stmm0;
 | |
|   struct __darwin_mmst_reg __fpu_stmm1;
 | |
|   struct __darwin_mmst_reg __fpu_stmm2;
 | |
|   struct __darwin_mmst_reg __fpu_stmm3;
 | |
|   struct __darwin_mmst_reg __fpu_stmm4;
 | |
|   struct __darwin_mmst_reg __fpu_stmm5;
 | |
|   struct __darwin_mmst_reg __fpu_stmm6;
 | |
|   struct __darwin_mmst_reg __fpu_stmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm0;
 | |
|   struct __darwin_xmm_reg __fpu_xmm1;
 | |
|   struct __darwin_xmm_reg __fpu_xmm2;
 | |
|   struct __darwin_xmm_reg __fpu_xmm3;
 | |
|   struct __darwin_xmm_reg __fpu_xmm4;
 | |
|   struct __darwin_xmm_reg __fpu_xmm5;
 | |
|   struct __darwin_xmm_reg __fpu_xmm6;
 | |
|   struct __darwin_xmm_reg __fpu_xmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm8;
 | |
|   struct __darwin_xmm_reg __fpu_xmm9;
 | |
|   struct __darwin_xmm_reg __fpu_xmm10;
 | |
|   struct __darwin_xmm_reg __fpu_xmm11;
 | |
|   struct __darwin_xmm_reg __fpu_xmm12;
 | |
|   struct __darwin_xmm_reg __fpu_xmm13;
 | |
|   struct __darwin_xmm_reg __fpu_xmm14;
 | |
|   struct __darwin_xmm_reg __fpu_xmm15;
 | |
|   char __fpu_rsrv4[6 * 16];
 | |
|   int32_t __fpu_reserved1;
 | |
|   char __avx_reserved1[64];
 | |
|   struct __darwin_xmm_reg __fpu_ymmh0;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh1;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh2;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh3;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh4;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh5;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh6;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh7;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh8;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh9;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh10;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh11;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh12;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh13;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh14;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh15;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_avx512_state64 {
 | |
|   int32_t __fpu_reserved[2];
 | |
|   struct __darwin_fp_control __fpu_fcw;
 | |
|   struct __darwin_fp_status __fpu_fsw;
 | |
|   uint8_t __fpu_ftw;
 | |
|   uint8_t __fpu_rsrv1;
 | |
|   uint16_t __fpu_fop;
 | |
|   uint32_t __fpu_ip;
 | |
|   uint16_t __fpu_cs;
 | |
|   uint16_t __fpu_rsrv2;
 | |
|   uint32_t __fpu_dp;
 | |
|   uint16_t __fpu_ds;
 | |
|   uint16_t __fpu_rsrv3;
 | |
|   uint32_t __fpu_mxcsr;
 | |
|   uint32_t __fpu_mxcsrmask;
 | |
|   struct __darwin_mmst_reg __fpu_stmm0;
 | |
|   struct __darwin_mmst_reg __fpu_stmm1;
 | |
|   struct __darwin_mmst_reg __fpu_stmm2;
 | |
|   struct __darwin_mmst_reg __fpu_stmm3;
 | |
|   struct __darwin_mmst_reg __fpu_stmm4;
 | |
|   struct __darwin_mmst_reg __fpu_stmm5;
 | |
|   struct __darwin_mmst_reg __fpu_stmm6;
 | |
|   struct __darwin_mmst_reg __fpu_stmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm0;
 | |
|   struct __darwin_xmm_reg __fpu_xmm1;
 | |
|   struct __darwin_xmm_reg __fpu_xmm2;
 | |
|   struct __darwin_xmm_reg __fpu_xmm3;
 | |
|   struct __darwin_xmm_reg __fpu_xmm4;
 | |
|   struct __darwin_xmm_reg __fpu_xmm5;
 | |
|   struct __darwin_xmm_reg __fpu_xmm6;
 | |
|   struct __darwin_xmm_reg __fpu_xmm7;
 | |
|   struct __darwin_xmm_reg __fpu_xmm8;
 | |
|   struct __darwin_xmm_reg __fpu_xmm9;
 | |
|   struct __darwin_xmm_reg __fpu_xmm10;
 | |
|   struct __darwin_xmm_reg __fpu_xmm11;
 | |
|   struct __darwin_xmm_reg __fpu_xmm12;
 | |
|   struct __darwin_xmm_reg __fpu_xmm13;
 | |
|   struct __darwin_xmm_reg __fpu_xmm14;
 | |
|   struct __darwin_xmm_reg __fpu_xmm15;
 | |
|   char __fpu_rsrv4[6 * 16];
 | |
|   int32_t __fpu_reserved1;
 | |
|   char __avx_reserved1[64];
 | |
|   struct __darwin_xmm_reg __fpu_ymmh0;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh1;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh2;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh3;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh4;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh5;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh6;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh7;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh8;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh9;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh10;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh11;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh12;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh13;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh14;
 | |
|   struct __darwin_xmm_reg __fpu_ymmh15;
 | |
|   struct __darwin_opmask_reg __fpu_k0;
 | |
|   struct __darwin_opmask_reg __fpu_k1;
 | |
|   struct __darwin_opmask_reg __fpu_k2;
 | |
|   struct __darwin_opmask_reg __fpu_k3;
 | |
|   struct __darwin_opmask_reg __fpu_k4;
 | |
|   struct __darwin_opmask_reg __fpu_k5;
 | |
|   struct __darwin_opmask_reg __fpu_k6;
 | |
|   struct __darwin_opmask_reg __fpu_k7;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh0;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh1;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh2;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh3;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh4;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh5;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh6;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh7;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh8;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh9;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh10;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh11;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh12;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh13;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh14;
 | |
|   struct __darwin_ymm_reg __fpu_zmmh15;
 | |
|   struct __darwin_zmm_reg __fpu_zmm16;
 | |
|   struct __darwin_zmm_reg __fpu_zmm17;
 | |
|   struct __darwin_zmm_reg __fpu_zmm18;
 | |
|   struct __darwin_zmm_reg __fpu_zmm19;
 | |
|   struct __darwin_zmm_reg __fpu_zmm20;
 | |
|   struct __darwin_zmm_reg __fpu_zmm21;
 | |
|   struct __darwin_zmm_reg __fpu_zmm22;
 | |
|   struct __darwin_zmm_reg __fpu_zmm23;
 | |
|   struct __darwin_zmm_reg __fpu_zmm24;
 | |
|   struct __darwin_zmm_reg __fpu_zmm25;
 | |
|   struct __darwin_zmm_reg __fpu_zmm26;
 | |
|   struct __darwin_zmm_reg __fpu_zmm27;
 | |
|   struct __darwin_zmm_reg __fpu_zmm28;
 | |
|   struct __darwin_zmm_reg __fpu_zmm29;
 | |
|   struct __darwin_zmm_reg __fpu_zmm30;
 | |
|   struct __darwin_zmm_reg __fpu_zmm31;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_exception_state64 {
 | |
|   uint16_t __trapno;
 | |
|   uint16_t __cpu;
 | |
|   uint32_t __err;
 | |
|   uint64_t __faultvaddr;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_debug_state64 {
 | |
|   uint64_t __dr0;
 | |
|   uint64_t __dr1;
 | |
|   uint64_t __dr2;
 | |
|   uint64_t __dr3;
 | |
|   uint64_t __dr4;
 | |
|   uint64_t __dr5;
 | |
|   uint64_t __dr6;
 | |
|   uint64_t __dr7;
 | |
| };
 | |
| 
 | |
| struct __darwin_x86_cpmu_state64 {
 | |
|   uint64_t __ctrs[16];
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext64_full {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_full_state64 __ss;
 | |
|   struct __darwin_x86_float_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext_avx64 {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_state64 __ss;
 | |
|   struct __darwin_x86_avx_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext_avx64_full {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_full_state64 __ss;
 | |
|   struct __darwin_x86_avx_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext_avx512_64 {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_state64 __ss;
 | |
|   struct __darwin_x86_avx512_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext_avx512_64_full {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_full_state64 __ss;
 | |
|   struct __darwin_x86_avx512_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_mcontext64 {
 | |
|   struct __darwin_x86_exception_state64 __es;
 | |
|   struct __darwin_x86_thread_state64 __ss;
 | |
|   struct __darwin_x86_float_state64 __fs;
 | |
| };
 | |
| 
 | |
| struct __darwin_ucontext {
 | |
|   int32_t uc_onstack;
 | |
|   uint32_t uc_sigmask;
 | |
|   struct __darwin_sigaltstack uc_stack;
 | |
|   struct __darwin_ucontext *uc_link;
 | |
|   uint64_t uc_mcsize;
 | |
|   struct __darwin_mcontext64 *uc_mcontext;
 | |
| };
 | |
| 
 | |
| static void xnuexceptionstate2linux(
 | |
|     mcontext_t *mc, struct __darwin_x86_exception_state64 *xnues) {
 | |
|   mc->trapno = xnues->__trapno;
 | |
|   mc->err = xnues->__err;
 | |
| }
 | |
| 
 | |
| static void xnuthreadstate2linux(ucontext_t *uc, mcontext_t *mc,
 | |
|                                  struct __darwin_x86_thread_state64 *xnuss) {
 | |
|   mc->rdi = xnuss->__rdi;
 | |
|   mc->rsi = xnuss->__rsi;
 | |
|   mc->rbp = xnuss->__rbp;
 | |
|   mc->rbx = xnuss->__rbx;
 | |
|   mc->rdx = xnuss->__rdx;
 | |
|   mc->rax = xnuss->__rax;
 | |
|   mc->rcx = xnuss->__rcx;
 | |
|   mc->rsp = xnuss->__rsp;
 | |
|   mc->rip = xnuss->__rip;
 | |
|   /* g.uc.uc_mcontext.rip = xnuctx->uc_mcontext->__es.__faultvaddr; */
 | |
|   mc->cs = xnuss->__cs;
 | |
|   mc->gs = xnuss->__gs;
 | |
|   mc->fs = xnuss->__fs;
 | |
|   mc->eflags = xnuss->__rflags;
 | |
|   uc->uc_flags = xnuss->__rflags;
 | |
|   memcpy(&mc->r8, &xnuss->__r8, 8 * sizeof(int64_t));
 | |
| }
 | |
| 
 | |
| static void xnussefpustate2linux(struct FpuState *fs,
 | |
|                                  struct __darwin_x86_float_state64 *xnufs) {
 | |
|   memcpy(&fs->cwd, &xnufs->__fpu_fcw, 2);
 | |
|   memcpy(&fs->swd, &xnufs->__fpu_fsw, 2);
 | |
|   fs->ftw = xnufs->__fpu_ftw;
 | |
|   fs->fop = xnufs->__fpu_fop;
 | |
|   fs->rip = xnufs->__fpu_ip;
 | |
|   fs->rdp = xnufs->__fpu_dp;
 | |
|   fs->mxcsr = xnufs->__fpu_mxcsr;
 | |
|   fs->mxcr_mask = xnufs->__fpu_mxcsrmask;
 | |
|   /* copy st0-st7 as well as xmm0-xmm15 */
 | |
|   memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t));
 | |
| }
 | |
| 
 | |
| wontreturn void xnutrampoline(void *fn, int infostyle, int sig,
 | |
|                               const struct __darwin_siginfo *xnuinfo,
 | |
|                               const struct __darwin_ucontext *xnuctx) {
 | |
|   /* note: this function impl can't access static memory */
 | |
|   intptr_t ax;
 | |
|   struct Goodies {
 | |
|     ucontext_t uc;
 | |
|     siginfo_t si;
 | |
|   } g;
 | |
|   memset(&g, 0, sizeof(g));
 | |
|   if (xnuctx) {
 | |
|     /* g.uc.uc_sigmask = xnuctx->uc_sigmask; */
 | |
|     g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp;
 | |
|     g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags;
 | |
|     g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size;
 | |
|     if (xnuctx->uc_mcontext) {
 | |
|       if (xnuctx->uc_mcsize >= sizeof(struct __darwin_x86_exception_state64)) {
 | |
|         xnuexceptionstate2linux(&g.uc.uc_mcontext, &xnuctx->uc_mcontext->__es);
 | |
|       }
 | |
|       if (xnuctx->uc_mcsize >= (sizeof(struct __darwin_x86_exception_state64) +
 | |
|                                 sizeof(struct __darwin_x86_thread_state64))) {
 | |
|         xnuthreadstate2linux(&g.uc, &g.uc.uc_mcontext,
 | |
|                              &xnuctx->uc_mcontext->__ss);
 | |
|       }
 | |
|       if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) {
 | |
|         xnussefpustate2linux(&g.uc.fpustate, &xnuctx->uc_mcontext->__fs);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (xnuinfo) {
 | |
|     g.si.si_signo = xnuinfo->si_signo;
 | |
|     g.si.si_errno = xnuinfo->si_errno;
 | |
|     g.si.si_code = xnuinfo->si_code;
 | |
|     if (xnuinfo->si_pid) {
 | |
|       g.si.si_pid = xnuinfo->si_pid;
 | |
|       g.si.si_uid = xnuinfo->si_uid;
 | |
|       g.si.si_status = xnuinfo->si_status;
 | |
|     } else {
 | |
|       g.si.si_addr = (void *)xnuinfo->si_addr;
 | |
|     }
 | |
|   }
 | |
|   __sigenter(sig, &g.si, &g.uc);
 | |
|   asm volatile("syscall"
 | |
|                : "=a"(ax)
 | |
|                : "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle)
 | |
|                : "rcx", "r11", "memory", "cc");
 | |
|   unreachable;
 | |
| }
 |