/*
 *  Emulation of Linux signals
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target/arm/cpu-features.h"
#include "vdso-asmoffset.h"

struct target_sigcontext {
    abi_ulong trap_no;
    abi_ulong error_code;
    abi_ulong oldmask;
    abi_ulong arm_r0;
    abi_ulong arm_r1;
    abi_ulong arm_r2;
    abi_ulong arm_r3;
    abi_ulong arm_r4;
    abi_ulong arm_r5;
    abi_ulong arm_r6;
    abi_ulong arm_r7;
    abi_ulong arm_r8;
    abi_ulong arm_r9;
    abi_ulong arm_r10;
    abi_ulong arm_fp;
    abi_ulong arm_ip;
    abi_ulong arm_sp;
    abi_ulong arm_lr;
    abi_ulong arm_pc;
    abi_ulong arm_cpsr;
    abi_ulong fault_address;
};

struct target_ucontext {
    abi_ulong tuc_flags;
    abi_ulong tuc_link;
    target_stack_t tuc_stack;
    struct target_sigcontext tuc_mcontext;
    target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
    char __unused[128 - sizeof(target_sigset_t)];
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
};

struct target_user_vfp {
    uint64_t fpregs[32];
    abi_ulong fpscr;
};

struct target_user_vfp_exc {
    abi_ulong fpexc;
    abi_ulong fpinst;
    abi_ulong fpinst2;
};

struct target_vfp_sigframe {
    abi_ulong magic;
    abi_ulong size;
    struct target_user_vfp ufp;
    struct target_user_vfp_exc ufp_exc;
} __attribute__((__aligned__(8)));

struct target_iwmmxt_sigframe {
    abi_ulong magic;
    abi_ulong size;
    uint64_t regs[16];
    /* Note that not all the coprocessor control registers are stored here */
    uint32_t wcssf;
    uint32_t wcasf;
    uint32_t wcgr0;
    uint32_t wcgr1;
    uint32_t wcgr2;
    uint32_t wcgr3;
} __attribute__((__aligned__(8)));

#define TARGET_VFP_MAGIC 0x56465001
#define TARGET_IWMMXT_MAGIC 0x12ef842a

struct sigframe
{
    struct target_ucontext uc;
    abi_ulong retcode[4];
};

struct rt_sigframe
{
    struct target_siginfo info;
    struct sigframe sig;
};

QEMU_BUILD_BUG_ON(offsetof(struct sigframe, retcode[3])
                  != SIGFRAME_RC3_OFFSET);
QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, sig.retcode[3])
                  != RT_SIGFRAME_RC3_OFFSET);

static abi_ptr sigreturn_fdpic_tramp;

/*
 * Up to 3 words of 'retcode' in the sigframe are code,
 * with retcode[3] being used by fdpic for the function descriptor.
 * This code is not actually executed, but is retained for ABI compat.
 *
 * We will create a table of 8 retcode variants in the sigtramp page.
 * Let each table entry use 3 words.
 */
#define RETCODE_WORDS  3
#define RETCODE_BYTES  (RETCODE_WORDS * 4)

static inline int valid_user_regs(CPUARMState *regs)
{
    return 1;
}

static void
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
                 CPUARMState *env, abi_ulong mask)
{
    __put_user(env->regs[0], &sc->arm_r0);
    __put_user(env->regs[1], &sc->arm_r1);
    __put_user(env->regs[2], &sc->arm_r2);
    __put_user(env->regs[3], &sc->arm_r3);
    __put_user(env->regs[4], &sc->arm_r4);
    __put_user(env->regs[5], &sc->arm_r5);
    __put_user(env->regs[6], &sc->arm_r6);
    __put_user(env->regs[7], &sc->arm_r7);
    __put_user(env->regs[8], &sc->arm_r8);
    __put_user(env->regs[9], &sc->arm_r9);
    __put_user(env->regs[10], &sc->arm_r10);
    __put_user(env->regs[11], &sc->arm_fp);
    __put_user(env->regs[12], &sc->arm_ip);
    __put_user(env->regs[13], &sc->arm_sp);
    __put_user(env->regs[14], &sc->arm_lr);
    __put_user(env->regs[15], &sc->arm_pc);
    __put_user(cpsr_read(env), &sc->arm_cpsr);

    __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
    __put_user(/* current->thread.error_code */ 0, &sc->error_code);
    __put_user(/* current->thread.address */ 0, &sc->fault_address);
    __put_user(mask, &sc->oldmask);
}

