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 #include "user/tswap-target.h" 25 26 /* from the Linux kernel - /arch/x86/include/uapi/asm/sigcontext.h */ 27 28 #define TARGET_FP_XSTATE_MAGIC1 0x46505853U /* FPXS */ 29 #define TARGET_FP_XSTATE_MAGIC2 0x46505845U /* FPXE */ 30 #define TARGET_FP_XSTATE_MAGIC2_SIZE 4 31 32 struct target_fpreg { 33 uint16_t significand[4]; 34 uint16_t exponent; 35 }; 36 37 /* Legacy x87 fpu state format for FSAVE/FRESTOR. */ 38 struct target_fregs_state { 39 uint32_t cwd; 40 uint32_t swd; 41 uint32_t twd; 42 uint32_t fip; 43 uint32_t fcs; 44 uint32_t foo; 45 uint32_t fos; 46 struct target_fpreg st[8]; 47 48 /* Software status information [not touched by FSAVE]. */ 49 uint16_t status; 50 uint16_t magic; /* 0xffff: FPU data only, 0x0000: FXSR FPU data */ 51 }; 52 QEMU_BUILD_BUG_ON(sizeof(struct target_fregs_state) != 32 + 80); 53 54 struct target_fpx_sw_bytes { 55 uint32_t magic1; 56 uint32_t extended_size; 57 uint64_t xfeatures; 58 uint32_t xstate_size; 59 uint32_t reserved[7]; 60 }; 61 QEMU_BUILD_BUG_ON(sizeof(struct target_fpx_sw_bytes) != 12*4); 62 63 struct target_fpstate_32 { 64 struct target_fregs_state fpstate; 65 X86LegacyXSaveArea fxstate; 66 }; 67 68 /* 69 * For simplicity, setup_frame aligns struct target_fpstate_32 to 70 * 16 bytes, so ensure that the FXSAVE area is also aligned. 71 */ 72 QEMU_BUILD_BUG_ON(offsetof(struct target_fpstate_32, fxstate) & 15); 73 74 #ifndef TARGET_X86_64 75 # define target_fpstate target_fpstate_32 76 # define TARGET_FPSTATE_FXSAVE_OFFSET offsetof(struct target_fpstate_32, fxstate) 77 #else 78 # define target_fpstate X86LegacyXSaveArea 79 # define TARGET_FPSTATE_FXSAVE_OFFSET 0 80 #endif 81 82 struct target_sigcontext_32 { 83 uint16_t gs, __gsh; 84 uint16_t fs, __fsh; 85 uint16_t es, __esh; 86 uint16_t ds, __dsh; 87 uint32_t edi; 88 uint32_t esi; 89 uint32_t ebp; 90 uint32_t esp; 91 uint32_t ebx; 92 uint32_t edx; 93 uint32_t ecx; 94 uint32_t eax; 95 uint32_t trapno; 96 uint32_t err; 97 uint32_t eip; 98 uint16_t cs, __csh; 99 uint32_t eflags; 100 uint32_t esp_at_signal; 101 uint16_t ss, __ssh; 102 uint32_t fpstate; /* pointer */ 103 uint32_t oldmask; 104 uint32_t cr2; 105 }; 106 107 struct target_sigcontext_64 { 108 uint64_t r8; 109 uint64_t r9; 110 uint64_t r10; 111 uint64_t r11; 112 uint64_t r12; 113 uint64_t r13; 114 uint64_t r14; 115 uint64_t r15; 116 117 uint64_t rdi; 118 uint64_t rsi; 119 uint64_t rbp; 120 uint64_t rbx; 121 uint64_t rdx; 122 uint64_t rax; 123 uint64_t rcx; 124 uint64_t rsp; 125 uint64_t rip; 126 127 uint64_t eflags; 128 129 uint16_t cs; 130 uint16_t gs; 131 uint16_t fs; 132 uint16_t ss; 133 134 uint64_t err; 135 uint64_t trapno; 136 uint64_t oldmask; 137 uint64_t cr2; 138 139 uint64_t fpstate; /* pointer */ 140 uint64_t padding[8]; 141 }; 142 143 #ifndef TARGET_X86_64 144 # define target_sigcontext target_sigcontext_32 145 #else 146 # define target_sigcontext target_sigcontext_64 147 #endif 148 149 /* see Linux/include/uapi/asm-generic/ucontext.h */ 150 struct target_ucontext { 151 abi_ulong tuc_flags; 152 abi_ulong tuc_link; 153 target_stack_t tuc_stack; 154 struct target_sigcontext tuc_mcontext; 155 target_sigset_t tuc_sigmask; /* mask last for extensibility */ 156 }; 157 158 #ifndef TARGET_X86_64 159 struct sigframe { 160 abi_ulong pretcode; 161 int sig; 162 struct target_sigcontext sc; 163 /* 164 * The actual fpstate is placed after retcode[] below, to make 165 * room for the variable-sized xsave data. The older unused fpstate 166 * has to be kept to avoid changing the offset of extramask[], which 167 * is part of the ABI. 168 */ 169 struct target_fpstate fpstate_unused; 170 abi_ulong extramask[TARGET_NSIG_WORDS-1]; 171 char retcode[8]; 172 173 /* 174 * This field will be 16-byte aligned in memory. Applying QEMU_ALIGNED 175 * to it ensures that the base of the frame has an appropriate alignment 176 * too. 177 */ 178 struct target_fpstate fpstate QEMU_ALIGNED(8); 179 }; 180 #define TARGET_SIGFRAME_FXSAVE_OFFSET ( \ 181 offsetof(struct sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET) 182 183 struct rt_sigframe { 184 abi_ulong pretcode; 185 int sig; 186 abi_ulong pinfo; 187 abi_ulong puc; 188 struct target_siginfo info; 189 struct target_ucontext uc; 190 char retcode[8]; 191 struct target_fpstate fpstate QEMU_ALIGNED(8); 192 }; 193 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \ 194 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET) 195 196 /* 197 * Verify that vdso-asmoffset.h constants match. 198 */ 199 #include "i386/vdso-asmoffset.h" 200 201 QEMU_BUILD_BUG_ON(offsetof(struct sigframe, sc.eip) 202 != SIGFRAME_SIGCONTEXT_eip); 203 QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, uc.tuc_mcontext.eip) 204 != RT_SIGFRAME_SIGCONTEXT_eip); 205 206 #else 207 208 struct rt_sigframe { 209 abi_ulong pretcode; 210 struct target_ucontext uc; 211 struct target_siginfo info; 212 struct target_fpstate fpstate QEMU_ALIGNED(16); 213 }; 214 #define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \ 215 offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET) 216 #endif 217 218 /* 219 * Set up a signal frame. 220 */ 221 222 static void xsave_sigcontext(CPUX86State *env, X86LegacyXSaveArea *fxsave, 223 abi_ulong fxsave_addr) 224 { 225 struct target_fpx_sw_bytes *sw = (void *)&fxsave->sw_reserved; 226 227 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { 228 /* fxsave_addr must be 16 byte aligned for fxsave */ 229 assert(!(fxsave_addr & 0xf)); 230 231 cpu_x86_fxsave(env, fxsave_addr); 232 __put_user(0, &sw->magic1); 233 } else { 234 uint32_t xstate_size = xsave_area_size(env->xcr0, false); 235 236 /* 237 * extended_size is the offset from fpstate_addr to right after the end 238 * of the extended save states. On 32-bit that includes the legacy 239 * FSAVE area. 240 */ 241 uint32_t extended_size = TARGET_FPSTATE_FXSAVE_OFFSET 242 + xstate_size + TARGET_FP_XSTATE_MAGIC2_SIZE; 243 244 /* fxsave_addr must be 64 byte aligned for xsave */ 245 assert(!(fxsave_addr & 0x3f)); 246 247 /* Zero the header, XSAVE *adds* features to an existing save state. */ 248 memset(fxsave + 1, 0, sizeof(X86XSaveHeader)); 249 cpu_x86_xsave(env, fxsave_addr, -1); 250 __put_user(TARGET_FP_XSTATE_MAGIC1, &sw->magic1); 251 __put_user(extended_size, &sw->extended_size); 252 __put_user(env->xcr0, &sw->xfeatures); 253 __put_user(xstate_size, &sw->xstate_size); 254 __put_user(TARGET_FP_XSTATE_MAGIC2, 255 (uint32_t *)((void *)fxsave + xstate_size)); 256 } 257 } 258 259 static void setup_sigcontext(struct target_sigcontext *sc, 260 struct target_fpstate *fpstate, CPUX86State *env, abi_ulong mask, 261 abi_ulong fpstate_addr) 262 { 263 CPUState *cs = env_cpu(env); 264 #ifndef TARGET_X86_64 265 uint16_t magic; 266 267 /* already locked in setup_frame() */ 268 __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs); 269 __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs); 270 __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es); 271 __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds); 272 __put_user(env->regs[R_EDI], &sc->edi); 273 __put_user(env->regs[R_ESI], &sc->esi); 274 __put_user(env->regs[R_EBP], &sc->ebp); 275 __put_user(env->regs[R_ESP], &sc->esp); 276 __put_user(env->regs[R_EBX], &sc->ebx); 277 __put_user(env->regs[R_EDX], &sc->edx); 278 __put_user(env->regs[R_ECX], &sc->ecx); 279 __put_user(env->regs[R_EAX], &sc->eax); 280 __put_user(cs->exception_index, &sc->trapno); 281 __put_user(env->error_code, &sc->err); 282 __put_user(env->eip, &sc->eip); 283 __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs); 284 __put_user(env->eflags, &sc->eflags); 285 __put_user(env->regs[R_ESP], &sc->esp_at_signal); 286 __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss); 287 288 cpu_x86_fsave(env, fpstate_addr, 1); 289 fpstate->fpstate.status = fpstate->fpstate.swd; 290 if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) { 291 magic = 0xffff; 292 } else { 293 xsave_sigcontext(env, &fpstate->fxstate, 294 fpstate_addr + TARGET_FPSTATE_FXSAVE_OFFSET); 295 magic = 0; 296 } 297 __put_user(magic, &fpstate->fpstate.magic); 298 #else 299 __put_user(env->regs[R_EDI], &sc->rdi); 300 __put_user(env->regs[R_ESI], &sc->rsi); 301 __put_user(env->regs[R_EBP], &sc->rbp); 302 __put_user(env->regs[R_ESP], &sc->rsp); 303 __put_user(env->regs[R_EBX], &sc->rbx); 304 __put_user(env->regs[R_EDX], &sc->rdx); 305 __put_user(env->regs[R_ECX], &sc->rcx); 306 __put_user(env->regs[R_EAX], &sc->rax); 307 308 __put_user(env->regs[8], &sc->r8); 309 __put_user(env->regs[9], &sc->r9); 310 __put_user(env->regs[10], &sc->r10); 311 __put_user(env->regs[11], &sc->r11); 312 __put_user(env->regs[12], &sc->r12); 313 __put_user(env->regs[13], &sc->r13); 314 __put_user(env->regs[14], &sc->r14); 315 __put_user(env->regs[15], &sc->r15); 316 317 __put_user(cs->exception_index, &sc->trapno); 318 __put_user(env->error_code, &sc->err); 319 __put_user(env->eip, &sc->rip); 320 321 __put_user(env->eflags, &sc->eflags); 322 __put_user(env->segs[R_CS].selector, &sc->cs); 323 __put_user((uint16_t)0, &sc->gs); 324 __put_user((uint16_t)0, &sc->fs); 325 __put_user(env->segs[R_SS].selector, &sc->ss); 326 327 xsave_sigcontext(env, fpstate, fpstate_addr); 328 #endif 329 330 __put_user(fpstate_addr, &sc->fpstate); 331 332 /* non-iBCS2 extensions.. */ 333 __put_user(mask, &sc->oldmask); 334 __put_user(env->cr[2], &sc->cr2); 335 } 336 337 /* 338 * Determine which stack to use.. 339 */ 340 341 static inline abi_ulong 342 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t fxsave_offset) 343 { 344 unsigned long esp; 345 346 /* Default to using normal stack */ 347 esp = get_sp_from_cpustate(env); 348 #ifdef TARGET_X86_64 349 esp -= 128; /* this is the redzone */ 350 #endif 351 352 /* This is the X/Open sanctioned signal stack switching. */ 353 if (ka->sa_flags & TARGET_SA_ONSTACK) { 354 esp = target_sigsp(esp, ka); 355 } else { 356 #ifndef TARGET_X86_64 357 /* This is the legacy signal stack switching. */ 358 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && 359 !(ka->sa_flags & TARGET_SA_RESTORER) && 360 ka->sa_restorer) { 361 esp = (unsigned long) ka->sa_restorer; 362 } 363 #endif 364 } 365 366 if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) { 367 return (esp - (fxsave_offset + sizeof(X86LegacyXSaveArea))) & -8ul; 368 } else if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { 369 return ((esp - sizeof(X86LegacyXSaveArea)) & -16ul) - fxsave_offset; 370 } else { 371 size_t xstate_size = 372 xsave_area_size(env->xcr0, false) + TARGET_FP_XSTATE_MAGIC2_SIZE; 373 return ((esp - xstate_size) & -64ul) - fxsave_offset; 374 } 375 } 376 377 #ifndef TARGET_X86_64 378 static void install_sigtramp(void *tramp) 379 { 380 /* This is popl %eax ; movl $syscall,%eax ; int $0x80 */ 381 __put_user(0xb858, (uint16_t *)(tramp + 0)); 382 __put_user(TARGET_NR_sigreturn, (int32_t *)(tramp + 2)); 383 __put_user(0x80cd, (uint16_t *)(tramp + 6)); 384 } 385 386 static void install_rt_sigtramp(void *tramp) 387 { 388 /* This is movl $syscall,%eax ; int $0x80 */ 389 __put_user(0xb8, (uint8_t *)(tramp + 0)); 390 __put_user(TARGET_NR_rt_sigreturn, (int32_t *)(tramp + 1)); 391 __put_user(0x80cd, (uint16_t *)(tramp + 5)); 392 } 393 394 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */ 395 void setup_frame(int sig, struct target_sigaction *ka, 396 target_sigset_t *set, CPUX86State *env) 397 { 398 abi_ulong frame_addr; 399 struct sigframe *frame; 400 int i; 401 402 frame_addr = get_sigframe(ka, env, TARGET_SIGFRAME_FXSAVE_OFFSET); 403 trace_user_setup_frame(env, frame_addr); 404 405 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) 406 goto give_sigsegv; 407 408 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0], 409 frame_addr + offsetof(struct sigframe, fpstate)); 410 411 for (i = 1; i < TARGET_NSIG_WORDS; i++) { 412 __put_user(set->sig[i], &frame->extramask[i - 1]); 413 } 414 415 /* Set up to return from userspace. If provided, use a stub 416 already in userspace. */ 417 if (ka->sa_flags & TARGET_SA_RESTORER) { 418 __put_user(ka->sa_restorer, &frame->pretcode); 419 } else { 420 /* This is no longer used, but is retained for ABI compatibility. */ 421 install_sigtramp(frame->retcode); 422 __put_user(default_sigreturn, &frame->pretcode); 423 } 424 425 /* Set up registers for signal handler */ 426 env->regs[R_ESP] = frame_addr; 427 env->eip = ka->_sa_handler; 428 429 /* Store argument for both -mregparm=3 and standard. */ 430 env->regs[R_EAX] = sig; 431 __put_user(sig, &frame->sig); 432 /* The kernel clears EDX and ECX even though there is only one arg. */ 433 env->regs[R_EDX] = 0; 434 env->regs[R_ECX] = 0; 435 436 cpu_x86_load_seg(env, R_DS, __USER_DS); 437 cpu_x86_load_seg(env, R_ES, __USER_DS); 438 cpu_x86_load_seg(env, R_SS, __USER_DS); 439 cpu_x86_load_seg(env, R_CS, __USER_CS); 440 env->eflags &= ~TF_MASK; 441 442 unlock_user_struct(frame, frame_addr, 1); 443 444 return; 445 446 give_sigsegv: 447 force_sigsegv(sig); 448 } 449 #endif 450 451 /* compare linux/arch/x86/kernel/signal.c:setup_rt_frame() */ 452 void setup_rt_frame(int sig, struct target_sigaction *ka, 453 target_siginfo_t *info, 454 target_sigset_t *set, CPUX86State *env) 455 { 456 abi_ulong frame_addr; 457 struct rt_sigframe *frame; 458 int i; 459 460 frame_addr = get_sigframe(ka, env, TARGET_RT_SIGFRAME_FXSAVE_OFFSET); 461 trace_user_setup_rt_frame(env, frame_addr); 462 463 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) 464 goto give_sigsegv; 465 466 if (ka->sa_flags & TARGET_SA_SIGINFO) { 467 frame->info = *info; 468 } 469 470 /* Create the ucontext. */ 471 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) { 472 __put_user(1, &frame->uc.tuc_flags); 473 } else { 474 __put_user(0, &frame->uc.tuc_flags); 475 } 476 __put_user(0, &frame->uc.tuc_link); 477 target_save_altstack(&frame->uc.tuc_stack, env); 478 setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env, 479 set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate)); 480 481 for (i = 0; i < TARGET_NSIG_WORDS; i++) { 482 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); 483 } 484 485 /* Set up to return from userspace. If provided, use a stub 486 already in userspace. */ 487 if (ka->sa_flags & TARGET_SA_RESTORER) { 488 __put_user(ka->sa_restorer, &frame->pretcode); 489 } else { 490 #ifdef TARGET_X86_64 491 /* For x86_64, SA_RESTORER is required ABI. */ 492 goto give_sigsegv; 493 #else 494 /* This is no longer used, but is retained for ABI compatibility. */ 495 install_rt_sigtramp(frame->retcode); 496 __put_user(default_rt_sigreturn, &frame->pretcode); 497 #endif 498 } 499 500 /* Set up registers for signal handler */ 501 env->regs[R_ESP] = frame_addr; 502 env->eip = ka->_sa_handler; 503 504 #ifndef TARGET_X86_64 505 /* Store arguments for both -mregparm=3 and standard. */ 506 env->regs[R_EAX] = sig; 507 __put_user(sig, &frame->sig); 508 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, info); 509 __put_user(env->regs[R_EDX], &frame->pinfo); 510 env->regs[R_ECX] = frame_addr + offsetof(struct rt_sigframe, uc); 511 __put_user(env->regs[R_ECX], &frame->puc); 512 #else 513 env->regs[R_EAX] = 0; 514 env->regs[R_EDI] = sig; 515 env->regs[R_ESI] = frame_addr + offsetof(struct rt_sigframe, info); 516 env->regs[R_EDX] = frame_addr + offsetof(struct rt_sigframe, uc); 517 #endif 518 519 cpu_x86_load_seg(env, R_DS, __USER_DS); 520 cpu_x86_load_seg(env, R_ES, __USER_DS); 521 cpu_x86_load_seg(env, R_CS, __USER_CS); 522 cpu_x86_load_seg(env, R_SS, __USER_DS); 523 env->eflags &= ~TF_MASK; 524 525 unlock_user_struct(frame, frame_addr, 1); 526 527 return; 528 529 give_sigsegv: 530 force_sigsegv(sig); 531 } 532 533 static bool xrstor_sigcontext(CPUX86State *env, X86LegacyXSaveArea *fxsave, 534 abi_ulong fxsave_addr) 535 { 536 struct target_fpx_sw_bytes *sw = (void *)&fxsave->sw_reserved; 537 538 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) { 539 uint32_t magic1 = tswapl(sw->magic1); 540 uint32_t extended_size = tswapl(sw->extended_size); 541 uint32_t xstate_size = tswapl(sw->xstate_size); 542 uint32_t minimum_size = (TARGET_FPSTATE_FXSAVE_OFFSET 543 + TARGET_FP_XSTATE_MAGIC2_SIZE 544 + xstate_size); 545 uint32_t magic2; 546 547 /* Linux checks MAGIC2 using xstate_size, not extended_size. */ 548 if (magic1 == TARGET_FP_XSTATE_MAGIC1 549 && extended_size >= minimum_size) { 550 if (!access_ok(env_cpu(env), VERIFY_READ, fxsave_addr, 551 extended_size - TARGET_FPSTATE_FXSAVE_OFFSET)) { 552 return false; 553 } 554 magic2 = tswapl(*(uint32_t *)((void *)fxsave + xstate_size)); 555 if (magic2 == TARGET_FP_XSTATE_MAGIC2) { 556 cpu_x86_xrstor(env, fxsave_addr, -1); 557 return true; 558 } 559 } 560 /* fall through to fxrstor */ 561 } 562 563 cpu_x86_fxrstor(env, fxsave_addr); 564 return true; 565 } 566 567 static bool restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc) 568 { 569 abi_ulong fpstate_addr; 570 unsigned int tmpflags; 571 struct target_fpstate *fpstate; 572 bool ok; 573 574 #ifndef TARGET_X86_64 575 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs)); 576 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs)); 577 cpu_x86_load_seg(env, R_ES, tswap16(sc->es)); 578 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds)); 579 580 env->regs[R_EDI] = tswapl(sc->edi); 581 env->regs[R_ESI] = tswapl(sc->esi); 582 env->regs[R_EBP] = tswapl(sc->ebp); 583 env->regs[R_ESP] = tswapl(sc->esp); 584 env->regs[R_EBX] = tswapl(sc->ebx); 585 env->regs[R_EDX] = tswapl(sc->edx); 586 env->regs[R_ECX] = tswapl(sc->ecx); 587 env->regs[R_EAX] = tswapl(sc->eax); 588 589 env->eip = tswapl(sc->eip); 590 #else 591 env->regs[8] = tswapl(sc->r8); 592 env->regs[9] = tswapl(sc->r9); 593 env->regs[10] = tswapl(sc->r10); 594 env->regs[11] = tswapl(sc->r11); 595 env->regs[12] = tswapl(sc->r12); 596 env->regs[13] = tswapl(sc->r13); 597 env->regs[14] = tswapl(sc->r14); 598 env->regs[15] = tswapl(sc->r15); 599 600 env->regs[R_EDI] = tswapl(sc->rdi); 601 env->regs[R_ESI] = tswapl(sc->rsi); 602 env->regs[R_EBP] = tswapl(sc->rbp); 603 env->regs[R_EBX] = tswapl(sc->rbx); 604 env->regs[R_EDX] = tswapl(sc->rdx); 605 env->regs[R_EAX] = tswapl(sc->rax); 606 env->regs[R_ECX] = tswapl(sc->rcx); 607 env->regs[R_ESP] = tswapl(sc->rsp); 608 609 env->eip = tswapl(sc->rip); 610 #endif 611 612 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3); 613 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3); 614 615 tmpflags = tswapl(sc->eflags); 616 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); 617 // regs->orig_eax = -1; /* disable syscall checks */ 618 619 fpstate_addr = tswapl(sc->fpstate); 620 if (fpstate_addr == 0) { 621 return true; 622 } 623 if (!lock_user_struct(VERIFY_READ, fpstate, fpstate_addr, 624 sizeof(struct target_fpstate))) { 625 return false; 626 } 627 #ifndef TARGET_X86_64 628 if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) { 629 cpu_x86_frstor(env, fpstate_addr, 1); 630 ok = true; 631 } else { 632 ok = xrstor_sigcontext(env, &fpstate->fxstate, 633 fpstate_addr + TARGET_FPSTATE_FXSAVE_OFFSET); 634 } 635 #else 636 ok = xrstor_sigcontext(env, fpstate, fpstate_addr); 637 #endif 638 unlock_user_struct(fpstate, fpstate_addr, 0); 639 640 return ok; 641 } 642 643 /* Note: there is no sigreturn on x86_64, there is only rt_sigreturn */ 644 #ifndef TARGET_X86_64 645 long do_sigreturn(CPUX86State *env) 646 { 647 struct sigframe *frame; 648 abi_ulong frame_addr = env->regs[R_ESP] - 8; 649 target_sigset_t target_set; 650 sigset_t set; 651 int i; 652 653 trace_user_do_sigreturn(env, frame_addr); 654 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) 655 goto badframe; 656 /* set blocked signals */ 657 __get_user(target_set.sig[0], &frame->sc.oldmask); 658 for(i = 1; i < TARGET_NSIG_WORDS; i++) { 659 __get_user(target_set.sig[i], &frame->extramask[i - 1]); 660 } 661 662 target_to_host_sigset_internal(&set, &target_set); 663 set_sigmask(&set); 664 665 /* restore registers */ 666 if (!restore_sigcontext(env, &frame->sc)) { 667 goto badframe; 668 } 669 unlock_user_struct(frame, frame_addr, 0); 670 return -QEMU_ESIGRETURN; 671 672 badframe: 673 unlock_user_struct(frame, frame_addr, 0); 674 force_sig(TARGET_SIGSEGV); 675 return -QEMU_ESIGRETURN; 676 } 677 #endif 678 679 long do_rt_sigreturn(CPUX86State *env) 680 { 681 abi_ulong frame_addr; 682 struct rt_sigframe *frame; 683 sigset_t set; 684 685 frame_addr = env->regs[R_ESP] - sizeof(abi_ulong); 686 trace_user_do_rt_sigreturn(env, frame_addr); 687 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) 688 goto badframe; 689 target_to_host_sigset(&set, &frame->uc.tuc_sigmask); 690 set_sigmask(&set); 691 692 if (!restore_sigcontext(env, &frame->uc.tuc_mcontext)) { 693 goto badframe; 694 } 695 696 target_restore_altstack(&frame->uc.tuc_stack, env); 697 698 unlock_user_struct(frame, frame_addr, 0); 699 return -QEMU_ESIGRETURN; 700 701 badframe: 702 unlock_user_struct(frame, frame_addr, 0); 703 force_sig(TARGET_SIGSEGV); 704 return -QEMU_ESIGRETURN; 705 } 706 707 #ifndef TARGET_X86_64 708 void setup_sigtramp(abi_ulong sigtramp_page) 709 { 710 uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0); 711 assert(tramp != NULL); 712 713 default_sigreturn = sigtramp_page; 714 install_sigtramp(tramp); 715 716 default_rt_sigreturn = sigtramp_page + 8; 717 install_rt_sigtramp(tramp + 8); 718 719 unlock_user(tramp, sigtramp_page, 2 * 8); 720 } 721 #endif 722