Commit 66fb9763af9cd743158957e8c9c2559d922b1c22

Authored by bellard
1 parent 1b6b029e

basic signal handling


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@41 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -36,7 +36,7 @@ LDFLAGS+=-p
36 36 main.o: CFLAGS+=-p
37 37 endif
38 38  
39   -OBJS= elfload.o main.o thunk.o syscall.o libgemu.a
  39 +OBJS= elfload.o main.o thunk.o syscall.o signal.o libgemu.a
40 40  
41 41 LIBOBJS+=translate-i386.o op-i386.o exec-i386.o
42 42 # NOTE: the disassembler code is only needed for debugging
... ...
  1 +- asynchronous signal interrupt / clear synchronous signal handling
  2 +- add eflags restore in emulator
  3 +- finish signal handing (fp87 state)
1 4 - verify thread support (clone() and various locks)
2   -- signals
3 5 - optimize translated cache chaining (DLL PLT-like system)
4 6 - vm86 syscall support
5 7 - overrides/16bit for string ops
... ...
linux-user/main.c
... ... @@ -81,10 +81,6 @@ int cpu_x86_inl(int addr)
81 81 return 0;
82 82 }
83 83  
84   -/* default linux values for the selectors */
85   -#define __USER_CS (0x23)
86   -#define __USER_DS (0x2B)
87   -
88 84 void write_dt(void *ptr, unsigned long addr, unsigned long limit,
89 85 int seg32_bit)
90 86 {
... ... @@ -135,6 +131,7 @@ void cpu_loop(struct CPUX86State *env)
135 131 (long)pc, err);
136 132 abort();
137 133 }
  134 + process_pending_signals(env);
138 135 }
139 136 }
140 137  
... ... @@ -199,6 +196,7 @@ int main(int argc, char **argv)
199 196  
200 197 target_set_brk((char *)info->brk);
201 198 syscall_init();
  199 + signal_init();
202 200  
203 201 env = cpu_x86_init();
204 202  
... ...
linux-user/qemu.h
... ... @@ -3,6 +3,12 @@
3 3  
4 4 #include "thunk.h"
5 5  
  6 +#ifdef TARGET_I386
  7 +
  8 +/* default linux values for the selectors */
  9 +#define __USER_CS (0x23)
  10 +#define __USER_DS (0x2B)
  11 +
6 12 struct target_pt_regs {
7 13 long ebx;
8 14 long ecx;
... ... @@ -21,6 +27,8 @@ struct target_pt_regs {
21 27 int xss;
22 28 };
23 29  
  30 +#endif
  31 +
24 32 /* This struct is used to hold certain information about the image.
25 33 * Basically, it replicates in user space what would be certain
26 34 * task_struct fields in the kernel
... ... @@ -53,5 +61,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
53 61 void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
54 62 struct CPUX86State;
55 63 void cpu_loop(struct CPUX86State *env);
  64 +void process_pending_signals(void *cpu_env);
  65 +void signal_init(void);
56 66  
57 67 #endif
... ...
linux-user/signal.c
1 1 /*
2   - * Emulation of Linux signal handling
  2 + * Emulation of Linux signals
3 3 *
4 4 * Copyright (c) 2003 Fabrice Bellard
5 5 *
... ... @@ -19,22 +19,49 @@
19 19 */
20 20 #include <stdlib.h>
21 21 #include <stdio.h>
  22 +#include <string.h>
22 23 #include <stdarg.h>
23 24 #include <signal.h>
  25 +#include <errno.h>
24 26 #include <sys/ucontext.h>
25 27  
26   -/* Algorithm strongly inspired from em86 : we queue the signals so
27   - that we can handle them at precise points in the emulated code. */
  28 +#include "gemu.h"
  29 +
  30 +#include "syscall_defs.h"
  31 +
  32 +#ifdef TARGET_I386
  33 +#include "cpu-i386.h"
  34 +#include "syscall-i386.h"
  35 +#endif
  36 +
  37 +/* signal handling inspired from em86. */
  38 +
  39 +//#define DEBUG_SIGNAL
  40 +
  41 +#define MAX_SIGQUEUE_SIZE 1024
  42 +
  43 +struct sigqueue {
  44 + struct sigqueue *next;
  45 + siginfo_t info;
  46 +};
28 47  
29 48 struct emulated_sigaction {
30 49 struct target_sigaction sa;
31   - int nb_pending;
32   - struct target_siginfo info;
  50 + int pending; /* true if signal is pending */
  51 + struct sigqueue *first;
  52 + struct sigqueue info; /* in order to always have memory for the
  53 + first signal, we put it here */
33 54 };
34 55  
35   -struct emulated_sigaction sigact_table[NSIG];
36   -int signal_pending;
  56 +static struct emulated_sigaction sigact_table[TARGET_NSIG];
  57 +static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
  58 +static struct sigqueue *first_free; /* first free siginfo queue entry */
  59 +static int signal_pending; /* non zero if a signal may be pending */
37 60  
  61 +static void host_signal_handler(int host_signum, siginfo_t *info,
  62 + void *puc);
  63 +
  64 +/* XXX: do it properly */
38 65 static inline int host_to_target_signal(int sig)
39 66 {
40 67 return sig;
... ... @@ -45,6 +72,51 @@ static inline int target_to_host_signal(int sig)
45 72 return sig;
46 73 }
47 74  
  75 +void host_to_target_sigset(target_sigset_t *d, sigset_t *s)
  76 +{
  77 + int i;
  78 + for(i = 0;i < TARGET_NSIG_WORDS; i++) {
  79 + d->sig[i] = tswapl(((unsigned long *)s)[i]);
  80 + }
  81 +}
  82 +
  83 +void target_to_host_sigset(sigset_t *d, target_sigset_t *s)
  84 +{
  85 + int i;
  86 + for(i = 0;i < TARGET_NSIG_WORDS; i++) {
  87 + ((unsigned long *)d)[i] = tswapl(s->sig[i]);
  88 + }
  89 +}
  90 +
  91 +void host_to_target_old_sigset(target_ulong *old_sigset,
  92 + const sigset_t *sigset)
  93 +{
  94 + *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
  95 +}
  96 +
  97 +void target_to_host_old_sigset(sigset_t *sigset,
  98 + const target_ulong *old_sigset)
  99 +{
  100 + sigemptyset(sigset);
  101 + *(unsigned long *)sigset = tswapl(*old_sigset);
  102 +}
  103 +
  104 +/* XXX: finish it */
  105 +void host_to_target_siginfo(target_siginfo_t *tinfo, siginfo_t *info)
  106 +{
  107 + tinfo->si_signo = tswap32(info->si_signo);
  108 + tinfo->si_errno = tswap32(info->si_errno);
  109 + tinfo->si_code = tswap32(info->si_code);
  110 +}
  111 +
  112 +/* XXX: finish it */
  113 +void target_to_host_siginfo(siginfo_t *info, target_siginfo_t *tinfo)
  114 +{
  115 + info->si_signo = tswap32(tinfo->si_signo);
  116 + info->si_errno = tswap32(tinfo->si_errno);
  117 + info->si_code = tswap32(tinfo->si_code);
  118 +}
  119 +
48 120 void signal_init(void)
49 121 {
50 122 struct sigaction act;
... ... @@ -55,51 +127,664 @@ void signal_init(void)
55 127 act.sa_flags = SA_SIGINFO;
56 128 act.sa_sigaction = host_signal_handler;
57 129 for(i = 1; i < NSIG; i++) {
58   - sigaction(i, &sa, NULL);
  130 + sigaction(i, &act, NULL);
59 131 }
60 132  
61 133 memset(sigact_table, 0, sizeof(sigact_table));
  134 +
  135 + first_free = &sigqueue_table[0];
  136 + for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
  137 + sigqueue_table[i].next = &sigqueue_table[i + 1];
  138 + sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
  139 +}
  140 +
  141 +/* signal queue handling */
  142 +
  143 +static inline struct sigqueue *alloc_sigqueue(void)
  144 +{
  145 + struct sigqueue *q = first_free;
  146 + if (!q)
  147 + return NULL;
  148 + first_free = q->next;
  149 + return q;
62 150 }
63 151  
  152 +static inline void free_sigqueue(struct sigqueue *q)
  153 +{
  154 + q->next = first_free;
  155 + first_free = q;
  156 +}
  157 +
  158 +static int queue_signal(struct emulated_sigaction *k, int sig, siginfo_t *info)
  159 +{
  160 + struct sigqueue *q, **pq;
  161 +
  162 + pq = &k->first;
  163 + if (!k->pending || sig < TARGET_SIGRTMIN) {
  164 + /* first signal or non real time signal */
  165 + q = &k->info;
  166 + } else {
  167 + q = alloc_sigqueue();
  168 + if (!q)
  169 + return -EAGAIN;
  170 + while (*pq != NULL)
  171 + pq = &(*pq)->next;
  172 + }
  173 + *pq = q;
  174 + q->info = *info;
  175 + q->next = NULL;
  176 + k->pending = 1;
  177 + /* signal that a new signal is pending */
  178 + signal_pending = 1;
  179 + return 0;
  180 +}
  181 +
  182 +void force_sig(int sig)
  183 +{
  184 + int host_sig;
  185 + /* abort execution with signal */
  186 + host_sig = target_to_host_signal(sig);
  187 + fprintf(stderr, "gemu: uncaught target signal %d (%s) - exiting\n",
  188 + sig, strsignal(host_sig));
  189 + _exit(-host_sig);
  190 +}
  191 +
  192 +
64 193 static void host_signal_handler(int host_signum, siginfo_t *info,
65 194 void *puc)
66 195 {
67   - struct ucontext *uc = puc;
68   - int signum;
  196 + struct emulated_sigaction *k;
  197 + int sig;
  198 + target_ulong handler;
  199 +
69 200 /* get target signal number */
70   - signum = host_to_target(host_signum);
71   - if (signum >= TARGET_NSIG)
  201 + sig = host_to_target_signal(host_signum);
  202 + if (sig < 1 || sig > TARGET_NSIG)
72 203 return;
73   - /* we save the old mask */
74   -
75   -
  204 + k = &sigact_table[sig - 1];
  205 +#ifdef DEBUG_SIGNAL
  206 + fprintf(stderr, "gemu: got signal %d\n", sig);
  207 +#endif
  208 + handler = k->sa._sa_handler;
  209 + if (handler == TARGET_SIG_DFL) {
  210 + /* default handler : ignore some signal. The other are fatal */
  211 + if (sig != TARGET_SIGCHLD &&
  212 + sig != TARGET_SIGURG &&
  213 + sig != TARGET_SIGWINCH) {
  214 + force_sig(sig);
  215 + }
  216 + } else if (handler == TARGET_SIG_IGN) {
  217 + /* ignore signal */
  218 + } else if (handler == TARGET_SIG_ERR) {
  219 + force_sig(sig);
  220 + } else {
  221 + queue_signal(k, sig, info);
  222 + }
  223 +}
  224 +
  225 +int do_sigaction(int sig, const struct target_sigaction *act,
  226 + struct target_sigaction *oact)
  227 +{
  228 + struct emulated_sigaction *k;
  229 +
  230 + if (sig < 1 || sig > TARGET_NSIG)
  231 + return -EINVAL;
  232 + k = &sigact_table[sig - 1];
  233 +#if defined(DEBUG_SIGNAL) && 0
  234 + fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
  235 + sig, (int)act, (int)oact);
  236 +#endif
  237 + if (oact) {
  238 + oact->_sa_handler = tswapl(k->sa._sa_handler);
  239 + oact->sa_flags = tswapl(k->sa.sa_flags);
  240 + oact->sa_restorer = tswapl(k->sa.sa_restorer);
  241 + oact->sa_mask = k->sa.sa_mask;
  242 + }
  243 + if (act) {
  244 + k->sa._sa_handler = tswapl(act->_sa_handler);
  245 + k->sa.sa_flags = tswapl(act->sa_flags);
  246 + k->sa.sa_restorer = tswapl(act->sa_restorer);
  247 + k->sa.sa_mask = act->sa_mask;
  248 + }
  249 + return 0;
  250 +}
  251 +
  252 +#ifdef TARGET_I386
  253 +
  254 +/* from the Linux kernel */
  255 +
  256 +struct target_fpreg {
  257 + uint16_t significand[4];
  258 + uint16_t exponent;
  259 +};
  260 +
  261 +struct target_fpxreg {
  262 + uint16_t significand[4];
  263 + uint16_t exponent;
  264 + uint16_t padding[3];
  265 +};
  266 +
  267 +struct target_xmmreg {
  268 + target_ulong element[4];
  269 +};
  270 +
  271 +struct target_fpstate {
  272 + /* Regular FPU environment */
  273 + target_ulong cw;
  274 + target_ulong sw;
  275 + target_ulong tag;
  276 + target_ulong ipoff;
  277 + target_ulong cssel;
  278 + target_ulong dataoff;
  279 + target_ulong datasel;
  280 + struct target_fpreg _st[8];
  281 + uint16_t status;
  282 + uint16_t magic; /* 0xffff = regular FPU data only */
  283 +
  284 + /* FXSR FPU environment */
  285 + target_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
  286 + target_ulong mxcsr;
  287 + target_ulong reserved;
  288 + struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
  289 + struct target_xmmreg _xmm[8];
  290 + target_ulong padding[56];
  291 +};
  292 +
  293 +#define X86_FXSR_MAGIC 0x0000
  294 +
  295 +struct target_sigcontext {
  296 + uint16_t gs, __gsh;
  297 + uint16_t fs, __fsh;
  298 + uint16_t es, __esh;
  299 + uint16_t ds, __dsh;
  300 + target_ulong edi;
  301 + target_ulong esi;
  302 + target_ulong ebp;
  303 + target_ulong esp;
  304 + target_ulong ebx;
  305 + target_ulong edx;
  306 + target_ulong ecx;
  307 + target_ulong eax;
  308 + target_ulong trapno;
  309 + target_ulong err;
  310 + target_ulong eip;
  311 + uint16_t cs, __csh;
  312 + target_ulong eflags;
  313 + target_ulong esp_at_signal;
  314 + uint16_t ss, __ssh;
  315 + target_ulong fpstate; /* pointer */
  316 + target_ulong oldmask;
  317 + target_ulong cr2;
  318 +};
  319 +
  320 +typedef struct target_sigaltstack {
  321 + target_ulong ss_sp;
  322 + int ss_flags;
  323 + target_ulong ss_size;
  324 +} target_stack_t;
  325 +
  326 +struct target_ucontext {
  327 + target_ulong uc_flags;
  328 + target_ulong uc_link;
  329 + target_stack_t uc_stack;
  330 + struct target_sigcontext uc_mcontext;
  331 + target_sigset_t uc_sigmask; /* mask last for extensibility */
  332 +};
  333 +
  334 +struct sigframe
  335 +{
  336 + target_ulong pretcode;
  337 + int sig;
  338 + struct target_sigcontext sc;
  339 + struct target_fpstate fpstate;
  340 + target_ulong extramask[TARGET_NSIG_WORDS-1];
  341 + char retcode[8];
  342 +};
  343 +
  344 +struct rt_sigframe
  345 +{
  346 + target_ulong pretcode;
  347 + int sig;
  348 + target_ulong pinfo;
  349 + target_ulong puc;
  350 + struct target_siginfo info;
  351 + struct target_ucontext uc;
  352 + struct target_fpstate fpstate;
  353 + char retcode[8];
  354 +};
  355 +
  356 +/*
  357 + * Set up a signal frame.
  358 + */
  359 +
  360 +#define __put_user(x,ptr)\
  361 +({\
  362 + int size = sizeof(*ptr);\
  363 + switch(size) {\
  364 + case 1:\
  365 + stb(ptr, (typeof(*ptr))(x));\
  366 + break;\
  367 + case 2:\
  368 + stw(ptr, (typeof(*ptr))(x));\
  369 + break;\
  370 + case 4:\
  371 + stl(ptr, (typeof(*ptr))(x));\
  372 + break;\
  373 + case 8:\
  374 + stq(ptr, (typeof(*ptr))(x));\
  375 + break;\
  376 + default:\
  377 + abort();\
  378 + }\
  379 + 0;\
  380 +})
  381 +
  382 +#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
  383 +
  384 +
  385 +#define __copy_to_user(dst, src, size)\
  386 +({\
  387 + memcpy(dst, src, size);\
  388 + 0;\
  389 +})
  390 +
  391 +static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, siginfo_t *info)
  392 +{
  393 + host_to_target_siginfo(tinfo, info);
  394 + return 0;
  395 +}
  396 +
  397 +/* XXX: save x87 state */
  398 +static int
  399 +setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
  400 + CPUX86State *env, unsigned long mask)
  401 +{
  402 + int err = 0;
  403 +
  404 + err |= __put_user(env->segs[R_GS], (unsigned int *)&sc->gs);
  405 + err |= __put_user(env->segs[R_FS], (unsigned int *)&sc->fs);
  406 + err |= __put_user(env->segs[R_ES], (unsigned int *)&sc->es);
  407 + err |= __put_user(env->segs[R_DS], (unsigned int *)&sc->ds);
  408 + err |= __put_user(env->regs[R_EDI], &sc->edi);
  409 + err |= __put_user(env->regs[R_ESI], &sc->esi);
  410 + err |= __put_user(env->regs[R_EBP], &sc->ebp);
  411 + err |= __put_user(env->regs[R_ESP], &sc->esp);
  412 + err |= __put_user(env->regs[R_EBX], &sc->ebx);
  413 + err |= __put_user(env->regs[R_EDX], &sc->edx);
  414 + err |= __put_user(env->regs[R_ECX], &sc->ecx);
  415 + err |= __put_user(env->regs[R_EAX], &sc->eax);
  416 + err |= __put_user(/*current->thread.trap_no*/ 0, &sc->trapno);
  417 + err |= __put_user(/*current->thread.error_code*/ 0, &sc->err);
  418 + err |= __put_user(env->eip, &sc->eip);
  419 + err |= __put_user(env->segs[R_CS], (unsigned int *)&sc->cs);
  420 + err |= __put_user(env->eflags, &sc->eflags);
  421 + err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
  422 + err |= __put_user(env->segs[R_SS], (unsigned int *)&sc->ss);
  423 +#if 0
  424 + tmp = save_i387(fpstate);
  425 + if (tmp < 0)
  426 + err = 1;
  427 + else
  428 + err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
  429 +#else
  430 + err |= __put_user(0, &sc->fpstate);
  431 +#endif
  432 + /* non-iBCS2 extensions.. */
  433 + err |= __put_user(mask, &sc->oldmask);
  434 + err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
  435 +
  436 + return err;
76 437 }
77 438  
  439 +/*
  440 + * Determine which stack to use..
  441 + */
78 442  
79   -void process_pending_signals(void)
  443 +static inline void *
  444 +get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
80 445 {
81   - int signum;
82   - target_ulong _sa_handler;
  446 + unsigned long esp;
  447 +
  448 + /* Default to using normal stack */
  449 + esp = env->regs[R_ESP];
  450 +#if 0
  451 + /* This is the X/Open sanctioned signal stack switching. */
  452 + if (ka->sa.sa_flags & SA_ONSTACK) {
  453 + if (sas_ss_flags(esp) == 0)
  454 + esp = current->sas_ss_sp + current->sas_ss_size;
  455 + }
  456 +
  457 + /* This is the legacy signal stack switching. */
  458 + else if ((regs->xss & 0xffff) != __USER_DS &&
  459 + !(ka->sa.sa_flags & SA_RESTORER) &&
  460 + ka->sa.sa_restorer) {
  461 + esp = (unsigned long) ka->sa.sa_restorer;
  462 + }
  463 +#endif
  464 + return (void *)((esp - frame_size) & -8ul);
  465 +}
  466 +
  467 +#define TF_MASK TRAP_FLAG
  468 +
  469 +static void setup_frame(int sig, struct emulated_sigaction *ka,
  470 + target_sigset_t *set, CPUX86State *env)
  471 +{
  472 + struct sigframe *frame;
  473 + int err = 0;
  474 +
  475 + frame = get_sigframe(ka, env, sizeof(*frame));
  476 +
  477 +#if 0
  478 + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  479 + goto give_sigsegv;
  480 +#endif
  481 + err |= __put_user((/*current->exec_domain
  482 + && current->exec_domain->signal_invmap
  483 + && sig < 32
  484 + ? current->exec_domain->signal_invmap[sig]
  485 + : */ sig),
  486 + &frame->sig);
  487 + if (err)
  488 + goto give_sigsegv;
  489 +
  490 + setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
  491 + if (err)
  492 + goto give_sigsegv;
  493 +
  494 + if (TARGET_NSIG_WORDS > 1) {
  495 + err |= __copy_to_user(frame->extramask, &set->sig[1],
  496 + sizeof(frame->extramask));
  497 + }
  498 + if (err)
  499 + goto give_sigsegv;
  500 +
  501 + /* Set up to return from userspace. If provided, use a stub
  502 + already in userspace. */
  503 + if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
  504 + err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
  505 + } else {
  506 + err |= __put_user(frame->retcode, &frame->pretcode);
  507 + /* This is popl %eax ; movl $,%eax ; int $0x80 */
  508 + err |= __put_user(0xb858, (short *)(frame->retcode+0));
  509 + err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
  510 + err |= __put_user(0x80cd, (short *)(frame->retcode+6));
  511 + }
  512 +
  513 + if (err)
  514 + goto give_sigsegv;
  515 +
  516 + /* Set up registers for signal handler */
  517 + env->regs[R_ESP] = (unsigned long) frame;
  518 + env->eip = (unsigned long) ka->sa._sa_handler;
  519 +
  520 + cpu_x86_load_seg(env, R_DS, __USER_DS);
  521 + cpu_x86_load_seg(env, R_ES, __USER_DS);
  522 + cpu_x86_load_seg(env, R_SS, __USER_DS);
  523 + cpu_x86_load_seg(env, R_CS, __USER_CS);
  524 + env->eflags &= ~TF_MASK;
  525 +
  526 + return;
  527 +
  528 +give_sigsegv:
  529 + if (sig == TARGET_SIGSEGV)
  530 + ka->sa._sa_handler = TARGET_SIG_DFL;
  531 + force_sig(TARGET_SIGSEGV /* , current */);
  532 +}
  533 +
  534 +static void setup_rt_frame(int sig, struct emulated_sigaction *ka, siginfo_t *info,
  535 + target_sigset_t *set, CPUX86State *env)
  536 +{
  537 + struct rt_sigframe *frame;
  538 + int err = 0;
  539 +
  540 + frame = get_sigframe(ka, env, sizeof(*frame));
  541 +
  542 +#if 0
  543 + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  544 + goto give_sigsegv;
  545 +#endif
  546 +
  547 + err |= __put_user((/*current->exec_domain
  548 + && current->exec_domain->signal_invmap
  549 + && sig < 32
  550 + ? current->exec_domain->signal_invmap[sig]
  551 + : */sig),
  552 + &frame->sig);
  553 + err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
  554 + err |= __put_user((target_ulong)&frame->uc, &frame->puc);
  555 + err |= copy_siginfo_to_user(&frame->info, info);
  556 + if (err)
  557 + goto give_sigsegv;
83 558  
84   - struct emulated_sigaction *esig;
  559 + /* Create the ucontext. */
  560 + err |= __put_user(0, &frame->uc.uc_flags);
  561 + err |= __put_user(0, &frame->uc.uc_link);
  562 + err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
  563 + err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
  564 + &frame->uc.uc_stack.ss_flags);
  565 + err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
  566 + err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
  567 + env, set->sig[0]);
  568 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  569 + if (err)
  570 + goto give_sigsegv;
85 571  
  572 + /* Set up to return from userspace. If provided, use a stub
  573 + already in userspace. */
  574 + if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
  575 + err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
  576 + } else {
  577 + err |= __put_user(frame->retcode, &frame->pretcode);
  578 + /* This is movl $,%eax ; int $0x80 */
  579 + err |= __put_user(0xb8, (char *)(frame->retcode+0));
  580 + err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
  581 + err |= __put_user(0x80cd, (short *)(frame->retcode+5));
  582 + }
  583 +
  584 + if (err)
  585 + goto give_sigsegv;
  586 +
  587 + /* Set up registers for signal handler */
  588 + env->regs[R_ESP] = (unsigned long) frame;
  589 + env->eip = (unsigned long) ka->sa._sa_handler;
  590 +
  591 + cpu_x86_load_seg(env, R_DS, __USER_DS);
  592 + cpu_x86_load_seg(env, R_ES, __USER_DS);
  593 + cpu_x86_load_seg(env, R_SS, __USER_DS);
  594 + cpu_x86_load_seg(env, R_CS, __USER_CS);
  595 + env->eflags &= ~TF_MASK;
  596 +
  597 + return;
  598 +
  599 +give_sigsegv:
  600 + if (sig == TARGET_SIGSEGV)
  601 + ka->sa._sa_handler = TARGET_SIG_DFL;
  602 + force_sig(TARGET_SIGSEGV /* , current */);
  603 +}
  604 +
  605 +static int
  606 +restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
  607 +{
  608 + unsigned int err = 0;
  609 +
  610 +
  611 +
  612 +#define COPY(x) err |= __get_user(regs->x, &sc->x)
  613 +
  614 +#define COPY_SEG(seg) \
  615 + { unsigned short tmp; \
  616 + err |= __get_user(tmp, &sc->seg); \
  617 + regs->x##seg = tmp; }
  618 +
  619 +#define COPY_SEG_STRICT(seg) \
  620 + { unsigned short tmp; \
  621 + err |= __get_user(tmp, &sc->seg); \
  622 + regs->x##seg = tmp|3; }
  623 +
  624 +#define GET_SEG(seg) \
  625 + { unsigned short tmp; \
  626 + err |= __get_user(tmp, &sc->seg); \
  627 + loadsegment(seg,tmp); }
  628 +
  629 + cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
  630 + cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
  631 + cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
  632 + cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
  633 +
  634 + env->regs[R_EDI] = ldl(&sc->edi);
  635 + env->regs[R_ESI] = ldl(&sc->esi);
  636 + env->regs[R_EBP] = ldl(&sc->ebp);
  637 + env->regs[R_ESP] = ldl(&sc->esp);
  638 + env->regs[R_EBX] = ldl(&sc->ebx);
  639 + env->regs[R_EDX] = ldl(&sc->edx);
  640 + env->regs[R_ECX] = ldl(&sc->ecx);
  641 + env->eip = ldl(&sc->eip);
  642 +
  643 + cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
  644 + cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
  645 +
  646 + {
  647 + unsigned int tmpflags;
  648 + tmpflags = ldl(&sc->eflags);
  649 + env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
  650 + // regs->orig_eax = -1; /* disable syscall checks */
  651 + }
  652 +
  653 +#if 0
  654 + {
  655 + struct _fpstate * buf;
  656 + err |= __get_user(buf, &sc->fpstate);
  657 + if (buf) {
  658 + if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
  659 + goto badframe;
  660 + err |= restore_i387(buf);
  661 + }
  662 + }
  663 +#endif
  664 + *peax = ldl(&sc->eax);
  665 + return err;
  666 +#if 0
  667 +badframe:
  668 + return 1;
  669 +#endif
  670 +}
  671 +
  672 +long do_sigreturn(CPUX86State *env)
  673 +{
  674 + struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
  675 + target_sigset_t target_set;
  676 + sigset_t set;
  677 + int eax, i;
  678 +
  679 + /* set blocked signals */
  680 + target_set.sig[0] = frame->sc.oldmask;
  681 + for(i = 1; i < TARGET_NSIG_WORDS; i++)
  682 + target_set.sig[i] = frame->extramask[i - 1];
  683 +
  684 + target_to_host_sigset(&set, &target_set);
  685 + sigprocmask(SIG_SETMASK, &set, NULL);
  686 +
  687 + /* restore registers */
  688 + if (restore_sigcontext(env, &frame->sc, &eax))
  689 + goto badframe;
  690 + return eax;
  691 +
  692 +badframe:
  693 + force_sig(TARGET_SIGSEGV);
  694 + return 0;
  695 +}
  696 +
  697 +long do_rt_sigreturn(CPUX86State *env)
  698 +{
  699 + struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
  700 + target_sigset_t target_set;
  701 + sigset_t set;
  702 + // stack_t st;
  703 + int eax;
  704 +
  705 +#if 0
  706 + if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
  707 + goto badframe;
  708 +#endif
  709 + memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
  710 +
  711 + target_to_host_sigset(&set, &target_set);
  712 + sigprocmask(SIG_SETMASK, &set, NULL);
  713 +
  714 + if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
  715 + goto badframe;
  716 +
  717 +#if 0
  718 + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
  719 + goto badframe;
  720 + /* It is more difficult to avoid calling this function than to
  721 + call it and ignore errors. */
  722 + do_sigaltstack(&st, NULL, regs->esp);
  723 +#endif
  724 + return eax;
  725 +
  726 +badframe:
  727 + force_sig(TARGET_SIGSEGV);
  728 + return 0;
  729 +}
  730 +
  731 +#endif
  732 +
  733 +void process_pending_signals(void *cpu_env)
  734 +{
  735 + int sig;
  736 + target_ulong handler;
  737 + target_sigset_t set;
  738 + struct emulated_sigaction *k;
  739 + struct sigqueue *q;
  740 +
86 741 if (!signal_pending)
87 742 return;
88 743  
89   - esig = sigact_table;
90   - for(signum = 1; signum < TARGET_NSIG; signum++) {
91   - if (esig->nb_pending != 0)
  744 + k = sigact_table;
  745 + for(sig = 1; sig <= TARGET_NSIG; sig++) {
  746 + if (k->pending)
92 747 goto handle_signal;
93   - esig++;
  748 + k++;
94 749 }
95 750 /* if no signal is pending, just return */
96 751 signal_pending = 0;
97 752 return;
  753 +
98 754 handle_signal:
99   - _sa_handler = esig->sa._sa_handler;
100   - if (_sa_handler == TARGET_SIG_DFL) {
101   - /* default handling
  755 +#ifdef DEBUG_SIGNAL
  756 + fprintf(stderr, "gemu: process signal %d\n", sig);
  757 +#endif
  758 + /* dequeue signal */
  759 + q = k->first;
  760 + k->first = q->next;
  761 + if (!k->first)
  762 + k->pending = 0;
  763 +
  764 + handler = k->sa._sa_handler;
  765 + if (handler == TARGET_SIG_DFL) {
  766 + /* default handler : ignore some signal. The other are fatal */
  767 + if (sig != TARGET_SIGCHLD &&
  768 + sig != TARGET_SIGURG &&
  769 + sig != TARGET_SIGWINCH) {
  770 + force_sig(sig);
  771 + }
  772 + } else if (handler == TARGET_SIG_IGN) {
  773 + /* ignore sig */
  774 + } else if (handler == TARGET_SIG_ERR) {
  775 + force_sig(sig);
  776 + } else {
  777 + set = k->sa.sa_mask;
  778 + /* send the signal to the CPU */
  779 + if (k->sa.sa_flags & TARGET_SA_SIGINFO)
  780 + setup_rt_frame(sig, k, &q->info, &set, cpu_env);
  781 + else
  782 + setup_frame(sig, k, &set, cpu_env);
  783 + if (k->sa.sa_flags & TARGET_SA_RESETHAND)
  784 + k->sa._sa_handler = TARGET_SIG_DFL;
102 785 }
  786 + if (q != &k->info)
  787 + free_sigqueue(q);
  788 +}
103 789  
104 790  
105   -}
... ...
linux-user/syscall.c
... ... @@ -75,12 +75,18 @@
75 75 #include "syscall-i386.h"
76 76 #endif
77 77  
  78 +void host_to_target_siginfo(target_siginfo_t *tinfo, siginfo_t *info);
  79 +void target_to_host_siginfo(siginfo_t *info, target_siginfo_t *tinfo);
  80 +long do_sigreturn(CPUX86State *env);
  81 +long do_rt_sigreturn(CPUX86State *env);
  82 +
78 83 #define __NR_sys_uname __NR_uname
79 84 #define __NR_sys_getcwd1 __NR_getcwd
80 85 #define __NR_sys_statfs __NR_statfs
81 86 #define __NR_sys_fstatfs __NR_fstatfs
82 87 #define __NR_sys_getdents __NR_getdents
83 88 #define __NR_sys_getdents64 __NR_getdents64
  89 +#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
84 90  
85 91 #ifdef __NR_gettid
86 92 _syscall0(int, gettid)
... ... @@ -97,6 +103,9 @@ _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
97 103 loff_t *, res, uint, wh);
98 104 _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
99 105 _syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf)
  106 +_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
  107 +
  108 +extern int personality(int);
100 109  
101 110 static inline long get_errno(long ret)
102 111 {
... ... @@ -199,18 +208,18 @@ static inline void host_to_target_fds(target_long *target_fds,
199 208 #endif
200 209 }
201 210  
202   -/* XXX: incorrect for some archs */
203   -static void host_to_target_old_sigset(target_ulong *old_sigset,
204   - const sigset_t *sigset)
  211 +static inline void target_to_host_timeval(struct timeval *tv,
  212 + struct target_timeval *target_tv)
205 213 {
206   - *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
  214 + tv->tv_sec = tswapl(target_tv->tv_sec);
  215 + tv->tv_usec = tswapl(target_tv->tv_usec);
207 216 }
208 217  
209   -static void target_to_host_old_sigset(sigset_t *sigset,
210   - const target_ulong *old_sigset)
  218 +static inline void host_to_target_timeval(struct target_timeval *target_tv,
  219 + struct timeval *tv)
211 220 {
212   - sigemptyset(sigset);
213   - *(unsigned long *)sigset = tswapl(*old_sigset);
  221 + target_tv->tv_sec = tswapl(tv->tv_sec);
  222 + target_tv->tv_usec = tswapl(tv->tv_usec);
214 223 }
215 224  
216 225  
... ... @@ -1042,28 +1051,195 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1042 1051 ret = get_errno(setsid());
1043 1052 break;
1044 1053 case TARGET_NR_sigaction:
1045   -#if 1
1046 1054 {
1047   - ret = 0;
  1055 + struct target_old_sigaction *old_act = (void *)arg2;
  1056 + struct target_old_sigaction *old_oact = (void *)arg3;
  1057 + struct target_sigaction act, oact, *pact;
  1058 + if (old_act) {
  1059 + act._sa_handler = old_act->_sa_handler;
  1060 + target_siginitset(&act.sa_mask, old_act->sa_mask);
  1061 + act.sa_flags = old_act->sa_flags;
  1062 + act.sa_restorer = old_act->sa_restorer;
  1063 + pact = &act;
  1064 + } else {
  1065 + pact = NULL;
  1066 + }
  1067 + ret = get_errno(do_sigaction(arg1, pact, &oact));
  1068 + if (!is_error(ret) && old_oact) {
  1069 + old_oact->_sa_handler = oact._sa_handler;
  1070 + old_oact->sa_mask = oact.sa_mask.sig[0];
  1071 + old_oact->sa_flags = oact.sa_flags;
  1072 + old_oact->sa_restorer = oact.sa_restorer;
  1073 + }
1048 1074 }
1049 1075 break;
1050   -#else
1051   - goto unimplemented;
1052   -#endif
  1076 + case TARGET_NR_rt_sigaction:
  1077 + ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3));
  1078 + break;
