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 | 9 | |
| 10 | 10 | #include "cpu.h" |
| 11 | 11 | #include "syscall.h" |
| 12 | +#include "target_signal.h" | |
| 12 | 13 | #include "gdbstub.h" |
| 13 | 14 | |
| 14 | 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 | 150 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); |
| 150 | 151 | long do_sigreturn(CPUState *env); |
| 151 | 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 | 157 | #ifdef TARGET_I386 |
| 154 | 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 | 26 | #include <errno.h> |
| 27 | 27 | #include <sys/ucontext.h> |
| 28 | 28 | |
| 29 | +#include "target_signal.h" | |
| 29 | 30 | #include "qemu.h" |
| 30 | 31 | |
| 31 | 32 | //#define DEBUG_SIGNAL |
| ... | ... | @@ -45,6 +46,12 @@ struct emulated_sigaction { |
| 45 | 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 | 55 | static struct emulated_sigaction sigact_table[TARGET_NSIG]; |
| 49 | 56 | static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ |
| 50 | 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 | 99 | }; |
| 93 | 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 | 114 | static inline int host_to_target_signal(int sig) |
| 96 | 115 | { |
| 97 | 116 | return host_to_target_signal_table[sig]; |
| ... | ... | @@ -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 | 502 | int do_sigaction(int sig, const struct target_sigaction *act, |
| 423 | 503 | struct target_sigaction *oact) |
| 424 | 504 | { |
| ... | ... | @@ -551,12 +631,6 @@ struct target_sigcontext { |
| 551 | 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 | 634 | struct target_ucontext { |
| 561 | 635 | target_ulong tuc_flags; |
| 562 | 636 | target_ulong tuc_link; |
| ... | ... | @@ -640,16 +714,14 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) |
| 640 | 714 | |
| 641 | 715 | /* Default to using normal stack */ |
| 642 | 716 | esp = env->regs[R_ESP]; |
| 643 | -#if 0 | |
| 644 | 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 | 723 | /* This is the legacy signal stack switching. */ |
| 651 | 724 | else |
| 652 | -#endif | |
| 653 | 725 | if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && |
| 654 | 726 | !(ka->sa.sa_flags & TARGET_SA_RESTORER) && |
| 655 | 727 | ka->sa.sa_restorer) { |
| ... | ... | @@ -750,11 +822,11 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, |
| 750 | 822 | /* Create the ucontext. */ |
| 751 | 823 | err |= __put_user(0, &frame->uc.tuc_flags); |
| 752 | 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 | 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 | 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 | 830 | &frame->uc.tuc_stack.ss_size); |
| 759 | 831 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, |
| 760 | 832 | env, set->sig[0]); |
| ... | ... | @@ -880,7 +952,6 @@ long do_rt_sigreturn(CPUX86State *env) |
| 880 | 952 | { |
| 881 | 953 | struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4); |
| 882 | 954 | sigset_t set; |
| 883 | - // stack_t st; | |
| 884 | 955 | int eax; |
| 885 | 956 | |
| 886 | 957 | #if 0 |
| ... | ... | @@ -893,13 +964,9 @@ long do_rt_sigreturn(CPUX86State *env) |
| 893 | 964 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) |
| 894 | 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 | 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 | 970 | return eax; |
| 904 | 971 | |
| 905 | 972 | badframe: |
| ... | ... | @@ -933,12 +1000,6 @@ struct target_sigcontext { |
| 933 | 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 | 1003 | struct target_ucontext { |
| 943 | 1004 | target_ulong tuc_flags; |
| 944 | 1005 | target_ulong tuc_link; |
| ... | ... | @@ -1031,13 +1092,11 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) |
| 1031 | 1092 | { |
| 1032 | 1093 | unsigned long sp = regs->regs[13]; |
| 1033 | 1094 | |
| 1034 | -#if 0 | |
| 1035 | 1095 | /* |
| 1036 | 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 | 1101 | * ATPCS B01 mandates 8-byte alignment |
| 1043 | 1102 | */ |
| ... | ... | @@ -1074,8 +1133,8 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, |
| 1074 | 1133 | else |
| 1075 | 1134 | cpsr &= ~T_BIT; |
| 1076 | 1135 | } |
| 1077 | -#endif | |
| 1078 | -#endif | |
| 1136 | +#endif /* CONFIG_ARM_THUMB */ | |
| 1137 | +#endif /* 0 */ | |
| 1079 | 1138 | #endif /* TARGET_CONFIG_CPU_32 */ |
| 1080 | 1139 | |
| 1081 | 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 | 1191 | target_sigset_t *set, CPUState *env) |
| 1133 | 1192 | { |
| 1134 | 1193 | struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); |
| 1194 | + struct target_sigaltstack stack; | |
| 1135 | 1195 | int i, err = 0; |
| 1136 | 1196 | |
| 1137 | 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 | 1204 | /* Clear all the bits of the ucontext we don't use. */ |
| 1145 | 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 | 1216 | err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ |
| 1148 | 1217 | env, set->sig[0]); |
| 1149 | 1218 | for(i = 0; i < TARGET_NSIG_WORDS; i++) { |
| ... | ... | @@ -1270,6 +1339,9 @@ long do_rt_sigreturn(CPUState *env) |
| 1270 | 1339 | if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) |
| 1271 | 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 | 1345 | #if 0 |
| 1274 | 1346 | /* Send SIGTRAP if we're single-stepping */ |
| 1275 | 1347 | if (ptrace_cancel_bpt(current)) |
| ... | ... | @@ -1382,14 +1454,13 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u |
| 1382 | 1454 | unsigned long sp; |
| 1383 | 1455 | |
| 1384 | 1456 | sp = env->regwptr[UREG_FP]; |
| 1385 | -#if 0 | |
| 1386 | 1457 | |
| 1387 | 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 | 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 | 1913 | */ |
| 1843 | 1914 | sp -= 32; |
| 1844 | 1915 | |
| 1845 | -#if 0 | |
| 1846 | 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 | 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 | 4318 | case TARGET_NR_capset: |
| 4319 | 4319 | goto unimplemented; |
| 4320 | 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 | 4327 | goto unimplemented; |
| 4328 | +#endif | |
| 4322 | 4329 | case TARGET_NR_sendfile: |
| 4323 | 4330 | goto unimplemented; |
| 4324 | 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 | 397 | void pal_init (CPUState *env); |
| 398 | 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 | 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 | 300 | #define cpu_gen_code cpu_arm_gen_code |
| 301 | 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 | 308 | #include "cpu-all.h" |
| 304 | 309 | |
| 305 | 310 | #endif | ... | ... |
target-i386/cpu.h
| ... | ... | @@ -688,6 +688,11 @@ static inline int cpu_get_time_fast(void) |
| 688 | 688 | #define cpu_gen_code cpu_x86_gen_code |
| 689 | 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 | 696 | #include "cpu-all.h" |
| 692 | 697 | |
| 693 | 698 | #include "svm.h" | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -548,4 +548,9 @@ CPUMIPSState *cpu_mips_init(void); |
| 548 | 548 | uint32_t cpu_mips_get_clock (void); |
| 549 | 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 | 556 | #endif /* !defined (__MIPS_CPU_H__) */ | ... | ... |
target-ppc/cpu.h
| ... | ... | @@ -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 | 1154 | #endif /* !defined (__CPU_PPC_H__) */ | ... | ... |
target-sparc/cpu.h
| ... | ... | @@ -316,6 +316,18 @@ void cpu_check_irqs(CPUSPARCState *env); |
| 316 | 316 | #define cpu_gen_code cpu_sparc_gen_code |
| 317 | 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 | 331 | #include "cpu-all.h" |
| 320 | 332 | |
| 321 | 333 | #endif | ... | ... |