linux-user: Handle rt_sigaction correctly for SPARC
SPARC is like Alpha in its handling of the rt_sigaction syscall: it takes an extra parameter 'restorer' which needs to be copied into the sa_restorer field of the sigaction struct. The order of the arguments differs slightly between SPARC and Alpha but the implementation is otherwise the same. (Compare the rt_sigaction() functions in arch/sparc/kernel/sys_sparc_64.c and arch/alpha/kernel/signal.c.) Note that this change is somewhat moot until SPARC acquires support for actually delivering RT signals. Reviewed-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
parent
8d8cb956e0
commit
78bfef72fb
@ -8579,8 +8579,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_rt_sigaction:
|
||||
{
|
||||
#if defined(TARGET_ALPHA)
|
||||
struct target_sigaction act, oact, *pact = 0;
|
||||
/* For Alpha and SPARC this is a 5 argument syscall, with
|
||||
* a 'restorer' parameter which must be copied into the
|
||||
* sa_restorer field of the sigaction struct.
|
||||
* For Alpha that 'restorer' is arg5; for SPARC it is arg4,
|
||||
* and arg5 is the sigsetsize.
|
||||
* Alpha also has a separate rt_sigaction struct that it uses
|
||||
* here; SPARC uses the usual sigaction struct.
|
||||
*/
|
||||
struct target_rt_sigaction *rt_act;
|
||||
struct target_sigaction act, oact, *pact = 0;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
@ -8606,18 +8614,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
unlock_user_struct(rt_act, arg3, 1);
|
||||
}
|
||||
#else
|
||||
#ifdef TARGET_SPARC
|
||||
target_ulong restorer = arg4;
|
||||
target_ulong sigsetsize = arg5;
|
||||
#else
|
||||
target_ulong sigsetsize = arg4;
|
||||
#endif
|
||||
struct target_sigaction *act;
|
||||
struct target_sigaction *oact;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
if (sigsetsize != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
|
||||
if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
|
||||
goto efault;
|
||||
} else
|
||||
}
|
||||
#ifdef TARGET_SPARC
|
||||
act->sa_restorer = restorer;
|
||||
#endif
|
||||
} else {
|
||||
act = NULL;
|
||||
}
|
||||
if (arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
|
||||
ret = -TARGET_EFAULT;
|
||||
|
Loading…
Reference in New Issue
Block a user