Revision 9e5f5284
b/linux-user/signal.c | ||
---|---|---|
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 | 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); |
Also available in: Unified diff