Commit 9e5f5284b3b452ace0097c5171d369be46847e74
1 parent
c596ed17
convert signal numbers
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@328 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
99 additions
and
11 deletions
linux-user/signal.c
| ... | ... | @@ -60,44 +60,122 @@ static int signal_pending; /* non zero if a signal may be pending */ |
| 60 | 60 | static void host_signal_handler(int host_signum, siginfo_t *info, |
| 61 | 61 | void *puc); |
| 62 | 62 | |
| 63 | -/* XXX: do it properly */ | |
| 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 | + [SIGIOT] = TARGET_SIGIOT, | |
| 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 | + /* next signals stay the same */ | |
| 99 | +}; | |
| 100 | +static uint8_t target_to_host_signal_table[65]; | |
| 101 | + | |
| 64 | 102 | static inline int host_to_target_signal(int sig) |
| 65 | 103 | { |
| 66 | - return sig; | |
| 104 | + return host_to_target_signal_table[sig]; | |
| 67 | 105 | } |
| 68 | 106 | |
| 69 | 107 | static inline int target_to_host_signal(int sig) |
| 70 | 108 | { |
| 71 | - return sig; | |
| 109 | + return target_to_host_signal_table[sig]; | |
| 72 | 110 | } |
| 73 | 111 | |
| 74 | -void host_to_target_sigset(target_sigset_t *d, sigset_t *s) | |
| 112 | +void host_to_target_sigset(target_sigset_t *d, const sigset_t *s) | |
| 75 | 113 | { |
| 76 | 114 | int i; |
| 77 | - for(i = 0;i < TARGET_NSIG_WORDS; i++) { | |
| 115 | + unsigned long sigmask; | |
| 116 | + uint32_t target_sigmask; | |
| 117 | + | |
| 118 | + sigmask = ((unsigned long *)s)[0]; | |
| 119 | + target_sigmask = 0; | |
| 120 | + for(i = 0; i < 32; i++) { | |
| 121 | + if (sigmask & (1 << i)) | |
| 122 | + target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1); | |
| 123 | + } | |
| 124 | +#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32 | |
| 125 | + d->sig[0] = tswapl(target_sigmask); | |
| 126 | + for(i = 1;i < TARGET_NSIG_WORDS; i++) { | |
| 78 | 127 | d->sig[i] = tswapl(((unsigned long *)s)[i]); |
| 79 | 128 | } |
| 129 | +#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 | |
| 130 | + d->sig[0] = tswapl(target_sigmask); | |
| 131 | + d->sig[1] = tswapl(sigmask >> 32); | |
| 132 | +#else | |
| 133 | +#error host_to_target_sigset | |
| 134 | +#endif | |
| 80 | 135 | } |
| 81 | 136 | |
| 82 | -void target_to_host_sigset(sigset_t *d, target_sigset_t *s) | |
| 137 | +void target_to_host_sigset(sigset_t *d, const target_sigset_t *s) | |
| 83 | 138 | { |
| 84 | 139 | int i; |
| 85 | - for(i = 0;i < TARGET_NSIG_WORDS; i++) { | |
| 140 | + unsigned long sigmask; | |
| 141 | + target_ulong target_sigmask; | |
| 142 | + | |
| 143 | + target_sigmask = tswapl(s->sig[0]); | |
| 144 | + sigmask = 0; | |
| 145 | + for(i = 0; i < 32; i++) { | |
| 146 | + if (target_sigmask & (1 << i)) | |
| 147 | + sigmask |= 1 << (target_to_host_signal(i + 1) - 1); | |
| 148 | + } | |
| 149 | +#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32 | |
| 150 | + ((unsigned long *)d)[0] = sigmask; | |
| 151 | + for(i = 1;i < TARGET_NSIG_WORDS; i++) { | |
| 86 | 152 | ((unsigned long *)d)[i] = tswapl(s->sig[i]); |
| 87 | 153 | } |
| 154 | +#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 | |
| 155 | + ((unsigned long *)d)[0] = sigmask | (tswapl(s->sig[1]) << 32); | |
| 156 | +#else | |
| 157 | +#error target_to_host_sigset | |
| 158 | +#endif /* TARGET_LONG_BITS */ | |
| 88 | 159 | } |
| 89 | 160 | |
| 90 | 161 | void host_to_target_old_sigset(target_ulong *old_sigset, |
| 91 | 162 | const sigset_t *sigset) |
| 92 | 163 | { |
| 93 | - *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff); | |
| 164 | + target_sigset_t d; | |
| 165 | + host_to_target_sigset(&d, sigset); | |
| 166 | + *old_sigset = d.sig[0]; | |
| 94 | 167 | } |
| 95 | 168 | |
| 96 | 169 | void target_to_host_old_sigset(sigset_t *sigset, |
| 97 | 170 | const target_ulong *old_sigset) |
| 98 | 171 | { |
| 99 | - sigemptyset(sigset); | |
| 100 | - *(unsigned long *)sigset = tswapl(*old_sigset); | |
| 172 | + target_sigset_t d; | |
| 173 | + int i; | |
| 174 | + | |
| 175 | + d.sig[0] = *old_sigset; | |
| 176 | + for(i = 1;i < TARGET_NSIG_WORDS; i++) | |
| 177 | + d.sig[i] = 0; | |
| 178 | + target_to_host_sigset(sigset, &d); | |
| 101 | 179 | } |
| 102 | 180 | |
| 103 | 181 | /* siginfo conversion */ |
| ... | ... | @@ -167,8 +245,18 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) |
| 167 | 245 | void signal_init(void) |
| 168 | 246 | { |
| 169 | 247 | struct sigaction act; |
| 170 | - int i; | |
| 248 | + int i, j; | |
| 171 | 249 | |
| 250 | + /* generate signal conversion tables */ | |
| 251 | + for(i = 1; i <= 64; i++) { | |
| 252 | + if (host_to_target_signal_table[i] == 0) | |
| 253 | + host_to_target_signal_table[i] = i; | |
| 254 | + } | |
| 255 | + for(i = 1; i <= 64; i++) { | |
| 256 | + j = host_to_target_signal_table[i]; | |
| 257 | + target_to_host_signal_table[j] = i; | |
| 258 | + } | |
| 259 | + | |
| 172 | 260 | /* set all host signal handlers. ALL signals are blocked during |
| 173 | 261 | the handlers to serialize them. */ |
| 174 | 262 | sigfillset(&act.sa_mask); | ... | ... |