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 | ... | ... |