/*
* Emulation of Linux signals
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
#include <errno.h>
#include <sys/ucontext.h>
+#include "target_signal.h"
#include "qemu.h"
//#define DEBUG_SIGNAL
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 sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
static struct sigqueue *first_free; /* first free siginfo queue entry */
static int signal_pending; /* non zero if a signal may be pending */
-static void host_signal_handler(int host_signum, siginfo_t *info,
+static void host_signal_handler(int host_signum, siginfo_t *info,
void *puc);
static uint8_t host_to_target_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)
{
return host_to_target_signal_table[sig];
return target_to_host_signal_table[sig];
}
-static void host_to_target_sigset_internal(target_sigset_t *d,
+static void host_to_target_sigset_internal(target_sigset_t *d,
const sigset_t *s)
{
int i;
unsigned long sigmask;
uint32_t target_sigmask;
-
+
sigmask = ((unsigned long *)s)[0];
target_sigmask = 0;
for(i = 0; i < 32; i++) {
- if (sigmask & (1 << i))
+ if (sigmask & (1 << i))
target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
}
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
target_sigmask = s->sig[0];
sigmask = 0;
for(i = 0; i < 32; i++) {
- if (target_sigmask & (1 << i))
+ if (target_sigmask & (1 << i))
sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
}
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
s1.sig[i] = tswapl(s->sig[i]);
target_to_host_sigset_internal(d, &s1);
}
-
-void host_to_target_old_sigset(target_ulong *old_sigset,
+
+void host_to_target_old_sigset(target_ulong *old_sigset,
const sigset_t *sigset)
{
target_sigset_t d;
*old_sigset = d.sig[0];
}
-void target_to_host_old_sigset(sigset_t *sigset,
+void target_to_host_old_sigset(sigset_t *sigset,
const target_ulong *old_sigset)
{
target_sigset_t d;
/* siginfo conversion */
-static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
+static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
const siginfo_t *info)
{
int sig;
tinfo->si_signo = sig;
tinfo->si_errno = 0;
tinfo->si_code = 0;
- if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
+ if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
/* should never come here, but who knows. The information for
the target is irrelevant */
tinfo->_sifields._rt._pid = info->si_pid;
tinfo->_sifields._rt._uid = info->si_uid;
/* XXX: potential problem if 64 bit */
- tinfo->_sifields._rt._sigval.sival_ptr =
+ tinfo->_sifields._rt._sigval.sival_ptr =
(target_ulong)info->si_value.sival_ptr;
}
}
-static void tswap_siginfo(target_siginfo_t *tinfo,
+static void tswap_siginfo(target_siginfo_t *tinfo,
const target_siginfo_t *info)
{
int sig;
tinfo->si_signo = tswap32(sig);
tinfo->si_errno = tswap32(info->si_errno);
tinfo->si_code = tswap32(info->si_code);
- if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
+ if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
- tinfo->_sifields._sigfault._addr =
+ tinfo->_sifields._sigfault._addr =
tswapl(info->_sifields._sigfault._addr);
} else if (sig == SIGIO) {
tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
} else if (sig >= TARGET_SIGRTMIN) {
tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
- tinfo->_sifields._rt._sigval.sival_ptr =
+ tinfo->_sifields._rt._sigval.sival_ptr =
tswapl(info->_sifields._rt._sigval.sival_ptr);
}
}
info->si_code = tswap32(tinfo->si_code);
info->si_pid = tswap32(tinfo->_sifields._rt._pid);
info->si_uid = tswap32(tinfo->_sifields._rt._uid);
- info->si_value.sival_ptr =
+ info->si_value.sival_ptr =
(void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
}
j = host_to_target_signal_table[i];
target_to_host_signal_table[j] = i;
}
-
+
/* set all host signal handlers. ALL signals are blocked during
the handlers to serialize them. */
sigfillset(&act.sa_mask);
for(i = 1; i < NSIG; i++) {
sigaction(i, &act, NULL);
}
-
+
memset(sigact_table, 0, sizeof(sigact_table));
first_free = &sigqueue_table[0];
- for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
+ for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
sigqueue_table[i].next = &sigqueue_table[i + 1];
sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
}
{
int host_sig;
host_sig = target_to_host_signal(sig);
- fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
+ fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
sig, strsignal(host_sig));
#if 1
_exit(-host_sig);
target_ulong handler;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "queue_signal: sig=%d\n",
+ fprintf(stderr, "queue_signal: sig=%d\n",
sig);
#endif
k = &sigact_table[sig - 1];
handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) {
/* default handler : ignore some signal. The other are fatal */
- if (sig != TARGET_SIGCHLD &&
- sig != TARGET_SIGURG &&
+ if (sig != TARGET_SIGCHLD &&
+ sig != TARGET_SIGURG &&
sig != TARGET_SIGWINCH) {
force_sig(sig);
} else {
}
}
-static void host_signal_handler(int host_signum, siginfo_t *info,
+static void host_signal_handler(int host_signum, siginfo_t *info,
void *puc)
{
int sig;
/* the CPU emulator uses some host signals to detect exceptions,
we we forward to it some signals */
- if (host_signum == SIGSEGV || host_signum == SIGBUS
+ if (host_signum == SIGSEGV || host_signum == SIGBUS
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
|| host_signum == SIGFPE
#endif
}
}
+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,
struct target_sigaction *oact)
{
return -EINVAL;
k = &sigact_table[sig - 1];
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
+ fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
sig, (int)act, (int)oact);
#endif
if (oact) {
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif
-static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
+static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
const target_siginfo_t *info)
{
tswap_siginfo(tinfo, info);
target_ulong cr2;
};
-typedef struct target_sigaltstack {
- target_ulong ss_sp;
- int ss_flags;
- target_ulong ss_size;
-} target_stack_t;
-
struct target_ucontext {
target_ulong tuc_flags;
target_ulong tuc_link;
/* Default to using normal stack */
esp = env->regs[R_ESP];
-#if 0
/* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(esp) == 0)
- esp = current->sas_ss_sp + current->sas_ss_size;
- }
+ if (ka->sa.sa_flags & TARGET_SA_ONSTACK) {
+ if (sas_ss_flags(esp) == 0)
+ esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
/* This is the legacy signal stack switching. */
- else
-#endif
+ else
if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
!(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
ka->sa.sa_restorer) {
force_sig(TARGET_SIGSEGV /* , current */);
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUX86State *env)
{
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.tuc_flags);
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);
- 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);
- err |= __put_user(/* current->sas_ss_size */ 0,
+ err |= __put_user(target_sigaltstack_used.ss_size,
&frame->uc.tuc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
env, set->sig[0]);
cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
-
+
{
unsigned int tmpflags;
tmpflags = ldl(&sc->eflags);
target_to_host_sigset_internal(&set, &target_set);
sigprocmask(SIG_SETMASK, &set, NULL);
-
+
/* restore registers */
if (restore_sigcontext(env, &frame->sc, &eax))
goto badframe;
{
struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
sigset_t set;
- // stack_t st;
int eax;
#if 0
#endif
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &set, NULL);
-
+
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
goto badframe;
-#if 0
- if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st)))
+ if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
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;
badframe:
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 {
target_ulong tuc_flags;
target_ulong tuc_link;
{
unsigned long sp = regs->regs[13];
-#if 0
/*
* This is the X/Open sanctioned signal stack switching.
*/
- if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
-#endif
+ if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
/*
* ATPCS B01 mandates 8-byte alignment
*/
else
cpsr &= ~T_BIT;
}
-#endif
-#endif
+#endif /* CONFIG_ARM_THUMB */
+#endif /* 0 */
#endif /* TARGET_CONFIG_CPU_32 */
if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
// return err;
}
-static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
+ struct target_sigaltstack stack;
int i, err = 0;
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
/* Clear all the bits of the ucontext we don't use. */
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,*/
env, set->sig[0]);
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
goto badframe;
+ if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
+ goto badframe;
+
#if 0
/* Send SIGTRAP if we're single-stepping */
if (ptrace_cancel_bpt(current))
unsigned long sp;
sp = env->regwptr[UREG_FP];
-#if 0
/* This is the X/Open sanctioned signal stack switching. */
- if (sa->sa_flags & TARGET_SA_ONSTACK) {
- if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ if (sa->sa.sa_flags & TARGET_SA_ONSTACK) {
+ if (!on_sig_stack(sp)
+ && !((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);
}
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
return -ENOSYS;
}
+#elif defined(TARGET_MIPS64)
+
+# warning signal handling not implemented
+
+static void setup_frame(int sig, struct emulated_sigaction *ka,
+ target_sigset_t *set, CPUState *env)
+{
+ fprintf(stderr, "setup_frame: not implemented\n");
+}
+
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUState *env)
+{
+ fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+ fprintf(stderr, "do_sigreturn: not implemented\n");
+ return -ENOSYS;
+}
+
+long do_rt_sigreturn(CPUState *env)
+{
+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+ return -ENOSYS;
+}
+
+#elif defined(TARGET_MIPSN32)
+
+# warning signal handling not implemented
+
+static void setup_frame(int sig, struct emulated_sigaction *ka,
+ target_sigset_t *set, CPUState *env)
+{
+ fprintf(stderr, "setup_frame: not implemented\n");
+}
+
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUState *env)
+{
+ fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+ fprintf(stderr, "do_sigreturn: not implemented\n");
+ return -ENOSYS;
+}
+
+long do_rt_sigreturn(CPUState *env)
+{
+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+ return -ENOSYS;
+}
+
#elif defined(TARGET_MIPS)
struct target_sigcontext {
{
int err = 0;
- err |= __put_user(regs->PC, &sc->sc_pc);
+ err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc);
-#define save_gp_reg(i) do { \
- err |= __put_user(regs->gpr[i], &sc->sc_regs[i]); \
+#define save_gp_reg(i) do { \
+ err |= __put_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
} while(0)
__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
save_gp_reg(31);
#undef save_gp_reg
- err |= __put_user(regs->HI, &sc->sc_mdhi);
- err |= __put_user(regs->LO, &sc->sc_mdlo);
+ err |= __put_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
+ err |= __put_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
/* Not used yet, but might be useful if we ever have DSP suppport */
#if 0
err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
- err |= __get_user(regs->HI, &sc->sc_mdhi);
- err |= __get_user(regs->LO, &sc->sc_mdlo);
+ err |= __get_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
+ err |= __get_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
-#define restore_gp_reg(i) do { \
- err |= __get_user(regs->gpr[i], &sc->sc_regs[i]); \
+#define restore_gp_reg(i) do { \
+ err |= __get_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \
} while(0)
restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
unsigned long sp;
/* Default to using normal stack */
- sp = regs->gpr[29];
+ sp = regs->gpr[29][regs->current_tc];
/*
* FPU emulator may have it's own trampoline active just
*/
sp -= 32;
-#if 0
/* This is the X/Open sanctioned signal stack switching. */
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
- sp = current->sas_ss_sp + current->sas_ss_size;
-#endif
+ if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
return g2h((sp - frame_size) & ~7);
}
-static void setup_frame(int sig, struct emulated_sigaction * ka,
+static void setup_frame(int sig, struct emulated_sigaction * ka,
target_sigset_t *set, CPUState *regs)
{
struct sigframe *frame;
* $25 and PC point to the signal handler, $29 points to the
* struct sigframe.
*/
- regs->gpr[ 4] = sig;
- regs->gpr[ 5] = 0;
- regs->gpr[ 6] = h2g(&frame->sf_sc);
- regs->gpr[29] = h2g(frame);
- regs->gpr[31] = h2g(frame->sf_code);
+ regs->gpr[ 4][regs->current_tc] = sig;
+ regs->gpr[ 5][regs->current_tc] = 0;
+ regs->gpr[ 6][regs->current_tc] = h2g(&frame->sf_sc);
+ regs->gpr[29][regs->current_tc] = h2g(frame);
+ regs->gpr[31][regs->current_tc] = h2g(frame->sf_code);
/* The original kernel code sets CP0_EPC to the handler
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
- regs->PC = regs->gpr[25] = ka->sa._sa_handler;
+ regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
return;
give_sigsegv:
force_sig(TARGET_SIGSEGV/*, current*/);
- return;
+ return;
}
long do_sigreturn(CPUState *regs)
#if defined(DEBUG_SIGNAL)
fprintf(stderr, "do_sigreturn\n");
#endif
- frame = (struct sigframe *) regs->gpr[29];
+ frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
:"r" (®s));
/* Unreached */
#endif
-
- regs->PC = regs->CP0_EPC;
+
+ regs->PC[regs->current_tc] = regs->CP0_EPC;
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
regs->CP0_EPC = 0;
return 0;
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
fprintf(stderr, "setup_frame: not implemented\n");
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
target_sigset_t target_old_set;
struct emulated_sigaction *k;
struct sigqueue *q;
-
+
if (!signal_pending)
return;
k->first = q->next;
if (!k->first)
k->pending = 0;
-
+
sig = gdb_handlesig (cpu_env, sig);
if (!sig) {
fprintf (stderr, "Lost signal\n");
handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) {
/* default handler : ignore some signal. The other are fatal */
- if (sig != TARGET_SIGCHLD &&
- sig != TARGET_SIGURG &&
+ if (sig != TARGET_SIGCHLD &&
+ sig != TARGET_SIGURG &&
sig != TARGET_SIGWINCH) {
force_sig(sig);
}
blocked during the handler */
if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
sigaddset(&set, target_to_host_signal(sig));
-
+
/* block signals in the handler using Linux */
sigprocmask(SIG_BLOCK, &set, &old_set);
/* save the previous blocked signal state to restore it at the