static inline abi_ulong
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
{
    unsigned long sp;

    sp = target_sigsp(get_sp_from_cpustate(regs), ka);
    /*
     * ATPCS B01 mandates 8-byte alignment
     */
    return (sp - framesize) & ~7;
}

static void write_arm_sigreturn(uint32_t *rc, int syscall);
static void write_arm_fdpic_sigreturn(uint32_t *rc, int ofs);

static int
setup_return(CPUARMState *env, struct target_sigaction *ka, int usig,
             struct sigframe *frame, abi_ulong sp_addr)
{
    abi_ulong handler = 0;
    abi_ulong handler_fdpic_GOT = 0;
    abi_ulong retcode;
    bool is_fdpic = info_is_fdpic(get_task_state(thread_cpu)->info);
    bool is_rt = ka->sa_flags & TARGET_SA_SIGINFO;
    bool thumb;

    if (is_fdpic) {
        /* In FDPIC mode, ka->_sa_handler points to a function
         * descriptor (FD). The first word contains the address of the
         * handler. The second word contains the value of the PIC
         * register (r9).  */
        abi_ulong funcdesc_ptr = ka->_sa_handler;
        if (get_user_ual(handler, funcdesc_ptr)
            || get_user_ual(handler_fdpic_GOT, funcdesc_ptr + 4)) {
            return 1;
        }
    } else {
        handler = ka->_sa_handler;
    }
    thumb = handler & 1;

    uint32_t cpsr = cpsr_read(env);

    cpsr &= ~CPSR_IT;
    if (thumb) {
        cpsr |= CPSR_T;
    } else {
        cpsr &= ~CPSR_T;
    }
    if (env->cp15.sctlr_el[1] & SCTLR_E0E) {
        cpsr |= CPSR_E;
    } else {
        cpsr &= ~CPSR_E;
    }

    /* Our vdso default_sigreturn label is a table of entry points. */
    retcode = default_sigreturn + (is_fdpic * 2 + is_rt) * 8;

    /*
     * Put the sigreturn code on the stack no matter which return
     * mechanism we use in order to remain ABI compliant.
     * Because this is about ABI, always use the A32 instructions,
     * despite the fact that our actual vdso trampoline is T16.
     */
    if (is_fdpic) {
        write_arm_fdpic_sigreturn(frame->retcode,
                                  is_rt ? RT_SIGFRAME_RC3_OFFSET
                                        : SIGFRAME_RC3_OFFSET);
    } else {
        write_arm_sigreturn(frame->retcode,
                            is_rt ? TARGET_NR_rt_sigreturn
                                  : TARGET_NR_sigreturn);
    }

    if (ka->sa_flags & TARGET_SA_RESTORER) {
        if (is_fdpic) {
            /* Place the function descriptor in slot 3. */
            __put_user((abi_ulong)ka->sa_restorer, &frame->retcode[3]);
        } else {
            retcode = ka->sa_restorer;
        }
    }

    env->regs[0] = usig;
    if (is_fdpic) {
        env->regs[9] = handler_fdpic_GOT;
    }
    env->regs[13] = sp_addr;
    env->regs[14] = retcode;
    env->regs[15] = handler & (thumb ? ~1 : ~3);
    cpsr_write(env, cpsr, CPSR_IT | CPSR_T | CPSR_E, CPSRWriteByInstr);

    return 0;
}

