Sandbox/qemu-sgx-master/linux-user/signal.c
/* do_sigaltstack() returns target values and errnos. */
/* compare linux/kernel/signal.c:do_sigaltstack() */
do_sigaltstack() returns target values and errnos.
do_sigaltstack () returns target values and errnos .
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
{
    int ret;
    struct target_sigaltstack oss;
    if(uoss_addr)
    {
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
    }
    if(uss_addr)
    {
        struct target_sigaltstack *uss;
        struct target_sigaltstack ss;
        size_t minstacksize = TARGET_MINSIGSTKSZ;
#if defined(TARGET_PPC64)
        struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
        if (get_ppc64_abi(image) > 1) {
            minstacksize = 4096;
        }
#endif
	ret = -TARGET_EFAULT;
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
            goto out;
        }
        __get_user(ss.ss_sp, &uss->ss_sp);
        __get_user(ss.ss_size, &uss->ss_size);
        __get_user(ss.ss_flags, &uss->ss_flags);
        unlock_user_struct(uss, uss_addr, 0);
	ret = -TARGET_EPERM;
	if (on_sig_stack(sp))
            goto out;
	ret = -TARGET_EINVAL;
	if (ss.ss_flags != TARGET_SS_DISABLE
            && ss.ss_flags != TARGET_SS_ONSTACK
            && ss.ss_flags != 0)
            goto out;
	if (ss.ss_flags == TARGET_SS_DISABLE) {
            ss.ss_size = 0;
            ss.ss_sp = 0;
	} else {
            ret = -TARGET_ENOMEM;
            if (ss.ss_size < minstacksize) {
                goto out;
            }
	}
        target_sigaltstack_used.ss_sp = ss.ss_sp;
        target_sigaltstack_used.ss_size = ss.ss_size;
    }
    if (uoss_addr) {
        ret = -TARGET_EFAULT;
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
            goto out;
    }
    ret = 0;
out:
    return ret;
}
abi_long do_sigaltstack ( abi_ulong uss_addr , abi_ulong uoss_addr , abi_ulong sp ) { int ret ; struct target_sigaltstack oss ; if ( uoss_addr ) { __put_user ( target_sigaltstack_used . ss_sp , & oss . ss_sp ) ; __put_user ( target_sigaltstack_used . ss_size , & oss . ss_size ) ; __put_user ( sas_ss_flags ( sp ) , & oss . ss_flags ) ; } if ( uss_addr ) { struct target_sigaltstack * uss ; struct target_sigaltstack ss ; size_t minstacksize = TARGET_MINSIGSTKSZ ; #if defined ( TARGET_PPC64 ) struct image_info * image = ( ( TaskState * ) thread_cpu -> opaque ) -> info ; if ( get_ppc64_abi ( image ) > 1 ) { minstacksize = 4096 ; } #endif ret = - TARGET_EFAULT ; if ( ! lock_user_struct ( VERIFY_READ , uss , uss_addr , 1 ) ) { goto out ; } __get_user ( ss . ss_sp , & uss -> ss_sp ) ; __get_user ( ss . ss_size , & uss -> ss_size ) ; __get_user ( ss . ss_flags , & uss -> ss_flags ) ; unlock_user_struct ( uss , uss_addr , 0 ) ; ret = - TARGET_EPERM ; if ( on_sig_stack ( sp ) ) goto out ; ret = - TARGET_EINVAL ; if ( ss . ss_flags != TARGET_SS_DISABLE && ss . ss_flags != TARGET_SS_ONSTACK && ss . ss_flags != 0 ) goto out ; if ( ss . ss_flags == TARGET_SS_DISABLE ) { ss . ss_size = 0 ; ss . ss_sp = 0 ; } else { ret = - TARGET_ENOMEM ; if ( ss . ss_size < minstacksize ) { goto out ; } } target_sigaltstack_used . ss_sp = ss . ss_sp ; target_sigaltstack_used . ss_size = ss . ss_size ; } if ( uoss_addr ) { ret = - TARGET_EFAULT ; if ( copy_to_user ( uoss_addr , & oss , sizeof ( oss ) ) ) goto out ; } ret = 0 ; out : return ret ; }
do_sigaltstack() returns target values and errnos.
do_sigaltstack () returns target values and errnos .
/* XXX: test errors */ /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */