1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <stdlib.h>
21: #include <stdio.h>
22: #include <string.h>
23: #include <stdarg.h>
24: #include <unistd.h>
25: #include <signal.h>
26: #include <errno.h>
27: #include <sys/ucontext.h>
28:
29: #include "qemu.h"
30: #include "target_signal.h"
31:
32:
33:
34: #define MAX_SIGQUEUE_SIZE 1024
35:
36: struct sigqueue {
37: struct sigqueue *next;
38: target_siginfo_t info;
39: };
40:
41: struct emulated_sigaction {
42: struct target_sigaction sa;
43: int pending;
44: struct sigqueue *first;
45: struct sigqueue info;
46:
47: };
48:
49: struct target_sigaltstack target_sigaltstack_used = {
50: .ss_sp = 0,
51: .ss_size = 0,
52: .ss_flags = TARGET_SS_DISABLE,
53: };
54:
55: static struct emulated_sigaction sigact_table[TARGET_NSIG];
56: static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE];
57: static struct sigqueue *first_free;
58: static int signal_pending;
59:
60: static void host_signal_handler(int host_signum, siginfo_t *info,
61: void *puc);
62:
63: static uint8_t host_to_target_signal_table[65] = {
64: [SIGHUP] = TARGET_SIGHUP,
65: [SIGINT] = TARGET_SIGINT,
66: [SIGQUIT] = TARGET_SIGQUIT,
67: [SIGILL] = TARGET_SIGILL,
68: [SIGTRAP] = TARGET_SIGTRAP,
69: [SIGABRT] = TARGET_SIGABRT,
70:
71: [SIGBUS] = TARGET_SIGBUS,
72: [SIGFPE] = TARGET_SIGFPE,
73: [SIGKILL] = TARGET_SIGKILL,
74: [SIGUSR1] = TARGET_SIGUSR1,
75: [SIGSEGV] = TARGET_SIGSEGV,
76: [SIGUSR2] = TARGET_SIGUSR2,
77: [SIGPIPE] = TARGET_SIGPIPE,
78: [SIGALRM] = TARGET_SIGALRM,
79: [SIGTERM] = TARGET_SIGTERM,
80: #ifdef SIGSTKFLT
81: [SIGSTKFLT] = TARGET_SIGSTKFLT,
82: #endif
83: [SIGCHLD] = TARGET_SIGCHLD,
84: [SIGCONT] = TARGET_SIGCONT,
85: [SIGSTOP] = TARGET_SIGSTOP,
86: [SIGTSTP] = TARGET_SIGTSTP,
87: [SIGTTIN] = TARGET_SIGTTIN,
88: [SIGTTOU] = TARGET_SIGTTOU,
89: [SIGURG] = TARGET_SIGURG,
90: [SIGXCPU] = TARGET_SIGXCPU,
91: [SIGXFSZ] = TARGET_SIGXFSZ,
92: [SIGVTALRM] = TARGET_SIGVTALRM,
93: [SIGPROF] = TARGET_SIGPROF,
94: [SIGWINCH] = TARGET_SIGWINCH,
95: [SIGIO] = TARGET_SIGIO,
96: [SIGPWR] = TARGET_SIGPWR,
97: [SIGSYS] = TARGET_SIGSYS,
98:
99: };
100: static uint8_t target_to_host_signal_table[65];
101:
102: static inline int on_sig_stack(unsigned long sp)
103: {
104: return (sp - target_sigaltstack_used.ss_sp
105: < target_sigaltstack_used.ss_size);
106: }
107:
108: static inline int sas_ss_flags(unsigned long sp)
109: {
110: return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
111: : on_sig_stack(sp) ? SS_ONSTACK : 0);
112: }
113:
114: static inline int host_to_target_signal(int sig)
115: {
116: return host_to_target_signal_table[sig];
117: }
118:
119: static inline int target_to_host_signal(int sig)
120: {
121: return target_to_host_signal_table[sig];
122: }
123:
124: static void host_to_target_sigset_internal(target_sigset_t *d,
125: const sigset_t *s)
126: {
127: int i;
128: unsigned long sigmask;
129: uint32_t target_sigmask;
130:
131: sigmask = ((unsigned long *)s)[0];
132: target_sigmask = 0;
133: for(i = 0; i < 32; i++) {
134: if (sigmask & (1 << i))
135: target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
136: }
137: #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 32
138: d->sig[0] = target_sigmask;
139: for(i = 1;i < TARGET_NSIG_WORDS; i++) {
140: d->sig[i] = ((unsigned long *)s)[i];
141: }
142: #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
143: d->sig[0] = target_sigmask;
144: d->sig[1] = sigmask >> 32;
145: #else
146:
147: #endif
148: }
149:
150: void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
151: {
152: target_sigset_t d1;
153: int i;
154:
155: host_to_target_sigset_internal(&d1, s);
156: for(i = 0;i < TARGET_NSIG_WORDS; i++)
157: d->sig[i] = tswapl(d1.sig[i]);
158: }
159:
160: void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
161: {
162: int i;
163: unsigned long sigmask;
164: abi_ulong target_sigmask;
165:
166: target_sigmask = s->sig[0];
167: sigmask = 0;
168: for(i = 0; i < 32; i++) {
169: if (target_sigmask & (1 << i))
170: sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
171: }
172: #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 32
173: ((unsigned long *)d)[0] = sigmask;
174: for(i = 1;i < TARGET_NSIG_WORDS; i++) {
175: ((unsigned long *)d)[i] = s->sig[i];
176: }
177: #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
178: ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
179: #else
180:
181: #endif
182: }
183:
184: void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
185: {
186: target_sigset_t s1;
187: int i;
188:
189: for(i = 0;i < TARGET_NSIG_WORDS; i++)
190: s1.sig[i] = tswapl(s->sig[i]);
191: target_to_host_sigset_internal(d, &s1);
192: }
193:
194: void host_to_target_old_sigset(abi_ulong *old_sigset,
195: const sigset_t *sigset)
196: {
197: target_sigset_t d;
198: host_to_target_sigset(&d, sigset);
199: *old_sigset = d.sig[0];
200: }
201:
202: void target_to_host_old_sigset(sigset_t *sigset,
203: const abi_ulong *old_sigset)
204: {
205: target_sigset_t d;
206: int i;
207:
208: d.sig[0] = *old_sigset;
209: for(i = 1;i < TARGET_NSIG_WORDS; i++)
210: d.sig[i] = 0;
211: target_to_host_sigset(sigset, &d);
212: }
213:
214:
215:
216: static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
217: const siginfo_t *info)
218: {
219: int sig;
220: sig = host_to_target_signal(info->si_signo);
221: tinfo->si_signo = sig;
222: tinfo->si_errno = 0;
223: tinfo->si_code = 0;
224: if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
225: sig == SIGBUS || sig == SIGTRAP) {
226:
227:
228: tinfo->_sifields._sigfault._addr = 0;
229: } else if (sig == SIGIO) {
230: tinfo->_sifields._sigpoll._fd = info->si_fd;
231: } else if (sig >= TARGET_SIGRTMIN) {
232: tinfo->_sifields._rt._pid = info->si_pid;
233: tinfo->_sifields._rt._uid = info->si_uid;
234:
235: tinfo->_sifields._rt._sigval.sival_ptr =
236: (abi_ulong)(unsigned long)info->si_value.sival_ptr;
237: }
238: }
239:
240: static void tswap_siginfo(target_siginfo_t *tinfo,
241: const target_siginfo_t *info)
242: {
243: int sig;
244: sig = info->si_signo;
245: tinfo->si_signo = tswap32(sig);
246: tinfo->si_errno = tswap32(info->si_errno);
247: tinfo->si_code = tswap32(info->si_code);
248: if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
249: sig == SIGBUS || sig == SIGTRAP) {
250: tinfo->_sifields._sigfault._addr =
251: tswapl(info->_sifields._sigfault._addr);
252: } else if (sig == SIGIO) {
253: tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
254: } else if (sig >= TARGET_SIGRTMIN) {
255: tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
256: tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
257: tinfo->_sifields._rt._sigval.sival_ptr =
258: tswapl(info->_sifields._rt._sigval.sival_ptr);
259: }
260: }
261:
262:
263: void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
264: {
265: host_to_target_siginfo_noswap(tinfo, info);
266: tswap_siginfo(tinfo, tinfo);
267: }
268:
269:
270:
271: void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
272: {
273: info->si_signo = tswap32(tinfo->si_signo);
274: info->si_errno = tswap32(tinfo->si_errno);
275: info->si_code = tswap32(tinfo->si_code);
276: info->si_pid = tswap32(tinfo->_sifields._rt._pid);
277: info->si_uid = tswap32(tinfo->_sifields._rt._uid);
278: info->si_value.sival_ptr =
279: (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
280: }
281:
282: void signal_init(void)
283: {
284: struct sigaction act;
285: int i, j;
286:
287:
288: for(i = 1; i <= 64; i++) {
289: if (host_to_target_signal_table[i] == 0)
290: host_to_target_signal_table[i] = i;
291: }
292: for(i = 1; i <= 64; i++) {
293: j = host_to_target_signal_table[i];
294: target_to_host_signal_table[j] = i;
295: }
296:
297:
298:
299: sigfillset(&act.sa_mask);
300: act.sa_flags = SA_SIGINFO;
301: act.sa_sigaction = host_signal_handler;
302: for(i = 1; i < NSIG; i++) {
303: sigaction(i, &act, NULL);
304: }
305:
306: memset(sigact_table, 0, sizeof(sigact_table));
307:
308: first_free = &sigqueue_table[0];
309: for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
310: sigqueue_table[i].next = &sigqueue_table[i + 1];
311: sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
312: }
313:
314:
315:
316: static inline struct sigqueue *alloc_sigqueue(void)
317: {
318: struct sigqueue *q = first_free;
319: if (!q)
320: return NULL;
321: first_free = q->next;
322: return q;
323: }
324:
325: static inline void free_sigqueue(struct sigqueue *q)
326: {
327: q->next = first_free;
328: first_free = q;
329: }
330:
331:
332: void __attribute((noreturn)) force_sig(int sig)
333: {
334: int host_sig;
335: host_sig = target_to_host_signal(sig);
336: fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
337: sig, strsignal(host_sig));
338: #if 1
339: _exit(-host_sig);
340: #else
341: {
342: struct sigaction act;
343: sigemptyset(&act.sa_mask);
344: act.sa_flags = SA_SIGINFO;
345: act.sa_sigaction = SIG_DFL;
346: sigaction(SIGABRT, &act, NULL);
347: abort();
348: }
349: #endif
350: }
351:
352:
353:
354: int queue_signal(int sig, target_siginfo_t *info)
355: {
356: struct emulated_sigaction *k;
357: struct sigqueue *q, **pq;
358: abi_ulong handler;
359:
360: #if defined(DEBUG_SIGNAL)
361: fprintf(stderr, "queue_signal: sig=%d\n",
362: sig);
363: #endif
364: k = &sigact_table[sig - 1];
365: handler = k->sa._sa_handler;
366: if (handler == TARGET_SIG_DFL) {
367:
368: if (sig != TARGET_SIGCHLD &&
369: sig != TARGET_SIGURG &&
370: sig != TARGET_SIGWINCH) {
371: force_sig(sig);
372: } else {
373: return 0;
374: }
375: } else if (handler == TARGET_SIG_IGN) {
376:
377: return 0;
378: } else if (handler == TARGET_SIG_ERR) {
379: force_sig(sig);
380: } else {
381: pq = &k->first;
382: if (sig < TARGET_SIGRTMIN) {
383:
384: if (!k->pending)
385: q = &k->info;
386: else
387: return 0;
388: } else {
389: if (!k->pending) {
390:
391: q = &k->info;
392: } else {
393: q = alloc_sigqueue();
394: if (!q)
395: return -EAGAIN;
396: while (*pq != NULL)
397: pq = &(*pq)->next;
398: }
399: }
400: *pq = q;
401: q->info = *info;
402: q->next = NULL;
403: k->pending = 1;
404:
405: signal_pending = 1;
406: return 1;
407: }
408: }
409:
410: static void host_signal_handler(int host_signum, siginfo_t *info,
411: void *puc)
412: {
413: int sig;
414: target_siginfo_t tinfo;
415:
416:
417:
418: if (host_signum == SIGSEGV || host_signum == SIGBUS) {
419: if (cpu_signal_handler(host_signum, info, puc))
420: return;
421: }
422:
423:
424: sig = host_to_target_signal(host_signum);
425: if (sig < 1 || sig > TARGET_NSIG)
426: return;
427: #if defined(DEBUG_SIGNAL)
428: fprintf(stderr, "qemu: got signal %d\n", sig);
429: #endif
430: host_to_target_siginfo_noswap(&tinfo, info);
431: if (queue_signal(sig, &tinfo) == 1) {
432:
433: cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
434: }
435: }
436:
437:
438:
439: abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
440: {
441: int ret;
442: struct target_sigaltstack oss;
443:
444:
445: if(uoss_addr)
446: {
447: __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
448: __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
449: __put_user(sas_ss_flags(sp), &oss.ss_flags);
450: }
451:
452: if(uss_addr)
453: {
454: struct target_sigaltstack *uss;
455: struct target_sigaltstack ss;
456:
457: ret = -TARGET_EFAULT;
458: if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
459: || __get_user(ss.ss_sp, &uss->ss_sp)
460: || __get_user(ss.ss_size, &uss->ss_size)
461: || __get_user(ss.ss_flags, &uss->ss_flags))
462: goto out;
463: unlock_user_struct(uss, uss_addr, 0);
464:
465: ret = -TARGET_EPERM;
466: if (on_sig_stack(sp))
467: goto out;
468:
469: ret = -TARGET_EINVAL;
470: if (ss.ss_flags != TARGET_SS_DISABLE
471: && ss.ss_flags != TARGET_SS_ONSTACK
472: && ss.ss_flags != 0)
473: goto out;
474:
475: if (ss.ss_flags == TARGET_SS_DISABLE) {
476: ss.ss_size = 0;
477: ss.ss_sp = 0;
478: } else {
479: ret = -TARGET_ENOMEM;
480: if (ss.ss_size < MINSIGSTKSZ)
481: goto out;
482: }
483:
484: target_sigaltstack_used.ss_sp = ss.ss_sp;
485: target_sigaltstack_used.ss_size = ss.ss_size;
486: }
487:
488: if (uoss_addr) {
489: ret = -TARGET_EFAULT;
490: if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
491: goto out;
492: }
493:
494: ret = 0;
495: out:
496: return ret;
497: }
498:
499:
500: int do_sigaction(int sig, const struct target_sigaction *act,
501: struct target_sigaction *oact)
502: {
503: struct emulated_sigaction *k;
504: struct sigaction act1;
505: int host_sig;
506: int ret = 0;
507:
508: if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP)
509: return -EINVAL;
510: k = &sigact_table[sig - 1];
511: #if defined(DEBUG_SIGNAL)
512: fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
513: sig, (int)act, (int)oact);
514: #endif
515: if (oact) {
516: oact->_sa_handler = tswapl(k->sa._sa_handler);
517: oact->sa_flags = tswapl(k->sa.sa_flags);
518: #if !defined(TARGET_MIPS)
519: oact->sa_restorer = tswapl(k->sa.sa_restorer);
520: #endif
521: oact->sa_mask = k->sa.sa_mask;
522: }
523: if (act) {
524: k->sa._sa_handler = tswapl(act->_sa_handler);
525: k->sa.sa_flags = tswapl(act->sa_flags);
526: #if !defined(TARGET_MIPS)
527: k->sa.sa_restorer = tswapl(act->sa_restorer);
528: #endif
529: k->sa.sa_mask = act->sa_mask;
530:
531:
532: host_sig = target_to_host_signal(sig);
533: if (host_sig != SIGSEGV && host_sig != SIGBUS) {
534: sigfillset(&act1.sa_mask);
535: act1.sa_flags = SA_SIGINFO;
536: if (k->sa.sa_flags & TARGET_SA_RESTART)
537: act1.sa_flags |= SA_RESTART;
538:
539:
540:
541: if (k->sa._sa_handler == TARGET_SIG_IGN) {
542: act1.sa_sigaction = (void *)SIG_IGN;
5