#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>
+#ifdef __ia64__
+#undef uc_mcontext
+#undef uc_sigmask
+#undef uc_stack
+#undef uc_link
+#endif
+
#include "qemu.h"
//#define DEBUG_SIGNAL
tinfo->si_signo = sig;
tinfo->si_errno = 0;
tinfo->si_code = 0;
- if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
+ 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._sigfault._addr = 0;
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 || sig == SIGBUS) {
+ if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
+ sig == SIGBUS || sig == SIGTRAP) {
tinfo->_sifields._sigfault._addr =
tswapl(info->_sifields._sigfault._addr);
} else if (sig >= TARGET_SIGRTMIN) {
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = host_signal_handler;
for(i = 1; i < NSIG; i++) {
- sigaction(i, &act, NULL);
+ sigaction(i, &act, NULL);
}
memset(sigact_table, 0, sizeof(sigact_table));
{
int host_sig;
host_sig = target_to_host_signal(sig);
- fprintf(stderr, "gemu: 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_sigal: sig=%d\n",
+ fprintf(stderr, "queue_signal: sig=%d\n",
sig);
#endif
k = &sigact_table[sig - 1];
/* 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 (cpu_x86_signal_handler(host_signum, info, puc))
+ if (cpu_signal_handler(host_signum, info, puc))
return;
}
if (sig < 1 || sig > TARGET_NSIG)
return;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "gemu: got signal %d\n", sig);
+ fprintf(stderr, "qemu: got signal %d\n", sig);
dump_regs(puc);
#endif
host_to_target_siginfo_noswap(&tinfo, info);
if (queue_signal(sig, &tinfo) == 1) {
/* interrupt the virtual CPU as soon as possible */
- cpu_x86_interrupt(global_env);
+ cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
}
}
{
int err = 0;
- err |= __put_user(env->segs[R_GS], (unsigned int *)&sc->gs);
- err |= __put_user(env->segs[R_FS], (unsigned int *)&sc->fs);
- err |= __put_user(env->segs[R_ES], (unsigned int *)&sc->es);
- err |= __put_user(env->segs[R_DS], (unsigned int *)&sc->ds);
+ err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
+ err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
+ err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
+ err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
err |= __put_user(env->regs[R_EDI], &sc->edi);
err |= __put_user(env->regs[R_ESI], &sc->esi);
err |= __put_user(env->regs[R_EBP], &sc->ebp);
err |= __put_user(env->regs[R_EDX], &sc->edx);
err |= __put_user(env->regs[R_ECX], &sc->ecx);
err |= __put_user(env->regs[R_EAX], &sc->eax);
- err |= __put_user(/*current->thread.trap_no*/ 0, &sc->trapno);
- err |= __put_user(/*current->thread.error_code*/ 0, &sc->err);
+ err |= __put_user(env->exception_index, &sc->trapno);
+ err |= __put_user(env->error_code, &sc->err);
err |= __put_user(env->eip, &sc->eip);
- err |= __put_user(env->segs[R_CS], (unsigned int *)&sc->cs);
+ err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
err |= __put_user(env->eflags, &sc->eflags);
err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
- err |= __put_user(env->segs[R_SS], (unsigned int *)&sc->ss);
-#if 0
- tmp = save_i387(fpstate);
- if (tmp < 0)
- err = 1;
- else
- err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
-#else
- err |= __put_user(0, &sc->fpstate);
-#endif
+ err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
+
+ cpu_x86_fsave(env, (void *)fpstate, 1);
+ fpstate->status = fpstate->sw;
+ err |= __put_user(0xffff, &fpstate->magic);
+ err |= __put_user(fpstate, &sc->fpstate);
+
/* non-iBCS2 extensions.. */
err |= __put_user(mask, &sc->oldmask);
- err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
-
+ err |= __put_user(env->cr[2], &sc->cr2);
return err;
}
}
/* This is the legacy signal stack switching. */
- else if ((regs->xss & 0xffff) != __USER_DS &&
- !(ka->sa.sa_flags & SA_RESTORER) &&
- ka->sa.sa_restorer) {
- esp = (unsigned long) ka->sa.sa_restorer;
- }
+ else
#endif
- return (void *)((esp - frame_size) & -8ul);
+ if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
+ !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
+ ka->sa.sa_restorer) {
+ esp = (unsigned long) ka->sa.sa_restorer;
+ }
+ return (void *)((esp - frame_size) & -8ul);
}
static void setup_frame(int sig, struct emulated_sigaction *ka,
{
unsigned int err = 0;
-
-
-#define COPY(x) err |= __get_user(regs->x, &sc->x)
-
-#define COPY_SEG(seg) \
- { unsigned short tmp; \
- err |= __get_user(tmp, &sc->seg); \
- regs->x##seg = tmp; }
-
-#define COPY_SEG_STRICT(seg) \
- { unsigned short tmp; \
- err |= __get_user(tmp, &sc->seg); \
- regs->x##seg = tmp|3; }
-
-#define GET_SEG(seg) \
- { unsigned short tmp; \
- err |= __get_user(tmp, &sc->seg); \
- loadsegment(seg,tmp); }
-
cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
// regs->orig_eax = -1; /* disable syscall checks */
}
-#if 0
{
struct _fpstate * buf;
- err |= __get_user(buf, &sc->fpstate);
+ buf = (void *)ldl(&sc->fpstate);
if (buf) {
+#if 0
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
- err |= restore_i387(buf);
+#endif
+ cpu_x86_frstor(env, (void *)buf, 1);
}
}
-#endif
+
*peax = ldl(&sc->eax);
return err;
#if 0
sigset_t set;
int eax, i;
+#if defined(DEBUG_SIGNAL)
+ fprintf(stderr, "do_sigreturn\n");
+#endif
/* set blocked signals */
target_set.sig[0] = frame->sc.oldmask;
for(i = 1; i < TARGET_NSIG_WORDS; i++)
return 0;
}
+#else
+
+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;
+}
+
#endif
void process_pending_signals(void *cpu_env)
handle_signal:
#ifdef DEBUG_SIGNAL
- fprintf(stderr, "gemu: process signal %d\n", sig);
+ fprintf(stderr, "qemu: process signal %d\n", sig);
#endif
/* dequeue signal */
q = k->first;
end of the signal execution (see do_sigreturn) */
host_to_target_sigset(&target_old_set, &old_set);
+ /* if the CPU is in VM86 mode, we restore the 32 bit values */
+#ifdef TARGET_I386
+ {
+ CPUX86State *env = cpu_env;
+ if (env->eflags & VM_MASK)
+ save_v86_state(env);
+ }
+#endif
/* prepare the stack frame of the virtual CPU */
if (k->sa.sa_flags & TARGET_SA_SIGINFO)
setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);