static abi_ulong *setup_sigframe_vfp(abi_ulong *regspace, CPUARMState *env)
{
    int i;
    struct target_vfp_sigframe *vfpframe;
    vfpframe = (struct target_vfp_sigframe *)regspace;
    __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
    __put_user(sizeof(*vfpframe), &vfpframe->size);
    for (i = 0; i < 32; i++) {
        __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
    }
    __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
    __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
    __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
    __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
    return (abi_ulong*)(vfpframe+1);
}

static abi_ulong *setup_sigframe_iwmmxt(abi_ulong *regspace, CPUARMState *env)
{
    int i;
    struct target_iwmmxt_sigframe *iwmmxtframe;
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
    __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
    __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
    for (i = 0; i < 16; i++) {
        __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
    }
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
    return (abi_ulong*)(iwmmxtframe+1);
}

static void setup_sigframe(struct target_ucontext *uc,
                           target_sigset_t *set, CPUARMState *env)
{
    struct target_sigaltstack stack;
    int i;
    abi_ulong *regspace;

    /* Clear all the bits of the ucontext we don't use.  */
    memset(uc, 0, offsetof(struct target_ucontext, tuc_mcontext));

    memset(&stack, 0, sizeof(stack));
    target_save_altstack(&stack, env);
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));

    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
    /* Save coprocessor signal frame.  */
    regspace = uc->tuc_regspace;
    if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
        regspace = setup_sigframe_vfp(regspace, env);
    }
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
        regspace = setup_sigframe_iwmmxt(regspace, env);
    }

    /* Write terminating magic word */
    __put_user(0, regspace);

    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
    }
}

void setup_frame(int usig, struct target_sigaction *ka,
                 target_sigset_t *set, CPUARMState *regs)
{
    struct sigframe *frame;
    abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));

    trace_user_setup_frame(regs, frame_addr);
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        goto sigsegv;
    }

    setup_sigframe(&frame->uc, set, regs);

    if (setup_return(regs, ka, usig, frame, frame_addr)) {
        goto sigsegv;
    }

    unlock_user_struct(frame, frame_addr, 1);
    return;
sigsegv:
    unlock_user_struct(frame, frame_addr, 1);
    force_sigsegv(usig);
}

void setup_rt_frame(int usig, struct target_sigaction *ka,
                    target_siginfo_t *info,
                    target_sigset_t *set, CPUARMState *env)
{
    struct rt_sigframe *frame;
    abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
    abi_ulong info_addr, uc_addr;

    trace_user_setup_rt_frame(env, frame_addr);
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        goto sigsegv;
    }

    info_addr = frame_addr + offsetof(struct rt_sigframe, info);
    uc_addr = frame_addr + offsetof(struct rt_sigframe, sig.uc);
    frame->info = *info;

    setup_sigframe(&frame->sig.uc, set, env);

    if (setup_return(env, ka, usig, &frame->sig, frame_addr)) {
        goto sigsegv;
    }

    env->regs[1] = info_addr;
    env->regs[2] = uc_addr;

    unlock_user_struct(frame, frame_addr, 1);
    return;
sigsegv:
    unlock_user_struct(frame, frame_addr, 1);
    force_sigsegv(usig);
}

static int
restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
{
    int err = 0;
    uint32_t cpsr;

    __get_user(env->regs[0], &sc->arm_r0);
    __get_user(env->regs[1], &sc->arm_r1);
    __get_user(env->regs[2], &sc->arm_r2);
    __get_user(env->regs[3], &sc->arm_r3);
    __get_user(env->regs[4], &sc->arm_r4);
    __get_user(env->regs[5], &sc->arm_r5);
    __get_user(env->regs[6], &sc->arm_r6);
    __get_user(env->regs[7], &sc->arm_r7);
    __get_user(env->regs[8], &sc->arm_r8);
    __get_user(env->regs[9], &sc->arm_r9);
    __get_user(env->regs[10], &sc->arm_r10);
    __get_user(env->regs[11], &sc->arm_fp);
    __get_user(env->regs[12], &sc->arm_ip);
    __get_user(env->regs[13], &sc->arm_sp);
    __get_user(env->regs[14], &sc->arm_lr);
    __get_user(env->regs[15], &sc->arm_pc);
    __get_user(cpsr, &sc->arm_cpsr);
    cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);

    err |= !valid_user_regs(env);

    return err;
}

