+ k = &sigact_table[sig - 1];
+#ifdef DEBUG_SIGNAL
+ fprintf(stderr, "gemu: got signal %d\n", sig);
+#endif
+ 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 &&
+ sig != TARGET_SIGWINCH) {
+ force_sig(sig);
+ }
+ } else if (handler == TARGET_SIG_IGN) {
+ /* ignore signal */
+ } else if (handler == TARGET_SIG_ERR) {
+ force_sig(sig);
+ } else {
+ queue_signal(k, sig, info);
+ }
+}
+
+int do_sigaction(int sig, const struct target_sigaction *act,
+ struct target_sigaction *oact)
+{
+ struct emulated_sigaction *k;
+
+ if (sig < 1 || sig > TARGET_NSIG)
+ return -EINVAL;
+ k = &sigact_table[sig - 1];
+#if defined(DEBUG_SIGNAL) && 0
+ fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
+ sig, (int)act, (int)oact);
+#endif
+ if (oact) {
+ oact->_sa_handler = tswapl(k->sa._sa_handler);
+ oact->sa_flags = tswapl(k->sa.sa_flags);
+ oact->sa_restorer = tswapl(k->sa.sa_restorer);
+ oact->sa_mask = k->sa.sa_mask;
+ }
+ if (act) {
+ k->sa._sa_handler = tswapl(act->_sa_handler);
+ k->sa.sa_flags = tswapl(act->sa_flags);
+ k->sa.sa_restorer = tswapl(act->sa_restorer);
+ k->sa.sa_mask = act->sa_mask;
+ }
+ return 0;
+}
+
+#ifdef TARGET_I386
+
+/* from the Linux kernel */
+
+struct target_fpreg {
+ uint16_t significand[4];
+ uint16_t exponent;
+};
+
+struct target_fpxreg {
+ uint16_t significand[4];
+ uint16_t exponent;
+ uint16_t padding[3];
+};
+
+struct target_xmmreg {
+ target_ulong element[4];
+};
+
+struct target_fpstate {
+ /* Regular FPU environment */
+ target_ulong cw;
+ target_ulong sw;
+ target_ulong tag;
+ target_ulong ipoff;
+ target_ulong cssel;
+ target_ulong dataoff;
+ target_ulong datasel;
+ struct target_fpreg _st[8];
+ uint16_t status;
+ uint16_t magic; /* 0xffff = regular FPU data only */
+
+ /* FXSR FPU environment */
+ target_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
+ target_ulong mxcsr;
+ target_ulong reserved;
+ struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
+ struct target_xmmreg _xmm[8];
+ target_ulong padding[56];
+};
+
+#define X86_FXSR_MAGIC 0x0000
+
+struct target_sigcontext {
+ uint16_t gs, __gsh;
+ uint16_t fs, __fsh;
+ uint16_t es, __esh;
+ uint16_t ds, __dsh;
+ target_ulong edi;
+ target_ulong esi;
+ target_ulong ebp;
+ target_ulong esp;
+ target_ulong ebx;
+ target_ulong edx;
+ target_ulong ecx;
+ target_ulong eax;
+ target_ulong trapno;
+ target_ulong err;
+ target_ulong eip;
+ uint16_t cs, __csh;
+ target_ulong eflags;
+ target_ulong esp_at_signal;
+ uint16_t ss, __ssh;
+ target_ulong fpstate; /* pointer */
+ target_ulong oldmask;
+ 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 uc_flags;
+ target_ulong uc_link;
+ target_stack_t uc_stack;
+ struct target_sigcontext uc_mcontext;
+ target_sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+struct sigframe
+{
+ target_ulong pretcode;
+ int sig;
+ struct target_sigcontext sc;
+ struct target_fpstate fpstate;
+ target_ulong extramask[TARGET_NSIG_WORDS-1];
+ char retcode[8];
+};
+
+struct rt_sigframe
+{
+ target_ulong pretcode;
+ int sig;
+ target_ulong pinfo;
+ target_ulong puc;
+ struct target_siginfo info;
+ struct target_ucontext uc;
+ struct target_fpstate fpstate;
+ char retcode[8];
+};
+
+/*
+ * Set up a signal frame.
+ */
+
+#define __put_user(x,ptr)\
+({\
+ int size = sizeof(*ptr);\
+ switch(size) {\
+ case 1:\
+ stb(ptr, (typeof(*ptr))(x));\
+ break;\
+ case 2:\
+ stw(ptr, (typeof(*ptr))(x));\
+ break;\
+ case 4:\
+ stl(ptr, (typeof(*ptr))(x));\
+ break;\
+ case 8:\
+ stq(ptr, (typeof(*ptr))(x));\
+ break;\
+ default:\
+ abort();\
+ }\
+ 0;\
+})
+
+#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
+
+
+#define __copy_to_user(dst, src, size)\
+({\
+ memcpy(dst, src, size);\
+ 0;\
+})
+
+static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, siginfo_t *info)
+{
+ host_to_target_siginfo(tinfo, info);
+ return 0;
+}
+
+/* XXX: save x87 state */
+static int
+setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
+ CPUX86State *env, unsigned long mask)
+{
+ 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->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_ESP], &sc->esp);
+ err |= __put_user(env->regs[R_EBX], &sc->ebx);
+ 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->eip, &sc->eip);
+ err |= __put_user(env->segs[R_CS], (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
+ /* non-iBCS2 extensions.. */
+ err |= __put_user(mask, &sc->oldmask);
+ err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
+
+ return err;