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 */
28 uint16_t significand
[4];
32 struct target_fpxreg
{
33 uint16_t significand
[4];
38 struct target_xmmreg
{
42 struct target_fpstate_32
{
43 /* Regular FPU environment */
51 struct target_fpreg st
[8];
53 uint16_t magic
; /* 0xffff = regular FPU data only */
55 /* FXSR FPU environment */
56 uint32_t _fxsr_env
[6]; /* FXSR FPU env is ignored */
59 struct target_fpxreg fxsr_st
[8]; /* FXSR FPU reg data is ignored */
60 struct target_xmmreg xmm
[8];
64 struct target_fpstate_64
{
74 uint32_t st_space
[32];
75 uint32_t xmm_space
[64];
76 uint32_t reserved
[24];
80 # define target_fpstate target_fpstate_32
82 # define target_fpstate target_fpstate_64
85 struct target_sigcontext_32
{
103 uint32_t esp_at_signal
;
105 uint32_t fpstate
; /* pointer */
110 struct target_sigcontext_64
{
142 uint64_t fpstate
; /* pointer */
146 #ifndef TARGET_X86_64
147 # define target_sigcontext target_sigcontext_32
149 # define target_sigcontext target_sigcontext_64
152 /* see Linux/include/uapi/asm-generic/ucontext.h */
153 struct target_ucontext
{
156 target_stack_t tuc_stack
;
157 struct target_sigcontext tuc_mcontext
;
158 target_sigset_t tuc_sigmask
; /* mask last for extensibility */
161 #ifndef TARGET_X86_64
165 struct target_sigcontext sc
;
167 * The actual fpstate is placed after retcode[] below, to make
168 * room for the variable-sized xsave data. The older unused fpstate
169 * has to be kept to avoid changing the offset of extramask[], which
170 * is part of the ABI.
172 struct target_fpstate fpstate_unused
;
173 abi_ulong extramask
[TARGET_NSIG_WORDS
-1];
175 struct target_fpstate fpstate
;
183 struct target_siginfo info
;
184 struct target_ucontext uc
;
186 struct target_fpstate fpstate
;
193 struct target_ucontext uc
;
194 struct target_siginfo info
;
195 struct target_fpstate fpstate
;
201 * Set up a signal frame.
204 /* XXX: save x87 state */
205 static void setup_sigcontext(struct target_sigcontext
*sc
,
206 struct target_fpstate
*fpstate
, CPUX86State
*env
, abi_ulong mask
,
207 abi_ulong fpstate_addr
)
209 CPUState
*cs
= env_cpu(env
);
210 #ifndef TARGET_X86_64
213 /* already locked in setup_frame() */
214 __put_user(env
->segs
[R_GS
].selector
, (unsigned int *)&sc
->gs
);
215 __put_user(env
->segs
[R_FS
].selector
, (unsigned int *)&sc
->fs
);
216 __put_user(env
->segs
[R_ES
].selector
, (unsigned int *)&sc
->es
);
217 __put_user(env
->segs
[R_DS
].selector
, (unsigned int *)&sc
->ds
);
218 __put_user(env
->regs
[R_EDI
], &sc
->edi
);
219 __put_user(env
->regs
[R_ESI
], &sc
->esi
);
220 __put_user(env
->regs
[R_EBP
], &sc
->ebp
);
221 __put_user(env
->regs
[R_ESP
], &sc
->esp
);
222 __put_user(env
->regs
[R_EBX
], &sc
->ebx
);
223 __put_user(env
->regs
[R_EDX
], &sc
->edx
);
224 __put_user(env
->regs
[R_ECX
], &sc
->ecx
);
225 __put_user(env
->regs
[R_EAX
], &sc
->eax
);
226 __put_user(cs
->exception_index
, &sc
->trapno
);
227 __put_user(env
->error_code
, &sc
->err
);
228 __put_user(env
->eip
, &sc
->eip
);
229 __put_user(env
->segs
[R_CS
].selector
, (unsigned int *)&sc
->cs
);
230 __put_user(env
->eflags
, &sc
->eflags
);
231 __put_user(env
->regs
[R_ESP
], &sc
->esp_at_signal
);
232 __put_user(env
->segs
[R_SS
].selector
, (unsigned int *)&sc
->ss
);
234 cpu_x86_fsave(env
, fpstate_addr
, 1);
235 fpstate
->status
= fpstate
->sw
;
237 __put_user(magic
, &fpstate
->magic
);
238 __put_user(fpstate_addr
, &sc
->fpstate
);
240 /* non-iBCS2 extensions.. */
241 __put_user(mask
, &sc
->oldmask
);
242 __put_user(env
->cr
[2], &sc
->cr2
);
244 __put_user(env
->regs
[R_EDI
], &sc
->rdi
);
245 __put_user(env
->regs
[R_ESI
], &sc
->rsi
);
246 __put_user(env
->regs
[R_EBP
], &sc
->rbp
);
247 __put_user(env
->regs
[R_ESP
], &sc
->rsp
);
248 __put_user(env
->regs
[R_EBX
], &sc
->rbx
);
249 __put_user(env
->regs
[R_EDX
], &sc
->rdx
);
250 __put_user(env
->regs
[R_ECX
], &sc
->rcx
);
251 __put_user(env
->regs
[R_EAX
], &sc
->rax
);
253 __put_user(env
->regs
[8], &sc
->r8
);
254 __put_user(env
->regs
[9], &sc
->r9
);
255 __put_user(env
->regs
[10], &sc
->r10
);
256 __put_user(env
->regs
[11], &sc
->r11
);
257 __put_user(env
->regs
[12], &sc
->r12
);
258 __put_user(env
->regs
[13], &sc
->r13
);
259 __put_user(env
->regs
[14], &sc
->r14
);
260 __put_user(env
->regs
[15], &sc
->r15
);
262 __put_user(cs
->exception_index
, &sc
->trapno
);
263 __put_user(env
->error_code
, &sc
->err
);
264 __put_user(env
->eip
, &sc
->rip
);
266 __put_user(env
->eflags
, &sc
->eflags
);
267 __put_user(env
->segs
[R_CS
].selector
, &sc
->cs
);
268 __put_user((uint16_t)0, &sc
->gs
);
269 __put_user((uint16_t)0, &sc
->fs
);
270 __put_user(env
->segs
[R_SS
].selector
, &sc
->ss
);
272 __put_user(mask
, &sc
->oldmask
);
273 __put_user(env
->cr
[2], &sc
->cr2
);
275 /* fpstate_addr must be 16 byte aligned for fxsave */
276 assert(!(fpstate_addr
& 0xf));
278 cpu_x86_fxsave(env
, fpstate_addr
);
279 __put_user(fpstate_addr
, &sc
->fpstate
);
284 * Determine which stack to use..
287 static inline abi_ulong
288 get_sigframe(struct target_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
292 /* Default to using normal stack */
293 esp
= get_sp_from_cpustate(env
);
295 esp
-= 128; /* this is the redzone */
298 /* This is the X/Open sanctioned signal stack switching. */
299 if (ka
->sa_flags
& TARGET_SA_ONSTACK
) {
300 esp
= target_sigsp(esp
, ka
);
302 #ifndef TARGET_X86_64
303 /* This is the legacy signal stack switching. */
304 if ((env
->segs
[R_SS
].selector
& 0xffff) != __USER_DS
&&
305 !(ka
->sa_flags
& TARGET_SA_RESTORER
) &&
307 esp
= (unsigned long) ka
->sa_restorer
;
312 #ifndef TARGET_X86_64
313 return (esp
- frame_size
) & -8ul;
315 return ((esp
- frame_size
) & (~15ul)) - 8;
319 #ifndef TARGET_X86_64
320 static void install_sigtramp(void *tramp
)
322 /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */
323 __put_user(0xb858, (uint16_t *)(tramp
+ 0));
324 __put_user(TARGET_NR_sigreturn
, (int32_t *)(tramp
+ 2));
325 __put_user(0x80cd, (uint16_t *)(tramp
+ 6));
328 static void install_rt_sigtramp(void *tramp
)
330 /* This is movl $syscall,%eax ; int $0x80 */
331 __put_user(0xb8, (uint8_t *)(tramp
+ 0));
332 __put_user(TARGET_NR_rt_sigreturn
, (int32_t *)(tramp
+ 1));
333 __put_user(0x80cd, (uint16_t *)(tramp
+ 5));
336 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
337 void setup_frame(int sig
, struct target_sigaction
*ka
,
338 target_sigset_t
*set
, CPUX86State
*env
)
340 abi_ulong frame_addr
;
341 struct sigframe
*frame
;
344 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
345 trace_user_setup_frame(env
, frame_addr
);
347 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
350 __put_user(sig
, &frame
->sig
);
352 setup_sigcontext(&frame
->sc
, &frame
->fpstate
, env
, set
->sig
[0],
353 frame_addr
+ offsetof(struct sigframe
, fpstate
));
355 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
356 __put_user(set
->sig
[i
], &frame
->extramask
[i
- 1]);
359 /* Set up to return from userspace. If provided, use a stub
360 already in userspace. */
361 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
362 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
364 /* This is no longer used, but is retained for ABI compatibility. */
365 install_sigtramp(frame
->retcode
);
366 __put_user(default_sigreturn
, &frame
->pretcode
);
369 /* Set up registers for signal handler */
370 env
->regs
[R_ESP
] = frame_addr
;
371 env
->eip
= ka
->_sa_handler
;
373 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
374 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
375 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
376 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
377 env
->eflags
&= ~TF_MASK
;
379 unlock_user_struct(frame
, frame_addr
, 1);
388 /* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */
389 void setup_rt_frame(int sig
, struct target_sigaction
*ka
,
390 target_siginfo_t
*info
,
391 target_sigset_t
*set
, CPUX86State
*env
)
393 abi_ulong frame_addr
;
394 #ifndef TARGET_X86_64
397 struct rt_sigframe
*frame
;
400 frame_addr
= get_sigframe(ka
, env
, sizeof(*frame
));
401 trace_user_setup_rt_frame(env
, frame_addr
);
403 if (!lock_user_struct(VERIFY_WRITE
, frame
, frame_addr
, 0))
406 /* These fields are only in rt_sigframe on 32 bit */
407 #ifndef TARGET_X86_64
408 __put_user(sig
, &frame
->sig
);
409 addr
= frame_addr
+ offsetof(struct rt_sigframe
, info
);
410 __put_user(addr
, &frame
->pinfo
);
411 addr
= frame_addr
+ offsetof(struct rt_sigframe
, uc
);
412 __put_user(addr
, &frame
->puc
);
414 if (ka
->sa_flags
& TARGET_SA_SIGINFO
) {
415 tswap_siginfo(&frame
->info
, info
);
418 /* Create the ucontext. */
419 __put_user(0, &frame
->uc
.tuc_flags
);
420 __put_user(0, &frame
->uc
.tuc_link
);
421 target_save_altstack(&frame
->uc
.tuc_stack
, env
);
422 setup_sigcontext(&frame
->uc
.tuc_mcontext
, &frame
->fpstate
, env
,
423 set
->sig
[0], frame_addr
+ offsetof(struct rt_sigframe
, fpstate
));
425 for(i
= 0; i
< TARGET_NSIG_WORDS
; i
++) {
426 __put_user(set
->sig
[i
], &frame
->uc
.tuc_sigmask
.sig
[i
]);
429 /* Set up to return from userspace. If provided, use a stub
430 already in userspace. */
431 if (ka
->sa_flags
& TARGET_SA_RESTORER
) {
432 __put_user(ka
->sa_restorer
, &frame
->pretcode
);
435 /* For x86_64, SA_RESTORER is required ABI. */
438 /* This is no longer used, but is retained for ABI compatibility. */
439 install_rt_sigtramp(frame
->retcode
);
440 __put_user(default_rt_sigreturn
, &frame
->pretcode
);
444 /* Set up registers for signal handler */
445 env
->regs
[R_ESP
] = frame_addr
;
446 env
->eip
= ka
->_sa_handler
;
448 #ifndef TARGET_X86_64
449 env
->regs
[R_EAX
] = sig
;
450 env
->regs
[R_EDX
] = frame_addr
+ offsetof(struct rt_sigframe
, info
);
451 env
->regs
[R_ECX
] = frame_addr
+ offsetof(struct rt_sigframe
, uc
);
453 env
->regs
[R_EAX
] = 0;
454 env
->regs
[R_EDI
] = sig
;
455 env
->regs
[R_ESI
] = frame_addr
+ offsetof(struct rt_sigframe
, info
);
456 env
->regs
[R_EDX
] = frame_addr
+ offsetof(struct rt_sigframe
, uc
);
459 cpu_x86_load_seg(env
, R_DS
, __USER_DS
);
460 cpu_x86_load_seg(env
, R_ES
, __USER_DS
);
461 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
462 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
463 env
->eflags
&= ~TF_MASK
;
465 unlock_user_struct(frame
, frame_addr
, 1);
474 restore_sigcontext(CPUX86State
*env
, struct target_sigcontext
*sc
)
476 unsigned int err
= 0;
477 abi_ulong fpstate_addr
;
478 unsigned int tmpflags
;
480 #ifndef TARGET_X86_64
481 cpu_x86_load_seg(env
, R_GS
, tswap16(sc
->gs
));
482 cpu_x86_load_seg(env
, R_FS
, tswap16(sc
->fs
));
483 cpu_x86_load_seg(env
, R_ES
, tswap16(sc
->es
));
484 cpu_x86_load_seg(env
, R_DS
, tswap16(sc
->ds
));
486 env
->regs
[R_EDI
] = tswapl(sc
->edi
);
487 env
->regs
[R_ESI
] = tswapl(sc
->esi
);
488 env
->regs
[R_EBP
] = tswapl(sc
->ebp
);
489 env
->regs
[R_ESP
] = tswapl(sc
->esp
);
490 env
->regs
[R_EBX
] = tswapl(sc
->ebx
);
491 env
->regs
[R_EDX
] = tswapl(sc
->edx
);
492 env
->regs
[R_ECX
] = tswapl(sc
->ecx
);
493 env
->regs
[R_EAX
] = tswapl(sc
->eax
);
495 env
->eip
= tswapl(sc
->eip
);
497 env
->regs
[8] = tswapl(sc
->r8
);
498 env
->regs
[9] = tswapl(sc
->r9
);
499 env
->regs
[10] = tswapl(sc
->r10
);
500 env
->regs
[11] = tswapl(sc
->r11
);
501 env
->regs
[12] = tswapl(sc
->r12
);
502 env
->regs
[13] = tswapl(sc
->r13
);
503 env
->regs
[14] = tswapl(sc
->r14
);
504 env
->regs
[15] = tswapl(sc
->r15
);
506 env
->regs
[R_EDI
] = tswapl(sc
->rdi
);
507 env
->regs
[R_ESI
] = tswapl(sc
->rsi
);
508 env
->regs
[R_EBP
] = tswapl(sc
->rbp
);
509 env
->regs
[R_EBX
] = tswapl(sc
->rbx
);
510 env
->regs
[R_EDX
] = tswapl(sc
->rdx
);
511 env
->regs
[R_EAX
] = tswapl(sc
->rax
);
512 env
->regs
[R_ECX
] = tswapl(sc
->rcx
);
513 env
->regs
[R_ESP
] = tswapl(sc
->rsp
);
515 env
->eip
= tswapl(sc
->rip
);
518 cpu_x86_load_seg(env
, R_CS
, lduw_p(&sc
->cs
) | 3);
519 cpu_x86_load_seg(env
, R_SS
, lduw_p(&sc
->ss
) | 3);
521 tmpflags
= tswapl(sc
->eflags
);
522 env
->eflags
= (env
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
523 // regs->orig_eax = -1; /* disable syscall checks */
525 fpstate_addr
= tswapl(sc
->fpstate
);
526 if (fpstate_addr
!= 0) {
527 if (!access_ok(env_cpu(env
), VERIFY_READ
, fpstate_addr
,
528 sizeof(struct target_fpstate
))) {
531 #ifndef TARGET_X86_64
532 cpu_x86_frstor(env
, fpstate_addr
, 1);
534 cpu_x86_fxrstor(env
, fpstate_addr
);
543 /* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */
544 #ifndef TARGET_X86_64
545 long do_sigreturn(CPUX86State
*env
)
547 struct sigframe
*frame
;
548 abi_ulong frame_addr
= env
->regs
[R_ESP
] - 8;
549 target_sigset_t target_set
;
553 trace_user_do_sigreturn(env
, frame_addr
);
554 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
556 /* set blocked signals */
557 __get_user(target_set
.sig
[0], &frame
->sc
.oldmask
);
558 for(i
= 1; i
< TARGET_NSIG_WORDS
; i
++) {
559 __get_user(target_set
.sig
[i
], &frame
->extramask
[i
- 1]);
562 target_to_host_sigset_internal(&set
, &target_set
);
565 /* restore registers */
566 if (restore_sigcontext(env
, &frame
->sc
))
568 unlock_user_struct(frame
, frame_addr
, 0);
569 return -QEMU_ESIGRETURN
;
572 unlock_user_struct(frame
, frame_addr
, 0);
573 force_sig(TARGET_SIGSEGV
);
574 return -QEMU_ESIGRETURN
;
578 long do_rt_sigreturn(CPUX86State
*env
)
580 abi_ulong frame_addr
;
581 struct rt_sigframe
*frame
;
584 frame_addr
= env
->regs
[R_ESP
] - sizeof(abi_ulong
);
585 trace_user_do_rt_sigreturn(env
, frame_addr
);
586 if (!lock_user_struct(VERIFY_READ
, frame
, frame_addr
, 1))
588 target_to_host_sigset(&set
, &frame
->uc
.tuc_sigmask
);
591 if (restore_sigcontext(env
, &frame
->uc
.tuc_mcontext
)) {
595 target_restore_altstack(&frame
->uc
.tuc_stack
, env
);
597 unlock_user_struct(frame
, frame_addr
, 0);
598 return -QEMU_ESIGRETURN
;
601 unlock_user_struct(frame
, frame_addr
, 0);
602 force_sig(TARGET_SIGSEGV
);
603 return -QEMU_ESIGRETURN
;
606 #ifndef TARGET_X86_64
607 void setup_sigtramp(abi_ulong sigtramp_page
)
609 uint16_t *tramp
= lock_user(VERIFY_WRITE
, sigtramp_page
, 2 * 8, 0);
610 assert(tramp
!= NULL
);
612 default_sigreturn
= sigtramp_page
;
613 install_sigtramp(tramp
);
615 default_rt_sigreturn
= sigtramp_page
+ 8;
616 install_rt_sigtramp(tramp
+ 8);
618 unlock_user(tramp
, sigtramp_page
, 2 * 8);