Commit a04e134ad1f4271bea2c7b7649b21e35ded91005
1 parent
e3b98085
linux-user sigaltstack() syscall, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3252 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
20 changed files
with
425 additions
and
43 deletions
linux-user/alpha/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 4096 | ||
| 22 | +#define TARGET_SIGSTKSZ 16384 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/arm/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/i386/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/m68k/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/mips/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_ulong ss_size; | ||
| 11 | + target_long ss_flags; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/ppc/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/ppc64/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/qemu.h
| @@ -9,6 +9,7 @@ | @@ -9,6 +9,7 @@ | ||
| 9 | 9 | ||
| 10 | #include "cpu.h" | 10 | #include "cpu.h" |
| 11 | #include "syscall.h" | 11 | #include "syscall.h" |
| 12 | +#include "target_signal.h" | ||
| 12 | #include "gdbstub.h" | 13 | #include "gdbstub.h" |
| 13 | 14 | ||
| 14 | /* This struct is used to hold certain information about the image. | 15 | /* This struct is used to hold certain information about the image. |
| @@ -149,6 +150,9 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | @@ -149,6 +150,9 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | ||
| 149 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); | 150 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); |
| 150 | long do_sigreturn(CPUState *env); | 151 | long do_sigreturn(CPUState *env); |
| 151 | long do_rt_sigreturn(CPUState *env); | 152 | long do_rt_sigreturn(CPUState *env); |
| 153 | +int do_sigaltstack(const struct target_sigaltstack *uss, | ||
| 154 | + struct target_sigaltstack *uoss, | ||
| 155 | + target_ulong sp); | ||
| 152 | 156 | ||
| 153 | #ifdef TARGET_I386 | 157 | #ifdef TARGET_I386 |
| 154 | /* vm86.c */ | 158 | /* vm86.c */ |
linux-user/sh4/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/signal.c
| @@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
| 26 | #include <errno.h> | 26 | #include <errno.h> |
| 27 | #include <sys/ucontext.h> | 27 | #include <sys/ucontext.h> |
| 28 | 28 | ||
| 29 | +#include "target_signal.h" | ||
| 29 | #include "qemu.h" | 30 | #include "qemu.h" |
| 30 | 31 | ||
| 31 | //#define DEBUG_SIGNAL | 32 | //#define DEBUG_SIGNAL |
| @@ -45,6 +46,12 @@ struct emulated_sigaction { | @@ -45,6 +46,12 @@ struct emulated_sigaction { | ||
| 45 | first signal, we put it here */ | 46 | first signal, we put it here */ |
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 49 | +struct target_sigaltstack target_sigaltstack_used = { | ||
| 50 | + .ss_sp = 0, | ||
| 51 | + .ss_size = 0, | ||
| 52 | + .ss_flags = TARGET_SS_DISABLE, | ||
| 53 | +}; | ||
| 54 | + | ||
| 48 | static struct emulated_sigaction sigact_table[TARGET_NSIG]; | 55 | static struct emulated_sigaction sigact_table[TARGET_NSIG]; |
| 49 | static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ | 56 | static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ |
| 50 | static struct sigqueue *first_free; /* first free siginfo queue entry */ | 57 | static struct sigqueue *first_free; /* first free siginfo queue entry */ |
| @@ -92,6 +99,18 @@ static uint8_t host_to_target_signal_table[65] = { | @@ -92,6 +99,18 @@ static uint8_t host_to_target_signal_table[65] = { | ||
| 92 | }; | 99 | }; |
| 93 | static uint8_t target_to_host_signal_table[65]; | 100 | static uint8_t target_to_host_signal_table[65]; |
| 94 | 101 | ||
| 102 | +static inline int on_sig_stack(unsigned long sp) | ||
| 103 | +{ | ||
| 104 | + return (sp - target_sigaltstack_used.ss_sp | ||
| 105 | + < target_sigaltstack_used.ss_size); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +static inline int sas_ss_flags(unsigned long sp) | ||
| 109 | +{ | ||
| 110 | + return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE | ||
| 111 | + : on_sig_stack(sp) ? SS_ONSTACK : 0); | ||
| 112 | +} | ||
| 113 | + | ||
| 95 | static inline int host_to_target_signal(int sig) | 114 | static inline int host_to_target_signal(int sig) |
| 96 | { | 115 | { |
| 97 | return host_to_target_signal_table[sig]; | 116 | return host_to_target_signal_table[sig]; |
| @@ -419,6 +438,67 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | @@ -419,6 +438,67 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | ||
| 419 | } | 438 | } |
| 420 | } | 439 | } |
| 421 | 440 | ||
| 441 | +int do_sigaltstack(const struct target_sigaltstack *uss, | ||
| 442 | + struct target_sigaltstack *uoss, | ||
| 443 | + target_ulong sp) | ||
| 444 | +{ | ||
| 445 | + int ret; | ||
| 446 | + struct target_sigaltstack oss; | ||
| 447 | + | ||
| 448 | + /* XXX: test errors */ | ||
| 449 | + if(uoss) | ||
| 450 | + { | ||
| 451 | + __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp); | ||
| 452 | + __put_user(target_sigaltstack_used.ss_size, &oss.ss_size); | ||
| 453 | + __put_user(sas_ss_flags(sp), &oss.ss_flags); | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + if(uss) | ||
| 457 | + { | ||
| 458 | + struct target_sigaltstack ss; | ||
| 459 | + | ||
| 460 | + ret = -EFAULT; | ||
| 461 | + if (!access_ok(VERIFY_READ, uss, sizeof(*uss)) | ||
| 462 | + || __get_user(ss.ss_sp, &uss->ss_sp) | ||
| 463 | + || __get_user(ss.ss_size, &uss->ss_size) | ||
| 464 | + || __get_user(ss.ss_flags, &uss->ss_flags)) | ||
| 465 | + goto out; | ||
| 466 | + | ||
| 467 | + ret = -EPERM; | ||
| 468 | + if (on_sig_stack(sp)) | ||
| 469 | + goto out; | ||
| 470 | + | ||
| 471 | + ret = -EINVAL; | ||
| 472 | + if (ss.ss_flags != TARGET_SS_DISABLE | ||
| 473 | + && ss.ss_flags != TARGET_SS_ONSTACK | ||
| 474 | + && ss.ss_flags != 0) | ||
| 475 | + goto out; | ||
| 476 | + | ||
| 477 | + if (ss.ss_flags == TARGET_SS_DISABLE) { | ||
| 478 | + ss.ss_size = 0; | ||
| 479 | + ss.ss_sp = 0; | ||
| 480 | + } else { | ||
| 481 | + ret = -ENOMEM; | ||
| 482 | + if (ss.ss_size < MINSIGSTKSZ) | ||
| 483 | + goto out; | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + target_sigaltstack_used.ss_sp = ss.ss_sp; | ||
| 487 | + target_sigaltstack_used.ss_size = ss.ss_size; | ||
| 488 | + } | ||
| 489 | + | ||
| 490 | + if (uoss) { | ||
| 491 | + ret = -EFAULT; | ||
| 492 | + if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss))) | ||
| 493 | + goto out; | ||
| 494 | + memcpy(uoss, &oss, sizeof(oss)); | ||
| 495 | + } | ||
| 496 | + | ||
| 497 | + ret = 0; | ||
| 498 | +out: | ||
| 499 | + return ret; | ||
| 500 | +} | ||
| 501 | + | ||
| 422 | int do_sigaction(int sig, const struct target_sigaction *act, | 502 | int do_sigaction(int sig, const struct target_sigaction *act, |
| 423 | struct target_sigaction *oact) | 503 | struct target_sigaction *oact) |
| 424 | { | 504 | { |
| @@ -551,12 +631,6 @@ struct target_sigcontext { | @@ -551,12 +631,6 @@ struct target_sigcontext { | ||
| 551 | target_ulong cr2; | 631 | target_ulong cr2; |
| 552 | }; | 632 | }; |
| 553 | 633 | ||
| 554 | -typedef struct target_sigaltstack { | ||
| 555 | - target_ulong ss_sp; | ||
| 556 | - int ss_flags; | ||
| 557 | - target_ulong ss_size; | ||
| 558 | -} target_stack_t; | ||
| 559 | - | ||
| 560 | struct target_ucontext { | 634 | struct target_ucontext { |
| 561 | target_ulong tuc_flags; | 635 | target_ulong tuc_flags; |
| 562 | target_ulong tuc_link; | 636 | target_ulong tuc_link; |
| @@ -640,16 +714,14 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) | @@ -640,16 +714,14 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) | ||
| 640 | 714 | ||
| 641 | /* Default to using normal stack */ | 715 | /* Default to using normal stack */ |
| 642 | esp = env->regs[R_ESP]; | 716 | esp = env->regs[R_ESP]; |
| 643 | -#if 0 | ||
| 644 | /* This is the X/Open sanctioned signal stack switching. */ | 717 | /* This is the X/Open sanctioned signal stack switching. */ |
| 645 | - if (ka->sa.sa_flags & SA_ONSTACK) { | ||
| 646 | - if (sas_ss_flags(esp) == 0) | ||
| 647 | - esp = current->sas_ss_sp + current->sas_ss_size; | ||
| 648 | - } | 718 | + if (ka->sa.sa_flags & TARGET_SA_ONSTACK) { |
| 719 | + if (sas_ss_flags(esp) == 0) | ||
| 720 | + esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | ||
| 721 | + } | ||
| 649 | 722 | ||
| 650 | /* This is the legacy signal stack switching. */ | 723 | /* This is the legacy signal stack switching. */ |
| 651 | else | 724 | else |
| 652 | -#endif | ||
| 653 | if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && | 725 | if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && |
| 654 | !(ka->sa.sa_flags & TARGET_SA_RESTORER) && | 726 | !(ka->sa.sa_flags & TARGET_SA_RESTORER) && |
| 655 | ka->sa.sa_restorer) { | 727 | ka->sa.sa_restorer) { |
| @@ -750,11 +822,11 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -750,11 +822,11 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
| 750 | /* Create the ucontext. */ | 822 | /* Create the ucontext. */ |
| 751 | err |= __put_user(0, &frame->uc.tuc_flags); | 823 | err |= __put_user(0, &frame->uc.tuc_flags); |
| 752 | err |= __put_user(0, &frame->uc.tuc_link); | 824 | err |= __put_user(0, &frame->uc.tuc_link); |
| 753 | - err |= __put_user(/*current->sas_ss_sp*/ 0, | 825 | + err |= __put_user(target_sigaltstack_used.ss_sp, |
| 754 | &frame->uc.tuc_stack.ss_sp); | 826 | &frame->uc.tuc_stack.ss_sp); |
| 755 | - err |= __put_user(/* sas_ss_flags(regs->esp) */ 0, | 827 | + err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)), |
| 756 | &frame->uc.tuc_stack.ss_flags); | 828 | &frame->uc.tuc_stack.ss_flags); |
| 757 | - err |= __put_user(/* current->sas_ss_size */ 0, | 829 | + err |= __put_user(target_sigaltstack_used.ss_size, |
| 758 | &frame->uc.tuc_stack.ss_size); | 830 | &frame->uc.tuc_stack.ss_size); |
| 759 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, | 831 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, |
| 760 | env, set->sig[0]); | 832 | env, set->sig[0]); |
| @@ -880,7 +952,6 @@ long do_rt_sigreturn(CPUX86State *env) | @@ -880,7 +952,6 @@ long do_rt_sigreturn(CPUX86State *env) | ||
| 880 | { | 952 | { |
| 881 | struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4); | 953 | struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4); |
| 882 | sigset_t set; | 954 | sigset_t set; |
| 883 | - // stack_t st; | ||
| 884 | int eax; | 955 | int eax; |
| 885 | 956 | ||
| 886 | #if 0 | 957 | #if 0 |
| @@ -893,13 +964,9 @@ long do_rt_sigreturn(CPUX86State *env) | @@ -893,13 +964,9 @@ long do_rt_sigreturn(CPUX86State *env) | ||
| 893 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) | 964 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) |
| 894 | goto badframe; | 965 | goto badframe; |
| 895 | 966 | ||
| 896 | -#if 0 | ||
| 897 | - if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st))) | 967 | + if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT) |
| 898 | goto badframe; | 968 | goto badframe; |
| 899 | - /* It is more difficult to avoid calling this function than to | ||
| 900 | - call it and ignore errors. */ | ||
| 901 | - do_sigaltstack(&st, NULL, regs->esp); | ||
| 902 | -#endif | 969 | + |
| 903 | return eax; | 970 | return eax; |
| 904 | 971 | ||
| 905 | badframe: | 972 | badframe: |
| @@ -933,12 +1000,6 @@ struct target_sigcontext { | @@ -933,12 +1000,6 @@ struct target_sigcontext { | ||
| 933 | target_ulong fault_address; | 1000 | target_ulong fault_address; |
| 934 | }; | 1001 | }; |
| 935 | 1002 | ||
| 936 | -typedef struct target_sigaltstack { | ||
| 937 | - target_ulong ss_sp; | ||
| 938 | - int ss_flags; | ||
| 939 | - target_ulong ss_size; | ||
| 940 | -} target_stack_t; | ||
| 941 | - | ||
| 942 | struct target_ucontext { | 1003 | struct target_ucontext { |
| 943 | target_ulong tuc_flags; | 1004 | target_ulong tuc_flags; |
| 944 | target_ulong tuc_link; | 1005 | target_ulong tuc_link; |
| @@ -1031,13 +1092,11 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) | @@ -1031,13 +1092,11 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) | ||
| 1031 | { | 1092 | { |
| 1032 | unsigned long sp = regs->regs[13]; | 1093 | unsigned long sp = regs->regs[13]; |
| 1033 | 1094 | ||
| 1034 | -#if 0 | ||
| 1035 | /* | 1095 | /* |
| 1036 | * This is the X/Open sanctioned signal stack switching. | 1096 | * This is the X/Open sanctioned signal stack switching. |
| 1037 | */ | 1097 | */ |
| 1038 | - if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) | ||
| 1039 | - sp = current->sas_ss_sp + current->sas_ss_size; | ||
| 1040 | -#endif | 1098 | + if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) |
| 1099 | + sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | ||
| 1041 | /* | 1100 | /* |
| 1042 | * ATPCS B01 mandates 8-byte alignment | 1101 | * ATPCS B01 mandates 8-byte alignment |
| 1043 | */ | 1102 | */ |
| @@ -1074,8 +1133,8 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, | @@ -1074,8 +1133,8 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, | ||
| 1074 | else | 1133 | else |
| 1075 | cpsr &= ~T_BIT; | 1134 | cpsr &= ~T_BIT; |
| 1076 | } | 1135 | } |
| 1077 | -#endif | ||
| 1078 | -#endif | 1136 | +#endif /* CONFIG_ARM_THUMB */ |
| 1137 | +#endif /* 0 */ | ||
| 1079 | #endif /* TARGET_CONFIG_CPU_32 */ | 1138 | #endif /* TARGET_CONFIG_CPU_32 */ |
| 1080 | 1139 | ||
| 1081 | if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | 1140 | if (ka->sa.sa_flags & TARGET_SA_RESTORER) { |
| @@ -1132,6 +1191,7 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, | @@ -1132,6 +1191,7 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, | ||
| 1132 | target_sigset_t *set, CPUState *env) | 1191 | target_sigset_t *set, CPUState *env) |
| 1133 | { | 1192 | { |
| 1134 | struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); | 1193 | struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); |
| 1194 | + struct target_sigaltstack stack; | ||
| 1135 | int i, err = 0; | 1195 | int i, err = 0; |
| 1136 | 1196 | ||
| 1137 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 1197 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
| @@ -1144,6 +1204,15 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, | @@ -1144,6 +1204,15 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, | ||
| 1144 | /* Clear all the bits of the ucontext we don't use. */ | 1204 | /* Clear all the bits of the ucontext we don't use. */ |
| 1145 | memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext)); | 1205 | memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext)); |
| 1146 | 1206 | ||
| 1207 | + memset(&stack, 0, sizeof(stack)); | ||
| 1208 | + __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp); | ||
| 1209 | + __put_user(target_sigaltstack_used.ss_size, &stack.ss_size); | ||
| 1210 | + __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags); | ||
| 1211 | + if (!access_ok(VERIFY_WRITE, &frame->uc.tuc_stack, sizeof(stack))) | ||
| 1212 | + err = 1; | ||
| 1213 | + else | ||
| 1214 | + memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack)); | ||
| 1215 | + | ||
| 1147 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ | 1216 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ |
| 1148 | env, set->sig[0]); | 1217 | env, set->sig[0]); |
| 1149 | for(i = 0; i < TARGET_NSIG_WORDS; i++) { | 1218 | for(i = 0; i < TARGET_NSIG_WORDS; i++) { |
| @@ -1270,6 +1339,9 @@ long do_rt_sigreturn(CPUState *env) | @@ -1270,6 +1339,9 @@ long do_rt_sigreturn(CPUState *env) | ||
| 1270 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) | 1339 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) |
| 1271 | goto badframe; | 1340 | goto badframe; |
| 1272 | 1341 | ||
| 1342 | + if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT) | ||
| 1343 | + goto badframe; | ||
| 1344 | + | ||
| 1273 | #if 0 | 1345 | #if 0 |
| 1274 | /* Send SIGTRAP if we're single-stepping */ | 1346 | /* Send SIGTRAP if we're single-stepping */ |
| 1275 | if (ptrace_cancel_bpt(current)) | 1347 | if (ptrace_cancel_bpt(current)) |
| @@ -1382,14 +1454,13 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u | @@ -1382,14 +1454,13 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u | ||
| 1382 | unsigned long sp; | 1454 | unsigned long sp; |
| 1383 | 1455 | ||
| 1384 | sp = env->regwptr[UREG_FP]; | 1456 | sp = env->regwptr[UREG_FP]; |
| 1385 | -#if 0 | ||
| 1386 | 1457 | ||
| 1387 | /* This is the X/Open sanctioned signal stack switching. */ | 1458 | /* This is the X/Open sanctioned signal stack switching. */ |
| 1388 | - if (sa->sa_flags & TARGET_SA_ONSTACK) { | ||
| 1389 | - if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) | ||
| 1390 | - sp = current->sas_ss_sp + current->sas_ss_size; | 1459 | + if (sa->sa.sa_flags & TARGET_SA_ONSTACK) { |
| 1460 | + if (!on_sig_stack(sp) | ||
| 1461 | + && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) | ||
| 1462 | + sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | ||
| 1391 | } | 1463 | } |
| 1392 | -#endif | ||
| 1393 | return g2h(sp - framesize); | 1464 | return g2h(sp - framesize); |
| 1394 | } | 1465 | } |
| 1395 | 1466 | ||
| @@ -1842,11 +1913,10 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | @@ -1842,11 +1913,10 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | ||
| 1842 | */ | 1913 | */ |
| 1843 | sp -= 32; | 1914 | sp -= 32; |
| 1844 | 1915 | ||
| 1845 | -#if 0 | ||
| 1846 | /* This is the X/Open sanctioned signal stack switching. */ | 1916 | /* This is the X/Open sanctioned signal stack switching. */ |
| 1847 | - if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | ||
| 1848 | - sp = current->sas_ss_sp + current->sas_ss_size; | ||
| 1849 | -#endif | 1917 | + if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) { |
| 1918 | + sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | ||
| 1919 | + } | ||
| 1850 | 1920 | ||
| 1851 | return g2h((sp - frame_size) & ~7); | 1921 | return g2h((sp - frame_size) & ~7); |
| 1852 | } | 1922 | } |
linux-user/sparc/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 4096 | ||
| 22 | +#define TARGET_SIGSTKSZ 16384 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/sparc64/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 4096 | ||
| 22 | +#define TARGET_SIGSTKSZ 16384 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
linux-user/syscall.c
| @@ -4318,7 +4318,14 @@ target_long do_syscall(void *cpu_env, int num, target_long arg1, | @@ -4318,7 +4318,14 @@ target_long do_syscall(void *cpu_env, int num, target_long arg1, | ||
| 4318 | case TARGET_NR_capset: | 4318 | case TARGET_NR_capset: |
| 4319 | goto unimplemented; | 4319 | goto unimplemented; |
| 4320 | case TARGET_NR_sigaltstack: | 4320 | case TARGET_NR_sigaltstack: |
| 4321 | +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) | ||
| 4322 | + ret = do_sigaltstack((struct target_sigaltstack *)arg1, | ||
| 4323 | + (struct target_sigaltstack *)arg2, | ||
| 4324 | + get_sp_from_cpustate((CPUState *)cpu_env)); | ||
| 4325 | + break; | ||
| 4326 | +#else | ||
| 4321 | goto unimplemented; | 4327 | goto unimplemented; |
| 4328 | +#endif | ||
| 4322 | case TARGET_NR_sendfile: | 4329 | case TARGET_NR_sendfile: |
| 4323 | goto unimplemented; | 4330 | goto unimplemented; |
| 4324 | #ifdef TARGET_NR_getpmsg | 4331 | #ifdef TARGET_NR_getpmsg |
linux-user/x86_64/target_signal.h
0 โ 100644
| 1 | +#ifndef TARGET_SIGNAL_H | ||
| 2 | +#define TARGET_SIGNAL_H | ||
| 3 | + | ||
| 4 | +#include "cpu.h" | ||
| 5 | + | ||
| 6 | +/* this struct defines a stack used during syscall handling */ | ||
| 7 | + | ||
| 8 | +typedef struct target_sigaltstack { | ||
| 9 | + target_ulong ss_sp; | ||
| 10 | + target_long ss_flags; | ||
| 11 | + target_ulong ss_size; | ||
| 12 | +} target_stack_t; | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +/* | ||
| 16 | + * sigaltstack controls | ||
| 17 | + */ | ||
| 18 | +#define TARGET_SS_ONSTACK 1 | ||
| 19 | +#define TARGET_SS_DISABLE 2 | ||
| 20 | + | ||
| 21 | +#define TARGET_MINSIGSTKSZ 2048 | ||
| 22 | +#define TARGET_SIGSTKSZ 8192 | ||
| 23 | + | ||
| 24 | +#endif /* TARGET_SIGNAL_H */ |
target-alpha/cpu.h
| @@ -397,4 +397,9 @@ void cpu_loop_exit (void); | @@ -397,4 +397,9 @@ void cpu_loop_exit (void); | ||
| 397 | void pal_init (CPUState *env); | 397 | void pal_init (CPUState *env); |
| 398 | void call_pal (CPUState *env, int palcode); | 398 | void call_pal (CPUState *env, int palcode); |
| 399 | 399 | ||
| 400 | +static inline target_ulong get_sp_from_cpustate(CPUAlphaState *state) | ||
| 401 | +{ | ||
| 402 | + return state->ir[IR_SP]; | ||
| 403 | +} | ||
| 404 | + | ||
| 400 | #endif /* !defined (__CPU_ALPHA_H__) */ | 405 | #endif /* !defined (__CPU_ALPHA_H__) */ |
target-arm/cpu.h
| @@ -300,6 +300,11 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, | @@ -300,6 +300,11 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, | ||
| 300 | #define cpu_gen_code cpu_arm_gen_code | 300 | #define cpu_gen_code cpu_arm_gen_code |
| 301 | #define cpu_signal_handler cpu_arm_signal_handler | 301 | #define cpu_signal_handler cpu_arm_signal_handler |
| 302 | 302 | ||
| 303 | +static inline target_ulong get_sp_from_cpustate(CPUARMState *state) | ||
| 304 | +{ | ||
| 305 | + return state->regs[13]; | ||
| 306 | +} | ||
| 307 | + | ||
| 303 | #include "cpu-all.h" | 308 | #include "cpu-all.h" |
| 304 | 309 | ||
| 305 | #endif | 310 | #endif |
target-i386/cpu.h
| @@ -688,6 +688,11 @@ static inline int cpu_get_time_fast(void) | @@ -688,6 +688,11 @@ static inline int cpu_get_time_fast(void) | ||
| 688 | #define cpu_gen_code cpu_x86_gen_code | 688 | #define cpu_gen_code cpu_x86_gen_code |
| 689 | #define cpu_signal_handler cpu_x86_signal_handler | 689 | #define cpu_signal_handler cpu_x86_signal_handler |
| 690 | 690 | ||
| 691 | +static inline target_ulong get_sp_from_cpustate(CPUX86State *state) | ||
| 692 | +{ | ||
| 693 | + return state->regs[R_ESP]; | ||
| 694 | +} | ||
| 695 | + | ||
| 691 | #include "cpu-all.h" | 696 | #include "cpu-all.h" |
| 692 | 697 | ||
| 693 | #include "svm.h" | 698 | #include "svm.h" |
target-mips/cpu.h
| @@ -548,4 +548,9 @@ CPUMIPSState *cpu_mips_init(void); | @@ -548,4 +548,9 @@ CPUMIPSState *cpu_mips_init(void); | ||
| 548 | uint32_t cpu_mips_get_clock (void); | 548 | uint32_t cpu_mips_get_clock (void); |
| 549 | int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); | 549 | int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); |
| 550 | 550 | ||
| 551 | +static inline target_ulong get_sp_from_cpustate(CPUMIPSState *state) | ||
| 552 | +{ | ||
| 553 | + return state->gpr[29][state->current_tc]; | ||
| 554 | +} | ||
| 555 | + | ||
| 551 | #endif /* !defined (__MIPS_CPU_H__) */ | 556 | #endif /* !defined (__MIPS_CPU_H__) */ |
target-ppc/cpu.h
| @@ -1146,4 +1146,9 @@ enum { | @@ -1146,4 +1146,9 @@ enum { | ||
| 1146 | 1146 | ||
| 1147 | /*****************************************************************************/ | 1147 | /*****************************************************************************/ |
| 1148 | 1148 | ||
| 1149 | +static inline target_ulong get_sp_from_cpustate(CPUPPCState *state) | ||
| 1150 | +{ | ||
| 1151 | + return state->gpr[1]; | ||
| 1152 | +} | ||
| 1153 | + | ||
| 1149 | #endif /* !defined (__CPU_PPC_H__) */ | 1154 | #endif /* !defined (__CPU_PPC_H__) */ |
target-sparc/cpu.h
| @@ -316,6 +316,18 @@ void cpu_check_irqs(CPUSPARCState *env); | @@ -316,6 +316,18 @@ void cpu_check_irqs(CPUSPARCState *env); | ||
| 316 | #define cpu_gen_code cpu_sparc_gen_code | 316 | #define cpu_gen_code cpu_sparc_gen_code |
| 317 | #define cpu_signal_handler cpu_sparc_signal_handler | 317 | #define cpu_signal_handler cpu_sparc_signal_handler |
| 318 | 318 | ||
| 319 | +#ifndef UREG_I6 | ||
| 320 | +#define UREG_I6 6 | ||
| 321 | +#endif | ||
| 322 | +#ifndef UREG_FP | ||
| 323 | +#define UREG_FP UREG_I6 | ||
| 324 | +#endif | ||
| 325 | + | ||
| 326 | +static inline target_ulong get_sp_from_cpustate(CPUSPARCState *state) | ||
| 327 | +{ | ||
| 328 | + return state->regwptr[UREG_FP]; | ||
| 329 | +} | ||
| 330 | + | ||
| 319 | #include "cpu-all.h" | 331 | #include "cpu-all.h" |
| 320 | 332 | ||
| 321 | #endif | 333 | #endif |