xref: /illumos-kvm-cmd/linux-user/signal.c (revision 68396ea9)
1 /*
2  *  Emulation of Linux signals
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/ucontext.h>
28 #include <sys/resource.h>
29 
30 #include "qemu.h"
31 #include "qemu-common.h"
32 #include "target_signal.h"
33 
34 //#define DEBUG_SIGNAL
35 
36 static struct target_sigaltstack target_sigaltstack_used = {
37     .ss_sp = 0,
38     .ss_size = 0,
39     .ss_flags = TARGET_SS_DISABLE,
40 };
41 
42 static struct target_sigaction sigact_table[TARGET_NSIG];
43 
44 static void host_signal_handler(int host_signum, siginfo_t *info,
45                                 void *puc);
46 
47 static uint8_t host_to_target_signal_table[_NSIG] = {
48     [SIGHUP] = TARGET_SIGHUP,
49     [SIGINT] = TARGET_SIGINT,
50     [SIGQUIT] = TARGET_SIGQUIT,
51     [SIGILL] = TARGET_SIGILL,
52     [SIGTRAP] = TARGET_SIGTRAP,
53     [SIGABRT] = TARGET_SIGABRT,
54 /*    [SIGIOT] = TARGET_SIGIOT,*/
55     [SIGBUS] = TARGET_SIGBUS,
56     [SIGFPE] = TARGET_SIGFPE,
57     [SIGKILL] = TARGET_SIGKILL,
58     [SIGUSR1] = TARGET_SIGUSR1,
59     [SIGSEGV] = TARGET_SIGSEGV,
60     [SIGUSR2] = TARGET_SIGUSR2,
61     [SIGPIPE] = TARGET_SIGPIPE,
62     [SIGALRM] = TARGET_SIGALRM,
63     [SIGTERM] = TARGET_SIGTERM,
64 #ifdef SIGSTKFLT
65     [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 #endif
67     [SIGCHLD] = TARGET_SIGCHLD,
68     [SIGCONT] = TARGET_SIGCONT,
69     [SIGSTOP] = TARGET_SIGSTOP,
70     [SIGTSTP] = TARGET_SIGTSTP,
71     [SIGTTIN] = TARGET_SIGTTIN,
72     [SIGTTOU] = TARGET_SIGTTOU,
73     [SIGURG] = TARGET_SIGURG,
74     [SIGXCPU] = TARGET_SIGXCPU,
75     [SIGXFSZ] = TARGET_SIGXFSZ,
76     [SIGVTALRM] = TARGET_SIGVTALRM,
77     [SIGPROF] = TARGET_SIGPROF,
78     [SIGWINCH] = TARGET_SIGWINCH,
79     [SIGIO] = TARGET_SIGIO,
80     [SIGPWR] = TARGET_SIGPWR,
81     [SIGSYS] = TARGET_SIGSYS,
82     /* next signals stay the same */
83     /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84        host libpthread signals.  This assumes noone actually uses SIGRTMAX :-/
85        To fix this properly we need to do manual signal delivery multiplexed
86        over a single host signal.  */
87     [__SIGRTMIN] = __SIGRTMAX,
88     [__SIGRTMAX] = __SIGRTMIN,
89 };
90 static uint8_t target_to_host_signal_table[_NSIG];
91 
on_sig_stack(unsigned long sp)92 static inline int on_sig_stack(unsigned long sp)
93 {
94     return (sp - target_sigaltstack_used.ss_sp
95             < target_sigaltstack_used.ss_size);
96 }
97 
sas_ss_flags(unsigned long sp)98 static inline int sas_ss_flags(unsigned long sp)
99 {
100     return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
101             : on_sig_stack(sp) ? SS_ONSTACK : 0);
102 }
103 
host_to_target_signal(int sig)104 int host_to_target_signal(int sig)
105 {
106     if (sig >= _NSIG)
107         return sig;
108     return host_to_target_signal_table[sig];
109 }
110 
target_to_host_signal(int sig)111 int target_to_host_signal(int sig)
112 {
113     if (sig >= _NSIG)
114         return sig;
115     return target_to_host_signal_table[sig];
116 }
117 
target_sigemptyset(target_sigset_t * set)118 static inline void target_sigemptyset(target_sigset_t *set)
119 {
120     memset(set, 0, sizeof(*set));
121 }
122 
target_sigaddset(target_sigset_t * set,int signum)123 static inline void target_sigaddset(target_sigset_t *set, int signum)
124 {
125     signum--;
126     abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127     set->sig[signum / TARGET_NSIG_BPW] |= mask;
128 }
129 
target_sigismember(const target_sigset_t * set,int signum)130 static inline int target_sigismember(const target_sigset_t *set, int signum)
131 {
132     signum--;
133     abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
134     return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
135 }
136 
host_to_target_sigset_internal(target_sigset_t * d,const sigset_t * s)137 static void host_to_target_sigset_internal(target_sigset_t *d,
138                                            const sigset_t *s)
139 {
140     int i;
141     target_sigemptyset(d);
142     for (i = 1; i <= TARGET_NSIG; i++) {
143         if (sigismember(s, i)) {
144             target_sigaddset(d, host_to_target_signal(i));
145         }
146     }
147 }
148 
host_to_target_sigset(target_sigset_t * d,const sigset_t * s)149 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
150 {
151     target_sigset_t d1;
152     int i;
153 
154     host_to_target_sigset_internal(&d1, s);
155     for(i = 0;i < TARGET_NSIG_WORDS; i++)
156         d->sig[i] = tswapl(d1.sig[i]);
157 }
158 
target_to_host_sigset_internal(sigset_t * d,const target_sigset_t * s)159 static void target_to_host_sigset_internal(sigset_t *d,
160                                            const target_sigset_t *s)
161 {
162     int i;
163     sigemptyset(d);
164     for (i = 1; i <= TARGET_NSIG; i++) {
165         if (target_sigismember(s, i)) {
166             sigaddset(d, target_to_host_signal(i));
167         }
168      }
169 }
170 
target_to_host_sigset(sigset_t * d,const target_sigset_t * s)171 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
172 {
173     target_sigset_t s1;
174     int i;
175 
176     for(i = 0;i < TARGET_NSIG_WORDS; i++)
177         s1.sig[i] = tswapl(s->sig[i]);
178     target_to_host_sigset_internal(d, &s1);
179 }
180 
host_to_target_old_sigset(abi_ulong * old_sigset,const sigset_t * sigset)181 void host_to_target_old_sigset(abi_ulong *old_sigset,
182                                const sigset_t *sigset)
183 {
184     target_sigset_t d;
185     host_to_target_sigset(&d, sigset);
186     *old_sigset = d.sig[0];
187 }
188 
target_to_host_old_sigset(sigset_t * sigset,const abi_ulong * old_sigset)189 void target_to_host_old_sigset(sigset_t *sigset,
190                                const abi_ulong *old_sigset)
191 {
192     target_sigset_t d;
193     int i;
194 
195     d.sig[0] = *old_sigset;
196     for(i = 1;i < TARGET_NSIG_WORDS; i++)
197         d.sig[i] = 0;
198     target_to_host_sigset(sigset, &d);
199 }
200 
201 /* siginfo conversion */
202 
host_to_target_siginfo_noswap(target_siginfo_t * tinfo,const siginfo_t * info)203 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
204                                                  const siginfo_t *info)
205 {
206     int sig;
207     sig = host_to_target_signal(info->si_signo);
208     tinfo->si_signo = sig;
209     tinfo->si_errno = 0;
210     tinfo->si_code = info->si_code;
211     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
212         sig == SIGBUS || sig == SIGTRAP) {
213         /* should never come here, but who knows. The information for
214            the target is irrelevant */
215         tinfo->_sifields._sigfault._addr = 0;
216     } else if (sig == SIGIO) {
217 	tinfo->_sifields._sigpoll._fd = info->si_fd;
218     } else if (sig >= TARGET_SIGRTMIN) {
219         tinfo->_sifields._rt._pid = info->si_pid;
220         tinfo->_sifields._rt._uid = info->si_uid;
221         /* XXX: potential problem if 64 bit */
222         tinfo->_sifields._rt._sigval.sival_ptr =
223             (abi_ulong)(unsigned long)info->si_value.sival_ptr;
224     }
225 }
226 
tswap_siginfo(target_siginfo_t * tinfo,const target_siginfo_t * info)227 static void tswap_siginfo(target_siginfo_t *tinfo,
228                           const target_siginfo_t *info)
229 {
230     int sig;
231     sig = info->si_signo;
232     tinfo->si_signo = tswap32(sig);
233     tinfo->si_errno = tswap32(info->si_errno);
234     tinfo->si_code = tswap32(info->si_code);
235     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
236         sig == SIGBUS || sig == SIGTRAP) {
237         tinfo->_sifields._sigfault._addr =
238             tswapl(info->_sifields._sigfault._addr);
239     } else if (sig == SIGIO) {
240 	tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
241     } else if (sig >= TARGET_SIGRTMIN) {
242         tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
243         tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
244         tinfo->_sifields._rt._sigval.sival_ptr =
245             tswapl(info->_sifields._rt._sigval.sival_ptr);
246     }
247 }
248 
249 
host_to_target_siginfo(target_siginfo_t * tinfo,const siginfo_t * info)250 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
251 {
252     host_to_target_siginfo_noswap(tinfo, info);
253     tswap_siginfo(tinfo, tinfo);
254 }
255 
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
target_to_host_siginfo(siginfo_t * info,const target_siginfo_t * tinfo)258 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
259 {
260     info->si_signo = tswap32(tinfo->si_signo);
261     info->si_errno = tswap32(tinfo->si_errno);
262     info->si_code = tswap32(tinfo->si_code);
263     info->si_pid = tswap32(tinfo->_sifields._rt._pid);
264     info->si_uid = tswap32(tinfo->_sifields._rt._uid);
265     info->si_value.sival_ptr =
266             (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
267 }
268 
fatal_signal(int sig)269 static int fatal_signal (int sig)
270 {
271     switch (sig) {
272     case TARGET_SIGCHLD:
273     case TARGET_SIGURG:
274     case TARGET_SIGWINCH:
275         /* Ignored by default.  */
276         return 0;
277     case TARGET_SIGCONT:
278     case TARGET_SIGSTOP:
279     case TARGET_SIGTSTP:
280     case TARGET_SIGTTIN:
281     case TARGET_SIGTTOU:
282         /* Job control signals.  */
283         return 0;
284     default:
285         return 1;
286     }
287 }
288 
289 /* returns 1 if given signal should dump core if not handled */
core_dump_signal(int sig)290 static int core_dump_signal(int sig)
291 {
292     switch (sig) {
293     case TARGET_SIGABRT:
294     case TARGET_SIGFPE:
295     case TARGET_SIGILL:
296     case TARGET_SIGQUIT:
297     case TARGET_SIGSEGV:
298     case TARGET_SIGTRAP:
299     case TARGET_SIGBUS:
300         return (1);
301     default:
302         return (0);
303     }
304 }
305 
signal_init(void)306 void signal_init(void)
307 {
308     struct sigaction act;
309     struct sigaction oact;
310     int i, j;
311     int host_sig;
312 
313     /* generate signal conversion tables */
314     for(i = 1; i < _NSIG; i++) {
315         if (host_to_target_signal_table[i] == 0)
316             host_to_target_signal_table[i] = i;
317     }
318     for(i = 1; i < _NSIG; i++) {
319         j = host_to_target_signal_table[i];
320         target_to_host_signal_table[j] = i;
321     }
322 
323     /* set all host signal handlers. ALL signals are blocked during
324        the handlers to serialize them. */
325     memset(sigact_table, 0, sizeof(sigact_table));
326 
327     sigfillset(&act.sa_mask);
328     act.sa_flags = SA_SIGINFO;
329     act.sa_sigaction = host_signal_handler;
330     for(i = 1; i <= TARGET_NSIG; i++) {
331         host_sig = target_to_host_signal(i);
332         sigaction(host_sig, NULL, &oact);
333         if (oact.sa_sigaction == (void *)SIG_IGN) {
334             sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
335         } else if (oact.sa_sigaction == (void *)SIG_DFL) {
336             sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
337         }
338         /* If there's already a handler installed then something has
339            gone horribly wrong, so don't even try to handle that case.  */
340         /* Install some handlers for our own use.  We need at least
341            SIGSEGV and SIGBUS, to detect exceptions.  We can not just
342            trap all signals because it affects syscall interrupt
343            behavior.  But do trap all default-fatal signals.  */
344         if (fatal_signal (i))
345             sigaction(host_sig, &act, NULL);
346     }
347 }
348 
349 /* signal queue handling */
350 
alloc_sigqueue(CPUState * env)351 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
352 {
353     TaskState *ts = env->opaque;
354     struct sigqueue *q = ts->first_free;
355     if (!q)
356         return NULL;
357     ts->first_free = q->next;
358     return q;
359 }
360 
free_sigqueue(CPUState * env,struct sigqueue * q)361 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
362 {
363     TaskState *ts = env->opaque;
364     q->next = ts->first_free;
365     ts->first_free = q;
366 }
367 
368 /* abort execution with signal */
force_sig(int target_sig)369 static void QEMU_NORETURN force_sig(int target_sig)
370 {
371     TaskState *ts = (TaskState *)thread_env->opaque;
372     int host_sig, core_dumped = 0;
373     struct sigaction act;
374     host_sig = target_to_host_signal(target_sig);
375     gdb_signalled(thread_env, target_sig);
376 
377     /* dump core if supported by target binary format */
378     if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
379         stop_all_tasks();
380         core_dumped =
381             ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
382     }
383     if (core_dumped) {
384         /* we already dumped the core of target process, we don't want
385          * a coredump of qemu itself */
386         struct rlimit nodump;
387         getrlimit(RLIMIT_CORE, &nodump);
388         nodump.rlim_cur=0;
389         setrlimit(RLIMIT_CORE, &nodump);
390         (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
391             target_sig, strsignal(host_sig), "core dumped" );
392     }
393 
394     /* The proper exit code for dieing from an uncaught signal is
395      * -<signal>.  The kernel doesn't allow exit() or _exit() to pass
396      * a negative value.  To get the proper exit code we need to
397      * actually die from an uncaught signal.  Here the default signal
398      * handler is installed, we send ourself a signal and we wait for
399      * it to arrive. */
400     sigfillset(&act.sa_mask);
401     act.sa_handler = SIG_DFL;
402     sigaction(host_sig, &act, NULL);
403 
404     /* For some reason raise(host_sig) doesn't send the signal when
405      * statically linked on x86-64. */
406     kill(getpid(), host_sig);
407 
408     /* Make sure the signal isn't masked (just reuse the mask inside
409     of act) */
410     sigdelset(&act.sa_mask, host_sig);
411     sigsuspend(&act.sa_mask);
412 
413     /* unreachable */
414     abort();
415 }
416 
417 /* queue a signal so that it will be send to the virtual CPU as soon
418    as possible */
queue_signal(CPUState * env,int sig,target_siginfo_t * info)419 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
420 {
421     TaskState *ts = env->opaque;
422     struct emulated_sigtable *k;
423     struct sigqueue *q, **pq;
424     abi_ulong handler;
425     int queue;
426 
427 #if defined(DEBUG_SIGNAL)
428     fprintf(stderr, "queue_signal: sig=%d\n",
429             sig);
430 #endif
431     k = &ts->sigtab[sig - 1];
432     queue = gdb_queuesig ();
433     handler = sigact_table[sig - 1]._sa_handler;
434     if (!queue && handler == TARGET_SIG_DFL) {
435         if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
436             kill(getpid(),SIGSTOP);
437             return 0;
438         } else
439         /* default handler : ignore some signal. The other are fatal */
440         if (sig != TARGET_SIGCHLD &&
441             sig != TARGET_SIGURG &&
442             sig != TARGET_SIGWINCH &&
443             sig != TARGET_SIGCONT) {
444             force_sig(sig);
445         } else {
446             return 0; /* indicate ignored */
447         }
448     } else if (!queue && handler == TARGET_SIG_IGN) {
449         /* ignore signal */
450         return 0;
451     } else if (!queue && handler == TARGET_SIG_ERR) {
452         force_sig(sig);
453     } else {
454         pq = &k->first;
455         if (sig < TARGET_SIGRTMIN) {
456             /* if non real time signal, we queue exactly one signal */
457             if (!k->pending)
458                 q = &k->info;
459             else
460                 return 0;
461         } else {
462             if (!k->pending) {
463                 /* first signal */
464                 q = &k->info;
465             } else {
466                 q = alloc_sigqueue(env);
467                 if (!q)
468                     return -EAGAIN;
469                 while (*pq != NULL)
470                     pq = &(*pq)->next;
471             }
472         }
473         *pq = q;
474         q->info = *info;
475         q->next = NULL;
476         k->pending = 1;
477         /* signal that a new signal is pending */
478         ts->signal_pending = 1;
479         return 1; /* indicates that the signal was queued */
480     }
481 }
482 
host_signal_handler(int host_signum,siginfo_t * info,void * puc)483 static void host_signal_handler(int host_signum, siginfo_t *info,
484                                 void *puc)
485 {
486     int sig;
487     target_siginfo_t tinfo;
488 
489     /* the CPU emulator uses some host signals to detect exceptions,
490        we forward to it some signals */
491     if ((host_signum == SIGSEGV || host_signum == SIGBUS)
492         && info->si_code > 0) {
493         if (cpu_signal_handler(host_signum, info, puc))
494             return;
495     }
496 
497     /* get target signal number */
498     sig = host_to_target_signal(host_signum);
499     if (sig < 1 || sig > TARGET_NSIG)
500         return;
501 #if defined(DEBUG_SIGNAL)
502     fprintf(stderr, "qemu: got signal %d\n", sig);
503 #endif
504     host_to_target_siginfo_noswap(&tinfo, info);
505     if (queue_signal(thread_env, sig, &tinfo) == 1) {
506         /* interrupt the virtual CPU as soon as possible */
507         cpu_exit(thread_env);
508     }
509 }
510 
511 /* do_sigaltstack() returns target values and errnos. */
512 /* compare linux/kernel/signal.c:do_sigaltstack() */
do_sigaltstack(abi_ulong uss_addr,abi_ulong uoss_addr,abi_ulong sp)513 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
514 {
515     int ret;
516     struct target_sigaltstack oss;
517 
518     /* XXX: test errors */
519     if(uoss_addr)
520     {
521         __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
522         __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
523         __put_user(sas_ss_flags(sp), &oss.ss_flags);
524     }
525 
526     if(uss_addr)
527     {
528         struct target_sigaltstack *uss;
529         struct target_sigaltstack ss;
530 
531 	ret = -TARGET_EFAULT;
532         if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
533 	    || __get_user(ss.ss_sp, &uss->ss_sp)
534 	    || __get_user(ss.ss_size, &uss->ss_size)
535 	    || __get_user(ss.ss_flags, &uss->ss_flags))
536             goto out;
537         unlock_user_struct(uss, uss_addr, 0);
538 
539 	ret = -TARGET_EPERM;
540 	if (on_sig_stack(sp))
541             goto out;
542 
543 	ret = -TARGET_EINVAL;
544 	if (ss.ss_flags != TARGET_SS_DISABLE
545             && ss.ss_flags != TARGET_SS_ONSTACK
546             && ss.ss_flags != 0)
547             goto out;
548 
549 	if (ss.ss_flags == TARGET_SS_DISABLE) {
550             ss.ss_size = 0;
551             ss.ss_sp = 0;
552 	} else {
553             ret = -TARGET_ENOMEM;
554             if (ss.ss_size < MINSIGSTKSZ)
555                 goto out;
556 	}
557 
558         target_sigaltstack_used.ss_sp = ss.ss_sp;
559         target_sigaltstack_used.ss_size = ss.ss_size;
560     }
561 
562     if (uoss_addr) {
563         ret = -TARGET_EFAULT;
564         if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
565             goto out;
566     }
567 
568     ret = 0;
569 out:
570     return ret;
571 }
572 
573 /* do_sigaction() return host values and errnos */
do_sigaction(int sig,const struct target_sigaction * act,struct target_sigaction * oact)574 int do_sigaction(int sig, const struct target_sigaction *act,
575                  struct target_sigaction *oact)
576 {
577     struct target_sigaction *k;
578     struct sigaction act1;
579     int host_sig;
580     int ret = 0;
581 
582     if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
583         return -EINVAL;
584     k = &sigact_table[sig - 1];
585 #if defined(DEBUG_SIGNAL)
586     fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
587             sig, act, oact);
588 #endif
589     if (oact) {
590         oact->_sa_handler = tswapl(k->_sa_handler);
591         oact->sa_flags = tswapl(k->sa_flags);
592 #if !defined(TARGET_MIPS)
593         oact->sa_restorer = tswapl(k->sa_restorer);
594 #endif
595         oact->sa_mask = k->sa_mask;
596     }
597     if (act) {
598         /* FIXME: This is not threadsafe.  */
599         k->_sa_handler = tswapl(act->_sa_handler);
600         k->sa_flags = tswapl(act->sa_flags);
601 #if !defined(TARGET_MIPS)
602         k->sa_restorer = tswapl(act->sa_restorer);
603 #endif
604         k->sa_mask = act->sa_mask;
605 
606         /* we update the host linux signal state */
607         host_sig = target_to_host_signal(sig);
608         if (host_sig != SIGSEGV && host_sig != SIGBUS) {
609             sigfillset(&act1.sa_mask);
610             act1.sa_flags = SA_SIGINFO;
611             if (k->sa_flags & TARGET_SA_RESTART)
612                 act1.sa_flags |= SA_RESTART;
613             /* NOTE: it is important to update the host kernel signal
614                ignore state to avoid getting unexpected interrupted
615                syscalls */
616             if (k->_sa_handler == TARGET_SIG_IGN) {
617                 act1.sa_sigaction = (void *)SIG_IGN;
618             } else if (k->_sa_handler == TARGET_SIG_DFL) {
619                 if (fatal_signal (sig))
620                     act1.sa_sigaction = host_signal_handler;
621                 else
622                     act1.sa_sigaction = (void *)SIG_DFL;
623             } else {
624                 act1.sa_sigaction = host_signal_handler;
625             }
626             ret = sigaction(host_sig, &act1, NULL);
627         }
628     }
629     return ret;
630 }
631 
copy_siginfo_to_user(target_siginfo_t * tinfo,const target_siginfo_t * info)632 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
633                                        const target_siginfo_t *info)
634 {
635     tswap_siginfo(tinfo, info);
636     return 0;
637 }
638 
current_exec_domain_sig(int sig)639 static inline int current_exec_domain_sig(int sig)
640 {
641     return /* current->exec_domain && current->exec_domain->signal_invmap
642 	      && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
643 }
644 
645 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
646 
647 /* from the Linux kernel */
648 
649 struct target_fpreg {
650 	uint16_t significand[4];
651 	uint16_t exponent;
652 };
653 
654 struct target_fpxreg {
655 	uint16_t significand[4];
656 	uint16_t exponent;
657 	uint16_t padding[3];
658 };
659 
660 struct target_xmmreg {
661 	abi_ulong element[4];
662 };
663 
664 struct target_fpstate {
665 	/* Regular FPU environment */
666         abi_ulong       cw;
667         abi_ulong       sw;
668         abi_ulong       tag;
669         abi_ulong       ipoff;
670         abi_ulong       cssel;
671         abi_ulong       dataoff;
672         abi_ulong       datasel;
673 	struct target_fpreg	_st[8];
674 	uint16_t	status;
675 	uint16_t	magic;		/* 0xffff = regular FPU data only */
676 
677 	/* FXSR FPU environment */
678         abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
679         abi_ulong       mxcsr;
680         abi_ulong       reserved;
681 	struct target_fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */
682 	struct target_xmmreg	_xmm[8];
683         abi_ulong       padding[56];
684 };
685 
686 #define X86_FXSR_MAGIC		0x0000
687 
688 struct target_sigcontext {
689 	uint16_t gs, __gsh;
690 	uint16_t fs, __fsh;
691 	uint16_t es, __esh;
692 	uint16_t ds, __dsh;
693         abi_ulong edi;
694         abi_ulong esi;
695         abi_ulong ebp;
696         abi_ulong esp;
697         abi_ulong ebx;
698         abi_ulong edx;
699         abi_ulong ecx;
700         abi_ulong eax;
701         abi_ulong trapno;
702         abi_ulong err;
703         abi_ulong eip;
704 	uint16_t cs, __csh;
705         abi_ulong eflags;
706         abi_ulong esp_at_signal;
707 	uint16_t ss, __ssh;
708         abi_ulong fpstate; /* pointer */
709         abi_ulong oldmask;
710         abi_ulong cr2;
711 };
712 
713 struct target_ucontext {
714         abi_ulong         tuc_flags;
715         abi_ulong         tuc_link;
716 	target_stack_t	  tuc_stack;
717 	struct target_sigcontext tuc_mcontext;
718 	target_sigset_t	  tuc_sigmask;	/* mask last for extensibility */
719 };
720 
721 struct sigframe
722 {
723     abi_ulong pretcode;
724     int sig;
725     struct target_sigcontext sc;
726     struct target_fpstate fpstate;
727     abi_ulong extramask[TARGET_NSIG_WORDS-1];
728     char retcode[8];
729 };
730 
731 struct rt_sigframe
732 {
733     abi_ulong pretcode;
734     int sig;
735     abi_ulong pinfo;
736     abi_ulong puc;
737     struct target_siginfo info;
738     struct target_ucontext uc;
739     struct target_fpstate fpstate;
740     char retcode[8];
741 };
742 
743 /*
744  * Set up a signal frame.
745  */
746 
747 /* XXX: save x87 state */
748 static int
setup_sigcontext(struct target_sigcontext * sc,struct target_fpstate * fpstate,CPUX86State * env,abi_ulong mask,abi_ulong fpstate_addr)749 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
750 		 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
751 {
752 	int err = 0;
753         uint16_t magic;
754 
755 	/* already locked in setup_frame() */
756 	err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
757 	err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
758 	err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
759 	err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
760 	err |= __put_user(env->regs[R_EDI], &sc->edi);
761 	err |= __put_user(env->regs[R_ESI], &sc->esi);
762 	err |= __put_user(env->regs[R_EBP], &sc->ebp);
763 	err |= __put_user(env->regs[R_ESP], &sc->esp);
764 	err |= __put_user(env->regs[R_EBX], &sc->ebx);
765 	err |= __put_user(env->regs[R_EDX], &sc->edx);
766 	err |= __put_user(env->regs[R_ECX], &sc->ecx);
767 	err |= __put_user(env->regs[R_EAX], &sc->eax);
768 	err |= __put_user(env->exception_index, &sc->trapno);
769 	err |= __put_user(env->error_code, &sc->err);
770 	err |= __put_user(env->eip, &sc->eip);
771 	err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
772 	err |= __put_user(env->eflags, &sc->eflags);
773 	err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
774 	err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
775 
776         cpu_x86_fsave(env, fpstate_addr, 1);
777         fpstate->status = fpstate->sw;
778         magic = 0xffff;
779         err |= __put_user(magic, &fpstate->magic);
780         err |= __put_user(fpstate_addr, &sc->fpstate);
781 
782 	/* non-iBCS2 extensions.. */
783 	err |= __put_user(mask, &sc->oldmask);
784 	err |= __put_user(env->cr[2], &sc->cr2);
785 	return err;
786 }
787 
788 /*
789  * Determine which stack to use..
790  */
791 
792 static inline abi_ulong
get_sigframe(struct target_sigaction * ka,CPUX86State * env,size_t frame_size)793 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
794 {
795 	unsigned long esp;
796 
797 	/* Default to using normal stack */
798 	esp = env->regs[R_ESP];
799 	/* This is the X/Open sanctioned signal stack switching.  */
800         if (ka->sa_flags & TARGET_SA_ONSTACK) {
801             if (sas_ss_flags(esp) == 0)
802                 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
803         }
804 
805 	/* This is the legacy signal stack switching. */
806 	else
807         if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
808             !(ka->sa_flags & TARGET_SA_RESTORER) &&
809             ka->sa_restorer) {
810             esp = (unsigned long) ka->sa_restorer;
811 	}
812         return (esp - frame_size) & -8ul;
813 }
814 
815 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
setup_frame(int sig,struct target_sigaction * ka,target_sigset_t * set,CPUX86State * env)816 static void setup_frame(int sig, struct target_sigaction *ka,
817 			target_sigset_t *set, CPUX86State *env)
818 {
819 	abi_ulong frame_addr;
820 	struct sigframe *frame;
821 	int i, err = 0;
822 
823 	frame_addr = get_sigframe(ka, env, sizeof(*frame));
824 
825 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
826 		goto give_sigsegv;
827 
828 	err |= __put_user(current_exec_domain_sig(sig),
829 		          &frame->sig);
830 	if (err)
831 		goto give_sigsegv;
832 
833 	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
834                          frame_addr + offsetof(struct sigframe, fpstate));
835 	if (err)
836 		goto give_sigsegv;
837 
838         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
839             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
840                 goto give_sigsegv;
841         }
842 
843 	/* Set up to return from userspace.  If provided, use a stub
844 	   already in userspace.  */
845 	if (ka->sa_flags & TARGET_SA_RESTORER) {
846 		err |= __put_user(ka->sa_restorer, &frame->pretcode);
847 	} else {
848                 uint16_t val16;
849                 abi_ulong retcode_addr;
850                 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
851 		err |= __put_user(retcode_addr, &frame->pretcode);
852 		/* This is popl %eax ; movl $,%eax ; int $0x80 */
853                 val16 = 0xb858;
854 		err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
855 		err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
856                 val16 = 0x80cd;
857 		err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
858 	}
859 
860 	if (err)
861 		goto give_sigsegv;
862 
863 	/* Set up registers for signal handler */
864 	env->regs[R_ESP] = frame_addr;
865 	env->eip = ka->_sa_handler;
866 
867         cpu_x86_load_seg(env, R_DS, __USER_DS);
868         cpu_x86_load_seg(env, R_ES, __USER_DS);
869         cpu_x86_load_seg(env, R_SS, __USER_DS);
870         cpu_x86_load_seg(env, R_CS, __USER_CS);
871 	env->eflags &= ~TF_MASK;
872 
873 	unlock_user_struct(frame, frame_addr, 1);
874 
875 	return;
876 
877 give_sigsegv:
878 	unlock_user_struct(frame, frame_addr, 1);
879 	if (sig == TARGET_SIGSEGV)
880 		ka->_sa_handler = TARGET_SIG_DFL;
881 	force_sig(TARGET_SIGSEGV /* , current */);
882 }
883 
884 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
setup_rt_frame(int sig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUX86State * env)885 static void setup_rt_frame(int sig, struct target_sigaction *ka,
886                            target_siginfo_t *info,
887 			   target_sigset_t *set, CPUX86State *env)
888 {
889         abi_ulong frame_addr, addr;
890 	struct rt_sigframe *frame;
891 	int i, err = 0;
892 
893 	frame_addr = get_sigframe(ka, env, sizeof(*frame));
894 
895 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
896 		goto give_sigsegv;
897 
898 	err |= __put_user(current_exec_domain_sig(sig),
899 			  &frame->sig);
900         addr = frame_addr + offsetof(struct rt_sigframe, info);
901 	err |= __put_user(addr, &frame->pinfo);
902         addr = frame_addr + offsetof(struct rt_sigframe, uc);
903 	err |= __put_user(addr, &frame->puc);
904 	err |= copy_siginfo_to_user(&frame->info, info);
905 	if (err)
906 		goto give_sigsegv;
907 
908 	/* Create the ucontext.  */
909 	err |= __put_user(0, &frame->uc.tuc_flags);
910 	err |= __put_user(0, &frame->uc.tuc_link);
911 	err |= __put_user(target_sigaltstack_used.ss_sp,
912 			  &frame->uc.tuc_stack.ss_sp);
913 	err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
914 			  &frame->uc.tuc_stack.ss_flags);
915 	err |= __put_user(target_sigaltstack_used.ss_size,
916 			  &frame->uc.tuc_stack.ss_size);
917 	err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
918 			        env, set->sig[0],
919                                 frame_addr + offsetof(struct rt_sigframe, fpstate));
920         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
921             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
922                 goto give_sigsegv;
923         }
924 
925 	/* Set up to return from userspace.  If provided, use a stub
926 	   already in userspace.  */
927 	if (ka->sa_flags & TARGET_SA_RESTORER) {
928 		err |= __put_user(ka->sa_restorer, &frame->pretcode);
929 	} else {
930                 uint16_t val16;
931                 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
932 		err |= __put_user(addr, &frame->pretcode);
933 		/* This is movl $,%eax ; int $0x80 */
934                 err |= __put_user(0xb8, (char *)(frame->retcode+0));
935 		err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
936                 val16 = 0x80cd;
937                 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
938 	}
939 
940 	if (err)
941 		goto give_sigsegv;
942 
943 	/* Set up registers for signal handler */
944 	env->regs[R_ESP] = frame_addr;
945 	env->eip = ka->_sa_handler;
946 
947         cpu_x86_load_seg(env, R_DS, __USER_DS);
948         cpu_x86_load_seg(env, R_ES, __USER_DS);
949         cpu_x86_load_seg(env, R_SS, __USER_DS);
950         cpu_x86_load_seg(env, R_CS, __USER_CS);
951 	env->eflags &= ~TF_MASK;
952 
953 	unlock_user_struct(frame, frame_addr, 1);
954 
955 	return;
956 
957 give_sigsegv:
958 	unlock_user_struct(frame, frame_addr, 1);
959 	if (sig == TARGET_SIGSEGV)
960 		ka->_sa_handler = TARGET_SIG_DFL;
961 	force_sig(TARGET_SIGSEGV /* , current */);
962 }
963 
964 static int
restore_sigcontext(CPUX86State * env,struct target_sigcontext * sc,int * peax)965 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
966 {
967 	unsigned int err = 0;
968         abi_ulong fpstate_addr;
969         unsigned int tmpflags;
970 
971         cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
972         cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
973         cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
974         cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
975 
976         env->regs[R_EDI] = tswapl(sc->edi);
977         env->regs[R_ESI] = tswapl(sc->esi);
978         env->regs[R_EBP] = tswapl(sc->ebp);
979         env->regs[R_ESP] = tswapl(sc->esp);
980         env->regs[R_EBX] = tswapl(sc->ebx);
981         env->regs[R_EDX] = tswapl(sc->edx);
982         env->regs[R_ECX] = tswapl(sc->ecx);
983         env->eip = tswapl(sc->eip);
984 
985         cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
986         cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
987 
988         tmpflags = tswapl(sc->eflags);
989         env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
990         //		regs->orig_eax = -1;		/* disable syscall checks */
991 
992         fpstate_addr = tswapl(sc->fpstate);
993 	if (fpstate_addr != 0) {
994                 if (!access_ok(VERIFY_READ, fpstate_addr,
995                                sizeof(struct target_fpstate)))
996                         goto badframe;
997                 cpu_x86_frstor(env, fpstate_addr, 1);
998 	}
999 
1000         *peax = tswapl(sc->eax);
1001 	return err;
1002 badframe:
1003 	return 1;
1004 }
1005 
do_sigreturn(CPUX86State * env)1006 long do_sigreturn(CPUX86State *env)
1007 {
1008     struct sigframe *frame;
1009     abi_ulong frame_addr = env->regs[R_ESP] - 8;
1010     target_sigset_t target_set;
1011     sigset_t set;
1012     int eax, i;
1013 
1014 #if defined(DEBUG_SIGNAL)
1015     fprintf(stderr, "do_sigreturn\n");
1016 #endif
1017     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1018         goto badframe;
1019     /* set blocked signals */
1020     if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1021         goto badframe;
1022     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1023         if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1024             goto badframe;
1025     }
1026 
1027     target_to_host_sigset_internal(&set, &target_set);
1028     sigprocmask(SIG_SETMASK, &set, NULL);
1029 
1030     /* restore registers */
1031     if (restore_sigcontext(env, &frame->sc, &eax))
1032         goto badframe;
1033     unlock_user_struct(frame, frame_addr, 0);
1034     return eax;
1035 
1036 badframe:
1037     unlock_user_struct(frame, frame_addr, 0);
1038     force_sig(TARGET_SIGSEGV);
1039     return 0;
1040 }
1041 
do_rt_sigreturn(CPUX86State * env)1042 long do_rt_sigreturn(CPUX86State *env)
1043 {
1044         abi_ulong frame_addr;
1045 	struct rt_sigframe *frame;
1046         sigset_t set;
1047 	int eax;
1048 
1049         frame_addr = env->regs[R_ESP] - 4;
1050         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1051                 goto badframe;
1052         target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1053         sigprocmask(SIG_SETMASK, &set, NULL);
1054 
1055 	if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1056 		goto badframe;
1057 
1058 	if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1059                            get_sp_from_cpustate(env)) == -EFAULT)
1060 		goto badframe;
1061 
1062         unlock_user_struct(frame, frame_addr, 0);
1063 	return eax;
1064 
1065 badframe:
1066         unlock_user_struct(frame, frame_addr, 0);
1067         force_sig(TARGET_SIGSEGV);
1068 	return 0;
1069 }
1070 
1071 #elif defined(TARGET_ARM)
1072 
1073 struct target_sigcontext {
1074 	abi_ulong trap_no;
1075 	abi_ulong error_code;
1076 	abi_ulong oldmask;
1077 	abi_ulong arm_r0;
1078 	abi_ulong arm_r1;
1079 	abi_ulong arm_r2;
1080 	abi_ulong arm_r3;
1081 	abi_ulong arm_r4;
1082 	abi_ulong arm_r5;
1083 	abi_ulong arm_r6;
1084 	abi_ulong arm_r7;
1085 	abi_ulong arm_r8;
1086 	abi_ulong arm_r9;
1087 	abi_ulong arm_r10;
1088 	abi_ulong arm_fp;
1089 	abi_ulong arm_ip;
1090 	abi_ulong arm_sp;
1091 	abi_ulong arm_lr;
1092 	abi_ulong arm_pc;
1093 	abi_ulong arm_cpsr;
1094 	abi_ulong fault_address;
1095 };
1096 
1097 struct target_ucontext_v1 {
1098     abi_ulong tuc_flags;
1099     abi_ulong tuc_link;
1100     target_stack_t tuc_stack;
1101     struct target_sigcontext tuc_mcontext;
1102     target_sigset_t  tuc_sigmask;	/* mask last for extensibility */
1103 };
1104 
1105 struct target_ucontext_v2 {
1106     abi_ulong tuc_flags;
1107     abi_ulong tuc_link;
1108     target_stack_t tuc_stack;
1109     struct target_sigcontext tuc_mcontext;
1110     target_sigset_t  tuc_sigmask;	/* mask last for extensibility */
1111     char __unused[128 - sizeof(target_sigset_t)];
1112     abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1113 };
1114 
1115 struct target_user_vfp {
1116     uint64_t fpregs[32];
1117     abi_ulong fpscr;
1118 };
1119 
1120 struct target_user_vfp_exc {
1121     abi_ulong fpexc;
1122     abi_ulong fpinst;
1123     abi_ulong fpinst2;
1124 };
1125 
1126 struct target_vfp_sigframe {
1127     abi_ulong magic;
1128     abi_ulong size;
1129     struct target_user_vfp ufp;
1130     struct target_user_vfp_exc ufp_exc;
1131 } __attribute__((__aligned__(8)));
1132 
1133 struct target_iwmmxt_sigframe {
1134     abi_ulong magic;
1135     abi_ulong size;
1136     uint64_t regs[16];
1137     /* Note that not all the coprocessor control registers are stored here */
1138     uint32_t wcssf;
1139     uint32_t wcasf;
1140     uint32_t wcgr0;
1141     uint32_t wcgr1;
1142     uint32_t wcgr2;
1143     uint32_t wcgr3;
1144 } __attribute__((__aligned__(8)));
1145 
1146 #define TARGET_VFP_MAGIC 0x56465001
1147 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1148 
1149 struct sigframe_v1
1150 {
1151     struct target_sigcontext sc;
1152     abi_ulong extramask[TARGET_NSIG_WORDS-1];
1153     abi_ulong retcode;
1154 };
1155 
1156 struct sigframe_v2
1157 {
1158     struct target_ucontext_v2 uc;
1159     abi_ulong retcode;
1160 };
1161 
1162 struct rt_sigframe_v1
1163 {
1164     abi_ulong pinfo;
1165     abi_ulong puc;
1166     struct target_siginfo info;
1167     struct target_ucontext_v1 uc;
1168     abi_ulong retcode;
1169 };
1170 
1171 struct rt_sigframe_v2
1172 {
1173     struct target_siginfo info;
1174     struct target_ucontext_v2 uc;
1175     abi_ulong retcode;
1176 };
1177 
1178 #define TARGET_CONFIG_CPU_32 1
1179 
1180 /*
1181  * For ARM syscalls, we encode the syscall number into the instruction.
1182  */
1183 #define SWI_SYS_SIGRETURN	(0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1184 #define SWI_SYS_RT_SIGRETURN	(0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1185 
1186 /*
1187  * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1188  * need two 16-bit instructions.
1189  */
1190 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1191 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1192 
1193 static const abi_ulong retcodes[4] = {
1194 	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,
1195 	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN
1196 };
1197 
1198 
1199 #define __get_user_error(x,p,e) __get_user(x, p)
1200 
valid_user_regs(CPUState * regs)1201 static inline int valid_user_regs(CPUState *regs)
1202 {
1203     return 1;
1204 }
1205 
1206 static void
setup_sigcontext(struct target_sigcontext * sc,CPUState * env,abi_ulong mask)1207 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1208 		 CPUState *env, abi_ulong mask)
1209 {
1210 	__put_user(env->regs[0], &sc->arm_r0);
1211 	__put_user(env->regs[1], &sc->arm_r1);
1212 	__put_user(env->regs[2], &sc->arm_r2);
1213 	__put_user(env->regs[3], &sc->arm_r3);
1214 	__put_user(env->regs[4], &sc->arm_r4);
1215 	__put_user(env->regs[5], &sc->arm_r5);
1216 	__put_user(env->regs[6], &sc->arm_r6);
1217 	__put_user(env->regs[7], &sc->arm_r7);
1218 	__put_user(env->regs[8], &sc->arm_r8);
1219 	__put_user(env->regs[9], &sc->arm_r9);
1220 	__put_user(env->regs[10], &sc->arm_r10);
1221 	__put_user(env->regs[11], &sc->arm_fp);
1222 	__put_user(env->regs[12], &sc->arm_ip);
1223 	__put_user(env->regs[13], &sc->arm_sp);
1224 	__put_user(env->regs[14], &sc->arm_lr);
1225 	__put_user(env->regs[15], &sc->arm_pc);
1226 #ifdef TARGET_CONFIG_CPU_32
1227 	__put_user(cpsr_read(env), &sc->arm_cpsr);
1228 #endif
1229 
1230 	__put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1231 	__put_user(/* current->thread.error_code */ 0, &sc->error_code);
1232 	__put_user(/* current->thread.address */ 0, &sc->fault_address);
1233 	__put_user(mask, &sc->oldmask);
1234 }
1235 
1236 static inline abi_ulong
get_sigframe(struct target_sigaction * ka,CPUState * regs,int framesize)1237 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1238 {
1239 	unsigned long sp = regs->regs[13];
1240 
1241 	/*
1242 	 * This is the X/Open sanctioned signal stack switching.
1243 	 */
1244 	if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1245             sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1246 	/*
1247 	 * ATPCS B01 mandates 8-byte alignment
1248 	 */
1249 	return (sp - framesize) & ~7;
1250 }
1251 
1252 static int
setup_return(CPUState * env,struct target_sigaction * ka,abi_ulong * rc,abi_ulong frame_addr,int usig,abi_ulong rc_addr)1253 setup_return(CPUState *env, struct target_sigaction *ka,
1254 	     abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1255 {
1256 	abi_ulong handler = ka->_sa_handler;
1257 	abi_ulong retcode;
1258 	int thumb = handler & 1;
1259 	uint32_t cpsr = cpsr_read(env);
1260 
1261 	cpsr &= ~CPSR_IT;
1262 	if (thumb) {
1263 		cpsr |= CPSR_T;
1264 	} else {
1265 		cpsr &= ~CPSR_T;
1266 	}
1267 
1268 	if (ka->sa_flags & TARGET_SA_RESTORER) {
1269 		retcode = ka->sa_restorer;
1270 	} else {
1271 		unsigned int idx = thumb;
1272 
1273 		if (ka->sa_flags & TARGET_SA_SIGINFO)
1274 			idx += 2;
1275 
1276 		if (__put_user(retcodes[idx], rc))
1277 			return 1;
1278 #if 0
1279 		flush_icache_range((abi_ulong)rc,
1280 				   (abi_ulong)(rc + 1));
1281 #endif
1282 		retcode = rc_addr + thumb;
1283 	}
1284 
1285 	env->regs[0] = usig;
1286 	env->regs[13] = frame_addr;
1287 	env->regs[14] = retcode;
1288 	env->regs[15] = handler & (thumb ? ~1 : ~3);
1289 	cpsr_write(env, cpsr, 0xffffffff);
1290 
1291 	return 0;
1292 }
1293 
setup_sigframe_v2_vfp(abi_ulong * regspace,CPUState * env)1294 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
1295 {
1296     int i;
1297     struct target_vfp_sigframe *vfpframe;
1298     vfpframe = (struct target_vfp_sigframe *)regspace;
1299     __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1300     __put_user(sizeof(*vfpframe), &vfpframe->size);
1301     for (i = 0; i < 32; i++) {
1302         __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1303     }
1304     __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1305     __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1306     __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1307     __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1308     return (abi_ulong*)(vfpframe+1);
1309 }
1310 
setup_sigframe_v2_iwmmxt(abi_ulong * regspace,CPUState * env)1311 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace, CPUState *env)
1312 {
1313     int i;
1314     struct target_iwmmxt_sigframe *iwmmxtframe;
1315     iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1316     __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1317     __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1318     for (i = 0; i < 16; i++) {
1319         __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1320     }
1321     __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1322     __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1323     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1324     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1325     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1326     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1327     return (abi_ulong*)(iwmmxtframe+1);
1328 }
1329 
setup_sigframe_v2(struct target_ucontext_v2 * uc,target_sigset_t * set,CPUState * env)1330 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1331                               target_sigset_t *set, CPUState *env)
1332 {
1333     struct target_sigaltstack stack;
1334     int i;
1335     abi_ulong *regspace;
1336 
1337     /* Clear all the bits of the ucontext we don't use.  */
1338     memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1339 
1340     memset(&stack, 0, sizeof(stack));
1341     __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1342     __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1343     __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1344     memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1345 
1346     setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1347     /* Save coprocessor signal frame.  */
1348     regspace = uc->tuc_regspace;
1349     if (arm_feature(env, ARM_FEATURE_VFP)) {
1350         regspace = setup_sigframe_v2_vfp(regspace, env);
1351     }
1352     if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1353         regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1354     }
1355 
1356     /* Write terminating magic word */
1357     __put_user(0, regspace);
1358 
1359     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1360         __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1361     }
1362 }
1363 
1364 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
setup_frame_v1(int usig,struct target_sigaction * ka,target_sigset_t * set,CPUState * regs)1365 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1366 			   target_sigset_t *set, CPUState *regs)
1367 {
1368 	struct sigframe_v1 *frame;
1369 	abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1370 	int i;
1371 
1372 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1373 		return;
1374 
1375 	setup_sigcontext(&frame->sc, regs, set->sig[0]);
1376 
1377         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1378             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1379                 goto end;
1380 	}
1381 
1382         setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1383                      frame_addr + offsetof(struct sigframe_v1, retcode));
1384 
1385 end:
1386 	unlock_user_struct(frame, frame_addr, 1);
1387 }
1388 
setup_frame_v2(int usig,struct target_sigaction * ka,target_sigset_t * set,CPUState * regs)1389 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1390 			   target_sigset_t *set, CPUState *regs)
1391 {
1392 	struct sigframe_v2 *frame;
1393 	abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1394 
1395 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1396 		return;
1397 
1398         setup_sigframe_v2(&frame->uc, set, regs);
1399 
1400         setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1401                      frame_addr + offsetof(struct sigframe_v2, retcode));
1402 
1403 	unlock_user_struct(frame, frame_addr, 1);
1404 }
1405 
setup_frame(int usig,struct target_sigaction * ka,target_sigset_t * set,CPUState * regs)1406 static void setup_frame(int usig, struct target_sigaction *ka,
1407 			target_sigset_t *set, CPUState *regs)
1408 {
1409     if (get_osversion() >= 0x020612) {
1410         setup_frame_v2(usig, ka, set, regs);
1411     } else {
1412         setup_frame_v1(usig, ka, set, regs);
1413     }
1414 }
1415 
1416 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
setup_rt_frame_v1(int usig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)1417 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1418                               target_siginfo_t *info,
1419 			      target_sigset_t *set, CPUState *env)
1420 {
1421 	struct rt_sigframe_v1 *frame;
1422 	abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1423 	struct target_sigaltstack stack;
1424 	int i;
1425         abi_ulong info_addr, uc_addr;
1426 
1427 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1428             return /* 1 */;
1429 
1430         info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1431 	__put_user(info_addr, &frame->pinfo);
1432         uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1433 	__put_user(uc_addr, &frame->puc);
1434 	copy_siginfo_to_user(&frame->info, info);
1435 
1436 	/* Clear all the bits of the ucontext we don't use.  */
1437 	memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1438 
1439         memset(&stack, 0, sizeof(stack));
1440         __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1441         __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1442         __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1443         memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1444 
1445 	setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1446         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1447             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1448                 goto end;
1449         }
1450 
1451         setup_return(env, ka, &frame->retcode, frame_addr, usig,
1452                      frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1453 
1454         env->regs[1] = info_addr;
1455         env->regs[2] = uc_addr;
1456 
1457 end:
1458 	unlock_user_struct(frame, frame_addr, 1);
1459 }
1460 
setup_rt_frame_v2(int usig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)1461 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1462                               target_siginfo_t *info,
1463                               target_sigset_t *set, CPUState *env)
1464 {
1465 	struct rt_sigframe_v2 *frame;
1466 	abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1467         abi_ulong info_addr, uc_addr;
1468 
1469 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1470             return /* 1 */;
1471 
1472         info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1473         uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1474 	copy_siginfo_to_user(&frame->info, info);
1475 
1476         setup_sigframe_v2(&frame->uc, set, env);
1477 
1478         setup_return(env, ka, &frame->retcode, frame_addr, usig,
1479                      frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1480 
1481         env->regs[1] = info_addr;
1482         env->regs[2] = uc_addr;
1483 
1484 	unlock_user_struct(frame, frame_addr, 1);
1485 }
1486 
setup_rt_frame(int usig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)1487 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1488                            target_siginfo_t *info,
1489 			   target_sigset_t *set, CPUState *env)
1490 {
1491     if (get_osversion() >= 0x020612) {
1492         setup_rt_frame_v2(usig, ka, info, set, env);
1493     } else {
1494         setup_rt_frame_v1(usig, ka, info, set, env);
1495     }
1496 }
1497 
1498 static int
restore_sigcontext(CPUState * env,struct target_sigcontext * sc)1499 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1500 {
1501 	int err = 0;
1502         uint32_t cpsr;
1503 
1504 	__get_user_error(env->regs[0], &sc->arm_r0, err);
1505 	__get_user_error(env->regs[1], &sc->arm_r1, err);
1506 	__get_user_error(env->regs[2], &sc->arm_r2, err);
1507 	__get_user_error(env->regs[3], &sc->arm_r3, err);
1508 	__get_user_error(env->regs[4], &sc->arm_r4, err);
1509 	__get_user_error(env->regs[5], &sc->arm_r5, err);
1510 	__get_user_error(env->regs[6], &sc->arm_r6, err);
1511 	__get_user_error(env->regs[7], &sc->arm_r7, err);
1512 	__get_user_error(env->regs[8], &sc->arm_r8, err);
1513 	__get_user_error(env->regs[9], &sc->arm_r9, err);
1514 	__get_user_error(env->regs[10], &sc->arm_r10, err);
1515 	__get_user_error(env->regs[11], &sc->arm_fp, err);
1516 	__get_user_error(env->regs[12], &sc->arm_ip, err);
1517 	__get_user_error(env->regs[13], &sc->arm_sp, err);
1518 	__get_user_error(env->regs[14], &sc->arm_lr, err);
1519 	__get_user_error(env->regs[15], &sc->arm_pc, err);
1520 #ifdef TARGET_CONFIG_CPU_32
1521 	__get_user_error(cpsr, &sc->arm_cpsr, err);
1522         cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1523 #endif
1524 
1525 	err |= !valid_user_regs(env);
1526 
1527 	return err;
1528 }
1529 
do_sigreturn_v1(CPUState * env)1530 static long do_sigreturn_v1(CPUState *env)
1531 {
1532         abi_ulong frame_addr;
1533 	struct sigframe_v1 *frame;
1534 	target_sigset_t set;
1535         sigset_t host_set;
1536         int i;
1537 
1538 	/*
1539 	 * Since we stacked the signal on a 64-bit boundary,
1540 	 * then 'sp' should be word aligned here.  If it's
1541 	 * not, then the user is trying to mess with us.
1542 	 */
1543 	if (env->regs[13] & 7)
1544 		goto badframe;
1545 
1546         frame_addr = env->regs[13];
1547 	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1548                 goto badframe;
1549 
1550 	if (__get_user(set.sig[0], &frame->sc.oldmask))
1551             goto badframe;
1552         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1553             if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1554                 goto badframe;
1555         }
1556 
1557         target_to_host_sigset_internal(&host_set, &set);
1558         sigprocmask(SIG_SETMASK, &host_set, NULL);
1559 
1560 	if (restore_sigcontext(env, &frame->sc))
1561 		goto badframe;
1562 
1563 #if 0
1564 	/* Send SIGTRAP if we're single-stepping */
1565 	if (ptrace_cancel_bpt(current))
1566 		send_sig(SIGTRAP, current, 1);
1567 #endif
1568 	unlock_user_struct(frame, frame_addr, 0);
1569         return env->regs[0];
1570 
1571 badframe:
1572 	unlock_user_struct(frame, frame_addr, 0);
1573         force_sig(TARGET_SIGSEGV /* , current */);
1574 	return 0;
1575 }
1576 
restore_sigframe_v2_vfp(CPUState * env,abi_ulong * regspace)1577 static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
1578 {
1579     int i;
1580     abi_ulong magic, sz;
1581     uint32_t fpscr, fpexc;
1582     struct target_vfp_sigframe *vfpframe;
1583     vfpframe = (struct target_vfp_sigframe *)regspace;
1584 
1585     __get_user(magic, &vfpframe->magic);
1586     __get_user(sz, &vfpframe->size);
1587     if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1588         return 0;
1589     }
1590     for (i = 0; i < 32; i++) {
1591         __get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1592     }
1593     __get_user(fpscr, &vfpframe->ufp.fpscr);
1594     vfp_set_fpscr(env, fpscr);
1595     __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1596     /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1597      * and the exception flag is cleared
1598      */
1599     fpexc |= (1 << 30);
1600     fpexc &= ~((1 << 31) | (1 << 28));
1601     env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1602     __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1603     __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1604     return (abi_ulong*)(vfpframe + 1);
1605 }
1606 
restore_sigframe_v2_iwmmxt(CPUState * env,abi_ulong * regspace)1607 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUState *env, abi_ulong *regspace)
1608 {
1609     int i;
1610     abi_ulong magic, sz;
1611     struct target_iwmmxt_sigframe *iwmmxtframe;
1612     iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1613 
1614     __get_user(magic, &iwmmxtframe->magic);
1615     __get_user(sz, &iwmmxtframe->size);
1616     if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1617         return 0;
1618     }
1619     for (i = 0; i < 16; i++) {
1620         __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1621     }
1622     __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1623     __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1624     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1625     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1626     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1627     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1628     return (abi_ulong*)(iwmmxtframe + 1);
1629 }
1630 
do_sigframe_return_v2(CPUState * env,target_ulong frame_addr,struct target_ucontext_v2 * uc)1631 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1632                                  struct target_ucontext_v2 *uc)
1633 {
1634     sigset_t host_set;
1635     abi_ulong *regspace;
1636 
1637     target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1638     sigprocmask(SIG_SETMASK, &host_set, NULL);
1639 
1640     if (restore_sigcontext(env, &uc->tuc_mcontext))
1641         return 1;
1642 
1643     /* Restore coprocessor signal frame */
1644     regspace = uc->tuc_regspace;
1645     if (arm_feature(env, ARM_FEATURE_VFP)) {
1646         regspace = restore_sigframe_v2_vfp(env, regspace);
1647         if (!regspace) {
1648             return 1;
1649         }
1650     }
1651     if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1652         regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1653         if (!regspace) {
1654             return 1;
1655         }
1656     }
1657 
1658     if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1659         return 1;
1660 
1661 #if 0
1662     /* Send SIGTRAP if we're single-stepping */
1663     if (ptrace_cancel_bpt(current))
1664             send_sig(SIGTRAP, current, 1);
1665 #endif
1666 
1667     return 0;
1668 }
1669 
do_sigreturn_v2(CPUState * env)1670 static long do_sigreturn_v2(CPUState *env)
1671 {
1672         abi_ulong frame_addr;
1673 	struct sigframe_v2 *frame;
1674 
1675 	/*
1676 	 * Since we stacked the signal on a 64-bit boundary,
1677 	 * then 'sp' should be word aligned here.  If it's
1678 	 * not, then the user is trying to mess with us.
1679 	 */
1680 	if (env->regs[13] & 7)
1681 		goto badframe;
1682 
1683         frame_addr = env->regs[13];
1684 	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1685                 goto badframe;
1686 
1687         if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1688                 goto badframe;
1689 
1690 	unlock_user_struct(frame, frame_addr, 0);
1691 	return env->regs[0];
1692 
1693 badframe:
1694 	unlock_user_struct(frame, frame_addr, 0);
1695         force_sig(TARGET_SIGSEGV /* , current */);
1696 	return 0;
1697 }
1698 
do_sigreturn(CPUState * env)1699 long do_sigreturn(CPUState *env)
1700 {
1701     if (get_osversion() >= 0x020612) {
1702         return do_sigreturn_v2(env);
1703     } else {
1704         return do_sigreturn_v1(env);
1705     }
1706 }
1707 
do_rt_sigreturn_v1(CPUState * env)1708 static long do_rt_sigreturn_v1(CPUState *env)
1709 {
1710         abi_ulong frame_addr;
1711 	struct rt_sigframe_v1 *frame;
1712         sigset_t host_set;
1713 
1714 	/*
1715 	 * Since we stacked the signal on a 64-bit boundary,
1716 	 * then 'sp' should be word aligned here.  If it's
1717 	 * not, then the user is trying to mess with us.
1718 	 */
1719 	if (env->regs[13] & 7)
1720 		goto badframe;
1721 
1722         frame_addr = env->regs[13];
1723 	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1724                 goto badframe;
1725 
1726         target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1727         sigprocmask(SIG_SETMASK, &host_set, NULL);
1728 
1729 	if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1730 		goto badframe;
1731 
1732 	if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1733 		goto badframe;
1734 
1735 #if 0
1736 	/* Send SIGTRAP if we're single-stepping */
1737 	if (ptrace_cancel_bpt(current))
1738 		send_sig(SIGTRAP, current, 1);
1739 #endif
1740 	unlock_user_struct(frame, frame_addr, 0);
1741 	return env->regs[0];
1742 
1743 badframe:
1744 	unlock_user_struct(frame, frame_addr, 0);
1745         force_sig(TARGET_SIGSEGV /* , current */);
1746 	return 0;
1747 }
1748 
do_rt_sigreturn_v2(CPUState * env)1749 static long do_rt_sigreturn_v2(CPUState *env)
1750 {
1751         abi_ulong frame_addr;
1752 	struct rt_sigframe_v2 *frame;
1753 
1754 	/*
1755 	 * Since we stacked the signal on a 64-bit boundary,
1756 	 * then 'sp' should be word aligned here.  If it's
1757 	 * not, then the user is trying to mess with us.
1758 	 */
1759 	if (env->regs[13] & 7)
1760 		goto badframe;
1761 
1762         frame_addr = env->regs[13];
1763 	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1764                 goto badframe;
1765 
1766         if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1767                 goto badframe;
1768 
1769 	unlock_user_struct(frame, frame_addr, 0);
1770 	return env->regs[0];
1771 
1772 badframe:
1773 	unlock_user_struct(frame, frame_addr, 0);
1774         force_sig(TARGET_SIGSEGV /* , current */);
1775 	return 0;
1776 }
1777 
do_rt_sigreturn(CPUState * env)1778 long do_rt_sigreturn(CPUState *env)
1779 {
1780     if (get_osversion() >= 0x020612) {
1781         return do_rt_sigreturn_v2(env);
1782     } else {
1783         return do_rt_sigreturn_v1(env);
1784     }
1785 }
1786 
1787 #elif defined(TARGET_SPARC)
1788 
1789 #define __SUNOS_MAXWIN   31
1790 
1791 /* This is what SunOS does, so shall I. */
1792 struct target_sigcontext {
1793         abi_ulong sigc_onstack;      /* state to restore */
1794 
1795         abi_ulong sigc_mask;         /* sigmask to restore */
1796         abi_ulong sigc_sp;           /* stack pointer */
1797         abi_ulong sigc_pc;           /* program counter */
1798         abi_ulong sigc_npc;          /* next program counter */
1799         abi_ulong sigc_psr;          /* for condition codes etc */
1800         abi_ulong sigc_g1;           /* User uses these two registers */
1801         abi_ulong sigc_o0;           /* within the trampoline code. */
1802 
1803         /* Now comes information regarding the users window set
1804          * at the time of the signal.
1805          */
1806         abi_ulong sigc_oswins;       /* outstanding windows */
1807 
1808         /* stack ptrs for each regwin buf */
1809         char *sigc_spbuf[__SUNOS_MAXWIN];
1810 
1811         /* Windows to restore after signal */
1812         struct {
1813                 abi_ulong locals[8];
1814                 abi_ulong ins[8];
1815         } sigc_wbuf[__SUNOS_MAXWIN];
1816 };
1817 /* A Sparc stack frame */
1818 struct sparc_stackf {
1819         abi_ulong locals[8];
1820         abi_ulong ins[8];
1821         /* It's simpler to treat fp and callers_pc as elements of ins[]
1822          * since we never need to access them ourselves.
1823          */
1824         char *structptr;
1825         abi_ulong xargs[6];
1826         abi_ulong xxargs[1];
1827 };
1828 
1829 typedef struct {
1830         struct {
1831                 abi_ulong psr;
1832                 abi_ulong pc;
1833                 abi_ulong npc;
1834                 abi_ulong y;
1835                 abi_ulong u_regs[16]; /* globals and ins */
1836         }               si_regs;
1837         int             si_mask;
1838 } __siginfo_t;
1839 
1840 typedef struct {
1841         unsigned   long si_float_regs [32];
1842         unsigned   long si_fsr;
1843         unsigned   long si_fpqdepth;
1844         struct {
1845                 unsigned long *insn_addr;
1846                 unsigned long insn;
1847         } si_fpqueue [16];
1848 } qemu_siginfo_fpu_t;
1849 
1850 
1851 struct target_signal_frame {
1852 	struct sparc_stackf	ss;
1853 	__siginfo_t		info;
1854 	abi_ulong               fpu_save;
1855 	abi_ulong		insns[2] __attribute__ ((aligned (8)));
1856 	abi_ulong		extramask[TARGET_NSIG_WORDS - 1];
1857 	abi_ulong		extra_size; /* Should be 0 */
1858 	qemu_siginfo_fpu_t	fpu_state;
1859 };
1860 struct target_rt_signal_frame {
1861 	struct sparc_stackf	ss;
1862 	siginfo_t		info;
1863 	abi_ulong		regs[20];
1864 	sigset_t		mask;
1865 	abi_ulong               fpu_save;
1866 	unsigned int		insns[2];
1867 	stack_t			stack;
1868 	unsigned int		extra_size; /* Should be 0 */
1869 	qemu_siginfo_fpu_t	fpu_state;
1870 };
1871 
1872 #define UREG_O0        16
1873 #define UREG_O6        22
1874 #define UREG_I0        0
1875 #define UREG_I1        1
1876 #define UREG_I2        2
1877 #define UREG_I3        3
1878 #define UREG_I4        4
1879 #define UREG_I5        5
1880 #define UREG_I6        6
1881 #define UREG_I7        7
1882 #define UREG_L0	       8
1883 #define UREG_FP        UREG_I6
1884 #define UREG_SP        UREG_O6
1885 
get_sigframe(struct target_sigaction * sa,CPUState * env,unsigned long framesize)1886 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1887                                      CPUState *env, unsigned long framesize)
1888 {
1889 	abi_ulong sp;
1890 
1891 	sp = env->regwptr[UREG_FP];
1892 
1893 	/* This is the X/Open sanctioned signal stack switching.  */
1894 	if (sa->sa_flags & TARGET_SA_ONSTACK) {
1895             if (!on_sig_stack(sp)
1896                 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1897                 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1898 	}
1899 	return sp - framesize;
1900 }
1901 
1902 static int
setup___siginfo(__siginfo_t * si,CPUState * env,abi_ulong mask)1903 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1904 {
1905 	int err = 0, i;
1906 
1907 	err |= __put_user(env->psr, &si->si_regs.psr);
1908 	err |= __put_user(env->pc, &si->si_regs.pc);
1909 	err |= __put_user(env->npc, &si->si_regs.npc);
1910 	err |= __put_user(env->y, &si->si_regs.y);
1911 	for (i=0; i < 8; i++) {
1912 		err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1913 	}
1914 	for (i=0; i < 8; i++) {
1915 		err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1916 	}
1917 	err |= __put_user(mask, &si->si_mask);
1918 	return err;
1919 }
1920 
1921 #if 0
1922 static int
1923 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1924 		 CPUState *env, unsigned long mask)
1925 {
1926 	int err = 0;
1927 
1928 	err |= __put_user(mask, &sc->sigc_mask);
1929 	err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1930 	err |= __put_user(env->pc, &sc->sigc_pc);
1931 	err |= __put_user(env->npc, &sc->sigc_npc);
1932 	err |= __put_user(env->psr, &sc->sigc_psr);
1933 	err |= __put_user(env->gregs[1], &sc->sigc_g1);
1934 	err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1935 
1936 	return err;
1937 }
1938 #endif
1939 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1940 
setup_frame(int sig,struct target_sigaction * ka,target_sigset_t * set,CPUState * env)1941 static void setup_frame(int sig, struct target_sigaction *ka,
1942 			target_sigset_t *set, CPUState *env)
1943 {
1944         abi_ulong sf_addr;
1945 	struct target_signal_frame *sf;
1946 	int sigframe_size, err, i;
1947 
1948 	/* 1. Make sure everything is clean */
1949 	//synchronize_user_stack();
1950 
1951         sigframe_size = NF_ALIGNEDSZ;
1952 	sf_addr = get_sigframe(ka, env, sigframe_size);
1953 
1954         sf = lock_user(VERIFY_WRITE, sf_addr,
1955                        sizeof(struct target_signal_frame), 0);
1956         if (!sf)
1957 		goto sigsegv;
1958 
1959 	//fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1960 #if 0
1961 	if (invalid_frame_pointer(sf, sigframe_size))
1962 		goto sigill_and_return;
1963 #endif
1964 	/* 2. Save the current process state */
1965 	err = setup___siginfo(&sf->info, env, set->sig[0]);
1966 	err |= __put_user(0, &sf->extra_size);
1967 
1968 	//err |= save_fpu_state(regs, &sf->fpu_state);
1969 	//err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1970 
1971 	err |= __put_user(set->sig[0], &sf->info.si_mask);
1972 	for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1973 		err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1974 	}
1975 
1976 	for (i = 0; i < 8; i++) {
1977 	  	err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1978 	}
1979 	for (i = 0; i < 8; i++) {
1980 	  	err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1981 	}
1982 	if (err)
1983 		goto sigsegv;
1984 
1985 	/* 3. signal handler back-trampoline and parameters */
1986 	env->regwptr[UREG_FP] = sf_addr;
1987 	env->regwptr[UREG_I0] = sig;
1988 	env->regwptr[UREG_I1] = sf_addr +
1989                 offsetof(struct target_signal_frame, info);
1990 	env->regwptr[UREG_I2] = sf_addr +
1991                 offsetof(struct target_signal_frame, info);
1992 
1993 	/* 4. signal handler */
1994 	env->pc = ka->_sa_handler;
1995 	env->npc = (env->pc + 4);
1996 	/* 5. return to kernel instructions */
1997 	if (ka->sa_restorer)
1998 		env->regwptr[UREG_I7] = ka->sa_restorer;
1999 	else {
2000                 uint32_t val32;
2001 
2002 		env->regwptr[UREG_I7] = sf_addr +
2003                         offsetof(struct target_signal_frame, insns) - 2 * 4;
2004 
2005 		/* mov __NR_sigreturn, %g1 */
2006                 val32 = 0x821020d8;
2007 		err |= __put_user(val32, &sf->insns[0]);
2008 
2009 		/* t 0x10 */
2010                 val32 = 0x91d02010;
2011 		err |= __put_user(val32, &sf->insns[1]);
2012 		if (err)
2013 			goto sigsegv;
2014 
2015 		/* Flush instruction space. */
2016 		//flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2017                 //		tb_flush(env);
2018 	}
2019         unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2020 	return;
2021 #if 0
2022 sigill_and_return:
2023 	force_sig(TARGET_SIGILL);
2024 #endif
2025 sigsegv:
2026 	//fprintf(stderr, "force_sig\n");
2027         unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2028 	force_sig(TARGET_SIGSEGV);
2029 }
2030 static inline int
restore_fpu_state(CPUState * env,qemu_siginfo_fpu_t * fpu)2031 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
2032 {
2033         int err;
2034 #if 0
2035 #ifdef CONFIG_SMP
2036         if (current->flags & PF_USEDFPU)
2037                 regs->psr &= ~PSR_EF;
2038 #else
2039         if (current == last_task_used_math) {
2040                 last_task_used_math = 0;
2041                 regs->psr &= ~PSR_EF;
2042         }
2043 #endif
2044         current->used_math = 1;
2045         current->flags &= ~PF_USEDFPU;
2046 #endif
2047 #if 0
2048         if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2049                 return -EFAULT;
2050 #endif
2051 
2052 #if 0
2053         /* XXX: incorrect */
2054         err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
2055 	                             (sizeof(unsigned long) * 32));
2056 #endif
2057         err |= __get_user(env->fsr, &fpu->si_fsr);
2058 #if 0
2059         err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2060         if (current->thread.fpqdepth != 0)
2061                 err |= __copy_from_user(&current->thread.fpqueue[0],
2062                                         &fpu->si_fpqueue[0],
2063                                         ((sizeof(unsigned long) +
2064                                         (sizeof(unsigned long *)))*16));
2065 #endif
2066         return err;
2067 }
2068 
2069 
setup_rt_frame(int sig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)2070 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2071                            target_siginfo_t *info,
2072 			   target_sigset_t *set, CPUState *env)
2073 {
2074     fprintf(stderr, "setup_rt_frame: not implemented\n");
2075 }
2076 
do_sigreturn(CPUState * env)2077 long do_sigreturn(CPUState *env)
2078 {
2079         abi_ulong sf_addr;
2080         struct target_signal_frame *sf;
2081         uint32_t up_psr, pc, npc;
2082         target_sigset_t set;
2083         sigset_t host_set;
2084         abi_ulong fpu_save_addr;
2085         int err, i;
2086 
2087         sf_addr = env->regwptr[UREG_FP];
2088         if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2089                 goto segv_and_exit;
2090 #if 0
2091 	fprintf(stderr, "sigreturn\n");
2092 	fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2093 #endif
2094 	//cpu_dump_state(env, stderr, fprintf, 0);
2095 
2096         /* 1. Make sure we are not getting garbage from the user */
2097 
2098         if (sf_addr & 3)
2099                 goto segv_and_exit;
2100 
2101         err = __get_user(pc,  &sf->info.si_regs.pc);
2102         err |= __get_user(npc, &sf->info.si_regs.npc);
2103 
2104         if ((pc | npc) & 3)
2105                 goto segv_and_exit;
2106 
2107         /* 2. Restore the state */
2108         err |= __get_user(up_psr, &sf->info.si_regs.psr);
2109 
2110         /* User can only change condition codes and FPU enabling in %psr. */
2111         env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2112                   | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2113 
2114 	env->pc = pc;
2115 	env->npc = npc;
2116         err |= __get_user(env->y, &sf->info.si_regs.y);
2117 	for (i=0; i < 8; i++) {
2118 		err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2119 	}
2120 	for (i=0; i < 8; i++) {
2121 		err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2122 	}
2123 
2124         err |= __get_user(fpu_save_addr, &sf->fpu_save);
2125 
2126         //if (fpu_save)
2127         //        err |= restore_fpu_state(env, fpu_save);
2128 
2129         /* This is pretty much atomic, no amount locking would prevent
2130          * the races which exist anyways.
2131          */
2132         err |= __get_user(set.sig[0], &sf->info.si_mask);
2133         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2134             err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2135         }
2136 
2137         target_to_host_sigset_internal(&host_set, &set);
2138         sigprocmask(SIG_SETMASK, &host_set, NULL);
2139 
2140         if (err)
2141                 goto segv_and_exit;
2142         unlock_user_struct(sf, sf_addr, 0);
2143         return env->regwptr[0];
2144 
2145 segv_and_exit:
2146         unlock_user_struct(sf, sf_addr, 0);
2147 	force_sig(TARGET_SIGSEGV);
2148 }
2149 
do_rt_sigreturn(CPUState * env)2150 long do_rt_sigreturn(CPUState *env)
2151 {
2152     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2153     return -TARGET_ENOSYS;
2154 }
2155 
2156 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2157 #define MC_TSTATE 0
2158 #define MC_PC 1
2159 #define MC_NPC 2
2160 #define MC_Y 3
2161 #define MC_G1 4
2162 #define MC_G2 5
2163 #define MC_G3 6
2164 #define MC_G4 7
2165 #define MC_G5 8
2166 #define MC_G6 9
2167 #define MC_G7 10
2168 #define MC_O0 11
2169 #define MC_O1 12
2170 #define MC_O2 13
2171 #define MC_O3 14
2172 #define MC_O4 15
2173 #define MC_O5 16
2174 #define MC_O6 17
2175 #define MC_O7 18
2176 #define MC_NGREG 19
2177 
2178 typedef abi_ulong target_mc_greg_t;
2179 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2180 
2181 struct target_mc_fq {
2182     abi_ulong *mcfq_addr;
2183     uint32_t mcfq_insn;
2184 };
2185 
2186 struct target_mc_fpu {
2187     union {
2188         uint32_t sregs[32];
2189         uint64_t dregs[32];
2190         //uint128_t qregs[16];
2191     } mcfpu_fregs;
2192     abi_ulong mcfpu_fsr;
2193     abi_ulong mcfpu_fprs;
2194     abi_ulong mcfpu_gsr;
2195     struct target_mc_fq *mcfpu_fq;
2196     unsigned char mcfpu_qcnt;
2197     unsigned char mcfpu_qentsz;
2198     unsigned char mcfpu_enab;
2199 };
2200 typedef struct target_mc_fpu target_mc_fpu_t;
2201 
2202 typedef struct {
2203     target_mc_gregset_t mc_gregs;
2204     target_mc_greg_t mc_fp;
2205     target_mc_greg_t mc_i7;
2206     target_mc_fpu_t mc_fpregs;
2207 } target_mcontext_t;
2208 
2209 struct target_ucontext {
2210     struct target_ucontext *tuc_link;
2211     abi_ulong tuc_flags;
2212     target_sigset_t tuc_sigmask;
2213     target_mcontext_t tuc_mcontext;
2214 };
2215 
2216 /* A V9 register window */
2217 struct target_reg_window {
2218     abi_ulong locals[8];
2219     abi_ulong ins[8];
2220 };
2221 
2222 #define TARGET_STACK_BIAS 2047
2223 
2224 /* {set, get}context() needed for 64-bit SparcLinux userland. */
sparc64_set_context(CPUSPARCState * env)2225 void sparc64_set_context(CPUSPARCState *env)
2226 {
2227     abi_ulong ucp_addr;
2228     struct target_ucontext *ucp;
2229     target_mc_gregset_t *grp;
2230     abi_ulong pc, npc, tstate;
2231     abi_ulong fp, i7, w_addr;
2232     unsigned char fenab;
2233     int err;
2234     unsigned int i;
2235 
2236     ucp_addr = env->regwptr[UREG_I0];
2237     if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2238         goto do_sigsegv;
2239     grp  = &ucp->tuc_mcontext.mc_gregs;
2240     err  = __get_user(pc, &((*grp)[MC_PC]));
2241     err |= __get_user(npc, &((*grp)[MC_NPC]));
2242     if (err || ((pc | npc) & 3))
2243         goto do_sigsegv;
2244     if (env->regwptr[UREG_I1]) {
2245         target_sigset_t target_set;
2246         sigset_t set;
2247 
2248         if (TARGET_NSIG_WORDS == 1) {
2249             if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2250                 goto do_sigsegv;
2251         } else {
2252             abi_ulong *src, *dst;
2253             src = ucp->tuc_sigmask.sig;
2254             dst = target_set.sig;
2255             for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2256                  i++, dst++, src++)
2257                 err |= __get_user(*dst, src);
2258             if (err)
2259                 goto do_sigsegv;
2260         }
2261         target_to_host_sigset_internal(&set, &target_set);
2262         sigprocmask(SIG_SETMASK, &set, NULL);
2263     }
2264     env->pc = pc;
2265     env->npc = npc;
2266     err |= __get_user(env->y, &((*grp)[MC_Y]));
2267     err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2268     env->asi = (tstate >> 24) & 0xff;
2269     cpu_put_ccr(env, tstate >> 32);
2270     cpu_put_cwp64(env, tstate & 0x1f);
2271     err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2272     err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2273     err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2274     err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2275     err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2276     err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2277     err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2278     err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2279     err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2280     err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2281     err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2282     err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2283     err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2284     err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2285     err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2286 
2287     err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2288     err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2289 
2290     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2291     if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2292                  abi_ulong) != 0)
2293         goto do_sigsegv;
2294     if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2295                  abi_ulong) != 0)
2296         goto do_sigsegv;
2297     err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2298     err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2299     {
2300         uint32_t *src, *dst;
2301         src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2302         dst = env->fpr;
2303         /* XXX: check that the CPU storage is the same as user context */
2304         for (i = 0; i < 64; i++, dst++, src++)
2305             err |= __get_user(*dst, src);
2306     }
2307     err |= __get_user(env->fsr,
2308                       &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2309     err |= __get_user(env->gsr,
2310                       &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2311     if (err)
2312         goto do_sigsegv;
2313     unlock_user_struct(ucp, ucp_addr, 0);
2314     return;
2315  do_sigsegv:
2316     unlock_user_struct(ucp, ucp_addr, 0);
2317     force_sig(TARGET_SIGSEGV);
2318 }
2319 
sparc64_get_context(CPUSPARCState * env)2320 void sparc64_get_context(CPUSPARCState *env)
2321 {
2322     abi_ulong ucp_addr;
2323     struct target_ucontext *ucp;
2324     target_mc_gregset_t *grp;
2325     target_mcontext_t *mcp;
2326     abi_ulong fp, i7, w_addr;
2327     int err;
2328     unsigned int i;
2329     target_sigset_t target_set;
2330     sigset_t set;
2331 
2332     ucp_addr = env->regwptr[UREG_I0];
2333     if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2334         goto do_sigsegv;
2335 
2336     mcp = &ucp->tuc_mcontext;
2337     grp = &mcp->mc_gregs;
2338 
2339     /* Skip over the trap instruction, first. */
2340     env->pc = env->npc;
2341     env->npc += 4;
2342 
2343     err = 0;
2344 
2345     sigprocmask(0, NULL, &set);
2346     host_to_target_sigset_internal(&target_set, &set);
2347     if (TARGET_NSIG_WORDS == 1) {
2348         err |= __put_user(target_set.sig[0],
2349                           (abi_ulong *)&ucp->tuc_sigmask);
2350     } else {
2351         abi_ulong *src, *dst;
2352         src = target_set.sig;
2353         dst = ucp->tuc_sigmask.sig;
2354         for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2355              i++, dst++, src++)
2356             err |= __put_user(*src, dst);
2357         if (err)
2358             goto do_sigsegv;
2359     }
2360 
2361     /* XXX: tstate must be saved properly */
2362     //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2363     err |= __put_user(env->pc, &((*grp)[MC_PC]));
2364     err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2365     err |= __put_user(env->y, &((*grp)[MC_Y]));
2366     err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2367     err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2368     err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2369     err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2370     err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2371     err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2372     err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2373     err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2374     err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2375     err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2376     err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2377     err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2378     err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2379     err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2380     err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2381 
2382     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2383     fp = i7 = 0;
2384     if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2385                  abi_ulong) != 0)
2386         goto do_sigsegv;
2387     if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2388                  abi_ulong) != 0)
2389         goto do_sigsegv;
2390     err |= __put_user(fp, &(mcp->mc_fp));
2391     err |= __put_user(i7, &(mcp->mc_i7));
2392 
2393     {
2394         uint32_t *src, *dst;
2395         src = env->fpr;
2396         dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2397         /* XXX: check that the CPU storage is the same as user context */
2398         for (i = 0; i < 64; i++, dst++, src++)
2399             err |= __put_user(*src, dst);
2400     }
2401     err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2402     err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2403     err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2404 
2405     if (err)
2406         goto do_sigsegv;
2407     unlock_user_struct(ucp, ucp_addr, 1);
2408     return;
2409  do_sigsegv:
2410     unlock_user_struct(ucp, ucp_addr, 1);
2411     force_sig(TARGET_SIGSEGV);
2412 }
2413 #endif
2414 #elif defined(TARGET_ABI_MIPSN64)
2415 
2416 # warning signal handling not implemented
2417 
setup_frame(int sig,struct target_sigaction * ka,target_sigset_t * set,CPUState * env)2418 static void setup_frame(int sig, struct target_sigaction *ka,
2419 			target_sigset_t *set, CPUState *env)
2420 {
2421     fprintf(stderr, "setup_frame: not implemented\n");
2422 }
2423 
setup_rt_frame(int sig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)2424 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2425                            target_siginfo_t *info,
2426 			   target_sigset_t *set, CPUState *env)
2427 {
2428     fprintf(stderr, "setup_rt_frame: not implemented\n");
2429 }
2430 
do_sigreturn(CPUState * env)2431 long do_sigreturn(CPUState *env)
2432 {
2433     fprintf(stderr, "do_sigreturn: not implemented\n");
2434     return -TARGET_ENOSYS;
2435 }
2436 
do_rt_sigreturn(CPUState * env)2437 long do_rt_sigreturn(CPUState *env)
2438 {
2439     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2440     return -TARGET_ENOSYS;
2441 }
2442 
2443 #elif defined(TARGET_ABI_MIPSN32)
2444 
2445 # warning signal handling not implemented
2446 
setup_frame(int sig,struct target_sigaction * ka,target_sigset_t * set,CPUState * env)2447 static void setup_frame(int sig, struct target_sigaction *ka,
2448 			target_sigset_t *set, CPUState *env)
2449 {
2450     fprintf(stderr, "setup_frame: not implemented\n");
2451 }
2452 
setup_rt_frame(int sig,struct target_sigaction * ka,target_siginfo_t * info,target_sigset_t * set,CPUState * env)2453 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2454                            target_siginfo_t *info,
2455 			   target_sigset_t *set, CPUState *env)
2456 {
2457     fprintf(stderr, "setup_rt_frame: not implemented\n");
2458 }
2459 
do_sigreturn(CPUState * env)2460 long do_sigreturn(CPUState *env)
2461 {
2462     fprintf(stderr, "do_sigreturn: not implemented\n");
2463     return -TARGET_ENOSYS;
2464 }
2465 
do_rt_sigreturn(CPUState * env)2466 long do_rt_sigreturn(CPUState *env)
2467 {
2468     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2469     return -TARGET_ENOSYS;
2470 }
2471 
2472 #elif defined(TARGET_ABI_MIPSO32)
2473 
2474 struct target_sigcontext {
2475     uint32_t   sc_regmask;     /* Unused */
2476     uint32_t   sc_status;
2477     uint64_t   sc_pc;
2478     uint64_t   sc_regs[32];
2479     uint64_t   sc_fpregs[32];
2480     uint32_t   sc_ownedfp;     /* Unused */
2481     uint32_t   sc_fpc_csr;
2482     uint32_t   sc_fpc_eir;     /* Unused */
2483     uint32_t   sc_used_math;
2484     uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2485     uint32_t   pad0;
2486     uint64_t   sc_mdhi;
2487     uint64_t   sc_mdlo;
2488     target_ulong   sc_hi1;         /* Was sc_cause */
2489     target_ulong   sc_lo1;         /* Was sc_badvaddr */
2490     target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2491     target_ulong   sc_lo2;
2492     target_ulong   sc_hi3;
2493     target_ulong   sc_lo3;
2494 };
2495 
2496 struct sigframe {
2497     uint32_t sf_ass[4];			/* argument save space for o32 */
2498     uint32_t sf_code[2];			/* signal trampoline */
2499     struct target_sigcontext sf_sc;
2500     target_sigset_t sf_mask;
2501 };
2502 
2503 struct target_ucontext {
2504     target_ulong tuc_flags;
2505     target_ulong tuc_link;
2506     target_stack_t tuc_stack;
2507     target_ulong pad0;
2508     struct target_sigcontext tuc_mcontext;
2509     target_sigset_t tuc_sigmask;
2510 };
2511 
2512 struct target_rt_sigframe {
2513     uint32_t rs_ass[4];               /* argument save space for o32 */
2514     uint32_t rs_code[2];              /* signal trampoline */
2515     struct target_siginfo rs_info;
2516     struct target_ucontext rs_uc;
2517 };
2518 
2519 /* Install trampoline to jump back from signal handler */
install_sigtramp(unsigned int * tramp,unsigned int syscall)2520 static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2521 {
2522     int err;
2523 
2524     /*
2525     * Set up the return code ...
2526     *
2527     *         li      v0, __NR__foo_sigreturn
2528     *         syscall
2529     */
2530 
2531     err = __put_user(0x24020000 + syscall, tramp + 0);
2532     err |= __put_user(0x0000000c          , tramp + 1);
2533     /* flush_cache_sigtramp((unsigned long) tramp); */
2534     return err;
2535 }
2536 
2537 static inline int
setup_sigcontext(CPUState * regs,struct target_sigcontext * sc)2538 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2539 {
2540     int err = 0;
2541 
2542     err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2543 
2544 #define save_gp_reg(i) do {   						\
2545         err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);	\
2546     } while(0)
2547     __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2548     save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2549     save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2550     save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2551     save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2552     save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2553     save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2554     save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2555     save_gp_reg(31);
2556 #undef save_gp_reg
2557 
2558     err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2559     err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2560 
2561     /* Not used yet, but might be useful if we ever have DSP suppport */
2562 #if 0
2563     if (cpu_has_dsp) {
2564 	err |= __put_user(mfhi1(), &sc->sc_hi1);
2565 	err |= __put_user(mflo1(), &sc->sc_lo1);
2566 	err |= __put_user(mfhi2(), &sc->sc_hi2);
2567 	err |= __put_user(mflo2(), &sc->sc_lo2);
2568 	err |= __put_user(mfhi3(), &sc->sc_hi3);
2569 	err |= __put_user(mflo3(), &sc->sc_lo3);
2570 	err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2571     }
2572     /* same with 64 bit */
2573 #ifdef CONFIG_64BIT
2574     err |= __put_user(regs->hi, &sc->sc_hi[0]);
2575     err |= __put_user(regs->lo, &sc->sc_lo[0]);
2576     if (cpu_has_dsp) {
2577 	err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2578 	err |= __put_user(mflo1(), &sc->sc_lo[1]);
2579 	err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2580 	err |= __put_user(mflo2(), &sc->sc_lo[2]);
2581 	err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2582 	err |= __put_user(mflo3(), &sc->sc_lo[3]);
2583 	err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2584     }
2585 #endif
2586 #endif
2587 
2588 #if 0
2589     err |= __put_user(!!used_math(), &sc->sc_used_math);
2590 
2591     if (!used_math())
2592 	goto out;
2593 
2594     /*
2595     * Save FPU state to signal context.  Signal handler will "inherit"
2596     * current FPU state.
2597     */
2598     preempt_disable();
2599 
2600     if (!is_fpu_owner()) {
2601 	own_fpu();
2602 	restore_fp(current);
2603     }
2604     err |= save_fp_context(sc);
2605 
2606     preempt_enable();
2607