1053 1079 case TARGET_NR_sgetmask:
1054   - goto unimplemented;
  1080 + {
  1081 + sigset_t cur_set;
  1082 + target_ulong target_set;
  1083 + sigprocmask(0, NULL, &cur_set);
  1084 + host_to_target_old_sigset(&target_set, &cur_set);
  1085 + ret = target_set;
  1086 + }
  1087 + break;
1055 1088 case TARGET_NR_ssetmask:
1056   - goto unimplemented;
  1089 + {
  1090 + sigset_t set, oset, cur_set;
  1091 + target_ulong target_set = arg1;
  1092 + sigprocmask(0, NULL, &cur_set);
  1093 + target_to_host_old_sigset(&set, &target_set);
  1094 + sigorset(&set, &set, &cur_set);
  1095 + sigprocmask(SIG_SETMASK, &set, &oset);
  1096 + host_to_target_old_sigset(&target_set, &oset);
  1097 + ret = target_set;
  1098 + }
  1099 + break;
  1100 + case TARGET_NR_sigprocmask:
  1101 + {
  1102 + int how = arg1;
  1103 + sigset_t set, oldset, *set_ptr;
  1104 + target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
  1105 +
  1106 + if (pset) {
  1107 + switch(how) {
  1108 + case TARGET_SIG_BLOCK:
  1109 + how = SIG_BLOCK;
  1110 + break;
  1111 + case TARGET_SIG_UNBLOCK:
  1112 + how = SIG_UNBLOCK;
  1113 + break;
  1114 + case TARGET_SIG_SETMASK:
  1115 + how = SIG_SETMASK;
  1116 + break;
  1117 + default:
  1118 + ret = -EINVAL;
  1119 + goto fail;
  1120 + }
  1121 + target_to_host_old_sigset(&set, pset);
  1122 + set_ptr = &set;
  1123 + } else {
  1124 + how = 0;
  1125 + set_ptr = NULL;
  1126 + }
  1127 + ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
  1128 + if (!is_error(ret) && poldset) {
  1129 + host_to_target_old_sigset(poldset, &oldset);
  1130 + }
  1131 + }
  1132 + break;
  1133 + case TARGET_NR_rt_sigprocmask:
  1134 + {
  1135 + int how = arg1;
  1136 + sigset_t set, oldset, *set_ptr;
  1137 + target_sigset_t *pset = (void *)arg2;
  1138 + target_sigset_t *poldset = (void *)arg3;
  1139 +
  1140 + if (pset) {
  1141 + switch(how) {
  1142 + case TARGET_SIG_BLOCK:
  1143 + how = SIG_BLOCK;
  1144 + break;
  1145 + case TARGET_SIG_UNBLOCK:
  1146 + how = SIG_UNBLOCK;
  1147 + break;
  1148 + case TARGET_SIG_SETMASK:
  1149 + how = SIG_SETMASK;
  1150 + break;
  1151 + default:
  1152 + ret = -EINVAL;
  1153 + goto fail;
  1154 + }
  1155 + target_to_host_sigset(&set, pset);
  1156 + set_ptr = &set;
  1157 + } else {
  1158 + how = 0;
  1159 + set_ptr = NULL;
  1160 + }
  1161 + ret = get_errno(sigprocmask(how, set_ptr, &oldset));
  1162 + if (!is_error(ret) && poldset) {
  1163 + host_to_target_sigset(poldset, &oldset);
  1164 + }
  1165 + }
  1166 + break;
  1167 + case TARGET_NR_sigpending:
  1168 + {
  1169 + sigset_t set;
  1170 + ret = get_errno(sigpending(&set));
  1171 + if (!is_error(ret)) {
  1172 + host_to_target_old_sigset((target_ulong *)arg1, &set);
  1173 + }
  1174 + }
  1175 + break;
  1176 + case TARGET_NR_rt_sigpending:
  1177 + {
  1178 + sigset_t set;
  1179 + ret = get_errno(sigpending(&set));
  1180 + if (!is_error(ret)) {
  1181 + host_to_target_sigset((target_sigset_t *)arg1, &set);
  1182 + }
  1183 + }
  1184 + break;
  1185 + case TARGET_NR_sigsuspend:
  1186 + {
  1187 + sigset_t set;
  1188 + target_to_host_old_sigset(&set, (target_ulong *)arg1);
  1189 + ret = get_errno(sigsuspend(&set));
  1190 + }
  1191 + break;
  1192 + case TARGET_NR_rt_sigsuspend:
  1193 + {
  1194 + sigset_t set;
  1195 + target_to_host_sigset(&set, (target_sigset_t *)arg1);
  1196 + ret = get_errno(sigsuspend(&set));
  1197 + }
  1198 + break;
  1199 + case TARGET_NR_rt_sigtimedwait:
  1200 + {
  1201 + target_sigset_t *target_set = (void *)arg1;
  1202 + target_siginfo_t *target_uinfo = (void *)arg2;
  1203 + struct target_timespec *target_uts = (void *)arg3;
  1204 + sigset_t set;
  1205 + struct timespec uts, *puts;
  1206 + siginfo_t uinfo;
  1207 +
  1208 + target_to_host_sigset(&set, target_set);
  1209 + if (target_uts) {
  1210 + puts = &uts;
  1211 + puts->tv_sec = tswapl(target_uts->tv_sec);
  1212 + puts->tv_nsec = tswapl(target_uts->tv_nsec);
  1213 + } else {
  1214 + puts = NULL;
  1215 + }
  1216 + ret = get_errno(sigtimedwait(&set, &uinfo, puts));
  1217 + if (!is_error(ret) && target_uinfo) {
  1218 + host_to_target_siginfo(target_uinfo, &uinfo);
  1219 + }
  1220 + }
  1221 + break;
  1222 + case TARGET_NR_rt_sigqueueinfo:
  1223 + {
  1224 + siginfo_t uinfo;
  1225 + target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3);
  1226 + ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
  1227 + }
  1228 + break;
  1229 + case TARGET_NR_sigreturn:
  1230 + /* NOTE: ret is eax, so not transcoding must be done */
  1231 + ret = do_sigreturn(cpu_env);
  1232 + break;
  1233 + case TARGET_NR_rt_sigreturn:
  1234 + /* NOTE: ret is eax, so not transcoding must be done */
  1235 + ret = do_rt_sigreturn(cpu_env);
  1236 + break;