static abi_ulong *restore_sigframe_vfp(CPUARMState *env, abi_ulong *regspace)
{
    int i;
    abi_ulong magic, sz;
    uint32_t fpscr, fpexc;
    struct target_vfp_sigframe *vfpframe;
    vfpframe = (struct target_vfp_sigframe *)regspace;

    __get_user(magic, &vfpframe->magic);
    __get_user(sz, &vfpframe->size);
    if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
        return 0;
    }
    for (i = 0; i < 32; i++) {
        __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
    }
    __get_user(fpscr, &vfpframe->ufp.fpscr);
    vfp_set_fpscr(env, fpscr);
    __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
    /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
     * and the exception flag is cleared
     */
    fpexc |= (1 << 30);
    fpexc &= ~((1 << 31) | (1 << 28));
    env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
    __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
    __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
    return (abi_ulong*)(vfpframe + 1);
}

static abi_ulong *restore_sigframe_iwmmxt(CPUARMState *env,
                                          abi_ulong *regspace)
{
    int i;
    abi_ulong magic, sz;
    struct target_iwmmxt_sigframe *iwmmxtframe;
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;

    __get_user(magic, &iwmmxtframe->magic);
    __get_user(sz, &iwmmxtframe->size);
    if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
        return 0;
    }
    for (i = 0; i < 16; i++) {
        __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
    }
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
    return (abi_ulong*)(iwmmxtframe + 1);
}

static int do_sigframe_return(CPUARMState *env,
                              target_ulong context_addr,
                              struct target_ucontext *uc)
{
    sigset_t host_set;
    abi_ulong *regspace;

    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
    set_sigmask(&host_set);

    if (restore_sigcontext(env, &uc->tuc_mcontext)) {
        return 1;
    }

    /* Restore coprocessor signal frame */
    regspace = uc->tuc_regspace;
    if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
        regspace = restore_sigframe_vfp(env, regspace);
        if (!regspace) {
            return 1;
        }
    }
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
        regspace = restore_sigframe_iwmmxt(env, regspace);
        if (!regspace) {
            return 1;
        }
    }

    target_restore_altstack(&uc->tuc_stack, env);

#if 0
    /* Send SIGTRAP if we're single-stepping */
    if (ptrace_cancel_bpt(current))
        send_sig(SIGTRAP, current, 1);
#endif

    return 0;
}

long do_sigreturn(CPUARMState *env)
{
    abi_ulong frame_addr;
    struct sigframe *frame = NULL;

    /*
     * Since we stacked the signal on a 64-bit boundary,
     * then 'sp' should be word aligned here.  If it's
     * not, then the user is trying to mess with us.
     */
    frame_addr = env->regs[13];
    trace_user_do_sigreturn(env, frame_addr);
    if (frame_addr & 7) {
        goto badframe;
    }

    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        goto badframe;
    }

    if (do_sigframe_return(env,
                           frame_addr + offsetof(struct sigframe, uc),
                           &frame->uc)) {
        goto badframe;
    }

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;

badframe:
    unlock_user_struct(frame, frame_addr, 0);
    force_sig(TARGET_SIGSEGV);
    return -QEMU_ESIGRETURN;
}

long do_rt_sigreturn(CPUARMState *env)
{
    abi_ulong frame_addr;
    struct rt_sigframe *frame = NULL;

    /*
     * Since we stacked the signal on a 64-bit boundary,
     * then 'sp' should be word aligned here.  If it's
     * not, then the user is trying to mess with us.
     */
    frame_addr = env->regs[13];
    trace_user_do_rt_sigreturn(env, frame_addr);
    if (frame_addr & 7) {
        goto badframe;
    }

    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        goto badframe;
    }

    if (do_sigframe_return(env,
                           frame_addr + offsetof(struct rt_sigframe, sig.uc),
                           &frame->sig.uc)) {
        goto badframe;
    }

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;

