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