signal.c (17079B)
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 "user-internals.h" 22#include "signal-common.h" 23#include "linux-user/trace.h" 24 25/* from the Linux kernel - /arch/x86/include/uapi/asm/sigcontext.h */ 26 27struct target_fpreg { 28 uint16_t significand[4]; 29 uint16_t exponent; 30}; 31 32struct target_fpxreg { 33 uint16_t significand[4]; 34 uint16_t exponent; 35 uint16_t padding[3]; 36}; 37 38struct target_xmmreg { 39 uint32_t element[4]; 40}; 41 42struct target_fpstate_32 { 43 /* Regular FPU environment */ 44 uint32_t cw; 45 uint32_t sw; 46 uint32_t tag; 47 uint32_t ipoff; 48 uint32_t cssel; 49 uint32_t dataoff; 50 uint32_t datasel; 51 struct target_fpreg st[8]; 52 uint16_t status; 53 uint16_t magic; /* 0xffff = regular FPU data only */ 54 55 /* FXSR FPU environment */ 56 uint32_t _fxsr_env[6]; /* FXSR FPU env is ignored */ 57 uint32_t mxcsr; 58 uint32_t reserved; 59 struct target_fpxreg fxsr_st[8]; /* FXSR FPU reg data is ignored */ 60 struct target_xmmreg xmm[8]; 61 uint32_t padding[56]; 62}; 63 64struct target_fpstate_64 { 65 /* FXSAVE format */ 66 uint16_t cw; 67 uint16_t sw; 68 uint16_t twd; 69 uint16_t fop; 70 uint64_t rip; 71 uint64_t rdp; 72 uint32_t mxcsr; 73 uint32_t mxcsr_mask; 74 uint32_t st_space[32]; 75 uint32_t xmm_space[64]; 76 uint32_t reserved[24]; 77}; 78 79#ifndef TARGET_X86_64 80# define target_fpstate target_fpstate_32 81#else 82# define target_fpstate target_fpstate_64 83#endif 84 85struct target_sigcontext_32 { 86 uint16_t gs, __gsh; 87 uint16_t fs, __fsh; 88 uint16_t es, __esh; 89 uint16_t ds, __dsh; 90 uint32_t edi; 91 uint32_t esi; 92 uint32_t ebp; 93 uint32_t esp; 94 uint32_t ebx; 95 uint32_t edx; 96 uint32_t ecx; 97 uint32_t eax; 98 uint32_t trapno; 99 uint32_t err; 100 uint32_t eip; 101 uint16_t cs, __csh; 102 uint32_t eflags; 103 uint32_t esp_at_signal; 104 uint16_t ss, __ssh; 105 uint32_t fpstate; /* pointer */ 106 uint32_t oldmask; 107 uint32_t cr2; 108}; 109 110struct target_sigcontext_64 { 111 uint64_t r8; 112 uint64_t r9; 113 uint64_t r10; 114 uint64_t r11; 115 uint64_t r12; 116 uint64_t r13; 117 uint64_t r14; 118 uint64_t r15; 119 120 uint64_t rdi; 121 uint64_t rsi; 122 uint64_t rbp; 123 uint64_t rbx; 124 uint64_t rdx; 125 uint64_t rax; 126 uint64_t rcx; 127 uint64_t rsp; 128 uint64_t rip; 129 130 uint64_t eflags; 131 132 uint16_t cs; 133 uint16_t gs; 134 uint16_t fs; 135 uint16_t ss; 136 137 uint64_t err; 138 uint64_t trapno; 139 uint64_t oldmask; 140 uint64_t cr2; 141 142 uint64_t fpstate; /* pointer */ 143 uint64_t padding[8]; 144}; 145 146#ifndef TARGET_X86_64 147# define target_sigcontext target_sigcontext_32 148#else 149# define target_sigcontext target_sigcontext_64 150#endif 151 152/* see Linux/include/uapi/asm-generic/ucontext.h */ 153struct target_ucontext { 154 abi_ulong tuc_flags; 155 abi_ulong tuc_link; 156 target_stack_t tuc_stack; 157 struct target_sigcontext tuc_mcontext; 158 target_sigset_t tuc_sigmask; /* mask last for extensibility */ 159}; 160 161#ifndef TARGET_X86_64 162struct sigframe { 163 abi_ulong pretcode; 164 int sig; 165 struct target_sigcontext sc; 166 struct target_fpstate fpstate; 167 abi_ulong extramask[TARGET_NSIG_WORDS-1]; 168 char retcode[8]; 169}; 170 171struct rt_sigframe { 172 abi_ulong pretcode; 173 int sig; 174 abi_ulong pinfo; 175 abi_ulong puc; 176 struct target_siginfo info; 177 struct target_ucontext uc; 178 struct target_fpstate fpstate; 179 char retcode[8]; 180}; 181 182#else 183 184struct rt_sigframe { 185 abi_ulong pretcode; 186 struct target_ucontext uc; 187 struct target_siginfo info; 188 struct target_fpstate fpstate; 189}; 190 191#endif 192 193/* 194 * Set up a signal frame. 195 */ 196 197/* XXX: save x87 state */ 198static void setup_sigcontext(struct target_sigcontext *sc, 199 struct target_fpstate *fpstate, CPUX86State *env, abi_ulong mask, 200 abi_ulong fpstate_addr) 201{ 202 CPUState *cs = env_cpu(env); 203#ifndef TARGET_X86_64 204 uint16_t magic; 205 206 /* already locked in setup_frame() */ 207 __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs); 208 __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs); 209 __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es); 210 __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds); 211 __put_user(env->regs[R_EDI], &sc->edi); 212 __put_user(env->regs[R_ESI], &sc->esi); 213 __put_user(env->regs[R_EBP], &sc->ebp); 214 __put_user(env->regs[R_ESP], &sc->esp); 215 __put_user(env->regs[R_EBX], &sc->ebx); 216 __put_user(env->regs[R_EDX], &sc->edx); 217 __put_user(env->regs[R_ECX], &sc->ecx); 218 __put_user(env->regs[R_EAX], &sc->eax); 219 __put_user(cs->exception_index, &sc->trapno); 220 __put_user(env->error_code, &sc->err); 221 __put_user(env->eip, &sc->eip); 222 __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs); 223 __put_user(env->eflags, &sc->eflags); 224 __put_user(env->regs[R_ESP], &sc->esp_at_signal); 225 __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss); 226 227 cpu_x86_fsave(env, fpstate_addr, 1); 228 fpstate->status = fpstate->sw; 229 magic = 0xffff; 230 __put_user(magic, &fpstate->magic); 231 __put_user(fpstate_addr, &sc->fpstate); 232 233 /* non-iBCS2 extensions.. */ 234 __put_user(mask, &sc->oldmask); 235 __put_user(env->cr[2], &sc->cr2); 236#else 237 __put_user(env->regs[R_EDI], &sc->rdi); 238 __put_user(env->regs[R_ESI], &sc->rsi); 239 __put_user(env->regs[R_EBP], &sc->rbp); 240 __put_user(env->regs[R_ESP], &sc->rsp); 241 __put_user(env->regs[R_EBX], &sc->rbx); 242 __put_user(env->regs[R_EDX], &sc->rdx); 243 __put_user(env->regs[R_ECX], &sc->rcx); 244 __put_user(env->regs[R_EAX], &sc->rax); 245 246 __put_user(env->regs[8], &sc->r8); 247 __put_user(env->regs[9], &sc->r9); 248 __put_user(env->regs[10], &sc->r10); 249 __put_user(env->regs[11], &sc->r11); 250 __put_user(env->regs[12], &sc->r12); 251 __put_user(env->regs[13], &sc->r13); 252 __put_user(env->regs[14], &sc->r14); 253 __put_user(env->regs[15], &sc->r15); 254 255 __put_user(cs->exception_index, &sc->trapno); 256 __put_user(env->error_code, &sc->err); 257 __put_user(env->eip, &sc->rip); 258 259 __put_user(env->eflags, &sc->eflags); 260 __put_user(env->segs[R_CS].selector, &sc->cs); 261 __put_user((uint16_t)0, &sc->gs); 262 __put_user((uint16_t)0, &sc->fs); 263 __put_user(env->segs[R_SS].selector, &sc->ss); 264 265 __put_user(mask, &sc->oldmask); 266 __put_user(env->cr[2], &sc->cr2); 267 268 /* fpstate_addr must be 16 byte aligned for fxsave */ 269 assert(!(fpstate_addr & 0xf)); 270 271 cpu_x86_fxsave(env, fpstate_addr); 272 __put_user(fpstate_addr, &sc->fpstate); 273#endif 274} 275 276/* 277 * Determine which stack to use.. 278 */ 279 280static inline abi_ulong 281get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size) 282{ 283 unsigned long esp; 284 285 /* Default to using normal stack */ 286 esp = get_sp_from_cpustate(env); 287#ifdef TARGET_X86_64 288 esp -= 128; /* this is the redzone */ 289#endif 290 291 /* This is the X/Open sanctioned signal stack switching. */ 292 if (ka->sa_flags & TARGET_SA_ONSTACK) { 293 esp = target_sigsp(esp, ka); 294 } else { 295#ifndef TARGET_X86_64 296 /* This is the legacy signal stack switching. */ 297 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && 298 !(ka->sa_flags & TARGET_SA_RESTORER) && 299 ka->sa_restorer) { 300 esp = (unsigned long) ka->sa_restorer; 301 } 302#endif 303 } 304 305#ifndef TARGET_X86_64 306 return (esp - frame_size) & -8ul; 307#else 308 return ((esp - frame_size) & (~15ul)) - 8; 309#endif 310} 311 312#ifndef TARGET_X86_64 313static void install_sigtramp(void *tramp) 314{ 315 /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */ 316 __put_user(0xb858, (uint16_t *)(tramp + 0)); 317 __put_user(TARGET_NR_sigreturn, (int32_t *)(tramp + 2)); 318 __put_user(0x80cd, (uint16_t *)(tramp + 6)); 319} 320 321static void install_rt_sigtramp(void *tramp) 322{ 323 /* This is movl $syscall,%eax ; int $0x80 */ 324 __put_user(0xb8, (uint8_t *)(tramp + 0)); 325 __put_user(TARGET_NR_rt_sigreturn, (int32_t *)(tramp + 1)); 326 __put_user(0x80cd, (uint16_t *)(tramp + 5)); 327} 328 329/* compare linux/arch/i386/kernel/signal.c:setup_frame() */ 330void setup_frame(int sig, struct target_sigaction *ka, 331 target_sigset_t *set, CPUX86State *env) 332{ 333 abi_ulong frame_addr; 334 struct sigframe *frame; 335 int i; 336 337 frame_addr = get_sigframe(ka, env, sizeof(*frame)); 338 trace_user_setup_frame(env, frame_addr); 339 340 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) 341 goto give_sigsegv; 342 343 __put_user(sig, &frame->sig); 344 345 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0], 346 frame_addr + offsetof(struct sigframe, fpstate)); 347 348 for(i = 1; i < TARGET_NSIG_WORDS; i++) { 349 __put_user(set->sig[i], &frame->extramask[i - 1]); 350 } 351 352 /* Set up to return from userspace. If provided, use a stub 353 already in userspace. */ 354 if (ka->sa_flags & TARGET_SA_RESTORER) { 355 __put_user(ka->sa_restorer, &frame->pretcode); 356 } else { 357 /* This is no longer used, but is retained for ABI compatibility. */ 358 install_sigtramp(frame->retcode); 359 __put_user(default_sigreturn, &frame->pretcode); 360 } 361 362 /* Set up registers for signal handler */ 363 env->regs[R_ESP] = frame_addr; 364 env->eip = ka->_sa_handler; 365 366 cpu_x86_load_seg(env, R_DS, __USER_DS); 367 cpu_x86_load_seg(env, R_ES, __USER_DS); 368 cpu_x86_load_seg(env, R_SS, __USER_DS); 369 cpu_x86_load_seg(env, R_CS, __USER_CS); 370 env->eflags &= ~TF_MASK; 371 372 unlock_user_struct(frame, frame_addr, 1); 373 374 return; 375 376give_sigsegv: 377 force_sigsegv(sig); 378} 379#endif 380 381/* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */ 382void setup_rt_frame(int sig, struct target_sigaction *ka, 383 target_siginfo_t *info, 384 target_sigset_t *set, CPUX86State *env) 385{ 386 abi_ulong frame_addr; 387#ifndef TARGET_X86_64 388 abi_ulong addr; 389#endif 390 struct rt_sigframe *frame; 391 int i; 392 393 frame_addr = get_sigframe(ka, env, sizeof(*frame)); 394 trace_user_setup_rt_frame(env, frame_addr); 395 396 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) 397 goto give_sigsegv; 398 399 /* These fields are only in rt_sigframe on 32 bit */ 400#ifndef TARGET_X86_64 401 __put_user(sig, &frame->sig); 402 addr = frame_addr + offsetof(struct rt_sigframe, info); 403 __put_user(addr, &frame->pinfo); 404 addr = frame_addr + offsetof(struct rt_sigframe, uc); 405 __put_user(addr, &frame->puc); 406#endif 407 if (ka->sa_flags & TARGET_SA_SIGINFO) { 408 tswap_siginfo(&frame->info, info); 409 } 410 411 /* Create the ucontext. */ 412 __put_user(0, &frame->uc.tuc_flags); 413 __put_user(0, &frame->uc.tuc_link); 414 target_save_altstack(&frame->uc.tuc_stack, env); 415 setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env, 416 set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate)); 417 418 for(i = 0; i < TARGET_NSIG_WORDS; i++) { 419 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); 420 } 421 422 /* Set up to return from userspace. If provided, use a stub 423 already in userspace. */ 424 if (ka->sa_flags & TARGET_SA_RESTORER) { 425 __put_user(ka->sa_restorer, &frame->pretcode); 426 } else { 427#ifdef TARGET_X86_64 428 /* For x86_64, SA_RESTORER is required ABI. */ 429 goto give_sigsegv; 430#else 431 /* This is no longer used, but is retained for ABI compatibility. */ 432 install_rt_sigtramp(frame->retcode); 433 __put_user(default_rt_sigreturn, &frame->pretcode); 434#endif 435 } 436 437 /* Set up registers for signal handler */ 438 env->regs[R_ESP] = frame_addr; 439 env->eip = ka->_sa_handler; 440 441#ifndef TARGET_X86_64 442 env->regs[R_EAX] = sig; 443 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, info); 444 env->regs[R_ECX] = frame_addr + offsetof(struct rt_sigframe, uc); 445#else 446 env->regs[R_EAX] = 0; 447 env->regs[R_EDI] = sig; 448 env->regs[R_ESI] = frame_addr + offsetof(struct rt_sigframe, info); 449 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, uc); 450#endif 451 452 cpu_x86_load_seg(env, R_DS, __USER_DS); 453 cpu_x86_load_seg(env, R_ES, __USER_DS); 454 cpu_x86_load_seg(env, R_CS, __USER_CS); 455 cpu_x86_load_seg(env, R_SS, __USER_DS); 456 env->eflags &= ~TF_MASK; 457 458 unlock_user_struct(frame, frame_addr, 1); 459 460 return; 461 462give_sigsegv: 463 force_sigsegv(sig); 464} 465 466static int 467restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc) 468{ 469 unsigned int err = 0; 470 abi_ulong fpstate_addr; 471 unsigned int tmpflags; 472 473#ifndef TARGET_X86_64 474 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs)); 475 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs)); 476 cpu_x86_load_seg(env, R_ES, tswap16(sc->es)); 477 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds)); 478 479 env->regs[R_EDI] = tswapl(sc->edi); 480 env->regs[R_ESI] = tswapl(sc->esi); 481 env->regs[R_EBP] = tswapl(sc->ebp); 482 env->regs[R_ESP] = tswapl(sc->esp); 483 env->regs[R_EBX] = tswapl(sc->ebx); 484 env->regs[R_EDX] = tswapl(sc->edx); 485 env->regs[R_ECX] = tswapl(sc->ecx); 486 env->regs[R_EAX] = tswapl(sc->eax); 487 488 env->eip = tswapl(sc->eip); 489#else 490 env->regs[8] = tswapl(sc->r8); 491 env->regs[9] = tswapl(sc->r9); 492 env->regs[10] = tswapl(sc->r10); 493 env->regs[11] = tswapl(sc->r11); 494 env->regs[12] = tswapl(sc->r12); 495 env->regs[13] = tswapl(sc->r13); 496 env->regs[14] = tswapl(sc->r14); 497 env->regs[15] = tswapl(sc->r15); 498 499 env->regs[R_EDI] = tswapl(sc->rdi); 500 env->regs[R_ESI] = tswapl(sc->rsi); 501 env->regs[R_EBP] = tswapl(sc->rbp); 502 env->regs[R_EBX] = tswapl(sc->rbx); 503 env->regs[R_EDX] = tswapl(sc->rdx); 504 env->regs[R_EAX] = tswapl(sc->rax); 505 env->regs[R_ECX] = tswapl(sc->rcx); 506 env->regs[R_ESP] = tswapl(sc->rsp); 507 508 env->eip = tswapl(sc->rip); 509#endif 510 511 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3); 512 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3); 513 514 tmpflags = tswapl(sc->eflags); 515 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); 516 // regs->orig_eax = -1; /* disable syscall checks */ 517 518 fpstate_addr = tswapl(sc->fpstate); 519 if (fpstate_addr != 0) { 520 if (!access_ok(env_cpu(env), VERIFY_READ, fpstate_addr, 521 sizeof(struct target_fpstate))) { 522 goto badframe; 523 } 524#ifndef TARGET_X86_64 525 cpu_x86_frstor(env, fpstate_addr, 1); 526#else 527 cpu_x86_fxrstor(env, fpstate_addr); 528#endif 529 } 530 531 return err; 532badframe: 533 return 1; 534} 535 536/* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */ 537#ifndef TARGET_X86_64 538long do_sigreturn(CPUX86State *env) 539{ 540 struct sigframe *frame; 541 abi_ulong frame_addr = env->regs[R_ESP] - 8; 542 target_sigset_t target_set; 543 sigset_t set; 544 int i; 545 546 trace_user_do_sigreturn(env, frame_addr); 547 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) 548 goto badframe; 549 /* set blocked signals */ 550 __get_user(target_set.sig[0], &frame->sc.oldmask); 551 for(i = 1; i < TARGET_NSIG_WORDS; i++) { 552 __get_user(target_set.sig[i], &frame->extramask[i - 1]); 553 } 554 555 target_to_host_sigset_internal(&set, &target_set); 556 set_sigmask(&set); 557 558 /* restore registers */ 559 if (restore_sigcontext(env, &frame->sc)) 560 goto badframe; 561 unlock_user_struct(frame, frame_addr, 0); 562 return -TARGET_QEMU_ESIGRETURN; 563 564badframe: 565 unlock_user_struct(frame, frame_addr, 0); 566 force_sig(TARGET_SIGSEGV); 567 return -TARGET_QEMU_ESIGRETURN; 568} 569#endif 570 571long do_rt_sigreturn(CPUX86State *env) 572{ 573 abi_ulong frame_addr; 574 struct rt_sigframe *frame; 575 sigset_t set; 576 577 frame_addr = env->regs[R_ESP] - sizeof(abi_ulong); 578 trace_user_do_rt_sigreturn(env, frame_addr); 579 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) 580 goto badframe; 581 target_to_host_sigset(&set, &frame->uc.tuc_sigmask); 582 set_sigmask(&set); 583 584 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) { 585 goto badframe; 586 } 587 588 target_restore_altstack(&frame->uc.tuc_stack, env); 589 590 unlock_user_struct(frame, frame_addr, 0); 591 return -TARGET_QEMU_ESIGRETURN; 592 593badframe: 594 unlock_user_struct(frame, frame_addr, 0); 595 force_sig(TARGET_SIGSEGV); 596 return -TARGET_QEMU_ESIGRETURN; 597} 598 599#ifndef TARGET_X86_64 600void setup_sigtramp(abi_ulong sigtramp_page) 601{ 602 uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0); 603 assert(tramp != NULL); 604 605 default_sigreturn = sigtramp_page; 606 install_sigtramp(tramp); 607 608 default_rt_sigreturn = sigtramp_page + 8; 609 install_rt_sigtramp(tramp + 8); 610 611 unlock_user(tramp, sigtramp_page, 2 * 8); 612} 613#endif