static void synth_ucontext( ThreadId tid, const vki_siginfo_t *si,
                            UWord trapno, UWord err, const vki_sigset_t *set, 
                            struct vki_ucontext *uc) 
{

   ThreadState *tst = VG_(get_ThreadState)(tid);
   struct vki_sigcontext *sc = &uc->uc_mcontext;

   VG_(memset)(uc, 0, sizeof(*uc));

   uc->uc_flags = 0;
   uc->uc_link = 0;
   uc->uc_sigmask = *set;
   uc->uc_stack = tst->altstack;

#  define SC2(reg)  sc->regs[reg] = tst->arch.vex.guest_X##reg
   SC2(0);   SC2(1);   SC2(2);   SC2(3);
   SC2(4);   SC2(5);   SC2(6);   SC2(7);
   SC2(8);   SC2(9);   SC2(10);  SC2(11);
   SC2(12);  SC2(13);  SC2(14);  SC2(15);
   SC2(16);  SC2(17);  SC2(18);  SC2(19);
   SC2(20);  SC2(21);  SC2(22);  SC2(23);
   SC2(24);  SC2(25);  SC2(26);  SC2(27);
   SC2(28);  SC2(29);  SC2(30);
#  undef SC2
   sc->sp = tst->arch.vex.guest_XSP;
   sc->pc = tst->arch.vex.guest_PC;
   sc->pstate = 0; /* slack .. could do better */

   //sc->trap_no = trapno;
   //sc->error_code = err;
   sc->fault_address = (ULong)si->_sifields._sigfault._addr;
}
static 
void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
                    UWord trapno, UWord err, const vki_sigset_t *set, 
                    struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
   ThreadState *tst = VG_(get_ThreadState)(tid);
   struct vki_sigcontext *sc = &uc->uc_mcontext;

   VG_(memset)(uc, 0, sizeof(*uc));

   uc->uc_flags = 0;
   uc->uc_link = 0;
   uc->uc_sigmask = *set;
   uc->uc_stack = tst->altstack;
   sc->fpstate = fpstate;

   

#  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
   SC2(gs,GS);
   SC2(fs,FS);
   SC2(es,ES);
   SC2(ds,DS);

   SC2(edi,EDI);
   SC2(esi,ESI);
   SC2(ebp,EBP);
   SC2(esp,ESP);
   SC2(ebx,EBX);
   SC2(edx,EDX);
   SC2(ecx,ECX);
   SC2(eax,EAX);

   SC2(eip,EIP);
   SC2(cs,CS);
   sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
   SC2(ss,SS);
   
   sc->trapno = trapno;
   sc->err = err;
#  undef SC2

   sc->cr2 = (UInt)si->_sifields._sigfault._addr;
}
static void synth_ucontext( ThreadId tid, const vki_siginfo_t *si,
                    UWord trapno, UWord err, const vki_sigset_t *set, 
                    struct vki_ucontext *uc){

   ThreadState *tst = VG_(get_ThreadState)(tid);
   struct vki_sigcontext *sc = &uc->uc_mcontext;

   VG_(memset)(uc, 0, sizeof(*uc));

   uc->uc_flags = 0;
   uc->uc_link = 0;
   uc->uc_sigmask = *set;
   uc->uc_stack = tst->altstack;

#  define SC2(reg,REG)  sc->arm_##reg = tst->arch.vex.guest_##REG
   SC2(r0,R0);
   SC2(r1,R1);
   SC2(r2,R2);
   SC2(r3,R3);
   SC2(r4,R4);
   SC2(r5,R5);
   SC2(r6,R6);
   SC2(r7,R7);
   SC2(r8,R8);
   SC2(r9,R9);
   SC2(r10,R10);
   SC2(fp,R11);
   SC2(ip,R12);
   SC2(sp,R13);
   SC2(lr,R14);
   SC2(pc,R15T);
#  undef SC2

   sc->trap_no = trapno;
   sc->error_code = err;
   sc->fault_address = (UInt)si->_sifields._sigfault._addr;
}
/* Create a plausible-looking sigcontext from the thread's
   Vex guest state.
*/
static 
void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
                    UWord trapno, UWord err, const vki_sigset_t *set, 
                    struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
   ThreadState *tst = VG_(get_ThreadState)(tid);
   struct vki_mcontext *sc = &uc->uc_mcontext;

   VG_(memset)(uc, 0, sizeof(*uc));

   uc->uc_flags = 0;
   uc->uc_link = 0;
   uc->uc_sigmask = *set;
   uc->uc_stack = tst->altstack;
   VG_(memcpy)(&sc->fpstate, fpstate, sizeof(*fpstate));

#  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
   SC2(r8,R8);
   SC2(r9,R9);
   SC2(r10,R10);
   SC2(r11,R11);
   SC2(r12,R12);
   SC2(r13,R13);
   SC2(r14,R14);
   SC2(r15,R15);
   SC2(rdi,RDI);
   SC2(rsi,RSI);
   SC2(rbp,RBP);
   SC2(rbx,RBX);
   SC2(rdx,RDX);
   SC2(rax,RAX);
   SC2(rcx,RCX);
   SC2(rsp,RSP);
/*
   SC2(cs,CS);
   SC2(gs,SS);
   XXX
*/
   SC2(rip,RIP);
   sc->addr = (UWord)si->si_addr;
   sc->err = err;
   sc->fpformat = VKI_FPFMT_NODEV;
   sc->len = sizeof(*sc);
   sc->ownedfp = VKI_FPOWNED_NONE;
   sc->rflags = LibVEX_GuestAMD64_get_rflags(&tst->arch.vex);
   sc->trapno = trapno;
#  undef SC2
}
/* Create a plausible-looking sigcontext from the thread's
   Vex guest state.  NOTE: does not fill in the FP or SSE
   bits of sigcontext at the moment.
*/
static
void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
                    UWord trapno, UWord err, const vki_sigset_t *set,
                    struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
    ThreadState *tst = VG_(get_ThreadState)(tid);
    struct vki_sigcontext *sc = &uc->uc_mcontext;

    VG_(memset)(uc, 0, sizeof(*uc));

    uc->uc_flags = 0;
    uc->uc_link = 0;
    uc->uc_sigmask = *set;
    uc->uc_stack = tst->altstack;
    sc->fpstate = fpstate;

    // FIXME: save_i387(&tst->arch, fpstate);

#  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
    SC2(r8,R8);
    SC2(r9,R9);
    SC2(r10,R10);
    SC2(r11,R11);
    SC2(r12,R12);
    SC2(r13,R13);
    SC2(r14,R14);
    SC2(r15,R15);
    SC2(rdi,RDI);
    SC2(rsi,RSI);
    SC2(rbp,RBP);
    SC2(rbx,RBX);
    SC2(rdx,RDX);
    SC2(rax,RAX);
    SC2(rcx,RCX);
    SC2(rsp,RSP);

    SC2(rip,RIP);
    sc->eflags = LibVEX_GuestAMD64_get_rflags(&tst->arch.vex);
    // FIXME: SC2(cs,CS);
    // FIXME: SC2(gs,GS);
    // FIXME: SC2(fs,FS);
    sc->trapno = trapno;
    sc->err = err;
#  undef SC2

    sc->cr2 = (UWord)si->_sifields._sigfault._addr;
}