1057 1237 case TARGET_NR_setreuid:
1058 1238 ret = get_errno(setreuid(arg1, arg2));
1059 1239 break;
1060 1240 case TARGET_NR_setregid:
1061 1241 ret = get_errno(setregid(arg1, arg2));
1062 1242 break;
1063   - case TARGET_NR_sigsuspend:
1064   - goto unimplemented;
1065   - case TARGET_NR_sigpending:
1066   - goto unimplemented;
1067 1243 case TARGET_NR_sethostname:
1068 1244 ret = get_errno(sethostname((const char *)arg1, arg2));
1069 1245 break;
... ... @@ -1190,9 +1366,43 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1190 1366 case TARGET_NR_syslog:
1191 1367 goto unimplemented;
1192 1368 case TARGET_NR_setitimer:
1193   - goto unimplemented;
  1369 + {
  1370 + struct target_itimerval *target_value = (void *)arg2;
  1371 + struct target_itimerval *target_ovalue = (void *)arg3;
  1372 + struct itimerval value, ovalue, *pvalue;
  1373 +
  1374 + if (target_value) {
  1375 + pvalue = &value;
  1376 + target_to_host_timeval(&pvalue->it_interval,
  1377 + &target_value->it_interval);
  1378 + target_to_host_timeval(&pvalue->it_value,
  1379 + &target_value->it_value);
  1380 + } else {
  1381 + pvalue = NULL;
  1382 + }
  1383 + ret = get_errno(setitimer(arg1, pvalue, &ovalue));
  1384 + if (!is_error(ret) && target_ovalue) {
  1385 + host_to_target_timeval(&target_ovalue->it_interval,
  1386 + &ovalue.it_interval);
  1387 + host_to_target_timeval(&target_ovalue->it_value,
  1388 + &ovalue.it_value);
  1389 + }
  1390 + }
  1391 + break;
