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,44 +60,122 @@ static int signal_pending; /* non zero if a signal may be pending */ | ||
60 | static void host_signal_handler(int host_signum, siginfo_t *info, | 60 | static void host_signal_handler(int host_signum, siginfo_t *info, |
61 | void *puc); | 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 | static inline int host_to_target_signal(int sig) | 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 | static inline int target_to_host_signal(int sig) | 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 | int i; | 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 | d->sig[i] = tswapl(((unsigned long *)s)[i]); | 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 | int i; | 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 | ((unsigned long *)d)[i] = tswapl(s->sig[i]); | 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 | void host_to_target_old_sigset(target_ulong *old_sigset, | 161 | void host_to_target_old_sigset(target_ulong *old_sigset, |
91 | const sigset_t *sigset) | 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 | void target_to_host_old_sigset(sigset_t *sigset, | 169 | void target_to_host_old_sigset(sigset_t *sigset, |
97 | const target_ulong *old_sigset) | 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 | /* siginfo conversion */ | 181 | /* siginfo conversion */ |
@@ -167,8 +245,18 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) | @@ -167,8 +245,18 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) | ||
167 | void signal_init(void) | 245 | void signal_init(void) |
168 | { | 246 | { |
169 | struct sigaction act; | 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 | /* set all host signal handlers. ALL signals are blocked during | 260 | /* set all host signal handlers. ALL signals are blocked during |
173 | the handlers to serialize them. */ | 261 | the handlers to serialize them. */ |
174 | sigfillset(&act.sa_mask); | 262 | sigfillset(&act.sa_mask); |