Revision 9231944d
b/linux-user/signal.c | ||
---|---|---|
109 | 109 |
return target_to_host_signal_table[sig]; |
110 | 110 |
} |
111 | 111 |
|
112 |
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s) |
|
112 |
static void host_to_target_sigset_internal(target_sigset_t *d, |
|
113 |
const sigset_t *s) |
|
113 | 114 |
{ |
114 | 115 |
int i; |
115 | 116 |
unsigned long sigmask; |
... | ... | |
122 | 123 |
target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1); |
123 | 124 |
} |
124 | 125 |
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32 |
125 |
d->sig[0] = tswapl(target_sigmask);
|
|
126 |
d->sig[0] = target_sigmask;
|
|
126 | 127 |
for(i = 1;i < TARGET_NSIG_WORDS; i++) { |
127 |
d->sig[i] = tswapl(((unsigned long *)s)[i]);
|
|
128 |
d->sig[i] = ((unsigned long *)s)[i];
|
|
128 | 129 |
} |
129 | 130 |
#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 |
130 |
d->sig[0] = tswapl(target_sigmask);
|
|
131 |
d->sig[1] = tswapl(sigmask >> 32);
|
|
131 |
d->sig[0] = target_sigmask;
|
|
132 |
d->sig[1] = sigmask >> 32;
|
|
132 | 133 |
#else |
133 | 134 |
#error host_to_target_sigset |
134 | 135 |
#endif |
135 | 136 |
} |
136 | 137 |
|
137 |
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s) |
|
138 |
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s) |
|
139 |
{ |
|
140 |
target_sigset_t d1; |
|
141 |
int i; |
|
142 |
|
|
143 |
host_to_target_sigset_internal(&d1, s); |
|
144 |
for(i = 0;i < TARGET_NSIG_WORDS; i++) |
|
145 |
__put_user(d1.sig[i], &d->sig[i]); |
|
146 |
} |
|
147 |
|
|
148 |
void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s) |
|
138 | 149 |
{ |
139 | 150 |
int i; |
140 | 151 |
unsigned long sigmask; |
141 | 152 |
target_ulong target_sigmask; |
142 | 153 |
|
143 |
target_sigmask = tswapl(s->sig[0]);
|
|
154 |
target_sigmask = s->sig[0];
|
|
144 | 155 |
sigmask = 0; |
145 | 156 |
for(i = 0; i < 32; i++) { |
146 | 157 |
if (target_sigmask & (1 << i)) |
... | ... | |
149 | 160 |
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32 |
150 | 161 |
((unsigned long *)d)[0] = sigmask; |
151 | 162 |
for(i = 1;i < TARGET_NSIG_WORDS; i++) { |
152 |
((unsigned long *)d)[i] = tswapl(s->sig[i]);
|
|
163 |
((unsigned long *)d)[i] = s->sig[i];
|
|
153 | 164 |
} |
154 | 165 |
#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 |
155 |
((unsigned long *)d)[0] = sigmask | ((unsigned long)tswapl(s->sig[1]) << 32);
|
|
166 |
((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32); |
|
156 | 167 |
#else |
157 | 168 |
#error target_to_host_sigset |
158 | 169 |
#endif /* TARGET_LONG_BITS */ |
159 | 170 |
} |
160 | 171 |
|
172 |
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s) |
|
173 |
{ |
|
174 |
target_sigset_t s1; |
|
175 |
int i; |
|
176 |
|
|
177 |
for(i = 0;i < TARGET_NSIG_WORDS; i++) |
|
178 |
__get_user(s1.sig[i], &s->sig[i]); |
|
179 |
target_to_host_sigset_internal(d, &s1); |
|
180 |
} |
|
181 |
|
|
161 | 182 |
void host_to_target_old_sigset(target_ulong *old_sigset, |
162 | 183 |
const sigset_t *sigset) |
163 | 184 |
{ |
... | ... | |
640 | 661 |
target_sigset_t *set, CPUX86State *env) |
641 | 662 |
{ |
642 | 663 |
struct sigframe *frame; |
643 |
int err = 0; |
|
664 |
int i, err = 0;
|
|
644 | 665 |
|
645 | 666 |
frame = get_sigframe(ka, env, sizeof(*frame)); |
646 | 667 |
|
... | ... | |
659 | 680 |
if (err) |
660 | 681 |
goto give_sigsegv; |
661 | 682 |
|
662 |
if (TARGET_NSIG_WORDS > 1) { |
|
663 |
err |= __copy_to_user(frame->extramask, &set->sig[1], |
|
664 |
sizeof(frame->extramask)); |
|
665 |
} |
|
666 |
if (err) |
|
667 |
goto give_sigsegv; |
|
683 |
for(i = 1; i < TARGET_NSIG_WORDS; i++) { |
|
684 |
if (__put_user(set->sig[i], &frame->extramask[i - 1])) |
|
685 |
goto give_sigsegv; |
|
686 |
} |
|
668 | 687 |
|
669 | 688 |
/* Set up to return from userspace. If provided, use a stub |
670 | 689 |
already in userspace. */ |
... | ... | |
704 | 723 |
target_sigset_t *set, CPUX86State *env) |
705 | 724 |
{ |
706 | 725 |
struct rt_sigframe *frame; |
707 |
int err = 0; |
|
726 |
int i, err = 0;
|
|
708 | 727 |
|
709 | 728 |
frame = get_sigframe(ka, env, sizeof(*frame)); |
710 | 729 |
|
... | ... | |
732 | 751 |
err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size); |
733 | 752 |
err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, |
734 | 753 |
env, set->sig[0]); |
735 |
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
|
736 |
if (err) |
|
737 |
goto give_sigsegv; |
|
754 |
for(i = 0; i < TARGET_NSIG_WORDS; i++) { |
|
755 |
if (__put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i])) |
|
756 |
goto give_sigsegv; |
|
757 |
} |
|
738 | 758 |
|
739 | 759 |
/* Set up to return from userspace. If provided, use a stub |
740 | 760 |
already in userspace. */ |
... | ... | |
829 | 849 |
fprintf(stderr, "do_sigreturn\n"); |
830 | 850 |
#endif |
831 | 851 |
/* set blocked signals */ |
832 |
target_set.sig[0] = frame->sc.oldmask; |
|
833 |
for(i = 1; i < TARGET_NSIG_WORDS; i++) |
|
834 |
target_set.sig[i] = frame->extramask[i - 1]; |
|
852 |
if (__get_user(target_set.sig[0], &frame->sc.oldmask)) |
|
853 |
goto badframe; |
|
854 |
for(i = 1; i < TARGET_NSIG_WORDS; i++) { |
|
855 |
if (__get_user(target_set.sig[i], &frame->extramask[i - 1])) |
|
856 |
goto badframe; |
|
857 |
} |
|
835 | 858 |
|
836 |
target_to_host_sigset(&set, &target_set); |
|
859 |
target_to_host_sigset_internal(&set, &target_set);
|
|
837 | 860 |
sigprocmask(SIG_SETMASK, &set, NULL); |
838 | 861 |
|
839 | 862 |
/* restore registers */ |
... | ... | |
849 | 872 |
long do_rt_sigreturn(CPUX86State *env) |
850 | 873 |
{ |
851 | 874 |
struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4); |
852 |
target_sigset_t target_set; |
|
853 | 875 |
sigset_t set; |
854 | 876 |
// stack_t st; |
855 | 877 |
int eax; |
... | ... | |
858 | 880 |
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) |
859 | 881 |
goto badframe; |
860 | 882 |
#endif |
861 |
memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t)); |
|
862 |
|
|
863 |
target_to_host_sigset(&set, &target_set); |
|
883 |
target_to_host_sigset(&set, &frame->uc.uc_sigmask); |
|
864 | 884 |
sigprocmask(SIG_SETMASK, &set, NULL); |
865 | 885 |
|
866 | 886 |
if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax)) |
... | ... | |
1084 | 1104 |
target_sigset_t *set, CPUState *regs) |
1085 | 1105 |
{ |
1086 | 1106 |
struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame)); |
1087 |
int err = 0; |
|
1107 |
int i, err = 0;
|
|
1088 | 1108 |
|
1089 | 1109 |
err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]); |
1090 | 1110 |
|
1091 |
if (TARGET_NSIG_WORDS > 1) {
|
|
1092 |
err |= __copy_to_user(frame->extramask, &set->sig[1],
|
|
1093 |
sizeof(frame->extramask));
|
|
1111 |
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
|
|
1112 |
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
|
|
1113 |
return;
|
|
1094 | 1114 |
} |
1095 | 1115 |
|
1096 | 1116 |
if (err == 0) |
... | ... | |
1103 | 1123 |
target_sigset_t *set, CPUState *env) |
1104 | 1124 |
{ |
1105 | 1125 |
struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); |
1106 |
int err = 0; |
|
1126 |
int i, err = 0;
|
|
1107 | 1127 |
|
1108 | 1128 |
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
1109 | 1129 |
return /* 1 */; |
... | ... | |
1117 | 1137 |
|
1118 | 1138 |
err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/ |
1119 | 1139 |
env, set->sig[0]); |
1120 |
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
|
1140 |
for(i = 0; i < TARGET_NSIG_WORDS; i++) { |
|
1141 |
if (__put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i])) |
|
1142 |
return; |
|
1143 |
} |
|
1121 | 1144 |
|
1122 | 1145 |
if (err == 0) |
1123 | 1146 |
err = setup_return(env, ka, &frame->retcode, frame, usig); |
... | ... | |
1170 | 1193 |
struct sigframe *frame; |
1171 | 1194 |
target_sigset_t set; |
1172 | 1195 |
sigset_t host_set; |
1196 |
int i; |
|
1173 | 1197 |
|
1174 | 1198 |
/* |
1175 | 1199 |
* Since we stacked the signal on a 64-bit boundary, |
... | ... | |
1185 | 1209 |
if (verify_area(VERIFY_READ, frame, sizeof (*frame))) |
1186 | 1210 |
goto badframe; |
1187 | 1211 |
#endif |
1188 |
if (__get_user(set.sig[0], &frame->sc.oldmask) |
|
1189 |
|| (TARGET_NSIG_WORDS > 1 |
|
1190 |
&& __copy_from_user(&set.sig[1], &frame->extramask, |
|
1191 |
sizeof(frame->extramask)))) |
|
1192 |
goto badframe; |
|
1212 |
if (__get_user(set.sig[0], &frame->sc.oldmask)) |
|
1213 |
goto badframe; |
|
1214 |
for(i = 1; i < TARGET_NSIG_WORDS; i++) { |
|
1215 |
if (__get_user(set.sig[i], &frame->extramask[i - 1])) |
|
1216 |
goto badframe; |
|
1217 |
} |
|
1193 | 1218 |
|
1194 |
target_to_host_sigset(&host_set, &set); |
|
1219 |
target_to_host_sigset_internal(&host_set, &set);
|
|
1195 | 1220 |
sigprocmask(SIG_SETMASK, &host_set, NULL); |
1196 | 1221 |
|
1197 | 1222 |
if (restore_sigcontext(env, &frame->sc)) |
... | ... | |
1212 | 1237 |
long do_rt_sigreturn(CPUState *env) |
1213 | 1238 |
{ |
1214 | 1239 |
struct rt_sigframe *frame; |
1215 |
target_sigset_t set; |
|
1216 | 1240 |
sigset_t host_set; |
1217 | 1241 |
|
1218 | 1242 |
/* |
... | ... | |
1229 | 1253 |
if (verify_area(VERIFY_READ, frame, sizeof (*frame))) |
1230 | 1254 |
goto badframe; |
1231 | 1255 |
#endif |
1232 |
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
|
1233 |
goto badframe; |
|
1234 |
|
|
1235 |
target_to_host_sigset(&host_set, &set); |
|
1256 |
target_to_host_sigset(&host_set, &frame->uc.uc_sigmask); |
|
1236 | 1257 |
sigprocmask(SIG_SETMASK, &host_set, NULL); |
1237 | 1258 |
|
1238 | 1259 |
if (restore_sigcontext(env, &frame->uc.uc_mcontext)) |
... | ... | |
1335 | 1356 |
sigprocmask(SIG_BLOCK, &set, &old_set); |
1336 | 1357 |
/* save the previous blocked signal state to restore it at the |
1337 | 1358 |
end of the signal execution (see do_sigreturn) */ |
1338 |
host_to_target_sigset(&target_old_set, &old_set); |
|
1359 |
host_to_target_sigset_internal(&target_old_set, &old_set);
|
|
1339 | 1360 |
|
1340 | 1361 |
/* if the CPU is in VM86 mode, we restore the 32 bit values */ |
1341 | 1362 |
#ifdef TARGET_I386 |
Also available in: Unified diff