1194 1392 case TARGET_NR_getitimer:
1195   - goto unimplemented;
  1393 + {
  1394 + struct target_itimerval *target_value = (void *)arg2;
  1395 + struct itimerval value;
  1396 +
  1397 + ret = get_errno(getitimer(arg1, &value));
  1398 + if (!is_error(ret) && target_value) {
  1399 + host_to_target_timeval(&target_value->it_interval,
  1400 + &value.it_interval);
  1401 + host_to_target_timeval(&target_value->it_value,
  1402 + &value.it_value);
  1403 + }
  1404 + }
  1405 + break;
1196 1406 case TARGET_NR_stat:
1197 1407 ret = get_errno(stat((const char *)arg1, &st));
1198 1408 goto do_stat;
... ... @@ -1279,8 +1489,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1279 1489 case TARGET_NR_fsync:
1280 1490 ret = get_errno(fsync(arg1));
1281 1491 break;
1282   - case TARGET_NR_sigreturn:
1283   - goto unimplemented;
1284 1492 case TARGET_NR_clone:
1285 1493 ret = get_errno(do_fork(cpu_env, arg1, arg2));
1286 1494 break;
... ... @@ -1301,39 +1509,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1301 1509 case TARGET_NR_mprotect:
1302 1510 ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1303 1511 break;
1304   - case TARGET_NR_sigprocmask:
1305   - {
1306   - int how = arg1;
1307   - sigset_t set, oldset, *set_ptr;
1308   - target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1309   -
1310   - switch(how) {
1311   - case TARGET_SIG_BLOCK:
1312   - how = SIG_BLOCK;
1313   - break;
1314   - case TARGET_SIG_UNBLOCK:
1315   - how = SIG_UNBLOCK;
1316   - break;
1317   - case TARGET_SIG_SETMASK:
1318   - how = SIG_SETMASK;
1319   - break;
1320   - default:
1321   - ret = -EINVAL;
1322   - goto fail;
1323   - }
1324   -
1325   - if (pset) {
1326   - target_to_host_old_sigset(&set, pset);
1327   - set_ptr = &set;
1328   - } else {
1329   - set_ptr = NULL;
1330   - }
1331   - ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1332   - if (!is_error(ret) && poldset) {
1333   - host_to_target_old_sigset(poldset, &oldset);
1334   - }
1335   - }
1336   - break;
1337 1512 case TARGET_NR_create_module:
1338 1513 case TARGET_NR_init_module:
1339 1514 case TARGET_NR_delete_module:
... ... @@ -1516,13 +1691,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1516 1691 case TARGET_NR_setresgid:
1517 1692 case TARGET_NR_getresgid:
1518 1693 case TARGET_NR_prctl:
1519   - case TARGET_NR_rt_sigreturn:
1520   - case TARGET_NR_rt_sigaction:
1521   - case TARGET_NR_rt_sigprocmask:
1522   - case TARGET_NR_rt_sigpending:
1523   - case TARGET_NR_rt_sigtimedwait:
1524   - case TARGET_NR_rt_sigqueueinfo:
1525   - case TARGET_NR_rt_sigsuspend:
1526 1694 case TARGET_NR_pread:
1527 1695 case TARGET_NR_pwrite:
1528 1696 goto unimplemented;
... ...
linux-user/syscall_defs.h
... ... @@ -29,6 +29,11 @@ struct target_timespec {
29 29 target_long tv_nsec;
30 30 };
31 31  
  32 +struct target_itimerval {
  33 + struct target_timeval it_interval;
  34 + struct target_timeval it_value;
  35 +};
  36 +