badframe:
    unlock_user_struct(frame, frame_addr, 0);
    force_sig(TARGET_SIGSEGV);
    return -QEMU_ESIGRETURN;
}

/*
 * EABI syscalls pass the number via r7.
 * Note that the kernel still adds the OABI syscall number to the trap,
 * presumably for backward ABI compatibility with unwinders.
 */
#define ARM_MOV_R7_IMM(X)       (0xe3a07000 | (X))
#define ARM_SWI_SYS(X)          (0xef000000 | (X) | ARM_SYSCALL_BASE)

#define THUMB_MOVS_R7_IMM(X)    (0x2700 | (X))
#define THUMB_SWI_SYS           0xdf00

static void write_arm_sigreturn(uint32_t *rc, int syscall)
{
    __put_user(ARM_MOV_R7_IMM(syscall), rc);
    __put_user(ARM_SWI_SYS(syscall), rc + 1);
    /* Wrote 8 of 12 bytes */
}

static void write_thm_sigreturn(uint32_t *rc, int syscall)
{
    __put_user(THUMB_SWI_SYS << 16 | THUMB_MOVS_R7_IMM(syscall), rc);
    /* Wrote 4 of 12 bytes */
}

/*
 * Stub needed to make sure the FD register (r9) contains the right value.
 * Use the same instruction sequence as the kernel.
 */
static void write_arm_fdpic_sigreturn(uint32_t *rc, int ofs)
{
    assert(ofs <= 0xfff);
    __put_user(0xe59d3000 | ofs, rc + 0);   /* ldr r3, [sp, #ofs] */
    __put_user(0xe8930908, rc + 1);         /* ldm r3, { r3, r9 } */
    __put_user(0xe12fff13, rc + 2);         /* bx  r3 */
    /* Wrote 12 of 12 bytes */
}

static void write_thm_fdpic_sigreturn(void *vrc, int ofs)
{
    uint16_t *rc = vrc;

    assert((ofs & ~0x3fc) == 0);
    __put_user(0x9b00 | (ofs >> 2), rc + 0);      /* ldr r3, [sp, #ofs] */
    __put_user(0xcb0c, rc + 1);                   /* ldm r3, { r2, r3 } */
    __put_user(0x4699, rc + 2);                   /* mov r9, r3 */
    __put_user(0x4710, rc + 3);                   /* bx  r2 */
    /* Wrote 8 of 12 bytes */
}

void setup_sigtramp(abi_ulong sigtramp_page)
{
    uint32_t total_size = 8 * RETCODE_BYTES;
    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, total_size, 0);

    assert(tramp != NULL);

    default_sigreturn = sigtramp_page;
    write_arm_sigreturn(&tramp[0 * RETCODE_WORDS], TARGET_NR_sigreturn);
    write_thm_sigreturn(&tramp[1 * RETCODE_WORDS], TARGET_NR_sigreturn);
    write_arm_sigreturn(&tramp[2 * RETCODE_WORDS], TARGET_NR_rt_sigreturn);
    write_thm_sigreturn(&tramp[3 * RETCODE_WORDS], TARGET_NR_rt_sigreturn);

    sigreturn_fdpic_tramp = sigtramp_page + 4 * RETCODE_BYTES;
    write_arm_fdpic_sigreturn(tramp + 4 * RETCODE_WORDS,
                              offsetof(struct sigframe, retcode[3]));
    write_thm_fdpic_sigreturn(tramp + 5 * RETCODE_WORDS,
                                offsetof(struct sigframe, retcode[3]));
    write_arm_fdpic_sigreturn(tramp + 6 * RETCODE_WORDS,
                              offsetof(struct rt_sigframe, sig.retcode[3]));
    write_thm_fdpic_sigreturn(tramp + 7 * RETCODE_WORDS,
                              offsetof(struct rt_sigframe, sig.retcode[3]));

    unlock_user(tramp, sigtramp_page, total_size);
}
