xref: /qemu/linux-user/arm/signal.c (revision 7ee9edfd)
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 "qemu/osdep.h"
20 #include "qemu.h"
21 #include "target_signal.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
24 
25 struct target_sigcontext {
26     abi_ulong trap_no;
27     abi_ulong error_code;
28     abi_ulong oldmask;
29     abi_ulong arm_r0;
30     abi_ulong arm_r1;
31     abi_ulong arm_r2;
32     abi_ulong arm_r3;
33     abi_ulong arm_r4;
34     abi_ulong arm_r5;
35     abi_ulong arm_r6;
36     abi_ulong arm_r7;
37     abi_ulong arm_r8;
38     abi_ulong arm_r9;
39     abi_ulong arm_r10;
40     abi_ulong arm_fp;
41     abi_ulong arm_ip;
42     abi_ulong arm_sp;
43     abi_ulong arm_lr;
44     abi_ulong arm_pc;
45     abi_ulong arm_cpsr;
46     abi_ulong fault_address;
47 };
48 
49 struct target_ucontext_v1 {
50     abi_ulong tuc_flags;
51     abi_ulong tuc_link;
52     target_stack_t tuc_stack;
53     struct target_sigcontext tuc_mcontext;
54     target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
55 };
56 
57 struct target_ucontext_v2 {
58     abi_ulong tuc_flags;
59     abi_ulong tuc_link;
60     target_stack_t tuc_stack;
61     struct target_sigcontext tuc_mcontext;
62     target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
63     char __unused[128 - sizeof(target_sigset_t)];
64     abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
65 };
66 
67 struct target_user_vfp {
68     uint64_t fpregs[32];
69     abi_ulong fpscr;
70 };
71 
72 struct target_user_vfp_exc {
73     abi_ulong fpexc;
74     abi_ulong fpinst;
75     abi_ulong fpinst2;
76 };
77 
78 struct target_vfp_sigframe {
79     abi_ulong magic;
80     abi_ulong size;
81     struct target_user_vfp ufp;
82     struct target_user_vfp_exc ufp_exc;
83 } __attribute__((__aligned__(8)));
84 
85 struct target_iwmmxt_sigframe {
86     abi_ulong magic;
87     abi_ulong size;
88     uint64_t regs[16];
89     /* Note that not all the coprocessor control registers are stored here */
90     uint32_t wcssf;
91     uint32_t wcasf;
92     uint32_t wcgr0;
93     uint32_t wcgr1;
94     uint32_t wcgr2;
95     uint32_t wcgr3;
96 } __attribute__((__aligned__(8)));
97 
98 #define TARGET_VFP_MAGIC 0x56465001
99 #define TARGET_IWMMXT_MAGIC 0x12ef842a
100 
101 struct sigframe_v1
102 {
103     struct target_sigcontext sc;
104     abi_ulong extramask[TARGET_NSIG_WORDS-1];
105     abi_ulong retcode;
106 };
107 
108 struct sigframe_v2
109 {
110     struct target_ucontext_v2 uc;
111     abi_ulong retcode;
112 };
113 
114 struct rt_sigframe_v1
115 {
116     abi_ulong pinfo;
117     abi_ulong puc;
118     struct target_siginfo info;
119     struct target_ucontext_v1 uc;
120     abi_ulong retcode;
121 };
122 
123 struct rt_sigframe_v2
124 {
125     struct target_siginfo info;
126     struct target_ucontext_v2 uc;
127     abi_ulong retcode;
128 };
129 
130 #define TARGET_CONFIG_CPU_32 1
131 
132 /*
133  * For ARM syscalls, we encode the syscall number into the instruction.
134  */
135 #define SWI_SYS_SIGRETURN       (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
136 #define SWI_SYS_RT_SIGRETURN    (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
137 
138 /*
139  * For Thumb syscalls, we pass the syscall number via r7.  We therefore
140  * need two 16-bit instructions.
141  */
142 #define SWI_THUMB_SIGRETURN     (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
143 #define SWI_THUMB_RT_SIGRETURN  (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
144 
145 static const abi_ulong retcodes[4] = {
146         SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
147         SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
148 };
149 
150 
151 static inline int valid_user_regs(CPUARMState *regs)
152 {
153     return 1;
154 }
155 
156 static void
157 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
158                  CPUARMState *env, abi_ulong mask)
159 {
160     __put_user(env->regs[0], &sc->arm_r0);
161     __put_user(env->regs[1], &sc->arm_r1);
162     __put_user(env->regs[2], &sc->arm_r2);
163     __put_user(env->regs[3], &sc->arm_r3);
164     __put_user(env->regs[4], &sc->arm_r4);
165     __put_user(env->regs[5], &sc->arm_r5);
166     __put_user(env->regs[6], &sc->arm_r6);
167     __put_user(env->regs[7], &sc->arm_r7);
168     __put_user(env->regs[8], &sc->arm_r8);
169     __put_user(env->regs[9], &sc->arm_r9);
170     __put_user(env->regs[10], &sc->arm_r10);
171     __put_user(env->regs[11], &sc->arm_fp);
172     __put_user(env->regs[12], &sc->arm_ip);
173     __put_user(env->regs[13], &sc->arm_sp);
174     __put_user(env->regs[14], &sc->arm_lr);
175     __put_user(env->regs[15], &sc->arm_pc);
176 #ifdef TARGET_CONFIG_CPU_32
177     __put_user(cpsr_read(env), &sc->arm_cpsr);
178 #endif
179 
180     __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
181     __put_user(/* current->thread.error_code */ 0, &sc->error_code);
182     __put_user(/* current->thread.address */ 0, &sc->fault_address);
183     __put_user(mask, &sc->oldmask);
184 }
185 
186 static inline abi_ulong
187 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
188 {
189     unsigned long sp = regs->regs[13];
190 
191     /*
192      * This is the X/Open sanctioned signal stack switching.
193      */
194     if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
195         sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
196     }
197     /*
198      * ATPCS B01 mandates 8-byte alignment
199      */
200     return (sp - framesize) & ~7;
201 }
202 
203 static void
204 setup_return(CPUARMState *env, struct target_sigaction *ka,
205              abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
206 {
207     abi_ulong handler = ka->_sa_handler;
208     abi_ulong retcode;
209     int thumb = handler & 1;
210     uint32_t cpsr = cpsr_read(env);
211 
212     cpsr &= ~CPSR_IT;
213     if (thumb) {
214         cpsr |= CPSR_T;
215     } else {
216         cpsr &= ~CPSR_T;
217     }
218 
219     if (ka->sa_flags & TARGET_SA_RESTORER) {
220         retcode = ka->sa_restorer;
221     } else {
222         unsigned int idx = thumb;
223 
224         if (ka->sa_flags & TARGET_SA_SIGINFO) {
225             idx += 2;
226         }
227 
228         __put_user(retcodes[idx], rc);
229 
230         retcode = rc_addr + thumb;
231     }
232 
233     env->regs[0] = usig;
234     env->regs[13] = frame_addr;
235     env->regs[14] = retcode;
236     env->regs[15] = handler & (thumb ? ~1 : ~3);
237     cpsr_write(env, cpsr, CPSR_IT | CPSR_T, CPSRWriteByInstr);
238 }
239 
240 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
241 {
242     int i;
243     struct target_vfp_sigframe *vfpframe;
244     vfpframe = (struct target_vfp_sigframe *)regspace;
245     __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
246     __put_user(sizeof(*vfpframe), &vfpframe->size);
247     for (i = 0; i < 32; i++) {
248         __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
249     }
250     __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
251     __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
252     __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
253     __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
254     return (abi_ulong*)(vfpframe+1);
255 }
256 
257 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
258                                            CPUARMState *env)
259 {
260     int i;
261     struct target_iwmmxt_sigframe *iwmmxtframe;
262     iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
263     __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
264     __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
265     for (i = 0; i < 16; i++) {
266         __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
267     }
268     __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
269     __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
270     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
271     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
272     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
273     __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
274     return (abi_ulong*)(iwmmxtframe+1);
275 }
276 
277 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
278                               target_sigset_t *set, CPUARMState *env)
279 {
280     struct target_sigaltstack stack;
281     int i;
282     abi_ulong *regspace;
283 
284     /* Clear all the bits of the ucontext we don't use.  */
285     memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
286 
287     memset(&stack, 0, sizeof(stack));
288     __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
289     __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
290     __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
291     memcpy(&uc->tuc_stack, &stack, sizeof(stack));
292 
293     setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
294     /* Save coprocessor signal frame.  */
295     regspace = uc->tuc_regspace;
296     if (arm_feature(env, ARM_FEATURE_VFP)) {
297         regspace = setup_sigframe_v2_vfp(regspace, env);
298     }
299     if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
300         regspace = setup_sigframe_v2_iwmmxt(regspace, env);
301     }
302 
303     /* Write terminating magic word */
304     __put_user(0, regspace);
305 
306     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
307         __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
308     }
309 }
310 
311 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
312 static void setup_frame_v1(int usig, struct target_sigaction *ka,
313                            target_sigset_t *set, CPUARMState *regs)
314 {
315     struct sigframe_v1 *frame;
316     abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
317     int i;
318 
319     trace_user_setup_frame(regs, frame_addr);
320     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
321         goto sigsegv;
322     }
323 
324     setup_sigcontext(&frame->sc, regs, set->sig[0]);
325 
326     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
327         __put_user(set->sig[i], &frame->extramask[i - 1]);
328     }
329 
330     setup_return(regs, ka, &frame->retcode, frame_addr, usig,
331                  frame_addr + offsetof(struct sigframe_v1, retcode));
332 
333     unlock_user_struct(frame, frame_addr, 1);
334     return;
335 sigsegv:
336     force_sigsegv(usig);
337 }
338 
339 static void setup_frame_v2(int usig, struct target_sigaction *ka,
340                            target_sigset_t *set, CPUARMState *regs)
341 {
342     struct sigframe_v2 *frame;
343     abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
344 
345     trace_user_setup_frame(regs, frame_addr);
346     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
347         goto sigsegv;
348     }
349 
350     setup_sigframe_v2(&frame->uc, set, regs);
351 
352     setup_return(regs, ka, &frame->retcode, frame_addr, usig,
353                  frame_addr + offsetof(struct sigframe_v2, retcode));
354 
355     unlock_user_struct(frame, frame_addr, 1);
356     return;
357 sigsegv:
358     force_sigsegv(usig);
359 }
360 
361 void setup_frame(int usig, struct target_sigaction *ka,
362                  target_sigset_t *set, CPUARMState *regs)
363 {
364     if (get_osversion() >= 0x020612) {
365         setup_frame_v2(usig, ka, set, regs);
366     } else {
367         setup_frame_v1(usig, ka, set, regs);
368     }
369 }
370 
371 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
372 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
373                               target_siginfo_t *info,
374                               target_sigset_t *set, CPUARMState *env)
375 {
376     struct rt_sigframe_v1 *frame;
377     abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
378     struct target_sigaltstack stack;
379     int i;
380     abi_ulong info_addr, uc_addr;
381 
382     trace_user_setup_rt_frame(env, frame_addr);
383     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
384         goto sigsegv;
385     }
386 
387     info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
388     __put_user(info_addr, &frame->pinfo);
389     uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
390     __put_user(uc_addr, &frame->puc);
391     tswap_siginfo(&frame->info, info);
392 
393     /* Clear all the bits of the ucontext we don't use.  */
394     memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
395 
396     memset(&stack, 0, sizeof(stack));
397     __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
398     __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
399     __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
400     memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
401 
402     setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
403     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
404         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
405     }
406 
407     setup_return(env, ka, &frame->retcode, frame_addr, usig,
408                  frame_addr + offsetof(struct rt_sigframe_v1, retcode));
409 
410     env->regs[1] = info_addr;
411     env->regs[2] = uc_addr;
412 
413     unlock_user_struct(frame, frame_addr, 1);
414     return;
415 sigsegv:
416     force_sigsegv(usig);
417 }
418 
419 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
420                               target_siginfo_t *info,
421                               target_sigset_t *set, CPUARMState *env)
422 {
423     struct rt_sigframe_v2 *frame;
424     abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
425     abi_ulong info_addr, uc_addr;
426 
427     trace_user_setup_rt_frame(env, frame_addr);
428     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
429         goto sigsegv;
430     }
431 
432     info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
433     uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
434     tswap_siginfo(&frame->info, info);
435 
436     setup_sigframe_v2(&frame->uc, set, env);
437 
438     setup_return(env, ka, &frame->retcode, frame_addr, usig,
439                  frame_addr + offsetof(struct rt_sigframe_v2, retcode));
440 
441     env->regs[1] = info_addr;
442     env->regs[2] = uc_addr;
443 
444     unlock_user_struct(frame, frame_addr, 1);
445     return;
446 sigsegv:
447     force_sigsegv(usig);
448 }
449 
450 void setup_rt_frame(int usig, struct target_sigaction *ka,
451                     target_siginfo_t *info,
452                     target_sigset_t *set, CPUARMState *env)
453 {
454     if (get_osversion() >= 0x020612) {
455         setup_rt_frame_v2(usig, ka, info, set, env);
456     } else {
457         setup_rt_frame_v1(usig, ka, info, set, env);
458     }
459 }
460 
461 static int
462 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
463 {
464     int err = 0;
465     uint32_t cpsr;
466 
467     __get_user(env->regs[0], &sc->arm_r0);
468     __get_user(env->regs[1], &sc->arm_r1);
469     __get_user(env->regs[2], &sc->arm_r2);
470     __get_user(env->regs[3], &sc->arm_r3);
471     __get_user(env->regs[4], &sc->arm_r4);
472     __get_user(env->regs[5], &sc->arm_r5);
473     __get_user(env->regs[6], &sc->arm_r6);
474     __get_user(env->regs[7], &sc->arm_r7);
475     __get_user(env->regs[8], &sc->arm_r8);
476     __get_user(env->regs[9], &sc->arm_r9);
477     __get_user(env->regs[10], &sc->arm_r10);
478     __get_user(env->regs[11], &sc->arm_fp);
479     __get_user(env->regs[12], &sc->arm_ip);
480     __get_user(env->regs[13], &sc->arm_sp);
481     __get_user(env->regs[14], &sc->arm_lr);
482     __get_user(env->regs[15], &sc->arm_pc);
483 #ifdef TARGET_CONFIG_CPU_32
484     __get_user(cpsr, &sc->arm_cpsr);
485     cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
486 #endif
487 
488     err |= !valid_user_regs(env);
489 
490     return err;
491 }
492 
493 static long do_sigreturn_v1(CPUARMState *env)
494 {
495     abi_ulong frame_addr;
496     struct sigframe_v1 *frame = NULL;
497     target_sigset_t set;
498     sigset_t host_set;
499     int i;
500 
501     /*
502      * Since we stacked the signal on a 64-bit boundary,
503      * then 'sp' should be word aligned here.  If it's
504      * not, then the user is trying to mess with us.
505      */
506     frame_addr = env->regs[13];
507     trace_user_do_sigreturn(env, frame_addr);
508     if (frame_addr & 7) {
509         goto badframe;
510     }
511 
512     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
513         goto badframe;
514     }
515 
516     __get_user(set.sig[0], &frame->sc.oldmask);
517     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
518         __get_user(set.sig[i], &frame->extramask[i - 1]);
519     }
520 
521     target_to_host_sigset_internal(&host_set, &set);
522     set_sigmask(&host_set);
523 
524     if (restore_sigcontext(env, &frame->sc)) {
525         goto badframe;
526     }
527 
528 #if 0
529     /* Send SIGTRAP if we're single-stepping */
530     if (ptrace_cancel_bpt(current))
531         send_sig(SIGTRAP, current, 1);
532 #endif
533     unlock_user_struct(frame, frame_addr, 0);
534     return -TARGET_QEMU_ESIGRETURN;
535 
536 badframe:
537     force_sig(TARGET_SIGSEGV);
538     return -TARGET_QEMU_ESIGRETURN;
539 }
540 
541 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
542 {
543     int i;
544     abi_ulong magic, sz;
545     uint32_t fpscr, fpexc;
546     struct target_vfp_sigframe *vfpframe;
547     vfpframe = (struct target_vfp_sigframe *)regspace;
548 
549     __get_user(magic, &vfpframe->magic);
550     __get_user(sz, &vfpframe->size);
551     if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
552         return 0;
553     }
554     for (i = 0; i < 32; i++) {
555         __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
556     }
557     __get_user(fpscr, &vfpframe->ufp.fpscr);
558     vfp_set_fpscr(env, fpscr);
559     __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
560     /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
561      * and the exception flag is cleared
562      */
563     fpexc |= (1 << 30);
564     fpexc &= ~((1 << 31) | (1 << 28));
565     env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
566     __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
567     __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
568     return (abi_ulong*)(vfpframe + 1);
569 }
570 
571 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
572                                              abi_ulong *regspace)
573 {
574     int i;
575     abi_ulong magic, sz;
576     struct target_iwmmxt_sigframe *iwmmxtframe;
577     iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
578 
579     __get_user(magic, &iwmmxtframe->magic);
580     __get_user(sz, &iwmmxtframe->size);
581     if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
582         return 0;
583     }
584     for (i = 0; i < 16; i++) {
585         __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
586     }
587     __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
588     __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
589     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
590     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
591     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
592     __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
593     return (abi_ulong*)(iwmmxtframe + 1);
594 }
595 
596 static int do_sigframe_return_v2(CPUARMState *env,
597                                  target_ulong context_addr,
598                                  struct target_ucontext_v2 *uc)
599 {
600     sigset_t host_set;
601     abi_ulong *regspace;
602 
603     target_to_host_sigset(&host_set, &uc->tuc_sigmask);
604     set_sigmask(&host_set);
605 
606     if (restore_sigcontext(env, &uc->tuc_mcontext))
607         return 1;
608 
609     /* Restore coprocessor signal frame */
610     regspace = uc->tuc_regspace;
611     if (arm_feature(env, ARM_FEATURE_VFP)) {
612         regspace = restore_sigframe_v2_vfp(env, regspace);
613         if (!regspace) {
614             return 1;
615         }
616     }
617     if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
618         regspace = restore_sigframe_v2_iwmmxt(env, regspace);
619         if (!regspace) {
620             return 1;
621         }
622     }
623 
624     if (do_sigaltstack(context_addr
625                        + offsetof(struct target_ucontext_v2, tuc_stack),
626                        0, get_sp_from_cpustate(env)) == -EFAULT) {
627         return 1;
628     }
629 
630 #if 0
631     /* Send SIGTRAP if we're single-stepping */
632     if (ptrace_cancel_bpt(current))
633         send_sig(SIGTRAP, current, 1);
634 #endif
635 
636     return 0;
637 }
638 
639 static long do_sigreturn_v2(CPUARMState *env)
640 {
641     abi_ulong frame_addr;
642     struct sigframe_v2 *frame = NULL;
643 
644     /*
645      * Since we stacked the signal on a 64-bit boundary,
646      * then 'sp' should be word aligned here.  If it's
647      * not, then the user is trying to mess with us.
648      */
649     frame_addr = env->regs[13];
650     trace_user_do_sigreturn(env, frame_addr);
651     if (frame_addr & 7) {
652         goto badframe;
653     }
654 
655     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
656         goto badframe;
657     }
658 
659     if (do_sigframe_return_v2(env,
660                               frame_addr
661                               + offsetof(struct sigframe_v2, uc),
662                               &frame->uc)) {
663         goto badframe;
664     }
665 
666     unlock_user_struct(frame, frame_addr, 0);
667     return -TARGET_QEMU_ESIGRETURN;
668 
669 badframe:
670     unlock_user_struct(frame, frame_addr, 0);
671     force_sig(TARGET_SIGSEGV);
672     return -TARGET_QEMU_ESIGRETURN;
673 }
674 
675 long do_sigreturn(CPUARMState *env)
676 {
677     if (get_osversion() >= 0x020612) {
678         return do_sigreturn_v2(env);
679     } else {
680         return do_sigreturn_v1(env);
681     }
682 }
683 
684 static long do_rt_sigreturn_v1(CPUARMState *env)
685 {
686     abi_ulong frame_addr;
687     struct rt_sigframe_v1 *frame = NULL;
688     sigset_t host_set;
689 
690     /*
691      * Since we stacked the signal on a 64-bit boundary,
692      * then 'sp' should be word aligned here.  If it's
693      * not, then the user is trying to mess with us.
694      */
695     frame_addr = env->regs[13];
696     trace_user_do_rt_sigreturn(env, frame_addr);
697     if (frame_addr & 7) {
698         goto badframe;
699     }
700 
701     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
702         goto badframe;
703     }
704 
705     target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
706     set_sigmask(&host_set);
707 
708     if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
709         goto badframe;
710     }
711 
712     if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
713         goto badframe;
714 
715 #if 0
716     /* Send SIGTRAP if we're single-stepping */
717     if (ptrace_cancel_bpt(current))
718         send_sig(SIGTRAP, current, 1);
719 #endif
720     unlock_user_struct(frame, frame_addr, 0);
721     return -TARGET_QEMU_ESIGRETURN;
722 
723 badframe:
724     unlock_user_struct(frame, frame_addr, 0);
725     force_sig(TARGET_SIGSEGV);
726     return -TARGET_QEMU_ESIGRETURN;
727 }
728 
729 static long do_rt_sigreturn_v2(CPUARMState *env)
730 {
731     abi_ulong frame_addr;
732     struct rt_sigframe_v2 *frame = NULL;
733 
734     /*
735      * Since we stacked the signal on a 64-bit boundary,
736      * then 'sp' should be word aligned here.  If it's
737      * not, then the user is trying to mess with us.
738      */
739     frame_addr = env->regs[13];
740     trace_user_do_rt_sigreturn(env, frame_addr);
741     if (frame_addr & 7) {
742         goto badframe;
743     }
744 
745     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
746         goto badframe;
747     }
748 
749     if (do_sigframe_return_v2(env,
750                               frame_addr
751                               + offsetof(struct rt_sigframe_v2, uc),
752                               &frame->uc)) {
753         goto badframe;
754     }
755 
756     unlock_user_struct(frame, frame_addr, 0);
757     return -TARGET_QEMU_ESIGRETURN;
758 
759 badframe:
760     unlock_user_struct(frame, frame_addr, 0);
761     force_sig(TARGET_SIGSEGV);
762     return -TARGET_QEMU_ESIGRETURN;
763 }
764 
765 long do_rt_sigreturn(CPUARMState *env)
766 {
767     if (get_osversion() >= 0x020612) {
768         return do_rt_sigreturn_v2(env);
769     } else {
770         return do_rt_sigreturn_v1(env);
771     }
772 }
773