32 37 struct target_iovec {
33 38 target_long iov_base; /* Starting address */
34 39 target_long iov_len; /* Number of bytes */
... ... @@ -113,6 +118,38 @@ typedef struct {
113 118 target_ulong sig[TARGET_NSIG_WORDS];
114 119 } target_sigset_t;
115 120  
  121 +#ifdef BSWAP_NEEDED
  122 +static inline void tswap_sigset(target_sigset_t *d, const target_sigset_t *s)
  123 +{
  124 + int i;
  125 + for(i = 0;i < TARGET_NSIG_WORDS; i++)
  126 + d->sig[i] = tswapl(s->sig[i]);
  127 +}
  128 +#else
  129 +static inline void tswap_sigset(target_sigset_t *d, const target_sigset_t *s)
  130 +{
  131 + *d = *s;
  132 +}
  133 +#endif
  134 +
  135 +static inline void target_siginitset(target_sigset_t *d, target_ulong set)
  136 +{
  137 + int i;
  138 + d->sig[0] = set;
  139 + for(i = 1;i < TARGET_NSIG_WORDS; i++)
  140 + d->sig[i] = 0;
  141 +}
  142 +
  143 +void host_to_target_sigset(target_sigset_t *d, sigset_t *s);
  144 +void target_to_host_sigset(sigset_t *d, target_sigset_t *s);
  145 +void host_to_target_old_sigset(target_ulong *old_sigset,
  146 + const sigset_t *sigset);
  147 +void target_to_host_old_sigset(sigset_t *sigset,
  148 + const target_ulong *old_sigset);
  149 +struct target_sigaction;
  150 +int do_sigaction(int sig, const struct target_sigaction *act,
  151 + struct target_sigaction *oact);
  152 +
116 153 /* Networking ioctls */
117 154 #define TARGET_SIOCADDRT 0x890B /* add routing table entry */
118 155 #define TARGET_SIOCDELRT 0x890C /* delete routing table entry */
... ...
ops_template.h
  1 +/*
  2 + * i386 micro operations (included several times to generate
  3 + * different operand sizes)
  4 + *
  5 + * Copyright (c) 2003 Fabrice Bellard
  6 + *
  7 + * This program is free software; you can redistribute it and/or modify
  8 + * it under the terms of the GNU General Public License as published by
  9 + * the Free Software Foundation; either version 2 of the License, or
  10 + * (at your option) any later version.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 + */
1 21  
2 22 #define DATA_BITS (1 << (3 + SHIFT))
3 23 #define SHIFT_MASK (DATA_BITS - 1)
... ...
syscall-i386.h
... ... @@ -302,20 +302,59 @@ struct target_stat64 {
302 302 unsigned long long st_ino;
303 303 };
304 304  
305   -typedef unsigned long old_sigset_t; /* at least 32 bits */
  305 +#define TARGET_SA_NOCLDSTOP 0x00000001
  306 +#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
  307 +#define TARGET_SA_SIGINFO 0x00000004
  308 +#define TARGET_SA_ONSTACK 0x08000000
  309 +#define TARGET_SA_RESTART 0x10000000
  310 +#define TARGET_SA_NODEFER 0x40000000
  311 +#define TARGET_SA_RESETHAND 0x80000000
  312 +#define TARGET_SA_RESTORER 0x04000000
  313 +
  314 +#define TARGET_SIGHUP 1
  315 +#define TARGET_SIGINT 2
  316 +#define TARGET_SIGQUIT 3
  317 +#define TARGET_SIGILL 4
  318 +#define TARGET_SIGTRAP 5
  319 +#define TARGET_SIGABRT 6
  320 +#define TARGET_SIGIOT 6
  321 +#define TARGET_SIGBUS 7
  322 +#define TARGET_SIGFPE 8
  323 +#define TARGET_SIGKILL 9
  324 +#define TARGET_SIGUSR1 10
  325 +#define TARGET_SIGSEGV 11
  326 +#define TARGET_SIGUSR2 12
  327 +#define TARGET_SIGPIPE 13
  328 +#define TARGET_SIGALRM 14
  329 +#define TARGET_SIGTERM 15
  330 +#define TARGET_SIGSTKFLT 16
  331 +#define TARGET_SIGCHLD 17
  332 +#define TARGET_SIGCONT 18
  333 +#define TARGET_SIGSTOP 19
  334 +#define TARGET_SIGTSTP 20
  335 +#define TARGET_SIGTTIN 21
  336 +#define TARGET_SIGTTOU 22
  337 +#define TARGET_SIGURG 23
  338 +#define TARGET_SIGXCPU 24
  339 +#define TARGET_SIGXFSZ 25
  340 +#define TARGET_SIGVTALRM 26
  341 +#define TARGET_SIGPROF 27
  342 +#define TARGET_SIGWINCH 28
  343 +#define TARGET_SIGIO 29
  344 +#define TARGET_SIGRTMIN 32
306 345  
307 346 struct target_old_sigaction {
308 347 target_ulong _sa_handler;
309 348 target_ulong sa_mask;
310 349 target_ulong sa_flags;
311   - void (*sa_restorer)(void);
  350 + target_ulong sa_restorer;
312 351 };
313 352  
314 353 struct target_sigaction {
315 354 target_ulong _sa_handler;
316   - target_sigset_t sa_mask;
317 355 target_ulong sa_flags;
318 356 target_ulong sa_restorer;
  357 + target_sigset_t sa_mask;
319 358 };
320 359  
321 360 typedef union target_sigval {
... ...