2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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/>.
19 #include "qemu/osdep.h"
21 #include "user-internals.h"
22 #include "signal-common.h"
23 #include "linux-user/trace.h"
25 /* from the Linux kernel - /arch/x86/include/uapi/asm/sigcontext.h */
27 #define TARGET_FP_XSTATE_MAGIC1 0x46505853U /* FPXS */
28 #define TARGET_FP_XSTATE_MAGIC2 0x46505845U /* FPXE */
29 #define TARGET_FP_XSTATE_MAGIC2_SIZE 4
32 uint16_t significand
[4];
36 struct target_fpxreg
{
37 uint16_t significand
[4];
42 struct target_xmmreg
{
46 struct target_fpx_sw_bytes
{
48 uint32_t extended_size
;
53 QEMU_BUILD_BUG_ON(sizeof(struct target_fpx_sw_bytes
) != 12*4);
55 struct target_fpstate_fxsave
{
65 uint32_t st_space
[32];
66 uint32_t xmm_space
[64];
67 uint32_t hw_reserved
[12];
68 struct target_fpx_sw_bytes sw_reserved
;
71 #define TARGET_FXSAVE_SIZE sizeof(struct target_fpstate_fxsave)
72 QEMU_BUILD_BUG_ON(TARGET_FXSAVE_SIZE
!= 512);
73 QEMU_BUILD_BUG_ON(offsetof(struct target_fpstate_fxsave
, sw_reserved
) != 464);
75 struct target_fpstate_32
{
76 /* Regular FPU environment */
84 struct target_fpreg st
[8];
86 uint16_t magic
; /* 0xffff = regular FPU data only */
87 struct target_fpstate_fxsave fxsave
;
91 * For simplicity, setup_frame aligns struct target_fpstate_32 to
92 * 16 bytes, so ensure that the FXSAVE area is also aligned.
94 QEMU_BUILD_BUG_ON(offsetof(struct target_fpstate_32
, fxsave
) & 15);
97 # define target_fpstate target_fpstate_32
98 # define TARGET_FPSTATE_FXSAVE_OFFSET offsetof(struct target_fpstate_32, fxsave)
100 # define target_fpstate target_fpstate_fxsave
101 # define TARGET_FPSTATE_FXSAVE_OFFSET 0
104 struct target_sigcontext_32
{
122 uint32_t esp_at_signal
;
124 uint32_t fpstate
; /* pointer */
129 struct target_sigcontext_64
{
161 uint64_t fpstate
; /* pointer */
165 #ifndef TARGET_X86_64
166 # define target_sigcontext target_sigcontext_32
168 # define target_sigcontext target_sigcontext_64
171 /* see Linux/include/uapi/asm-generic/ucontext.h */
172 struct target_ucontext
{
175 target_stack_t tuc_stack
;
176 struct target_sigcontext tuc_mcontext
;
177 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
180 #ifndef TARGET_X86_64
184 struct target_sigcontext sc
;
186 * The actual fpstate is placed after retcode[] below, to make
187 * room for the variable-sized xsave data. The older unused fpstate
188 * has to be kept to avoid changing the offset of extramask[], which
189 * is part of the ABI.
191 struct target_fpstate fpstate_unused
;
192 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
196 * This field will be 16-byte aligned in memory. Applying QEMU_ALIGNED
197 * to it ensures that the base of the frame has an appropriate alignment
200 struct target_fpstate fpstate
QEMU_ALIGNED(8);
202 #define TARGET_SIGFRAME_FXSAVE_OFFSET ( \
203 offsetof(struct sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
210 struct target_siginfo info
;
211 struct target_ucontext uc
;
213 struct target_fpstate fpstate
QEMU_ALIGNED(8);
215 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \
216 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
219 * Verify that vdso-asmoffset.h constants match.
221 #include "i386/vdso-asmoffset.h"
223 QEMU_BUILD_BUG_ON(offsetof(struct sigframe
, sc
.eip
)
224 != SIGFRAME_SIGCONTEXT_eip
);
225 QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe
, uc
.tuc_mcontext
.eip
)
226 != RT_SIGFRAME_SIGCONTEXT_eip
);
232 struct target_ucontext uc
;
233 struct target_siginfo info
;
234 struct target_fpstate fpstate
QEMU_ALIGNED(16);
236 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \
237 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET)
241 * Set up a signal frame.
244 static void xsave_sigcontext(CPUX86State
*env
, struct target_fpstate_fxsave
*fxsave
,
245 abi_ulong fxsave_addr
)
247 if (!(env
->features
[FEAT_1_ECX
] & CPUID_EXT_XSAVE
)) {
248 /* fxsave_addr must be 16 byte aligned for fxsave */
249 assert(!(fxsave_addr
& 0xf));
251 cpu_x86_fxsave(env
, fxsave_addr
);
252 __put_user(0, &fxsave
->sw_reserved
.magic1
);
254 uint32_t xstate_size
= xsave_area_size(env
->xcr0
, false);
255 uint32_t xfeatures_size
= xstate_size
- TARGET_FXSAVE_SIZE
;
258 * extended_size is the offset from fpstate_addr to right after the end
259 * of the extended save states. On 32-bit that includes the legacy
262 uint32_t extended_size
= TARGET_FPSTATE_FXSAVE_OFFSET
263 + xstate_size
+ TARGET_FP_XSTATE_MAGIC2_SIZE
;
265 /* fxsave_addr must be 64 byte aligned for xsave */
266 assert(!(fxsave_addr
& 0x3f));
268 /* Zero the header, XSAVE *adds* features to an existing save state. */
269 memset(fxsave
->xfeatures
, 0, 64);
270 cpu_x86_xsave(env
, fxsave_addr
);
271 __put_user(TARGET_FP_XSTATE_MAGIC1
, &fxsave
->sw_reserved
.magic1
);
272 __put_user(extended_size
, &fxsave
->sw_reserved
.extended_size
);
273 __put_user(env
->xcr0
, &fxsave
->sw_reserved
.xfeatures
);
274 __put_user(xstate_size
, &fxsave
->sw_reserved
.xstate_size
);
275 __put_user(TARGET_FP_XSTATE_MAGIC2
, (uint32_t *) &fxsave
->xfeatures
[xfeatures_size
]);
279 static void setup_sigcontext(struct target_sigcontext
*sc
,
280 struct target_fpstate
*fpstate
, CPUX86State
*env
, abi_ulong mask
,
281 abi_ulong fpstate_addr
)
283 CPUState
*cs
= env_cpu(env
);
284 #ifndef TARGET_X86_64
287 /* already locked in setup_frame() */
288 __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
289 __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
290 __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
291 __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
292 __put_user(env
->regs
[R_EDI
], &sc
->edi
);
293 __put_user(env
->regs
[R_ESI
], &sc
->esi
);
294 __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
295 __put_user(env
->regs
[R_ESP
], &sc
->esp
);
296 __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
297 __put_user(env
->regs
[R_EDX
], &sc
->edx
);
298 __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
299 __put_user(env
->regs
[R_EAX
], &sc
->eax
);
300 __put_user(cs
->exception_index
, &sc
->trapno
);
301 __put_user(env
->error_code
, &sc
->err
);
302 __put_user(env
->eip
, &sc
->eip
);
303 __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
304 __put_user(env
->eflags
, &sc
->eflags
);
305 __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
306 __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
308 cpu_x86_fsave(env
, fpstate_addr
, 1);
309 fpstate
->status
= fpstate
->sw
;
310 if (!(env
->features
[FEAT_1_EDX
] & CPUID_FXSR
)) {
313 xsave_sigcontext(env
, &fpstate
->fxsave
,
314 fpstate_addr
+ TARGET_FPSTATE_FXSAVE_OFFSET
);
317 __put_user(magic
, &fpstate
->magic
);
319 __put_user(env
->regs
[R_EDI
], &sc
->rdi
);
320 __put_user(env
->regs
[R_ESI
], &sc
->rsi
);
321 __put_user(env
->regs
[R_EBP
], &sc
->rbp
);
322 __put_user(env
->regs
[R_ESP
], &sc
->rsp
);
323 __put_user(env
->regs
[R_EBX
], &sc
->rbx
);
324 __put_user(env
->regs
[R_EDX
], &sc
->rdx
);
325 __put_user(env
->regs
[R_ECX
], &sc
->rcx
);
326 __put_user(env
->regs
[R_EAX
], &sc
->rax
);
328 __put_user(env
->regs
[8], &sc
->r8
);
329 __put_user(env
->regs
[9], &sc
->r9
);
330 __put_user(env
->regs
[10], &sc
->r10
);
331 __put_user(env
->regs
[11], &sc
->r11
);
332 __put_user(env
->regs
[12], &sc
->r12
);
333 __put_user(env
->regs
[13], &sc
->r13
);
334 __put_user(env
->regs
[14], &sc
->r14
);
335 __put_user(env
->regs
[15], &sc
->r15
);
337 __put_user(cs
->exception_index
, &sc
->trapno
);
338 __put_user(env
->error_code
, &sc
->err
);
339 __put_user(env
->eip
, &sc
->rip
);
341 __put_user(env
->eflags
, &sc
->eflags
);
342 __put_user(env
->segs
[R_CS
].selector
, &sc
->cs
);
343 __put_user((uint16_t)0, &sc
->gs
);
344 __put_user((uint16_t)0, &sc
->fs
);
345 __put_user(env
->segs
[R_SS
].selector
, &sc
->ss
);
347 xsave_sigcontext(env
, fpstate
, fpstate_addr
);
350 __put_user(fpstate_addr
, &sc
->fpstate
);
352 /* non-iBCS2 extensions.. */
353 __put_user(mask
, &sc
->oldmask
);
354 __put_user(env
->cr
[2], &sc
->cr2
);
358 * Determine which stack to use..
361 static inline abi_ulong
362 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t fxsave_offset
)
366 /* Default to using normal stack */
367 esp
= get_sp_from_cpustate(env
);
369 esp
-= 128; /* this is the redzone */
372 /* This is the X/Open sanctioned signal stack switching. */
373 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
374 esp
= target_sigsp(esp
, ka
);
376 #ifndef TARGET_X86_64
377 /* This is the legacy signal stack switching. */
378 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
379 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
381 esp
= (unsigned long) ka
->sa_restorer
;
386 if (!(env
->features
[FEAT_1_EDX
] & CPUID_FXSR
)) {
387 return (esp
- (fxsave_offset
+ TARGET_FXSAVE_SIZE
)) & -8ul;
388 } else if (!(env
->features
[FEAT_1_ECX
] & CPUID_EXT_XSAVE
)) {
389 return ((esp
- TARGET_FXSAVE_SIZE
) & -16ul) - fxsave_offset
;
392 xsave_area_size(env
->xcr0
, false) + TARGET_FP_XSTATE_MAGIC2_SIZE
;
393 return ((esp
- xstate_size
) & -64ul) - fxsave_offset
;
397 #ifndef TARGET_X86_64
398 static void install_sigtramp(void *tramp
)
400 /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */
401 __put_user(0xb858, (uint16_t *)(tramp
+ 0));
402 __put_user(TARGET_NR_sigreturn
, (int32_t *)(tramp
+ 2));
403 __put_user(0x80cd, (uint16_t *)(tramp
+ 6));
406 static void install_rt_sigtramp(void *tramp
)
408 /* This is movl $syscall,%eax ; int $0x80 */
409 __put_user(0xb8, (uint8_t *)(tramp
+ 0));
410 __put_user(TARGET_NR_rt_sigreturn
, (int32_t *)(tramp
+ 1));
411 __put_user(0x80cd, (uint16_t *)(tramp
+ 5));
414 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
415 void setup_frame(int sig
, struct target_sigaction
*ka
,
416 target_sigset_t
*set
, CPUX86State
*env
)
418 abi_ulong frame_addr
;
419 struct sigframe
*frame
;
422 frame_addr
= get_sigframe(ka
, env
, TARGET_SIGFRAME_FXSAVE_OFFSET
);
423 trace_user_setup_frame(env
, frame_addr
);
425 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
428 __put_user(sig
, &frame
->sig
);
430 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
431 frame_addr
+ offsetof(struct sigframe
, fpstate
));
433 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
434 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
437 /* Set up to return from userspace. If provided, use a stub
438 already in userspace. */
439 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
440 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
442 /* This is no longer used, but is retained for ABI compatibility. */
443 install_sigtramp(frame
->retcode
);
444 __put_user(default_sigreturn
, &frame
->pretcode
);
447 /* Set up registers for signal handler */
448 env
->regs
[R_ESP
] = frame_addr
;
449 env
->eip
= ka
->_sa_handler
;
451 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
452 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
453 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
454 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
455 env
->eflags
&= ~TF_MASK
;
457 unlock_user_struct(frame
, frame_addr
, 1);
466 /* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */
467 void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
468 target_siginfo_t
*info
,
469 target_sigset_t
*set
, CPUX86State
*env
)
471 abi_ulong frame_addr
;
472 #ifndef TARGET_X86_64
475 struct rt_sigframe
*frame
;
478 frame_addr
= get_sigframe(ka
, env
, TARGET_RT_SIGFRAME_FXSAVE_OFFSET
);
479 trace_user_setup_rt_frame(env
, frame_addr
);
481 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
484 /* These fields are only in rt_sigframe on 32 bit */
485 #ifndef TARGET_X86_64
486 __put_user(sig
, &frame
->sig
);
487 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
488 __put_user(addr
, &frame
->pinfo
);
489 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
490 __put_user(addr
, &frame
->puc
);
492 if (ka
->sa_flags
& TARGET_SA_SIGINFO
) {
493 tswap_siginfo(&frame
->info
, info
);
496 /* Create the ucontext. */
497 if (env
->features
[FEAT_1_ECX
] & CPUID_EXT_XSAVE
) {
498 __put_user(1, &frame
->uc
.tuc_flags
);
500 __put_user(0, &frame
->uc
.tuc_flags
);
502 __put_user(0, &frame
->uc
.tuc_link
);
503 target_save_altstack(&frame
->uc
.tuc_stack
, env
);
504 setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
, env
,
505 set
->sig
[0], frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
507 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
508 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
511 /* Set up to return from userspace. If provided, use a stub
512 already in userspace. */
513 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
514 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
517 /* For x86_64, SA_RESTORER is required ABI. */
520 /* This is no longer used, but is retained for ABI compatibility. */
521 install_rt_sigtramp(frame
->retcode
);
522 __put_user(default_rt_sigreturn
, &frame
->pretcode
);
526 /* Set up registers for signal handler */
527 env
->regs
[R_ESP
] = frame_addr
;
528 env
->eip
= ka
->_sa_handler
;
530 #ifndef TARGET_X86_64
531 env
->regs
[R_EAX
] = sig
;
532 env
->regs
[R_EDX
] = frame_addr
+ offsetof(struct rt_sigframe
, info
);
533 env
->regs
[R_ECX
] = frame_addr
+ offsetof(struct rt_sigframe
, uc
);
535 env
->regs
[R_EAX
] = 0;
536 env
->regs
[R_EDI
] = sig
;
537 env
->regs
[R_ESI
] = frame_addr
+ offsetof(struct rt_sigframe
, info
);
538 env
->regs
[R_EDX
] = frame_addr
+ offsetof(struct rt_sigframe
, uc
);
541 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
542 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
543 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
544 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
545 env
->eflags
&= ~TF_MASK
;
547 unlock_user_struct(frame
, frame_addr
, 1);
555 static int xrstor_sigcontext(CPUX86State
*env
, struct target_fpstate_fxsave
*fxsave
,
556 abi_ulong fxsave_addr
)
558 if (env
->features
[FEAT_1_ECX
] & CPUID_EXT_XSAVE
) {
559 uint32_t extended_size
= tswapl(fxsave
->sw_reserved
.extended_size
);
560 uint32_t xstate_size
= tswapl(fxsave
->sw_reserved
.xstate_size
);
561 uint32_t xfeatures_size
= xstate_size
- TARGET_FXSAVE_SIZE
;
563 /* Linux checks MAGIC2 using xstate_size, not extended_size. */
564 if (tswapl(fxsave
->sw_reserved
.magic1
) == TARGET_FP_XSTATE_MAGIC1
&&
565 extended_size
>= TARGET_FPSTATE_FXSAVE_OFFSET
+ xstate_size
+ TARGET_FP_XSTATE_MAGIC2_SIZE
) {
566 if (!access_ok(env_cpu(env
), VERIFY_READ
, fxsave_addr
,
567 extended_size
- TARGET_FPSTATE_FXSAVE_OFFSET
)) {
570 if (tswapl(*(uint32_t *) &fxsave
->xfeatures
[xfeatures_size
]) == TARGET_FP_XSTATE_MAGIC2
) {
571 cpu_x86_xrstor(env
, fxsave_addr
);
575 /* fall through to fxrstor */
578 cpu_x86_fxrstor(env
, fxsave_addr
);
583 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
)
586 abi_ulong fpstate_addr
;
587 unsigned int tmpflags
;
589 #ifndef TARGET_X86_64
590 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
591 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
592 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
593 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
595 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
596 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
597 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
598 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
599 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
600 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
601 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
602 env
->regs
[R_EAX
] = tswapl(sc
->eax
);
604 env
->eip
= tswapl(sc
->eip
);
606 env
->regs
[8] = tswapl(sc
->r8
);
607 env
->regs
[9] = tswapl(sc
->r9
);
608 env
->regs
[10] = tswapl(sc
->r10
);
609 env
->regs
[11] = tswapl(sc
->r11
);
610 env
->regs
[12] = tswapl(sc
->r12
);
611 env
->regs
[13] = tswapl(sc
->r13
);
612 env
->regs
[14] = tswapl(sc
->r14
);
613 env
->regs
[15] = tswapl(sc
->r15
);
615 env
->regs
[R_EDI
] = tswapl(sc
->rdi
);
616 env
->regs
[R_ESI
] = tswapl(sc
->rsi
);
617 env
->regs
[R_EBP
] = tswapl(sc
->rbp
);
618 env
->regs
[R_EBX
] = tswapl(sc
->rbx
);
619 env
->regs
[R_EDX
] = tswapl(sc
->rdx
);
620 env
->regs
[R_EAX
] = tswapl(sc
->rax
);
621 env
->regs
[R_ECX
] = tswapl(sc
->rcx
);
622 env
->regs
[R_ESP
] = tswapl(sc
->rsp
);
624 env
->eip
= tswapl(sc
->rip
);
627 cpu_x86_load_seg(env
, R_CS
, lduw_p(&sc
->cs
) | 3);
628 cpu_x86_load_seg(env
, R_SS
, lduw_p(&sc
->ss
) | 3);
630 tmpflags
= tswapl(sc
->eflags
);
631 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
632 // regs->orig_eax = -1; /* disable syscall checks */
634 fpstate_addr
= tswapl(sc
->fpstate
);
635 if (fpstate_addr
!= 0) {
636 struct target_fpstate
*fpstate
;
637 if (!lock_user_struct(VERIFY_READ
, fpstate
, fpstate_addr
,
638 sizeof(struct target_fpstate
))) {
641 #ifndef TARGET_X86_64
642 if (!(env
->features
[FEAT_1_EDX
] & CPUID_FXSR
)) {
643 cpu_x86_frstor(env
, fpstate_addr
, 1);
646 err
= xrstor_sigcontext(env
, &fpstate
->fxsave
,
647 fpstate_addr
+ TARGET_FPSTATE_FXSAVE_OFFSET
);
650 err
= xrstor_sigcontext(env
, fpstate
, fpstate_addr
);
652 unlock_user_struct(fpstate
, fpstate_addr
, 0);
660 /* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */
661 #ifndef TARGET_X86_64
662 long do_sigreturn(CPUX86State
*env
)
664 struct sigframe
*frame
;
665 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
666 target_sigset_t target_set
;
670 trace_user_do_sigreturn(env
, frame_addr
);
671 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
673 /* set blocked signals */
674 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
675 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
676 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
679 target_to_host_sigset_internal(&set
, &target_set
);
682 /* restore registers */
683 if (restore_sigcontext(env
, &frame
->sc
))
685 unlock_user_struct(frame
, frame_addr
, 0);
686 return -QEMU_ESIGRETURN
;
689 unlock_user_struct(frame
, frame_addr
, 0);
690 force_sig(TARGET_SIGSEGV
);
691 return -QEMU_ESIGRETURN
;
695 long do_rt_sigreturn(CPUX86State
*env
)
697 abi_ulong frame_addr
;
698 struct rt_sigframe
*frame
;
701 frame_addr
= env
->regs
[R_ESP
] - sizeof(abi_ulong
);
702 trace_user_do_rt_sigreturn(env
, frame_addr
);
703 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
705 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
708 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
712 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
714 unlock_user_struct(frame
, frame_addr
, 0);
715 return -QEMU_ESIGRETURN
;
718 unlock_user_struct(frame
, frame_addr
, 0);
719 force_sig(TARGET_SIGSEGV
);
720 return -QEMU_ESIGRETURN
;
723 #ifndef TARGET_X86_64
724 void setup_sigtramp(abi_ulong sigtramp_page
)
726 uint16_t *tramp
= lock_user(VERIFY_WRITE
, sigtramp_page
, 2 * 8, 0);
727 assert(tramp
!= NULL
);
729 default_sigreturn
= sigtramp_page
;
730 install_sigtramp(tramp
);
732 default_rt_sigreturn
= sigtramp_page
+ 8;
733 install_rt_sigtramp(tramp
+ 8);
735 unlock_user(tramp
, sigtramp_page
, 2 * 8);