Bug Summary

File:linux-user/signal.c
Location:line 2680, column 5
Description:Value stored to 'fp' is never read

Annotated Source Code

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 <errno(*__errno_location ()).h>
25#include <assert.h>
26#include <sys/ucontext.h>
27#include <sys/resource.h>
28
29#include "qemu.h"
30#include "qemu-common.h"
31#include "target_signal.h"
32
33//#define DEBUG_SIGNAL
34
35static struct target_sigaltstack target_sigaltstack_used = {
36 .ss_sp = 0,
37 .ss_size = 0,
38 .ss_flags = TARGET_SS_DISABLE2,
39};
40
41static struct target_sigaction sigact_table[TARGET_NSIG64];
42
43static void host_signal_handler(int host_signum, siginfo_t *info,
44 void *puc);
45
46static uint8_t host_to_target_signal_table[_NSIG65] = {
47 [SIGHUP1] = TARGET_SIGHUP1,
48 [SIGINT2] = TARGET_SIGINT2,
49 [SIGQUIT3] = TARGET_SIGQUIT3,
50 [SIGILL4] = TARGET_SIGILL4,
51 [SIGTRAP5] = TARGET_SIGTRAP5,
52 [SIGABRT6] = TARGET_SIGABRT6,
53/* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS7] = TARGET_SIGBUS10,
55 [SIGFPE8] = TARGET_SIGFPE8,
56 [SIGKILL9] = TARGET_SIGKILL9,
57 [SIGUSR110] = TARGET_SIGUSR130,
58 [SIGSEGV11] = TARGET_SIGSEGV11,
59 [SIGUSR212] = TARGET_SIGUSR231,
60 [SIGPIPE13] = TARGET_SIGPIPE13,
61 [SIGALRM14] = TARGET_SIGALRM14,
62 [SIGTERM15] = TARGET_SIGTERM15,
63#ifdef SIGSTKFLT16
64 [SIGSTKFLT16] = TARGET_SIGSTKFLT7,
65#endif
66 [SIGCHLD17] = TARGET_SIGCHLD20,
67 [SIGCONT18] = TARGET_SIGCONT19,
68 [SIGSTOP19] = TARGET_SIGSTOP17,
69 [SIGTSTP20] = TARGET_SIGTSTP18,
70 [SIGTTIN21] = TARGET_SIGTTIN21,
71 [SIGTTOU22] = TARGET_SIGTTOU22,
72 [SIGURG23] = TARGET_SIGURG16,
73 [SIGXCPU24] = TARGET_SIGXCPU24,
74 [SIGXFSZ25] = TARGET_SIGXFSZ25,
75 [SIGVTALRM26] = TARGET_SIGVTALRM26,
76 [SIGPROF27] = TARGET_SIGPROF27,
77 [SIGWINCH28] = TARGET_SIGWINCH28,
78 [SIGIO29] = TARGET_SIGIO23,
79 [SIGPWR30] = TARGET_SIGPWR29,
80 [SIGSYS31] = TARGET_SIGSYS12,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN32] = __SIGRTMAX(65 - 1),
87 [__SIGRTMAX(65 - 1)] = __SIGRTMIN32,
88};
89static uint8_t target_to_host_signal_table[_NSIG65];
90
91static inline int on_sig_stack(unsigned long sp)
92{
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
95}
96
97static inline int sas_ss_flags(unsigned long sp)
98{
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLESS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACKSS_ONSTACK : 0);
101}
102
103int host_to_target_signal(int sig)
104{
105 if (sig < 0 || sig >= _NSIG65)
106 return sig;
107 return host_to_target_signal_table[sig];
108}
109
110int target_to_host_signal(int sig)
111{
112 if (sig < 0 || sig >= _NSIG65)
113 return sig;
114 return target_to_host_signal_table[sig];
115}
116
117static inline void target_sigemptyset(target_sigset_t *set)
118{
119 memset(set, 0, sizeof(*set));
120}
121
122static inline void target_sigaddset(target_sigset_t *set, int signum)
123{
124 signum--;
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW64);
126 set->sig[signum / TARGET_NSIG_BPW64] |= mask;
127}
128
129static inline int target_sigismember(const target_sigset_t *set, int signum)
130{
131 signum--;
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW64);
133 return ((set->sig[signum / TARGET_NSIG_BPW64] & mask) != 0);
134}
135
136static void host_to_target_sigset_internal(target_sigset_t *d,
137 const sigset_t *s)
138{
139 int i;
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG64; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
144 }
145 }
146}
147
148void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
149{
150 target_sigset_t d1;
151 int i;
152
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS(64 / 64); i++)
155 d->sig[i] = tswapal(d1.sig[i]);
156}
157
158static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
160{
161 int i;
162 sigemptyset(d);
163 for (i = 1; i <= TARGET_NSIG64; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
166 }
167 }
168}
169
170void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
171{
172 target_sigset_t s1;
173 int i;
174
175 for(i = 0;i < TARGET_NSIG_WORDS(64 / 64); i++)
176 s1.sig[i] = tswapal(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
178}
179
180void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
182{
183 target_sigset_t d;
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
186}
187
188void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
190{
191 target_sigset_t d;
192 int i;
193
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS(64 / 64); i++)
196 d.sig[i] = 0;
197 target_to_host_sigset(sigset, &d);
198}
199
200/* siginfo conversion */
201
202static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
203 const siginfo_t *info)
204{
205 int sig = host_to_target_signal(info->si_signo);
206 tinfo->si_signo = sig;
207 tinfo->si_errno = 0;
208 tinfo->si_code = info->si_code;
209
210 if (sig == TARGET_SIGILL4 || sig == TARGET_SIGFPE8 || sig == TARGET_SIGSEGV11
211 || sig == TARGET_SIGBUS10 || sig == TARGET_SIGTRAP5) {
212 /* Should never come here, but who knows. The information for
213 the target is irrelevant. */
214 tinfo->_sifields._sigfault._addr = 0;
215 } else if (sig == TARGET_SIGIO23) {
216 tinfo->_sifields._sigpoll._band = info->si_band_sifields._sigpoll.si_band;
217 tinfo->_sifields._sigpoll._fd = info->si_fd_sifields._sigpoll.si_fd;
218 } else if (sig == TARGET_SIGCHLD20) {
219 tinfo->_sifields._sigchld._pid = info->si_pid_sifields._kill.si_pid;
220 tinfo->_sifields._sigchld._uid = info->si_uid_sifields._kill.si_uid;
221 tinfo->_sifields._sigchld._status
222 = host_to_target_waitstatus(info->si_status_sifields._sigchld.si_status);
223 tinfo->_sifields._sigchld._utime = info->si_utime_sifields._sigchld.si_utime;
224 tinfo->_sifields._sigchld._stime = info->si_stime_sifields._sigchld.si_stime;
225 } else if (sig >= TARGET_SIGRTMIN32) {
226 tinfo->_sifields._rt._pid = info->si_pid_sifields._kill.si_pid;
227 tinfo->_sifields._rt._uid = info->si_uid_sifields._kill.si_uid;
228 /* XXX: potential problem if 64 bit */
229 tinfo->_sifields._rt._sigval.sival_ptr
230 = (abi_ulong)(unsigned long)info->si_value_sifields._rt.si_sigval.sival_ptr;
231 }
232}
233
234static void tswap_siginfo(target_siginfo_t *tinfo,
235 const target_siginfo_t *info)
236{
237 int sig = info->si_signo;
238 tinfo->si_signo = tswap32(sig);
239 tinfo->si_errno = tswap32(info->si_errno);
240 tinfo->si_code = tswap32(info->si_code);
241
242 if (sig == TARGET_SIGILL4 || sig == TARGET_SIGFPE8 || sig == TARGET_SIGSEGV11
243 || sig == TARGET_SIGBUS10 || sig == TARGET_SIGTRAP5) {
244 tinfo->_sifields._sigfault._addr
245 = tswapal(info->_sifields._sigfault._addr);
246 } else if (sig == TARGET_SIGIO23) {
247 tinfo->_sifields._sigpoll._band
248 = tswap32(info->_sifields._sigpoll._band);
249 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
250 } else if (sig == TARGET_SIGCHLD20) {
251 tinfo->_sifields._sigchld._pid
252 = tswap32(info->_sifields._sigchld._pid);
253 tinfo->_sifields._sigchld._uid
254 = tswap32(info->_sifields._sigchld._uid);
255 tinfo->_sifields._sigchld._status
256 = tswap32(info->_sifields._sigchld._status);
257 tinfo->_sifields._sigchld._utime
258 = tswapal(info->_sifields._sigchld._utime);
259 tinfo->_sifields._sigchld._stime
260 = tswapal(info->_sifields._sigchld._stime);
261 } else if (sig >= TARGET_SIGRTMIN32) {
262 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
263 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
264 tinfo->_sifields._rt._sigval.sival_ptr
265 = tswapal(info->_sifields._rt._sigval.sival_ptr);
266 }
267}
268
269
270void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
271{
272 host_to_target_siginfo_noswap(tinfo, info);
273 tswap_siginfo(tinfo, tinfo);
274}
275
276/* XXX: we support only POSIX RT signals are used. */
277/* XXX: find a solution for 64 bit (additional malloced data is needed) */
278void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
279{
280 info->si_signo = tswap32(tinfo->si_signo);
281 info->si_errno = tswap32(tinfo->si_errno);
282 info->si_code = tswap32(tinfo->si_code);
283 info->si_pid_sifields._kill.si_pid = tswap32(tinfo->_sifields._rt._pid);
284 info->si_uid_sifields._kill.si_uid = tswap32(tinfo->_sifields._rt._uid);
285 info->si_value_sifields._rt.si_sigval.sival_ptr =
286 (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
287}
288
289static int fatal_signal (int sig)
290{
291 switch (sig) {
292 case TARGET_SIGCHLD20:
293 case TARGET_SIGURG16:
294 case TARGET_SIGWINCH28:
295 /* Ignored by default. */
296 return 0;
297 case TARGET_SIGCONT19:
298 case TARGET_SIGSTOP17:
299 case TARGET_SIGTSTP18:
300 case TARGET_SIGTTIN21:
301 case TARGET_SIGTTOU22:
302 /* Job control signals. */
303 return 0;
304 default:
305 return 1;
306 }
307}
308
309/* returns 1 if given signal should dump core if not handled */
310static int core_dump_signal(int sig)
311{
312 switch (sig) {
313 case TARGET_SIGABRT6:
314 case TARGET_SIGFPE8:
315 case TARGET_SIGILL4:
316 case TARGET_SIGQUIT3:
317 case TARGET_SIGSEGV11:
318 case TARGET_SIGTRAP5:
319 case TARGET_SIGBUS10:
320 return (1);
321 default:
322 return (0);
323 }
324}
325
326void signal_init(void)
327{
328 struct sigaction act;
329 struct sigaction oact;
330 int i, j;
331 int host_sig;
332
333 /* generate signal conversion tables */
334 for(i = 1; i < _NSIG65; i++) {
335 if (host_to_target_signal_table[i] == 0)
336 host_to_target_signal_table[i] = i;
337 }
338 for(i = 1; i < _NSIG65; i++) {
339 j = host_to_target_signal_table[i];
340 target_to_host_signal_table[j] = i;
341 }
342
343 /* set all host signal handlers. ALL signals are blocked during
344 the handlers to serialize them. */
345 memset(sigact_table, 0, sizeof(sigact_table));
346
347 sigfillset(&act.sa_mask);
348 act.sa_flags = SA_SIGINFO4;
349 act.sa_sigaction__sigaction_handler.sa_sigaction = host_signal_handler;
350 for(i = 1; i <= TARGET_NSIG64; i++) {
351 host_sig = target_to_host_signal(i);
352 sigaction(host_sig, NULL((void*)0), &oact);
353 if (oact.sa_sigaction__sigaction_handler.sa_sigaction == (void *)SIG_IGN((__sighandler_t) 1)) {
354 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN((abi_long)1);
355 } else if (oact.sa_sigaction__sigaction_handler.sa_sigaction == (void *)SIG_DFL((__sighandler_t) 0)) {
356 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL((abi_long)0);
357 }
358 /* If there's already a handler installed then something has
359 gone horribly wrong, so don't even try to handle that case. */
360 /* Install some handlers for our own use. We need at least
361 SIGSEGV and SIGBUS, to detect exceptions. We can not just
362 trap all signals because it affects syscall interrupt
363 behavior. But do trap all default-fatal signals. */
364 if (fatal_signal (i))
365 sigaction(host_sig, &act, NULL((void*)0));
366 }
367}
368
369/* signal queue handling */
370
371static inline struct sigqueue *alloc_sigqueue(CPUArchStatestruct CPUSPARCState *env)
372{
373 TaskState *ts = env->opaque;
374 struct sigqueue *q = ts->first_free;
375 if (!q)
376 return NULL((void*)0);
377 ts->first_free = q->next;
378 return q;
379}
380
381static inline void free_sigqueue(CPUArchStatestruct CPUSPARCState *env, struct sigqueue *q)
382{
383 TaskState *ts = env->opaque;
384 q->next = ts->first_free;
385 ts->first_free = q;
386}
387
388/* abort execution with signal */
389static void QEMU_NORETURN__attribute__ ((__noreturn__)) force_sig(int target_sig)
390{
391 CPUArchStatestruct CPUSPARCState *env = thread_cpu->env_ptr;
392 TaskState *ts = (TaskState *)env->opaque;
393 int host_sig, core_dumped = 0;
394 struct sigaction act;
395 host_sig = target_to_host_signal(target_sig);
396 gdb_signalled(env, target_sig);
397
398 /* dump core if supported by target binary format */
399 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL((void*)0))) {
400 stop_all_tasks();
401 core_dumped =
402 ((*ts->bprm->core_dump)(target_sig, env) == 0);
403 }
404 if (core_dumped) {
405 /* we already dumped the core of target process, we don't want
406 * a coredump of qemu itself */
407 struct rlimit nodump;
408 getrlimit(RLIMIT_CORERLIMIT_CORE, &nodump);
409 nodump.rlim_cur=0;
410 setrlimit(RLIMIT_CORERLIMIT_CORE, &nodump);
411 (void) fprintf(stderrstderr, "qemu: uncaught target signal %d (%s) - %s\n",
412 target_sig, strsignal(host_sig), "core dumped" );
413 }
414
415 /* The proper exit code for dying from an uncaught signal is
416 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
417 * a negative value. To get the proper exit code we need to
418 * actually die from an uncaught signal. Here the default signal
419 * handler is installed, we send ourself a signal and we wait for
420 * it to arrive. */
421 sigfillset(&act.sa_mask);
422 act.sa_handler__sigaction_handler.sa_handler = SIG_DFL((__sighandler_t) 0);
423 sigaction(host_sig, &act, NULL((void*)0));
424
425 /* For some reason raise(host_sig) doesn't send the signal when
426 * statically linked on x86-64. */
427 kill(getpid(), host_sig);
428
429 /* Make sure the signal isn't masked (just reuse the mask inside
430 of act) */
431 sigdelset(&act.sa_mask, host_sig);
432 sigsuspend(&act.sa_mask);
433
434 /* unreachable */
435 abort();
436}
437
438/* queue a signal so that it will be send to the virtual CPU as soon
439 as possible */
440int queue_signal(CPUArchStatestruct CPUSPARCState *env, int sig, target_siginfo_t *info)
441{
442 TaskState *ts = env->opaque;
443 struct emulated_sigtable *k;
444 struct sigqueue *q, **pq;
445 abi_ulong handler;
446 int queue;
447
448#if defined(DEBUG_SIGNAL)
449 fprintf(stderrstderr, "queue_signal: sig=%d\n",
450 sig);
451#endif
452 k = &ts->sigtab[sig - 1];
453 queue = gdb_queuesig ();
454 handler = sigact_table[sig - 1]._sa_handler;
455 if (!queue && handler == TARGET_SIG_DFL((abi_long)0)) {
456 if (sig == TARGET_SIGTSTP18 || sig == TARGET_SIGTTIN21 || sig == TARGET_SIGTTOU22) {
457 kill(getpid(),SIGSTOP19);
458 return 0;
459 } else
460 /* default handler : ignore some signal. The other are fatal */
461 if (sig != TARGET_SIGCHLD20 &&
462 sig != TARGET_SIGURG16 &&
463 sig != TARGET_SIGWINCH28 &&
464 sig != TARGET_SIGCONT19) {
465 force_sig(sig);
466 } else {
467 return 0; /* indicate ignored */
468 }
469 } else if (!queue && handler == TARGET_SIG_IGN((abi_long)1)) {
470 /* ignore signal */
471 return 0;
472 } else if (!queue && handler == TARGET_SIG_ERR((abi_long)-1)) {
473 force_sig(sig);
474 } else {
475 pq = &k->first;
476 if (sig < TARGET_SIGRTMIN32) {
477 /* if non real time signal, we queue exactly one signal */
478 if (!k->pending)
479 q = &k->info;
480 else
481 return 0;
482 } else {
483 if (!k->pending) {
484 /* first signal */
485 q = &k->info;
486 } else {
487 q = alloc_sigqueue(env);
488 if (!q)
489 return -EAGAIN11;
490 while (*pq != NULL((void*)0))
491 pq = &(*pq)->next;
492 }
493 }
494 *pq = q;
495 q->info = *info;
496 q->next = NULL((void*)0);
497 k->pending = 1;
498 /* signal that a new signal is pending */
499 ts->signal_pending = 1;
500 return 1; /* indicates that the signal was queued */
501 }
502}
503
504static void host_signal_handler(int host_signum, siginfo_t *info,
505 void *puc)
506{
507 CPUArchStatestruct CPUSPARCState *env = thread_cpu->env_ptr;
508 int sig;
509 target_siginfo_t tinfo;
510
511 /* the CPU emulator uses some host signals to detect exceptions,
512 we forward to it some signals */
513 if ((host_signum == SIGSEGV11 || host_signum == SIGBUS7)
514 && info->si_code > 0) {
515 if (cpu_signal_handlercpu_sparc_signal_handler(host_signum, info, puc))
516 return;
517 }
518
519 /* get target signal number */
520 sig = host_to_target_signal(host_signum);
521 if (sig < 1 || sig > TARGET_NSIG64)
522 return;
523#if defined(DEBUG_SIGNAL)
524 fprintf(stderrstderr, "qemu: got signal %d\n", sig);
525#endif
526 host_to_target_siginfo_noswap(&tinfo, info);
527 if (queue_signal(env, sig, &tinfo) == 1) {
528 /* interrupt the virtual CPU as soon as possible */
529 cpu_exit(thread_cpu);
530 }
531}
532
533/* do_sigaltstack() returns target values and errnos. */
534/* compare linux/kernel/signal.c:do_sigaltstack() */
535abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
536{
537 int ret;
538 struct target_sigaltstack oss;
539
540 /* XXX: test errors */
541 if(uoss_addr)
542 {
543 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp)(__builtin_choose_expr(sizeof(*(&oss.ss_sp)) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&oss.ss_sp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_sp)) == 8, stq_be_p
, abort)))) ((&oss.ss_sp), (target_sigaltstack_used.ss_sp
)), 0)
;
544 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size)(__builtin_choose_expr(sizeof(*(&oss.ss_size)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&oss.ss_size)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_size)) == 8, stq_be_p
, abort)))) ((&oss.ss_size), (target_sigaltstack_used.ss_size
)), 0)
;
545 __put_user(sas_ss_flags(sp), &oss.ss_flags)(__builtin_choose_expr(sizeof(*(&oss.ss_flags)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&oss.ss_flags)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&oss.ss_flags)) == 8, stq_be_p
, abort)))) ((&oss.ss_flags), (sas_ss_flags(sp))), 0)
;
546 }
547
548 if(uss_addr)
549 {
550 struct target_sigaltstack *uss;
551 struct target_sigaltstack ss;
552
553 ret = -TARGET_EFAULT14;
554 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)(uss = lock_user(0, uss_addr, sizeof(*uss), 1))
555 || __get_user(ss.ss_sp, &uss->ss_sp)((ss.ss_sp) = (typeof(*&uss->ss_sp))( __builtin_choose_expr
(sizeof(*(&uss->ss_sp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&uss->ss_sp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_sp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_sp)) == 8, ldq_be_p, abort)))) (&
uss->ss_sp)), 0)
556 || __get_user(ss.ss_size, &uss->ss_size)((ss.ss_size) = (typeof(*&uss->ss_size))( __builtin_choose_expr
(sizeof(*(&uss->ss_size)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&uss->ss_size)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_size)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_size)) == 8, ldq_be_p, abort)))) (&
uss->ss_size)), 0)
557 || __get_user(ss.ss_flags, &uss->ss_flags)((ss.ss_flags) = (typeof(*&uss->ss_flags))( __builtin_choose_expr
(sizeof(*(&uss->ss_flags)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&uss->ss_flags)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_flags)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&uss->ss_flags)) == 8, ldq_be_p, abort)))) (
&uss->ss_flags)), 0)
)
558 goto out;
559 unlock_user_struct(uss, uss_addr, 0)unlock_user(uss, uss_addr, (0) ? sizeof(*uss) : 0);
560
561 ret = -TARGET_EPERM1;
562 if (on_sig_stack(sp))
563 goto out;
564
565 ret = -TARGET_EINVAL22;
566 if (ss.ss_flags != TARGET_SS_DISABLE2
567 && ss.ss_flags != TARGET_SS_ONSTACK1
568 && ss.ss_flags != 0)
569 goto out;
570
571 if (ss.ss_flags == TARGET_SS_DISABLE2) {
572 ss.ss_size = 0;
573 ss.ss_sp = 0;
574 } else {
575 ret = -TARGET_ENOMEM12;
576 if (ss.ss_size < MINSIGSTKSZ2048)
577 goto out;
578 }
579
580 target_sigaltstack_used.ss_sp = ss.ss_sp;
581 target_sigaltstack_used.ss_size = ss.ss_size;
582 }
583
584 if (uoss_addr) {
585 ret = -TARGET_EFAULT14;
586 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
587 goto out;
588 }
589
590 ret = 0;
591out:
592 return ret;
593}
594
595/* do_sigaction() return host values and errnos */
596int do_sigaction(int sig, const struct target_sigaction *act,
597 struct target_sigaction *oact)
598{
599 struct target_sigaction *k;
600 struct sigaction act1;
601 int host_sig;
602 int ret = 0;
603
604 if (sig < 1 || sig > TARGET_NSIG64 || sig == TARGET_SIGKILL9 || sig == TARGET_SIGSTOP17)
605 return -EINVAL22;
606 k = &sigact_table[sig - 1];
607#if defined(DEBUG_SIGNAL)
608 fprintf(stderrstderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
609 sig, act, oact);
610#endif
611 if (oact) {
612 __put_user(k->_sa_handler, &oact->_sa_handler)(__builtin_choose_expr(sizeof(*(&oact->_sa_handler)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&oact->_sa_handler
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&oact->
_sa_handler)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&oact->_sa_handler)) == 8, stq_be_p, abort)))) ((&
oact->_sa_handler), (k->_sa_handler)), 0)
;
613 __put_user(k->sa_flags, &oact->sa_flags)(__builtin_choose_expr(sizeof(*(&oact->sa_flags)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&oact->sa_flags
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&oact->
sa_flags)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
oact->sa_flags)) == 8, stq_be_p, abort)))) ((&oact->
sa_flags), (k->sa_flags)), 0)
;
614#if !defined(TARGET_MIPS)
615 __put_user(k->sa_restorer, &oact->sa_restorer)(__builtin_choose_expr(sizeof(*(&oact->sa_restorer)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&oact->sa_restorer
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&oact->
sa_restorer)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&oact->sa_restorer)) == 8, stq_be_p, abort)))) ((&
oact->sa_restorer), (k->sa_restorer)), 0)
;
616#endif
617 /* Not swapped. */
618 oact->sa_mask = k->sa_mask;
619 }
620 if (act) {
621 /* FIXME: This is not threadsafe. */
622 __get_user(k->_sa_handler, &act->_sa_handler)((k->_sa_handler) = (typeof(*&act->_sa_handler))( __builtin_choose_expr
(sizeof(*(&act->_sa_handler)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&act->_sa_handler)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&act->_sa_handler)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&act->_sa_handler)) == 8, ldq_be_p, abort)))
) (&act->_sa_handler)), 0)
;
623 __get_user(k->sa_flags, &act->sa_flags)((k->sa_flags) = (typeof(*&act->sa_flags))( __builtin_choose_expr
(sizeof(*(&act->sa_flags)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&act->sa_flags)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&act->sa_flags)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&act->sa_flags)) == 8, ldq_be_p, abort)))) (
&act->sa_flags)), 0)
;
624#if !defined(TARGET_MIPS)
625 __get_user(k->sa_restorer, &act->sa_restorer)((k->sa_restorer) = (typeof(*&act->sa_restorer))( __builtin_choose_expr
(sizeof(*(&act->sa_restorer)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&act->sa_restorer)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&act->sa_restorer)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&act->sa_restorer)) == 8, ldq_be_p, abort)))
) (&act->sa_restorer)), 0)
;
626#endif
627 /* To be swapped in target_to_host_sigset. */
628 k->sa_mask = act->sa_mask;
629
630 /* we update the host linux signal state */
631 host_sig = target_to_host_signal(sig);
632 if (host_sig != SIGSEGV11 && host_sig != SIGBUS7) {
633 sigfillset(&act1.sa_mask);
634 act1.sa_flags = SA_SIGINFO4;
635 if (k->sa_flags & TARGET_SA_RESTART2u)
636 act1.sa_flags |= SA_RESTART0x10000000;
637 /* NOTE: it is important to update the host kernel signal
638 ignore state to avoid getting unexpected interrupted
639 syscalls */
640 if (k->_sa_handler == TARGET_SIG_IGN((abi_long)1)) {
641 act1.sa_sigaction__sigaction_handler.sa_sigaction = (void *)SIG_IGN((__sighandler_t) 1);
642 } else if (k->_sa_handler == TARGET_SIG_DFL((abi_long)0)) {
643 if (fatal_signal (sig))
644 act1.sa_sigaction__sigaction_handler.sa_sigaction = host_signal_handler;
645 else
646 act1.sa_sigaction__sigaction_handler.sa_sigaction = (void *)SIG_DFL((__sighandler_t) 0);
647 } else {
648 act1.sa_sigaction__sigaction_handler.sa_sigaction = host_signal_handler;
649 }
650 ret = sigaction(host_sig, &act1, NULL((void*)0));
651 }
652 }
653 return ret;
654}
655
656static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
657 const target_siginfo_t *info)
658{
659 tswap_siginfo(tinfo, info);
660 return 0;
661}
662
663static inline int current_exec_domain_sig(int sig)
664{
665 return /* current->exec_domain && current->exec_domain->signal_invmap
666 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
667}
668
669#if defined(TARGET_I386) && TARGET_ABI_BITS64 == 32
670
671/* from the Linux kernel */
672
673struct target_fpreg {
674 uint16_t significand[4];
675 uint16_t exponent;
676};
677
678struct target_fpxreg {
679 uint16_t significand[4];
680 uint16_t exponent;
681 uint16_t padding[3];
682};
683
684struct target_xmmreg {
685 abi_ulong element[4];
686};
687
688struct target_fpstate {
689 /* Regular FPU environment */
690 abi_ulong cw;
691 abi_ulong sw;
692 abi_ulong tag;
693 abi_ulong ipoff;
694 abi_ulong cssel;
695 abi_ulong dataoff;
696 abi_ulong datasel;
697 struct target_fpreg _st[8];
698 uint16_t status;
699 uint16_t magic; /* 0xffff = regular FPU data only */
700
701 /* FXSR FPU environment */
702 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
703 abi_ulong mxcsr;
704 abi_ulong reserved;
705 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
706 struct target_xmmreg _xmm[8];
707 abi_ulong padding[56];
708};
709
710#define X86_FXSR_MAGIC 0x0000
711
712struct target_sigcontext {
713 uint16_t gs, __gsh;
714 uint16_t fs, __fsh;
715 uint16_t es, __esh;
716 uint16_t ds, __dsh;
717 abi_ulong edi;
718 abi_ulong esi;
719 abi_ulong ebp;
720 abi_ulong esp;
721 abi_ulong ebx;
722 abi_ulong edx;
723 abi_ulong ecx;
724 abi_ulong eax;
725 abi_ulong trapno;
726 abi_ulong err;
727 abi_ulong eip;
728 uint16_t cs, __csh;
729 abi_ulong eflags;
730 abi_ulong esp_at_signal;
731 uint16_t ss, __ssh;
732 abi_ulong fpstate; /* pointer */
733 abi_ulong oldmask;
734 abi_ulong cr2;
735};
736
737struct target_ucontext {
738 abi_ulong tuc_flags;
739 abi_ulong tuc_link;
740 target_stack_t tuc_stack;
741 struct target_sigcontext tuc_mcontext;
742 target_sigset_t tuc_sigmask; /* mask last for extensibility */
743};
744
745struct sigframe
746{
747 abi_ulong pretcode;
748 int sig;
749 struct target_sigcontext sc;
750 struct target_fpstate fpstate;
751 abi_ulong extramask[TARGET_NSIG_WORDS(64 / 64)-1];
752 char retcode[8];
753};
754
755struct rt_sigframe
756{
757 abi_ulong pretcode;
758 int sig;
759 abi_ulong pinfo;
760 abi_ulong puc;
761 struct target_siginfo info;
762 struct target_ucontext uc;
763 struct target_fpstate fpstate;
764 char retcode[8];
765};
766
767/*
768 * Set up a signal frame.
769 */
770
771/* XXX: save x87 state */
772static int
773setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
774 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
775{
776 int err = 0;
777 uint16_t magic;
778
779 /* already locked in setup_frame() */
780 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->gs
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->gs)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->gs)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->gs)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->gs), (env->segs[R_GS].selector
)), 0)
;
781 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->fs
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->fs)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->fs)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->fs)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->fs), (env->segs[R_FS].selector
)), 0)
;
782 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->es
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->es)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->es)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->es)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->es), (env->segs[R_ES].selector
)), 0)
;
783 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->ds
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->ds)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->ds)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->ds)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->ds), (env->segs[R_DS].selector
)), 0)
;
784 err |= __put_user(env->regs[R_EDI], &sc->edi)(__builtin_choose_expr(sizeof(*(&sc->edi)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->edi)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->edi)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->edi)) == 8, stq_be_p
, abort)))) ((&sc->edi), (env->regs[R_EDI])), 0)
;
785 err |= __put_user(env->regs[R_ESI], &sc->esi)(__builtin_choose_expr(sizeof(*(&sc->esi)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->esi)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->esi)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->esi)) == 8, stq_be_p
, abort)))) ((&sc->esi), (env->regs[R_ESI])), 0)
;
786 err |= __put_user(env->regs[R_EBP], &sc->ebp)(__builtin_choose_expr(sizeof(*(&sc->ebp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->ebp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->ebp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->ebp)) == 8, stq_be_p
, abort)))) ((&sc->ebp), (env->regs[R_EBP])), 0)
;
787 err |= __put_user(env->regs[R_ESP], &sc->esp)(__builtin_choose_expr(sizeof(*(&sc->esp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->esp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->esp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->esp)) == 8, stq_be_p
, abort)))) ((&sc->esp), (env->regs[R_ESP])), 0)
;
788 err |= __put_user(env->regs[R_EBX], &sc->ebx)(__builtin_choose_expr(sizeof(*(&sc->ebx)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->ebx)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->ebx)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->ebx)) == 8, stq_be_p
, abort)))) ((&sc->ebx), (env->regs[R_EBX])), 0)
;
789 err |= __put_user(env->regs[R_EDX], &sc->edx)(__builtin_choose_expr(sizeof(*(&sc->edx)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->edx)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->edx)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->edx)) == 8, stq_be_p
, abort)))) ((&sc->edx), (env->regs[R_EDX])), 0)
;
790 err |= __put_user(env->regs[R_ECX], &sc->ecx)(__builtin_choose_expr(sizeof(*(&sc->ecx)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->ecx)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->ecx)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->ecx)) == 8, stq_be_p
, abort)))) ((&sc->ecx), (env->regs[R_ECX])), 0)
;
791 err |= __put_user(env->regs[R_EAX], &sc->eax)(__builtin_choose_expr(sizeof(*(&sc->eax)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->eax)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->eax)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->eax)) == 8, stq_be_p
, abort)))) ((&sc->eax), (env->regs[R_EAX])), 0)
;
792 err |= __put_user(env->exception_index, &sc->trapno)(__builtin_choose_expr(sizeof(*(&sc->trapno)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->trapno)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->trapno)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->trapno)) == 8, stq_be_p
, abort)))) ((&sc->trapno), (env->exception_index))
, 0)
;
793 err |= __put_user(env->error_code, &sc->err)(__builtin_choose_expr(sizeof(*(&sc->err)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->err)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->err)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->err)) == 8, stq_be_p
, abort)))) ((&sc->err), (env->error_code)), 0)
;
794 err |= __put_user(env->eip, &sc->eip)(__builtin_choose_expr(sizeof(*(&sc->eip)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->eip)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->eip)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->eip)) == 8, stq_be_p
, abort)))) ((&sc->eip), (env->eip)), 0)
;
795 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->cs
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->cs)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->cs)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->cs)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->cs), (env->segs[R_CS].selector
)), 0)
;
796 err |= __put_user(env->eflags, &sc->eflags)(__builtin_choose_expr(sizeof(*(&sc->eflags)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->eflags)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->eflags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->eflags)) == 8, stq_be_p
, abort)))) ((&sc->eflags), (env->eflags)), 0)
;
797 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal)(__builtin_choose_expr(sizeof(*(&sc->esp_at_signal)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->esp_at_signal
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
esp_at_signal)) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&sc->esp_at_signal)) == 8, stq_be_p, abort)))) ((&
sc->esp_at_signal), (env->regs[R_ESP])), 0)
;
798 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss)(__builtin_choose_expr(sizeof(*((unsigned int *)&sc->ss
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned int *
)&sc->ss)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((unsigned int *)&sc->ss)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((unsigned int *)&sc->ss)) == 8, stq_be_p, abort
)))) (((unsigned int *)&sc->ss), (env->segs[R_SS].selector
)), 0)
;
799
800 cpu_x86_fsave(env, fpstate_addr, 1);
801 fpstate->status = fpstate->sw;
802 magic = 0xffff;
803 err |= __put_user(magic, &fpstate->magic)(__builtin_choose_expr(sizeof(*(&fpstate->magic)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&fpstate->magic
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&fpstate
->magic)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
fpstate->magic)) == 8, stq_be_p, abort)))) ((&fpstate->
magic), (magic)), 0)
;
804 err |= __put_user(fpstate_addr, &sc->fpstate)(__builtin_choose_expr(sizeof(*(&sc->fpstate)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->fpstate)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->fpstate)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->fpstate)) == 8, stq_be_p
, abort)))) ((&sc->fpstate), (fpstate_addr)), 0)
;
805
806 /* non-iBCS2 extensions.. */
807 err |= __put_user(mask, &sc->oldmask)(__builtin_choose_expr(sizeof(*(&sc->oldmask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 8, stq_be_p
, abort)))) ((&sc->oldmask), (mask)), 0)
;
808 err |= __put_user(env->cr[2], &sc->cr2)(__builtin_choose_expr(sizeof(*(&sc->cr2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->cr2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->cr2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->cr2)) == 8, stq_be_p
, abort)))) ((&sc->cr2), (env->cr[2])), 0)
;
809 return err;
810}
811
812/*
813 * Determine which stack to use..
814 */
815
816static inline abi_ulong
817get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
818{
819 unsigned long esp;
820
821 /* Default to using normal stack */
822 esp = env->regs[R_ESP];
823 /* This is the X/Open sanctioned signal stack switching. */
824 if (ka->sa_flags & TARGET_SA_ONSTACK1u) {
825 if (sas_ss_flags(esp) == 0)
826 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
827 }
828
829 /* This is the legacy signal stack switching. */
830 else
831 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
832 !(ka->sa_flags & TARGET_SA_RESTORER) &&
833 ka->sa_restorer) {
834 esp = (unsigned long) ka->sa_restorer;
835 }
836 return (esp - frame_size) & -8ul;
837}
838
839/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
840static void setup_frame(int sig, struct target_sigaction *ka,
841 target_sigset_t *set, CPUX86State *env)
842{
843 abi_ulong frame_addr;
844 struct sigframe *frame;
845 int i, err = 0;
846
847 frame_addr = get_sigframe(ka, env, sizeof(*frame));
848
849 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
850 goto give_sigsegv;
851
852 err |= __put_user(current_exec_domain_sig(sig),(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (current_exec_domain_sig(sig
))), 0)
853 &frame->sig)(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (current_exec_domain_sig(sig
))), 0)
;
854 if (err)
855 goto give_sigsegv;
856
857 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
858 frame_addr + offsetof(struct sigframe, fpstate)__builtin_offsetof(struct sigframe, fpstate));
859 if (err)
860 goto give_sigsegv;
861
862 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
863 if (__put_user(set->sig[i], &frame->extramask[i - 1])(__builtin_choose_expr(sizeof(*(&frame->extramask[i - 1
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
extramask[i - 1])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i - 1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, stq_be_p, abort
)))) ((&frame->extramask[i - 1]), (set->sig[i])), 0
)
)
864 goto give_sigsegv;
865 }
866
867 /* Set up to return from userspace. If provided, use a stub
868 already in userspace. */
869 if (ka->sa_flags & TARGET_SA_RESTORER) {
870 err |= __put_user(ka->sa_restorer, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (ka->sa_restorer)), 0)
;
871 } else {
872 uint16_t val16;
873 abi_ulong retcode_addr;
874 retcode_addr = frame_addr + offsetof(struct sigframe, retcode)__builtin_offsetof(struct sigframe, retcode);
875 err |= __put_user(retcode_addr, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (retcode_addr)), 0)
;
876 /* This is popl %eax ; movl $,%eax ; int $0x80 */
877 val16 = 0xb858;
878 err |= __put_user(val16, (uint16_t *)(frame->retcode+0))(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+0))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *
)(frame->retcode+0))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode+0))) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+0))) == 8, stq_be_p, abort)))) (((uint16_t *)(frame->retcode
+0)), (val16)), 0)
;
879 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2))(__builtin_choose_expr(sizeof(*((int *)(frame->retcode+2))
) == 1, stb_p, __builtin_choose_expr(sizeof(*((int *)(frame->
retcode+2))) == 2, stw_be_p, __builtin_choose_expr(sizeof(*((
int *)(frame->retcode+2))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((int *)(frame->retcode+2))) == 8, stq_be_p, abort
)))) (((int *)(frame->retcode+2)), (216)), 0)
;
880 val16 = 0x80cd;
881 err |= __put_user(val16, (uint16_t *)(frame->retcode+6))(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+6))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *
)(frame->retcode+6))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode+6))) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+6))) == 8, stq_be_p, abort)))) (((uint16_t *)(frame->retcode
+6)), (val16)), 0)
;
882 }
883
884 if (err)
885 goto give_sigsegv;
886
887 /* Set up registers for signal handler */
888 env->regs[R_ESP] = frame_addr;
889 env->eip = ka->_sa_handler;
890
891 cpu_x86_load_seg(env, R_DS, __USER_DS);
892 cpu_x86_load_seg(env, R_ES, __USER_DS);
893 cpu_x86_load_seg(env, R_SS, __USER_DS);
894 cpu_x86_load_seg(env, R_CS, __USER_CS);
895 env->eflags &= ~TF_MASK;
896
897 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
898
899 return;
900
901give_sigsegv:
902 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
903 if (sig == TARGET_SIGSEGV11)
904 ka->_sa_handler = TARGET_SIG_DFL((abi_long)0);
905 force_sig(TARGET_SIGSEGV11 /* , current */);
906}
907
908/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
909static void setup_rt_frame(int sig, struct target_sigaction *ka,
910 target_siginfo_t *info,
911 target_sigset_t *set, CPUX86State *env)
912{
913 abi_ulong frame_addr, addr;
914 struct rt_sigframe *frame;
915 int i, err = 0;
916
917 frame_addr = get_sigframe(ka, env, sizeof(*frame));
918
919 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
920 goto give_sigsegv;
921
922 err |= __put_user(current_exec_domain_sig(sig),(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (current_exec_domain_sig(sig
))), 0)
923 &frame->sig)(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (current_exec_domain_sig(sig
))), 0)
;
924 addr = frame_addr + offsetof(struct rt_sigframe, info)__builtin_offsetof(struct rt_sigframe, info);
925 err |= __put_user(addr, &frame->pinfo)(__builtin_choose_expr(sizeof(*(&frame->pinfo)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->pinfo)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&frame->pinfo
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&frame->
pinfo)) == 8, stq_be_p, abort)))) ((&frame->pinfo), (addr
)), 0)
;
926 addr = frame_addr + offsetof(struct rt_sigframe, uc)__builtin_offsetof(struct rt_sigframe, uc);
927 err |= __put_user(addr, &frame->puc)(__builtin_choose_expr(sizeof(*(&frame->puc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 8, stq_be_p
, abort)))) ((&frame->puc), (addr)), 0)
;
928 err |= copy_siginfo_to_user(&frame->info, info);
929 if (err)
930 goto give_sigsegv;
931
932 /* Create the ucontext. */
933 err |= __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
934 err |= __put_user(0, &frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&frame->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
frame->uc.tuc_link), (0)), 0)
;
935 err |= __put_user(target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
936 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
937 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env)))), 0)
938 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env)))), 0)
;
939 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
940 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
941 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
942 env, set->sig[0],
943 frame_addr + offsetof(struct rt_sigframe, fpstate)__builtin_offsetof(struct rt_sigframe, fpstate));
944 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
945 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
)
946 goto give_sigsegv;
947 }
948
949 /* Set up to return from userspace. If provided, use a stub
950 already in userspace. */
951 if (ka->sa_flags & TARGET_SA_RESTORER) {
952 err |= __put_user(ka->sa_restorer, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (ka->sa_restorer)), 0)
;
953 } else {
954 uint16_t val16;
955 addr = frame_addr + offsetof(struct rt_sigframe, retcode)__builtin_offsetof(struct rt_sigframe, retcode);
956 err |= __put_user(addr, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (addr)), 0)
;
957 /* This is movl $,%eax ; int $0x80 */
958 err |= __put_user(0xb8, (char *)(frame->retcode+0))(__builtin_choose_expr(sizeof(*((char *)(frame->retcode+0)
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((char *)(frame
->retcode+0))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((char *)(frame->retcode+0))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((char *)(frame->retcode+0))) == 8, stq_be_p, abort
)))) (((char *)(frame->retcode+0)), (0xb8)), 0)
;
959 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1))(__builtin_choose_expr(sizeof(*((int *)(frame->retcode+1))
) == 1, stb_p, __builtin_choose_expr(sizeof(*((int *)(frame->
retcode+1))) == 2, stw_be_p, __builtin_choose_expr(sizeof(*((
int *)(frame->retcode+1))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((int *)(frame->retcode+1))) == 8, stq_be_p, abort
)))) (((int *)(frame->retcode+1)), (101)), 0)
;
960 val16 = 0x80cd;
961 err |= __put_user(val16, (uint16_t *)(frame->retcode+5))(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+5))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *
)(frame->retcode+5))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode+5))) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
+5))) == 8, stq_be_p, abort)))) (((uint16_t *)(frame->retcode
+5)), (val16)), 0)
;
962 }
963
964 if (err)
965 goto give_sigsegv;
966
967 /* Set up registers for signal handler */
968 env->regs[R_ESP] = frame_addr;
969 env->eip = ka->_sa_handler;
970
971 cpu_x86_load_seg(env, R_DS, __USER_DS);
972 cpu_x86_load_seg(env, R_ES, __USER_DS);
973 cpu_x86_load_seg(env, R_SS, __USER_DS);
974 cpu_x86_load_seg(env, R_CS, __USER_CS);
975 env->eflags &= ~TF_MASK;
976
977 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
978
979 return;
980
981give_sigsegv:
982 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
983 if (sig == TARGET_SIGSEGV11)
984 ka->_sa_handler = TARGET_SIG_DFL((abi_long)0);
985 force_sig(TARGET_SIGSEGV11 /* , current */);
986}
987
988static int
989restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
990{
991 unsigned int err = 0;
992 abi_ulong fpstate_addr;
993 unsigned int tmpflags;
994
995 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
996 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
997 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
998 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
999
1000 env->regs[R_EDI] = tswapl(sc->edi)tswap64(sc->edi);
1001 env->regs[R_ESI] = tswapl(sc->esi)tswap64(sc->esi);
1002 env->regs[R_EBP] = tswapl(sc->ebp)tswap64(sc->ebp);
1003 env->regs[R_ESP] = tswapl(sc->esp)tswap64(sc->esp);
1004 env->regs[R_EBX] = tswapl(sc->ebx)tswap64(sc->ebx);
1005 env->regs[R_EDX] = tswapl(sc->edx)tswap64(sc->edx);
1006 env->regs[R_ECX] = tswapl(sc->ecx)tswap64(sc->ecx);
1007 env->eip = tswapl(sc->eip)tswap64(sc->eip);
1008
1009 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs)lduw_be_p(&sc->cs) | 3);
1010 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss)lduw_be_p(&sc->ss) | 3);
1011
1012 tmpflags = tswapl(sc->eflags)tswap64(sc->eflags);
1013 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1014 // regs->orig_eax = -1; /* disable syscall checks */
1015
1016 fpstate_addr = tswapl(sc->fpstate)tswap64(sc->fpstate);
1017 if (fpstate_addr != 0) {
1018 if (!access_ok(VERIFY_READ0, fpstate_addr,
1019 sizeof(struct target_fpstate)))
1020 goto badframe;
1021 cpu_x86_frstor(env, fpstate_addr, 1);
1022 }
1023
1024 *peax = tswapl(sc->eax)tswap64(sc->eax);
1025 return err;
1026badframe:
1027 return 1;
1028}
1029
1030long do_sigreturn(CPUX86State *env)
1031{
1032 struct sigframe *frame;
1033 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1034 target_sigset_t target_set;
1035 sigset_t set;
1036 int eax, i;
1037
1038#if defined(DEBUG_SIGNAL)
1039 fprintf(stderrstderr, "do_sigreturn\n");
1040#endif
1041 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
1042 goto badframe;
1043 /* set blocked signals */
1044 if (__get_user(target_set.sig[0], &frame->sc.oldmask)((target_set.sig[0]) = (typeof(*&frame->sc.oldmask))( __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 8, ldq_be_p, abort))
)) (&frame->sc.oldmask)), 0)
)
1045 goto badframe;
1046 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1047 if (__get_user(target_set.sig[i], &frame->extramask[i - 1])((target_set.sig[i]) = (typeof(*&frame->extramask[i - 1
]))( __builtin_choose_expr(sizeof(*(&frame->extramask[
i - 1])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
)
1048 goto badframe;
1049 }
1050
1051 target_to_host_sigset_internal(&set, &target_set);
1052 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
1053
1054 /* restore registers */
1055 if (restore_sigcontext(env, &frame->sc, &eax))
1056 goto badframe;
1057 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1058 return eax;
1059
1060badframe:
1061 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1062 force_sig(TARGET_SIGSEGV11);
1063 return 0;
1064}
1065
1066long do_rt_sigreturn(CPUX86State *env)
1067{
1068 abi_ulong frame_addr;
1069 struct rt_sigframe *frame;
1070 sigset_t set;
1071 int eax;
1072
1073 frame_addr = env->regs[R_ESP] - 4;
1074 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
1075 goto badframe;
1076 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1077 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
1078
1079 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1080 goto badframe;
1081
1082 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack)__builtin_offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1083 get_sp_from_cpustate(env)) == -EFAULT14)
1084 goto badframe;
1085
1086 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1087 return eax;
1088
1089badframe:
1090 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1091 force_sig(TARGET_SIGSEGV11);
1092 return 0;
1093}
1094
1095#elif defined(TARGET_AARCH64)
1096
1097struct target_sigcontext {
1098 uint64_t fault_address;
1099 /* AArch64 registers */
1100 uint64_t regs[31];
1101 uint64_t sp;
1102 uint64_t pc;
1103 uint64_t pstate;
1104 /* 4K reserved for FP/SIMD state and future expansion */
1105 char __reserved[4096] __attribute__((__aligned__(16)));
1106};
1107
1108struct target_ucontext {
1109 abi_ulong tuc_flags;
1110 abi_ulong tuc_link;
1111 target_stack_t tuc_stack;
1112 target_sigset_t tuc_sigmask;
1113 /* glibc uses a 1024-bit sigset_t */
1114 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1115 /* last for future expansion */
1116 struct target_sigcontext tuc_mcontext;
1117};
1118
1119/*
1120 * Header to be used at the beginning of structures extending the user
1121 * context. Such structures must be placed after the rt_sigframe on the stack
1122 * and be 16-byte aligned. The last structure must be a dummy one with the
1123 * magic and size set to 0.
1124 */
1125struct target_aarch64_ctx {
1126 uint32_t magic;
1127 uint32_t size;
1128};
1129
1130#define TARGET_FPSIMD_MAGIC 0x46508001
1131
1132struct target_fpsimd_context {
1133 struct target_aarch64_ctx head;
1134 uint32_t fpsr;
1135 uint32_t fpcr;
1136 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1137};
1138
1139/*
1140 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1141 * user space as it will change with the addition of new context. User space
1142 * should check the magic/size information.
1143 */
1144struct target_aux_context {
1145 struct target_fpsimd_context fpsimd;
1146 /* additional context to be added before "end" */
1147 struct target_aarch64_ctx end;
1148};
1149
1150struct target_rt_sigframe {
1151 struct target_siginfo info;
1152 struct target_ucontext uc;
1153 uint64_t fp;
1154 uint64_t lr;
1155 uint32_t tramp[2];
1156};
1157
1158static int target_setup_sigframe(struct target_rt_sigframe *sf,
1159 CPUARMState *env, target_sigset_t *set)
1160{
1161 int i;
1162 struct target_aux_context *aux =
1163 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1164
1165 /* set up the stack frame for unwinding */
1166 __put_user(env->xregs[29], &sf->fp)(__builtin_choose_expr(sizeof(*(&sf->fp)) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&sf->fp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sf->fp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sf->fp)) == 8, stq_be_p
, abort)))) ((&sf->fp), (env->xregs[29])), 0)
;
1167 __put_user(env->xregs[30], &sf->lr)(__builtin_choose_expr(sizeof(*(&sf->lr)) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&sf->lr)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sf->lr)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sf->lr)) == 8, stq_be_p
, abort)))) ((&sf->lr), (env->xregs[30])), 0)
;
1168
1169 for (i = 0; i < 31; i++) {
1170 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i])(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.regs
[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->
uc.tuc_mcontext.regs[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.regs[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.
regs[i])) == 8, stq_be_p, abort)))) ((&sf->uc.tuc_mcontext
.regs[i]), (env->xregs[i])), 0)
;
1171 }
1172 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp)(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->uc
.tuc_mcontext.sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&sf->uc.tuc_mcontext.sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.sp)) == 8, stq_be_p, abort
)))) ((&sf->uc.tuc_mcontext.sp), (env->xregs[31])),
0)
;
1173 __put_user(env->pc, &sf->uc.tuc_mcontext.pc)(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.pc
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->uc
.tuc_mcontext.pc)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&sf->uc.tuc_mcontext.pc)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pc)) == 8, stq_be_p, abort
)))) ((&sf->uc.tuc_mcontext.pc), (env->pc)), 0)
;
1174 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate)(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.pstate
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->uc
.tuc_mcontext.pstate)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&sf->uc.tuc_mcontext.pstate)) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.pstate
)) == 8, stq_be_p, abort)))) ((&sf->uc.tuc_mcontext.pstate
), (pstate_read(env))), 0)
;
1175
1176 __put_user(/*current->thread.fault_address*/ 0,(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.fault_address
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->uc
.tuc_mcontext.fault_address)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.fault_address)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.
fault_address)) == 8, stq_be_p, abort)))) ((&sf->uc.tuc_mcontext
.fault_address), (0)), 0)
1177 &sf->uc.tuc_mcontext.fault_address)(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.fault_address
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->uc
.tuc_mcontext.fault_address)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.fault_address)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.
fault_address)) == 8, stq_be_p, abort)))) ((&sf->uc.tuc_mcontext
.fault_address), (0)), 0)
;
1178
1179 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1180 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&sf->uc.tuc_sigmask.sig
[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sf->
uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_sigmask.sig[i])) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*(&sf->uc.tuc_sigmask.sig
[i])) == 8, stq_be_p, abort)))) ((&sf->uc.tuc_sigmask.
sig[i]), (set->sig[i])), 0)
;
1181 }
1182
1183 for (i = 0; i < 32; i++) {
1184#ifdef TARGET_WORDS_BIGENDIAN1
1185 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1])(__builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2 + 1])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux
->fpsimd.vregs[i * 2 + 1])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.vregs[i * 2 + 1])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2 + 1])) == 8, stq_be_p, abort)))) ((&aux->fpsimd.vregs
[i * 2 + 1]), (env->vfp.regs[i * 2])), 0)
;
1186 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2])(__builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux->
fpsimd.vregs[i * 2])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&aux->fpsimd.vregs[i * 2])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.vregs[i * 2])) == 8, stq_be_p, abort
)))) ((&aux->fpsimd.vregs[i * 2]), (env->vfp.regs[i
* 2 + 1])), 0)
;
1187#else
1188 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2])(__builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux->
fpsimd.vregs[i * 2])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&aux->fpsimd.vregs[i * 2])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.vregs[i * 2])) == 8, stq_be_p, abort
)))) ((&aux->fpsimd.vregs[i * 2]), (env->vfp.regs[i
* 2])), 0)
;
1189 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1])(__builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2 + 1])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux
->fpsimd.vregs[i * 2 + 1])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.vregs[i * 2 + 1])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs[i *
2 + 1])) == 8, stq_be_p, abort)))) ((&aux->fpsimd.vregs
[i * 2 + 1]), (env->vfp.regs[i * 2 + 1])), 0)
;
1190#endif
1191 }
1192 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr)(__builtin_choose_expr(sizeof(*(&aux->fpsimd.fpsr)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&aux->fpsimd
.fpsr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&aux
->fpsimd.fpsr)) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&aux->fpsimd.fpsr)) == 8, stq_be_p, abort)))) ((&
aux->fpsimd.fpsr), (vfp_get_fpsr(env))), 0)
;
1193 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr)(__builtin_choose_expr(sizeof(*(&aux->fpsimd.fpcr)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&aux->fpsimd
.fpcr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&aux
->fpsimd.fpcr)) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&aux->fpsimd.fpcr)) == 8, stq_be_p, abort)))) ((&
aux->fpsimd.fpcr), (vfp_get_fpcr(env))), 0)
;
1194 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic)(__builtin_choose_expr(sizeof(*(&aux->fpsimd.head.magic
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux->fpsimd
.head.magic)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(
&aux->fpsimd.head.magic)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.magic)) == 8, stq_be_p, abort
)))) ((&aux->fpsimd.head.magic), (TARGET_FPSIMD_MAGIC)
), 0)
;
1195 __put_user(sizeof(struct target_fpsimd_context),(__builtin_choose_expr(sizeof(*(&aux->fpsimd.head.size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux->fpsimd
.head.size)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
aux->fpsimd.head.size)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 8, stq_be_p, abort
)))) ((&aux->fpsimd.head.size), (sizeof(struct target_fpsimd_context
))), 0)
1196 &aux->fpsimd.head.size)(__builtin_choose_expr(sizeof(*(&aux->fpsimd.head.size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&aux->fpsimd
.head.size)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
aux->fpsimd.head.size)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 8, stq_be_p, abort
)))) ((&aux->fpsimd.head.size), (sizeof(struct target_fpsimd_context
))), 0)
;
1197
1198 /* set the "end" magic */
1199 __put_user(0, &aux->end.magic)(__builtin_choose_expr(sizeof(*(&aux->end.magic)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&aux->end.magic
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&aux->
end.magic)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
aux->end.magic)) == 8, stq_be_p, abort)))) ((&aux->
end.magic), (0)), 0)
;
1200 __put_user(0, &aux->end.size)(__builtin_choose_expr(sizeof(*(&aux->end.size)) == 1,
stb_p, __builtin_choose_expr(sizeof(*(&aux->end.size)
) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&aux->
end.size)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
aux->end.size)) == 8, stq_be_p, abort)))) ((&aux->end
.size), (0)), 0)
;
1201
1202 return 0;
1203}
1204
1205static int target_restore_sigframe(CPUARMState *env,
1206 struct target_rt_sigframe *sf)
1207{
1208 sigset_t set;
1209 int i;
1210 struct target_aux_context *aux =
1211 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1212 uint32_t magic, size, fpsr, fpcr;
1213 uint64_t pstate;
1214
1215 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1216 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
1217
1218 for (i = 0; i < 31; i++) {
1219 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i])((env->xregs[i]) = (typeof(*&sf->uc.tuc_mcontext.regs
[i]))( __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext
.regs[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
sf->uc.tuc_mcontext.regs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.regs[i])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.
regs[i])) == 8, ldq_be_p, abort)))) (&sf->uc.tuc_mcontext
.regs[i])), 0)
;
1220 }
1221
1222 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp)((env->xregs[31]) = (typeof(*&sf->uc.tuc_mcontext.sp
))( __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext
.sp)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&sf->
uc.tuc_mcontext.sp)) == 2, lduw_be_p, __builtin_choose_expr(sizeof
(*(&sf->uc.tuc_mcontext.sp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.sp)) == 8, ldq_be_p, abort
)))) (&sf->uc.tuc_mcontext.sp)), 0)
;
1223 __get_user(env->pc, &sf->uc.tuc_mcontext.pc)((env->pc) = (typeof(*&sf->uc.tuc_mcontext.pc))( __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pc)) == 8, ldq_be_p, abort
)))) (&sf->uc.tuc_mcontext.pc)), 0)
;
1224 __get_user(pstate, &sf->uc.tuc_mcontext.pstate)((pstate) = (typeof(*&sf->uc.tuc_mcontext.pstate))( __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pstate)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->uc.tuc_mcontext.pstate)) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&sf->uc.tuc_mcontext.
pstate)) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(&
sf->uc.tuc_mcontext.pstate)) == 8, ldq_be_p, abort)))) (&
sf->uc.tuc_mcontext.pstate)), 0)
;
1225 pstate_write(env, pstate);
1226
1227 __get_user(magic, &aux->fpsimd.head.magic)((magic) = (typeof(*&aux->fpsimd.head.magic))( __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.magic)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.magic)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.magic)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.magic)) == 8, ldq_be_p, abort
)))) (&aux->fpsimd.head.magic)), 0)
;
1228 __get_user(size, &aux->fpsimd.head.size)((size) = (typeof(*&aux->fpsimd.head.size))( __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.head.size)) == 8, ldq_be_p, abort
)))) (&aux->fpsimd.head.size)), 0)
;
1229
1230 if (magic != TARGET_FPSIMD_MAGIC
1231 || size != sizeof(struct target_fpsimd_context)) {
1232 return 1;
1233 }
1234
1235 for (i = 0; i < 32 * 2; i++) {
1236 __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i])((env->vfp.regs[i]) = (typeof(*&aux->fpsimd.vregs[i
]))( __builtin_choose_expr(sizeof(*(&aux->fpsimd.vregs
[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&aux->
fpsimd.vregs[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof
(*(&aux->fpsimd.vregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.vregs[i])) == 8, ldq_be_p, abort
)))) (&aux->fpsimd.vregs[i])), 0)
;
1237 }
1238 __get_user(fpsr, &aux->fpsimd.fpsr)((fpsr) = (typeof(*&aux->fpsimd.fpsr))( __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpsr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpsr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpsr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpsr)) == 8, ldq_be_p, abort)))
) (&aux->fpsimd.fpsr)), 0)
;
1239 vfp_set_fpsr(env, fpsr);
1240 __get_user(fpcr, &aux->fpsimd.fpcr)((fpcr) = (typeof(*&aux->fpsimd.fpcr))( __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpcr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpcr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpcr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&aux->fpsimd.fpcr)) == 8, ldq_be_p, abort)))
) (&aux->fpsimd.fpcr)), 0)
;
1241 vfp_set_fpcr(env, fpcr);
1242
1243 return 0;
1244}
1245
1246static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1247{
1248 abi_ulong sp;
1249
1250 sp = env->xregs[31];
1251
1252 /*
1253 * This is the X/Open sanctioned signal stack switching.
1254 */
1255 if ((ka->sa_flags & SA_ONSTACK0x08000000) && !sas_ss_flags(sp)) {
1256 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1257 }
1258
1259 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1260
1261 return sp;
1262}
1263
1264static void target_setup_frame(int usig, struct target_sigaction *ka,
1265 target_siginfo_t *info, target_sigset_t *set,
1266 CPUARMState *env)
1267{
1268 struct target_rt_sigframe *frame;
1269 abi_ulong frame_addr;
1270
1271 frame_addr = get_sigframe(ka, env);
1272 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
1273 goto give_sigsegv;
1274 }
1275
1276 __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
1277 __put_user(0, &frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&frame->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
frame->uc.tuc_link), (0)), 0)
;
1278
1279 __put_user(target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
1280 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
1281 __put_user(sas_ss_flags(env->xregs[31]),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->xregs[31]))), 0)
1282 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->xregs[31]))), 0)
;
1283 __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
1284 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
1285 target_setup_sigframe(frame, env, set);
1286 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1287 __put_user(0xd2801168, &frame->tramp[0])(__builtin_choose_expr(sizeof(*(&frame->tramp[0])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->tramp[
0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->tramp[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&frame->tramp[0])) == 8, stq_be_p, abort)))) ((&
frame->tramp[0]), (0xd2801168)), 0)
;
1288 __put_user(0xd4000001, &frame->tramp[1])(__builtin_choose_expr(sizeof(*(&frame->tramp[1])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->tramp[
1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->tramp[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&frame->tramp[1])) == 8, stq_be_p, abort)))) ((&
frame->tramp[1]), (0xd4000001)), 0)
;
1289 env->xregs[0] = usig;
1290 env->xregs[31] = frame_addr;
1291 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp)__builtin_offsetof(struct target_rt_sigframe, fp);
1292 env->pc = ka->_sa_handler;
1293 env->xregs[30] = env->xregs[31] +
1294 offsetof(struct target_rt_sigframe, tramp)__builtin_offsetof(struct target_rt_sigframe, tramp);
1295 if (info) {
1296 if (copy_siginfo_to_user(&frame->info, info)) {
1297 goto give_sigsegv;
1298 }
1299 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info)__builtin_offsetof(struct target_rt_sigframe, info);
1300 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc)__builtin_offsetof(struct target_rt_sigframe, uc);
1301 }
1302
1303 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1304 return;
1305
1306 give_sigsegv:
1307 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1308 force_sig(TARGET_SIGSEGV11);
1309}
1310
1311static void setup_rt_frame(int sig, struct target_sigaction *ka,
1312 target_siginfo_t *info, target_sigset_t *set,
1313 CPUARMState *env)
1314{
1315 target_setup_frame(sig, ka, info, set, env);
1316}
1317
1318static void setup_frame(int sig, struct target_sigaction *ka,
1319 target_sigset_t *set, CPUARMState *env)
1320{
1321 target_setup_frame(sig, ka, 0, set, env);
1322}
1323
1324long do_rt_sigreturn(CPUARMState *env)
1325{
1326 struct target_rt_sigframe *frame;
1327 abi_ulong frame_addr = env->xregs[31];
1328
1329 if (frame_addr & 15) {
1330 goto badframe;
1331 }
1332
1333 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1))) {
1334 goto badframe;
1335 }
1336
1337 if (target_restore_sigframe(env, frame)) {
1338 goto badframe;
1339 }
1340
1341 if (do_sigaltstack(frame_addr +
1342 offsetof(struct target_rt_sigframe, uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack),
1343 0, get_sp_from_cpustate(env)) == -EFAULT14) {
1344 goto badframe;
1345 }
1346
1347 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1348 return env->xregs[0];
1349
1350 badframe:
1351 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1352 force_sig(TARGET_SIGSEGV11);
1353 return 0;
1354}
1355
1356long do_sigreturn(CPUARMState *env)
1357{
1358 return do_rt_sigreturn(env);
1359}
1360
1361#elif defined(TARGET_ARM)
1362
1363struct target_sigcontext {
1364 abi_ulong trap_no;
1365 abi_ulong error_code;
1366 abi_ulong oldmask;
1367 abi_ulong arm_r0;
1368 abi_ulong arm_r1;
1369 abi_ulong arm_r2;
1370 abi_ulong arm_r3;
1371 abi_ulong arm_r4;
1372 abi_ulong arm_r5;
1373 abi_ulong arm_r6;
1374 abi_ulong arm_r7;
1375 abi_ulong arm_r8;
1376 abi_ulong arm_r9;
1377 abi_ulong arm_r10;
1378 abi_ulong arm_fp;
1379 abi_ulong arm_ip;
1380 abi_ulong arm_sp;
1381 abi_ulong arm_lr;
1382 abi_ulong arm_pc;
1383 abi_ulong arm_cpsr;
1384 abi_ulong fault_address;
1385};
1386
1387struct target_ucontext_v1 {
1388 abi_ulong tuc_flags;
1389 abi_ulong tuc_link;
1390 target_stack_t tuc_stack;
1391 struct target_sigcontext tuc_mcontext;
1392 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1393};
1394
1395struct target_ucontext_v2 {
1396 abi_ulong tuc_flags;
1397 abi_ulong tuc_link;
1398 target_stack_t tuc_stack;
1399 struct target_sigcontext tuc_mcontext;
1400 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1401 char __unused[128 - sizeof(target_sigset_t)];
1402 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1403};
1404
1405struct target_user_vfp {
1406 uint64_t fpregs[32];
1407 abi_ulong fpscr;
1408};
1409
1410struct target_user_vfp_exc {
1411 abi_ulong fpexc;
1412 abi_ulong fpinst;
1413 abi_ulong fpinst2;
1414};
1415
1416struct target_vfp_sigframe {
1417 abi_ulong magic;
1418 abi_ulong size;
1419 struct target_user_vfp ufp;
1420 struct target_user_vfp_exc ufp_exc;
1421} __attribute__((__aligned__(8)));
1422
1423struct target_iwmmxt_sigframe {
1424 abi_ulong magic;
1425 abi_ulong size;
1426 uint64_t regs[16];
1427 /* Note that not all the coprocessor control registers are stored here */
1428 uint32_t wcssf;
1429 uint32_t wcasf;
1430 uint32_t wcgr0;
1431 uint32_t wcgr1;
1432 uint32_t wcgr2;
1433 uint32_t wcgr3;
1434} __attribute__((__aligned__(8)));
1435
1436#define TARGET_VFP_MAGIC 0x56465001
1437#define TARGET_IWMMXT_MAGIC 0x12ef842a
1438
1439struct sigframe_v1
1440{
1441 struct target_sigcontext sc;
1442 abi_ulong extramask[TARGET_NSIG_WORDS(64 / 64)-1];
1443 abi_ulong retcode;
1444};
1445
1446struct sigframe_v2
1447{
1448 struct target_ucontext_v2 uc;
1449 abi_ulong retcode;
1450};
1451
1452struct rt_sigframe_v1
1453{
1454 abi_ulong pinfo;
1455 abi_ulong puc;
1456 struct target_siginfo info;
1457 struct target_ucontext_v1 uc;
1458 abi_ulong retcode;
1459};
1460
1461struct rt_sigframe_v2
1462{
1463 struct target_siginfo info;
1464 struct target_ucontext_v2 uc;
1465 abi_ulong retcode;
1466};
1467
1468#define TARGET_CONFIG_CPU_32 1
1469
1470/*
1471 * For ARM syscalls, we encode the syscall number into the instruction.
1472 */
1473#define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn216 + ARM_SYSCALL_BASE))
1474#define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn101 + ARM_SYSCALL_BASE))
1475
1476/*
1477 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1478 * need two 16-bit instructions.
1479 */
1480#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn216))
1481#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn101))
1482
1483static const abi_ulong retcodes[4] = {
1484 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1485 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1486};
1487
1488
1489#define __get_user_error(x,p,e) __get_user(x, p)((x) = (typeof(*p))( __builtin_choose_expr(sizeof(*(p)) == 1,
ldub_p, __builtin_choose_expr(sizeof(*(p)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(p)) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
p)) == 8, ldq_be_p, abort)))) (p)), 0)
1490
1491static inline int valid_user_regs(CPUARMState *regs)
1492{
1493 return 1;
1494}
1495
1496static void
1497setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1498 CPUARMState *env, abi_ulong mask)
1499{
1500 __put_user(env->regs[0], &sc->arm_r0)(__builtin_choose_expr(sizeof(*(&sc->arm_r0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r0)) == 8, stq_be_p
, abort)))) ((&sc->arm_r0), (env->regs[0])), 0)
;
1501 __put_user(env->regs[1], &sc->arm_r1)(__builtin_choose_expr(sizeof(*(&sc->arm_r1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r1)) == 8, stq_be_p
, abort)))) ((&sc->arm_r1), (env->regs[1])), 0)
;
1502 __put_user(env->regs[2], &sc->arm_r2)(__builtin_choose_expr(sizeof(*(&sc->arm_r2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r2)) == 8, stq_be_p
, abort)))) ((&sc->arm_r2), (env->regs[2])), 0)
;
1503 __put_user(env->regs[3], &sc->arm_r3)(__builtin_choose_expr(sizeof(*(&sc->arm_r3)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r3)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r3)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r3)) == 8, stq_be_p
, abort)))) ((&sc->arm_r3), (env->regs[3])), 0)
;
1504 __put_user(env->regs[4], &sc->arm_r4)(__builtin_choose_expr(sizeof(*(&sc->arm_r4)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r4)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r4)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r4)) == 8, stq_be_p
, abort)))) ((&sc->arm_r4), (env->regs[4])), 0)
;
1505 __put_user(env->regs[5], &sc->arm_r5)(__builtin_choose_expr(sizeof(*(&sc->arm_r5)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r5)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r5)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r5)) == 8, stq_be_p
, abort)))) ((&sc->arm_r5), (env->regs[5])), 0)
;
1506 __put_user(env->regs[6], &sc->arm_r6)(__builtin_choose_expr(sizeof(*(&sc->arm_r6)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r6)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r6)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r6)) == 8, stq_be_p
, abort)))) ((&sc->arm_r6), (env->regs[6])), 0)
;
1507 __put_user(env->regs[7], &sc->arm_r7)(__builtin_choose_expr(sizeof(*(&sc->arm_r7)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r7)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r7)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r7)) == 8, stq_be_p
, abort)))) ((&sc->arm_r7), (env->regs[7])), 0)
;
1508 __put_user(env->regs[8], &sc->arm_r8)(__builtin_choose_expr(sizeof(*(&sc->arm_r8)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r8)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r8)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r8)) == 8, stq_be_p
, abort)))) ((&sc->arm_r8), (env->regs[8])), 0)
;
1509 __put_user(env->regs[9], &sc->arm_r9)(__builtin_choose_expr(sizeof(*(&sc->arm_r9)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r9)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r9)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r9)) == 8, stq_be_p
, abort)))) ((&sc->arm_r9), (env->regs[9])), 0)
;
1510 __put_user(env->regs[10], &sc->arm_r10)(__builtin_choose_expr(sizeof(*(&sc->arm_r10)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r10)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r10)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_r10)) == 8, stq_be_p
, abort)))) ((&sc->arm_r10), (env->regs[10])), 0)
;
1511 __put_user(env->regs[11], &sc->arm_fp)(__builtin_choose_expr(sizeof(*(&sc->arm_fp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_fp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_fp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_fp)) == 8, stq_be_p
, abort)))) ((&sc->arm_fp), (env->regs[11])), 0)
;
1512 __put_user(env->regs[12], &sc->arm_ip)(__builtin_choose_expr(sizeof(*(&sc->arm_ip)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_ip)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_ip)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_ip)) == 8, stq_be_p
, abort)))) ((&sc->arm_ip), (env->regs[12])), 0)
;
1513 __put_user(env->regs[13], &sc->arm_sp)(__builtin_choose_expr(sizeof(*(&sc->arm_sp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_sp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_sp)) == 8, stq_be_p
, abort)))) ((&sc->arm_sp), (env->regs[13])), 0)
;
1514 __put_user(env->regs[14], &sc->arm_lr)(__builtin_choose_expr(sizeof(*(&sc->arm_lr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_lr)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_lr)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_lr)) == 8, stq_be_p
, abort)))) ((&sc->arm_lr), (env->regs[14])), 0)
;
1515 __put_user(env->regs[15], &sc->arm_pc)(__builtin_choose_expr(sizeof(*(&sc->arm_pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->arm_pc)) == 8, stq_be_p
, abort)))) ((&sc->arm_pc), (env->regs[15])), 0)
;
1516#ifdef TARGET_CONFIG_CPU_32
1517 __put_user(cpsr_read(env), &sc->arm_cpsr)(__builtin_choose_expr(sizeof(*(&sc->arm_cpsr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->arm_cpsr)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->arm_cpsr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
arm_cpsr)) == 8, stq_be_p, abort)))) ((&sc->arm_cpsr),
(cpsr_read(env))), 0)
;
1518#endif
1519
1520 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no)(__builtin_choose_expr(sizeof(*(&sc->trap_no)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->trap_no)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->trap_no)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->trap_no)) == 8, stq_be_p
, abort)))) ((&sc->trap_no), (0)), 0)
;
1521 __put_user(/* current->thread.error_code */ 0, &sc->error_code)(__builtin_choose_expr(sizeof(*(&sc->error_code)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->error_code
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
error_code)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->error_code)) == 8, stq_be_p, abort)))) ((&sc->error_code
), (0)), 0)
;
1522 __put_user(/* current->thread.address */ 0, &sc->fault_address)(__builtin_choose_expr(sizeof(*(&sc->fault_address)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->fault_address
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
fault_address)) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&sc->fault_address)) == 8, stq_be_p, abort)))) ((&
sc->fault_address), (0)), 0)
;
1523 __put_user(mask, &sc->oldmask)(__builtin_choose_expr(sizeof(*(&sc->oldmask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 8, stq_be_p
, abort)))) ((&sc->oldmask), (mask)), 0)
;
1524}
1525
1526static inline abi_ulong
1527get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1528{
1529 unsigned long sp = regs->regs[13];
1530
1531 /*
1532 * This is the X/Open sanctioned signal stack switching.
1533 */
1534 if ((ka->sa_flags & TARGET_SA_ONSTACK1u) && !sas_ss_flags(sp))
1535 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1536 /*
1537 * ATPCS B01 mandates 8-byte alignment
1538 */
1539 return (sp - framesize) & ~7;
1540}
1541
1542static int
1543setup_return(CPUARMState *env, struct target_sigaction *ka,
1544 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1545{
1546 abi_ulong handler = ka->_sa_handler;
1547 abi_ulong retcode;
1548 int thumb = handler & 1;
1549 uint32_t cpsr = cpsr_read(env);
1550
1551 cpsr &= ~CPSR_IT;
1552 if (thumb) {
1553 cpsr |= CPSR_T;
1554 } else {
1555 cpsr &= ~CPSR_T;
1556 }
1557
1558 if (ka->sa_flags & TARGET_SA_RESTORER) {
1559 retcode = ka->sa_restorer;
1560 } else {
1561 unsigned int idx = thumb;
1562
1563 if (ka->sa_flags & TARGET_SA_SIGINFO0x200u)
1564 idx += 2;
1565
1566 if (__put_user(retcodes[idx], rc)(__builtin_choose_expr(sizeof(*(rc)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(rc)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*
(rc)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(rc)) == 8
, stq_be_p, abort)))) ((rc), (retcodes[idx])), 0)
)
1567 return 1;
1568
1569 retcode = rc_addr + thumb;
1570 }
1571
1572 env->regs[0] = usig;
1573 env->regs[13] = frame_addr;
1574 env->regs[14] = retcode;
1575 env->regs[15] = handler & (thumb ? ~1 : ~3);
1576 cpsr_write(env, cpsr, 0xffffffff);
1577
1578 return 0;
1579}
1580
1581static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1582{
1583 int i;
1584 struct target_vfp_sigframe *vfpframe;
1585 vfpframe = (struct target_vfp_sigframe *)regspace;
1586 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic)(__builtin_choose_expr(sizeof(*(&vfpframe->magic)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->magic
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&vfpframe
->magic)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
vfpframe->magic)) == 8, stq_be_p, abort)))) ((&vfpframe
->magic), (TARGET_VFP_MAGIC)), 0)
;
1587 __put_user(sizeof(*vfpframe), &vfpframe->size)(__builtin_choose_expr(sizeof(*(&vfpframe->size)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->size
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&vfpframe
->size)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
vfpframe->size)) == 8, stq_be_p, abort)))) ((&vfpframe
->size), (sizeof(*vfpframe))), 0)
;
1588 for (i = 0; i < 32; i++) {
1589 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i])(__builtin_choose_expr(sizeof(*(&vfpframe->ufp.fpregs[
i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe
->ufp.fpregs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp.fpregs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpregs[i])) == 8, stq_be_p, abort
)))) ((&vfpframe->ufp.fpregs[i]), ((env->vfp.regs[i
]))), 0)
;
1590 }
1591 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr)(__builtin_choose_expr(sizeof(*(&vfpframe->ufp.fpscr))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->
ufp.fpscr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
vfpframe->ufp.fpscr)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpscr)) == 8, stq_be_p, abort
)))) ((&vfpframe->ufp.fpscr), (vfp_get_fpscr(env))), 0
)
;
1592 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc)(__builtin_choose_expr(sizeof(*(&vfpframe->ufp_exc.fpexc
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->
ufp_exc.fpexc)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(&vfpframe->ufp_exc.fpexc)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpexc)) == 8, stq_be_p, abort
)))) ((&vfpframe->ufp_exc.fpexc), (env->vfp.xregs[ARM_VFP_FPEXC
])), 0)
;
1593 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst)(__builtin_choose_expr(sizeof(*(&vfpframe->ufp_exc.fpinst
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->
ufp_exc.fpinst)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp_exc.fpinst)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpinst)) == 8, stq_be_p, abort
)))) ((&vfpframe->ufp_exc.fpinst), (env->vfp.xregs[
ARM_VFP_FPINST])), 0)
;
1594 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2)(__builtin_choose_expr(sizeof(*(&vfpframe->ufp_exc.fpinst2
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&vfpframe->
ufp_exc.fpinst2)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp_exc.fpinst2)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpinst2)) == 8, stq_be_p,
abort)))) ((&vfpframe->ufp_exc.fpinst2), (env->vfp
.xregs[ARM_VFP_FPINST2])), 0)
;
1595 return (abi_ulong*)(vfpframe+1);
1596}
1597
1598static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1599 CPUARMState *env)
1600{
1601 int i;
1602 struct target_iwmmxt_sigframe *iwmmxtframe;
1603 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1604 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->magic)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
magic)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->magic)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->magic)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->magic), (TARGET_IWMMXT_MAGIC)), 0)
;
1605 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->size)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
size)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->size)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->size)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->size), (sizeof(*iwmmxtframe))), 0)
;
1606 for (i = 0; i < 16; i++) {
1607 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i])(__builtin_choose_expr(sizeof(*(&iwmmxtframe->regs[i])
) == 1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->regs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*
(&iwmmxtframe->regs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->regs[i])) == 8, stq_be_p, abort
)))) ((&iwmmxtframe->regs[i]), (env->iwmmxt.regs[i]
)), 0)
;
1608 }
1609 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcssf)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcssf)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcssf)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcssf)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcssf), (env->vfp.xregs[ARM_IWMMXT_wCSSF])), 0)
;
1610 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcssf)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcssf)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcssf)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcssf)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcssf), (env->vfp.xregs[ARM_IWMMXT_wCASF])), 0)
;
1611 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcgr0)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcgr0)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr0)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr0)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcgr0), (env->vfp.xregs[ARM_IWMMXT_wCGR0])), 0)
;
1612 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcgr1)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcgr1)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr1)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr1)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcgr1), (env->vfp.xregs[ARM_IWMMXT_wCGR1])), 0)
;
1613 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcgr2)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcgr2)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr2)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr2)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcgr2), (env->vfp.xregs[ARM_IWMMXT_wCGR2])), 0)
;
1614 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3)(__builtin_choose_expr(sizeof(*(&iwmmxtframe->wcgr3)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe->
wcgr3)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr3)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr3)) == 8, stq_be_p, abort)))) ((&iwmmxtframe
->wcgr3), (env->vfp.xregs[ARM_IWMMXT_wCGR3])), 0)
;
1615 return (abi_ulong*)(iwmmxtframe+1);
1616}
1617
1618static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1619 target_sigset_t *set, CPUARMState *env)
1620{
1621 struct target_sigaltstack stack;
1622 int i;
1623 abi_ulong *regspace;
1624
1625 /* Clear all the bits of the ucontext we don't use. */
1626 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext)__builtin_offsetof(struct target_ucontext_v2, tuc_mcontext));
1627
1628 memset(&stack, 0, sizeof(stack));
1629 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp)(__builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 8, stq_be_p
, abort)))) ((&stack.ss_sp), (target_sigaltstack_used.ss_sp
)), 0)
;
1630 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size)(__builtin_choose_expr(sizeof(*(&stack.ss_size)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 8, stq_be_p
, abort)))) ((&stack.ss_size), (target_sigaltstack_used.ss_size
)), 0)
;
1631 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags)(__builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 8, stq_be_p
, abort)))) ((&stack.ss_flags), (sas_ss_flags(get_sp_from_cpustate
(env)))), 0)
;
1632 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1633
1634 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1635 /* Save coprocessor signal frame. */
1636 regspace = uc->tuc_regspace;
1637 if (arm_feature(env, ARM_FEATURE_VFP)) {
1638 regspace = setup_sigframe_v2_vfp(regspace, env);
1639 }
1640 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1641 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1642 }
1643
1644 /* Write terminating magic word */
1645 __put_user(0, regspace)(__builtin_choose_expr(sizeof(*(regspace)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(regspace)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(regspace)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
regspace)) == 8, stq_be_p, abort)))) ((regspace), (0)), 0)
;
1646
1647 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1648 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&uc->tuc_sigmask.sig[i
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&uc->tuc_sigmask
.sig[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
uc->tuc_sigmask.sig[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&uc->tuc_sigmask.sig[i])) == 8, stq_be_p, abort
)))) ((&uc->tuc_sigmask.sig[i]), (set->sig[i])), 0)
;
1649 }
1650}
1651
1652/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1653static void setup_frame_v1(int usig, struct target_sigaction *ka,
1654 target_sigset_t *set, CPUARMState *regs)
1655{
1656 struct sigframe_v1 *frame;
1657 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1658 int i;
1659
1660 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
1661 return;
1662
1663 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1664
1665 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1666 if (__put_user(set->sig[i], &frame->extramask[i - 1])(__builtin_choose_expr(sizeof(*(&frame->extramask[i - 1
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
extramask[i - 1])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i - 1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, stq_be_p, abort
)))) ((&frame->extramask[i - 1]), (set->sig[i])), 0
)
)
1667 goto end;
1668 }
1669
1670 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1671 frame_addr + offsetof(struct sigframe_v1, retcode)__builtin_offsetof(struct sigframe_v1, retcode));
1672
1673end:
1674 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1675}
1676
1677static void setup_frame_v2(int usig, struct target_sigaction *ka,
1678 target_sigset_t *set, CPUARMState *regs)
1679{
1680 struct sigframe_v2 *frame;
1681 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1682
1683 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
1684 return;
1685
1686 setup_sigframe_v2(&frame->uc, set, regs);
1687
1688 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1689 frame_addr + offsetof(struct sigframe_v2, retcode)__builtin_offsetof(struct sigframe_v2, retcode));
1690
1691 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1692}
1693
1694static void setup_frame(int usig, struct target_sigaction *ka,
1695 target_sigset_t *set, CPUARMState *regs)
1696{
1697 if (get_osversion() >= 0x020612) {
1698 setup_frame_v2(usig, ka, set, regs);
1699 } else {
1700 setup_frame_v1(usig, ka, set, regs);
1701 }
1702}
1703
1704/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1705static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1706 target_siginfo_t *info,
1707 target_sigset_t *set, CPUARMState *env)
1708{
1709 struct rt_sigframe_v1 *frame;
1710 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1711 struct target_sigaltstack stack;
1712 int i;
1713 abi_ulong info_addr, uc_addr;
1714
1715 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
1716 return /* 1 */;
1717
1718 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info)__builtin_offsetof(struct rt_sigframe_v1, info);
1719 __put_user(info_addr, &frame->pinfo)(__builtin_choose_expr(sizeof(*(&frame->pinfo)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->pinfo)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&frame->pinfo
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&frame->
pinfo)) == 8, stq_be_p, abort)))) ((&frame->pinfo), (info_addr
)), 0)
;
1720 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc)__builtin_offsetof(struct rt_sigframe_v1, uc);
1721 __put_user(uc_addr, &frame->puc)(__builtin_choose_expr(sizeof(*(&frame->puc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 8, stq_be_p
, abort)))) ((&frame->puc), (uc_addr)), 0)
;
1722 copy_siginfo_to_user(&frame->info, info);
1723
1724 /* Clear all the bits of the ucontext we don't use. */
1725 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext)__builtin_offsetof(struct target_ucontext_v1, tuc_mcontext));
1726
1727 memset(&stack, 0, sizeof(stack));
1728 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp)(__builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_sp)) == 8, stq_be_p
, abort)))) ((&stack.ss_sp), (target_sigaltstack_used.ss_sp
)), 0)
;
1729 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size)(__builtin_choose_expr(sizeof(*(&stack.ss_size)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_size)) == 8, stq_be_p
, abort)))) ((&stack.ss_size), (target_sigaltstack_used.ss_size
)), 0)
;
1730 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags)(__builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&stack.ss_flags)) == 8, stq_be_p
, abort)))) ((&stack.ss_flags), (sas_ss_flags(get_sp_from_cpustate
(env)))), 0)
;
1731 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1732
1733 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1734 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1735 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
)
1736 goto end;
1737 }
1738
1739 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1740 frame_addr + offsetof(struct rt_sigframe_v1, retcode)__builtin_offsetof(struct rt_sigframe_v1, retcode));
1741
1742 env->regs[1] = info_addr;
1743 env->regs[2] = uc_addr;
1744
1745end:
1746 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1747}
1748
1749static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1750 target_siginfo_t *info,
1751 target_sigset_t *set, CPUARMState *env)
1752{
1753 struct rt_sigframe_v2 *frame;
1754 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1755 abi_ulong info_addr, uc_addr;
1756
1757 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
1758 return /* 1 */;
1759
1760 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info)__builtin_offsetof(struct rt_sigframe_v2, info);
1761 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc)__builtin_offsetof(struct rt_sigframe_v2, uc);
1762 copy_siginfo_to_user(&frame->info, info);
1763
1764 setup_sigframe_v2(&frame->uc, set, env);
1765
1766 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1767 frame_addr + offsetof(struct rt_sigframe_v2, retcode)__builtin_offsetof(struct rt_sigframe_v2, retcode));
1768
1769 env->regs[1] = info_addr;
1770 env->regs[2] = uc_addr;
1771
1772 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
1773}
1774
1775static void setup_rt_frame(int usig, struct target_sigaction *ka,
1776 target_siginfo_t *info,
1777 target_sigset_t *set, CPUARMState *env)
1778{
1779 if (get_osversion() >= 0x020612) {
1780 setup_rt_frame_v2(usig, ka, info, set, env);
1781 } else {
1782 setup_rt_frame_v1(usig, ka, info, set, env);
1783 }
1784}
1785
1786static int
1787restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1788{
1789 int err = 0;
1790 uint32_t cpsr;
1791
1792 __get_user_error(env->regs[0], &sc->arm_r0, err);
1793 __get_user_error(env->regs[1], &sc->arm_r1, err);
1794 __get_user_error(env->regs[2], &sc->arm_r2, err);
1795 __get_user_error(env->regs[3], &sc->arm_r3, err);
1796 __get_user_error(env->regs[4], &sc->arm_r4, err);
1797 __get_user_error(env->regs[5], &sc->arm_r5, err);
1798 __get_user_error(env->regs[6], &sc->arm_r6, err);
1799 __get_user_error(env->regs[7], &sc->arm_r7, err);
1800 __get_user_error(env->regs[8], &sc->arm_r8, err);
1801 __get_user_error(env->regs[9], &sc->arm_r9, err);
1802 __get_user_error(env->regs[10], &sc->arm_r10, err);
1803 __get_user_error(env->regs[11], &sc->arm_fp, err);
1804 __get_user_error(env->regs[12], &sc->arm_ip, err);
1805 __get_user_error(env->regs[13], &sc->arm_sp, err);
1806 __get_user_error(env->regs[14], &sc->arm_lr, err);
1807 __get_user_error(env->regs[15], &sc->arm_pc, err);
1808#ifdef TARGET_CONFIG_CPU_32
1809 __get_user_error(cpsr, &sc->arm_cpsr, err);
1810 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1811#endif
1812
1813 err |= !valid_user_regs(env);
1814
1815 return err;
1816}
1817
1818static long do_sigreturn_v1(CPUARMState *env)
1819{
1820 abi_ulong frame_addr;
1821 struct sigframe_v1 *frame = NULL((void*)0);
1822 target_sigset_t set;
1823 sigset_t host_set;
1824 int i;
1825
1826 /*
1827 * Since we stacked the signal on a 64-bit boundary,
1828 * then 'sp' should be word aligned here. If it's
1829 * not, then the user is trying to mess with us.
1830 */
1831 frame_addr = env->regs[13];
1832 if (frame_addr & 7) {
1833 goto badframe;
1834 }
1835
1836 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
1837 goto badframe;
1838
1839 if (__get_user(set.sig[0], &frame->sc.oldmask)((set.sig[0]) = (typeof(*&frame->sc.oldmask))( __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 8, ldq_be_p, abort))
)) (&frame->sc.oldmask)), 0)
)
1840 goto badframe;
1841 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
1842 if (__get_user(set.sig[i], &frame->extramask[i - 1])((set.sig[i]) = (typeof(*&frame->extramask[i - 1]))( __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
)
1843 goto badframe;
1844 }
1845
1846 target_to_host_sigset_internal(&host_set, &set);
1847 sigprocmask(SIG_SETMASK2, &host_set, NULL((void*)0));
1848
1849 if (restore_sigcontext(env, &frame->sc))
1850 goto badframe;
1851
1852#if 0
1853 /* Send SIGTRAP if we're single-stepping */
1854 if (ptrace_cancel_bpt(current))
1855 send_sig(SIGTRAP5, current, 1);
1856#endif
1857 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1858 return env->regs[0];
1859
1860badframe:
1861 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1862 force_sig(TARGET_SIGSEGV11 /* , current */);
1863 return 0;
1864}
1865
1866static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1867{
1868 int i;
1869 abi_ulong magic, sz;
1870 uint32_t fpscr, fpexc;
1871 struct target_vfp_sigframe *vfpframe;
1872 vfpframe = (struct target_vfp_sigframe *)regspace;
1873
1874 __get_user(magic, &vfpframe->magic)((magic) = (typeof(*&vfpframe->magic))( __builtin_choose_expr
(sizeof(*(&vfpframe->magic)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vfpframe->magic)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->magic)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->magic)) == 8, ldq_be_p, abort))))
(&vfpframe->magic)), 0)
;
1875 __get_user(sz, &vfpframe->size)((sz) = (typeof(*&vfpframe->size))( __builtin_choose_expr
(sizeof(*(&vfpframe->size)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vfpframe->size)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->size)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->size)) == 8, ldq_be_p, abort)))) (
&vfpframe->size)), 0)
;
1876 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1877 return 0;
1878 }
1879 for (i = 0; i < 32; i++) {
1880 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i])(((env->vfp.regs[i])) = (typeof(*&vfpframe->ufp.fpregs
[i]))( __builtin_choose_expr(sizeof(*(&vfpframe->ufp.fpregs
[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&vfpframe
->ufp.fpregs[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp.fpregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpregs[i])) == 8, ldq_be_p, abort
)))) (&vfpframe->ufp.fpregs[i])), 0)
;
1881 }
1882 __get_user(fpscr, &vfpframe->ufp.fpscr)((fpscr) = (typeof(*&vfpframe->ufp.fpscr))( __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpscr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpscr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpscr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp.fpscr)) == 8, ldq_be_p, abort
)))) (&vfpframe->ufp.fpscr)), 0)
;
1883 vfp_set_fpscr(env, fpscr);
1884 __get_user(fpexc, &vfpframe->ufp_exc.fpexc)((fpexc) = (typeof(*&vfpframe->ufp_exc.fpexc))( __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpexc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpexc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpexc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpexc)) == 8, ldq_be_p, abort
)))) (&vfpframe->ufp_exc.fpexc)), 0)
;
1885 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1886 * and the exception flag is cleared
1887 */
1888 fpexc |= (1 << 30);
1889 fpexc &= ~((1 << 31) | (1 << 28));
1890 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1891 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst)((env->vfp.xregs[ARM_VFP_FPINST]) = (typeof(*&vfpframe
->ufp_exc.fpinst))( __builtin_choose_expr(sizeof(*(&vfpframe
->ufp_exc.fpinst)) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp_exc.fpinst)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpinst)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpinst)) == 8, ldq_be_p, abort
)))) (&vfpframe->ufp_exc.fpinst)), 0)
;
1892 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2)((env->vfp.xregs[ARM_VFP_FPINST2]) = (typeof(*&vfpframe
->ufp_exc.fpinst2))( __builtin_choose_expr(sizeof(*(&vfpframe
->ufp_exc.fpinst2)) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&vfpframe->ufp_exc.fpinst2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vfpframe->ufp_exc.fpinst2)) == 4, ldl_be_p,
__builtin_choose_expr(sizeof(*(&vfpframe->ufp_exc.fpinst2
)) == 8, ldq_be_p, abort)))) (&vfpframe->ufp_exc.fpinst2
)), 0)
;
1893 return (abi_ulong*)(vfpframe + 1);
1894}
1895
1896static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1897 abi_ulong *regspace)
1898{
1899 int i;
1900 abi_ulong magic, sz;
1901 struct target_iwmmxt_sigframe *iwmmxtframe;
1902 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1903
1904 __get_user(magic, &iwmmxtframe->magic)((magic) = (typeof(*&iwmmxtframe->magic))( __builtin_choose_expr
(sizeof(*(&iwmmxtframe->magic)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->magic)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->magic)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->magic)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->magic)), 0)
;
1905 __get_user(sz, &iwmmxtframe->size)((sz) = (typeof(*&iwmmxtframe->size))( __builtin_choose_expr
(sizeof(*(&iwmmxtframe->size)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->size)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->size)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->size)) == 8, ldq_be_p, abort))
)) (&iwmmxtframe->size)), 0)
;
1906 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1907 return 0;
1908 }
1909 for (i = 0; i < 16; i++) {
1910 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i])((env->iwmmxt.regs[i]) = (typeof(*&iwmmxtframe->regs
[i]))( __builtin_choose_expr(sizeof(*(&iwmmxtframe->regs
[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&iwmmxtframe
->regs[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(
*(&iwmmxtframe->regs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->regs[i])) == 8, ldq_be_p, abort
)))) (&iwmmxtframe->regs[i])), 0)
;
1911 }
1912 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf)((env->vfp.xregs[ARM_IWMMXT_wCSSF]) = (typeof(*&iwmmxtframe
->wcssf))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcssf)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcssf)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcssf)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcssf)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcssf)), 0)
;
1913 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf)((env->vfp.xregs[ARM_IWMMXT_wCASF]) = (typeof(*&iwmmxtframe
->wcssf))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcssf)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcssf)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcssf)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcssf)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcssf)), 0)
;
1914 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0)((env->vfp.xregs[ARM_IWMMXT_wCGR0]) = (typeof(*&iwmmxtframe
->wcgr0))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr0)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr0)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr0)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr0)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcgr0)), 0)
;
1915 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1)((env->vfp.xregs[ARM_IWMMXT_wCGR1]) = (typeof(*&iwmmxtframe
->wcgr1))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr1)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr1)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcgr1)), 0)
;
1916 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2)((env->vfp.xregs[ARM_IWMMXT_wCGR2]) = (typeof(*&iwmmxtframe
->wcgr2))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr2)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr2)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr2)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcgr2)), 0)
;
1917 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3)((env->vfp.xregs[ARM_IWMMXT_wCGR3]) = (typeof(*&iwmmxtframe
->wcgr3))( __builtin_choose_expr(sizeof(*(&iwmmxtframe
->wcgr3)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
iwmmxtframe->wcgr3)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr3)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&iwmmxtframe->wcgr3)) == 8, ldq_be_p, abort)
))) (&iwmmxtframe->wcgr3)), 0)
;
1918 return (abi_ulong*)(iwmmxtframe + 1);
1919}
1920
1921static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1922 struct target_ucontext_v2 *uc)
1923{
1924 sigset_t host_set;
1925 abi_ulong *regspace;
1926
1927 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1928 sigprocmask(SIG_SETMASK2, &host_set, NULL((void*)0));
1929
1930 if (restore_sigcontext(env, &uc->tuc_mcontext))
1931 return 1;
1932
1933 /* Restore coprocessor signal frame */
1934 regspace = uc->tuc_regspace;
1935 if (arm_feature(env, ARM_FEATURE_VFP)) {
1936 regspace = restore_sigframe_v2_vfp(env, regspace);
1937 if (!regspace) {
1938 return 1;
1939 }
1940 }
1941 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1942 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1943 if (!regspace) {
1944 return 1;
1945 }
1946 }
1947
1948 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack)__builtin_offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT14)
1949 return 1;
1950
1951#if 0
1952 /* Send SIGTRAP if we're single-stepping */
1953 if (ptrace_cancel_bpt(current))
1954 send_sig(SIGTRAP5, current, 1);
1955#endif
1956
1957 return 0;
1958}
1959
1960static long do_sigreturn_v2(CPUARMState *env)
1961{
1962 abi_ulong frame_addr;
1963 struct sigframe_v2 *frame = NULL((void*)0);
1964
1965 /*
1966 * Since we stacked the signal on a 64-bit boundary,
1967 * then 'sp' should be word aligned here. If it's
1968 * not, then the user is trying to mess with us.
1969 */
1970 frame_addr = env->regs[13];
1971 if (frame_addr & 7) {
1972 goto badframe;
1973 }
1974
1975 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
1976 goto badframe;
1977
1978 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1979 goto badframe;
1980
1981 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1982 return env->regs[0];
1983
1984badframe:
1985 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
1986 force_sig(TARGET_SIGSEGV11 /* , current */);
1987 return 0;
1988}
1989
1990long do_sigreturn(CPUARMState *env)
1991{
1992 if (get_osversion() >= 0x020612) {
1993 return do_sigreturn_v2(env);
1994 } else {
1995 return do_sigreturn_v1(env);
1996 }
1997}
1998
1999static long do_rt_sigreturn_v1(CPUARMState *env)
2000{
2001 abi_ulong frame_addr;
2002 struct rt_sigframe_v1 *frame = NULL((void*)0);
2003 sigset_t host_set;
2004
2005 /*
2006 * Since we stacked the signal on a 64-bit boundary,
2007 * then 'sp' should be word aligned here. If it's
2008 * not, then the user is trying to mess with us.
2009 */
2010 frame_addr = env->regs[13];
2011 if (frame_addr & 7) {
2012 goto badframe;
2013 }
2014
2015 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
2016 goto badframe;
2017
2018 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2019 sigprocmask(SIG_SETMASK2, &host_set, NULL((void*)0));
2020
2021 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2022 goto badframe;
2023
2024 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack)__builtin_offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT14)
2025 goto badframe;
2026
2027#if 0
2028 /* Send SIGTRAP if we're single-stepping */
2029 if (ptrace_cancel_bpt(current))
2030 send_sig(SIGTRAP5, current, 1);
2031#endif
2032 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
2033 return env->regs[0];
2034
2035badframe:
2036 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
2037 force_sig(TARGET_SIGSEGV11 /* , current */);
2038 return 0;
2039}
2040
2041static long do_rt_sigreturn_v2(CPUARMState *env)
2042{
2043 abi_ulong frame_addr;
2044 struct rt_sigframe_v2 *frame = NULL((void*)0);
2045
2046 /*
2047 * Since we stacked the signal on a 64-bit boundary,
2048 * then 'sp' should be word aligned here. If it's
2049 * not, then the user is trying to mess with us.
2050 */
2051 frame_addr = env->regs[13];
2052 if (frame_addr & 7) {
2053 goto badframe;
2054 }
2055
2056 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
2057 goto badframe;
2058
2059 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2060 goto badframe;
2061
2062 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
2063 return env->regs[0];
2064
2065badframe:
2066 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
2067 force_sig(TARGET_SIGSEGV11 /* , current */);
2068 return 0;
2069}
2070
2071long do_rt_sigreturn(CPUARMState *env)
2072{
2073 if (get_osversion() >= 0x020612) {
2074 return do_rt_sigreturn_v2(env);
2075 } else {
2076 return do_rt_sigreturn_v1(env);
2077 }
2078}
2079
2080#elif defined(TARGET_SPARC1)
2081
2082#define __SUNOS_MAXWIN31 31
2083
2084/* This is what SunOS does, so shall I. */
2085struct target_sigcontext {
2086 abi_ulong sigc_onstack; /* state to restore */
2087
2088 abi_ulong sigc_mask; /* sigmask to restore */
2089 abi_ulong sigc_sp; /* stack pointer */
2090 abi_ulong sigc_pc; /* program counter */
2091 abi_ulong sigc_npc; /* next program counter */
2092 abi_ulong sigc_psr; /* for condition codes etc */
2093 abi_ulong sigc_g1; /* User uses these two registers */
2094 abi_ulong sigc_o0; /* within the trampoline code. */
2095
2096 /* Now comes information regarding the users window set
2097 * at the time of the signal.
2098 */
2099 abi_ulong sigc_oswins; /* outstanding windows */
2100
2101 /* stack ptrs for each regwin buf */
2102 char *sigc_spbuf[__SUNOS_MAXWIN31];
2103
2104 /* Windows to restore after signal */
2105 struct {
2106 abi_ulong locals[8];
2107 abi_ulong ins[8];
2108 } sigc_wbuf[__SUNOS_MAXWIN31];
2109};
2110/* A Sparc stack frame */
2111struct sparc_stackf {
2112 abi_ulong locals[8];
2113 abi_ulong ins[8];
2114 /* It's simpler to treat fp and callers_pc as elements of ins[]
2115 * since we never need to access them ourselves.
2116 */
2117 char *structptr;
2118 abi_ulong xargs[6];
2119 abi_ulong xxargs[1];
2120};
2121
2122typedef struct {
2123 struct {
2124 abi_ulong psr;
2125 abi_ulong pc;
2126 abi_ulong npc;
2127 abi_ulong y;
2128 abi_ulong u_regs[16]; /* globals and ins */
2129 } si_regs;
2130 int si_mask;
2131} __siginfo_t;
2132
2133typedef struct {
2134 abi_ulong si_float_regs[32];
2135 unsigned long si_fsr;
2136 unsigned long si_fpqdepth;
2137 struct {
2138 unsigned long *insn_addr;
2139 unsigned long insn;
2140 } si_fpqueue [16];
2141} qemu_siginfo_fpu_t;
2142
2143
2144struct target_signal_frame {
2145 struct sparc_stackf ss;
2146 __siginfo_t info;
2147 abi_ulong fpu_save;
2148 abi_ulong insns[2] __attribute__ ((aligned (8)));
2149 abi_ulong extramask[TARGET_NSIG_WORDS(64 / 64) - 1];
2150 abi_ulong extra_size; /* Should be 0 */
2151 qemu_siginfo_fpu_t fpu_state;
2152};
2153struct target_rt_signal_frame {
2154 struct sparc_stackf ss;
2155 siginfo_t info;
2156 abi_ulong regs[20];
2157 sigset_t mask;
2158 abi_ulong fpu_save;
2159 unsigned int insns[2];
2160 stack_t stack;
2161 unsigned int extra_size; /* Should be 0 */
2162 qemu_siginfo_fpu_t fpu_state;
2163};
2164
2165#define UREG_O016 16
2166#define UREG_O622 22
2167#define UREG_I00 0
2168#define UREG_I11 1
2169#define UREG_I22 2
2170#define UREG_I33 3
2171#define UREG_I44 4
2172#define UREG_I55 5
2173#define UREG_I66 6
2174#define UREG_I77 7
2175#define UREG_L08 8
2176#define UREG_FP6 UREG_I66
2177#define UREG_SP22 UREG_O622
2178
2179static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2180 CPUSPARCState *env,
2181 unsigned long framesize)
2182{
2183 abi_ulong sp;
2184
2185 sp = env->regwptr[UREG_FP6];
2186
2187 /* This is the X/Open sanctioned signal stack switching. */
2188 if (sa->sa_flags & TARGET_SA_ONSTACK1u) {
2189 if (!on_sig_stack(sp)
2190 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2191 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2192 }
2193 return sp - framesize;
2194}
2195
2196static int
2197setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2198{
2199 int err = 0, i;
2200
2201 err |= __put_user(env->psr, &si->si_regs.psr)(__builtin_choose_expr(sizeof(*(&si->si_regs.psr)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&si->si_regs.psr
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&si->
si_regs.psr)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&si->si_regs.psr)) == 8, stq_be_p, abort)))) ((&si
->si_regs.psr), (env->psr)), 0)
;
2202 err |= __put_user(env->pc, &si->si_regs.pc)(__builtin_choose_expr(sizeof(*(&si->si_regs.pc)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&si->si_regs.pc
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&si->
si_regs.pc)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
si->si_regs.pc)) == 8, stq_be_p, abort)))) ((&si->si_regs
.pc), (env->pc)), 0)
;
2203 err |= __put_user(env->npc, &si->si_regs.npc)(__builtin_choose_expr(sizeof(*(&si->si_regs.npc)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&si->si_regs.npc
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&si->
si_regs.npc)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&si->si_regs.npc)) == 8, stq_be_p, abort)))) ((&si
->si_regs.npc), (env->npc)), 0)
;
2204 err |= __put_user(env->y, &si->si_regs.y)(__builtin_choose_expr(sizeof(*(&si->si_regs.y)) == 1,
stb_p, __builtin_choose_expr(sizeof(*(&si->si_regs.y)
) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&si->
si_regs.y)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
si->si_regs.y)) == 8, stq_be_p, abort)))) ((&si->si_regs
.y), (env->y)), 0)
;
2205 for (i=0; i < 8; i++) {
2206 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i])(__builtin_choose_expr(sizeof(*(&si->si_regs.u_regs[i]
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&si->si_regs
.u_regs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
si->si_regs.u_regs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&si->si_regs.u_regs[i])) == 8, stq_be_p, abort
)))) ((&si->si_regs.u_regs[i]), (env->gregs[i])), 0
)
;
2207 }
2208 for (i=0; i < 8; i++) {
2209 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8])(__builtin_choose_expr(sizeof(*(&si->si_regs.u_regs[i+
8])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&si->
si_regs.u_regs[i+8])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&si->si_regs.u_regs[i+8])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&si->si_regs.u_regs[i+8])) == 8, stq_be_p, abort
)))) ((&si->si_regs.u_regs[i+8]), (env->regwptr[0 +
i])), 0)
;
2210 }
2211 err |= __put_user(mask, &si->si_mask)(__builtin_choose_expr(sizeof(*(&si->si_mask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&si->si_mask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&si->si_mask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&si->si_mask)) == 8, stq_be_p
, abort)))) ((&si->si_mask), (mask)), 0)
;
2212 return err;
2213}
2214
2215#if 0
2216static int
2217setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2218 CPUSPARCState *env, unsigned long mask)
2219{
2220 int err = 0;
2221
2222 err |= __put_user(mask, &sc->sigc_mask)(__builtin_choose_expr(sizeof(*(&sc->sigc_mask)) == 1,
stb_p, __builtin_choose_expr(sizeof(*(&sc->sigc_mask)
) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sigc_mask)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->sigc_mask)) == 8, stq_be_p, abort)))) ((&sc->sigc_mask
), (mask)), 0)
;
2223 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp)(__builtin_choose_expr(sizeof(*(&sc->sigc_sp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_sp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_sp)) == 8, stq_be_p
, abort)))) ((&sc->sigc_sp), (env->regwptr[22])), 0
)
;
2224 err |= __put_user(env->pc, &sc->sigc_pc)(__builtin_choose_expr(sizeof(*(&sc->sigc_pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_pc)) == 8, stq_be_p
, abort)))) ((&sc->sigc_pc), (env->pc)), 0)
;
2225 err |= __put_user(env->npc, &sc->sigc_npc)(__builtin_choose_expr(sizeof(*(&sc->sigc_npc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_npc)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->sigc_npc
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
sigc_npc)) == 8, stq_be_p, abort)))) ((&sc->sigc_npc),
(env->npc)), 0)
;
2226 err |= __put_user(env->psr, &sc->sigc_psr)(__builtin_choose_expr(sizeof(*(&sc->sigc_psr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_psr)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->sigc_psr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
sigc_psr)) == 8, stq_be_p, abort)))) ((&sc->sigc_psr),
(env->psr)), 0)
;
2227 err |= __put_user(env->gregs[1], &sc->sigc_g1)(__builtin_choose_expr(sizeof(*(&sc->sigc_g1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_g1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_g1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_g1)) == 8, stq_be_p
, abort)))) ((&sc->sigc_g1), (env->gregs[1])), 0)
;
2228 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0)(__builtin_choose_expr(sizeof(*(&sc->sigc_o0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_o0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_o0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sigc_o0)) == 8, stq_be_p
, abort)))) ((&sc->sigc_o0), (env->regwptr[16])), 0
)
;
2229
2230 return err;
2231}
2232#endif
2233#define NF_ALIGNEDSZ(((sizeof(struct target_signal_frame) + 7) & (~7))) (((sizeof(struct target_signal_frame) + 7) & (~7)))
2234
2235static void setup_frame(int sig, struct target_sigaction *ka,
2236 target_sigset_t *set, CPUSPARCState *env)
2237{
2238 abi_ulong sf_addr;
2239 struct target_signal_frame *sf;
2240 int sigframe_size, err, i;
2241
2242 /* 1. Make sure everything is clean */
2243 //synchronize_user_stack();
2244
2245 sigframe_size = NF_ALIGNEDSZ(((sizeof(struct target_signal_frame) + 7) & (~7)));
2246 sf_addr = get_sigframe(ka, env, sigframe_size);
2247
2248 sf = lock_user(VERIFY_WRITE1, sf_addr,
2249 sizeof(struct target_signal_frame), 0);
2250 if (!sf)
2251 goto sigsegv;
2252
2253 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2254#if 0
2255 if (invalid_frame_pointer(sf, sigframe_size))
2256 goto sigill_and_return;
2257#endif
2258 /* 2. Save the current process state */
2259 err = setup___siginfo(&sf->info, env, set->sig[0]);
2260 err |= __put_user(0, &sf->extra_size)(__builtin_choose_expr(sizeof(*(&sf->extra_size)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sf->extra_size
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sf->
extra_size)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sf->extra_size)) == 8, stq_be_p, abort)))) ((&sf->extra_size
), (0)), 0)
;
2261
2262 //err |= save_fpu_state(regs, &sf->fpu_state);
2263 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2264
2265 err |= __put_user(set->sig[0], &sf->info.si_mask)(__builtin_choose_expr(sizeof(*(&sf->info.si_mask)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sf->info.si_mask
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sf->
info.si_mask)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sf->info.si_mask)) == 8, stq_be_p, abort)))) ((&
sf->info.si_mask), (set->sig[0])), 0)
;
2266 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64) - 1; i++) {
2267 err |= __put_user(set->sig[i + 1], &sf->extramask[i])(__builtin_choose_expr(sizeof(*(&sf->extramask[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sf->extramask
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sf->
extramask[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sf->extramask[i])) == 8, stq_be_p, abort)))) ((&
sf->extramask[i]), (set->sig[i + 1])), 0)
;
2268 }
2269
2270 for (i = 0; i < 8; i++) {
2271 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i])(__builtin_choose_expr(sizeof(*(&sf->ss.locals[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sf->ss.locals
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sf->
ss.locals[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sf->ss.locals[i])) == 8, stq_be_p, abort)))) ((&
sf->ss.locals[i]), (env->regwptr[i + 8])), 0)
;
2272 }
2273 for (i = 0; i < 8; i++) {
2274 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i])(__builtin_choose_expr(sizeof(*(&sf->ss.ins[i])) == 1,
stb_p, __builtin_choose_expr(sizeof(*(&sf->ss.ins[i])
) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sf->
ss.ins[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sf->ss.ins[i])) == 8, stq_be_p, abort)))) ((&sf->ss
.ins[i]), (env->regwptr[i + 0])), 0)
;
2275 }
2276 if (err)
2277 goto sigsegv;
2278
2279 /* 3. signal handler back-trampoline and parameters */
2280 env->regwptr[UREG_FP6] = sf_addr;
2281 env->regwptr[UREG_I00] = sig;
2282 env->regwptr[UREG_I11] = sf_addr +
2283 offsetof(struct target_signal_frame, info)__builtin_offsetof(struct target_signal_frame, info);
2284 env->regwptr[UREG_I22] = sf_addr +
2285 offsetof(struct target_signal_frame, info)__builtin_offsetof(struct target_signal_frame, info);
2286
2287 /* 4. signal handler */
2288 env->pc = ka->_sa_handler;
2289 env->npc = (env->pc + 4);
2290 /* 5. return to kernel instructions */
2291 if (ka->sa_restorer)
2292 env->regwptr[UREG_I77] = ka->sa_restorer;
2293 else {
2294 uint32_t val32;
2295
2296 env->regwptr[UREG_I77] = sf_addr +
2297 offsetof(struct target_signal_frame, insns)__builtin_offsetof(struct target_signal_frame, insns) - 2 * 4;
2298
2299 /* mov __NR_sigreturn, %g1 */
2300 val32 = 0x821020d8;
2301 err |= __put_user(val32, &sf->insns[0])(__builtin_choose_expr(sizeof(*(&sf->insns[0])) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sf->insns[0])) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sf->insns[0
])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sf->
insns[0])) == 8, stq_be_p, abort)))) ((&sf->insns[0]),
(val32)), 0)
;
2302
2303 /* t 0x10 */
2304 val32 = 0x91d02010;
2305 err |= __put_user(val32, &sf->insns[1])(__builtin_choose_expr(sizeof(*(&sf->insns[1])) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sf->insns[1])) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sf->insns[1
])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sf->
insns[1])) == 8, stq_be_p, abort)))) ((&sf->insns[1]),
(val32)), 0)
;
2306 if (err)
2307 goto sigsegv;
2308
2309 /* Flush instruction space. */
2310 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2311 // tb_flush(env);
2312 }
2313 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2314 return;
2315#if 0
2316sigill_and_return:
2317 force_sig(TARGET_SIGILL4);
2318#endif
2319sigsegv:
2320 //fprintf(stderr, "force_sig\n");
2321 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2322 force_sig(TARGET_SIGSEGV11);
2323}
2324static inline int
2325restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2326{
2327 int err;
2328#if 0
2329#ifdef CONFIG_SMP
2330 if (current->flags & PF_USEDFPU)
2331 regs->psr &= ~PSR_EF;
2332#else
2333 if (current == last_task_used_math) {
2334 last_task_used_math = 0;
2335 regs->psr &= ~PSR_EF;
2336 }
2337#endif
2338 current->used_math = 1;
2339 current->flags &= ~PF_USEDFPU;
2340#endif
2341#if 0
2342 if (verify_area (VERIFY_READ0, fpu, sizeof(*fpu)))
2343 return -EFAULT14;
2344#endif
2345
2346 /* XXX: incorrect */
2347 err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
2348 (sizeof(abi_ulong) * 32));
2349 err |= __get_user(env->fsr, &fpu->si_fsr)((env->fsr) = (typeof(*&fpu->si_fsr))( __builtin_choose_expr
(sizeof(*(&fpu->si_fsr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&fpu->si_fsr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&fpu->si_fsr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&fpu->si_fsr)) == 8, ldq_be_p, abort)))) (&
fpu->si_fsr)), 0)
;
2350#if 0
2351 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth)((current->thread.fpqdepth) = (typeof(*&fpu->si_fpqdepth
))( __builtin_choose_expr(sizeof(*(&fpu->si_fpqdepth))
== 1, ldub_p, __builtin_choose_expr(sizeof(*(&fpu->si_fpqdepth
)) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(&fpu->
si_fpqdepth)) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
&fpu->si_fpqdepth)) == 8, ldq_be_p, abort)))) (&fpu
->si_fpqdepth)), 0)
;
2352 if (current->thread.fpqdepth != 0)
2353 err |= __copy_from_user(&current->thread.fpqueue[0],
2354 &fpu->si_fpqueue[0],
2355 ((sizeof(unsigned long) +
2356 (sizeof(unsigned long *)))*16));
2357#endif
2358 return err;
2359}
2360
2361
2362static void setup_rt_frame(int sig, struct target_sigaction *ka,
2363 target_siginfo_t *info,
2364 target_sigset_t *set, CPUSPARCState *env)
2365{
2366 fprintf(stderrstderr, "setup_rt_frame: not implemented\n");
2367}
2368
2369long do_sigreturn(CPUSPARCState *env)
2370{
2371 abi_ulong sf_addr;
2372 struct target_signal_frame *sf;
2373 uint32_t up_psr, pc, npc;
2374 target_sigset_t set;
2375 sigset_t host_set;
2376 int err, i;
2377
2378 sf_addr = env->regwptr[UREG_FP6];
2379 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)(sf = lock_user(0, sf_addr, sizeof(*sf), 1)))
2380 goto segv_and_exit;
2381#if 0
2382 fprintf(stderrstderr, "sigreturn\n");
2383 fprintf(stderrstderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP6], env->regwptr[UREG_SP22]);
2384#endif
2385 //cpu_dump_state(env, stderr, fprintf, 0);
2386
2387 /* 1. Make sure we are not getting garbage from the user */
2388
2389 if (sf_addr & 3)
2390 goto segv_and_exit;
2391
2392 err = __get_user(pc, &sf->info.si_regs.pc)((pc) = (typeof(*&sf->info.si_regs.pc))( __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.pc)) == 8, ldq_be_p, abort
)))) (&sf->info.si_regs.pc)), 0)
;
2393 err |= __get_user(npc, &sf->info.si_regs.npc)((npc) = (typeof(*&sf->info.si_regs.npc))( __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.npc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.npc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.npc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.npc)) == 8, ldq_be_p, abort
)))) (&sf->info.si_regs.npc)), 0)
;
2394
2395 if ((pc | npc) & 3)
2396 goto segv_and_exit;
2397
2398 /* 2. Restore the state */
2399 err |= __get_user(up_psr, &sf->info.si_regs.psr)((up_psr) = (typeof(*&sf->info.si_regs.psr))( __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.psr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.psr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.psr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.psr)) == 8, ldq_be_p, abort
)))) (&sf->info.si_regs.psr)), 0)
;
2400
2401 /* User can only change condition codes and FPU enabling in %psr. */
2402 env->psr = (up_psr & (PSR_ICC((1 << 23)|(1 << 22)|(1 << 21)|(1 << 20
))
/* | PSR_EF */))
2403 | (env->psr & ~(PSR_ICC((1 << 23)|(1 << 22)|(1 << 21)|(1 << 20
))
/* | PSR_EF */));
2404
2405 env->pc = pc;
2406 env->npc = npc;
2407 err |= __get_user(env->y, &sf->info.si_regs.y)((env->y) = (typeof(*&sf->info.si_regs.y))( __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.y)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.y)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.y)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.y)) == 8, ldq_be_p, abort)
))) (&sf->info.si_regs.y)), 0)
;
2408 for (i=0; i < 8; i++) {
2409 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i])((env->gregs[i]) = (typeof(*&sf->info.si_regs.u_regs
[i]))( __builtin_choose_expr(sizeof(*(&sf->info.si_regs
.u_regs[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&
sf->info.si_regs.u_regs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.u_regs[i])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&sf->info.si_regs.u_regs
[i])) == 8, ldq_be_p, abort)))) (&sf->info.si_regs.u_regs
[i])), 0)
;
2410 }
2411 for (i=0; i < 8; i++) {
2412 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8])((env->regwptr[i + 0]) = (typeof(*&sf->info.si_regs
.u_regs[i+8]))( __builtin_choose_expr(sizeof(*(&sf->info
.si_regs.u_regs[i+8])) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&sf->info.si_regs.u_regs[i+8])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_regs.u_regs[i+8])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&sf->info.si_regs.u_regs
[i+8])) == 8, ldq_be_p, abort)))) (&sf->info.si_regs.u_regs
[i+8])), 0)
;
2413 }
2414
2415 /* FIXME: implement FPU save/restore:
2416 * __get_user(fpu_save, &sf->fpu_save);
2417 * if (fpu_save)
2418 * err |= restore_fpu_state(env, fpu_save);
2419 */
2420
2421 /* This is pretty much atomic, no amount locking would prevent
2422 * the races which exist anyways.
2423 */
2424 err |= __get_user(set.sig[0], &sf->info.si_mask)((set.sig[0]) = (typeof(*&sf->info.si_mask))( __builtin_choose_expr
(sizeof(*(&sf->info.si_mask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_mask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_mask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->info.si_mask)) == 8, ldq_be_p, abort)))
) (&sf->info.si_mask)), 0)
;
2425 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
2426 err |= (__get_user(set.sig[i], &sf->extramask[i - 1])((set.sig[i]) = (typeof(*&sf->extramask[i - 1]))( __builtin_choose_expr
(sizeof(*(&sf->extramask[i - 1])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sf->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sf->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sf->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&sf->extramask[i - 1])), 0)
);
2427 }
2428
2429 target_to_host_sigset_internal(&host_set, &set);
2430 sigprocmask(SIG_SETMASK2, &host_set, NULL((void*)0));
2431
2432 if (err)
2433 goto segv_and_exit;
2434 unlock_user_struct(sf, sf_addr, 0)unlock_user(sf, sf_addr, (0) ? sizeof(*sf) : 0);
2435 return env->regwptr[0];
2436
2437segv_and_exit:
2438 unlock_user_struct(sf, sf_addr, 0)unlock_user(sf, sf_addr, (0) ? sizeof(*sf) : 0);
2439 force_sig(TARGET_SIGSEGV11);
2440}
2441
2442long do_rt_sigreturn(CPUSPARCState *env)
2443{
2444 fprintf(stderrstderr, "do_rt_sigreturn: not implemented\n");
2445 return -TARGET_ENOSYS38;
2446}
2447
2448#if defined(TARGET_SPARC641) && !defined(TARGET_ABI32)
2449#define MC_TSTATE0 0
2450#define MC_PC1 1
2451#define MC_NPC2 2
2452#define MC_Y3 3
2453#define MC_G14 4
2454#define MC_G25 5
2455#define MC_G36 6
2456#define MC_G47 7
2457#define MC_G58 8
2458#define MC_G69 9
2459#define MC_G710 10
2460#define MC_O011 11
2461#define MC_O112 12
2462#define MC_O213 13
2463#define MC_O314 14
2464#define MC_O415 15
2465#define MC_O516 16
2466#define MC_O617 17
2467#define MC_O718 18
2468#define MC_NGREG19 19
2469
2470typedef abi_ulong target_mc_greg_t;
2471typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG19];
2472
2473struct target_mc_fq {
2474 abi_ulong *mcfq_addr;
2475 uint32_t mcfq_insn;
2476};
2477
2478struct target_mc_fpu {
2479 union {
2480 uint32_t sregs[32];
2481 uint64_t dregs[32];
2482 //uint128_t qregs[16];
2483 } mcfpu_fregs;
2484 abi_ulong mcfpu_fsr;
2485 abi_ulong mcfpu_fprs;
2486 abi_ulong mcfpu_gsr;
2487 struct target_mc_fq *mcfpu_fq;
2488 unsigned char mcfpu_qcnt;
2489 unsigned char mcfpu_qentsz;
2490 unsigned char mcfpu_enab;
2491};
2492typedef struct target_mc_fpu target_mc_fpu_t;
2493
2494typedef struct {
2495 target_mc_gregset_t mc_gregs;
2496 target_mc_greg_t mc_fp;
2497 target_mc_greg_t mc_i7;
2498 target_mc_fpu_t mc_fpregs;
2499} target_mcontext_t;
2500
2501struct target_ucontext {
2502 struct target_ucontext *tuc_link;
2503 abi_ulong tuc_flags;
2504 target_sigset_t tuc_sigmask;
2505 target_mcontext_t tuc_mcontext;
2506};
2507
2508/* A V9 register window */
2509struct target_reg_window {
2510 abi_ulong locals[8];
2511 abi_ulong ins[8];
2512};
2513
2514#define TARGET_STACK_BIAS2047 2047
2515
2516/* {set, get}context() needed for 64-bit SparcLinux userland. */
2517void sparc64_set_context(CPUSPARCState *env)
2518{
2519 abi_ulong ucp_addr;
2520 struct target_ucontext *ucp;
2521 target_mc_gregset_t *grp;
2522 abi_ulong pc, npc, tstate;
2523 abi_ulong fp, i7, w_addr;
2524 int err;
2525 unsigned int i;
2526
2527 ucp_addr = env->regwptr[UREG_I00];
2528 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)(ucp = lock_user(0, ucp_addr, sizeof(*ucp), 1)))
2529 goto do_sigsegv;
2530 grp = &ucp->tuc_mcontext.mc_gregs;
2531 err = __get_user(pc, &((*grp)[MC_PC]))((pc) = (typeof(*&((*grp)[1])))( __builtin_choose_expr(sizeof
(*(&((*grp)[1]))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&((*grp)[1]))) == 2, lduw_be_p, __builtin_choose_expr(
sizeof(*(&((*grp)[1]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[1]))) == 8, ldq_be_p, abort)))) (&
((*grp)[1]))), 0)
;
2532 err |= __get_user(npc, &((*grp)[MC_NPC]))((npc) = (typeof(*&((*grp)[2])))( __builtin_choose_expr(sizeof
(*(&((*grp)[2]))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&((*grp)[2]))) == 2, lduw_be_p, __builtin_choose_expr(
sizeof(*(&((*grp)[2]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[2]))) == 8, ldq_be_p, abort)))) (&
((*grp)[2]))), 0)
;
2533 if (err || ((pc | npc) & 3))
2534 goto do_sigsegv;
2535 if (env->regwptr[UREG_I11]) {
2536 target_sigset_t target_set;
2537 sigset_t set;
2538
2539 if (TARGET_NSIG_WORDS(64 / 64) == 1) {
2540 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0])((target_set.sig[0]) = (typeof(*&ucp->tuc_sigmask.sig[
0]))( __builtin_choose_expr(sizeof(*(&ucp->tuc_sigmask
.sig[0])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&ucp
->tuc_sigmask.sig[0])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&ucp->tuc_sigmask.sig[0])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&ucp->tuc_sigmask.sig[0])) == 8, ldq_be_p, abort
)))) (&ucp->tuc_sigmask.sig[0])), 0)
)
2541 goto do_sigsegv;
2542 } else {
2543 abi_ulong *src, *dst;
2544 src = ucp->tuc_sigmask.sig;
2545 dst = target_set.sig;
2546 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++, dst++, src++) {
2547 err |= __get_user(*dst, src)((*dst) = (typeof(*src))( __builtin_choose_expr(sizeof(*(src)
) == 1, ldub_p, __builtin_choose_expr(sizeof(*(src)) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(src)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(src)) == 8, ldq_be_p, abort)))) (src)), 0)
;
2548 }
2549 if (err)
2550 goto do_sigsegv;
2551 }
2552 target_to_host_sigset_internal(&set, &target_set);
2553 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
2554 }
2555 env->pc = pc;
2556 env->npc = npc;
2557 err |= __get_user(env->y, &((*grp)[MC_Y]))((env->y) = (typeof(*&((*grp)[3])))( __builtin_choose_expr
(sizeof(*(&((*grp)[3]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&((*grp)[3]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[3]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[3]))) == 8, ldq_be_p, abort)))) (&
((*grp)[3]))), 0)
;
2558 err |= __get_user(tstate, &((*grp)[MC_TSTATE]))((tstate) = (typeof(*&((*grp)[0])))( __builtin_choose_expr
(sizeof(*(&((*grp)[0]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&((*grp)[0]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[0]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&((*grp)[0]))) == 8, ldq_be_p, abort)))) (&
((*grp)[0]))), 0)
;
2559 env->asi = (tstate >> 24) & 0xff;
2560 cpu_put_ccr(env, tstate >> 32);
2561 cpu_put_cwp64(env, tstate & 0x1f);
2562 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]))((env->gregs[1]) = (typeof(*(&(*grp)[4])))( __builtin_choose_expr
(sizeof(*((&(*grp)[4]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[4]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[4]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[4]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[4]))), 0)
;
2563 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]))((env->gregs[2]) = (typeof(*(&(*grp)[5])))( __builtin_choose_expr
(sizeof(*((&(*grp)[5]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[5]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[5]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[5]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[5]))), 0)
;
2564 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]))((env->gregs[3]) = (typeof(*(&(*grp)[6])))( __builtin_choose_expr
(sizeof(*((&(*grp)[6]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[6]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[6]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[6]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[6]))), 0)
;
2565 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]))((env->gregs[4]) = (typeof(*(&(*grp)[7])))( __builtin_choose_expr
(sizeof(*((&(*grp)[7]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[7]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[7]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[7]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[7]))), 0)
;
2566 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]))((env->gregs[5]) = (typeof(*(&(*grp)[8])))( __builtin_choose_expr
(sizeof(*((&(*grp)[8]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[8]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[8]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[8]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[8]))), 0)
;
2567 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]))((env->gregs[6]) = (typeof(*(&(*grp)[9])))( __builtin_choose_expr
(sizeof(*((&(*grp)[9]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[9]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[9]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[9]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[9]))), 0)
;
2568 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]))((env->gregs[7]) = (typeof(*(&(*grp)[10])))( __builtin_choose_expr
(sizeof(*((&(*grp)[10]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[10]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[10]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[10]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[10]))), 0)
;
2569 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]))((env->regwptr[0]) = (typeof(*(&(*grp)[11])))( __builtin_choose_expr
(sizeof(*((&(*grp)[11]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[11]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[11]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[11]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[11]))), 0)
;
2570 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]))((env->regwptr[1]) = (typeof(*(&(*grp)[12])))( __builtin_choose_expr
(sizeof(*((&(*grp)[12]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[12]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[12]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[12]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[12]))), 0)
;
2571 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]))((env->regwptr[2]) = (typeof(*(&(*grp)[13])))( __builtin_choose_expr
(sizeof(*((&(*grp)[13]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[13]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[13]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[13]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[13]))), 0)
;
2572 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]))((env->regwptr[3]) = (typeof(*(&(*grp)[14])))( __builtin_choose_expr
(sizeof(*((&(*grp)[14]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[14]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[14]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[14]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[14]))), 0)
;
2573 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]))((env->regwptr[4]) = (typeof(*(&(*grp)[15])))( __builtin_choose_expr
(sizeof(*((&(*grp)[15]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[15]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[15]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[15]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[15]))), 0)
;
2574 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]))((env->regwptr[5]) = (typeof(*(&(*grp)[16])))( __builtin_choose_expr
(sizeof(*((&(*grp)[16]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[16]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[16]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[16]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[16]))), 0)
;
2575 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]))((env->regwptr[6]) = (typeof(*(&(*grp)[17])))( __builtin_choose_expr
(sizeof(*((&(*grp)[17]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[17]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[17]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[17]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[17]))), 0)
;
2576 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]))((env->regwptr[7]) = (typeof(*(&(*grp)[18])))( __builtin_choose_expr
(sizeof(*((&(*grp)[18]))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*((&(*grp)[18]))) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[18]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((&(*grp)[18]))) == 8, ldq_be_p, abort)))) ((&
(*grp)[18]))), 0)
;
2577
2578 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp))((fp) = (typeof(*&(ucp->tuc_mcontext.mc_fp)))( __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_fp))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_fp))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_fp
))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(&(ucp->
tuc_mcontext.mc_fp))) == 8, ldq_be_p, abort)))) (&(ucp->
tuc_mcontext.mc_fp))), 0)
;
2579 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7))((i7) = (typeof(*&(ucp->tuc_mcontext.mc_i7)))( __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_i7))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_i7))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_i7
))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(&(ucp->
tuc_mcontext.mc_i7))) == 8, ldq_be_p, abort)))) (&(ucp->
tuc_mcontext.mc_i7))), 0)
;
2580
2581 w_addr = TARGET_STACK_BIAS2047+env->regwptr[UREG_I66];
2582 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[6])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(1, __gaddr, sizeof(abi_ulong), 0))) { __ret = (__builtin_choose_expr
(sizeof(*(__hptr)) == 1, stb_p, __builtin_choose_expr(sizeof(
*(__hptr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(__hptr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(__hptr)) ==
8, stq_be_p, abort)))) ((__hptr), ((fp))), 0); unlock_user(__hptr
, __gaddr, sizeof(abi_ulong)); } else __ret = -14; __ret; })
2583 abi_ulong)({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[6])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(1, __gaddr, sizeof(abi_ulong), 0))) { __ret = (__builtin_choose_expr
(sizeof(*(__hptr)) == 1, stb_p, __builtin_choose_expr(sizeof(
*(__hptr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(__hptr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(__hptr)) ==
8, stq_be_p, abort)))) ((__hptr), ((fp))), 0); unlock_user(__hptr
, __gaddr, sizeof(abi_ulong)); } else __ret = -14; __ret; })
!= 0)
2584 goto do_sigsegv;
2585 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[7])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(1, __gaddr, sizeof(abi_ulong), 0))) { __ret = (__builtin_choose_expr
(sizeof(*(__hptr)) == 1, stb_p, __builtin_choose_expr(sizeof(
*(__hptr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(__hptr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(__hptr)) ==
8, stq_be_p, abort)))) ((__hptr), ((i7))), 0); unlock_user(__hptr
, __gaddr, sizeof(abi_ulong)); } else __ret = -14; __ret; })
2586 abi_ulong)({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[7])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(1, __gaddr, sizeof(abi_ulong), 0))) { __ret = (__builtin_choose_expr
(sizeof(*(__hptr)) == 1, stb_p, __builtin_choose_expr(sizeof(
*(__hptr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(__hptr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(__hptr)) ==
8, stq_be_p, abort)))) ((__hptr), ((i7))), 0); unlock_user(__hptr
, __gaddr, sizeof(abi_ulong)); } else __ret = -14; __ret; })
!= 0)
2587 goto do_sigsegv;
2588 /* FIXME this does not match how the kernel handles the FPU in
2589 * its sparc64_set_context implementation. In particular the FPU
2590 * is only restored if fenab is non-zero in:
2591 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2592 */
2593 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs))((env->fprs) = (typeof(*&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fprs)))( __builtin_choose_expr(sizeof(*(&(ucp->
tuc_mcontext.mc_fpregs.mcfpu_fprs))) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs))) ==
2, lduw_be_p, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext
.mc_fpregs.mcfpu_fprs))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs))) ==
8, ldq_be_p, abort)))) (&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fprs))), 0)
;
2594 {
2595 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2596 for (i = 0; i < 64; i++, src++) {
2597 if (i & 1) {
2598 err |= __get_user(env->fpr[i/2].l.lower, src)((env->fpr[i/2].l.lower) = (typeof(*src))( __builtin_choose_expr
(sizeof(*(src)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(
src)) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(src)) ==
4, ldl_be_p, __builtin_choose_expr(sizeof(*(src)) == 8, ldq_be_p
, abort)))) (src)), 0)
;
2599 } else {
2600 err |= __get_user(env->fpr[i/2].l.upper, src)((env->fpr[i/2].l.upper) = (typeof(*src))( __builtin_choose_expr
(sizeof(*(src)) == 1, ldub_p, __builtin_choose_expr(sizeof(*(
src)) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(src)) ==
4, ldl_be_p, __builtin_choose_expr(sizeof(*(src)) == 8, ldq_be_p
, abort)))) (src)), 0)
;
2601 }
2602 }
2603 }
2604 err |= __get_user(env->fsr,((env->fsr) = (typeof(*&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fsr)))( __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext
.mc_fpregs.mcfpu_fsr))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fsr))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))) == 8, ldq_be_p
, abort)))) (&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))
), 0)
2605 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))((env->fsr) = (typeof(*&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fsr)))( __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext
.mc_fpregs.mcfpu_fsr))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_fsr))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))) == 8, ldq_be_p
, abort)))) (&(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr))
), 0)
;
2606 err |= __get_user(env->gsr,((env->gsr) = (typeof(*&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_gsr)))( __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext
.mc_fpregs.mcfpu_gsr))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_gsr))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))) == 8, ldq_be_p
, abort)))) (&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))
), 0)
2607 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))((env->gsr) = (typeof(*&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_gsr)))( __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext
.mc_fpregs.mcfpu_gsr))) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&(ucp->tuc_mcontext.mc_fpregs
.mcfpu_gsr))) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(
&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))) == 8, ldq_be_p
, abort)))) (&(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr))
), 0)
;
2608 if (err)
2609 goto do_sigsegv;
2610 unlock_user_struct(ucp, ucp_addr, 0)unlock_user(ucp, ucp_addr, (0) ? sizeof(*ucp) : 0);
2611 return;
2612 do_sigsegv:
2613 unlock_user_struct(ucp, ucp_addr, 0)unlock_user(ucp, ucp_addr, (0) ? sizeof(*ucp) : 0);
2614 force_sig(TARGET_SIGSEGV11);
2615}
2616
2617void sparc64_get_context(CPUSPARCState *env)
2618{
2619 abi_ulong ucp_addr;
2620 struct target_ucontext *ucp;
2621 target_mc_gregset_t *grp;
2622 target_mcontext_t *mcp;
2623 abi_ulong fp, i7, w_addr;
2624 int err;
2625 unsigned int i;
2626 target_sigset_t target_set;
2627 sigset_t set;
2628
2629 ucp_addr = env->regwptr[UREG_I00];
2630 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)(ucp = lock_user(1, ucp_addr, sizeof(*ucp), 0)))
2631 goto do_sigsegv;
2632
2633 mcp = &ucp->tuc_mcontext;
2634 grp = &mcp->mc_gregs;
2635
2636 /* Skip over the trap instruction, first. */
2637 env->pc = env->npc;
2638 env->npc += 4;
2639
2640 err = 0;
2641
2642 sigprocmask(0, NULL((void*)0), &set);
2643 host_to_target_sigset_internal(&target_set, &set);
2644 if (TARGET_NSIG_WORDS(64 / 64) == 1) {
2645 err |= __put_user(target_set.sig[0],(__builtin_choose_expr(sizeof(*((abi_ulong *)&ucp->tuc_sigmask
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((abi_ulong *)&
ucp->tuc_sigmask)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((abi_ulong *)&ucp->tuc_sigmask)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&ucp->tuc_sigmask)) == 8, stq_be_p
, abort)))) (((abi_ulong *)&ucp->tuc_sigmask), (target_set
.sig[0])), 0)
2646 (abi_ulong *)&ucp->tuc_sigmask)(__builtin_choose_expr(sizeof(*((abi_ulong *)&ucp->tuc_sigmask
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((abi_ulong *)&
ucp->tuc_sigmask)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((abi_ulong *)&ucp->tuc_sigmask)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&ucp->tuc_sigmask)) == 8, stq_be_p
, abort)))) (((abi_ulong *)&ucp->tuc_sigmask), (target_set
.sig[0])), 0)
;
2647 } else {
2648 abi_ulong *src, *dst;
2649 src = target_set.sig;
2650 dst = ucp->tuc_sigmask.sig;
2651 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++, dst++, src++) {
2652 err |= __put_user(*src, dst)(__builtin_choose_expr(sizeof(*(dst)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(dst)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(dst)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(dst)) ==
8, stq_be_p, abort)))) ((dst), (*src)), 0)
;
2653 }
2654 if (err)
2655 goto do_sigsegv;
2656 }
2657
2658 /* XXX: tstate must be saved properly */
2659 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2660 err |= __put_user(env->pc, &((*grp)[MC_PC]))(__builtin_choose_expr(sizeof(*(&((*grp)[1]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[1]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[1]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[1]))) == 8, stq_be_p
, abort)))) ((&((*grp)[1])), (env->pc)), 0)
;
2661 err |= __put_user(env->npc, &((*grp)[MC_NPC]))(__builtin_choose_expr(sizeof(*(&((*grp)[2]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[2]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[2]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[2]))) == 8, stq_be_p
, abort)))) ((&((*grp)[2])), (env->npc)), 0)
;
2662 err |= __put_user(env->y, &((*grp)[MC_Y]))(__builtin_choose_expr(sizeof(*(&((*grp)[3]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[3]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[3]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[3]))) == 8, stq_be_p
, abort)))) ((&((*grp)[3])), (env->y)), 0)
;
2663 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]))(__builtin_choose_expr(sizeof(*(&((*grp)[4]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[4]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[4]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[4]))) == 8, stq_be_p
, abort)))) ((&((*grp)[4])), (env->gregs[1])), 0)
;
2664 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]))(__builtin_choose_expr(sizeof(*(&((*grp)[5]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[5]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[5]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[5]))) == 8, stq_be_p
, abort)))) ((&((*grp)[5])), (env->gregs[2])), 0)
;
2665 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]))(__builtin_choose_expr(sizeof(*(&((*grp)[6]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[6]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[6]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[6]))) == 8, stq_be_p
, abort)))) ((&((*grp)[6])), (env->gregs[3])), 0)
;
2666 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]))(__builtin_choose_expr(sizeof(*(&((*grp)[7]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[7]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[7]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[7]))) == 8, stq_be_p
, abort)))) ((&((*grp)[7])), (env->gregs[4])), 0)
;
2667 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]))(__builtin_choose_expr(sizeof(*(&((*grp)[8]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[8]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[8]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[8]))) == 8, stq_be_p
, abort)))) ((&((*grp)[8])), (env->gregs[5])), 0)
;
2668 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]))(__builtin_choose_expr(sizeof(*(&((*grp)[9]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[9]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[9]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[9]))) == 8, stq_be_p
, abort)))) ((&((*grp)[9])), (env->gregs[6])), 0)
;
2669 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]))(__builtin_choose_expr(sizeof(*(&((*grp)[10]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[10]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[10]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[10]))) == 8, stq_be_p
, abort)))) ((&((*grp)[10])), (env->gregs[7])), 0)
;
2670 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]))(__builtin_choose_expr(sizeof(*(&((*grp)[11]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[11]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[11]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[11]))) == 8, stq_be_p
, abort)))) ((&((*grp)[11])), (env->regwptr[0])), 0)
;
2671 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]))(__builtin_choose_expr(sizeof(*(&((*grp)[12]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[12]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[12]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[12]))) == 8, stq_be_p
, abort)))) ((&((*grp)[12])), (env->regwptr[1])), 0)
;
2672 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]))(__builtin_choose_expr(sizeof(*(&((*grp)[13]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[13]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[13]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[13]))) == 8, stq_be_p
, abort)))) ((&((*grp)[13])), (env->regwptr[2])), 0)
;
2673 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]))(__builtin_choose_expr(sizeof(*(&((*grp)[14]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[14]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[14]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[14]))) == 8, stq_be_p
, abort)))) ((&((*grp)[14])), (env->regwptr[3])), 0)
;
2674 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]))(__builtin_choose_expr(sizeof(*(&((*grp)[15]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[15]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[15]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[15]))) == 8, stq_be_p
, abort)))) ((&((*grp)[15])), (env->regwptr[4])), 0)
;
2675 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]))(__builtin_choose_expr(sizeof(*(&((*grp)[16]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[16]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[16]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[16]))) == 8, stq_be_p
, abort)))) ((&((*grp)[16])), (env->regwptr[5])), 0)
;
2676 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]))(__builtin_choose_expr(sizeof(*(&((*grp)[17]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[17]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[17]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[17]))) == 8, stq_be_p
, abort)))) ((&((*grp)[17])), (env->regwptr[6])), 0)
;
2677 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]))(__builtin_choose_expr(sizeof(*(&((*grp)[18]))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&((*grp)[18]))) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[18]))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&((*grp)[18]))) == 8, stq_be_p
, abort)))) ((&((*grp)[18])), (env->regwptr[7])), 0)
;
2678
2679 w_addr = TARGET_STACK_BIAS2047+env->regwptr[UREG_I66];
2680 fp = i7 = 0;
Value stored to 'fp' is never read
2681 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[6])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(0, __gaddr, sizeof(abi_ulong), 1))) { __ret = (((fp)) = (typeof
(*__hptr))( __builtin_choose_expr(sizeof(*(__hptr)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(__hptr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(__hptr)) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(__hptr)) == 8, ldq_be_p, abort)))) (__hptr)), 0); unlock_user
(__hptr, __gaddr, 0); } else { (fp) = 0; __ret = -14; } __ret
; })
2682 abi_ulong)({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[6])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(0, __gaddr, sizeof(abi_ulong), 1))) { __ret = (((fp)) = (typeof
(*__hptr))( __builtin_choose_expr(sizeof(*(__hptr)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(__hptr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(__hptr)) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(__hptr)) == 8, ldq_be_p, abort)))) (__hptr)), 0); unlock_user
(__hptr, __gaddr, 0); } else { (fp) = 0; __ret = -14; } __ret
; })
!= 0)
2683 goto do_sigsegv;
2684 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[7])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(0, __gaddr, sizeof(abi_ulong), 1))) { __ret = (((i7)) = (typeof
(*__hptr))( __builtin_choose_expr(sizeof(*(__hptr)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(__hptr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(__hptr)) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(__hptr)) == 8, ldq_be_p, abort)))) (__hptr)), 0); unlock_user
(__hptr, __gaddr, 0); } else { (i7) = 0; __ret = -14; } __ret
; })
2685 abi_ulong)({ abi_ulong __gaddr = (w_addr + __builtin_offsetof(struct target_reg_window
, ins[7])); abi_ulong *__hptr; abi_long __ret; if ((__hptr = lock_user
(0, __gaddr, sizeof(abi_ulong), 1))) { __ret = (((i7)) = (typeof
(*__hptr))( __builtin_choose_expr(sizeof(*(__hptr)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(__hptr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(__hptr)) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(__hptr)) == 8, ldq_be_p, abort)))) (__hptr)), 0); unlock_user
(__hptr, __gaddr, 0); } else { (i7) = 0; __ret = -14; } __ret
; })
!= 0)
2686 goto do_sigsegv;
2687 err |= __put_user(fp, &(mcp->mc_fp))(__builtin_choose_expr(sizeof(*(&(mcp->mc_fp))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&(mcp->mc_fp))) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&(mcp->mc_fp
))) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&(mcp->
mc_fp))) == 8, stq_be_p, abort)))) ((&(mcp->mc_fp)), (
fp)), 0)
;
2688 err |= __put_user(i7, &(mcp->mc_i7))(__builtin_choose_expr(sizeof(*(&(mcp->mc_i7))) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&(mcp->mc_i7))) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&(mcp->mc_i7
))) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&(mcp->
mc_i7))) == 8, stq_be_p, abort)))) ((&(mcp->mc_i7)), (
i7)), 0)
;
2689
2690 {
2691 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2692 for (i = 0; i < 64; i++, dst++) {
2693 if (i & 1) {
2694 err |= __put_user(env->fpr[i/2].l.lower, dst)(__builtin_choose_expr(sizeof(*(dst)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(dst)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(dst)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(dst)) ==
8, stq_be_p, abort)))) ((dst), (env->fpr[i/2].l.lower)), 0
)
;
2695 } else {
2696 err |= __put_user(env->fpr[i/2].l.upper, dst)(__builtin_choose_expr(sizeof(*(dst)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(dst)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(dst)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(dst)) ==
8, stq_be_p, abort)))) ((dst), (env->fpr[i/2].l.upper)), 0
)
;
2697 }
2698 }
2699 }
2700 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr))(__builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_fsr
))) == 1, stb_p, __builtin_choose_expr(sizeof(*(&(mcp->
mc_fpregs.mcfpu_fsr))) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&(mcp->mc_fpregs.mcfpu_fsr))) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_fsr
))) == 8, stq_be_p, abort)))) ((&(mcp->mc_fpregs.mcfpu_fsr
)), (env->fsr)), 0)
;
2701 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr))(__builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_gsr
))) == 1, stb_p, __builtin_choose_expr(sizeof(*(&(mcp->
mc_fpregs.mcfpu_gsr))) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&(mcp->mc_fpregs.mcfpu_gsr))) == 4, stl_be_p,
__builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_gsr
))) == 8, stq_be_p, abort)))) ((&(mcp->mc_fpregs.mcfpu_gsr
)), (env->gsr)), 0)
;
2702 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs))(__builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_fprs
))) == 1, stb_p, __builtin_choose_expr(sizeof(*(&(mcp->
mc_fpregs.mcfpu_fprs))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&(mcp->mc_fpregs.mcfpu_fprs))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&(mcp->mc_fpregs.mcfpu_fprs
))) == 8, stq_be_p, abort)))) ((&(mcp->mc_fpregs.mcfpu_fprs
)), (env->fprs)), 0)
;
2703
2704 if (err)
2705 goto do_sigsegv;
2706 unlock_user_struct(ucp, ucp_addr, 1)unlock_user(ucp, ucp_addr, (1) ? sizeof(*ucp) : 0);
2707 return;
2708 do_sigsegv:
2709 unlock_user_struct(ucp, ucp_addr, 1)unlock_user(ucp, ucp_addr, (1) ? sizeof(*ucp) : 0);
2710 force_sig(TARGET_SIGSEGV11);
2711}
2712#endif
2713#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2714
2715# if defined(TARGET_ABI_MIPSO32)
2716struct target_sigcontext {
2717 uint32_t sc_regmask; /* Unused */
2718 uint32_t sc_status;
2719 uint64_t sc_pc;
2720 uint64_t sc_regs[32];
2721 uint64_t sc_fpregs[32];
2722 uint32_t sc_ownedfp; /* Unused */
2723 uint32_t sc_fpc_csr;
2724 uint32_t sc_fpc_eir; /* Unused */
2725 uint32_t sc_used_math;
2726 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2727 uint32_t pad0;
2728 uint64_t sc_mdhi;
2729 uint64_t sc_mdlo;
2730 target_ulong sc_hi1; /* Was sc_cause */
2731 target_ulong sc_lo1; /* Was sc_badvaddr */
2732 target_ulong sc_hi2; /* Was sc_sigset[4] */
2733 target_ulong sc_lo2;
2734 target_ulong sc_hi3;
2735 target_ulong sc_lo3;
2736};
2737# else /* N32 || N64 */
2738struct target_sigcontext {
2739 uint64_t sc_regs[32];
2740 uint64_t sc_fpregs[32];
2741 uint64_t sc_mdhi;
2742 uint64_t sc_hi1;
2743 uint64_t sc_hi2;
2744 uint64_t sc_hi3;
2745 uint64_t sc_mdlo;
2746 uint64_t sc_lo1;
2747 uint64_t sc_lo2;
2748 uint64_t sc_lo3;
2749 uint64_t sc_pc;
2750 uint32_t sc_fpc_csr;
2751 uint32_t sc_used_math;
2752 uint32_t sc_dsp;
2753 uint32_t sc_reserved;
2754};
2755# endif /* O32 */
2756
2757struct sigframe {
2758 uint32_t sf_ass[4]; /* argument save space for o32 */
2759 uint32_t sf_code[2]; /* signal trampoline */
2760 struct target_sigcontext sf_sc;
2761 target_sigset_t sf_mask;
2762};
2763
2764struct target_ucontext {
2765 target_ulong tuc_flags;
2766 target_ulong tuc_link;
2767 target_stack_t tuc_stack;
2768 target_ulong pad0;
2769 struct target_sigcontext tuc_mcontext;
2770 target_sigset_t tuc_sigmask;
2771};
2772
2773struct target_rt_sigframe {
2774 uint32_t rs_ass[4]; /* argument save space for o32 */
2775 uint32_t rs_code[2]; /* signal trampoline */
2776 struct target_siginfo rs_info;
2777 struct target_ucontext rs_uc;
2778};
2779
2780/* Install trampoline to jump back from signal handler */
2781static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2782{
2783 int err = 0;
2784
2785 /*
2786 * Set up the return code ...
2787 *
2788 * li v0, __NR__foo_sigreturn
2789 * syscall
2790 */
2791
2792 err |= __put_user(0x24020000 + syscall, tramp + 0)(__builtin_choose_expr(sizeof(*(tramp + 0)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(tramp + 0)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(tramp + 0)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(tramp + 0)) == 8, stq_be_p, abort)))) ((tramp + 0), (0x24020000
+ syscall)), 0)
;
2793 err |= __put_user(0x0000000c , tramp + 1)(__builtin_choose_expr(sizeof(*(tramp + 1)) == 1, stb_p, __builtin_choose_expr
(sizeof(*(tramp + 1)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(tramp + 1)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(tramp + 1)) == 8, stq_be_p, abort)))) ((tramp + 1), (0x0000000c
)), 0)
;
2794 return err;
2795}
2796
2797static inline int
2798setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2799{
2800 int err = 0;
2801 int i;
2802
2803 err |= __put_user(exception_resume_pc(regs), &sc->sc_pc)(__builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 8, stq_be_p
, abort)))) ((&sc->sc_pc), (exception_resume_pc(regs))
), 0)
;
2804 regs->hflags &= ~MIPS_HFLAG_BMASK;
2805
2806 __put_user(0, &sc->sc_regs[0])(__builtin_choose_expr(sizeof(*(&sc->sc_regs[0])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_regs[0
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_regs[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->sc_regs[0])) == 8, stq_be_p, abort)))) ((&sc->sc_regs
[0]), (0)), 0)
;
2807 for (i = 1; i < 32; ++i) {
2808 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i])(__builtin_choose_expr(sizeof(*(&sc->sc_regs[i])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_regs[i
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_regs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->sc_regs[i])) == 8, stq_be_p, abort)))) ((&sc->sc_regs
[i]), (regs->active_tc.gpr[i])), 0)
;
2809 }
2810
2811 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi)(__builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 8, stq_be_p
, abort)))) ((&sc->sc_mdhi), (regs->active_tc.HI[0]
)), 0)
;
2812 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo)(__builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 8, stq_be_p
, abort)))) ((&sc->sc_mdlo), (regs->active_tc.LO[0]
)), 0)
;
2813
2814 /* Rather than checking for dsp existence, always copy. The storage
2815 would just be garbage otherwise. */
2816 err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1)(__builtin_choose_expr(sizeof(*(&sc->sc_hi1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi1)) == 8, stq_be_p
, abort)))) ((&sc->sc_hi1), (regs->active_tc.HI[1])
), 0)
;
2817 err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2)(__builtin_choose_expr(sizeof(*(&sc->sc_hi2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi2)) == 8, stq_be_p
, abort)))) ((&sc->sc_hi2), (regs->active_tc.HI[2])
), 0)
;
2818 err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3)(__builtin_choose_expr(sizeof(*(&sc->sc_hi3)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi3)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi3)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_hi3)) == 8, stq_be_p
, abort)))) ((&sc->sc_hi3), (regs->active_tc.HI[3])
), 0)
;
2819 err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1)(__builtin_choose_expr(sizeof(*(&sc->sc_lo1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo1)) == 8, stq_be_p
, abort)))) ((&sc->sc_lo1), (regs->active_tc.LO[1])
), 0)
;
2820 err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2)(__builtin_choose_expr(sizeof(*(&sc->sc_lo2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo2)) == 8, stq_be_p
, abort)))) ((&sc->sc_lo2), (regs->active_tc.LO[2])
), 0)
;
2821 err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3)(__builtin_choose_expr(sizeof(*(&sc->sc_lo3)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo3)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo3)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_lo3)) == 8, stq_be_p
, abort)))) ((&sc->sc_lo3), (regs->active_tc.LO[3])
), 0)
;
2822 {
2823 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2824 err |= __put_user(dsp, &sc->sc_dsp)(__builtin_choose_expr(sizeof(*(&sc->sc_dsp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_dsp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_dsp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_dsp)) == 8, stq_be_p
, abort)))) ((&sc->sc_dsp), (dsp)), 0)
;
2825 }
2826
2827 err |= __put_user(1, &sc->sc_used_math)(__builtin_choose_expr(sizeof(*(&sc->sc_used_math)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_used_math
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_used_math)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sc->sc_used_math)) == 8, stq_be_p, abort)))) ((&
sc->sc_used_math), (1)), 0)
;
2828
2829 for (i = 0; i < 32; ++i) {
2830 err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i])(__builtin_choose_expr(sizeof(*(&sc->sc_fpregs[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_fpregs
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_fpregs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sc->sc_fpregs[i])) == 8, stq_be_p, abort)))) ((&
sc->sc_fpregs[i]), (regs->active_fpu.fpr[i].d)), 0)
;
2831 }
2832
2833 return err;
2834}
2835
2836static inline int
2837restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2838{
2839 int err = 0;
2840 int i;
2841
2842 err |= __get_user(regs->CP0_EPC, &sc->sc_pc)((regs->CP0_EPC) = (typeof(*&sc->sc_pc))( __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 8, ldq_be_p, abort)))) (&
sc->sc_pc)), 0)
;
2843
2844 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi)((regs->active_tc.HI[0]) = (typeof(*&sc->sc_mdhi))(
__builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdhi)) == 8, ldq_be_p
, abort)))) (&sc->sc_mdhi)), 0)
;
2845 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo)((regs->active_tc.LO[0]) = (typeof(*&sc->sc_mdlo))(
__builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mdlo)) == 8, ldq_be_p
, abort)))) (&sc->sc_mdlo)), 0)
;
2846
2847 for (i = 1; i < 32; ++i) {
2848 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i])((regs->active_tc.gpr[i]) = (typeof(*&sc->sc_regs[i
]))( __builtin_choose_expr(sizeof(*(&sc->sc_regs[i])) ==
1, ldub_p, __builtin_choose_expr(sizeof(*(&sc->sc_regs
[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(&sc
->sc_regs[i])) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(&sc->sc_regs[i])) == 8, ldq_be_p, abort)))) (&sc
->sc_regs[i])), 0)
;
2849 }
2850
2851 err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1)((regs->active_tc.HI[1]) = (typeof(*&sc->sc_hi1))( __builtin_choose_expr
(sizeof(*(&sc->sc_hi1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi1)) == 8, ldq_be_p, abort)))) (&
sc->sc_hi1)), 0)
;
2852 err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2)((regs->active_tc.HI[2]) = (typeof(*&sc->sc_hi2))( __builtin_choose_expr
(sizeof(*(&sc->sc_hi2)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi2)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi2)) == 8, ldq_be_p, abort)))) (&
sc->sc_hi2)), 0)
;
2853 err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3)((regs->active_tc.HI[3]) = (typeof(*&sc->sc_hi3))( __builtin_choose_expr
(sizeof(*(&sc->sc_hi3)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi3)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi3)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_hi3)) == 8, ldq_be_p, abort)))) (&
sc->sc_hi3)), 0)
;
2854 err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1)((regs->active_tc.LO[1]) = (typeof(*&sc->sc_lo1))( __builtin_choose_expr
(sizeof(*(&sc->sc_lo1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo1)) == 8, ldq_be_p, abort)))) (&
sc->sc_lo1)), 0)
;
2855 err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2)((regs->active_tc.LO[2]) = (typeof(*&sc->sc_lo2))( __builtin_choose_expr
(sizeof(*(&sc->sc_lo2)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo2)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo2)) == 8, ldq_be_p, abort)))) (&
sc->sc_lo2)), 0)
;
2856 err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3)((regs->active_tc.LO[3]) = (typeof(*&sc->sc_lo3))( __builtin_choose_expr
(sizeof(*(&sc->sc_lo3)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo3)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo3)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_lo3)) == 8, ldq_be_p, abort)))) (&
sc->sc_lo3)), 0)
;
2857 {
2858 uint32_t dsp;
2859 err |= __get_user(dsp, &sc->sc_dsp)((dsp) = (typeof(*&sc->sc_dsp))( __builtin_choose_expr
(sizeof(*(&sc->sc_dsp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_dsp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_dsp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_dsp)) == 8, ldq_be_p, abort)))) (&
sc->sc_dsp)), 0)
;
2860 cpu_wrdsp(dsp, 0x3ff, regs);
2861 }
2862
2863 for (i = 0; i < 32; ++i) {
2864 err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i])((regs->active_fpu.fpr[i].d) = (typeof(*&sc->sc_fpregs
[i]))( __builtin_choose_expr(sizeof(*(&sc->sc_fpregs[i
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&sc->
sc_fpregs[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(
*(&sc->sc_fpregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 8, ldq_be_p, abort)))
) (&sc->sc_fpregs[i])), 0)
;
2865 }
2866
2867 return err;
2868}
2869
2870/*
2871 * Determine which stack to use..
2872 */
2873static inline abi_ulong
2874get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2875{
2876 unsigned long sp;
2877
2878 /* Default to using normal stack */
2879 sp = regs->active_tc.gpr[29];
2880
2881 /*
2882 * FPU emulator may have its own trampoline active just
2883 * above the user stack, 16-bytes before the next lowest
2884 * 16 byte boundary. Try to avoid trashing it.
2885 */
2886 sp -= 32;
2887
2888 /* This is the X/Open sanctioned signal stack switching. */
2889 if ((ka->sa_flags & TARGET_SA_ONSTACK1u) && (sas_ss_flags (sp) == 0)) {
2890 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2891 }
2892
2893 return (sp - frame_size) & ~7;
2894}
2895
2896static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2897{
2898 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2899 env->hflags &= ~MIPS_HFLAG_M16;
2900 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2901 env->active_tc.PC &= ~(target_ulong) 1;
2902 }
2903}
2904
2905# if defined(TARGET_ABI_MIPSO32)
2906/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2907static void setup_frame(int sig, struct target_sigaction * ka,
2908 target_sigset_t *set, CPUMIPSState *regs)
2909{
2910 struct sigframe *frame;
2911 abi_ulong frame_addr;
2912 int i;
2913
2914 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2915 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
2916 goto give_sigsegv;
2917
2918 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn216);
2919
2920 if(setup_sigcontext(regs, &frame->sf_sc))
2921 goto give_sigsegv;
2922
2923 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
2924 if(__put_user(set->sig[i], &frame->sf_mask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->sf_mask.sig[i]
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
sf_mask.sig[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->sf_mask.sig[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sf_mask.sig[i])) == 8, stq_be_p, abort
)))) ((&frame->sf_mask.sig[i]), (set->sig[i])), 0)
)
2925 goto give_sigsegv;
2926 }
2927
2928 /*
2929 * Arguments to signal handler:
2930 *
2931 * a0 = signal number
2932 * a1 = 0 (should be cause)
2933 * a2 = pointer to struct sigcontext
2934 *
2935 * $25 and PC point to the signal handler, $29 points to the
2936 * struct sigframe.
2937 */
2938 regs->active_tc.gpr[ 4] = sig;
2939 regs->active_tc.gpr[ 5] = 0;
2940 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc)__builtin_offsetof(struct sigframe, sf_sc);
2941 regs->active_tc.gpr[29] = frame_addr;
2942 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code)__builtin_offsetof(struct sigframe, sf_code);
2943 /* The original kernel code sets CP0_EPC to the handler
2944 * since it returns to userland using eret
2945 * we cannot do this here, and we must set PC directly */
2946 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2947 mips_set_hflags_isa_mode_from_pc(regs);
2948 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
2949 return;
2950
2951give_sigsegv:
2952 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
2953 force_sig(TARGET_SIGSEGV11/*, current*/);
2954}
2955
2956long do_sigreturn(CPUMIPSState *regs)
2957{
2958 struct sigframe *frame;
2959 abi_ulong frame_addr;
2960 sigset_t blocked;
2961 target_sigset_t target_set;
2962 int i;
2963
2964#if defined(DEBUG_SIGNAL)
2965 fprintf(stderrstderr, "do_sigreturn\n");
2966#endif
2967 frame_addr = regs->active_tc.gpr[29];
2968 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
2969 goto badframe;
2970
2971 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
2972 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i])((target_set.sig[i]) = (typeof(*&frame->sf_mask.sig[i]
))( __builtin_choose_expr(sizeof(*(&frame->sf_mask.sig
[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->sf_mask.sig[i])) == 2, lduw_be_p, __builtin_choose_expr(
sizeof(*(&frame->sf_mask.sig[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sf_mask.sig[i])) == 8, ldq_be_p, abort
)))) (&frame->sf_mask.sig[i])), 0)
)
2973 goto badframe;
2974 }
2975
2976 target_to_host_sigset_internal(&blocked, &target_set);
2977 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
2978
2979 if (restore_sigcontext(regs, &frame->sf_sc))
2980 goto badframe;
2981
2982#if 0
2983 /*
2984 * Don't let your children do this ...
2985 */
2986 __asm__ __volatile__(
2987 "move\t$29, %0\n\t"
2988 "j\tsyscall_exit"
2989 :/* no outputs */
2990 :"r" (&regs));
2991 /* Unreached */
2992#endif
2993
2994 regs->active_tc.PC = regs->CP0_EPC;
2995 mips_set_hflags_isa_mode_from_pc(regs);
2996 /* I am not sure this is right, but it seems to work
2997 * maybe a problem with nested signals ? */
2998 regs->CP0_EPC = 0;
2999 return -TARGET_QEMU_ESIGRETURN;
3000
3001badframe:
3002 force_sig(TARGET_SIGSEGV11/*, current*/);
3003 return 0;
3004}
3005# endif /* O32 */
3006
3007static void setup_rt_frame(int sig, struct target_sigaction *ka,
3008 target_siginfo_t *info,
3009 target_sigset_t *set, CPUMIPSState *env)
3010{
3011 struct target_rt_sigframe *frame;
3012 abi_ulong frame_addr;
3013 int i;
3014
3015 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3016 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
3017 goto give_sigsegv;
3018
3019 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn101);
3020
3021 copy_siginfo_to_user(&frame->rs_info, info);
3022
3023 __put_user(0, &frame->rs_uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
rs_uc.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->rs_uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->rs_uc.tuc_flags), (0)), 0)
;
3024 __put_user(0, &frame->rs_uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_link
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
rs_uc.tuc_link)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->rs_uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_link)) == 8, stq_be_p, abort
)))) ((&frame->rs_uc.tuc_link), (0)), 0)
;
3025 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_sp)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->rs_uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_stack.ss_sp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_sp)) == 8, stq_be_p, abort)))) ((&frame->rs_uc.tuc_stack
.ss_sp), (target_sigaltstack_used.ss_sp)), 0)
;
3026 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_size)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->rs_uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_size)) == 8, stq_be_p, abort)))) ((&frame->rs_uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
3027 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_flags)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&
frame->rs_uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_flags)) == 8, stq_be_p, abort)))) ((&frame->rs_uc.
tuc_stack.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env))
)), 0)
3028 &frame->rs_uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_flags)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&
frame->rs_uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_stack
.ss_flags)) == 8, stq_be_p, abort)))) ((&frame->rs_uc.
tuc_stack.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env))
)), 0)
;
3029
3030 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3031
3032 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3033 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->rs_uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->rs_uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->rs_uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->rs_uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
;
3034 }
3035
3036 /*
3037 * Arguments to signal handler:
3038 *
3039 * a0 = signal number
3040 * a1 = pointer to siginfo_t
3041 * a2 = pointer to struct ucontext
3042 *
3043 * $25 and PC point to the signal handler, $29 points to the
3044 * struct sigframe.
3045 */
3046 env->active_tc.gpr[ 4] = sig;
3047 env->active_tc.gpr[ 5] = frame_addr
3048 + offsetof(struct target_rt_sigframe, rs_info)__builtin_offsetof(struct target_rt_sigframe, rs_info);
3049 env->active_tc.gpr[ 6] = frame_addr
3050 + offsetof(struct target_rt_sigframe, rs_uc)__builtin_offsetof(struct target_rt_sigframe, rs_uc);
3051 env->active_tc.gpr[29] = frame_addr;
3052 env->active_tc.gpr[31] = frame_addr
3053 + offsetof(struct target_rt_sigframe, rs_code)__builtin_offsetof(struct target_rt_sigframe, rs_code);
3054 /* The original kernel code sets CP0_EPC to the handler
3055 * since it returns to userland using eret
3056 * we cannot do this here, and we must set PC directly */
3057 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3058 mips_set_hflags_isa_mode_from_pc(env);
3059 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3060 return;
3061
3062give_sigsegv:
3063 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3064 force_sig(TARGET_SIGSEGV11/*, current*/);
3065}
3066
3067long do_rt_sigreturn(CPUMIPSState *env)
3068{
3069 struct target_rt_sigframe *frame;
3070 abi_ulong frame_addr;
3071 sigset_t blocked;
3072
3073#if defined(DEBUG_SIGNAL)
3074 fprintf(stderrstderr, "do_rt_sigreturn\n");
3075#endif
3076 frame_addr = env->active_tc.gpr[29];
3077 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
3078 goto badframe;
3079
3080 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3081 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
3082
3083 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3084 goto badframe;
3085
3086 if (do_sigaltstack(frame_addr +
3087 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, rs_uc.tuc_stack
)
,
3088 0, get_sp_from_cpustate(env)) == -EFAULT14)
3089 goto badframe;
3090
3091 env->active_tc.PC = env->CP0_EPC;
3092 mips_set_hflags_isa_mode_from_pc(env);
3093 /* I am not sure this is right, but it seems to work
3094 * maybe a problem with nested signals ? */
3095 env->CP0_EPC = 0;
3096 return -TARGET_QEMU_ESIGRETURN;
3097
3098badframe:
3099 force_sig(TARGET_SIGSEGV11/*, current*/);
3100 return 0;
3101}
3102
3103#elif defined(TARGET_SH4)
3104
3105/*
3106 * code and data structures from linux kernel:
3107 * include/asm-sh/sigcontext.h
3108 * arch/sh/kernel/signal.c
3109 */
3110
3111struct target_sigcontext {
3112 target_ulong oldmask;
3113
3114 /* CPU registers */
3115 target_ulong sc_gregs[16];
3116 target_ulong sc_pc;
3117 target_ulong sc_pr;
3118 target_ulong sc_sr;
3119 target_ulong sc_gbr;
3120 target_ulong sc_mach;
3121 target_ulong sc_macl;
3122
3123 /* FPU registers */
3124 target_ulong sc_fpregs[16];
3125 target_ulong sc_xfpregs[16];
3126 unsigned int sc_fpscr;
3127 unsigned int sc_fpul;
3128 unsigned int sc_ownedfp;
3129};
3130
3131struct target_sigframe
3132{
3133 struct target_sigcontext sc;
3134 target_ulong extramask[TARGET_NSIG_WORDS(64 / 64)-1];
3135 uint16_t retcode[3];
3136};
3137
3138
3139struct target_ucontext {
3140 target_ulong tuc_flags;
3141 struct target_ucontext *tuc_link;
3142 target_stack_t tuc_stack;
3143 struct target_sigcontext tuc_mcontext;
3144 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3145};
3146
3147struct target_rt_sigframe
3148{
3149 struct target_siginfo info;
3150 struct target_ucontext uc;
3151 uint16_t retcode[3];
3152};
3153
3154
3155#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3156#define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3157
3158static abi_ulong get_sigframe(struct target_sigaction *ka,
3159 unsigned long sp, size_t frame_size)
3160{
3161 if ((ka->sa_flags & TARGET_SA_ONSTACK1u) && (sas_ss_flags(sp) == 0)) {
3162 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3163 }
3164
3165 return (sp - frame_size) & -8ul;
3166}
3167
3168static int setup_sigcontext(struct target_sigcontext *sc,
3169 CPUSH4State *regs, unsigned long mask)
3170{
3171 int err = 0;
3172 int i;
3173
3174#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)(__builtin_choose_expr(sizeof(*(&sc->sc_##x)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_##x)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_##x)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_##x)) == 8, stq_be_p
, abort)))) ((&sc->sc_##x), (regs->x)), 0)
3175 COPY(gregs[0]); COPY(gregs[1]);
3176 COPY(gregs[2]); COPY(gregs[3]);
3177 COPY(gregs[4]); COPY(gregs[5]);
3178 COPY(gregs[6]); COPY(gregs[7]);
3179 COPY(gregs[8]); COPY(gregs[9]);
3180 COPY(gregs[10]); COPY(gregs[11]);
3181 COPY(gregs[12]); COPY(gregs[13]);
3182 COPY(gregs[14]); COPY(gregs[15]);
3183 COPY(gbr); COPY(mach);
3184 COPY(macl); COPY(pr);
3185 COPY(sr); COPY(pc);
3186#undef COPY
3187
3188 for (i=0; i<16; i++) {
3189 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i])(__builtin_choose_expr(sizeof(*(&sc->sc_fpregs[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_fpregs
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_fpregs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sc->sc_fpregs[i])) == 8, stq_be_p, abort)))) ((&
sc->sc_fpregs[i]), (regs->fregs[i])), 0)
;
3190 }
3191 err |= __put_user(regs->fpscr, &sc->sc_fpscr)(__builtin_choose_expr(sizeof(*(&sc->sc_fpscr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpscr)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->sc_fpscr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_fpscr)) == 8, stq_be_p, abort)))) ((&sc->sc_fpscr),
(regs->fpscr)), 0)
;
3192 err |= __put_user(regs->fpul, &sc->sc_fpul)(__builtin_choose_expr(sizeof(*(&sc->sc_fpul)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpul)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpul)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpul)) == 8, stq_be_p
, abort)))) ((&sc->sc_fpul), (regs->fpul)), 0)
;
3193
3194 /* non-iBCS2 extensions.. */
3195 err |= __put_user(mask, &sc->oldmask)(__builtin_choose_expr(sizeof(*(&sc->oldmask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 8, stq_be_p
, abort)))) ((&sc->oldmask), (mask)), 0)
;
3196
3197 return err;
3198}
3199
3200static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3201 target_ulong *r0_p)
3202{
3203 unsigned int err = 0;
3204 int i;
3205
3206#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)((regs->x) = (typeof(*&sc->sc_##x))( __builtin_choose_expr
(sizeof(*(&sc->sc_##x)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_##x)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_##x)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_##x)) == 8, ldq_be_p, abort)))) (&
sc->sc_##x)), 0)
3207 COPY(gregs[1]);
3208 COPY(gregs[2]); COPY(gregs[3]);
3209 COPY(gregs[4]); COPY(gregs[5]);
3210 COPY(gregs[6]); COPY(gregs[7]);
3211 COPY(gregs[8]); COPY(gregs[9]);
3212 COPY(gregs[10]); COPY(gregs[11]);
3213 COPY(gregs[12]); COPY(gregs[13]);
3214 COPY(gregs[14]); COPY(gregs[15]);
3215 COPY(gbr); COPY(mach);
3216 COPY(macl); COPY(pr);
3217 COPY(sr); COPY(pc);
3218#undef COPY
3219
3220 for (i=0; i<16; i++) {
3221 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i])((regs->fregs[i]) = (typeof(*&sc->sc_fpregs[i]))( __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 8, ldq_be_p, abort)))
) (&sc->sc_fpregs[i])), 0)
;
3222 }
3223 err |= __get_user(regs->fpscr, &sc->sc_fpscr)((regs->fpscr) = (typeof(*&sc->sc_fpscr))( __builtin_choose_expr
(sizeof(*(&sc->sc_fpscr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpscr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpscr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpscr)) == 8, ldq_be_p, abort)))) (&
sc->sc_fpscr)), 0)
;
3224 err |= __get_user(regs->fpul, &sc->sc_fpul)((regs->fpul) = (typeof(*&sc->sc_fpul))( __builtin_choose_expr
(sizeof(*(&sc->sc_fpul)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpul)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpul)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpul)) == 8, ldq_be_p, abort)))) (&
sc->sc_fpul)), 0)
;
3225
3226 regs->tra = -1; /* disable syscall checks */
3227 err |= __get_user(*r0_p, &sc->sc_gregs[0])((*r0_p) = (typeof(*&sc->sc_gregs[0]))( __builtin_choose_expr
(sizeof(*(&sc->sc_gregs[0])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_gregs[0])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_gregs[0])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_gregs[0])) == 8, ldq_be_p, abort))))
(&sc->sc_gregs[0])), 0)
;
3228 return err;
3229}
3230
3231static void setup_frame(int sig, struct target_sigaction *ka,
3232 target_sigset_t *set, CPUSH4State *regs)
3233{
3234 struct target_sigframe *frame;
3235 abi_ulong frame_addr;
3236 int i;
3237 int err = 0;
3238 int signal;
3239
3240 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3241 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
3242 goto give_sigsegv;
3243
3244 signal = current_exec_domain_sig(sig);
3245
3246 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3247
3248 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64) - 1; i++) {
3249 err |= __put_user(set->sig[i + 1], &frame->extramask[i])(__builtin_choose_expr(sizeof(*(&frame->extramask[i]))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->extramask
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i])) == 8, stq_be_p, abort)))) ((
&frame->extramask[i]), (set->sig[i + 1])), 0)
;
3250 }
3251
3252 /* Set up to return from userspace. If provided, use a stub
3253 already in userspace. */
3254 if (ka->sa_flags & TARGET_SA_RESTORER) {
3255 regs->pr = (unsigned long) ka->sa_restorer;
3256 } else {
3257 /* Generate return code (system call to sigreturn) */
3258 err |= __put_user(MOVW(2), &frame->retcode[0])(__builtin_choose_expr(sizeof(*(&frame->retcode[0])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[0])) == 8, stq_be_p, abort)))) ((&
frame->retcode[0]), (MOVW(2))), 0)
;
3259 err |= __put_user(TRAP_NOARG, &frame->retcode[1])(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (TRAP_NOARG)), 0)
;
3260 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2])(__builtin_choose_expr(sizeof(*(&frame->retcode[2])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[2])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[2])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[2])) == 8, stq_be_p, abort)))) ((&
frame->retcode[2]), ((216))), 0)
;
3261 regs->pr = (unsigned long) frame->retcode;
3262 }
3263
3264 if (err)
3265 goto give_sigsegv;
3266
3267 /* Set up registers for signal handler */
3268 regs->gregs[15] = frame_addr;
3269 regs->gregs[4] = signal; /* Arg for signal handler */
3270 regs->gregs[5] = 0;
3271 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc)__builtin_offsetof(typeof(*frame), sc);
3272 regs->pc = (unsigned long) ka->_sa_handler;
3273
3274 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3275 return;
3276
3277give_sigsegv:
3278 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3279 force_sig(TARGET_SIGSEGV11);
3280}
3281
3282static void setup_rt_frame(int sig, struct target_sigaction *ka,
3283 target_siginfo_t *info,
3284 target_sigset_t *set, CPUSH4State *regs)
3285{
3286 struct target_rt_sigframe *frame;
3287 abi_ulong frame_addr;
3288 int i;
3289 int err = 0;
3290 int signal;
3291
3292 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3293 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
3294 goto give_sigsegv;
3295
3296 signal = current_exec_domain_sig(sig);
3297
3298 err |= copy_siginfo_to_user(&frame->info, info);
3299
3300 /* Create the ucontext. */
3301 err |= __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
3302 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*((unsigned long *)&frame->
uc.tuc_link)) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned
long *)&frame->uc.tuc_link)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((unsigned long *)&frame->uc.tuc_link)) == 4,
stl_be_p, __builtin_choose_expr(sizeof(*((unsigned long *)&
frame->uc.tuc_link)) == 8, stq_be_p, abort)))) (((unsigned
long *)&frame->uc.tuc_link), (0)), 0)
;
3303 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), ((unsigned long
)target_sigaltstack_used.ss_sp)), 0)
3304 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), ((unsigned long
)target_sigaltstack_used.ss_sp)), 0)
;
3305 err |= __put_user(sas_ss_flags(regs->gregs[15]),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(regs->gregs[15]))), 0)
3306 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(regs->gregs[15]))), 0)
;
3307 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
3308 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
3309 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3310 regs, set->sig[0]);
3311 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3312 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
;
3313 }
3314
3315 /* Set up to return from userspace. If provided, use a stub
3316 already in userspace. */
3317 if (ka->sa_flags & TARGET_SA_RESTORER) {
3318 regs->pr = (unsigned long) ka->sa_restorer;
3319 } else {
3320 /* Generate return code (system call to sigreturn) */
3321 err |= __put_user(MOVW(2), &frame->retcode[0])(__builtin_choose_expr(sizeof(*(&frame->retcode[0])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[0])) == 8, stq_be_p, abort)))) ((&
frame->retcode[0]), (MOVW(2))), 0)
;
3322 err |= __put_user(TRAP_NOARG, &frame->retcode[1])(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (TRAP_NOARG)), 0)
;
3323 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2])(__builtin_choose_expr(sizeof(*(&frame->retcode[2])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[2])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[2])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[2])) == 8, stq_be_p, abort)))) ((&
frame->retcode[2]), ((101))), 0)
;
3324 regs->pr = (unsigned long) frame->retcode;
3325 }
3326
3327 if (err)
3328 goto give_sigsegv;
3329
3330 /* Set up registers for signal handler */
3331 regs->gregs[15] = frame_addr;
3332 regs->gregs[4] = signal; /* Arg for signal handler */
3333 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info)__builtin_offsetof(typeof(*frame), info);
3334 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc)__builtin_offsetof(typeof(*frame), uc);
3335 regs->pc = (unsigned long) ka->_sa_handler;
3336
3337 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3338 return;
3339
3340give_sigsegv:
3341 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3342 force_sig(TARGET_SIGSEGV11);
3343}
3344
3345long do_sigreturn(CPUSH4State *regs)
3346{
3347 struct target_sigframe *frame;
3348 abi_ulong frame_addr;
3349 sigset_t blocked;
3350 target_sigset_t target_set;
3351 target_ulong r0;
3352 int i;
3353 int err = 0;
3354
3355#if defined(DEBUG_SIGNAL)
3356 fprintf(stderrstderr, "do_sigreturn\n");
3357#endif
3358 frame_addr = regs->gregs[15];
3359 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
3360 goto badframe;
3361
3362 err |= __get_user(target_set.sig[0], &frame->sc.oldmask)((target_set.sig[0]) = (typeof(*&frame->sc.oldmask))( __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 8, ldq_be_p, abort))
)) (&frame->sc.oldmask)), 0)
;
3363 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3364 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1])((target_set.sig[i]) = (typeof(*&frame->extramask[i - 1
]))( __builtin_choose_expr(sizeof(*(&frame->extramask[
i - 1])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
);
3365 }
3366
3367 if (err)
3368 goto badframe;
3369
3370 target_to_host_sigset_internal(&blocked, &target_set);
3371 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
3372
3373 if (restore_sigcontext(regs, &frame->sc, &r0))
3374 goto badframe;
3375
3376 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3377 return r0;
3378
3379badframe:
3380 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3381 force_sig(TARGET_SIGSEGV11);
3382 return 0;
3383}
3384
3385long do_rt_sigreturn(CPUSH4State *regs)
3386{
3387 struct target_rt_sigframe *frame;
3388 abi_ulong frame_addr;
3389 sigset_t blocked;
3390 target_ulong r0;
3391
3392#if defined(DEBUG_SIGNAL)
3393 fprintf(stderrstderr, "do_rt_sigreturn\n");
3394#endif
3395 frame_addr = regs->gregs[15];
3396 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
3397 goto badframe;
3398
3399 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3400 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
3401
3402 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3403 goto badframe;
3404
3405 if (do_sigaltstack(frame_addr +
3406 offsetof(struct target_rt_sigframe, uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack),
3407 0, get_sp_from_cpustate(regs)) == -EFAULT14)
3408 goto badframe;
3409
3410 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3411 return r0;
3412
3413badframe:
3414 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3415 force_sig(TARGET_SIGSEGV11);
3416 return 0;
3417}
3418#elif defined(TARGET_MICROBLAZE)
3419
3420struct target_sigcontext {
3421 struct target_pt_regs regs; /* needs to be first */
3422 uint32_t oldmask;
3423};
3424
3425struct target_stack_t {
3426 abi_ulong ss_sp;
3427 int ss_flags;
3428 unsigned int ss_size;
3429};
3430
3431struct target_ucontext {
3432 abi_ulong tuc_flags;
3433 abi_ulong tuc_link;
3434 struct target_stack_t tuc_stack;
3435 struct target_sigcontext tuc_mcontext;
3436 uint32_t tuc_extramask[TARGET_NSIG_WORDS(64 / 64) - 1];
3437};
3438
3439/* Signal frames. */
3440struct target_signal_frame {
3441 struct target_ucontext uc;
3442 uint32_t extramask[TARGET_NSIG_WORDS(64 / 64) - 1];
3443 uint32_t tramp[2];
3444};
3445
3446struct rt_signal_frame {
3447 siginfo_t info;
3448 struct ucontext uc;
3449 uint32_t tramp[2];
3450};
3451
3452static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3453{
3454 __put_user(env->regs[0], &sc->regs.r0)(__builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 8, stq_be_p
, abort)))) ((&sc->regs.r0), (env->regs[0])), 0)
;
3455 __put_user(env->regs[1], &sc->regs.r1)(__builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 8, stq_be_p
, abort)))) ((&sc->regs.r1), (env->regs[1])), 0)
;
3456 __put_user(env->regs[2], &sc->regs.r2)(__builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 8, stq_be_p
, abort)))) ((&sc->regs.r2), (env->regs[2])), 0)
;
3457 __put_user(env->regs[3], &sc->regs.r3)(__builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 8, stq_be_p
, abort)))) ((&sc->regs.r3), (env->regs[3])), 0)
;
3458 __put_user(env->regs[4], &sc->regs.r4)(__builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 8, stq_be_p
, abort)))) ((&sc->regs.r4), (env->regs[4])), 0)
;
3459 __put_user(env->regs[5], &sc->regs.r5)(__builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 8, stq_be_p
, abort)))) ((&sc->regs.r5), (env->regs[5])), 0)
;
3460 __put_user(env->regs[6], &sc->regs.r6)(__builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 8, stq_be_p
, abort)))) ((&sc->regs.r6), (env->regs[6])), 0)
;
3461 __put_user(env->regs[7], &sc->regs.r7)(__builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 8, stq_be_p
, abort)))) ((&sc->regs.r7), (env->regs[7])), 0)
;
3462 __put_user(env->regs[8], &sc->regs.r8)(__builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 8, stq_be_p
, abort)))) ((&sc->regs.r8), (env->regs[8])), 0)
;
3463 __put_user(env->regs[9], &sc->regs.r9)(__builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 8, stq_be_p
, abort)))) ((&sc->regs.r9), (env->regs[9])), 0)
;
3464 __put_user(env->regs[10], &sc->regs.r10)(__builtin_choose_expr(sizeof(*(&sc->regs.r10)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r10)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r10
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r10)) == 8, stq_be_p, abort)))) ((&sc->regs.r10),
(env->regs[10])), 0)
;
3465 __put_user(env->regs[11], &sc->regs.r11)(__builtin_choose_expr(sizeof(*(&sc->regs.r11)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r11)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r11
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r11)) == 8, stq_be_p, abort)))) ((&sc->regs.r11),
(env->regs[11])), 0)
;
3466 __put_user(env->regs[12], &sc->regs.r12)(__builtin_choose_expr(sizeof(*(&sc->regs.r12)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r12)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r12
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r12)) == 8, stq_be_p, abort)))) ((&sc->regs.r12),
(env->regs[12])), 0)
;
3467 __put_user(env->regs[13], &sc->regs.r13)(__builtin_choose_expr(sizeof(*(&sc->regs.r13)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r13)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r13
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r13)) == 8, stq_be_p, abort)))) ((&sc->regs.r13),
(env->regs[13])), 0)
;
3468 __put_user(env->regs[14], &sc->regs.r14)(__builtin_choose_expr(sizeof(*(&sc->regs.r14)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r14)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r14
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r14)) == 8, stq_be_p, abort)))) ((&sc->regs.r14),
(env->regs[14])), 0)
;
3469 __put_user(env->regs[15], &sc->regs.r15)(__builtin_choose_expr(sizeof(*(&sc->regs.r15)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r15)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r15
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r15)) == 8, stq_be_p, abort)))) ((&sc->regs.r15),
(env->regs[15])), 0)
;
3470 __put_user(env->regs[16], &sc->regs.r16)(__builtin_choose_expr(sizeof(*(&sc->regs.r16)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r16)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r16
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r16)) == 8, stq_be_p, abort)))) ((&sc->regs.r16),
(env->regs[16])), 0)
;
3471 __put_user(env->regs[17], &sc->regs.r17)(__builtin_choose_expr(sizeof(*(&sc->regs.r17)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r17)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r17
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r17)) == 8, stq_be_p, abort)))) ((&sc->regs.r17),
(env->regs[17])), 0)
;
3472 __put_user(env->regs[18], &sc->regs.r18)(__builtin_choose_expr(sizeof(*(&sc->regs.r18)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r18)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r18
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r18)) == 8, stq_be_p, abort)))) ((&sc->regs.r18),
(env->regs[18])), 0)
;
3473 __put_user(env->regs[19], &sc->regs.r19)(__builtin_choose_expr(sizeof(*(&sc->regs.r19)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r19)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r19
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r19)) == 8, stq_be_p, abort)))) ((&sc->regs.r19),
(env->regs[19])), 0)
;
3474 __put_user(env->regs[20], &sc->regs.r20)(__builtin_choose_expr(sizeof(*(&sc->regs.r20)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r20)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r20
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r20)) == 8, stq_be_p, abort)))) ((&sc->regs.r20),
(env->regs[20])), 0)
;
3475 __put_user(env->regs[21], &sc->regs.r21)(__builtin_choose_expr(sizeof(*(&sc->regs.r21)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r21)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r21
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r21)) == 8, stq_be_p, abort)))) ((&sc->regs.r21),
(env->regs[21])), 0)
;
3476 __put_user(env->regs[22], &sc->regs.r22)(__builtin_choose_expr(sizeof(*(&sc->regs.r22)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r22)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r22
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r22)) == 8, stq_be_p, abort)))) ((&sc->regs.r22),
(env->regs[22])), 0)
;
3477 __put_user(env->regs[23], &sc->regs.r23)(__builtin_choose_expr(sizeof(*(&sc->regs.r23)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r23)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r23
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r23)) == 8, stq_be_p, abort)))) ((&sc->regs.r23),
(env->regs[23])), 0)
;
3478 __put_user(env->regs[24], &sc->regs.r24)(__builtin_choose_expr(sizeof(*(&sc->regs.r24)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r24)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r24
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r24)) == 8, stq_be_p, abort)))) ((&sc->regs.r24),
(env->regs[24])), 0)
;
3479 __put_user(env->regs[25], &sc->regs.r25)(__builtin_choose_expr(sizeof(*(&sc->regs.r25)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r25)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r25
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r25)) == 8, stq_be_p, abort)))) ((&sc->regs.r25),
(env->regs[25])), 0)
;
3480 __put_user(env->regs[26], &sc->regs.r26)(__builtin_choose_expr(sizeof(*(&sc->regs.r26)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r26)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r26
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r26)) == 8, stq_be_p, abort)))) ((&sc->regs.r26),
(env->regs[26])), 0)
;
3481 __put_user(env->regs[27], &sc->regs.r27)(__builtin_choose_expr(sizeof(*(&sc->regs.r27)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r27)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r27
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r27)) == 8, stq_be_p, abort)))) ((&sc->regs.r27),
(env->regs[27])), 0)
;
3482 __put_user(env->regs[28], &sc->regs.r28)(__builtin_choose_expr(sizeof(*(&sc->regs.r28)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r28)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r28
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r28)) == 8, stq_be_p, abort)))) ((&sc->regs.r28),
(env->regs[28])), 0)
;
3483 __put_user(env->regs[29], &sc->regs.r29)(__builtin_choose_expr(sizeof(*(&sc->regs.r29)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r29)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r29
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r29)) == 8, stq_be_p, abort)))) ((&sc->regs.r29),
(env->regs[29])), 0)
;
3484 __put_user(env->regs[30], &sc->regs.r30)(__builtin_choose_expr(sizeof(*(&sc->regs.r30)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r30)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r30
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r30)) == 8, stq_be_p, abort)))) ((&sc->regs.r30),
(env->regs[30])), 0)
;
3485 __put_user(env->regs[31], &sc->regs.r31)(__builtin_choose_expr(sizeof(*(&sc->regs.r31)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r31)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r31
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r31)) == 8, stq_be_p, abort)))) ((&sc->regs.r31),
(env->regs[31])), 0)
;
3486 __put_user(env->sregs[SR_PC], &sc->regs.pc)(__builtin_choose_expr(sizeof(*(&sc->regs.pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.pc)) == 8, stq_be_p
, abort)))) ((&sc->regs.pc), (env->sregs[SR_PC])), 0
)
;
3487}
3488
3489static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3490{
3491 __get_user(env->regs[0], &sc->regs.r0)((env->regs[0]) = (typeof(*&sc->regs.r0))( __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 8, ldq_be_p, abort)))) (&
sc->regs.r0)), 0)
;
3492 __get_user(env->regs[1], &sc->regs.r1)((env->regs[1]) = (typeof(*&sc->regs.r1))( __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 8, ldq_be_p, abort)))) (&
sc->regs.r1)), 0)
;
3493 __get_user(env->regs[2], &sc->regs.r2)((env->regs[2]) = (typeof(*&sc->regs.r2))( __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 8, ldq_be_p, abort)))) (&
sc->regs.r2)), 0)
;
3494 __get_user(env->regs[3], &sc->regs.r3)((env->regs[3]) = (typeof(*&sc->regs.r3))( __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 8, ldq_be_p, abort)))) (&
sc->regs.r3)), 0)
;
3495 __get_user(env->regs[4], &sc->regs.r4)((env->regs[4]) = (typeof(*&sc->regs.r4))( __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 8, ldq_be_p, abort)))) (&
sc->regs.r4)), 0)
;
3496 __get_user(env->regs[5], &sc->regs.r5)((env->regs[5]) = (typeof(*&sc->regs.r5))( __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 8, ldq_be_p, abort)))) (&
sc->regs.r5)), 0)
;
3497 __get_user(env->regs[6], &sc->regs.r6)((env->regs[6]) = (typeof(*&sc->regs.r6))( __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 8, ldq_be_p, abort)))) (&
sc->regs.r6)), 0)
;
3498 __get_user(env->regs[7], &sc->regs.r7)((env->regs[7]) = (typeof(*&sc->regs.r7))( __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 8, ldq_be_p, abort)))) (&
sc->regs.r7)), 0)
;
3499 __get_user(env->regs[8], &sc->regs.r8)((env->regs[8]) = (typeof(*&sc->regs.r8))( __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 8, ldq_be_p, abort)))) (&
sc->regs.r8)), 0)
;
3500 __get_user(env->regs[9], &sc->regs.r9)((env->regs[9]) = (typeof(*&sc->regs.r9))( __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 8, ldq_be_p, abort)))) (&
sc->regs.r9)), 0)
;
3501 __get_user(env->regs[10], &sc->regs.r10)((env->regs[10]) = (typeof(*&sc->regs.r10))( __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 8, ldq_be_p, abort)))) (&
sc->regs.r10)), 0)
;
3502 __get_user(env->regs[11], &sc->regs.r11)((env->regs[11]) = (typeof(*&sc->regs.r11))( __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 8, ldq_be_p, abort)))) (&
sc->regs.r11)), 0)
;
3503 __get_user(env->regs[12], &sc->regs.r12)((env->regs[12]) = (typeof(*&sc->regs.r12))( __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 8, ldq_be_p, abort)))) (&
sc->regs.r12)), 0)
;
3504 __get_user(env->regs[13], &sc->regs.r13)((env->regs[13]) = (typeof(*&sc->regs.r13))( __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 8, ldq_be_p, abort)))) (&
sc->regs.r13)), 0)
;
3505 __get_user(env->regs[14], &sc->regs.r14)((env->regs[14]) = (typeof(*&sc->regs.r14))( __builtin_choose_expr
(sizeof(*(&sc->regs.r14)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r14)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r14)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r14)) == 8, ldq_be_p, abort)))) (&
sc->regs.r14)), 0)
;
3506 __get_user(env->regs[15], &sc->regs.r15)((env->regs[15]) = (typeof(*&sc->regs.r15))( __builtin_choose_expr
(sizeof(*(&sc->regs.r15)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r15)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r15)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r15)) == 8, ldq_be_p, abort)))) (&
sc->regs.r15)), 0)
;
3507 __get_user(env->regs[16], &sc->regs.r16)((env->regs[16]) = (typeof(*&sc->regs.r16))( __builtin_choose_expr
(sizeof(*(&sc->regs.r16)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r16)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r16)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r16)) == 8, ldq_be_p, abort)))) (&
sc->regs.r16)), 0)
;
3508 __get_user(env->regs[17], &sc->regs.r17)((env->regs[17]) = (typeof(*&sc->regs.r17))( __builtin_choose_expr
(sizeof(*(&sc->regs.r17)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r17)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r17)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r17)) == 8, ldq_be_p, abort)))) (&
sc->regs.r17)), 0)
;
3509 __get_user(env->regs[18], &sc->regs.r18)((env->regs[18]) = (typeof(*&sc->regs.r18))( __builtin_choose_expr
(sizeof(*(&sc->regs.r18)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r18)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r18)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r18)) == 8, ldq_be_p, abort)))) (&
sc->regs.r18)), 0)
;
3510 __get_user(env->regs[19], &sc->regs.r19)((env->regs[19]) = (typeof(*&sc->regs.r19))( __builtin_choose_expr
(sizeof(*(&sc->regs.r19)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r19)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r19)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r19)) == 8, ldq_be_p, abort)))) (&
sc->regs.r19)), 0)
;
3511 __get_user(env->regs[20], &sc->regs.r20)((env->regs[20]) = (typeof(*&sc->regs.r20))( __builtin_choose_expr
(sizeof(*(&sc->regs.r20)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r20)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r20)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r20)) == 8, ldq_be_p, abort)))) (&
sc->regs.r20)), 0)
;
3512 __get_user(env->regs[21], &sc->regs.r21)((env->regs[21]) = (typeof(*&sc->regs.r21))( __builtin_choose_expr
(sizeof(*(&sc->regs.r21)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r21)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r21)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r21)) == 8, ldq_be_p, abort)))) (&
sc->regs.r21)), 0)
;
3513 __get_user(env->regs[22], &sc->regs.r22)((env->regs[22]) = (typeof(*&sc->regs.r22))( __builtin_choose_expr
(sizeof(*(&sc->regs.r22)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r22)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r22)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r22)) == 8, ldq_be_p, abort)))) (&
sc->regs.r22)), 0)
;
3514 __get_user(env->regs[23], &sc->regs.r23)((env->regs[23]) = (typeof(*&sc->regs.r23))( __builtin_choose_expr
(sizeof(*(&sc->regs.r23)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r23)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r23)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r23)) == 8, ldq_be_p, abort)))) (&
sc->regs.r23)), 0)
;
3515 __get_user(env->regs[24], &sc->regs.r24)((env->regs[24]) = (typeof(*&sc->regs.r24))( __builtin_choose_expr
(sizeof(*(&sc->regs.r24)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r24)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r24)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r24)) == 8, ldq_be_p, abort)))) (&
sc->regs.r24)), 0)
;
3516 __get_user(env->regs[25], &sc->regs.r25)((env->regs[25]) = (typeof(*&sc->regs.r25))( __builtin_choose_expr
(sizeof(*(&sc->regs.r25)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r25)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r25)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r25)) == 8, ldq_be_p, abort)))) (&
sc->regs.r25)), 0)
;
3517 __get_user(env->regs[26], &sc->regs.r26)((env->regs[26]) = (typeof(*&sc->regs.r26))( __builtin_choose_expr
(sizeof(*(&sc->regs.r26)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r26)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r26)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r26)) == 8, ldq_be_p, abort)))) (&
sc->regs.r26)), 0)
;
3518 __get_user(env->regs[27], &sc->regs.r27)((env->regs[27]) = (typeof(*&sc->regs.r27))( __builtin_choose_expr
(sizeof(*(&sc->regs.r27)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r27)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r27)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r27)) == 8, ldq_be_p, abort)))) (&
sc->regs.r27)), 0)
;
3519 __get_user(env->regs[28], &sc->regs.r28)((env->regs[28]) = (typeof(*&sc->regs.r28))( __builtin_choose_expr
(sizeof(*(&sc->regs.r28)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r28)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r28)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r28)) == 8, ldq_be_p, abort)))) (&
sc->regs.r28)), 0)
;
3520 __get_user(env->regs[29], &sc->regs.r29)((env->regs[29]) = (typeof(*&sc->regs.r29))( __builtin_choose_expr
(sizeof(*(&sc->regs.r29)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r29)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r29)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r29)) == 8, ldq_be_p, abort)))) (&
sc->regs.r29)), 0)
;
3521 __get_user(env->regs[30], &sc->regs.r30)((env->regs[30]) = (typeof(*&sc->regs.r30))( __builtin_choose_expr
(sizeof(*(&sc->regs.r30)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r30)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r30)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r30)) == 8, ldq_be_p, abort)))) (&
sc->regs.r30)), 0)
;
3522 __get_user(env->regs[31], &sc->regs.r31)((env->regs[31]) = (typeof(*&sc->regs.r31))( __builtin_choose_expr
(sizeof(*(&sc->regs.r31)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r31)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r31)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r31)) == 8, ldq_be_p, abort)))) (&
sc->regs.r31)), 0)
;
3523 __get_user(env->sregs[SR_PC], &sc->regs.pc)((env->sregs[SR_PC]) = (typeof(*&sc->regs.pc))( __builtin_choose_expr
(sizeof(*(&sc->regs.pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.pc)) == 8, ldq_be_p, abort)))) (&
sc->regs.pc)), 0)
;
3524}
3525
3526static abi_ulong get_sigframe(struct target_sigaction *ka,
3527 CPUMBState *env, int frame_size)
3528{
3529 abi_ulong sp = env->regs[1];
3530
3531 if ((ka->sa_flags & SA_ONSTACK0x08000000) != 0 && !on_sig_stack(sp))
3532 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3533
3534 return ((sp - frame_size) & -8UL);
3535}
3536
3537static void setup_frame(int sig, struct target_sigaction *ka,
3538 target_sigset_t *set, CPUMBState *env)
3539{
3540 struct target_signal_frame *frame;
3541 abi_ulong frame_addr;
3542 int err = 0;
3543 int i;
3544
3545 frame_addr = get_sigframe(ka, env, sizeof *frame);
3546 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
3547 goto badframe;
3548
3549 /* Save the mask. */
3550 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_mcontext
.oldmask)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_mcontext.oldmask)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_mcontext.oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_mcontext
.oldmask)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_mcontext
.oldmask), (set->sig[0])), 0)
;
3551 if (err)
3552 goto badframe;
3553
3554 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3555 if (__put_user(set->sig[i], &frame->extramask[i - 1])(__builtin_choose_expr(sizeof(*(&frame->extramask[i - 1
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
extramask[i - 1])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i - 1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, stq_be_p, abort
)))) ((&frame->extramask[i - 1]), (set->sig[i])), 0
)
)
3556 goto badframe;
3557 }
3558
3559 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3560
3561 /* Set up to return from userspace. If provided, use a stub
3562 already in userspace. */
3563 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3564 if (ka->sa_flags & TARGET_SA_RESTORER) {
3565 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3566 } else {
3567 uint32_t t;
3568 /* Note, these encodings are _big endian_! */
3569 /* addi r12, r0, __NR_sigreturn */
3570 t = 0x31800000UL | TARGET_NR_sigreturn216;
3571 err |= __put_user(t, frame->tramp + 0)(__builtin_choose_expr(sizeof(*(frame->tramp + 0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 0)) == 8, stq_be_p
, abort)))) ((frame->tramp + 0), (t)), 0)
;
3572 /* brki r14, 0x8 */
3573 t = 0xb9cc0008UL;
3574 err |= __put_user(t, frame->tramp + 1)(__builtin_choose_expr(sizeof(*(frame->tramp + 1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->tramp + 1)) == 8, stq_be_p
, abort)))) ((frame->tramp + 1), (t)), 0)
;
3575
3576 /* Return from sighandler will jump to the tramp.
3577 Negative 8 offset because return is rtsd r15, 8 */
3578 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3579 }
3580
3581 if (err)
3582 goto badframe;
3583
3584 /* Set up registers for signal handler */
3585 env->regs[1] = frame_addr;
3586 /* Signal handler args: */
3587 env->regs[5] = sig; /* Arg 0: signum */
3588 env->regs[6] = 0;
3589 /* arg 1: sigcontext */
3590 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc)__builtin_offsetof(typeof(*frame), uc);
3591
3592 /* Offset of 4 to handle microblaze rtid r14, 0 */
3593 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3594
3595 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3596 return;
3597 badframe:
3598 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3599 force_sig(TARGET_SIGSEGV11);
3600}
3601
3602static void setup_rt_frame(int sig, struct target_sigaction *ka,
3603 target_siginfo_t *info,
3604 target_sigset_t *set, CPUMBState *env)
3605{
3606 fprintf(stderrstderr, "Microblaze setup_rt_frame: not implemented\n");
3607}
3608
3609long do_sigreturn(CPUMBState *env)
3610{
3611 struct target_signal_frame *frame;
3612 abi_ulong frame_addr;
3613 target_sigset_t target_set;
3614 sigset_t set;
3615 int i;
3616
3617 frame_addr = env->regs[R_SP];
3618 /* Make sure the guest isn't playing games. */
3619 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)(frame = lock_user(1, frame_addr, sizeof(*frame), 1)))
3620 goto badframe;
3621
3622 /* Restore blocked signals */
3623 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask)((target_set.sig[0]) = (typeof(*&frame->uc.tuc_mcontext
.oldmask))( __builtin_choose_expr(sizeof(*(&frame->uc.
tuc_mcontext.oldmask)) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_mcontext.oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_mcontext.oldmask)) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_mcontext
.oldmask)) == 8, ldq_be_p, abort)))) (&frame->uc.tuc_mcontext
.oldmask)), 0)
)
3624 goto badframe;
3625 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3626 if (__get_user(target_set.sig[i], &frame->extramask[i - 1])((target_set.sig[i]) = (typeof(*&frame->extramask[i - 1
]))( __builtin_choose_expr(sizeof(*(&frame->extramask[
i - 1])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
)
3627 goto badframe;
3628 }
3629 target_to_host_sigset_internal(&set, &target_set);
3630 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
3631
3632 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3633 /* We got here through a sigreturn syscall, our path back is via an
3634 rtb insn so setup r14 for that. */
3635 env->regs[14] = env->sregs[SR_PC];
3636
3637 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3638 return env->regs[10];
3639 badframe:
3640 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3641 force_sig(TARGET_SIGSEGV11);
3642}
3643
3644long do_rt_sigreturn(CPUMBState *env)
3645{
3646 fprintf(stderrstderr, "Microblaze do_rt_sigreturn: not implemented\n");
3647 return -TARGET_ENOSYS38;
3648}
3649
3650#elif defined(TARGET_CRIS)
3651
3652struct target_sigcontext {
3653 struct target_pt_regs regs; /* needs to be first */
3654 uint32_t oldmask;
3655 uint32_t usp; /* usp before stacking this gunk on it */
3656};
3657
3658/* Signal frames. */
3659struct target_signal_frame {
3660 struct target_sigcontext sc;
3661 uint32_t extramask[TARGET_NSIG_WORDS(64 / 64) - 1];
3662 uint8_t retcode[8]; /* Trampoline code. */
3663};
3664
3665struct rt_signal_frame {
3666 siginfo_t *pinfo;
3667 void *puc;
3668 siginfo_t info;
3669 struct ucontext uc;
3670 uint8_t retcode[8]; /* Trampoline code. */
3671};
3672
3673static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3674{
3675 __put_user(env->regs[0], &sc->regs.r0)(__builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r0)) == 8, stq_be_p
, abort)))) ((&sc->regs.r0), (env->regs[0])), 0)
;
3676 __put_user(env->regs[1], &sc->regs.r1)(__builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r1)) == 8, stq_be_p
, abort)))) ((&sc->regs.r1), (env->regs[1])), 0)
;
3677 __put_user(env->regs[2], &sc->regs.r2)(__builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r2)) == 8, stq_be_p
, abort)))) ((&sc->regs.r2), (env->regs[2])), 0)
;
3678 __put_user(env->regs[3], &sc->regs.r3)(__builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r3)) == 8, stq_be_p
, abort)))) ((&sc->regs.r3), (env->regs[3])), 0)
;
3679 __put_user(env->regs[4], &sc->regs.r4)(__builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r4)) == 8, stq_be_p
, abort)))) ((&sc->regs.r4), (env->regs[4])), 0)
;
3680 __put_user(env->regs[5], &sc->regs.r5)(__builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r5)) == 8, stq_be_p
, abort)))) ((&sc->regs.r5), (env->regs[5])), 0)
;
3681 __put_user(env->regs[6], &sc->regs.r6)(__builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r6)) == 8, stq_be_p
, abort)))) ((&sc->regs.r6), (env->regs[6])), 0)
;
3682 __put_user(env->regs[7], &sc->regs.r7)(__builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r7)) == 8, stq_be_p
, abort)))) ((&sc->regs.r7), (env->regs[7])), 0)
;
3683 __put_user(env->regs[8], &sc->regs.r8)(__builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r8)) == 8, stq_be_p
, abort)))) ((&sc->regs.r8), (env->regs[8])), 0)
;
3684 __put_user(env->regs[9], &sc->regs.r9)(__builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r9)) == 8, stq_be_p
, abort)))) ((&sc->regs.r9), (env->regs[9])), 0)
;
3685 __put_user(env->regs[10], &sc->regs.r10)(__builtin_choose_expr(sizeof(*(&sc->regs.r10)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r10)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r10
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r10)) == 8, stq_be_p, abort)))) ((&sc->regs.r10),
(env->regs[10])), 0)
;
3686 __put_user(env->regs[11], &sc->regs.r11)(__builtin_choose_expr(sizeof(*(&sc->regs.r11)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r11)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r11
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r11)) == 8, stq_be_p, abort)))) ((&sc->regs.r11),
(env->regs[11])), 0)
;
3687 __put_user(env->regs[12], &sc->regs.r12)(__builtin_choose_expr(sizeof(*(&sc->regs.r12)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r12)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r12
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r12)) == 8, stq_be_p, abort)))) ((&sc->regs.r12),
(env->regs[12])), 0)
;
3688 __put_user(env->regs[13], &sc->regs.r13)(__builtin_choose_expr(sizeof(*(&sc->regs.r13)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.r13)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.r13
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.r13)) == 8, stq_be_p, abort)))) ((&sc->regs.r13),
(env->regs[13])), 0)
;
3689 __put_user(env->regs[14], &sc->usp)(__builtin_choose_expr(sizeof(*(&sc->usp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 8, stq_be_p
, abort)))) ((&sc->usp), (env->regs[14])), 0)
;
3690 __put_user(env->regs[15], &sc->regs.acr)(__builtin_choose_expr(sizeof(*(&sc->regs.acr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.acr)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.acr
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.acr)) == 8, stq_be_p, abort)))) ((&sc->regs.acr),
(env->regs[15])), 0)
;
3691 __put_user(env->pregs[PR_MOF], &sc->regs.mof)(__builtin_choose_expr(sizeof(*(&sc->regs.mof)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.mof)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.mof
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.mof)) == 8, stq_be_p, abort)))) ((&sc->regs.mof),
(env->pregs[PR_MOF])), 0)
;
3692 __put_user(env->pregs[PR_SRP], &sc->regs.srp)(__builtin_choose_expr(sizeof(*(&sc->regs.srp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.srp)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.srp
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.srp)) == 8, stq_be_p, abort)))) ((&sc->regs.srp),
(env->pregs[PR_SRP])), 0)
;
3693 __put_user(env->pc, &sc->regs.erp)(__builtin_choose_expr(sizeof(*(&sc->regs.erp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs.erp)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&sc->regs.erp
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&sc->
regs.erp)) == 8, stq_be_p, abort)))) ((&sc->regs.erp),
(env->pc)), 0)
;
3694}
3695
3696static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3697{
3698 __get_user(env->regs[0], &sc->regs.r0)((env->regs[0]) = (typeof(*&sc->regs.r0))( __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r0)) == 8, ldq_be_p, abort)))) (&
sc->regs.r0)), 0)
;
3699 __get_user(env->regs[1], &sc->regs.r1)((env->regs[1]) = (typeof(*&sc->regs.r1))( __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r1)) == 8, ldq_be_p, abort)))) (&
sc->regs.r1)), 0)
;
3700 __get_user(env->regs[2], &sc->regs.r2)((env->regs[2]) = (typeof(*&sc->regs.r2))( __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r2)) == 8, ldq_be_p, abort)))) (&
sc->regs.r2)), 0)
;
3701 __get_user(env->regs[3], &sc->regs.r3)((env->regs[3]) = (typeof(*&sc->regs.r3))( __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r3)) == 8, ldq_be_p, abort)))) (&
sc->regs.r3)), 0)
;
3702 __get_user(env->regs[4], &sc->regs.r4)((env->regs[4]) = (typeof(*&sc->regs.r4))( __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r4)) == 8, ldq_be_p, abort)))) (&
sc->regs.r4)), 0)
;
3703 __get_user(env->regs[5], &sc->regs.r5)((env->regs[5]) = (typeof(*&sc->regs.r5))( __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r5)) == 8, ldq_be_p, abort)))) (&
sc->regs.r5)), 0)
;
3704 __get_user(env->regs[6], &sc->regs.r6)((env->regs[6]) = (typeof(*&sc->regs.r6))( __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r6)) == 8, ldq_be_p, abort)))) (&
sc->regs.r6)), 0)
;
3705 __get_user(env->regs[7], &sc->regs.r7)((env->regs[7]) = (typeof(*&sc->regs.r7))( __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r7)) == 8, ldq_be_p, abort)))) (&
sc->regs.r7)), 0)
;
3706 __get_user(env->regs[8], &sc->regs.r8)((env->regs[8]) = (typeof(*&sc->regs.r8))( __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r8)) == 8, ldq_be_p, abort)))) (&
sc->regs.r8)), 0)
;
3707 __get_user(env->regs[9], &sc->regs.r9)((env->regs[9]) = (typeof(*&sc->regs.r9))( __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r9)) == 8, ldq_be_p, abort)))) (&
sc->regs.r9)), 0)
;
3708 __get_user(env->regs[10], &sc->regs.r10)((env->regs[10]) = (typeof(*&sc->regs.r10))( __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r10)) == 8, ldq_be_p, abort)))) (&
sc->regs.r10)), 0)
;
3709 __get_user(env->regs[11], &sc->regs.r11)((env->regs[11]) = (typeof(*&sc->regs.r11))( __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r11)) == 8, ldq_be_p, abort)))) (&
sc->regs.r11)), 0)
;
3710 __get_user(env->regs[12], &sc->regs.r12)((env->regs[12]) = (typeof(*&sc->regs.r12))( __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r12)) == 8, ldq_be_p, abort)))) (&
sc->regs.r12)), 0)
;
3711 __get_user(env->regs[13], &sc->regs.r13)((env->regs[13]) = (typeof(*&sc->regs.r13))( __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.r13)) == 8, ldq_be_p, abort)))) (&
sc->regs.r13)), 0)
;
3712 __get_user(env->regs[14], &sc->usp)((env->regs[14]) = (typeof(*&sc->usp))( __builtin_choose_expr
(sizeof(*(&sc->usp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 8, ldq_be_p, abort)))) (&sc
->usp)), 0)
;
3713 __get_user(env->regs[15], &sc->regs.acr)((env->regs[15]) = (typeof(*&sc->regs.acr))( __builtin_choose_expr
(sizeof(*(&sc->regs.acr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acr)) == 8, ldq_be_p, abort)))) (&
sc->regs.acr)), 0)
;
3714 __get_user(env->pregs[PR_MOF], &sc->regs.mof)((env->pregs[PR_MOF]) = (typeof(*&sc->regs.mof))( __builtin_choose_expr
(sizeof(*(&sc->regs.mof)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.mof)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.mof)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.mof)) == 8, ldq_be_p, abort)))) (&
sc->regs.mof)), 0)
;
3715 __get_user(env->pregs[PR_SRP], &sc->regs.srp)((env->pregs[PR_SRP]) = (typeof(*&sc->regs.srp))( __builtin_choose_expr
(sizeof(*(&sc->regs.srp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.srp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.srp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.srp)) == 8, ldq_be_p, abort)))) (&
sc->regs.srp)), 0)
;
3716 __get_user(env->pc, &sc->regs.erp)((env->pc) = (typeof(*&sc->regs.erp))( __builtin_choose_expr
(sizeof(*(&sc->regs.erp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.erp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.erp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.erp)) == 8, ldq_be_p, abort)))) (&
sc->regs.erp)), 0)
;
3717}
3718
3719static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3720{
3721 abi_ulong sp;
3722 /* Align the stack downwards to 4. */
3723 sp = (env->regs[R_SP] & ~3);
3724 return sp - framesize;
3725}
3726
3727static void setup_frame(int sig, struct target_sigaction *ka,
3728 target_sigset_t *set, CPUCRISState *env)
3729{
3730 struct target_signal_frame *frame;
3731 abi_ulong frame_addr;
3732 int err = 0;
3733 int i;
3734
3735 frame_addr = get_sigframe(env, sizeof *frame);
3736 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
3737 goto badframe;
3738
3739 /*
3740 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3741 * use this trampoline anymore but it sets it up for GDB.
3742 * In QEMU, using the trampoline simplifies things a bit so we use it.
3743 *
3744 * This is movu.w __NR_sigreturn, r9; break 13;
3745 */
3746 err |= __put_user(0x9c5f, frame->retcode+0)(__builtin_choose_expr(sizeof(*(frame->retcode+0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->retcode+0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+0)) == 8, stq_be_p
, abort)))) ((frame->retcode+0), (0x9c5f)), 0)
;
3747 err |= __put_user(TARGET_NR_sigreturn,(__builtin_choose_expr(sizeof(*(frame->retcode+2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 8, stq_be_p
, abort)))) ((frame->retcode+2), (216)), 0)
3748 frame->retcode+2)(__builtin_choose_expr(sizeof(*(frame->retcode+2)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+2)) == 8, stq_be_p
, abort)))) ((frame->retcode+2), (216)), 0)
;
3749 err |= __put_user(0xe93d, frame->retcode+4)(__builtin_choose_expr(sizeof(*(frame->retcode+4)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(frame->retcode+4)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+4)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(frame->retcode+4)) == 8, stq_be_p
, abort)))) ((frame->retcode+4), (0xe93d)), 0)
;
3750
3751 /* Save the mask. */
3752 err |= __put_user(set->sig[0], &frame->sc.oldmask)(__builtin_choose_expr(sizeof(*(&frame->sc.oldmask)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->sc.oldmask
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
sc.oldmask)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->sc.oldmask)) == 8, stq_be_p, abort)))) ((&frame
->sc.oldmask), (set->sig[0])), 0)
;
3753 if (err)
3754 goto badframe;
3755
3756 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3757 if (__put_user(set->sig[i], &frame->extramask[i - 1])(__builtin_choose_expr(sizeof(*(&frame->extramask[i - 1
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
extramask[i - 1])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i - 1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, stq_be_p, abort
)))) ((&frame->extramask[i - 1]), (set->sig[i])), 0
)
)
3758 goto badframe;
3759 }
3760
3761 setup_sigcontext(&frame->sc, env);
3762
3763 /* Move the stack and setup the arguments for the handler. */
3764 env->regs[R_SP] = frame_addr;
3765 env->regs[10] = sig;
3766 env->pc = (unsigned long) ka->_sa_handler;
3767 /* Link SRP so the guest returns through the trampoline. */
3768 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode)__builtin_offsetof(typeof(*frame), retcode);
3769
3770 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3771 return;
3772 badframe:
3773 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
3774 force_sig(TARGET_SIGSEGV11);
3775}
3776
3777static void setup_rt_frame(int sig, struct target_sigaction *ka,
3778 target_siginfo_t *info,
3779 target_sigset_t *set, CPUCRISState *env)
3780{
3781 fprintf(stderrstderr, "CRIS setup_rt_frame: not implemented\n");
3782}
3783
3784long do_sigreturn(CPUCRISState *env)
3785{
3786 struct target_signal_frame *frame;
3787 abi_ulong frame_addr;
3788 target_sigset_t target_set;
3789 sigset_t set;
3790 int i;
3791
3792 frame_addr = env->regs[R_SP];
3793 /* Make sure the guest isn't playing games. */
3794 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)(frame = lock_user(1, frame_addr, sizeof(*frame), 1)))
3795 goto badframe;
3796
3797 /* Restore blocked signals */
3798 if (__get_user(target_set.sig[0], &frame->sc.oldmask)((target_set.sig[0]) = (typeof(*&frame->sc.oldmask))( __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask)) == 8, ldq_be_p, abort))
)) (&frame->sc.oldmask)), 0)
)
3799 goto badframe;
3800 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
3801 if (__get_user(target_set.sig[i], &frame->extramask[i - 1])((target_set.sig[i]) = (typeof(*&frame->extramask[i - 1
]))( __builtin_choose_expr(sizeof(*(&frame->extramask[
i - 1])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
)
3802 goto badframe;
3803 }
3804 target_to_host_sigset_internal(&set, &target_set);
3805 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
3806
3807 restore_sigcontext(&frame->sc, env);
3808 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3809 return env->regs[10];
3810 badframe:
3811 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
3812 force_sig(TARGET_SIGSEGV11);
3813}
3814
3815long do_rt_sigreturn(CPUCRISState *env)
3816{
3817 fprintf(stderrstderr, "CRIS do_rt_sigreturn: not implemented\n");
3818 return -TARGET_ENOSYS38;
3819}
3820
3821#elif defined(TARGET_OPENRISC)
3822
3823struct target_sigcontext {
3824 struct target_pt_regs regs;
3825 abi_ulong oldmask;
3826 abi_ulong usp;
3827};
3828
3829struct target_ucontext {
3830 abi_ulong tuc_flags;
3831 abi_ulong tuc_link;
3832 target_stack_t tuc_stack;
3833 struct target_sigcontext tuc_mcontext;
3834 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3835};
3836
3837struct target_rt_sigframe {
3838 abi_ulong pinfo;
3839 uint64_t puc;
3840 struct target_siginfo info;
3841 struct target_sigcontext sc;
3842 struct target_ucontext uc;
3843 unsigned char retcode[16]; /* trampoline code */
3844};
3845
3846/* This is the asm-generic/ucontext.h version */
3847#if 0
3848static int restore_sigcontext(CPUOpenRISCState *regs,
3849 struct target_sigcontext *sc)
3850{
3851 unsigned int err = 0;
3852 unsigned long old_usp;
3853
3854 /* Alwys make any pending restarted system call return -EINTR */
3855 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3856
3857 /* restore the regs from &sc->regs (same as sc, since regs is first)
3858 * (sc is already checked for VERIFY_READ since the sigframe was
3859 * checked in sys_sigreturn previously)
3860 */
3861
3862 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3863 goto badframe;
3864 }
3865
3866 /* make sure the U-flag is set so user-mode cannot fool us */
3867
3868 regs->sr &= ~SR_SM;
3869
3870 /* restore the old USP as it was before we stacked the sc etc.
3871 * (we cannot just pop the sigcontext since we aligned the sp and
3872 * stuff after pushing it)
3873 */
3874
3875 err |= __get_user(old_usp, &sc->usp)((old_usp) = (typeof(*&sc->usp))( __builtin_choose_expr
(sizeof(*(&sc->usp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->usp)) == 8, ldq_be_p, abort)))) (&sc
->usp)), 0)
;
3876 phx_signal("old_usp 0x%lx", old_usp);
3877
3878 __PHX__ REALLY /* ??? */
3879 wrusp(old_usp);
3880 regs->gpr[1] = old_usp;
3881
3882 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3883 * after this completes, but we don't use that mechanism. maybe we can
3884 * use it now ?
3885 */
3886
3887 return err;
3888
3889badframe:
3890 return 1;
3891}
3892#endif
3893
3894/* Set up a signal frame. */
3895
3896static int setup_sigcontext(struct target_sigcontext *sc,
3897 CPUOpenRISCState *regs,
3898 unsigned long mask)
3899{
3900 int err = 0;
3901 unsigned long usp = regs->gpr[1];
3902
3903 /* copy the regs. they are first in sc so we can use sc directly */
3904
3905 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3906
3907 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3908 the signal handler. The frametype will be restored to its previous
3909 value in restore_sigcontext. */
3910 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3911
3912 /* then some other stuff */
3913 err |= __put_user(mask, &sc->oldmask)(__builtin_choose_expr(sizeof(*(&sc->oldmask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 8, stq_be_p
, abort)))) ((&sc->oldmask), (mask)), 0)
;
3914 err |= __put_user(usp, &sc->usp)(__builtin_choose_expr(sizeof(*(&sc->usp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->usp)) == 8, stq_be_p
, abort)))) ((&sc->usp), (usp)), 0)
; return err;
3915}
3916
3917static inline unsigned long align_sigframe(unsigned long sp)
3918{
3919 unsigned long i;
3920 i = sp & ~3UL;
3921 return i;
3922}
3923
3924static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3925 CPUOpenRISCState *regs,
3926 size_t frame_size)
3927{
3928 unsigned long sp = regs->gpr[1];
3929 int onsigstack = on_sig_stack(sp);
3930
3931 /* redzone */
3932 /* This is the X/Open sanctioned signal stack switching. */
3933 if ((ka->sa_flags & SA_ONSTACK0x08000000) != 0 && !onsigstack) {
3934 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3935 }
3936
3937 sp = align_sigframe(sp - frame_size);
3938
3939 /*
3940 * If we are on the alternate signal stack and would overflow it, don't.
3941 * Return an always-bogus address instead so we will die with SIGSEGV.
3942 */
3943
3944 if (onsigstack && !likely(on_sig_stack(sp))__builtin_expect(!!(on_sig_stack(sp)), 1)) {
3945 return -1L;
3946 }
3947
3948 return sp;
3949}
3950
3951static void setup_frame(int sig, struct target_sigaction *ka,
3952 target_sigset_t *set, CPUOpenRISCState *env)
3953{
3954 qemu_log("Not implement.\n");
3955}
3956
3957static void setup_rt_frame(int sig, struct target_sigaction *ka,
3958 target_siginfo_t *info,
3959 target_sigset_t *set, CPUOpenRISCState *env)
3960{
3961 int err = 0;
3962 abi_ulong frame_addr;
3963 unsigned long return_ip;
3964 struct target_rt_sigframe *frame;
3965 abi_ulong info_addr, uc_addr;
3966
3967 frame_addr = get_sigframe(ka, env, sizeof *frame);
3968
3969 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3970 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
3971 goto give_sigsegv;
3972 }
3973
3974 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info)__builtin_offsetof(struct target_rt_sigframe, info);
3975 err |= __put_user(info_addr, &frame->pinfo)(__builtin_choose_expr(sizeof(*(&frame->pinfo)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->pinfo)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&frame->pinfo
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&frame->
pinfo)) == 8, stq_be_p, abort)))) ((&frame->pinfo), (info_addr
)), 0)
;
3976 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc)__builtin_offsetof(struct target_rt_sigframe, uc);
3977 err |= __put_user(uc_addr, &frame->puc)(__builtin_choose_expr(sizeof(*(&frame->puc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 8, stq_be_p
, abort)))) ((&frame->puc), (uc_addr)), 0)
;
3978
3979 if (ka->sa_flags & SA_SIGINFO4) {
3980 err |= copy_siginfo_to_user(&frame->info, info);
3981 }
3982 if (err) {
3983 goto give_sigsegv;
3984 }
3985
3986 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3987 err |= __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
3988 err |= __put_user(0, &frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&frame->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
frame->uc.tuc_link), (0)), 0)
;
3989 err |= __put_user(target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
3990 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
3991 err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->gpr[1]))), 0)
;
3992 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
3993 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
3994 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
3995
3996 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3997
3998 if (err) {
3999 goto give_sigsegv;
4000 }
4001
4002 /* trampoline - the desired return ip is the retcode itself */
4003 return_ip = (unsigned long)&frame->retcode;
4004 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4005 err |= __put_user(0xa960, (short *)(frame->retcode + 0))(__builtin_choose_expr(sizeof(*((short *)(frame->retcode +
0))) == 1, stb_p, __builtin_choose_expr(sizeof(*((short *)(frame
->retcode + 0))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((short *)(frame->retcode + 0))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((short *)(frame->retcode + 0))) == 8, stq_be_p, abort
)))) (((short *)(frame->retcode + 0)), (0xa960)), 0)
;
4006 err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2))(__builtin_choose_expr(sizeof(*((short *)(frame->retcode +
2))) == 1, stb_p, __builtin_choose_expr(sizeof(*((short *)(frame
->retcode + 2))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((short *)(frame->retcode + 2))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((short *)(frame->retcode + 2))) == 8, stq_be_p, abort
)))) (((short *)(frame->retcode + 2)), (101)), 0)
;
4007 err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4))(__builtin_choose_expr(sizeof(*((unsigned long *)(frame->retcode
+ 4))) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned
long *)(frame->retcode + 4))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((unsigned long *)(frame->retcode + 4))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((unsigned long *)(frame->
retcode + 4))) == 8, stq_be_p, abort)))) (((unsigned long *)(
frame->retcode + 4)), (0x20000001)), 0)
;
4008 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8))(__builtin_choose_expr(sizeof(*((unsigned long *)(frame->retcode
+ 8))) == 1, stb_p, __builtin_choose_expr(sizeof(*((unsigned
long *)(frame->retcode + 8))) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((unsigned long *)(frame->retcode + 8))) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((unsigned long *)(frame->
retcode + 8))) == 8, stq_be_p, abort)))) (((unsigned long *)(
frame->retcode + 8)), (0x15000000)), 0)
;
4009
4010 if (err) {
4011 goto give_sigsegv;
4012 }
4013
4014 /* TODO what is the current->exec_domain stuff and invmap ? */
4015
4016 /* Set up registers for signal handler */
4017 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
4018 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
4019 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
4020 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
4021 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
4022
4023 /* actually move the usp to reflect the stacked frame */
4024 env->gpr[1] = (unsigned long)frame;
4025
4026 return;
4027
4028give_sigsegv:
4029 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4030 if (sig == TARGET_SIGSEGV11) {
4031 ka->_sa_handler = TARGET_SIG_DFL((abi_long)0);
4032 }
4033 force_sig(TARGET_SIGSEGV11);
4034}
4035
4036long do_sigreturn(CPUOpenRISCState *env)
4037{
4038
4039 qemu_log("do_sigreturn: not implemented\n");
4040 return -TARGET_ENOSYS38;
4041}
4042
4043long do_rt_sigreturn(CPUOpenRISCState *env)
4044{
4045 qemu_log("do_rt_sigreturn: not implemented\n");
4046 return -TARGET_ENOSYS38;
4047}
4048/* TARGET_OPENRISC */
4049
4050#elif defined(TARGET_S390X)
4051
4052#define __NUM_GPRS 16
4053#define __NUM_FPRS 16
4054#define __NUM_ACRS 16
4055
4056#define S390_SYSCALL_SIZE 2
4057#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4058
4059#define _SIGCONTEXT_NSIG 64
4060#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4061#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4062#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4063#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4064#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4065
4066typedef struct {
4067 target_psw_t psw;
4068 target_ulong gprs[__NUM_GPRS];
4069 unsigned int acrs[__NUM_ACRS];
4070} target_s390_regs_common;
4071
4072typedef struct {
4073 unsigned int fpc;
4074 double fprs[__NUM_FPRS];
4075} target_s390_fp_regs;
4076
4077typedef struct {
4078 target_s390_regs_common regs;
4079 target_s390_fp_regs fpregs;
4080} target_sigregs;
4081
4082struct target_sigcontext {
4083 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4084 target_sigregs *sregs;
4085};
4086
4087typedef struct {
4088 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4089 struct target_sigcontext sc;
4090 target_sigregs sregs;
4091 int signo;
4092 uint8_t retcode[S390_SYSCALL_SIZE];
4093} sigframe;
4094
4095struct target_ucontext {
4096 target_ulong tuc_flags;
4097 struct target_ucontext *tuc_link;
4098 target_stack_t tuc_stack;
4099 target_sigregs tuc_mcontext;
4100 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4101};
4102
4103typedef struct {
4104 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4105 uint8_t retcode[S390_SYSCALL_SIZE];
4106 struct target_siginfo info;
4107 struct target_ucontext uc;
4108} rt_sigframe;
4109
4110static inline abi_ulong
4111get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4112{
4113 abi_ulong sp;
4114
4115 /* Default to using normal stack */
4116 sp = env->regs[15];
4117
4118 /* This is the X/Open sanctioned signal stack switching. */
4119 if (ka->sa_flags & TARGET_SA_ONSTACK1u) {
4120 if (!sas_ss_flags(sp)) {
4121 sp = target_sigaltstack_used.ss_sp +
4122 target_sigaltstack_used.ss_size;
4123 }
4124 }
4125
4126 /* This is the legacy signal stack switching. */
4127 else if (/* FIXME !user_mode(regs) */ 0 &&
4128 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4129 ka->sa_restorer) {
4130 sp = (abi_ulong) ka->sa_restorer;
4131 }
4132
4133 return (sp - frame_size) & -8ul;
4134}
4135
4136static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4137{
4138 int i;
4139 //save_access_regs(current->thread.acrs); FIXME
4140
4141 /* Copy a 'clean' PSW mask to the user to avoid leaking
4142 information about whether PER is currently on. */
4143 __put_user(env->psw.mask, &sregs->regs.psw.mask)(__builtin_choose_expr(sizeof(*(&sregs->regs.psw.mask)
) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sregs->
regs.psw.mask)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(&sregs->regs.psw.mask)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sregs->regs.psw.mask)) == 8, stq_be_p, abort
)))) ((&sregs->regs.psw.mask), (env->psw.mask)), 0)
;
4144 __put_user(env->psw.addr, &sregs->regs.psw.addr)(__builtin_choose_expr(sizeof(*(&sregs->regs.psw.addr)
) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sregs->
regs.psw.addr)) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(&sregs->regs.psw.addr)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sregs->regs.psw.addr)) == 8, stq_be_p, abort
)))) ((&sregs->regs.psw.addr), (env->psw.addr)), 0)
;
4145 for (i = 0; i < 16; i++) {
4146 __put_user(env->regs[i], &sregs->regs.gprs[i])(__builtin_choose_expr(sizeof(*(&sregs->regs.gprs[i]))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&sregs->regs
.gprs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
sregs->regs.gprs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sregs->regs.gprs[i])) == 8, stq_be_p, abort
)))) ((&sregs->regs.gprs[i]), (env->regs[i])), 0)
;
4147 }
4148 for (i = 0; i < 16; i++) {
4149 __put_user(env->aregs[i], &sregs->regs.acrs[i])(__builtin_choose_expr(sizeof(*(&sregs->regs.acrs[i]))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&sregs->regs
.acrs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
sregs->regs.acrs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sregs->regs.acrs[i])) == 8, stq_be_p, abort
)))) ((&sregs->regs.acrs[i]), (env->aregs[i])), 0)
;
4150 }
4151 /*
4152 * We have to store the fp registers to current->thread.fp_regs
4153 * to merge them with the emulated registers.
4154 */
4155 //save_fp_regs(&current->thread.fp_regs); FIXME
4156 for (i = 0; i < 16; i++) {
4157 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i])(__builtin_choose_expr(sizeof(*(&sregs->fpregs.fprs[i]
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&sregs->
fpregs.fprs[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&sregs->fpregs.fprs[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&sregs->fpregs.fprs[i])) == 8, stq_be_p, abort
)))) ((&sregs->fpregs.fprs[i]), (env->fregs[i].ll))
, 0)
;
4158 }
4159}
4160
4161static void setup_frame(int sig, struct target_sigaction *ka,
4162 target_sigset_t *set, CPUS390XState *env)
4163{
4164 sigframe *frame;
4165 abi_ulong frame_addr;
4166
4167 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4168 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4169 (unsigned long long)frame_addr);
4170 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
4171 goto give_sigsegv;
4172 }
4173
4174 qemu_log("%s: 1\n", __FUNCTION__);
4175 if (__put_user(set->sig[0], &frame->sc.oldmask[0])(__builtin_choose_expr(sizeof(*(&frame->sc.oldmask[0])
) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
sc.oldmask[0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(
*(&frame->sc.oldmask[0])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask[0])) == 8, stq_be_p, abort
)))) ((&frame->sc.oldmask[0]), (set->sig[0])), 0)
) {
4176 goto give_sigsegv;
4177 }
4178
4179 save_sigregs(env, &frame->sregs);
4180
4181 __put_user((abi_ulong)(unsigned long)&frame->sregs,(__builtin_choose_expr(sizeof(*((abi_ulong *)&frame->sc
.sregs)) == 1, stb_p, __builtin_choose_expr(sizeof(*((abi_ulong
*)&frame->sc.sregs)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&frame->sc.sregs)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *)&frame->
sc.sregs)) == 8, stq_be_p, abort)))) (((abi_ulong *)&frame
->sc.sregs), ((abi_ulong)(unsigned long)&frame->sregs
)), 0)
4182 (abi_ulong *)&frame->sc.sregs)(__builtin_choose_expr(sizeof(*((abi_ulong *)&frame->sc
.sregs)) == 1, stb_p, __builtin_choose_expr(sizeof(*((abi_ulong
*)&frame->sc.sregs)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&frame->sc.sregs)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *)&frame->
sc.sregs)) == 8, stq_be_p, abort)))) (((abi_ulong *)&frame
->sc.sregs), ((abi_ulong)(unsigned long)&frame->sregs
)), 0)
;
4183
4184 /* Set up to return from userspace. If provided, use a stub
4185 already in userspace. */
4186 if (ka->sa_flags & TARGET_SA_RESTORER) {
4187 env->regs[14] = (unsigned long)
4188 ka->sa_restorer | PSW_ADDR_AMODE;
4189 } else {
4190 env->regs[14] = (unsigned long)
4191 frame->retcode | PSW_ADDR_AMODE;
4192 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *)(
frame->retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((uint16_t *)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((uint16_t *)(frame->retcode)), (S390_SYSCALL_OPCODE
| 216)), 0)
4193 (uint16_t *)(frame->retcode))(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *)(
frame->retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((uint16_t *)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((uint16_t *)(frame->retcode)), (S390_SYSCALL_OPCODE
| 216)), 0)
)
4194 goto give_sigsegv;
4195 }
4196
4197 /* Set up backchain. */
4198 if (__put_user(env->regs[15], (abi_ulong *) frame)(__builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 1, stb_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 8, stq_be_p
, abort)))) (((abi_ulong *) frame), (env->regs[15])), 0)
) {
4199 goto give_sigsegv;
4200 }
4201
4202 /* Set up registers for signal handler */
4203 env->regs[15] = frame_addr;
4204 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4205
4206 env->regs[2] = sig; //map_signal(sig);
4207 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc)__builtin_offsetof(typeof(*frame), sc);
4208
4209 /* We forgot to include these in the sigcontext.
4210 To avoid breaking binary compatibility, they are passed as args. */
4211 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4212 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4213
4214 /* Place signal number on stack to allow backtrace from handler. */
4215 if (__put_user(env->regs[2], (int *) &frame->signo)(__builtin_choose_expr(sizeof(*((int *) &frame->signo)
) == 1, stb_p, __builtin_choose_expr(sizeof(*((int *) &frame
->signo)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*((
int *) &frame->signo)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((int *) &frame->signo)) == 8, stq_be_p, abort
)))) (((int *) &frame->signo), (env->regs[2])), 0)
) {
4216 goto give_sigsegv;
4217 }
4218 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4219 return;
4220
4221give_sigsegv:
4222 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4223 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4224 force_sig(TARGET_SIGSEGV11);
4225}
4226
4227static void setup_rt_frame(int sig, struct target_sigaction *ka,
4228 target_siginfo_t *info,
4229 target_sigset_t *set, CPUS390XState *env)
4230{
4231 int i;
4232 rt_sigframe *frame;
4233 abi_ulong frame_addr;
4234
4235 frame_addr = get_sigframe(ka, env, sizeof *frame);
4236 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4237 (unsigned long long)frame_addr);
4238 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
4239 goto give_sigsegv;
4240 }
4241
4242 qemu_log("%s: 1\n", __FUNCTION__);
4243 if (copy_siginfo_to_user(&frame->info, info)) {
4244 goto give_sigsegv;
4245 }
4246
4247 /* Create the ucontext. */
4248 __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
4249 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*((abi_ulong *)&frame->uc
.tuc_link)) == 1, stb_p, __builtin_choose_expr(sizeof(*((abi_ulong
*)&frame->uc.tuc_link)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&frame->uc.tuc_link)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *)&frame->
uc.tuc_link)) == 8, stq_be_p, abort)))) (((abi_ulong *)&frame
->uc.tuc_link), ((abi_ulong)0)), 0)
;
4250 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
4251 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env)))), 0)
4252 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(get_sp_from_cpustate(env)))), 0)
;
4253 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
4254 save_sigregs(env, &frame->uc.tuc_mcontext);
4255 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
4256 __put_user((abi_ulong)set->sig[i],(__builtin_choose_expr(sizeof(*((abi_ulong *)&frame->uc
.tuc_sigmask.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof
(*((abi_ulong *)&frame->uc.tuc_sigmask.sig[i])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *)&frame->
uc.tuc_sigmask.sig[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&frame->uc.tuc_sigmask.sig[i]))
== 8, stq_be_p, abort)))) (((abi_ulong *)&frame->uc.tuc_sigmask
.sig[i]), ((abi_ulong)set->sig[i])), 0)
4257 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*((abi_ulong *)&frame->uc
.tuc_sigmask.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof
(*((abi_ulong *)&frame->uc.tuc_sigmask.sig[i])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *)&frame->
uc.tuc_sigmask.sig[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((abi_ulong *)&frame->uc.tuc_sigmask.sig[i]))
== 8, stq_be_p, abort)))) (((abi_ulong *)&frame->uc.tuc_sigmask
.sig[i]), ((abi_ulong)set->sig[i])), 0)
;
4258 }
4259
4260 /* Set up to return from userspace. If provided, use a stub
4261 already in userspace. */
4262 if (ka->sa_flags & TARGET_SA_RESTORER) {
4263 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4264 } else {
4265 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4266 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *)(
frame->retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((uint16_t *)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((uint16_t *)(frame->retcode)), (S390_SYSCALL_OPCODE
| 101)), 0)
4267 (uint16_t *)(frame->retcode))(__builtin_choose_expr(sizeof(*((uint16_t *)(frame->retcode
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((uint16_t *)(
frame->retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((uint16_t *)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((uint16_t *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((uint16_t *)(frame->retcode)), (S390_SYSCALL_OPCODE
| 101)), 0)
) {
4268 goto give_sigsegv;
4269 }
4270 }
4271
4272 /* Set up backchain. */
4273 if (__put_user(env->regs[15], (abi_ulong *) frame)(__builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 1, stb_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*((abi_ulong *) frame)) == 8, stq_be_p
, abort)))) (((abi_ulong *) frame), (env->regs[15])), 0)
) {
4274 goto give_sigsegv;
4275 }
4276
4277 /* Set up registers for signal handler */
4278 env->regs[15] = frame_addr;
4279 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4280
4281 env->regs[2] = sig; //map_signal(sig);
4282 env->regs[3] = frame_addr + offsetof(typeof(*frame), info)__builtin_offsetof(typeof(*frame), info);
4283 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc)__builtin_offsetof(typeof(*frame), uc);
4284 return;
4285
4286give_sigsegv:
4287 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4288 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4289 force_sig(TARGET_SIGSEGV11);
4290}
4291
4292static int
4293restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4294{
4295 int err = 0;
4296 int i;
4297
4298 for (i = 0; i < 16; i++) {
4299 err |= __get_user(env->regs[i], &sc->regs.gprs[i])((env->regs[i]) = (typeof(*&sc->regs.gprs[i]))( __builtin_choose_expr
(sizeof(*(&sc->regs.gprs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.gprs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.gprs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.gprs[i])) == 8, ldq_be_p, abort)))
) (&sc->regs.gprs[i])), 0)
;
4300 }
4301
4302 err |= __get_user(env->psw.mask, &sc->regs.psw.mask)((env->psw.mask) = (typeof(*&sc->regs.psw.mask))( __builtin_choose_expr
(sizeof(*(&sc->regs.psw.mask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.mask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.mask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.mask)) == 8, ldq_be_p, abort))
)) (&sc->regs.psw.mask)), 0)
;
4303 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4304 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4305 (unsigned long long)env->psw.addr);
4306 err |= __get_user(env->psw.addr, &sc->regs.psw.addr)((env->psw.addr) = (typeof(*&sc->regs.psw.addr))( __builtin_choose_expr
(sizeof(*(&sc->regs.psw.addr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.addr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.addr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.psw.addr)) == 8, ldq_be_p, abort))
)) (&sc->regs.psw.addr)), 0)
;
4307 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4308
4309 for (i = 0; i < 16; i++) {
4310 err |= __get_user(env->aregs[i], &sc->regs.acrs[i])((env->aregs[i]) = (typeof(*&sc->regs.acrs[i]))( __builtin_choose_expr
(sizeof(*(&sc->regs.acrs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acrs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acrs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs.acrs[i])) == 8, ldq_be_p, abort)))
) (&sc->regs.acrs[i])), 0)
;
4311 }
4312 for (i = 0; i < 16; i++) {
4313 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i])((env->fregs[i].ll) = (typeof(*&sc->fpregs.fprs[i])
)( __builtin_choose_expr(sizeof(*(&sc->fpregs.fprs[i])
) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&sc->fpregs
.fprs[i])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(&
sc->fpregs.fprs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->fpregs.fprs[i])) == 8, ldq_be_p, abort)
))) (&sc->fpregs.fprs[i])), 0)
;
4314 }
4315
4316 return err;
4317}
4318
4319long do_sigreturn(CPUS390XState *env)
4320{
4321 sigframe *frame;
4322 abi_ulong frame_addr = env->regs[15];
4323 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4324 (unsigned long long)frame_addr);
4325 target_sigset_t target_set;
4326 sigset_t set;
4327
4328 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1))) {
4329 goto badframe;
4330 }
4331 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])((target_set.sig[0]) = (typeof(*&frame->sc.oldmask[0])
)( __builtin_choose_expr(sizeof(*(&frame->sc.oldmask[0
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame->
sc.oldmask[0])) == 2, lduw_be_p, __builtin_choose_expr(sizeof
(*(&frame->sc.oldmask[0])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.oldmask[0])) == 8, ldq_be_p, abort
)))) (&frame->sc.oldmask[0])), 0)
) {
4332 goto badframe;
4333 }
4334
4335 target_to_host_sigset_internal(&set, &target_set);
4336 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0)); /* ~_BLOCKABLE? */
4337
4338 if (restore_sigregs(env, &frame->sregs)) {
4339 goto badframe;
4340 }
4341
4342 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
4343 return env->regs[2];
4344
4345badframe:
4346 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
4347 force_sig(TARGET_SIGSEGV11);
4348 return 0;
4349}
4350
4351long do_rt_sigreturn(CPUS390XState *env)
4352{
4353 rt_sigframe *frame;
4354 abi_ulong frame_addr = env->regs[15];
4355 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4356 (unsigned long long)frame_addr);
4357 sigset_t set;
4358
4359 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1))) {
4360 goto badframe;
4361 }
4362 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4363
4364 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0)); /* ~_BLOCKABLE? */
4365
4366 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4367 goto badframe;
4368 }
4369
4370 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack)__builtin_offsetof(rt_sigframe, uc.tuc_stack), 0,
4371 get_sp_from_cpustate(env)) == -EFAULT14) {
4372 goto badframe;
4373 }
4374 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
4375 return env->regs[2];
4376
4377badframe:
4378 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
4379 force_sig(TARGET_SIGSEGV11);
4380 return 0;
4381}
4382
4383#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4384
4385/* FIXME: Many of the structures are defined for both PPC and PPC64, but
4386 the signal handling is different enough that we haven't implemented
4387 support for PPC64 yet. Hence the restriction above.
4388
4389 There are various #if'd blocks for code for TARGET_PPC64. These
4390 blocks should go away so that we can successfully run 32-bit and
4391 64-bit binaries on a QEMU configured for PPC64. */
4392
4393/* Size of dummy stack frame allocated when calling signal handler.
4394 See arch/powerpc/include/asm/ptrace.h. */
4395#if defined(TARGET_PPC64)
4396#define SIGNAL_FRAMESIZE 128
4397#else
4398#define SIGNAL_FRAMESIZE 64
4399#endif
4400
4401/* See arch/powerpc/include/asm/sigcontext.h. */
4402struct target_sigcontext {
4403 target_ulong _unused[4];
4404 int32_t signal;
4405#if defined(TARGET_PPC64)
4406 int32_t pad0;
4407#endif
4408 target_ulong handler;
4409 target_ulong oldmask;
4410 target_ulong regs; /* struct pt_regs __user * */
4411 /* TODO: PPC64 includes extra bits here. */
4412};
4413
4414/* Indices for target_mcontext.mc_gregs, below.
4415 See arch/powerpc/include/asm/ptrace.h for details. */
4416enum {
4417 TARGET_PT_R0 = 0,
4418 TARGET_PT_R1 = 1,
4419 TARGET_PT_R2 = 2,
4420 TARGET_PT_R3 = 3,
4421 TARGET_PT_R4 = 4,
4422 TARGET_PT_R5 = 5,
4423 TARGET_PT_R6 = 6,
4424 TARGET_PT_R7 = 7,
4425 TARGET_PT_R8 = 8,
4426 TARGET_PT_R9 = 9,
4427 TARGET_PT_R10 = 10,
4428 TARGET_PT_R11 = 11,
4429 TARGET_PT_R12 = 12,
4430 TARGET_PT_R13 = 13,
4431 TARGET_PT_R14 = 14,
4432 TARGET_PT_R15 = 15,
4433 TARGET_PT_R16 = 16,
4434 TARGET_PT_R17 = 17,
4435 TARGET_PT_R18 = 18,
4436 TARGET_PT_R19 = 19,
4437 TARGET_PT_R20 = 20,
4438 TARGET_PT_R21 = 21,
4439 TARGET_PT_R22 = 22,
4440 TARGET_PT_R23 = 23,
4441 TARGET_PT_R24 = 24,
4442 TARGET_PT_R25 = 25,
4443 TARGET_PT_R26 = 26,
4444 TARGET_PT_R27 = 27,
4445 TARGET_PT_R28 = 28,
4446 TARGET_PT_R29 = 29,
4447 TARGET_PT_R30 = 30,
4448 TARGET_PT_R31 = 31,
4449 TARGET_PT_NIP = 32,
4450 TARGET_PT_MSR = 33,
4451 TARGET_PT_ORIG_R3 = 34,
4452 TARGET_PT_CTR = 35,
4453 TARGET_PT_LNK = 36,
4454 TARGET_PT_XER = 37,
4455 TARGET_PT_CCR = 38,
4456 /* Yes, there are two registers with #39. One is 64-bit only. */
4457 TARGET_PT_MQ = 39,
4458 TARGET_PT_SOFTE = 39,
4459 TARGET_PT_TRAP = 40,
4460 TARGET_PT_DAR = 41,
4461 TARGET_PT_DSISR = 42,
4462 TARGET_PT_RESULT = 43,
4463 TARGET_PT_REGS_COUNT = 44
4464};
4465
4466/* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4467 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4468struct target_mcontext {
4469 target_ulong mc_gregs[48];
4470 /* Includes fpscr. */
4471 uint64_t mc_fregs[33];
4472 target_ulong mc_pad[2];
4473 /* We need to handle Altivec and SPE at the same time, which no
4474 kernel needs to do. Fortunately, the kernel defines this bit to
4475 be Altivec-register-large all the time, rather than trying to
4476 twiddle it based on the specific platform. */
4477 union {
4478 /* SPE vector registers. One extra for SPEFSCR. */
4479 uint32_t spe[33];
4480 /* Altivec vector registers. The packing of VSCR and VRSAVE
4481 varies depending on whether we're PPC64 or not: PPC64 splits
4482 them apart; PPC32 stuffs them together. */
4483#if defined(TARGET_PPC64)
4484#define QEMU_NVRREG 34
4485#else
4486#define QEMU_NVRREG 33
4487#endif
4488 ppc_avr_t altivec[QEMU_NVRREG];
4489#undef QEMU_NVRREG
4490 } mc_vregs __attribute__((__aligned__(16)));
4491};
4492
4493struct target_ucontext {
4494 target_ulong tuc_flags;
4495 target_ulong tuc_link; /* struct ucontext __user * */
4496 struct target_sigaltstack tuc_stack;
4497#if !defined(TARGET_PPC64)
4498 int32_t tuc_pad[7];
4499 target_ulong tuc_regs; /* struct mcontext __user *
4500 points to uc_mcontext field */
4501#endif
4502 target_sigset_t tuc_sigmask;
4503#if defined(TARGET_PPC64)
4504 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4505 struct target_sigcontext tuc_mcontext;
4506#else
4507 int32_t tuc_maskext[30];
4508 int32_t tuc_pad2[3];
4509 struct target_mcontext tuc_mcontext;
4510#endif
4511};
4512
4513/* See arch/powerpc/kernel/signal_32.c. */
4514struct target_sigframe {
4515 struct target_sigcontext sctx;
4516 struct target_mcontext mctx;
4517 int32_t abigap[56];
4518};
4519
4520struct target_rt_sigframe {
4521 struct target_siginfo info;
4522 struct target_ucontext uc;
4523 int32_t abigap[56];
4524};
4525
4526/* We use the mc_pad field for the signal return trampoline. */
4527#define tramp mc_pad
4528
4529/* See arch/powerpc/kernel/signal.c. */
4530static target_ulong get_sigframe(struct target_sigaction *ka,
4531 CPUPPCState *env,
4532 int frame_size)
4533{
4534 target_ulong oldsp, newsp;
4535
4536 oldsp = env->gpr[1];
4537
4538 if ((ka->sa_flags & TARGET_SA_ONSTACK1u) &&
4539 (sas_ss_flags(oldsp) == 0)) {
4540 oldsp = (target_sigaltstack_used.ss_sp
4541 + target_sigaltstack_used.ss_size);
4542 }
4543
4544 newsp = (oldsp - frame_size) & ~0xFUL;
4545
4546 return newsp;
4547}
4548
4549static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4550 int sigret)
4551{
4552 target_ulong msr = env->msr;
4553 int i;
4554 target_ulong ccr = 0;
4555
4556 /* In general, the kernel attempts to be intelligent about what it
4557 needs to save for Altivec/FP/SPE registers. We don't care that
4558 much, so we just go ahead and save everything. */
4559
4560 /* Save general registers. */
4561 for (i = 0; i < ARRAY_SIZE(env->gpr)(sizeof(env->gpr) / sizeof((env->gpr)[0])); i++) {
4562 if (__put_user(env->gpr[i], &frame->mc_gregs[i])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->mc_gregs
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->mc_gregs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_gregs[i])) == 8, stq_be_p, abort)))) ((&
frame->mc_gregs[i]), (env->gpr[i])), 0)
) {
4563 return 1;
4564 }
4565 }
4566 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_NIP])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_NIP
]), (env->nip)), 0)
4567 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_CTR])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_CTR
]), (env->ctr)), 0)
4568 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_LNK])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_LNK
]), (env->lr)), 0)
4569 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_XER
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_XER])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_XER])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_XER
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_XER
]), (env->xer)), 0)
)
4570 return 1;
4571
4572 for (i = 0; i < ARRAY_SIZE(env->crf)(sizeof(env->crf) / sizeof((env->crf)[0])); i++) {
4573 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4574 }
4575 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_CCR])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_CCR
]), (ccr)), 0)
)
4576 return 1;
4577
4578 /* Save Altivec registers if necessary. */
4579 if (env->insns_flags & PPC_ALTIVEC) {
4580 for (i = 0; i < ARRAY_SIZE(env->avr)(sizeof(env->avr) / sizeof((env->avr)[0])); i++) {
4581 ppc_avr_t *avr = &env->avr[i];
4582 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4583
4584 if (__put_user(avr->u64[0], &vreg->u64[0])(__builtin_choose_expr(sizeof(*(&vreg->u64[0])) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&vreg->u64[0])) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&vreg->u64[0
])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&vreg->
u64[0])) == 8, stq_be_p, abort)))) ((&vreg->u64[0]), (
avr->u64[0])), 0)
||
4585 __put_user(avr->u64[1], &vreg->u64[1])(__builtin_choose_expr(sizeof(*(&vreg->u64[1])) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&vreg->u64[1])) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&vreg->u64[1
])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&vreg->
u64[1])) == 8, stq_be_p, abort)))) ((&vreg->u64[1]), (
avr->u64[1])), 0)
) {
4586 return 1;
4587 }
4588 }
4589 /* Set MSR_VR in the saved MSR value to indicate that
4590 frame->mc_vregs contains valid data. */
4591 msr |= MSR_VR;
4592 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],(__builtin_choose_expr(sizeof(*(&frame->mc_vregs.altivec
[32].u32[3])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&
frame->mc_vregs.altivec[32].u32[3])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.altivec[32].u32[3])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_vregs.altivec
[32].u32[3])) == 8, stq_be_p, abort)))) ((&frame->mc_vregs
.altivec[32].u32[3]), ((uint32_t)env->spr[SPR_VRSAVE])), 0
)
4593 &frame->mc_vregs.altivec[32].u32[3])(__builtin_choose_expr(sizeof(*(&frame->mc_vregs.altivec
[32].u32[3])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&
frame->mc_vregs.altivec[32].u32[3])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.altivec[32].u32[3])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_vregs.altivec
[32].u32[3])) == 8, stq_be_p, abort)))) ((&frame->mc_vregs
.altivec[32].u32[3]), ((uint32_t)env->spr[SPR_VRSAVE])), 0
)
)
4594 return 1;
4595 }
4596
4597 /* Save floating point registers. */
4598 if (env->insns_flags & PPC_FLOAT) {
4599 for (i = 0; i < ARRAY_SIZE(env->fpr)(sizeof(env->fpr) / sizeof((env->fpr)[0])); i++) {
4600 if (__put_user(env->fpr[i], &frame->mc_fregs[i])(__builtin_choose_expr(sizeof(*(&frame->mc_fregs[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->mc_fregs
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->mc_fregs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_fregs[i])) == 8, stq_be_p, abort)))) ((&
frame->mc_fregs[i]), (env->fpr[i])), 0)
) {
4601 return 1;
4602 }
4603 }
4604 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32])(__builtin_choose_expr(sizeof(*(&frame->mc_fregs[32]))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->mc_fregs
[32])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->mc_fregs[32])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_fregs[32])) == 8, stq_be_p, abort)))) ((
&frame->mc_fregs[32]), ((uint64_t) env->fpscr)), 0)
)
4605 return 1;
4606 }
4607
4608 /* Save SPE registers. The kernel only saves the high half. */
4609 if (env->insns_flags & PPC_SPE) {
4610#if defined(TARGET_PPC64)
4611 for (i = 0; i < ARRAY_SIZE(env->gpr)(sizeof(env->gpr) / sizeof((env->gpr)[0])); i++) {
4612 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])(__builtin_choose_expr(sizeof(*(&frame->mc_vregs.spe[i
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_vregs.spe[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_vregs.spe[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 8, stq_be_p, abort
)))) ((&frame->mc_vregs.spe[i]), (env->gpr[i] >>
32)), 0)
) {
4613 return 1;
4614 }
4615 }
4616#else
4617 for (i = 0; i < ARRAY_SIZE(env->gprh)(sizeof(env->gprh) / sizeof((env->gprh)[0])); i++) {
4618 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])(__builtin_choose_expr(sizeof(*(&frame->mc_vregs.spe[i
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_vregs.spe[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_vregs.spe[i])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 8, stq_be_p, abort
)))) ((&frame->mc_vregs.spe[i]), (env->gprh[i])), 0
)
) {
4619 return 1;
4620 }
4621 }
4622#endif
4623 /* Set MSR_SPE in the saved MSR value to indicate that
4624 frame->mc_vregs contains valid data. */
4625 msr |= MSR_SPE;
4626 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32])(__builtin_choose_expr(sizeof(*(&frame->mc_vregs.spe[32
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_vregs.spe[32])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->mc_vregs.spe[32])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[32])) == 8, stq_be_p, abort
)))) ((&frame->mc_vregs.spe[32]), (env->spe_fscr)),
0)
)
4627 return 1;
4628 }
4629
4630 /* Store MSR. */
4631 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR])(__builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_MSR])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR
])) == 8, stq_be_p, abort)))) ((&frame->mc_gregs[TARGET_PT_MSR
]), (msr)), 0)
)
4632 return 1;
4633
4634 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4635 if (sigret) {
4636 if (__put_user(0x38000000UL | sigret, &frame->tramp[0])(__builtin_choose_expr(sizeof(*(&frame->tramp[0])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->tramp[
0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->tramp[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&frame->tramp[0])) == 8, stq_be_p, abort)))) ((&
frame->tramp[0]), (0x38000000UL | sigret)), 0)
||
4637 __put_user(0x44000002UL, &frame->tramp[1])(__builtin_choose_expr(sizeof(*(&frame->tramp[1])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->tramp[
1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->tramp[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&frame->tramp[1])) == 8, stq_be_p, abort)))) ((&
frame->tramp[1]), (0x44000002UL)), 0)
) {
4638 return 1;
4639 }
4640 }
4641
4642 return 0;
4643}
4644
4645static int restore_user_regs(CPUPPCState *env,
4646 struct target_mcontext *frame, int sig)
4647{
4648 target_ulong save_r2 = 0;
4649 target_ulong msr;
4650 target_ulong ccr;
4651
4652 int i;
4653
4654 if (!sig) {
4655 save_r2 = env->gpr[2];
4656 }
4657
4658 /* Restore general registers. */
4659 for (i = 0; i < ARRAY_SIZE(env->gpr)(sizeof(env->gpr) / sizeof((env->gpr)[0])); i++) {
4660 if (__get_user(env->gpr[i], &frame->mc_gregs[i])((env->gpr[i]) = (typeof(*&frame->mc_gregs[i]))( __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[i])) == 8, ldq_be_p, abort)
))) (&frame->mc_gregs[i])), 0)
) {
4661 return 1;
4662 }
4663 }
4664 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])((env->nip) = (typeof(*&frame->mc_gregs[TARGET_PT_NIP
]))( __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_NIP])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_NIP
])) == 8, ldq_be_p, abort)))) (&frame->mc_gregs[TARGET_PT_NIP
])), 0)
4665 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])((env->ctr) = (typeof(*&frame->mc_gregs[TARGET_PT_CTR
]))( __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_CTR])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CTR
])) == 8, ldq_be_p, abort)))) (&frame->mc_gregs[TARGET_PT_CTR
])), 0)
4666 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])((env->lr) = (typeof(*&frame->mc_gregs[TARGET_PT_LNK
]))( __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_LNK])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_LNK
])) == 8, ldq_be_p, abort)))) (&frame->mc_gregs[TARGET_PT_LNK
])), 0)
4667 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER])((env->xer) = (typeof(*&frame->mc_gregs[TARGET_PT_XER
]))( __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_XER
])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame->
mc_gregs[TARGET_PT_XER])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_XER])) == 4, ldl_be_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_XER
])) == 8, ldq_be_p, abort)))) (&frame->mc_gregs[TARGET_PT_XER
])), 0)
)
4668 return 1;
4669 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR])((ccr) = (typeof(*&frame->mc_gregs[TARGET_PT_CCR]))( __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR])) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR
])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(&frame
->mc_gregs[TARGET_PT_CCR])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_CCR])) == 8, ldq_be_p
, abort)))) (&frame->mc_gregs[TARGET_PT_CCR])), 0)
)
4670 return 1;
4671
4672 for (i = 0; i < ARRAY_SIZE(env->crf)(sizeof(env->crf) / sizeof((env->crf)[0])); i++) {
4673 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4674 }
4675
4676 if (!sig) {
4677 env->gpr[2] = save_r2;
4678 }
4679 /* Restore MSR. */
4680 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR])((msr) = (typeof(*&frame->mc_gregs[TARGET_PT_MSR]))( __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR])) == 1, ldub_p
, __builtin_choose_expr(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR
])) == 2, lduw_be_p, __builtin_choose_expr(sizeof(*(&frame
->mc_gregs[TARGET_PT_MSR])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_gregs[TARGET_PT_MSR])) == 8, ldq_be_p
, abort)))) (&frame->mc_gregs[TARGET_PT_MSR])), 0)
)
4681 return 1;
4682
4683 /* If doing signal return, restore the previous little-endian mode. */
4684 if (sig)
4685 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4686
4687 /* Restore Altivec registers if necessary. */
4688 if (env->insns_flags & PPC_ALTIVEC) {
4689 for (i = 0; i < ARRAY_SIZE(env->avr)(sizeof(env->avr) / sizeof((env->avr)[0])); i++) {
4690 ppc_avr_t *avr = &env->avr[i];
4691 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4692
4693 if (__get_user(avr->u64[0], &vreg->u64[0])((avr->u64[0]) = (typeof(*&vreg->u64[0]))( __builtin_choose_expr
(sizeof(*(&vreg->u64[0])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[0])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[0])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[0])) == 8, ldq_be_p, abort)))) (&
vreg->u64[0])), 0)
||
4694 __get_user(avr->u64[1], &vreg->u64[1])((avr->u64[1]) = (typeof(*&vreg->u64[1]))( __builtin_choose_expr
(sizeof(*(&vreg->u64[1])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&vreg->u64[1])) == 8, ldq_be_p, abort)))) (&
vreg->u64[1])), 0)
) {
4695 return 1;
4696 }
4697 }
4698 /* Set MSR_VEC in the saved MSR value to indicate that
4699 frame->mc_vregs contains valid data. */
4700 if (__get_user(env->spr[SPR_VRSAVE],((env->spr[SPR_VRSAVE]) = (typeof(*(target_ulong *)(&frame
->mc_vregs.altivec[32].u32[3])))( __builtin_choose_expr(sizeof
(*((target_ulong *)(&frame->mc_vregs.altivec[32].u32[3
]))) == 1, ldub_p, __builtin_choose_expr(sizeof(*((target_ulong
*)(&frame->mc_vregs.altivec[32].u32[3]))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*((target_ulong *)(&frame->
mc_vregs.altivec[32].u32[3]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((target_ulong *)(&frame->mc_vregs.altivec[32
].u32[3]))) == 8, ldq_be_p, abort)))) ((target_ulong *)(&
frame->mc_vregs.altivec[32].u32[3]))), 0)
4701 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3]))((env->spr[SPR_VRSAVE]) = (typeof(*(target_ulong *)(&frame
->mc_vregs.altivec[32].u32[3])))( __builtin_choose_expr(sizeof
(*((target_ulong *)(&frame->mc_vregs.altivec[32].u32[3
]))) == 1, ldub_p, __builtin_choose_expr(sizeof(*((target_ulong
*)(&frame->mc_vregs.altivec[32].u32[3]))) == 2, lduw_be_p
, __builtin_choose_expr(sizeof(*((target_ulong *)(&frame->
mc_vregs.altivec[32].u32[3]))) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*((target_ulong *)(&frame->mc_vregs.altivec[32
].u32[3]))) == 8, ldq_be_p, abort)))) ((target_ulong *)(&
frame->mc_vregs.altivec[32].u32[3]))), 0)
)
4702 return 1;
4703 }
4704
4705 /* Restore floating point registers. */
4706 if (env->insns_flags & PPC_FLOAT) {
4707 uint64_t fpscr;
4708 for (i = 0; i < ARRAY_SIZE(env->fpr)(sizeof(env->fpr) / sizeof((env->fpr)[0])); i++) {
4709 if (__get_user(env->fpr[i], &frame->mc_fregs[i])((env->fpr[i]) = (typeof(*&frame->mc_fregs[i]))( __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[i])) == 8, ldq_be_p, abort)
))) (&frame->mc_fregs[i])), 0)
) {
4710 return 1;
4711 }
4712 }
4713 if (__get_user(fpscr, &frame->mc_fregs[32])((fpscr) = (typeof(*&frame->mc_fregs[32]))( __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[32])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[32])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[32])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_fregs[32])) == 8, ldq_be_p, abort
)))) (&frame->mc_fregs[32])), 0)
)
4714 return 1;
4715 env->fpscr = (uint32_t) fpscr;
4716 }
4717
4718 /* Save SPE registers. The kernel only saves the high half. */
4719 if (env->insns_flags & PPC_SPE) {
4720#if defined(TARGET_PPC64)
4721 for (i = 0; i < ARRAY_SIZE(env->gpr)(sizeof(env->gpr) / sizeof((env->gpr)[0])); i++) {
4722 uint32_t hi;
4723
4724 if (__get_user(hi, &frame->mc_vregs.spe[i])((hi) = (typeof(*&frame->mc_vregs.spe[i]))( __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 8, ldq_be_p, abort
)))) (&frame->mc_vregs.spe[i])), 0)
) {
4725 return 1;
4726 }
4727 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4728 }
4729#else
4730 for (i = 0; i < ARRAY_SIZE(env->gprh)(sizeof(env->gprh) / sizeof((env->gprh)[0])); i++) {
4731 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])((env->gprh[i]) = (typeof(*&frame->mc_vregs.spe[i])
)( __builtin_choose_expr(sizeof(*(&frame->mc_vregs.spe
[i])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->mc_vregs.spe[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[i])) == 8, ldq_be_p, abort
)))) (&frame->mc_vregs.spe[i])), 0)
) {
4732 return 1;
4733 }
4734 }
4735#endif
4736 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32])((env->spe_fscr) = (typeof(*&frame->mc_vregs.spe[32
]))( __builtin_choose_expr(sizeof(*(&frame->mc_vregs.spe
[32])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->mc_vregs.spe[32])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[32])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->mc_vregs.spe[32])) == 8, ldq_be_p, abort
)))) (&frame->mc_vregs.spe[32])), 0)
)
4737 return 1;
4738 }
4739
4740 return 0;
4741}
4742
4743static void setup_frame(int sig, struct target_sigaction *ka,
4744 target_sigset_t *set, CPUPPCState *env)
4745{
4746 struct target_sigframe *frame;
4747 struct target_sigcontext *sc;
4748 target_ulong frame_addr, newsp;
4749 int err = 0;
4750 int signal;
4751
4752 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4753 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)(frame = lock_user(1, frame_addr, sizeof(*frame), 1)))
4754 goto sigsegv;
4755 sc = &frame->sctx;
4756
4757 signal = current_exec_domain_sig(sig);
4758
4759 err |= __put_user(ka->_sa_handler, &sc->handler)(__builtin_choose_expr(sizeof(*(&sc->handler)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->handler)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->handler)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->handler)) == 8, stq_be_p
, abort)))) ((&sc->handler), (ka->_sa_handler)), 0)
;
4760 err |= __put_user(set->sig[0], &sc->oldmask)(__builtin_choose_expr(sizeof(*(&sc->oldmask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->oldmask)) == 8, stq_be_p
, abort)))) ((&sc->oldmask), (set->sig[0])), 0)
;
4761#if defined(TARGET_PPC64)
4762 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3])(__builtin_choose_expr(sizeof(*(&sc->_unused[3])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->_unused[3
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
_unused[3])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->_unused[3])) == 8, stq_be_p, abort)))) ((&sc->_unused
[3]), (set->sig[0] >> 32)), 0)
;
4763#else
4764 err |= __put_user(set->sig[1], &sc->_unused[3])(__builtin_choose_expr(sizeof(*(&sc->_unused[3])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->_unused[3
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
_unused[3])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->_unused[3])) == 8, stq_be_p, abort)))) ((&sc->_unused
[3]), (set->sig[1])), 0)
;
4765#endif
4766 err |= __put_user(h2g(&frame->mctx), &sc->regs)(__builtin_choose_expr(sizeof(*(&sc->regs)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->regs)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->regs)) == 8, stq_be_p
, abort)))) ((&sc->regs), (({ ((({ unsigned long __guest
= (unsigned long)(&frame->mctx) - guest_base; (__guest
< (1ul << 44)) && (!reserved_va || (__guest
< reserved_va)); })) ? (void) (0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(&frame->mctx) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4766
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(&frame->mctx) - guest_base; (abi_ulong)__ret; }); })
)), 0)
;
4767 err |= __put_user(sig, &sc->signal)(__builtin_choose_expr(sizeof(*(&sc->signal)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->signal)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->signal)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->signal)) == 8, stq_be_p
, abort)))) ((&sc->signal), (sig)), 0)
;
4768
4769 /* Save user regs. */
4770 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn216);
4771
4772 /* The kernel checks for the presence of a VDSO here. We don't
4773 emulate a vdso, so use a sigreturn system call. */
4774 env->lr = (target_ulong) h2g(frame->mctx.tramp)({ ((({ unsigned long __guest = (unsigned long)(frame->mctx
.tramp) - guest_base; (__guest < (1ul << 44)) &&
(!reserved_va || (__guest < reserved_va)); })) ? (void) (
0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(frame->mctx.tramp) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4774
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(frame->mctx.tramp) - guest_base; (abi_ulong)__ret; }); }
)
;
4775
4776 /* Turn off all fp exceptions. */
4777 env->fpscr = 0;
4778
4779 /* Create a stack frame for the caller of the handler. */
4780 newsp = frame_addr - SIGNAL_FRAMESIZE;
4781 err |= put_user(env->gpr[1], newsp, target_ulong)({ abi_ulong __gaddr = (newsp); target_ulong *__hptr; abi_long
__ret; if ((__hptr = lock_user(1, __gaddr, sizeof(target_ulong
), 0))) { __ret = (__builtin_choose_expr(sizeof(*(__hptr)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(__hptr)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(__hptr)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(__hptr)) == 8, stq_be_p, abort)))) ((__hptr), ((env
->gpr[1]))), 0); unlock_user(__hptr, __gaddr, sizeof(target_ulong
)); } else __ret = -14; __ret; })
;
4782
4783 if (err)
4784 goto sigsegv;
4785
4786 /* Set up registers for signal handler. */
4787 env->gpr[1] = newsp;
4788 env->gpr[3] = signal;
4789 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx)__builtin_offsetof(struct target_sigframe, sctx);
4790 env->nip = (target_ulong) ka->_sa_handler;
4791 /* Signal handlers are entered in big-endian mode. */
4792 env->msr &= ~MSR_LE;
4793
4794 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4795 return;
4796
4797sigsegv:
4798 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
4799 qemu_log("segfaulting from setup_frame\n");
4800 force_sig(TARGET_SIGSEGV11);
4801}
4802
4803static void setup_rt_frame(int sig, struct target_sigaction *ka,
4804 target_siginfo_t *info,
4805 target_sigset_t *set, CPUPPCState *env)
4806{
4807 struct target_rt_sigframe *rt_sf;
4808 struct target_mcontext *frame;
4809 target_ulong rt_sf_addr, newsp = 0;
4810 int i, err = 0;
4811 int signal;
4812
4813 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4814 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1)(rt_sf = lock_user(1, rt_sf_addr, sizeof(*rt_sf), 1)))
4815 goto sigsegv;
4816
4817 signal = current_exec_domain_sig(sig);
4818
4819 err |= copy_siginfo_to_user(&rt_sf->info, info);
4820
4821 err |= __put_user(0, &rt_sf->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
rt_sf->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&rt_sf->uc.tuc_flags), (0)), 0)
;
4822 err |= __put_user(0, &rt_sf->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&rt_sf->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
rt_sf->uc.tuc_link), (0)), 0)
;
4823 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&rt_sf->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&rt_sf->uc.tuc_stack.ss_sp), ((target_ulong
)target_sigaltstack_used.ss_sp)), 0)
4824 &rt_sf->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&rt_sf->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&rt_sf->uc.tuc_stack.ss_sp), ((target_ulong
)target_sigaltstack_used.ss_sp)), 0)
;
4825 err |= __put_user(sas_ss_flags(env->gpr[1]),(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&rt_sf->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->gpr[1]))), 0)
4826 &rt_sf->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&rt_sf->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->gpr[1]))), 0)
;
4827 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&rt_sf->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&rt_sf->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
4828 &rt_sf->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&rt_sf->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&rt_sf->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
4829 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_regs)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_regs
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_regs)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&rt_sf->uc.tuc_regs)) == 8, stq_be_p, abort)))) ((&
rt_sf->uc.tuc_regs), (({ ((({ unsigned long __guest = (unsigned
long)(&rt_sf->uc.tuc_mcontext) - guest_base; (__guest
< (1ul << 44)) && (!reserved_va || (__guest
< reserved_va)); })) ? (void) (0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(&rt_sf->uc.tuc_mcontext) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4829
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(&rt_sf->uc.tuc_mcontext) - guest_base; (abi_ulong)__ret
; }); }))), 0)
4830 &rt_sf->uc.tuc_regs)(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_regs)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_regs
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&rt_sf->
uc.tuc_regs)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&rt_sf->uc.tuc_regs)) == 8, stq_be_p, abort)))) ((&
rt_sf->uc.tuc_regs), (({ ((({ unsigned long __guest = (unsigned
long)(&rt_sf->uc.tuc_mcontext) - guest_base; (__guest
< (1ul << 44)) && (!reserved_va || (__guest
< reserved_va)); })) ? (void) (0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(&rt_sf->uc.tuc_mcontext) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4829
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(&rt_sf->uc.tuc_mcontext) - guest_base; (abi_ulong)__ret
; }); }))), 0)
;
4831 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
4832 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&rt_sf
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&rt_sf->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&rt_sf->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&rt_sf->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
;
4833 }
4834
4835 frame = &rt_sf->uc.tuc_mcontext;
4836 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn101);
4837
4838 /* The kernel checks for the presence of a VDSO here. We don't
4839 emulate a vdso, so use a sigreturn system call. */
4840 env->lr = (target_ulong) h2g(frame->tramp)({ ((({ unsigned long __guest = (unsigned long)(frame->tramp
) - guest_base; (__guest < (1ul << 44)) && (
!reserved_va || (__guest < reserved_va)); })) ? (void) (0)
: __assert_fail ("({ unsigned long __guest = (unsigned long)(frame->tramp) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4840
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(frame->tramp) - guest_base; (abi_ulong)__ret; }); })
;
4841
4842 /* Turn off all fp exceptions. */
4843 env->fpscr = 0;
4844
4845 /* Create a stack frame for the caller of the handler. */
4846 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4847 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp)(__builtin_choose_expr(sizeof(*((target_ulong *)(uintptr_t) newsp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*((target_ulong *
)(uintptr_t) newsp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((target_ulong *)(uintptr_t) newsp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((target_ulong *)(uintptr_t) newsp)) == 8, stq_be_p,
abort)))) (((target_ulong *)(uintptr_t) newsp), (env->gpr
[1])), 0)
;
4848
4849 if (err)
4850 goto sigsegv;
4851
4852 /* Set up registers for signal handler. */
4853 env->gpr[1] = newsp;
4854 env->gpr[3] = (target_ulong) signal;
4855 env->gpr[4] = (target_ulong) h2g(&rt_sf->info)({ ((({ unsigned long __guest = (unsigned long)(&rt_sf->
info) - guest_base; (__guest < (1ul << 44)) &&
(!reserved_va || (__guest < reserved_va)); })) ? (void) (
0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(&rt_sf->info) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4855
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(&rt_sf->info) - guest_base; (abi_ulong)__ret; }); })
;
4856 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc)({ ((({ unsigned long __guest = (unsigned long)(&rt_sf->
uc) - guest_base; (__guest < (1ul << 44)) &&
(!reserved_va || (__guest < reserved_va)); })) ? (void) (
0) : __assert_fail ("({ unsigned long __guest = (unsigned long)(&rt_sf->uc) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4856
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(&rt_sf->uc) - guest_base; (abi_ulong)__ret; }); })
;
4857 env->gpr[6] = (target_ulong) h2g(rt_sf)({ ((({ unsigned long __guest = (unsigned long)(rt_sf) - guest_base
; (__guest < (1ul << 44)) && (!reserved_va ||
(__guest < reserved_va)); })) ? (void) (0) : __assert_fail
("({ unsigned long __guest = (unsigned long)(rt_sf) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4857
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(rt_sf) - guest_base; (abi_ulong)__ret; }); })
;
4858 env->nip = (target_ulong) ka->_sa_handler;
4859 /* Signal handlers are entered in big-endian mode. */
4860 env->msr &= ~MSR_LE;
4861
4862 unlock_user_struct(rt_sf, rt_sf_addr, 1)unlock_user(rt_sf, rt_sf_addr, (1) ? sizeof(*rt_sf) : 0);
4863 return;
4864
4865sigsegv:
4866 unlock_user_struct(rt_sf, rt_sf_addr, 1)unlock_user(rt_sf, rt_sf_addr, (1) ? sizeof(*rt_sf) : 0);
4867 qemu_log("segfaulting from setup_rt_frame\n");
4868 force_sig(TARGET_SIGSEGV11);
4869
4870}
4871
4872long do_sigreturn(CPUPPCState *env)
4873{
4874 struct target_sigcontext *sc = NULL((void*)0);
4875 struct target_mcontext *sr = NULL((void*)0);
4876 target_ulong sr_addr = 0, sc_addr;
4877 sigset_t blocked;
4878 target_sigset_t set;
4879
4880 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4881 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)(sc = lock_user(0, sc_addr, sizeof(*sc), 1)))
4882 goto sigsegv;
4883
4884#if defined(TARGET_PPC64)
4885 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4886#else
4887 if(__get_user(set.sig[0], &sc->oldmask)((set.sig[0]) = (typeof(*&sc->oldmask))( __builtin_choose_expr
(sizeof(*(&sc->oldmask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->oldmask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->oldmask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->oldmask)) == 8, ldq_be_p, abort)))) (&
sc->oldmask)), 0)
||
4888 __get_user(set.sig[1], &sc->_unused[3])((set.sig[1]) = (typeof(*&sc->_unused[3]))( __builtin_choose_expr
(sizeof(*(&sc->_unused[3])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->_unused[3])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->_unused[3])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->_unused[3])) == 8, ldq_be_p, abort)))) (
&sc->_unused[3])), 0)
)
4889 goto sigsegv;
4890#endif
4891 target_to_host_sigset_internal(&blocked, &set);
4892 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
4893
4894 if (__get_user(sr_addr, &sc->regs)((sr_addr) = (typeof(*&sc->regs))( __builtin_choose_expr
(sizeof(*(&sc->regs)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->regs)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->regs)) == 8, ldq_be_p, abort)))) (&
sc->regs)), 0)
)
4895 goto sigsegv;
4896 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1)(sr = lock_user(0, sr_addr, sizeof(*sr), 1)))
4897 goto sigsegv;
4898 if (restore_user_regs(env, sr, 1))
4899 goto sigsegv;
4900
4901 unlock_user_struct(sr, sr_addr, 1)unlock_user(sr, sr_addr, (1) ? sizeof(*sr) : 0);
4902 unlock_user_struct(sc, sc_addr, 1)unlock_user(sc, sc_addr, (1) ? sizeof(*sc) : 0);
4903 return -TARGET_QEMU_ESIGRETURN;
4904
4905sigsegv:
4906 unlock_user_struct(sr, sr_addr, 1)unlock_user(sr, sr_addr, (1) ? sizeof(*sr) : 0);
4907 unlock_user_struct(sc, sc_addr, 1)unlock_user(sc, sc_addr, (1) ? sizeof(*sc) : 0);
4908 qemu_log("segfaulting from do_sigreturn\n");
4909 force_sig(TARGET_SIGSEGV11);
4910 return 0;
4911}
4912
4913/* See arch/powerpc/kernel/signal_32.c. */
4914static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4915{
4916 struct target_mcontext *mcp;
4917 target_ulong mcp_addr;
4918 sigset_t blocked;
4919 target_sigset_t set;
4920
4921 if (copy_from_user(&set, h2g(ucp)({ ((({ unsigned long __guest = (unsigned long)(ucp) - guest_base
; (__guest < (1ul << 44)) && (!reserved_va ||
(__guest < reserved_va)); })) ? (void) (0) : __assert_fail
("({ unsigned long __guest = (unsigned long)(ucp) - guest_base; (__guest < (1ul << 44)) && (!reserved_va || (__guest < reserved_va)); })"
, "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c", 4921
, __PRETTY_FUNCTION__)); ({ unsigned long __ret = (unsigned long
)(ucp) - guest_base; (abi_ulong)__ret; }); })
+ offsetof(struct target_ucontext, tuc_sigmask)__builtin_offsetof(struct target_ucontext, tuc_sigmask),
4922 sizeof (set)))
4923 return 1;
4924
4925#if defined(TARGET_PPC64)
4926 fprintf (stderrstderr, "do_setcontext: not implemented\n");
4927 return 0;
4928#else
4929 if (__get_user(mcp_addr, &ucp->tuc_regs)((mcp_addr) = (typeof(*&ucp->tuc_regs))( __builtin_choose_expr
(sizeof(*(&ucp->tuc_regs)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&ucp->tuc_regs)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&ucp->tuc_regs)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&ucp->tuc_regs)) == 8, ldq_be_p, abort)))) (
&ucp->tuc_regs)), 0)
)
4930 return 1;
4931
4932 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1)(mcp = lock_user(0, mcp_addr, sizeof(*mcp), 1)))
4933 return 1;
4934
4935 target_to_host_sigset_internal(&blocked, &set);
4936 sigprocmask(SIG_SETMASK2, &blocked, NULL((void*)0));
4937 if (restore_user_regs(env, mcp, sig))
4938 goto sigsegv;
4939
4940 unlock_user_struct(mcp, mcp_addr, 1)unlock_user(mcp, mcp_addr, (1) ? sizeof(*mcp) : 0);
4941 return 0;
4942
4943sigsegv:
4944 unlock_user_struct(mcp, mcp_addr, 1)unlock_user(mcp, mcp_addr, (1) ? sizeof(*mcp) : 0);
4945 return 1;
4946#endif
4947}
4948
4949long do_rt_sigreturn(CPUPPCState *env)
4950{
4951 struct target_rt_sigframe *rt_sf = NULL((void*)0);
4952 target_ulong rt_sf_addr;
4953
4954 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4955 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1)(rt_sf = lock_user(0, rt_sf_addr, sizeof(*rt_sf), 1)))
4956 goto sigsegv;
4957
4958 if (do_setcontext(&rt_sf->uc, env, 1))
4959 goto sigsegv;
4960
4961 do_sigaltstack(rt_sf_addr
4962 + offsetof(struct target_rt_sigframe, uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack),
4963 0, env->gpr[1]);
4964
4965 unlock_user_struct(rt_sf, rt_sf_addr, 1)unlock_user(rt_sf, rt_sf_addr, (1) ? sizeof(*rt_sf) : 0);
4966 return -TARGET_QEMU_ESIGRETURN;
4967
4968sigsegv:
4969 unlock_user_struct(rt_sf, rt_sf_addr, 1)unlock_user(rt_sf, rt_sf_addr, (1) ? sizeof(*rt_sf) : 0);
4970 qemu_log("segfaulting from do_rt_sigreturn\n");
4971 force_sig(TARGET_SIGSEGV11);
4972 return 0;
4973}
4974
4975#elif defined(TARGET_M68K)
4976
4977struct target_sigcontext {
4978 abi_ulong sc_mask;
4979 abi_ulong sc_usp;
4980 abi_ulong sc_d0;
4981 abi_ulong sc_d1;
4982 abi_ulong sc_a0;
4983 abi_ulong sc_a1;
4984 unsigned short sc_sr;
4985 abi_ulong sc_pc;
4986};
4987
4988struct target_sigframe
4989{
4990 abi_ulong pretcode;
4991 int sig;
4992 int code;
4993 abi_ulong psc;
4994 char retcode[8];
4995 abi_ulong extramask[TARGET_NSIG_WORDS(64 / 64)-1];
4996 struct target_sigcontext sc;
4997};
4998
4999typedef int target_greg_t;
5000#define TARGET_NGREG 18
5001typedef target_greg_t target_gregset_t[TARGET_NGREG];
5002
5003typedef struct target_fpregset {
5004 int f_fpcntl[3];
5005 int f_fpregs[8*3];
5006} target_fpregset_t;
5007
5008struct target_mcontext {
5009 int version;
5010 target_gregset_t gregs;
5011 target_fpregset_t fpregs;
5012};
5013
5014#define TARGET_MCONTEXT_VERSION 2
5015
5016struct target_ucontext {
5017 abi_ulong tuc_flags;
5018 abi_ulong tuc_link;
5019 target_stack_t tuc_stack;
5020 struct target_mcontext tuc_mcontext;
5021 abi_long tuc_filler[80];
5022 target_sigset_t tuc_sigmask;
5023};
5024
5025struct target_rt_sigframe
5026{
5027 abi_ulong pretcode;
5028 int sig;
5029 abi_ulong pinfo;
5030 abi_ulong puc;
5031 char retcode[8];
5032 struct target_siginfo info;
5033 struct target_ucontext uc;
5034};
5035
5036static int
5037setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
5038 abi_ulong mask)
5039{
5040 int err = 0;
5041
5042 err |= __put_user(mask, &sc->sc_mask)(__builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 8, stq_be_p
, abort)))) ((&sc->sc_mask), (mask)), 0)
;
5043 err |= __put_user(env->aregs[7], &sc->sc_usp)(__builtin_choose_expr(sizeof(*(&sc->sc_usp)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_usp)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_usp)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_usp)) == 8, stq_be_p
, abort)))) ((&sc->sc_usp), (env->aregs[7])), 0)
;
5044 err |= __put_user(env->dregs[0], &sc->sc_d0)(__builtin_choose_expr(sizeof(*(&sc->sc_d0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d0)) == 8, stq_be_p
, abort)))) ((&sc->sc_d0), (env->dregs[0])), 0)
;
5045 err |= __put_user(env->dregs[1], &sc->sc_d1)(__builtin_choose_expr(sizeof(*(&sc->sc_d1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_d1)) == 8, stq_be_p
, abort)))) ((&sc->sc_d1), (env->dregs[1])), 0)
;
5046 err |= __put_user(env->aregs[0], &sc->sc_a0)(__builtin_choose_expr(sizeof(*(&sc->sc_a0)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a0)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a0)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a0)) == 8, stq_be_p
, abort)))) ((&sc->sc_a0), (env->aregs[0])), 0)
;
5047 err |= __put_user(env->aregs[1], &sc->sc_a1)(__builtin_choose_expr(sizeof(*(&sc->sc_a1)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a1)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a1)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_a1)) == 8, stq_be_p
, abort)))) ((&sc->sc_a1), (env->aregs[1])), 0)
;
5048 err |= __put_user(env->sr, &sc->sc_sr)(__builtin_choose_expr(sizeof(*(&sc->sc_sr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_sr)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_sr)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_sr)) == 8, stq_be_p
, abort)))) ((&sc->sc_sr), (env->sr)), 0)
;
5049 err |= __put_user(env->pc, &sc->sc_pc)(__builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 8, stq_be_p
, abort)))) ((&sc->sc_pc), (env->pc)), 0)
;
5050
5051 return err;
5052}
5053
5054static int
5055restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5056{
5057 int err = 0;
5058 int temp;
5059
5060 err |= __get_user(env->aregs[7], &sc->sc_usp)((env->aregs[7]) = (typeof(*&sc->sc_usp))( __builtin_choose_expr
(sizeof(*(&sc->sc_usp)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_usp)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_usp)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_usp)) == 8, ldq_be_p, abort)))) (&
sc->sc_usp)), 0)
;
5061 err |= __get_user(env->dregs[1], &sc->sc_d1)((env->dregs[1]) = (typeof(*&sc->sc_d1))( __builtin_choose_expr
(sizeof(*(&sc->sc_d1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_d1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_d1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_d1)) == 8, ldq_be_p, abort)))) (&
sc->sc_d1)), 0)
;
5062 err |= __get_user(env->aregs[0], &sc->sc_a0)((env->aregs[0]) = (typeof(*&sc->sc_a0))( __builtin_choose_expr
(sizeof(*(&sc->sc_a0)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a0)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a0)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a0)) == 8, ldq_be_p, abort)))) (&
sc->sc_a0)), 0)
;
5063 err |= __get_user(env->aregs[1], &sc->sc_a1)((env->aregs[1]) = (typeof(*&sc->sc_a1))( __builtin_choose_expr
(sizeof(*(&sc->sc_a1)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a1)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a1)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_a1)) == 8, ldq_be_p, abort)))) (&
sc->sc_a1)), 0)
;
5064 err |= __get_user(env->pc, &sc->sc_pc)((env->pc) = (typeof(*&sc->sc_pc))( __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 8, ldq_be_p, abort)))) (&
sc->sc_pc)), 0)
;
5065 err |= __get_user(temp, &sc->sc_sr)((temp) = (typeof(*&sc->sc_sr))( __builtin_choose_expr
(sizeof(*(&sc->sc_sr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_sr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_sr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_sr)) == 8, ldq_be_p, abort)))) (&
sc->sc_sr)), 0)
;
5066 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5067
5068 *pd0 = tswapl(sc->sc_d0)tswap64(sc->sc_d0);
5069
5070 return err;
5071}
5072
5073/*
5074 * Determine which stack to use..
5075 */
5076static inline abi_ulong
5077get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5078 size_t frame_size)
5079{
5080 unsigned long sp;
5081
5082 sp = regs->aregs[7];
5083
5084 /* This is the X/Open sanctioned signal stack switching. */
5085 if ((ka->sa_flags & TARGET_SA_ONSTACK1u) && (sas_ss_flags (sp) == 0)) {
5086 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5087 }
5088
5089 return ((sp - frame_size) & -8UL);
5090}
5091
5092static void setup_frame(int sig, struct target_sigaction *ka,
5093 target_sigset_t *set, CPUM68KState *env)
5094{
5095 struct target_sigframe *frame;
5096 abi_ulong frame_addr;
5097 abi_ulong retcode_addr;
5098 abi_ulong sc_addr;
5099 int err = 0;
5100 int i;
5101
5102 frame_addr = get_sigframe(ka, env, sizeof *frame);
5103 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
5104 goto give_sigsegv;
5105
5106 err |= __put_user(sig, &frame->sig)(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (sig)), 0)
;
5107
5108 sc_addr = frame_addr + offsetof(struct target_sigframe, sc)__builtin_offsetof(struct target_sigframe, sc);
5109 err |= __put_user(sc_addr, &frame->psc)(__builtin_choose_expr(sizeof(*(&frame->psc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->psc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->psc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->psc)) == 8, stq_be_p
, abort)))) ((&frame->psc), (sc_addr)), 0)
;
5110
5111 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5112 if (err)
5113 goto give_sigsegv;
5114
5115 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
5116 if (__put_user(set->sig[i], &frame->extramask[i - 1])(__builtin_choose_expr(sizeof(*(&frame->extramask[i - 1
])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
extramask[i - 1])) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->extramask[i - 1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, stq_be_p, abort
)))) ((&frame->extramask[i - 1]), (set->sig[i])), 0
)
)
5117 goto give_sigsegv;
5118 }
5119
5120 /* Set up to return from userspace. */
5121
5122 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode)__builtin_offsetof(struct target_sigframe, retcode);
5123 err |= __put_user(retcode_addr, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (retcode_addr)), 0)
;
5124
5125 /* moveq #,d0; trap #0 */
5126
5127 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),(__builtin_choose_expr(sizeof(*((long *)(frame->retcode)))
== 1, stb_p, __builtin_choose_expr(sizeof(*((long *)(frame->
retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof(*((long
*)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((long *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((long *)(frame->retcode)), (0x70004e40 + (216 <<
16))), 0)
5128 (long *)(frame->retcode))(__builtin_choose_expr(sizeof(*((long *)(frame->retcode)))
== 1, stb_p, __builtin_choose_expr(sizeof(*((long *)(frame->
retcode))) == 2, stw_be_p, __builtin_choose_expr(sizeof(*((long
*)(frame->retcode))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((long *)(frame->retcode))) == 8, stq_be_p, abort
)))) (((long *)(frame->retcode)), (0x70004e40 + (216 <<
16))), 0)
;
5129
5130 if (err)
5131 goto give_sigsegv;
5132
5133 /* Set up to return from userspace */
5134
5135 env->aregs[7] = frame_addr;
5136 env->pc = ka->_sa_handler;
5137
5138 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
5139 return;
5140
5141give_sigsegv:
5142 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
5143 force_sig(TARGET_SIGSEGV11);
5144}
5145
5146static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5147 CPUM68KState *env)
5148{
5149 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5150 int err;
5151
5152 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version)(__builtin_choose_expr(sizeof(*(&uc->tuc_mcontext.version
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&uc->tuc_mcontext
.version)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
uc->tuc_mcontext.version)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&uc->tuc_mcontext.version)) == 8, stq_be_p, abort
)))) ((&uc->tuc_mcontext.version), (TARGET_MCONTEXT_VERSION
)), 0)
;
5153 err |= __put_user(env->dregs[0], &gregs[0])(__builtin_choose_expr(sizeof(*(&gregs[0])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 8, stq_be_p, abort)))) ((&gregs
[0]), (env->dregs[0])), 0)
;
5154 err |= __put_user(env->dregs[1], &gregs[1])(__builtin_choose_expr(sizeof(*(&gregs[1])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 8, stq_be_p, abort)))) ((&gregs
[1]), (env->dregs[1])), 0)
;
5155 err |= __put_user(env->dregs[2], &gregs[2])(__builtin_choose_expr(sizeof(*(&gregs[2])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 8, stq_be_p, abort)))) ((&gregs
[2]), (env->dregs[2])), 0)
;
5156 err |= __put_user(env->dregs[3], &gregs[3])(__builtin_choose_expr(sizeof(*(&gregs[3])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 8, stq_be_p, abort)))) ((&gregs
[3]), (env->dregs[3])), 0)
;
5157 err |= __put_user(env->dregs[4], &gregs[4])(__builtin_choose_expr(sizeof(*(&gregs[4])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 8, stq_be_p, abort)))) ((&gregs
[4]), (env->dregs[4])), 0)
;
5158 err |= __put_user(env->dregs[5], &gregs[5])(__builtin_choose_expr(sizeof(*(&gregs[5])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 8, stq_be_p, abort)))) ((&gregs
[5]), (env->dregs[5])), 0)
;
5159 err |= __put_user(env->dregs[6], &gregs[6])(__builtin_choose_expr(sizeof(*(&gregs[6])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 8, stq_be_p, abort)))) ((&gregs
[6]), (env->dregs[6])), 0)
;
5160 err |= __put_user(env->dregs[7], &gregs[7])(__builtin_choose_expr(sizeof(*(&gregs[7])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 8, stq_be_p, abort)))) ((&gregs
[7]), (env->dregs[7])), 0)
;
5161 err |= __put_user(env->aregs[0], &gregs[8])(__builtin_choose_expr(sizeof(*(&gregs[8])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 8, stq_be_p, abort)))) ((&gregs
[8]), (env->aregs[0])), 0)
;
5162 err |= __put_user(env->aregs[1], &gregs[9])(__builtin_choose_expr(sizeof(*(&gregs[9])) == 1, stb_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 8, stq_be_p, abort)))) ((&gregs
[9]), (env->aregs[1])), 0)
;
5163 err |= __put_user(env->aregs[2], &gregs[10])(__builtin_choose_expr(sizeof(*(&gregs[10])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[10])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[10])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[10])) == 8, stq_be_p
, abort)))) ((&gregs[10]), (env->aregs[2])), 0)
;
5164 err |= __put_user(env->aregs[3], &gregs[11])(__builtin_choose_expr(sizeof(*(&gregs[11])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[11])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[11])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[11])) == 8, stq_be_p
, abort)))) ((&gregs[11]), (env->aregs[3])), 0)
;
5165 err |= __put_user(env->aregs[4], &gregs[12])(__builtin_choose_expr(sizeof(*(&gregs[12])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[12])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[12])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[12])) == 8, stq_be_p
, abort)))) ((&gregs[12]), (env->aregs[4])), 0)
;
5166 err |= __put_user(env->aregs[5], &gregs[13])(__builtin_choose_expr(sizeof(*(&gregs[13])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[13])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[13])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[13])) == 8, stq_be_p
, abort)))) ((&gregs[13]), (env->aregs[5])), 0)
;
5167 err |= __put_user(env->aregs[6], &gregs[14])(__builtin_choose_expr(sizeof(*(&gregs[14])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[14])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[14])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[14])) == 8, stq_be_p
, abort)))) ((&gregs[14]), (env->aregs[6])), 0)
;
5168 err |= __put_user(env->aregs[7], &gregs[15])(__builtin_choose_expr(sizeof(*(&gregs[15])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[15])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[15])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[15])) == 8, stq_be_p
, abort)))) ((&gregs[15]), (env->aregs[7])), 0)
;
5169 err |= __put_user(env->pc, &gregs[16])(__builtin_choose_expr(sizeof(*(&gregs[16])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[16])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[16])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[16])) == 8, stq_be_p
, abort)))) ((&gregs[16]), (env->pc)), 0)
;
5170 err |= __put_user(env->sr, &gregs[17])(__builtin_choose_expr(sizeof(*(&gregs[17])) == 1, stb_p,
__builtin_choose_expr(sizeof(*(&gregs[17])) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&gregs[17])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&gregs[17])) == 8, stq_be_p
, abort)))) ((&gregs[17]), (env->sr)), 0)
;
5171
5172 return err;
5173}
5174
5175static inline int target_rt_restore_ucontext(CPUM68KState *env,
5176 struct target_ucontext *uc,
5177 int *pd0)
5178{
5179 int temp;
5180 int err;
5181 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5182
5183 err = __get_user(temp, &uc->tuc_mcontext.version)((temp) = (typeof(*&uc->tuc_mcontext.version))( __builtin_choose_expr
(sizeof(*(&uc->tuc_mcontext.version)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&uc->tuc_mcontext.version)) == 2, lduw_be_p,
__builtin_choose_expr(sizeof(*(&uc->tuc_mcontext.version
)) == 4, ldl_be_p, __builtin_choose_expr(sizeof(*(&uc->
tuc_mcontext.version)) == 8, ldq_be_p, abort)))) (&uc->
tuc_mcontext.version)), 0)
;
5184 if (temp != TARGET_MCONTEXT_VERSION)
5185 goto badframe;
5186
5187 /* restore passed registers */
5188 err |= __get_user(env->dregs[0], &gregs[0])((env->dregs[0]) = (typeof(*&gregs[0]))( __builtin_choose_expr
(sizeof(*(&gregs[0])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[0])) == 8, ldq_be_p, abort)))) (&gregs
[0])), 0)
;
5189 err |= __get_user(env->dregs[1], &gregs[1])((env->dregs[1]) = (typeof(*&gregs[1]))( __builtin_choose_expr
(sizeof(*(&gregs[1])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[1])) == 8, ldq_be_p, abort)))) (&gregs
[1])), 0)
;
5190 err |= __get_user(env->dregs[2], &gregs[2])((env->dregs[2]) = (typeof(*&gregs[2]))( __builtin_choose_expr
(sizeof(*(&gregs[2])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[2])) == 8, ldq_be_p, abort)))) (&gregs
[2])), 0)
;
5191 err |= __get_user(env->dregs[3], &gregs[3])((env->dregs[3]) = (typeof(*&gregs[3]))( __builtin_choose_expr
(sizeof(*(&gregs[3])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[3])) == 8, ldq_be_p, abort)))) (&gregs
[3])), 0)
;
5192 err |= __get_user(env->dregs[4], &gregs[4])((env->dregs[4]) = (typeof(*&gregs[4]))( __builtin_choose_expr
(sizeof(*(&gregs[4])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[4])) == 8, ldq_be_p, abort)))) (&gregs
[4])), 0)
;
5193 err |= __get_user(env->dregs[5], &gregs[5])((env->dregs[5]) = (typeof(*&gregs[5]))( __builtin_choose_expr
(sizeof(*(&gregs[5])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[5])) == 8, ldq_be_p, abort)))) (&gregs
[5])), 0)
;
5194 err |= __get_user(env->dregs[6], &gregs[6])((env->dregs[6]) = (typeof(*&gregs[6]))( __builtin_choose_expr
(sizeof(*(&gregs[6])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[6])) == 8, ldq_be_p, abort)))) (&gregs
[6])), 0)
;
5195 err |= __get_user(env->dregs[7], &gregs[7])((env->dregs[7]) = (typeof(*&gregs[7]))( __builtin_choose_expr
(sizeof(*(&gregs[7])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[7])) == 8, ldq_be_p, abort)))) (&gregs
[7])), 0)
;
5196 err |= __get_user(env->aregs[0], &gregs[8])((env->aregs[0]) = (typeof(*&gregs[8]))( __builtin_choose_expr
(sizeof(*(&gregs[8])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[8])) == 8, ldq_be_p, abort)))) (&gregs
[8])), 0)
;
5197 err |= __get_user(env->aregs[1], &gregs[9])((env->aregs[1]) = (typeof(*&gregs[9]))( __builtin_choose_expr
(sizeof(*(&gregs[9])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[9])) == 8, ldq_be_p, abort)))) (&gregs
[9])), 0)
;
5198 err |= __get_user(env->aregs[2], &gregs[10])((env->aregs[2]) = (typeof(*&gregs[10]))( __builtin_choose_expr
(sizeof(*(&gregs[10])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[10])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[10])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[10])) == 8, ldq_be_p, abort)))) (&gregs
[10])), 0)
;
5199 err |= __get_user(env->aregs[3], &gregs[11])((env->aregs[3]) = (typeof(*&gregs[11]))( __builtin_choose_expr
(sizeof(*(&gregs[11])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[11])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[11])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[11])) == 8, ldq_be_p, abort)))) (&gregs
[11])), 0)
;
5200 err |= __get_user(env->aregs[4], &gregs[12])((env->aregs[4]) = (typeof(*&gregs[12]))( __builtin_choose_expr
(sizeof(*(&gregs[12])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[12])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[12])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[12])) == 8, ldq_be_p, abort)))) (&gregs
[12])), 0)
;
5201 err |= __get_user(env->aregs[5], &gregs[13])((env->aregs[5]) = (typeof(*&gregs[13]))( __builtin_choose_expr
(sizeof(*(&gregs[13])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[13])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[13])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[13])) == 8, ldq_be_p, abort)))) (&gregs
[13])), 0)
;
5202 err |= __get_user(env->aregs[6], &gregs[14])((env->aregs[6]) = (typeof(*&gregs[14]))( __builtin_choose_expr
(sizeof(*(&gregs[14])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[14])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[14])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[14])) == 8, ldq_be_p, abort)))) (&gregs
[14])), 0)
;
5203 err |= __get_user(env->aregs[7], &gregs[15])((env->aregs[7]) = (typeof(*&gregs[15]))( __builtin_choose_expr
(sizeof(*(&gregs[15])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[15])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[15])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[15])) == 8, ldq_be_p, abort)))) (&gregs
[15])), 0)
;
5204 err |= __get_user(env->pc, &gregs[16])((env->pc) = (typeof(*&gregs[16]))( __builtin_choose_expr
(sizeof(*(&gregs[16])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&gregs[16])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&gregs[16])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&gregs[16])) == 8, ldq_be_p, abort)))) (&gregs
[16])), 0)
;
5205 err |= __get_user(temp, &gregs[17])((temp) = (typeof(*&gregs[17]))( __builtin_choose_expr(sizeof
(*(&gregs[17])) == 1, ldub_p, __builtin_choose_expr(sizeof
(*(&gregs[17])) == 2, lduw_be_p, __builtin_choose_expr(sizeof
(*(&gregs[17])) == 4, ldl_be_p, __builtin_choose_expr(sizeof
(*(&gregs[17])) == 8, ldq_be_p, abort)))) (&gregs[17]
)), 0)
;
5206 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5207
5208 *pd0 = env->dregs[0];
5209 return err;
5210
5211badframe:
5212 return 1;
5213}
5214
5215static void setup_rt_frame(int sig, struct target_sigaction *ka,
5216 target_siginfo_t *info,
5217 target_sigset_t *set, CPUM68KState *env)
5218{
5219 struct target_rt_sigframe *frame;
5220 abi_ulong frame_addr;
5221 abi_ulong retcode_addr;
5222 abi_ulong info_addr;
5223 abi_ulong uc_addr;
5224 int err = 0;
5225 int i;
5226
5227 frame_addr = get_sigframe(ka, env, sizeof *frame);
5228 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0)))
5229 goto give_sigsegv;
5230
5231 err |= __put_user(sig, &frame->sig)(__builtin_choose_expr(sizeof(*(&frame->sig)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->sig)) == 8, stq_be_p
, abort)))) ((&frame->sig), (sig)), 0)
;
5232
5233 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info)__builtin_offsetof(struct target_rt_sigframe, info);
5234 err |= __put_user(info_addr, &frame->pinfo)(__builtin_choose_expr(sizeof(*(&frame->pinfo)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->pinfo)) == 2,
stw_be_p, __builtin_choose_expr(sizeof(*(&frame->pinfo
)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&frame->
pinfo)) == 8, stq_be_p, abort)))) ((&frame->pinfo), (info_addr
)), 0)
;
5235
5236 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc)__builtin_offsetof(struct target_rt_sigframe, uc);
5237 err |= __put_user(uc_addr, &frame->puc)(__builtin_choose_expr(sizeof(*(&frame->puc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->puc)) == 8, stq_be_p
, abort)))) ((&frame->puc), (uc_addr)), 0)
;
5238
5239 err |= copy_siginfo_to_user(&frame->info, info);
5240
5241 /* Create the ucontext */
5242
5243 err |= __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
5244 err |= __put_user(0, &frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&frame->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
frame->uc.tuc_link), (0)), 0)
;
5245 err |= __put_user(target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
5246 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
5247 err |= __put_user(sas_ss_flags(env->aregs[7]),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->aregs[7]))), 0)
5248 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->aregs[7]))), 0)
;
5249 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
5250 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
5251 err |= target_rt_setup_ucontext(&frame->uc, env);
5252
5253 if (err)
5254 goto give_sigsegv;
5255
5256 for(i = 0; i < TARGET_NSIG_WORDS(64 / 64); i++) {
5257 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
)
5258 goto give_sigsegv;
5259 }
5260
5261 /* Set up to return from userspace. */
5262
5263 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode)__builtin_offsetof(struct target_sigframe, retcode);
5264 err |= __put_user(retcode_addr, &frame->pretcode)(__builtin_choose_expr(sizeof(*(&frame->pretcode)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&frame->pretcode
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
pretcode)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
frame->pretcode)) == 8, stq_be_p, abort)))) ((&frame->
pretcode), (retcode_addr)), 0)
;
5265
5266 /* moveq #,d0; notb d0; trap #0 */
5267
5268 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),(__builtin_choose_expr(sizeof(*((long *)(frame->retcode + 0
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((long *)(frame
->retcode + 0))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((long *)(frame->retcode + 0))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((long *)(frame->retcode + 0))) == 8, stq_be_p, abort
)))) (((long *)(frame->retcode + 0)), (0x70004600 + ((101 ^
0xff) << 16))), 0)
5269 (long *)(frame->retcode + 0))(__builtin_choose_expr(sizeof(*((long *)(frame->retcode + 0
))) == 1, stb_p, __builtin_choose_expr(sizeof(*((long *)(frame
->retcode + 0))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((long *)(frame->retcode + 0))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((long *)(frame->retcode + 0))) == 8, stq_be_p, abort
)))) (((long *)(frame->retcode + 0)), (0x70004600 + ((101 ^
0xff) << 16))), 0)
;
5270 err |= __put_user(0x4e40, (short *)(frame->retcode + 4))(__builtin_choose_expr(sizeof(*((short *)(frame->retcode +
4))) == 1, stb_p, __builtin_choose_expr(sizeof(*((short *)(frame
->retcode + 4))) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*((short *)(frame->retcode + 4))) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*((short *)(frame->retcode + 4))) == 8, stq_be_p, abort
)))) (((short *)(frame->retcode + 4)), (0x4e40)), 0)
;
5271
5272 if (err)
5273 goto give_sigsegv;
5274
5275 /* Set up to return from userspace */
5276
5277 env->aregs[7] = frame_addr;
5278 env->pc = ka->_sa_handler;
5279
5280 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
5281 return;
5282
5283give_sigsegv:
5284 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
5285 force_sig(TARGET_SIGSEGV11);
5286}
5287
5288long do_sigreturn(CPUM68KState *env)
5289{
5290 struct target_sigframe *frame;
5291 abi_ulong frame_addr = env->aregs[7] - 4;
5292 target_sigset_t target_set;
5293 sigset_t set;
5294 int d0, i;
5295
5296 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
5297 goto badframe;
5298
5299 /* set blocked signals */
5300
5301 if (__get_user(target_set.sig[0], &frame->sc.sc_mask)((target_set.sig[0]) = (typeof(*&frame->sc.sc_mask))( __builtin_choose_expr
(sizeof(*(&frame->sc.sc_mask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&frame->sc.sc_mask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.sc_mask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->sc.sc_mask)) == 8, ldq_be_p, abort))
)) (&frame->sc.sc_mask)), 0)
)
5302 goto badframe;
5303
5304 for(i = 1; i < TARGET_NSIG_WORDS(64 / 64); i++) {
5305 if (__get_user(target_set.sig[i], &frame->extramask[i - 1])((target_set.sig[i]) = (typeof(*&frame->extramask[i - 1
]))( __builtin_choose_expr(sizeof(*(&frame->extramask[
i - 1])) == 1, ldub_p, __builtin_choose_expr(sizeof(*(&frame
->extramask[i - 1])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&frame->extramask[i - 1])) == 8, ldq_be_p, abort
)))) (&frame->extramask[i - 1])), 0)
)
5306 goto badframe;
5307 }
5308
5309 target_to_host_sigset_internal(&set, &target_set);
5310 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
5311
5312 /* restore registers */
5313
5314 if (restore_sigcontext(env, &frame->sc, &d0))
5315 goto badframe;
5316
5317 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5318 return d0;
5319
5320badframe:
5321 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5322 force_sig(TARGET_SIGSEGV11);
5323 return 0;
5324}
5325
5326long do_rt_sigreturn(CPUM68KState *env)
5327{
5328 struct target_rt_sigframe *frame;
5329 abi_ulong frame_addr = env->aregs[7] - 4;
5330 target_sigset_t target_set;
5331 sigset_t set;
5332 int d0;
5333
5334 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1)))
5335 goto badframe;
5336
5337 target_to_host_sigset_internal(&set, &target_set);
5338 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
5339
5340 /* restore registers */
5341
5342 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5343 goto badframe;
5344
5345 if (do_sigaltstack(frame_addr +
5346 offsetof(struct target_rt_sigframe, uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack),
5347 0, get_sp_from_cpustate(env)) == -EFAULT14)
5348 goto badframe;
5349
5350 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5351 return d0;
5352
5353badframe:
5354 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5355 force_sig(TARGET_SIGSEGV11);
5356 return 0;
5357}
5358
5359#elif defined(TARGET_ALPHA)
5360
5361struct target_sigcontext {
5362 abi_long sc_onstack;
5363 abi_long sc_mask;
5364 abi_long sc_pc;
5365 abi_long sc_ps;
5366 abi_long sc_regs[32];
5367 abi_long sc_ownedfp;
5368 abi_long sc_fpregs[32];
5369 abi_ulong sc_fpcr;
5370 abi_ulong sc_fp_control;
5371 abi_ulong sc_reserved1;
5372 abi_ulong sc_reserved2;
5373 abi_ulong sc_ssize;
5374 abi_ulong sc_sbase;
5375 abi_ulong sc_traparg_a0;
5376 abi_ulong sc_traparg_a1;
5377 abi_ulong sc_traparg_a2;
5378 abi_ulong sc_fp_trap_pc;
5379 abi_ulong sc_fp_trigger_sum;
5380 abi_ulong sc_fp_trigger_inst;
5381};
5382
5383struct target_ucontext {
5384 abi_ulong tuc_flags;
5385 abi_ulong tuc_link;
5386 abi_ulong tuc_osf_sigmask;
5387 target_stack_t tuc_stack;
5388 struct target_sigcontext tuc_mcontext;
5389 target_sigset_t tuc_sigmask;
5390};
5391
5392struct target_sigframe {
5393 struct target_sigcontext sc;
5394 unsigned int retcode[3];
5395};
5396
5397struct target_rt_sigframe {
5398 target_siginfo_t info;
5399 struct target_ucontext uc;
5400 unsigned int retcode[3];
5401};
5402
5403#define INSN_MOV_R30_R16 0x47fe0410
5404#define INSN_LDI_R0 0x201f0000
5405#define INSN_CALLSYS 0x00000083
5406
5407static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5408 abi_ulong frame_addr, target_sigset_t *set)
5409{
5410 int i, err = 0;
5411
5412 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack)(__builtin_choose_expr(sizeof(*(&sc->sc_onstack)) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_onstack
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_onstack)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->sc_onstack)) == 8, stq_be_p, abort)))) ((&sc->sc_onstack
), (on_sig_stack(frame_addr))), 0)
;
5413 err |= __put_user(set->sig[0], &sc->sc_mask)(__builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_mask)) == 8, stq_be_p
, abort)))) ((&sc->sc_mask), (set->sig[0])), 0)
;
5414 err |= __put_user(env->pc, &sc->sc_pc)(__builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_pc)) == 8, stq_be_p
, abort)))) ((&sc->sc_pc), (env->pc)), 0)
;
5415 err |= __put_user(8, &sc->sc_ps)(__builtin_choose_expr(sizeof(*(&sc->sc_ps)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_ps)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_ps)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_ps)) == 8, stq_be_p
, abort)))) ((&sc->sc_ps), (8)), 0)
;
5416
5417 for (i = 0; i < 31; ++i) {
5418 err |= __put_user(env->ir[i], &sc->sc_regs[i])(__builtin_choose_expr(sizeof(*(&sc->sc_regs[i])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_regs[i
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_regs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(&
sc->sc_regs[i])) == 8, stq_be_p, abort)))) ((&sc->sc_regs
[i]), (env->ir[i])), 0)
;
5419 }
5420 err |= __put_user(0, &sc->sc_regs[31])(__builtin_choose_expr(sizeof(*(&sc->sc_regs[31])) == 1
, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_regs[31
])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_regs[31])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&sc->sc_regs[31])) == 8, stq_be_p, abort)))) ((&sc
->sc_regs[31]), (0)), 0)
;
5421
5422 for (i = 0; i < 31; ++i) {
5423 err |= __put_user(env->fir[i], &sc->sc_fpregs[i])(__builtin_choose_expr(sizeof(*(&sc->sc_fpregs[i])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_fpregs
[i])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_fpregs[i])) == 4, stl_be_p, __builtin_choose_expr(sizeof(*
(&sc->sc_fpregs[i])) == 8, stq_be_p, abort)))) ((&
sc->sc_fpregs[i]), (env->fir[i])), 0)
;
5424 }
5425 err |= __put_user(0, &sc->sc_fpregs[31])(__builtin_choose_expr(sizeof(*(&sc->sc_fpregs[31])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_fpregs
[31])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc
->sc_fpregs[31])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&sc->sc_fpregs[31])) == 8, stq_be_p, abort)))) ((&
sc->sc_fpregs[31]), (0)), 0)
;
5426 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr)(__builtin_choose_expr(sizeof(*(&sc->sc_fpcr)) == 1, stb_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpcr)) == 2, stw_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpcr)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&sc->sc_fpcr)) == 8, stq_be_p
, abort)))) ((&sc->sc_fpcr), (cpu_alpha_load_fpcr(env)
)), 0)
;
5427
5428 err |= __put_user(0, &sc->sc_traparg_a0)(__builtin_choose_expr(sizeof(*(&sc->sc_traparg_a0)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_traparg_a0
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_traparg_a0)) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&sc->sc_traparg_a0)) == 8, stq_be_p, abort)))) ((&
sc->sc_traparg_a0), (0)), 0)
; /* FIXME */
5429 err |= __put_user(0, &sc->sc_traparg_a1)(__builtin_choose_expr(sizeof(*(&sc->sc_traparg_a1)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_traparg_a1
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_traparg_a1)) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&sc->sc_traparg_a1)) == 8, stq_be_p, abort)))) ((&
sc->sc_traparg_a1), (0)), 0)
; /* FIXME */
5430 err |= __put_user(0, &sc->sc_traparg_a2)(__builtin_choose_expr(sizeof(*(&sc->sc_traparg_a2)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&sc->sc_traparg_a2
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&sc->
sc_traparg_a2)) == 4, stl_be_p, __builtin_choose_expr(sizeof(
*(&sc->sc_traparg_a2)) == 8, stq_be_p, abort)))) ((&
sc->sc_traparg_a2), (0)), 0)
; /* FIXME */
5431
5432 return err;
5433}
5434
5435static int restore_sigcontext(CPUAlphaState *env,
5436 struct target_sigcontext *sc)
5437{
5438 uint64_t fpcr;
5439 int i, err = 0;
5440
5441 err |= __get_user(env->pc, &sc->sc_pc)((env->pc) = (typeof(*&sc->sc_pc))( __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_pc)) == 8, ldq_be_p, abort)))) (&
sc->sc_pc)), 0)
;
5442
5443 for (i = 0; i < 31; ++i) {
5444 err |= __get_user(env->ir[i], &sc->sc_regs[i])((env->ir[i]) = (typeof(*&sc->sc_regs[i]))( __builtin_choose_expr
(sizeof(*(&sc->sc_regs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_regs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_regs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_regs[i])) == 8, ldq_be_p, abort)))) (
&sc->sc_regs[i])), 0)
;
5445 }
5446 for (i = 0; i < 31; ++i) {
5447 err |= __get_user(env->fir[i], &sc->sc_fpregs[i])((env->fir[i]) = (typeof(*&sc->sc_fpregs[i]))( __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpregs[i])) == 8, ldq_be_p, abort)))
) (&sc->sc_fpregs[i])), 0)
;
5448 }
5449
5450 err |= __get_user(fpcr, &sc->sc_fpcr)((fpcr) = (typeof(*&sc->sc_fpcr))( __builtin_choose_expr
(sizeof(*(&sc->sc_fpcr)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpcr)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpcr)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_fpcr)) == 8, ldq_be_p, abort)))) (&
sc->sc_fpcr)), 0)
;
5451 cpu_alpha_store_fpcr(env, fpcr);
5452
5453 return err;
5454}
5455
5456static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5457 CPUAlphaState *env,
5458 unsigned long framesize)
5459{
5460 abi_ulong sp = env->ir[IR_SP];
5461
5462 /* This is the X/Open sanctioned signal stack switching. */
5463 if ((sa->sa_flags & TARGET_SA_ONSTACK1u) != 0 && !sas_ss_flags(sp)) {
5464 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5465 }
5466 return (sp - framesize) & -32;
5467}
5468
5469static void setup_frame(int sig, struct target_sigaction *ka,
5470 target_sigset_t *set, CPUAlphaState *env)
5471{
5472 abi_ulong frame_addr, r26;
5473 struct target_sigframe *frame;
5474 int err = 0;
5475
5476 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5477 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
5478 goto give_sigsegv;
5479 }
5480
5481 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5482
5483 if (ka->sa_restorer) {
5484 r26 = ka->sa_restorer;
5485 } else {
5486 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0])(__builtin_choose_expr(sizeof(*(&frame->retcode[0])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[0])) == 8, stq_be_p, abort)))) ((&
frame->retcode[0]), (INSN_MOV_R30_R16)), 0)
;
5487 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (INSN_LDI_R0 + 216)), 0)
5488 &frame->retcode[1])(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (INSN_LDI_R0 + 216)), 0)
;
5489 err |= __put_user(INSN_CALLSYS, &frame->retcode[2])(__builtin_choose_expr(sizeof(*(&frame->retcode[2])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[2])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[2])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[2])) == 8, stq_be_p, abort)))) ((&
frame->retcode[2]), (INSN_CALLSYS)), 0)
;
5490 /* imb() */
5491 r26 = frame_addr;
5492 }
5493
5494 unlock_user_struct(frame, frame_addr, 1)unlock_user(frame, frame_addr, (1) ? sizeof(*frame) : 0);
5495
5496 if (err) {
5497 give_sigsegv:
5498 if (sig == TARGET_SIGSEGV11) {
5499 ka->_sa_handler = TARGET_SIG_DFL((abi_long)0);
5500 }
5501 force_sig(TARGET_SIGSEGV11);
5502 }
5503
5504 env->ir[IR_RA] = r26;
5505 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5506 env->ir[IR_A0] = sig;
5507 env->ir[IR_A1] = 0;
5508 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc)__builtin_offsetof(struct target_sigframe, sc);
5509 env->ir[IR_SP] = frame_addr;
5510}
5511
5512static void setup_rt_frame(int sig, struct target_sigaction *ka,
5513 target_siginfo_t *info,
5514 target_sigset_t *set, CPUAlphaState *env)
5515{
5516 abi_ulong frame_addr, r26;
5517 struct target_rt_sigframe *frame;
5518 int i, err = 0;
5519
5520 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5521 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)(frame = lock_user(1, frame_addr, sizeof(*frame), 0))) {
5522 goto give_sigsegv;
5523 }
5524
5525 err |= copy_siginfo_to_user(&frame->info, info);
5526
5527 err |= __put_user(0, &frame->uc.tuc_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_flags))
== 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc
.tuc_flags)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&
frame->uc.tuc_flags)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_flags)) == 8, stq_be_p, abort
)))) ((&frame->uc.tuc_flags), (0)), 0)
;
5528 err |= __put_user(0, &frame->uc.tuc_link)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_link)) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_link
)) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_link)) == 4, stl_be_p, __builtin_choose_expr(sizeof(*(
&frame->uc.tuc_link)) == 8, stq_be_p, abort)))) ((&
frame->uc.tuc_link), (0)), 0)
;
5529 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_osf_sigmask
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_osf_sigmask)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_osf_sigmask)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_osf_sigmask)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_osf_sigmask), (set->sig
[0])), 0)
;
5530 err |= __put_user(target_sigaltstack_used.ss_sp,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
5531 &frame->uc.tuc_stack.ss_sp)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_sp
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_sp)) == 2, stw_be_p, __builtin_choose_expr(sizeof
(*(&frame->uc.tuc_stack.ss_sp)) == 4, stl_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_sp)) == 8, stq_be_p,
abort)))) ((&frame->uc.tuc_stack.ss_sp), (target_sigaltstack_used
.ss_sp)), 0)
;
5532 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->ir[IR_SP]))), 0)
5533 &frame->uc.tuc_stack.ss_flags)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_flags
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_flags)) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_stack.ss_flags)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_flags)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_flags), (sas_ss_flags(env->ir[IR_SP]))), 0)
;
5534 err |= __put_user(target_sigaltstack_used.ss_size,(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
5535 &frame->uc.tuc_stack.ss_size)(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.ss_size
)) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame->
uc.tuc_stack.ss_size)) == 2, stw_be_p, __builtin_choose_expr(
sizeof(*(&frame->uc.tuc_stack.ss_size)) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_stack.
ss_size)) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_stack
.ss_size), (target_sigaltstack_used.ss_size)), 0)
;
5536 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5537 for (i = 0; i < TARGET_NSIG_WORDS(64 / 64); ++i) {
5538 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])(__builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 1, stb_p, __builtin_choose_expr(sizeof(*(&frame
->uc.tuc_sigmask.sig[i])) == 2, stw_be_p, __builtin_choose_expr
(sizeof(*(&frame->uc.tuc_sigmask.sig[i])) == 4, stl_be_p
, __builtin_choose_expr(sizeof(*(&frame->uc.tuc_sigmask
.sig[i])) == 8, stq_be_p, abort)))) ((&frame->uc.tuc_sigmask
.sig[i]), (set->sig[i])), 0)
;
5539 }
5540
5541 if (ka->sa_restorer) {
5542 r26 = ka->sa_restorer;
5543 } else {
5544 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0])(__builtin_choose_expr(sizeof(*(&frame->retcode[0])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[0])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[0])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[0])) == 8, stq_be_p, abort)))) ((&
frame->retcode[0]), (INSN_MOV_R30_R16)), 0)
;
5545 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (INSN_LDI_R0 + 101)), 0)
5546 &frame->retcode[1])(__builtin_choose_expr(sizeof(*(&frame->retcode[1])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[1])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[1])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[1])) == 8, stq_be_p, abort)))) ((&
frame->retcode[1]), (INSN_LDI_R0 + 101)), 0)
;
5547 err |= __put_user(INSN_CALLSYS, &frame->retcode[2])(__builtin_choose_expr(sizeof(*(&frame->retcode[2])) ==
1, stb_p, __builtin_choose_expr(sizeof(*(&frame->retcode
[2])) == 2, stw_be_p, __builtin_choose_expr(sizeof(*(&frame
->retcode[2])) == 4, stl_be_p, __builtin_choose_expr(sizeof
(*(&frame->retcode[2])) == 8, stq_be_p, abort)))) ((&
frame->retcode[2]), (INSN_CALLSYS)), 0)
;
5548 /* imb(); */
5549 r26 = frame_addr;
5550 }
5551
5552 if (err) {
5553 give_sigsegv:
5554 if (sig == TARGET_SIGSEGV11) {
5555 ka->_sa_handler = TARGET_SIG_DFL((abi_long)0);
5556 }
5557 force_sig(TARGET_SIGSEGV11);
5558 }
5559
5560 env->ir[IR_RA] = r26;
5561 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5562 env->ir[IR_A0] = sig;
5563 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info)__builtin_offsetof(struct target_rt_sigframe, info);
5564 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc)__builtin_offsetof(struct target_rt_sigframe, uc);
5565 env->ir[IR_SP] = frame_addr;
5566}
5567
5568long do_sigreturn(CPUAlphaState *env)
5569{
5570 struct target_sigcontext *sc;
5571 abi_ulong sc_addr = env->ir[IR_A0];
5572 target_sigset_t target_set;
5573 sigset_t set;
5574
5575 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)(sc = lock_user(0, sc_addr, sizeof(*sc), 1))) {
5576 goto badframe;
5577 }
5578
5579 target_sigemptyset(&target_set);
5580 if (__get_user(target_set.sig[0], &sc->sc_mask)((target_set.sig[0]) = (typeof(*&sc->sc_mask))( __builtin_choose_expr
(sizeof(*(&sc->sc_mask)) == 1, ldub_p, __builtin_choose_expr
(sizeof(*(&sc->sc_mask)) == 2, lduw_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_mask)) == 4, ldl_be_p, __builtin_choose_expr
(sizeof(*(&sc->sc_mask)) == 8, ldq_be_p, abort)))) (&
sc->sc_mask)), 0)
) {
5581 goto badframe;
5582 }
5583
5584 target_to_host_sigset_internal(&set, &target_set);
5585 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
5586
5587 if (restore_sigcontext(env, sc)) {
5588 goto badframe;
5589 }
5590 unlock_user_struct(sc, sc_addr, 0)unlock_user(sc, sc_addr, (0) ? sizeof(*sc) : 0);
5591 return env->ir[IR_V0];
5592
5593 badframe:
5594 unlock_user_struct(sc, sc_addr, 0)unlock_user(sc, sc_addr, (0) ? sizeof(*sc) : 0);
5595 force_sig(TARGET_SIGSEGV11);
5596}
5597
5598long do_rt_sigreturn(CPUAlphaState *env)
5599{
5600 abi_ulong frame_addr = env->ir[IR_A0];
5601 struct target_rt_sigframe *frame;
5602 sigset_t set;
5603
5604 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)(frame = lock_user(0, frame_addr, sizeof(*frame), 1))) {
5605 goto badframe;
5606 }
5607 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5608 sigprocmask(SIG_SETMASK2, &set, NULL((void*)0));
5609
5610 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5611 goto badframe;
5612 }
5613 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack)
5614 uc.tuc_stack)__builtin_offsetof(struct target_rt_sigframe, uc.tuc_stack),
5615 0, env->ir[IR_SP]) == -EFAULT14) {
5616 goto badframe;
5617 }
5618
5619 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5620 return env->ir[IR_V0];
5621
5622
5623 badframe:
5624 unlock_user_struct(frame, frame_addr, 0)unlock_user(frame, frame_addr, (0) ? sizeof(*frame) : 0);
5625 force_sig(TARGET_SIGSEGV11);
5626}
5627
5628#else
5629
5630static void setup_frame(int sig, struct target_sigaction *ka,
5631 target_sigset_t *set, CPUArchStatestruct CPUSPARCState *env)
5632{
5633 fprintf(stderrstderr, "setup_frame: not implemented\n");
5634}
5635
5636static void setup_rt_frame(int sig, struct target_sigaction *ka,
5637 target_siginfo_t *info,
5638 target_sigset_t *set, CPUArchStatestruct CPUSPARCState *env)
5639{
5640 fprintf(stderrstderr, "setup_rt_frame: not implemented\n");
5641}
5642
5643long do_sigreturn(CPUArchStatestruct CPUSPARCState *env)
5644{
5645 fprintf(stderrstderr, "do_sigreturn: not implemented\n");
5646 return -TARGET_ENOSYS38;
5647}
5648
5649long do_rt_sigreturn(CPUArchStatestruct CPUSPARCState *env)
5650{
5651 fprintf(stderrstderr, "do_rt_sigreturn: not implemented\n");
5652 return -TARGET_ENOSYS38;
5653}
5654
5655#endif
5656
5657void process_pending_signals(CPUArchStatestruct CPUSPARCState *cpu_env)
5658{
5659 CPUState *cpu = ENV_GET_CPU(cpu_env)((CPUState *)object_dynamic_cast_assert(((Object *)((sparc_env_get_cpu
(cpu_env)))), ("cpu"), "/home/stefan/src/qemu/qemu.org/qemu/linux-user/signal.c"
, 5659, __func__))
;
5660 int sig;
5661 abi_ulong handler;
5662 sigset_t set, old_set;
5663 target_sigset_t target_old_set;
5664 struct emulated_sigtable *k;
5665 struct target_sigaction *sa;
5666 struct sigqueue *q;
5667 TaskState *ts = cpu_env->opaque;
5668
5669 if (!ts->signal_pending)
5670 return;
5671
5672 /* FIXME: This is not threadsafe. */
5673 k = ts->sigtab;
5674 for(sig = 1; sig <= TARGET_NSIG64; sig++) {
5675 if (k->pending)
5676 goto handle_signal;
5677 k++;
5678 }
5679 /* if no signal is pending, just return */
5680 ts->signal_pending = 0;
5681 return;
5682
5683 handle_signal:
5684#ifdef DEBUG_SIGNAL
5685 fprintf(stderrstderr, "qemu: process signal %d\n", sig);
5686#endif
5687 /* dequeue signal */
5688 q = k->first;
5689 k->first = q->next;
5690 if (!k->first)
5691 k->pending = 0;
5692
5693 sig = gdb_handlesig(cpu, sig);
5694 if (!sig) {
5695 sa = NULL((void*)0);
5696 handler = TARGET_SIG_IGN((abi_long)1);
5697 } else {
5698 sa = &sigact_table[sig - 1];
5699 handler = sa->_sa_handler;
5700 }
5701
5702 if (handler == TARGET_SIG_DFL((abi_long)0)) {
5703 /* default handler : ignore some signal. The other are job control or fatal */
5704 if (sig == TARGET_SIGTSTP18 || sig == TARGET_SIGTTIN21 || sig == TARGET_SIGTTOU22) {
5705 kill(getpid(),SIGSTOP19);
5706 } else if (sig != TARGET_SIGCHLD20 &&
5707 sig != TARGET_SIGURG16 &&
5708 sig != TARGET_SIGWINCH28 &&
5709 sig != TARGET_SIGCONT19) {
5710 force_sig(sig);
5711 }
5712 } else if (handler == TARGET_SIG_IGN((abi_long)1)) {
5713 /* ignore sig */
5714 } else if (handler == TARGET_SIG_ERR((abi_long)-1)) {
5715 force_sig(sig);
5716 } else {
5717 /* compute the blocked signals during the handler execution */
5718 target_to_host_sigset(&set, &sa->sa_mask);
5719 /* SA_NODEFER indicates that the current signal should not be
5720 blocked during the handler */
5721 if (!(sa->sa_flags & TARGET_SA_NODEFER0x20u))
5722 sigaddset(&set, target_to_host_signal(sig));
5723
5724 /* block signals in the handler using Linux */
5725 sigprocmask(SIG_BLOCK0, &set, &old_set);
5726 /* save the previous blocked signal state to restore it at the
5727 end of the signal execution (see do_sigreturn) */
5728 host_to_target_sigset_internal(&target_old_set, &old_set);
5729
5730 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5731#if defined(TARGET_I386) && !defined(TARGET_X86_64)
5732 {
5733 CPUX86State *env = cpu_env;
5734 if (env->eflags & VM_MASK)
5735 save_v86_state(env);
5736 }
5737#endif
5738 /* prepare the stack frame of the virtual CPU */
5739#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5740 /* These targets do not have traditional signals. */
5741 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5742#else
5743 if (sa->sa_flags & TARGET_SA_SIGINFO0x200u)
5744 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5745 else
5746 setup_frame(sig, sa, &target_old_set, cpu_env);
5747#endif
5748 if (sa->sa_flags & TARGET_SA_RESETHAND4u)
5749 sa->_sa_handler = TARGET_SIG_DFL((abi_long)0);
5750 }
5751 if (q != &k->info)
5752 free_sigqueue(cpu_env, q);
5753}