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 |