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); | ... | ... |