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