Commit 9e5f5284b3b452ace0097c5171d369be46847e74

Authored by bellard
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);
... ...