linux-user sigaltstack() syscall, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3252 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e3b9808535
commit
a04e134ad1
24
linux-user/alpha/target_signal.h
Normal file
24
linux-user/alpha/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 4096
|
||||||
|
#define TARGET_SIGSTKSZ 16384
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/arm/target_signal.h
Normal file
24
linux-user/arm/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/i386/target_signal.h
Normal file
24
linux-user/i386/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/m68k/target_signal.h
Normal file
24
linux-user/m68k/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/mips/target_signal.h
Normal file
24
linux-user/mips/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_ulong ss_size;
|
||||||
|
target_long ss_flags;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/ppc/target_signal.h
Normal file
24
linux-user/ppc/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/ppc64/target_signal.h
Normal file
24
linux-user/ppc64/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "target_signal.h"
|
||||||
#include "gdbstub.h"
|
#include "gdbstub.h"
|
||||||
|
|
||||||
/* This struct is used to hold certain information about the image.
|
/* This struct is used to hold certain information about the image.
|
||||||
@ -149,6 +150,9 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
|
|||||||
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
|
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
|
||||||
long do_sigreturn(CPUState *env);
|
long do_sigreturn(CPUState *env);
|
||||||
long do_rt_sigreturn(CPUState *env);
|
long do_rt_sigreturn(CPUState *env);
|
||||||
|
int do_sigaltstack(const struct target_sigaltstack *uss,
|
||||||
|
struct target_sigaltstack *uoss,
|
||||||
|
target_ulong sp);
|
||||||
|
|
||||||
#ifdef TARGET_I386
|
#ifdef TARGET_I386
|
||||||
/* vm86.c */
|
/* vm86.c */
|
||||||
|
24
linux-user/sh4/target_signal.h
Normal file
24
linux-user/sh4/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
@ -26,6 +26,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/ucontext.h>
|
#include <sys/ucontext.h>
|
||||||
|
|
||||||
|
#include "target_signal.h"
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
|
|
||||||
//#define DEBUG_SIGNAL
|
//#define DEBUG_SIGNAL
|
||||||
@ -45,6 +46,12 @@ struct emulated_sigaction {
|
|||||||
first signal, we put it here */
|
first signal, we put it here */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct target_sigaltstack target_sigaltstack_used = {
|
||||||
|
.ss_sp = 0,
|
||||||
|
.ss_size = 0,
|
||||||
|
.ss_flags = TARGET_SS_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
static struct emulated_sigaction sigact_table[TARGET_NSIG];
|
static struct emulated_sigaction sigact_table[TARGET_NSIG];
|
||||||
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
|
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
|
||||||
static struct sigqueue *first_free; /* first free siginfo queue entry */
|
static struct sigqueue *first_free; /* first free siginfo queue entry */
|
||||||
@ -92,6 +99,18 @@ static uint8_t host_to_target_signal_table[65] = {
|
|||||||
};
|
};
|
||||||
static uint8_t target_to_host_signal_table[65];
|
static uint8_t target_to_host_signal_table[65];
|
||||||
|
|
||||||
|
static inline int on_sig_stack(unsigned long sp)
|
||||||
|
{
|
||||||
|
return (sp - target_sigaltstack_used.ss_sp
|
||||||
|
< target_sigaltstack_used.ss_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int sas_ss_flags(unsigned long sp)
|
||||||
|
{
|
||||||
|
return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
|
||||||
|
: on_sig_stack(sp) ? SS_ONSTACK : 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int host_to_target_signal(int sig)
|
static inline int host_to_target_signal(int sig)
|
||||||
{
|
{
|
||||||
return host_to_target_signal_table[sig];
|
return host_to_target_signal_table[sig];
|
||||||
@ -419,6 +438,67 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do_sigaltstack(const struct target_sigaltstack *uss,
|
||||||
|
struct target_sigaltstack *uoss,
|
||||||
|
target_ulong sp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct target_sigaltstack oss;
|
||||||
|
|
||||||
|
/* XXX: test errors */
|
||||||
|
if(uoss)
|
||||||
|
{
|
||||||
|
__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)
|
||||||
|
{
|
||||||
|
struct target_sigaltstack ss;
|
||||||
|
|
||||||
|
ret = -EFAULT;
|
||||||
|
if (!access_ok(VERIFY_READ, uss, sizeof(*uss))
|
||||||
|
|| __get_user(ss.ss_sp, &uss->ss_sp)
|
||||||
|
|| __get_user(ss.ss_size, &uss->ss_size)
|
||||||
|
|| __get_user(ss.ss_flags, &uss->ss_flags))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -EPERM;
|
||||||
|
if (on_sig_stack(sp))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -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 = -ENOMEM;
|
||||||
|
if (ss.ss_size < MINSIGSTKSZ)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_sigaltstack_used.ss_sp = ss.ss_sp;
|
||||||
|
target_sigaltstack_used.ss_size = ss.ss_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uoss) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss)))
|
||||||
|
goto out;
|
||||||
|
memcpy(uoss, &oss, sizeof(oss));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int do_sigaction(int sig, const struct target_sigaction *act,
|
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||||
struct target_sigaction *oact)
|
struct target_sigaction *oact)
|
||||||
{
|
{
|
||||||
@ -551,12 +631,6 @@ struct target_sigcontext {
|
|||||||
target_ulong cr2;
|
target_ulong cr2;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct target_sigaltstack {
|
|
||||||
target_ulong ss_sp;
|
|
||||||
int ss_flags;
|
|
||||||
target_ulong ss_size;
|
|
||||||
} target_stack_t;
|
|
||||||
|
|
||||||
struct target_ucontext {
|
struct target_ucontext {
|
||||||
target_ulong tuc_flags;
|
target_ulong tuc_flags;
|
||||||
target_ulong tuc_link;
|
target_ulong tuc_link;
|
||||||
@ -640,16 +714,14 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
|
|||||||
|
|
||||||
/* Default to using normal stack */
|
/* Default to using normal stack */
|
||||||
esp = env->regs[R_ESP];
|
esp = env->regs[R_ESP];
|
||||||
#if 0
|
|
||||||
/* This is the X/Open sanctioned signal stack switching. */
|
/* This is the X/Open sanctioned signal stack switching. */
|
||||||
if (ka->sa.sa_flags & SA_ONSTACK) {
|
if (ka->sa.sa_flags & TARGET_SA_ONSTACK) {
|
||||||
if (sas_ss_flags(esp) == 0)
|
if (sas_ss_flags(esp) == 0)
|
||||||
esp = current->sas_ss_sp + current->sas_ss_size;
|
esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the legacy signal stack switching. */
|
/* This is the legacy signal stack switching. */
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
|
if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
|
||||||
!(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
|
!(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
|
||||||
ka->sa.sa_restorer) {
|
ka->sa.sa_restorer) {
|
||||||
@ -750,11 +822,11 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
|
|||||||
/* Create the ucontext. */
|
/* Create the ucontext. */
|
||||||
err |= __put_user(0, &frame->uc.tuc_flags);
|
err |= __put_user(0, &frame->uc.tuc_flags);
|
||||||
err |= __put_user(0, &frame->uc.tuc_link);
|
err |= __put_user(0, &frame->uc.tuc_link);
|
||||||
err |= __put_user(/*current->sas_ss_sp*/ 0,
|
err |= __put_user(target_sigaltstack_used.ss_sp,
|
||||||
&frame->uc.tuc_stack.ss_sp);
|
&frame->uc.tuc_stack.ss_sp);
|
||||||
err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
|
err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||||
&frame->uc.tuc_stack.ss_flags);
|
&frame->uc.tuc_stack.ss_flags);
|
||||||
err |= __put_user(/* current->sas_ss_size */ 0,
|
err |= __put_user(target_sigaltstack_used.ss_size,
|
||||||
&frame->uc.tuc_stack.ss_size);
|
&frame->uc.tuc_stack.ss_size);
|
||||||
err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
|
err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
|
||||||
env, set->sig[0]);
|
env, set->sig[0]);
|
||||||
@ -880,7 +952,6 @@ long do_rt_sigreturn(CPUX86State *env)
|
|||||||
{
|
{
|
||||||
struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
|
struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
// stack_t st;
|
|
||||||
int eax;
|
int eax;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -893,13 +964,9 @@ long do_rt_sigreturn(CPUX86State *env)
|
|||||||
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
|
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
#if 0
|
if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
|
||||||
if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st)))
|
|
||||||
goto badframe;
|
goto badframe;
|
||||||
/* It is more difficult to avoid calling this function than to
|
|
||||||
call it and ignore errors. */
|
|
||||||
do_sigaltstack(&st, NULL, regs->esp);
|
|
||||||
#endif
|
|
||||||
return eax;
|
return eax;
|
||||||
|
|
||||||
badframe:
|
badframe:
|
||||||
@ -933,12 +1000,6 @@ struct target_sigcontext {
|
|||||||
target_ulong fault_address;
|
target_ulong fault_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct target_sigaltstack {
|
|
||||||
target_ulong ss_sp;
|
|
||||||
int ss_flags;
|
|
||||||
target_ulong ss_size;
|
|
||||||
} target_stack_t;
|
|
||||||
|
|
||||||
struct target_ucontext {
|
struct target_ucontext {
|
||||||
target_ulong tuc_flags;
|
target_ulong tuc_flags;
|
||||||
target_ulong tuc_link;
|
target_ulong tuc_link;
|
||||||
@ -1031,13 +1092,11 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
|
|||||||
{
|
{
|
||||||
unsigned long sp = regs->regs[13];
|
unsigned long sp = regs->regs[13];
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
/*
|
||||||
* This is the X/Open sanctioned signal stack switching.
|
* This is the X/Open sanctioned signal stack switching.
|
||||||
*/
|
*/
|
||||||
if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
|
if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* ATPCS B01 mandates 8-byte alignment
|
* ATPCS B01 mandates 8-byte alignment
|
||||||
*/
|
*/
|
||||||
@ -1074,8 +1133,8 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
|
|||||||
else
|
else
|
||||||
cpsr &= ~T_BIT;
|
cpsr &= ~T_BIT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* CONFIG_ARM_THUMB */
|
||||||
#endif
|
#endif /* 0 */
|
||||||
#endif /* TARGET_CONFIG_CPU_32 */
|
#endif /* TARGET_CONFIG_CPU_32 */
|
||||||
|
|
||||||
if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
|
if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
|
||||||
@ -1132,6 +1191,7 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
|
|||||||
target_sigset_t *set, CPUState *env)
|
target_sigset_t *set, CPUState *env)
|
||||||
{
|
{
|
||||||
struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
|
struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
|
||||||
|
struct target_sigaltstack stack;
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
@ -1144,6 +1204,15 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
|
|||||||
/* Clear all the bits of the ucontext we don't use. */
|
/* Clear all the bits of the ucontext we don't use. */
|
||||||
memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));
|
memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));
|
||||||
|
|
||||||
|
memset(&stack, 0, sizeof(stack));
|
||||||
|
__put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
|
||||||
|
__put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
|
||||||
|
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
|
||||||
|
if (!access_ok(VERIFY_WRITE, &frame->uc.tuc_stack, sizeof(stack)))
|
||||||
|
err = 1;
|
||||||
|
else
|
||||||
|
memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
|
||||||
|
|
||||||
err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
|
err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
|
||||||
env, set->sig[0]);
|
env, set->sig[0]);
|
||||||
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
|
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||||
@ -1270,6 +1339,9 @@ long do_rt_sigreturn(CPUState *env)
|
|||||||
if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
|
if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
|
if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
|
||||||
|
goto badframe;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Send SIGTRAP if we're single-stepping */
|
/* Send SIGTRAP if we're single-stepping */
|
||||||
if (ptrace_cancel_bpt(current))
|
if (ptrace_cancel_bpt(current))
|
||||||
@ -1382,14 +1454,13 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
|
|||||||
unsigned long sp;
|
unsigned long sp;
|
||||||
|
|
||||||
sp = env->regwptr[UREG_FP];
|
sp = env->regwptr[UREG_FP];
|
||||||
#if 0
|
|
||||||
|
|
||||||
/* This is the X/Open sanctioned signal stack switching. */
|
/* This is the X/Open sanctioned signal stack switching. */
|
||||||
if (sa->sa_flags & TARGET_SA_ONSTACK) {
|
if (sa->sa.sa_flags & TARGET_SA_ONSTACK) {
|
||||||
if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
|
if (!on_sig_stack(sp)
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
&& !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
|
||||||
|
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return g2h(sp - framesize);
|
return g2h(sp - framesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1842,11 +1913,10 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
|
|||||||
*/
|
*/
|
||||||
sp -= 32;
|
sp -= 32;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* This is the X/Open sanctioned signal stack switching. */
|
/* This is the X/Open sanctioned signal stack switching. */
|
||||||
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
|
if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return g2h((sp - frame_size) & ~7);
|
return g2h((sp - frame_size) & ~7);
|
||||||
}
|
}
|
||||||
|
24
linux-user/sparc/target_signal.h
Normal file
24
linux-user/sparc/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 4096
|
||||||
|
#define TARGET_SIGSTKSZ 16384
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
24
linux-user/sparc64/target_signal.h
Normal file
24
linux-user/sparc64/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 4096
|
||||||
|
#define TARGET_SIGSTKSZ 16384
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
@ -4318,7 +4318,14 @@ target_long do_syscall(void *cpu_env, int num, target_long arg1,
|
|||||||
case TARGET_NR_capset:
|
case TARGET_NR_capset:
|
||||||
goto unimplemented;
|
goto unimplemented;
|
||||||
case TARGET_NR_sigaltstack:
|
case TARGET_NR_sigaltstack:
|
||||||
|
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
|
||||||
|
ret = do_sigaltstack((struct target_sigaltstack *)arg1,
|
||||||
|
(struct target_sigaltstack *)arg2,
|
||||||
|
get_sp_from_cpustate((CPUState *)cpu_env));
|
||||||
|
break;
|
||||||
|
#else
|
||||||
goto unimplemented;
|
goto unimplemented;
|
||||||
|
#endif
|
||||||
case TARGET_NR_sendfile:
|
case TARGET_NR_sendfile:
|
||||||
goto unimplemented;
|
goto unimplemented;
|
||||||
#ifdef TARGET_NR_getpmsg
|
#ifdef TARGET_NR_getpmsg
|
||||||
|
24
linux-user/x86_64/target_signal.h
Normal file
24
linux-user/x86_64/target_signal.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef TARGET_SIGNAL_H
|
||||||
|
#define TARGET_SIGNAL_H
|
||||||
|
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
/* this struct defines a stack used during syscall handling */
|
||||||
|
|
||||||
|
typedef struct target_sigaltstack {
|
||||||
|
target_ulong ss_sp;
|
||||||
|
target_long ss_flags;
|
||||||
|
target_ulong ss_size;
|
||||||
|
} target_stack_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigaltstack controls
|
||||||
|
*/
|
||||||
|
#define TARGET_SS_ONSTACK 1
|
||||||
|
#define TARGET_SS_DISABLE 2
|
||||||
|
|
||||||
|
#define TARGET_MINSIGSTKSZ 2048
|
||||||
|
#define TARGET_SIGSTKSZ 8192
|
||||||
|
|
||||||
|
#endif /* TARGET_SIGNAL_H */
|
@ -397,4 +397,9 @@ void cpu_loop_exit (void);
|
|||||||
void pal_init (CPUState *env);
|
void pal_init (CPUState *env);
|
||||||
void call_pal (CPUState *env, int palcode);
|
void call_pal (CPUState *env, int palcode);
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUAlphaState *state)
|
||||||
|
{
|
||||||
|
return state->ir[IR_SP];
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined (__CPU_ALPHA_H__) */
|
#endif /* !defined (__CPU_ALPHA_H__) */
|
||||||
|
@ -300,6 +300,11 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
|
|||||||
#define cpu_gen_code cpu_arm_gen_code
|
#define cpu_gen_code cpu_arm_gen_code
|
||||||
#define cpu_signal_handler cpu_arm_signal_handler
|
#define cpu_signal_handler cpu_arm_signal_handler
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUARMState *state)
|
||||||
|
{
|
||||||
|
return state->regs[13];
|
||||||
|
}
|
||||||
|
|
||||||
#include "cpu-all.h"
|
#include "cpu-all.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -688,6 +688,11 @@ static inline int cpu_get_time_fast(void)
|
|||||||
#define cpu_gen_code cpu_x86_gen_code
|
#define cpu_gen_code cpu_x86_gen_code
|
||||||
#define cpu_signal_handler cpu_x86_signal_handler
|
#define cpu_signal_handler cpu_x86_signal_handler
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUX86State *state)
|
||||||
|
{
|
||||||
|
return state->regs[R_ESP];
|
||||||
|
}
|
||||||
|
|
||||||
#include "cpu-all.h"
|
#include "cpu-all.h"
|
||||||
|
|
||||||
#include "svm.h"
|
#include "svm.h"
|
||||||
|
@ -548,4 +548,9 @@ CPUMIPSState *cpu_mips_init(void);
|
|||||||
uint32_t cpu_mips_get_clock (void);
|
uint32_t cpu_mips_get_clock (void);
|
||||||
int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
|
int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUMIPSState *state)
|
||||||
|
{
|
||||||
|
return state->gpr[29][state->current_tc];
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined (__MIPS_CPU_H__) */
|
#endif /* !defined (__MIPS_CPU_H__) */
|
||||||
|
@ -1146,4 +1146,9 @@ enum {
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUPPCState *state)
|
||||||
|
{
|
||||||
|
return state->gpr[1];
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined (__CPU_PPC_H__) */
|
#endif /* !defined (__CPU_PPC_H__) */
|
||||||
|
@ -316,6 +316,18 @@ void cpu_check_irqs(CPUSPARCState *env);
|
|||||||
#define cpu_gen_code cpu_sparc_gen_code
|
#define cpu_gen_code cpu_sparc_gen_code
|
||||||
#define cpu_signal_handler cpu_sparc_signal_handler
|
#define cpu_signal_handler cpu_sparc_signal_handler
|
||||||
|
|
||||||
|
#ifndef UREG_I6
|
||||||
|
#define UREG_I6 6
|
||||||
|
#endif
|
||||||
|
#ifndef UREG_FP
|
||||||
|
#define UREG_FP UREG_I6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline target_ulong get_sp_from_cpustate(CPUSPARCState *state)
|
||||||
|
{
|
||||||
|
return state->regwptr[UREG_FP];
|
||||||
|
}
|
||||||
|
|
||||||
#include "cpu-all.h"
|
#include "cpu-all.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user